diff --git a/.circleci/config.yml b/.circleci/config.yml
new file mode 100644
index 0000000..f898133
--- /dev/null
+++ b/.circleci/config.yml
@@ -0,0 +1,197 @@
+version: 2
+jobs:
+ build:
+ docker:
+ - image: zondax/circleci:latest
+ steps:
+ - checkout
+ - run: git submodule update --init --recursive
+ - run: cmake -DCMAKE_BUILD_TYPE=Debug . && make
+ # Unfortunately need to disable leak sanitizer https://github.com/google/sanitizers/issues/916
+ # Still run all other ASAN components
+ - run: GTEST_COLOR=1 ASAN_OPTIONS=detect_leaks=0 ctest -VV
+
+ build_only_rust:
+ docker:
+ - image: zondax/rust-ci:latest
+ steps:
+ - checkout
+ - run:
+ name: rustfmt
+ command: |
+ cd ~/project/app/rust
+ cargo fmt --version
+ cargo fmt -- --check
+ - run:
+ name: clippy
+ command: |
+ cd ~/project/app/rust
+ cargo clippy --version
+ cargo clippy --all-features --all-targets || true
+ - run:
+ name: audit
+ command: |
+ cd ~/project/app/rust
+ cargo audit --version
+ cargo audit
+ - run:
+ name: run tests
+ command: |
+ cd ~/project/app/rust
+ cargo test
+
+ build_ledger:
+ docker:
+ - image: zondax/builder-bolos:latest
+ working_directory: ~/project
+ environment:
+ BOLOS_SDK: /home/zondax/project/deps/nanos-secure-sdk
+ BOLOS_ENV: /opt/bolos
+ steps:
+ - checkout
+ # Docker entrypoint is not considered
+ - run: git submodule update --init --recursive
+ - run:
+ name: Build Standard light parser app
+ command: |
+ source /home/zondax/.cargo/env
+ make SUBSTRATE_PARSER_FULL=0
+ - run:
+ name: Build Standard full parser app
+ command: |
+ source /home/zondax/.cargo/env
+ make SUBSTRATE_PARSER_FULL=1
+ - run:
+ name: Build SR25519 app
+ command: |
+ source /home/zondax/.cargo/env
+ make SUPPORT_SR25519=1
+
+ test_zemu:
+ machine:
+ image: ubuntu-2004:202101-01
+ resource_class: large
+ working_directory: ~/repo
+ environment:
+ BASH_ENV: "/opt/circleci/.nvm/nvm.sh"
+ steps:
+ - checkout
+ - run: git submodule update --init --recursive
+ - run: sudo apt-get update -y && sudo apt-get install -y libusb-1.0.0 libudev-dev
+ - run:
+ name: Install rust
+ command: |
+ sudo apt-get update
+ sudo apt-get install -y cmake binutils-dev libcurl4-openssl-dev libiberty-dev libelf-dev libdw-dev
+ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --no-modify-path --default-toolchain none -y;
+ no_output_timeout: 1800s
+ - run:
+ name: Install node + yarn
+ command: |
+ nvm install 14.17.0
+ nvm use 14.17.0
+ npm install -g yarn
+ - run:
+ name: Build Ledger app
+ command: |
+ make clean_build && SUBSTRATE_PARSER_FULL=1 make buildS
+ make clean_build && SUBSTRATE_PARSER_FULL=1 make buildX
+ - run:
+ name: Build/Install build js deps
+ command: |
+ nvm use 14.17.0
+ export PATH=~/.cargo/bin:$PATH
+ make zemu_install
+ - run:
+ name: Run zemu tests
+ command: |
+ nvm use 14.17.0
+ export PATH=~/.cargo/bin:$PATH
+ make zemu_test
+
+ test_zemu_sr25519:
+ machine:
+ image: ubuntu-2004:202101-01
+ resource_class: large
+ working_directory: ~/repo
+ environment:
+ BASH_ENV: "/opt/circleci/.nvm/nvm.sh"
+ steps:
+ - checkout
+ - run: git submodule update --init --recursive
+ - run: sudo apt-get update -y && sudo apt-get install -y libusb-1.0.0 libudev-dev
+ - run:
+ name: Install rust
+ command: |
+ sudo apt-get update
+ sudo apt-get install -y cmake binutils-dev libcurl4-openssl-dev libiberty-dev libelf-dev libdw-dev
+ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --no-modify-path --default-toolchain none -y;
+ no_output_timeout: 1800s
+ - run:
+ name: Install node + yarn
+ command: |
+ nvm install 14.17.0
+ nvm use 14.17.0
+ npm install -g yarn
+ - run:
+ name: Build Ledger app
+ command: |
+ make clean_build && SUBSTRATE_PARSER_FULL=1 SUPPORT_SR25519=1 make buildS
+ - run:
+ name: Build/Install build js deps
+ command: |
+ nvm use 14.17.0
+ export PATH=~/.cargo/bin:$PATH
+ make zemu_install
+ - run:
+ name: Run zemu tests for sr25519
+ command: |
+ nvm use 14.17.0
+ export PATH=~/.cargo/bin:$PATH
+ cd tests_zemu && yarn testSR25519
+
+ build_package:
+ docker:
+ - image: zondax/builder-bolos:latest
+ environment:
+ BOLOS_SDK: /home/zondax/project/deps/nanos-secure-sdk
+ BOLOS_ENV: /opt/bolos
+ steps:
+ - checkout
+ - run: git submodule update --init --recursive
+ - run:
+ name: Build
+ command: |
+ source /home/zondax/.cargo/env
+ cd /home/zondax/project
+ make SUBSTRATE_PARSER_FULL=0
+ - run: /home/zondax/go/bin/ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} -delete $(/home/zondax/project/app/pkg/installer_s.sh version) /home/zondax/project/app/pkg/installer_s.sh
+ - run:
+ name: Clear and rebuild XL version
+ command: |
+ source /home/zondax/.cargo/env
+ cd /home/zondax/project
+ make SUBSTRATE_PARSER_FULL=1
+ cp /home/zondax/project/app/pkg/installer_s.sh /home/zondax/project/app/pkg/installer_XL_s.sh
+ - run: /home/zondax/go/bin/ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} -delete $(/home/zondax/project/app/pkg/installer_XL_s.sh version) /home/zondax/project/app/pkg/installer_XL_s.sh
+
+workflows:
+ version: 2
+
+ default:
+ jobs:
+ - build
+ - build_only_rust
+ - build_ledger
+ - test_zemu
+ - test_zemu_sr25519
+ - build_package:
+ requires:
+ - build
+ - build_ledger
+ - test_zemu
+ - test_zemu_sr25519
+ filters:
+ branches:
+ only:
+ - main
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..2d7db14
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,16 @@
+# top-most EditorConfig file
+root = true
+
+[*]
+charset = utf-8
+trim_trailing_whitespace = true
+end_of_line = lf
+insert_final_newline = true
+
+[*.{c,h,cpp,hpp}]
+indent_style = space
+indent_size = 4
+
+[*.{yml,sh}]
+indent_style = space
+indent_size = 2
diff --git a/.gdbinit b/.gdbinit
new file mode 100644
index 0000000..b45602e
--- /dev/null
+++ b/.gdbinit
@@ -0,0 +1,11 @@
+# https://www.jetbrains.com/help/clion/configuring-debugger-options.html#gdbinit-lldbinit
+#
+# You need to create `$HOME/.gdbinit` with the following content:
+# set auto-load local-gdbinit on
+# add-auto-load-safe-path /
+
+# set architecture arm
+# handle SIGILL nostop pass noprint
+# add-symbol-file app/bin/app.elf 0x40000000
+# set backtrace limit 20
+# b *0x40000000
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 0000000..f8e4c43
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,151 @@
+name: Build
+on: [push]
+
+jobs:
+ configure:
+ runs-on: ubuntu-latest
+ outputs:
+ uid_gid: ${{ steps.get-user.outputs.uid_gid }}
+ steps:
+ - id: get-user
+ run: echo "::set-output name=uid_gid::$(id -u):$(id -g)"
+
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ with:
+ submodules: true
+ - name: Install deps
+ run: |
+ sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 10
+ make deps
+ brew install conan
+ - run: cmake -DCMAKE_BUILD_TYPE=Debug . && make
+ - run: GTEST_COLOR=1 ASAN_OPTIONS=detect_leaks=0 ctest -VV
+
+ build_only_rust:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ with:
+ submodules: true
+ - name: Install deps
+ run: |
+ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
+ - name: rustfmt
+ run: |
+ cd ./app/rust
+ cargo fmt --version
+ cargo fmt -- --check
+ - name: clippy
+ run: |
+ cd ./app/rust
+ cargo clippy --version
+ cargo clippy --all-features --all-targets || true
+ - name: audit
+ run: |
+ cd ./app/rust
+ cargo audit --version
+ cargo audit
+ - name: run tests
+ run: |
+ cd ./app/rust
+ cargo test
+
+ build_ledger:
+ needs: configure
+ runs-on: ubuntu-latest
+ container:
+ image: zondax/builder-bolos:latest
+ options: --user ${{ needs.configure.outputs.uid_gid }}
+ env:
+ BOLOS_SDK: ${{ github.workspace }}/deps/nanos-secure-sdk
+ BOLOS_ENV: /opt/bolos
+ HOME: /home/zondax_circle
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ with:
+ submodules: true
+ - name: Build Standard app
+ shell: bash -l {0}
+ run: |
+ source $HOME/.cargo/env
+ make
+ - name: Build SR25519 app
+ shell: bash -l {0}
+ run: |
+ source $HOME/.cargo/env
+ SUPPORT_SR25519=1 make
+
+ test_zemu:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Test
+ run: |
+ id
+ echo $HOME
+ echo $DISPLAY
+ - name: Checkout
+ uses: actions/checkout@v2
+ with:
+ submodules: true
+ - run: sudo apt-get update -y && sudo apt-get install -y libusb-1.0.0 libudev-dev
+ - name: Install rust
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y cmake binutils-dev libcurl4-openssl-dev libiberty-dev libelf-dev libdw-dev
+ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --no-modify-path --default-toolchain none -y;
+ - name: Install node
+ uses: actions/setup-node@v2
+ with:
+ node-version: '14.4.0'
+ - name: Install yarn
+ run: |
+ npm install -g yarn
+ - name: Build Ledger app
+ run: |
+ make SUBSTRATE_PARSER_FULL=1
+ - name: Build/Install build js deps
+ run: |
+ export PATH=~/.cargo/bin:$PATH
+ make zemu_install
+ - name: Run zemu tests
+ run: |
+ export PATH=~/.cargo/bin:$PATH
+ make zemu_test
+
+ test_zemu_sr25519:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ with:
+ submodules: true
+ - run: sudo apt-get update -y && sudo apt-get install -y libusb-1.0.0 libudev-dev
+ - name: Install rust
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y cmake binutils-dev libcurl4-openssl-dev libiberty-dev libelf-dev libdw-dev
+ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --no-modify-path --default-toolchain none -y;
+ - name: Install node
+ uses: actions/setup-node@v2
+ with:
+ node-version: '14.4.0'
+ - name: Install yarn
+ run: |
+ npm install -g yarn
+ - name: Build Ledger app
+ run: |
+ make clean_build && SUBSTRATE_PARSER_FULL=1 SUPPORT_SR25519=1 make buildS
+ - name: Build/Install build js deps
+ run: |
+ export PATH=~/.cargo/bin:$PATH
+ make zemu_install
+ - name: Run zemu tests for sr25519
+ run: |
+ export PATH=~/.cargo/bin:$PATH
+ cd tests_zemu && yarn testSR25519
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f633842
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,76 @@
+# Created by .ignore support plugin (hsz.mobi)
+### C template
+# Prerequisites
+*.d
+
+# Object files
+*.o
+*.ko
+*.obj
+*.elf
+
+# Linker output
+*.ilk
+*.map
+*.exp
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Libraries
+*.lib
+*.a
+*.la
+*.lo
+
+# Shared objects (inc. Windows DLLs)
+*.dll
+*.so
+*.so.*
+*.dylib
+
+# Executables
+*.exe
+*.out
+*.app
+*.i*86
+*.x86_64
+*.hex
+
+# Debug files
+*.dSYM/
+*.su
+*.idb
+*.pdb
+
+# Kernel Module Compile Results
+*.mod*
+*.cmd
+
+##########################
+
+tests_zemu/.yarn/*
+tests_zemu/!.yarn/patches
+tests_zemu/!.yarn/releases
+tests_zemu/!.yarn/plugins
+tests_zemu/!.yarn/sdks
+tests_zemu/!.yarn/versions
+tests_zemu/.pnp.*
+
+#########################
+
+.vscode
+.idea
+
+node_modules
+fuzz/corpora
+
+!build/.gitkeep
+build/*
+cmake-build-debug
+
+tests_zemu/snapshots-tmp
+tests_zemu/yarn.lock
+tests_tools/target
+
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..a5e87aa
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,12 @@
+[submodule "deps/nanos-secure-sdk"]
+ path = deps/nanos-secure-sdk
+ url = https://github.com/LedgerHQ/nanos-secure-sdk.git
+[submodule "deps/BLAKE2"]
+ path = deps/BLAKE2
+ url = https://github.com/BLAKE2/BLAKE2
+[submodule "cmake/cmake-modules"]
+ path = cmake/cmake-modules
+ url = https://github.com/bilke/cmake-modules.git
+[submodule "deps/nanox-secure-sdk"]
+ path = deps/nanox-secure-sdk
+ url = https://github.com/LedgerHQ/nanox-secure-sdk.git
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..73f69e0
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/
diff --git a/.idea/ledger-kusama.iml b/.idea/ledger-kusama.iml
new file mode 100644
index 0000000..f08604b
--- /dev/null
+++ b/.idea/ledger-kusama.iml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..79b3c94
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..1b5d041
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..d9af925
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..954951c
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,7 @@
+{
+ "makefile.extensionOutputFolder": "./.vscode",
+ "files.associations": {
+ "crypto_helper.h": "c",
+ "inttypes.h": "c"
+ }
+}
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..a870ef8
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,171 @@
+#*******************************************************************************
+#* (c) 2020 Zondax GmbH
+#*
+#* Licensed under the Apache License, Version 2.0 (the "License");
+#* you may not use this file except in compliance with the License.
+#* You may obtain a copy of the License at
+#*
+#* http://www.apache.org/licenses/LICENSE-2.0
+#*
+#* Unless required by applicable law or agreed to in writing, software
+#* distributed under the License is distributed on an "AS IS" BASIS,
+#* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#* See the License for the specific language governing permissions and
+#* limitations under the License.
+#********************************************************************************
+cmake_minimum_required(VERSION 3.0)
+project(ledger-nodle VERSION 0.0.0)
+enable_testing()
+
+cmake_policy(SET CMP0025 NEW)
+set(CMAKE_CXX_STANDARD 11)
+
+option(ENABLE_FUZZING "Build with fuzzing instrumentation and build fuzz targets" OFF)
+option(ENABLE_COVERAGE "Build with source code coverage instrumentation" OFF)
+option(ENABLE_SANITIZERS "Build with ASAN and UBSAN" OFF)
+
+string(APPEND CMAKE_C_FLAGS " -fno-omit-frame-pointer -g")
+string(APPEND CMAKE_CXX_FLAGS " -fno-omit-frame-pointer -g")
+string(APPEND CMAKE_LINKER_FLAGS " -fno-omit-frame-pointer -g")
+
+add_definitions(-DAPP_STANDARD)
+add_definitions(-DSUBSTRATE_PARSER_FULL)
+
+if(ENABLE_FUZZING)
+ add_definitions(-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION=1)
+ SET(ENABLE_SANITIZERS ON CACHE BOOL "Sanitizer automatically enabled" FORCE)
+ SET(CMAKE_BUILD_TYPE Debug)
+
+ if (DEFINED ENV{FUZZ_LOGGING})
+ add_definitions(-DFUZZING_LOGGING)
+ message(FATAL_ERROR "Fuzz logging enabled")
+ endif()
+
+ set(CMAKE_CXX_CLANG_TIDY clang-tidy -checks=-*,bugprone-*,cert-*,clang-analyzer-*,-cert-err58-cpp,misc-*)
+
+ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+ # require at least clang 3.2
+ if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10.0)
+ message(FATAL_ERROR "Clang version must be at least 10.0!")
+ endif()
+ else()
+ message(FATAL_ERROR
+ "You are using an unsupported compiler! Fuzzing only works with Clang 10.\n"
+ "1. Install clang-10 \n"
+ "2. Pass -DCMAKE_C_COMPILER=clang-10 -DCMAKE_CXX_COMPILER=clang++-10")
+ endif()
+
+ string(APPEND CMAKE_C_FLAGS " -fsanitize=fuzzer-no-link")
+ string(APPEND CMAKE_CXX_FLAGS " -fsanitize=fuzzer-no-link")
+ string(APPEND CMAKE_LINKER_FLAGS " -fsanitize=fuzzer-no-link")
+endif()
+
+if(ENABLE_COVERAGE)
+ string(APPEND CMAKE_C_FLAGS " -fprofile-instr-generate -fcoverage-mapping")
+ string(APPEND CMAKE_CXX_FLAGS " -fprofile-instr-generate -fcoverage-mapping")
+ string(APPEND CMAKE_LINKER_FLAGS " -fprofile-instr-generate -fcoverage-mapping")
+endif()
+
+if(ENABLE_SANITIZERS)
+ string(APPEND CMAKE_C_FLAGS " -fsanitize=address,undefined -fsanitize-recover=address,undefined")
+ string(APPEND CMAKE_CXX_FLAGS " -fsanitize=address,undefined -fsanitize-recover=address,undefined")
+ string(APPEND CMAKE_LINKER_FLAGS " -fsanitize=address,undefined -fsanitize-recover=address,undefined")
+endif()
+
+include(cmake/conan/CMakeLists.txt)
+add_subdirectory(cmake/gtest)
+
+set (RETRIEVE_MAJOR_CMD
+ "cat ${CMAKE_CURRENT_SOURCE_DIR}/app/Makefile.version | grep APPVERSION_M | cut -b 14- | tr -d '\n'"
+)
+set (RETRIEVE_MINOR_CMD
+ "cat ${CMAKE_CURRENT_SOURCE_DIR}/app/Makefile.version | grep APPVERSION_N | cut -b 14- | tr -d '\n'"
+)
+execute_process(
+ COMMAND bash "-c" ${RETRIEVE_MAJOR_CMD}
+ RESULT_VARIABLE MAJOR_RESULT
+ OUTPUT_VARIABLE MAJOR_VERSION
+)
+execute_process(
+ COMMAND bash "-c" ${RETRIEVE_MINOR_CMD}
+ RESULT_VARIABLE MINOR_RESULT
+ OUTPUT_VARIABLE MINOR_VERSION
+)
+
+message(STATUS "LEDGER_MAJOR_VERSION [${MAJOR_RESULT}]: ${MAJOR_VERSION}" )
+message(STATUS "LEDGER_MINOR_VERSION [${MINOR_RESULT}]: ${MINOR_VERSION}" )
+
+add_definitions(
+ -DLEDGER_MAJOR_VERSION=${MAJOR_VERSION}
+ -DLEDGER_MINOR_VERSION=${MINOR_VERSION}
+)
+
+##############################################################
+##############################################################
+# static libs
+file(GLOB_RECURSE LIB_SRC
+ ${CMAKE_CURRENT_SOURCE_DIR}/deps/BLAKE2/ref/blake2b-ref.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/deps/ledger-zxlib/src/app_mode.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/deps/ledger-zxlib/src/base58.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/deps/ledger-zxlib/src/bignum.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/deps/ledger-zxlib/src/hexutils.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/deps/ledger-zxlib/src/zxmacros.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/deps/ledger-zxlib/src/zbuffer.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/deps/ledger-zxlib/src/zxformat.c
+ ####
+ ${CMAKE_CURRENT_SOURCE_DIR}/app/src/crypto_helper.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/app/src/parser.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/app/src/parser_impl.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/app/src/parser_txdef.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/app/src/substrate*.c
+ )
+
+add_library(app_lib STATIC ${LIB_SRC})
+target_include_directories(app_lib PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/deps/BLAKE2/ref
+ ${CMAKE_CURRENT_SOURCE_DIR}/deps/ledger-zxlib/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/app/src
+ ${CMAKE_CURRENT_SOURCE_DIR}/app/src/lib
+ ${CMAKE_CURRENT_SOURCE_DIR}/app/src/common
+ )
+
+##############################################################
+##############################################################
+# Tests
+file(GLOB_RECURSE TESTS_SRC
+ ${CMAKE_CURRENT_SOURCE_DIR}/tests/*.cpp)
+
+add_executable(unittests ${TESTS_SRC})
+target_include_directories(unittests PRIVATE
+ ${gtest_SOURCE_DIR}/include
+ ${gmock_SOURCE_DIR}/include
+ ${CONAN_INCLUDE_DIRS_FMT}
+ ${CONAN_INCLUDE_DIRS_JSONCPP}
+ ${CMAKE_CURRENT_SOURCE_DIR}/app/src
+ ${CMAKE_CURRENT_SOURCE_DIR}/app/src/lib
+ )
+
+target_link_libraries(unittests PRIVATE
+ gtest_main
+ app_lib
+ CONAN_PKG::fmt
+ CONAN_PKG::jsoncpp)
+
+add_compile_definitions(TESTVECTORS_DIR="${CMAKE_CURRENT_SOURCE_DIR}/tests/")
+add_test(unittests ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/unittests)
+set_tests_properties(unittests PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests)
+
+##############################################################
+##############################################################
+# Fuzz Targets
+if(ENABLE_FUZZING)
+ set(FUZZ_TARGETS
+ parser_parse
+ )
+
+ foreach(target ${FUZZ_TARGETS})
+ add_executable(fuzz-${target} ${CMAKE_CURRENT_SOURCE_DIR}/fuzz/${target}.cpp)
+ target_link_libraries(fuzz-${target} PRIVATE app_lib)
+ target_link_options(fuzz-${target} PRIVATE "-fsanitize=fuzzer")
+ endforeach()
+endif()
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..0fa613e
--- /dev/null
+++ b/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 2018-2020 Zondax GmbH
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..4fc6f96
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,53 @@
+#*******************************************************************************
+#* (c) 2019 Zondax GmbH
+#*
+#* Licensed under the Apache License, Version 2.0 (the "License");
+#* you may not use this file except in compliance with the License.
+#* You may obtain a copy of the License at
+#*
+#* http://www.apache.org/licenses/LICENSE-2.0
+#*
+#* Unless required by applicable law or agreed to in writing, software
+#* distributed under the License is distributed on an "AS IS" BASIS,
+#* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#* See the License for the specific language governing permissions and
+#* limitations under the License.
+#********************************************************************************
+
+# We use BOLOS_SDK to determine the development environment that is being used
+# BOLOS_SDK IS DEFINED We use the plain Makefile for Ledger
+# BOLOS_SDK NOT DEFINED We use a containerized build approach
+
+#TESTS_JS_PACKAGE = "@zondax/ledger-polkadot"
+#TESTS_JS_DIR = $(CURDIR)/../ledger-polkadot-js
+
+ifeq ($(BOLOS_SDK),)
+# In this case, there is not predefined SDK and we run dockerized
+# When not using the SDK, we override and build the XL complete app
+
+SUBSTRATE_PARSER_FULL ?= 1
+include $(CURDIR)/deps/ledger-zxlib/dockerized_build.mk
+
+else
+default:
+ $(MAKE) -C app
+%:
+ $(info "Calling app Makefile for target $@")
+ COIN=$(COIN) $(MAKE) -C app $@
+endif
+
+tests_tools_build:
+ cd tests_tools/neon && yarn install
+
+tests_tools_test: tests_tools_build
+ cd tests_tools/neon && yarn test
+
+zemu_install: tests_tools_build
+
+test_all:
+ make zemu_install
+ # test sr25519
+ make clean_build && SUBSTRATE_PARSER_FULL=1 SUPPORT_SR25519=1 make buildS
+ cd tests_zemu && yarn testSR25519
+ make clean_build && SUBSTRATE_PARSER_FULL=1 make
+ make zemu_test
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..1975006
--- /dev/null
+++ b/README.md
@@ -0,0 +1,385 @@
+# Ledger Nodle App
+[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
+[![CircleCI](https://circleci.com/gh/Zondax/ledger-nodle.svg?style=shield)](https://circleci.com/gh/Zondax/ledger-nodle)
+
+-------------------
+
+![zondax](docs/zondax.jpg)
+
+_Please visit our website at [zondax.ch](zondax.ch)_
+
+------------------
+This project contains the Nodle app (https://nodle.network/) for Ledger Nano S and X.
+
+- Ledger Nano S/X BOLOS app
+- Specs / Documentation
+- C++ unit tests
+- Zemu tests
+
+For more information: [How to build](docs/build.md)
+
+## ATTENTION
+
+Please:
+
+- **Do not use in production**
+- **Do not use a Ledger device with funds for development purposes.**
+- **Have a separate and marked device that is used ONLY for development and testing**
+
+# Nodle 3.52.x
+
+## System
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|fill_block | | :white_check_mark: | :white_check_mark: | `Perbill` _ratio
|
+|remark | | :white_check_mark: | :white_check_mark: | `Bytes` _remark
|
+|set_heap_pages | | :white_check_mark: | :white_check_mark: | `u64` pages
|
+|set_code | | :white_check_mark: | :white_check_mark: | `Bytes` code
|
+|set_code_without_checks | | :white_check_mark: | :white_check_mark: | `Bytes` code
|
+|set_changes_trie_config | | | | `Option` changes_trie_config
|
+|set_storage | | | | `Vec` items
|
+|kill_storage | | | | `Vec` keys
|
+|kill_prefix | | | | `Key` prefix
`u32` _subkeys
|
+
+## Timestamp
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|set | | :white_check_mark: | | `Compact` now
|
+
+## Indices
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|claim | | :white_check_mark: | | `AccountIndex` index
|
+|transfer | | :white_check_mark: | | `AccountId` new
`AccountIndex` index
|
+|free | | :white_check_mark: | | `AccountIndex` index
|
+|force_transfer | | :white_check_mark: | | `AccountId` new
`AccountIndex` index
`bool` freeze
|
+|freeze | | :white_check_mark: | | `AccountIndex` index
|
+
+## Balances
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|transfer | :white_check_mark: | :white_check_mark: | :white_check_mark: | `LookupSource` dest
`Compact` value
|
+|set_balance | | :white_check_mark: | :white_check_mark: | `LookupSource` who
`Compact` new_free
`Compact` new_reserved
|
+|force_transfer | | :white_check_mark: | :white_check_mark: | `LookupSource` source
`LookupSource` dest
`Compact` value
|
+|transfer_keep_alive | :white_check_mark: | :white_check_mark: | :white_check_mark: | `LookupSource` dest
`Compact` value
|
+
+## TransactionPayment
+
+Empty
+
+## RandomnessCollectiveFlip
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+
+## Babe
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|report_equivocation | | | | `BabeEquivocationProof` equivocation_proof
`KeyOwnerProof` key_owner_proof
|
+|report_equivocation_unsigned | | | | `BabeEquivocationProof` equivocation_proof
`KeyOwnerProof` key_owner_proof
|
+
+## Grandpa
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|report_equivocation | | | | `GrandpaEquivocationProof` equivocation_proof
`KeyOwnerProof` key_owner_proof
|
+|report_equivocation_unsigned | | | | `GrandpaEquivocationProof` equivocation_proof
`KeyOwnerProof` key_owner_proof
|
+|note_stalled | | :white_check_mark: | | `BlockNumber` delay
`BlockNumber` best_finalized_block_number
|
+
+## Authorship
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|set_uncles | | | | `Vec` new_uncles
|
+
+## ImOnline
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|heartbeat | | | | `Heartbeat` heartbeat
`Signature` _signature
|
+
+## Offences
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+
+## ValidatorsSet
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|add_member | | :white_check_mark: | | `AccountId` who
|
+|remove_member | | :white_check_mark: | | `AccountId` who
|
+|swap_member | | :white_check_mark: | | `AccountId` remove
`AccountId` add
|
+|reset_members | | :white_check_mark: | | `Vec` members
|
+|change_key | | :white_check_mark: | | `AccountId` new
|
+|set_prime | | :white_check_mark: | | `AccountId` who
|
+|clear_prime | | :white_check_mark: | | |
+
+## Session
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|set_keys | :white_check_mark: | | | `Keys` keys
`Bytes` proof
|
+|purge_keys | :white_check_mark: | :white_check_mark: | | |
+
+## Historical
+
+Empty
+
+## AuthorityDiscovery
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+
+## TechnicalCommittee
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|set_members | | :white_check_mark: | | `Vec` new_members
`Option` prime
`MemberCount` old_count
|
+|execute | | | | `Proposal` proposal
`Compact` length_bound
|
+|propose | | | | `Compact` threshold
`Proposal` proposal
`Compact` length_bound
|
+|vote | | :white_check_mark: | | `Hash` proposal
`Compact` index
`bool` approve
|
+|close | | :white_check_mark: | | `Hash` proposal_hash
`Compact` index
`Compact` proposal_weight_bound
`Compact` length_bound
|
+|disapprove_proposal | | :white_check_mark: | | `Hash` proposal_hash
|
+
+## TechnicalMembership
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|add_member | | :white_check_mark: | | `AccountId` who
|
+|remove_member | | :white_check_mark: | | `AccountId` who
|
+|swap_member | | :white_check_mark: | | `AccountId` remove
`AccountId` add
|
+|reset_members | | :white_check_mark: | | `Vec` members
|
+|change_key | | :white_check_mark: | | `AccountId` new
|
+|set_prime | | :white_check_mark: | | `AccountId` who
|
+|clear_prime | | :white_check_mark: | | |
+
+## FinancialCommittee
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|set_members | | :white_check_mark: | | `Vec` new_members
`Option` prime
`MemberCount` old_count
|
+|execute | | :white_check_mark: | | `Proposal` proposal
`Compact` length_bound
|
+|propose | | :white_check_mark: | | `Compact` threshold
`Proposal` proposal
`Compact` length_bound
|
+|vote | | :white_check_mark: | | `Hash` proposal
`Compact` index
`bool` approve
|
+|close | | :white_check_mark: | | `Hash` proposal_hash
`Compact` index
`Compact` proposal_weight_bound
`Compact` length_bound
|
+|disapprove_proposal | | :white_check_mark: | | `Hash` proposal_hash
|
+
+## FinancialMembership
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|add_member | | :white_check_mark: | | `AccountId` who
|
+|remove_member | | :white_check_mark: | | `AccountId` who
|
+|swap_member | | :white_check_mark: | | `AccountId` remove
`AccountId` add
|
+|reset_members | | :white_check_mark: | | `Vec` members
|
+|change_key | | :white_check_mark: | | `AccountId` new
|
+|set_prime | | :white_check_mark: | | `AccountId` who
|
+|clear_prime | | :white_check_mark: | | |
+
+## RootCommittee
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|set_members | | :white_check_mark: | | `Vec` new_members
`Option` prime
`MemberCount` old_count
|
+|execute | | :white_check_mark: | | `Proposal` proposal
`Compact` length_bound
|
+|propose | | :white_check_mark: | | `Compact` threshold
`Proposal` proposal
`Compact` length_bound
|
+|vote | | :white_check_mark: | | `Hash` proposal
`Compact` index
`bool` approve
|
+|close | | :white_check_mark: | | `Hash` proposal_hash
`Compact` index
`Compact` proposal_weight_bound
`Compact` length_bound
|
+|disapprove_proposal | | :white_check_mark: | | `Hash` proposal_hash
|
+
+## RootMembership
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|add_member | | :white_check_mark: | | `AccountId` who
|
+|remove_member | | :white_check_mark: | | `AccountId` who
|
+|swap_member | | :white_check_mark: | | `AccountId` remove
`AccountId` add
|
+|reset_members | | :white_check_mark: | | `Vec` members
|
+|change_key | | :white_check_mark: | | `AccountId` new
|
+|set_prime | | :white_check_mark: | | `AccountId` who
|
+|clear_prime | | :white_check_mark: | | |
+
+## Scheduler
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|schedule | | | | `BlockNumber` when
`Option` maybe_periodic
`Priority` priority
`Call` call
|
+|cancel | | | | `BlockNumber` when
`u32` index
|
+|schedule_named | | | | `Bytes` id
`BlockNumber` when
`Option` maybe_periodic
`Priority` priority
`Call` call
|
+|cancel_named | | | | `Bytes` id
|
+|schedule_after | | | | `BlockNumber` after
`Option` maybe_periodic
`Priority` priority
`Call` call
|
+|schedule_named_after | | | | `Bytes` id
`BlockNumber` after
`Option` maybe_periodic
`Priority` priority
`Call` call
|
+
+## Amendments
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|propose | | | | `Amendment` amendment
|
+|veto | | :white_check_mark: | | `u64` amendment_id
|
+
+## Mandate
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|apply | | :white_check_mark: | | `Call` call
|
+
+## CompanyReserve
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|spend | | :white_check_mark: | | `AccountId` to
`BalanceOf` amount
|
+|tip | | :white_check_mark: | | `BalanceOf` amount
|
+|apply_as | | :white_check_mark: | | `Call` call
|
+
+## InternationalReserve
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|spend | | :white_check_mark: | | `AccountId` to
`BalanceOf` amount
|
+|tip | | :white_check_mark: | | `BalanceOf` amount
|
+|apply_as | | :white_check_mark: | | `Call` call
|
+
+## UsaReserve
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|spend | | :white_check_mark: | | `AccountId` to
`BalanceOf` amount
|
+|tip | | :white_check_mark: | | `BalanceOf` amount
|
+|apply_as | | :white_check_mark: | | `Call` call
|
+
+## Vesting
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|claim | | :white_check_mark: | | |
+|add_vesting_schedule | | | | `LookupSource` dest
`VestingScheduleOf` schedule
|
+|cancel_all_vesting_schedules | | :white_check_mark: | | `LookupSource` who
`LookupSource` funds_collector
`bool` limit_to_free_balance
|
+
+## Identity
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|add_registrar | | :white_check_mark: | | `AccountId` account
|
+|set_identity | | | | `IdentityInfo` info
|
+|set_subs | | | | `Vec<(AccountId,Data)>` subs
|
+|clear_identity | | :white_check_mark: | | |
+|request_judgement | | :white_check_mark: | | `Compact` reg_index
`Compact` max_fee
|
+|cancel_request | | :white_check_mark: | | `RegistrarIndex` reg_index
|
+|set_fee | | :white_check_mark: | | `Compact` index
`Compact` fee
|
+|set_account_id | | :white_check_mark: | | `Compact` index
`AccountId` new
|
+|set_fields | | | | `Compact` index
`IdentityFields` fields
|
+|provide_judgement | | | | `Compact` reg_index
`LookupSource` target
`IdentityJudgement` judgement
|
+|kill_identity | | :white_check_mark: | | `LookupSource` target
|
+|add_sub | | | | `LookupSource` sub
`Data` data
|
+|rename_sub | | | | `LookupSource` sub
`Data` data
|
+|remove_sub | | :white_check_mark: | | `LookupSource` sub
|
+|quit_sub | | :white_check_mark: | | |
+
+## Recovery
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|as_recovered | | | | `AccountId` account
`Call` call
|
+|set_recovered | | :white_check_mark: | | `AccountId` lost
`AccountId` rescuer
|
+|create_recovery | | | | `Vec` friends
`u16` threshold
`BlockNumber` delay_period
|
+|initiate_recovery | | :white_check_mark: | | `AccountId` account
|
+|vouch_recovery | | :white_check_mark: | | `AccountId` lost
`AccountId` rescuer
|
+|claim_recovery | | :white_check_mark: | | `AccountId` account
|
+|close_recovery | | :white_check_mark: | | `AccountId` rescuer
|
+|remove_recovery | | :white_check_mark: | | |
+|cancel_recovered | | :white_check_mark: | | `AccountId` account
|
+
+## Utility
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|batch | :white_check_mark: | :white_check_mark: | | `Vec` calls
|
+|as_derivative | | | | `u16` index
`Call` call
|
+|batch_all | :white_check_mark: | :white_check_mark: | | `Vec` calls
|
+
+## Proxy
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|proxy | | :white_check_mark: | :white_check_mark: | `AccountId` real
`Option` force_proxy_type
`Call` call
|
+|add_proxy | | :white_check_mark: | | `AccountId` delegate
`ProxyType` proxy_type
`BlockNumber` delay
|
+|remove_proxy | | :white_check_mark: | | `AccountId` delegate
`ProxyType` proxy_type
`BlockNumber` delay
|
+|remove_proxies | | :white_check_mark: | | |
+|anonymous | | :white_check_mark: | | `ProxyType` proxy_type
`BlockNumber` delay
`u16` index
|
+|kill_anonymous | | :white_check_mark: | | `AccountId` spawner
`ProxyType` proxy_type
`u16` index
`Compact` height
`Compact` ext_index
|
+|announce | | :white_check_mark: | | `AccountId` real
`CallHashOf` call_hash
|
+|remove_announcement | | :white_check_mark: | | `AccountId` real
`CallHashOf` call_hash
|
+|reject_announcement | | :white_check_mark: | | `AccountId` delegate
`CallHashOf` call_hash
|
+|proxy_announced | | :white_check_mark: | | `AccountId` delegate
`AccountId` real
`Option` force_proxy_type
`Call` call
|
+
+## Multisig
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|as_multi_threshold_1 | | :white_check_mark: | :white_check_mark: | `Vec` other_signatories
`Call` call
|
+|as_multi | | :white_check_mark: | :white_check_mark: | `u16` threshold
`Vec` other_signatories
`Option` maybe_timepoint
`OpaqueCall` call
`bool` store_call
`Weight` max_weight
|
+|approve_as_multi | | :white_check_mark: | :white_check_mark: | `u16` threshold
`Vec` other_signatories
`Option` maybe_timepoint
`[u8;32]` call_hash
`Weight` max_weight
|
+|cancel_as_multi | | :white_check_mark: | :white_check_mark: | `u16` threshold
`Vec` other_signatories
`Timepoint` timepoint
`[u8;32]` call_hash
|
+
+## Contracts
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|update_schedule | | | | `Schedule` schedule
|
+|call | | :white_check_mark: | | `LookupSource` dest
`Compact` value
`Compact` gas_limit
`Bytes` data
|
+|instantiate_with_code | | :white_check_mark: | | `Compact` endowment
`Compact` gas_limit
`Bytes` code
`Bytes` data
`Bytes` salt
|
+|instantiate | | | | `Compact` endowment
`Compact` gas_limit
`CodeHash` code_hash
`Bytes` data
`Bytes` salt
|
+|claim_surcharge | | :white_check_mark: | | `AccountId` dest
`Option` aux_sender
|
+
+## PkiTcr
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|apply | | :white_check_mark: | | `Bytes` metadata
`BalanceOf` deposit
|
+|counter | | :white_check_mark: | | `AccountId` member
`BalanceOf` deposit
|
+|vote | | :white_check_mark: | | `AccountId` member
`bool` supporting
`BalanceOf` deposit
|
+|challenge | | :white_check_mark: | | `AccountId` member
`BalanceOf` deposit
|
+
+## PkiRootOfTrust
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|book_slot | | | | `CertificateId` certificate_id
|
+|renew_slot | | | | `CertificateId` certificate_id
|
+|revoke_slot | | | | `CertificateId` certificate_id
|
+|revoke_child | | | | `CertificateId` root
`CertificateId` child
|
+
+## EmergencyShutdown
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|toggle | | :white_check_mark: | | |
+
+## Allocations
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|allocate | | :white_check_mark: | | `AccountId` to
`BalanceOf` amount
`Bytes` proof
|
+
+## AllocationsOracles
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|add_member | | :white_check_mark: | | `AccountId` who
|
+|remove_member | | :white_check_mark: | | `AccountId` who
|
+|swap_member | | :white_check_mark: | | `AccountId` remove
`AccountId` add
|
+|reset_members | | :white_check_mark: | | `Vec` members
|
+|change_key | | :white_check_mark: | | `AccountId` new
|
+|set_prime | | :white_check_mark: | | `AccountId` who
|
+|clear_prime | | :white_check_mark: | | |
+
+## Poa
+
+Empty
+
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..760c384
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1,52 @@
+# Prerequisites
+*.d
+
+# Compiled Object files
+*.slo
+*.lo
+*.o
+*.obj
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Compiled Dynamic libraries
+*.so
+*.dylib
+*.dll
+
+# Fortran module files
+*.mod
+*.smod
+
+# Compiled Static libraries
+*.lai
+*.la
+*.a
+*.lib
+
+# Executables
+*.exe
+*.out
+*.app
+
+# OS related files
+.DS_Store
+
+# Others
+cmake-build-debug/
+\.idea/workspace\.xml
+\.idea/
+
+glyphs/glyphs\.h
+glyphs/glyphs\.c
+obj/
+bin/
+debug/
+bin/app.sha256
+bin/app.apdu
+
+\output/app.*
+pkg/zxtool.sh
+pkg/installer_?.sh
diff --git a/app/LICENSE b/app/LICENSE
new file mode 100644
index 0000000..996fc28
--- /dev/null
+++ b/app/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 2018-2021 Zondax GmbH
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/app/Makefile b/app/Makefile
new file mode 100755
index 0000000..c668fca
--- /dev/null
+++ b/app/Makefile
@@ -0,0 +1,247 @@
+#*******************************************************************************
+# Ledger App
+# (c) 2018-2021 Zondax GmbH
+# (c) 2017 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.
+#*******************************************************************************
+
+ifeq ($(BOLOS_SDK),)
+$(error BOLOS_SDK is not set)
+endif
+
+MY_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
+
+all: bin/app.elf
+ @echo "#!/usr/bin/env bash" > $(OUTPUT_INSTALLER)
+ @echo "APPNAME=\"${APPNAME}\"" >> $(OUTPUT_INSTALLER)
+ @echo "APPVERSION=\"${APPVERSION}\"" >> $(OUTPUT_INSTALLER)
+ @echo "APPPATH=\""${APPPATH}"\"" >> $(OUTPUT_INSTALLER)
+ @echo "LOAD_PARAMS=\"${COMMON_LOAD_PARAMS}\"" >> $(OUTPUT_INSTALLER)
+ @echo "DELETE_PARAMS=\"${COMMON_DELETE_PARAMS}\"" >> $(OUTPUT_INSTALLER)
+ @echo "APPHEX=\"" >> $(OUTPUT_INSTALLER)
+ @cat $(CURDIR)/bin/app.hex >> $(OUTPUT_INSTALLER)
+ @echo "\"" >> $(OUTPUT_INSTALLER)
+ @cat $(CURDIR)/../deps/ledger-zxlib/scripts/template.sh >> $(OUTPUT_INSTALLER)
+ @chmod +x $(OUTPUT_INSTALLER)
+ @cp $(CURDIR)/bin/* $(CURDIR)/output
+ @cp $(CURDIR)/output/app.elf ${OUTPUT_ELF}
+ @rm $(CURDIR)/output/app.elf
+
+include $(BOLOS_SDK)/Makefile.defines
+
+DEFINES += APP_SECRET_MODE_ENABLED
+
+$(info ************ TARGET_NAME = [$(TARGET_NAME)])
+
+ifeq ($(APP_TESTING),1)
+DEFINES += APP_TESTING
+DEFINES += ZEMU_LOGGING
+$(info ************ LOGGING ENABLED ************)
+endif
+
+ifeq ($(SUPPORT_SR25519),1)
+DEFINES += SUPPORT_SR25519
+OUTPUT_ELF ?= $(CURDIR)/output/app_sr25519.elf
+$(info ************ SR25519 ENABLED ************)
+endif
+
+ifeq ($(SUBSTRATE_PARSER_FULL),1)
+DEFINES += SUBSTRATE_PARSER_FULL
+$(info ************ FULL PARSER ENABLED ************)
+endif
+
+ifndef COIN
+COIN=KSM
+endif
+
+include $(CURDIR)/Makefile.version
+
+$(info COIN = [$(COIN)])
+
+ifeq ($(COIN),KSM)
+# Main app configuration
+DEFINES += APP_STANDARD
+ifeq ($(TARGET_NAME),TARGET_NANOX)
+DEFINES += SUBSTRATE_PARSER_FULL
+endif
+APPNAME = "Nodle"
+APPPATH = "44'/434'" --path "44'/354'"
+
+else ifeq ($(COIN),KSM_XL)
+# XL app configuration
+DEFINES += APP_STANDARD SUBSTRATE_PARSER_FULL
+APPNAME = "Nodle XL"
+APPPATH = "44'/434'" --path "44'/354'"
+
+else
+define error_message
+
+
+COIN value not supported: [$(COIN)]
+
+
+endef
+$(error "$(error_message)")
+endif
+
+APP_LOAD_PARAMS = --appFlags 0x200 --delete $(COMMON_LOAD_PARAMS) --path $(APPPATH)
+
+ifeq ($(TARGET_NAME),TARGET_NANOS)
+APP_STACK_SIZE:=3472
+ICONNAME:=$(CURDIR)/nanos_icon.gif
+OUTPUT_ELF ?= $(CURDIR)/output/app_s.elf
+OUTPUT_INSTALLER := $(CURDIR)/pkg/installer_s.sh
+endif
+
+ifeq ($(TARGET_NAME),TARGET_NANOX)
+SCRIPT_LD:=$(CURDIR)/script_x.ld
+ICONNAME:=$(CURDIR)/nanox_icon.gif
+OUTPUT_ELF ?= $(CURDIR)/output/app_x.elf
+OUTPUT_INSTALLER:= $(CURDIR)/pkg/installer_x.sh
+endif
+
+$(info ICONNAME = [$(ICONNAME)])
+
+ifndef ICONNAME
+$(error ICONNAME is not set)
+endif
+
+############
+# Platform
+
+DEFINES += UNUSED\(x\)=\(void\)x
+DEFINES += PRINTF\(...\)=
+
+APPVERSION=$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)
+DEFINES += APPVERSION=\"$(APPVERSION)\"
+
+DEFINES += OS_IO_SEPROXYHAL
+DEFINES += HAVE_BAGL HAVE_SPRINTF
+DEFINES += HAVE_IO_USB HAVE_L4_USBLIB IO_USB_MAX_ENDPOINTS=7 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 += USB_SEGMENT_SIZE=64
+DEFINES += HAVE_BOLOS_APP_STACK_CANARY
+
+DEFINES += HAVE_WEBUSB WEBUSB_URL_SIZE_B=0 WEBUSB_URL=""
+
+ifeq ($(TARGET_NAME),TARGET_NANOX)
+DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=300
+
+DEFINES += HAVE_GLO096
+DEFINES += HAVE_BAGL 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
+
+DEFINES += HAVE_UX_FLOW
+
+DEFINES += HAVE_BLE
+DEFINES += HAVE_BLE_APDU BLE_COMMAND_TIMEOUT_MS=2000
+
+SDK_SOURCE_PATH += lib_blewbxx lib_blewbxx_impl
+else
+# Assume Nano S
+DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=128
+endif
+
+# X specific
+
+#Feature temporarily disabled
+DEFINES += LEDGER_SPECIFIC
+
+# Compiler, assembler, and linker
+
+ifneq ($(BOLOS_ENV),)
+$(info BOLOS_ENV is $(BOLOS_ENV))
+CLANGPATH := /usr/bin/
+GCCPATH := /usr/bin/
+else
+$(info BOLOS_ENV is not set: falling back to CLANGPATH and GCCPATH)
+endif
+
+ifeq ($(CLANGPATH),)
+$(info CLANGPATH is not set: clang will be used from PATH)
+endif
+
+ifeq ($(GCCPATH),)
+$(info GCCPATH is not set: arm-none-eabi-* will be used from PATH)
+endif
+
+#########################
+
+CC := $(CLANGPATH)clang
+CFLAGS += -O3 -Os -Wno-unknown-pragmas -Wno-unused-parameter
+
+AS := $(GCCPATH)arm-none-eabi-gcc
+AFLAGS +=
+
+LD := $(GCCPATH)arm-none-eabi-gcc
+LDFLAGS += -O3 -Os
+LDFLAGS += -z muldefs
+LDLIBS += -lm -lgcc -lc
+LDLIBS += -Lrust/target/thumbv6m-none-eabi/release -lrslib
+
+##########################
+GLYPH_SRC_DIR = glyphs
+INCLUDES_PATH += $(MY_DIR)/glyphs
+include $(BOLOS_SDK)/Makefile.glyphs
+
+APP_SOURCE_PATH += $(MY_DIR)/src
+APP_SOURCE_PATH += $(MY_DIR)/glyphs
+APP_SOURCE_PATH += $(MY_DIR)/rust/include
+APP_SOURCE_PATH += $(MY_DIR)/../deps/ledger-zxlib/include
+APP_SOURCE_PATH += $(MY_DIR)/../deps/ledger-zxlib/src
+APP_SOURCE_PATH += $(MY_DIR)/../deps/ledger-zxlib/app/common
+
+SDK_SOURCE_PATH += lib_stusb lib_stusb_impl
+SDK_SOURCE_PATH += lib_ux
+
+.PHONY: rust
+rust:
+ cd rust && CARGO_HOME="$(CURDIR)/rust/.cargo" cargo build --target thumbv6m-none-eabi --release
+
+# Before linking, we need to be sure rust lib is there
+bin/app.elf: rust
+
+.PHONY: rust_clean
+rust_clean:
+ cd rust && CARGO_HOME="$(CURDIR)/rust/.cargo" cargo clean
+
+clean: rust_clean
+
+# load, delete and listvariants are provided to comply with Ledger requirements
+.PHONY: load
+load:
+ python -m ledgerblue.loadApp $(APP_LOAD_PARAMS)
+
+.PHONY: delete
+delete:
+ python -m ledgerblue.deleteApp $(COMMON_DELETE_PARAMS)
+
+# Import generic rules from the SDK
+include $(BOLOS_SDK)/Makefile.rules
+
+#add dependency on custom makefile filename
+dep/%.d: %.c Makefile
+
+.PHONY: listvariants
+listvariants:
+ifeq ($(TARGET_NAME),TARGET_NANOS)
+ @echo VARIANTS COIN KSM KSM_XL
+else ifeq ($(TARGET_NAME),TARGET_NANOX)
+ @echo VARIANTS COIN KSM
+endif
diff --git a/app/Makefile.version b/app/Makefile.version
new file mode 100644
index 0000000..2ff1f12
--- /dev/null
+++ b/app/Makefile.version
@@ -0,0 +1,6 @@
+# This is the `transaction_version` field of `Runtime`
+APPVERSION_M=3
+# This is the `spec_version` field of `Runtime`
+APPVERSION_N=52
+# This is the patch version of this release
+APPVERSION_P=0
diff --git a/app/glyphs/icon_app.gif b/app/glyphs/icon_app.gif
new file mode 100644
index 0000000..c957142
Binary files /dev/null and b/app/glyphs/icon_app.gif differ
diff --git a/app/glyphs/icon_back.gif b/app/glyphs/icon_back.gif
new file mode 100644
index 0000000..a2a7e6d
Binary files /dev/null and b/app/glyphs/icon_back.gif differ
diff --git a/app/glyphs/icon_crossmark.gif b/app/glyphs/icon_crossmark.gif
new file mode 100644
index 0000000..2dcf9d9
Binary files /dev/null and b/app/glyphs/icon_crossmark.gif differ
diff --git a/app/glyphs/icon_dashboard.gif b/app/glyphs/icon_dashboard.gif
new file mode 100644
index 0000000..33d9b0a
Binary files /dev/null and b/app/glyphs/icon_dashboard.gif differ
diff --git a/app/glyphs/icon_eye.gif b/app/glyphs/icon_eye.gif
new file mode 100644
index 0000000..df4bb82
Binary files /dev/null and b/app/glyphs/icon_eye.gif differ
diff --git a/app/glyphs/icon_key.gif b/app/glyphs/icon_key.gif
new file mode 100644
index 0000000..1830d46
Binary files /dev/null and b/app/glyphs/icon_key.gif differ
diff --git a/app/glyphs/icon_refresh.gif b/app/glyphs/icon_refresh.gif
new file mode 100644
index 0000000..a6606de
Binary files /dev/null and b/app/glyphs/icon_refresh.gif differ
diff --git a/app/glyphs/icon_validate_14.gif b/app/glyphs/icon_validate_14.gif
new file mode 100644
index 0000000..ccb5cab
Binary files /dev/null and b/app/glyphs/icon_validate_14.gif differ
diff --git a/app/glyphs/icon_warning.gif b/app/glyphs/icon_warning.gif
new file mode 100644
index 0000000..f3037a7
Binary files /dev/null and b/app/glyphs/icon_warning.gif differ
diff --git a/app/nanos_icon.gif b/app/nanos_icon.gif
new file mode 100644
index 0000000..c957142
Binary files /dev/null and b/app/nanos_icon.gif differ
diff --git a/app/nanox_icon.gif b/app/nanox_icon.gif
new file mode 100644
index 0000000..7fa1257
Binary files /dev/null and b/app/nanox_icon.gif differ
diff --git a/app/output/.gitkeep b/app/output/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/app/pkg/.gitkeep b/app/pkg/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/app/rust/.cargo/.gitignore b/app/rust/.cargo/.gitignore
new file mode 100644
index 0000000..2249544
--- /dev/null
+++ b/app/rust/.cargo/.gitignore
@@ -0,0 +1,3 @@
+registry/
+.package-cache
+
diff --git a/app/rust/.cargo/config b/app/rust/.cargo/config
new file mode 100644
index 0000000..dbe610e
--- /dev/null
+++ b/app/rust/.cargo/config
@@ -0,0 +1,9 @@
+[build]
+
+[target.thumbv6m-none-eabi]
+rustflags = [
+ "--emit", "asm",
+ "-C", "relocation-model=ropi",
+ "-C", "link-arg=-nostartfiles",
+ "-C", "link-arg=-Tlink.ld",
+]
diff --git a/app/rust/.gitignore b/app/rust/.gitignore
new file mode 100644
index 0000000..2f7896d
--- /dev/null
+++ b/app/rust/.gitignore
@@ -0,0 +1 @@
+target/
diff --git a/app/rust/Cargo.lock b/app/rust/Cargo.lock
new file mode 100644
index 0000000..7a143ef
--- /dev/null
+++ b/app/rust/Cargo.lock
@@ -0,0 +1,507 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "aho-corasick"
+version = "0.7.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "arrayref"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
+
+[[package]]
+name = "arrayvec"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
+
+[[package]]
+name = "atty"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
+dependencies = [
+ "hermit-abi",
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "block-buffer"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
+dependencies = [
+ "block-padding",
+ "byte-tools",
+ "byteorder",
+ "generic-array 0.12.4",
+]
+
+[[package]]
+name = "block-padding"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
+dependencies = [
+ "byte-tools",
+]
+
+[[package]]
+name = "byte-tools"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
+
+[[package]]
+name = "byteorder"
+version = "1.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "curve25519-dalek"
+version = "2.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "434e1720189a637d44fe464f4df1e6eb900b4835255b14354497c78af37d9bb8"
+dependencies = [
+ "byteorder",
+ "digest 0.8.1",
+ "rand_core",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
+name = "curve25519-dalek"
+version = "3.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "639891fde0dbea823fc3d798a0fdf9d2f9440a42d64a78ab3488b0ca025117b3"
+dependencies = [
+ "byteorder",
+ "digest 0.9.0",
+ "rand_core",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
+name = "digest"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
+dependencies = [
+ "generic-array 0.12.4",
+]
+
+[[package]]
+name = "digest"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
+dependencies = [
+ "generic-array 0.14.4",
+]
+
+[[package]]
+name = "env_logger"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
+dependencies = [
+ "atty",
+ "humantime",
+ "log",
+ "regex",
+ "termcolor",
+]
+
+[[package]]
+name = "fake-simd"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
+
+[[package]]
+name = "generic-array"
+version = "0.12.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
+dependencies = [
+ "typenum",
+]
+
+[[package]]
+name = "generic-array"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.1.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi",
+]
+
+[[package]]
+name = "hermit-abi"
+version = "0.1.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "hex"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
+
+[[package]]
+name = "hex-literal"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "961de220ec9a91af2e1e5bd80d02109155695e516771762381ef8581317066e0"
+dependencies = [
+ "hex-literal-impl",
+ "proc-macro-hack",
+]
+
+[[package]]
+name = "hex-literal-impl"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "853f769599eb31de176303197b7ba4973299c38c7a7604a6bc88c3eef05b9b46"
+dependencies = [
+ "proc-macro-hack",
+]
+
+[[package]]
+name = "humantime"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
+dependencies = [
+ "quick-error",
+]
+
+[[package]]
+name = "keccak"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7"
+
+[[package]]
+name = "libc"
+version = "0.2.93"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41"
+
+[[package]]
+name = "log"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "memchr"
+version = "2.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
+
+[[package]]
+name = "merlin"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4e261cf0f8b3c42ded9f7d2bb59dea03aa52bc8a1cbc7482f9fc3fd1229d3b42"
+dependencies = [
+ "byteorder",
+ "keccak",
+ "rand_core",
+ "zeroize",
+]
+
+[[package]]
+name = "opaque-debug"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
+
+[[package]]
+name = "panic-halt"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "de96540e0ebde571dc55c73d60ef407c653844e6f9a1e2fdbd40c07b9252d812"
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
+
+[[package]]
+name = "proc-macro-hack"
+version = "0.5.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
+dependencies = [
+ "unicode-xid",
+]
+
+[[package]]
+name = "quick-error"
+version = "1.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
+
+[[package]]
+name = "quote"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rand"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
+dependencies = [
+ "rand_chacha",
+ "rand_core",
+ "rand_hc",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
+dependencies = [
+ "ppv-lite86",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
+
+[[package]]
+name = "rand_hc"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
+dependencies = [
+ "rand_core",
+]
+
+[[package]]
+name = "regex"
+version = "1.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "957056ecddbeba1b26965114e191d2e8589ce74db242b6ea25fc4062427a5c19"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548"
+
+[[package]]
+name = "rslib"
+version = "0.1.0"
+dependencies = [
+ "curve25519-dalek 3.1.0",
+ "env_logger",
+ "getrandom",
+ "hex",
+ "hex-literal",
+ "log",
+ "merlin",
+ "panic-halt",
+ "rand",
+ "schnorrkel",
+ "zeroize",
+]
+
+[[package]]
+name = "schnorrkel"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "021b403afe70d81eea68f6ea12f6b3c9588e5d536a94c3bf80f15e7faa267862"
+dependencies = [
+ "arrayref",
+ "arrayvec",
+ "curve25519-dalek 2.1.2",
+ "merlin",
+ "rand_core",
+ "sha2",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
+name = "sha2"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69"
+dependencies = [
+ "block-buffer",
+ "digest 0.8.1",
+ "fake-simd",
+ "opaque-debug",
+]
+
+[[package]]
+name = "subtle"
+version = "2.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2"
+
+[[package]]
+name = "syn"
+version = "1.0.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "48fe99c6bd8b1cc636890bcc071842de909d902c81ac7dab53ba33c421ab8ffb"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-xid",
+]
+
+[[package]]
+name = "synstructure"
+version = "0.12.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "unicode-xid",
+]
+
+[[package]]
+name = "termcolor"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "typenum"
+version = "1.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
+
+[[package]]
+name = "unicode-xid"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
+
+[[package]]
+name = "version_check"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
+
+[[package]]
+name = "wasi"
+version = "0.9.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "zeroize"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81a974bcdd357f0dca4d41677db03436324d45a4c9ed2d0b873a5a360ce41c36"
+dependencies = [
+ "zeroize_derive",
+]
+
+[[package]]
+name = "zeroize_derive"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3f369ddb18862aba61aa49bf31e74d29f0f162dec753063200e1dc084345d16"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
diff --git a/app/rust/Cargo.toml b/app/rust/Cargo.toml
new file mode 100644
index 0000000..0ecf51f
--- /dev/null
+++ b/app/rust/Cargo.toml
@@ -0,0 +1,47 @@
+[package]
+authors = ["Zondax GmbH "]
+name = "rslib"
+version = "0.1.0"
+edition = "2018"
+readme = "README.md"
+
+[lib]
+name = "rslib"
+crate-type = ["staticlib"]
+
+[dependencies]
+rand={ version = "0.7.3", default-features = false}
+merlin = {version = "2.0.0", default-features=false}
+zeroize = {version = "1.1.1", default-features=false}
+
+[target.'cfg(target_arch = "x86_64")'.dependencies]
+getrandom = {version="0.1.14", default-features=false}
+
+[dependencies.curve25519-dalek]
+version = "3.0.0"
+default-features = false
+features=["u32_backend"]
+
+[dependencies.schnorrkel]
+version = "0.9.1"
+default-features = false
+features=["u32_backend"]
+
+[dev-dependencies]
+hex-literal = "0.2.1"
+hex = "0.4.2"
+env_logger = "0.7.1"
+log = "0.4.8"
+
+[target.thumbv6m-none-eabi.dev-dependencies]
+panic-halt = "0.2.0"
+
+[profile.release]
+lto=false
+codegen-units = 1
+debug=true
+opt-level = "s"
+
+[profile.dev]
+panic = "abort"
+
diff --git a/app/rust/include/rslib.h b/app/rust/include/rslib.h
new file mode 100644
index 0000000..8e26766
--- /dev/null
+++ b/app/rust/include/rslib.h
@@ -0,0 +1,8 @@
+#pragma once
+
+#include
+
+void get_sr25519_sk(uint8_t *sk_ed25519_expanded);
+
+void sign_sr25519_phase1(const uint8_t *sk_ed25519_expanded, const uint8_t *pk, const uint8_t *context_ptr, uint32_t context_len, const uint8_t *msg_ptr, uint32_t msg_len, uint8_t *sig_ptr);
+void sign_sr25519_phase2(const uint8_t *sk_ed25519_expanded, const uint8_t *pk, const uint8_t *context_ptr, uint32_t context_len, const uint8_t *msg_ptr, uint32_t msg_len, uint8_t *sig_ptr);
diff --git a/app/rust/src/bolos.rs b/app/rust/src/bolos.rs
new file mode 100644
index 0000000..bbfba41
--- /dev/null
+++ b/app/rust/src/bolos.rs
@@ -0,0 +1,84 @@
+/*******************************************************************************
+* (c) 2020 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+//! Rust interfaces to Ledger SDK APIs.
+#[cfg(test)]
+use curve25519_dalek::constants::RISTRETTO_BASEPOINT_POINT;
+use curve25519_dalek::scalar::Scalar;
+#[cfg(test)]
+#[cfg(target_arch = "x86_64")]
+use getrandom::getrandom;
+use merlin::TranscriptRng;
+use rand::{CryptoRng, RngCore};
+
+extern "C" {
+ fn cx_rng(buffer: *mut u8, len: u32);
+ fn zemu_log_stack(buffer: *const u8);
+ fn check_app_canary();
+}
+
+#[cfg(not(test))]
+pub fn c_zemu_log_stack(s: &[u8]) {
+ unsafe { zemu_log_stack(s.as_ptr()) }
+}
+
+#[cfg(test)]
+pub fn c_zemu_log_stack(s: &[u8]) {}
+
+pub fn c_check_app_canary() {
+ unsafe { check_app_canary() }
+}
+
+pub struct Trng;
+
+impl RngCore for Trng {
+ fn next_u32(&mut self) -> u32 {
+ let mut out = [0; 4];
+ self.fill_bytes(&mut out);
+ u32::from_le_bytes(out)
+ }
+
+ fn next_u64(&mut self) -> u64 {
+ let mut out = [0; 8];
+ self.fill_bytes(&mut out);
+ u64::from_le_bytes(out)
+ }
+
+ #[cfg(not(target_arch = "x86_64"))]
+ fn fill_bytes(&mut self, dest: &mut [u8]) {
+ c_zemu_log_stack(b"fill_bytes\x00".as_ref());
+
+ unsafe {
+ cx_rng(dest.as_mut_ptr(), dest.len() as u32);
+ }
+ }
+
+ #[cfg(target_arch = "x86_64")]
+ #[cfg(test)]
+ fn fill_bytes(&mut self, dest: &mut [u8]) {
+ getrandom(dest);
+ }
+
+ #[cfg(target_arch = "x86_64")]
+ #[cfg(not(test))]
+ fn fill_bytes(&mut self, _dest: &mut [u8]) {}
+
+ fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> {
+ self.fill_bytes(dest);
+ Ok(())
+ }
+}
+
+impl CryptoRng for Trng {}
diff --git a/app/rust/src/lib.rs b/app/rust/src/lib.rs
new file mode 100644
index 0000000..1e97cb7
--- /dev/null
+++ b/app/rust/src/lib.rs
@@ -0,0 +1,281 @@
+/*******************************************************************************
+* (c) 2020 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#![no_std]
+#![no_builtins]
+#![allow(dead_code, unused_imports)]
+
+extern crate core;
+#[cfg(test)]
+#[macro_use]
+extern crate hex_literal;
+
+use core::convert::TryInto;
+use core::mem;
+use core::panic::PanicInfo;
+use core::slice::{from_raw_parts, from_raw_parts_mut};
+
+use curve25519_dalek::scalar::Scalar;
+use merlin::{Transcript, TranscriptRng, TranscriptRngBuilder};
+use rand::RngCore;
+use schnorrkel::context::{SigningContext, SigningTranscript};
+use schnorrkel::{PublicKey, SecretKey};
+use zeroize::Zeroize;
+
+use crate::bolos::*;
+
+mod bolos;
+
+fn debug(_msg: &str) {}
+
+#[cfg(not(test))]
+#[panic_handler]
+fn panic(_info: &PanicInfo) -> ! {
+ loop {}
+}
+
+#[inline(never)]
+fn mult_with_secret(k: &mut Scalar, sk: &[u8]) {
+ let mut skbytes = [0u8; 32];
+ skbytes.copy_from_slice(&sk[0..32]);
+ let s = Scalar::from_bits(skbytes);
+ *k *= s;
+}
+
+#[inline(never)]
+fn add_witness(k: &mut Scalar, x: [u8; 32]) -> [u8; 32] {
+ let r = Scalar::from_bits(x);
+ *k += r;
+ k.to_bytes()
+}
+
+#[inline(never)]
+fn get_challenge_scalar(k: &mut Scalar, tr: &mut Transcript) {
+ let mut kbytes = [0u8; 64];
+ tr.challenge_bytes(b"sign:c", &mut kbytes);
+ *k += Scalar::from_bytes_mod_order_wide(&kbytes);
+}
+
+#[inline(never)]
+fn get_witness_bytes_custom(br: &mut Transcript, nonce_seeds: &[&[u8]]) -> [u8; 32] {
+ c_zemu_log_stack(b"witness_bytes\x00".as_ref());
+ let mut x = [0u8; 32];
+ for ns in nonce_seeds {
+ br.append_message(b"nonce-bytes", ns);
+ }
+ {
+ let random_bytes = {
+ let mut bytes = [0u8; 32];
+ Trng.fill_bytes(&mut bytes);
+ bytes
+ };
+ br.append_message(b"rng", &random_bytes);
+ }
+ br.challenge_bytes(b"witness-bytes", &mut x);
+ br.zeroize();
+ x
+}
+
+#[no_mangle]
+pub extern "C" fn sign_sr25519_phase1(
+ sk_ristretto_expanded_ptr: *const u8,
+ pk_ptr: *const u8,
+ context_ptr: *const u8,
+ context_len: usize,
+ msg_ptr: *const u8,
+ msg_len: usize,
+ sig_ptr: *mut u8,
+) {
+ c_zemu_log_stack(b"sign_sr25519\x00".as_ref());
+
+ let sk_ristretto_expanded =
+ unsafe { from_raw_parts(sk_ristretto_expanded_ptr as *const u8, 64) };
+ let pk = unsafe { from_raw_parts(pk_ptr as *const u8, 32) };
+ let context = unsafe { from_raw_parts(context_ptr as *const u8, context_len) };
+ let message = unsafe { from_raw_parts(msg_ptr as *const u8, msg_len) };
+ let signature = unsafe { from_raw_parts_mut(sig_ptr as *mut u8, 64) };
+
+ let mut signtranscript = Transcript::new(b"SigningContext");
+ signtranscript.append_message(b"", context);
+ signtranscript.append_message(b"sign-bytes", message);
+ signtranscript.append_message(b"proto-name", b"Schnorr-sig"); //proto name
+ signtranscript.append_message(b"sign:pk", pk); //commitpoint: pk
+
+ let x = get_witness_bytes_custom(&mut signtranscript, &[&sk_ristretto_expanded[32..]]);
+ signature[32..64].copy_from_slice(&x);
+}
+
+#[no_mangle]
+pub extern "C" fn sign_sr25519_phase2(
+ sk_ristretto_expanded_ptr: *const u8,
+ pk_ptr: *const u8,
+ context_ptr: *const u8,
+ context_len: usize,
+ msg_ptr: *const u8,
+ msg_len: usize,
+ sig_ptr: *mut u8,
+) {
+ c_zemu_log_stack(b"sign_sr25519\x00".as_ref());
+
+ let sk_ristretto_expanded =
+ unsafe { from_raw_parts(sk_ristretto_expanded_ptr as *const u8, 64) };
+ let pk = unsafe { from_raw_parts(pk_ptr as *const u8, 32) };
+ let context = unsafe { from_raw_parts(context_ptr as *const u8, context_len) };
+ let message = unsafe { from_raw_parts(msg_ptr as *const u8, msg_len) };
+ let signature = unsafe { from_raw_parts_mut(sig_ptr as *mut u8, 64) };
+
+ let mut signtranscript = Transcript::new(b"SigningContext");
+ signtranscript.append_message(b"", context);
+ signtranscript.append_message(b"sign-bytes", message);
+ signtranscript.append_message(b"proto-name", b"Schnorr-sig"); //proto name
+ signtranscript.append_message(b"sign:pk", pk); //commitpoint: pk
+ signtranscript.append_message(b"sign:R", &signature[0..32]); //commitpoint: pk
+
+ let mut x = [0u8; 32];
+ x.copy_from_slice(&signature[32..64]);
+
+ let mut k = Scalar::zero();
+ get_challenge_scalar(&mut k, &mut signtranscript);
+
+ mult_with_secret(&mut k, sk_ristretto_expanded);
+ signature[32..].copy_from_slice(&add_witness(&mut k, x));
+ signature[63] |= 128;
+}
+
+#[no_mangle]
+pub extern "C" fn get_sr25519_sk(sk_ed25519_expanded_ptr: *mut u8) {
+ let sk_ed25519_expanded = unsafe { from_raw_parts_mut(sk_ed25519_expanded_ptr as *mut u8, 64) };
+ let secret: SecretKey = SecretKey::from_ed25519_bytes(&sk_ed25519_expanded[..]).unwrap();
+ sk_ed25519_expanded.copy_from_slice(&secret.to_bytes());
+}
+
+#[cfg(test)]
+mod tests {
+ use curve25519_dalek::constants::RISTRETTO_BASEPOINT_POINT;
+ use curve25519_dalek::edwards::EdwardsPoint;
+ use curve25519_dalek::scalar::Scalar;
+ use log::{debug, info};
+ use schnorrkel::{context::*, Keypair, PublicKey, SecretKey, Signature};
+
+ use crate::*;
+ use core::ops::Mul;
+
+ fn init_logging() {
+ let _ = env_logger::builder().is_test(true).try_init();
+ }
+
+ fn ristretto_scalarmult(sk: &[u8], pk: &mut [u8]) {
+ let mut seckey = [0u8; 32];
+ seckey.copy_from_slice(&sk[0..32]);
+ let pubkey = RISTRETTO_BASEPOINT_POINT
+ .mul(Scalar::from_bits(seckey))
+ .compress()
+ .0;
+ pk.copy_from_slice(&pubkey);
+ }
+
+ #[test]
+ fn test_sign_verify() {
+ let mut sk_ed25519_expanded = [
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+ 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03,
+ 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01,
+ 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ ];
+
+ let pk_expected = "b65abc66a8fdeac1197d03daa6c3791d0c0799a52db6b7127b1cd12d46e34364";
+
+ let secret = SecretKey::from_ed25519_bytes(&sk_ed25519_expanded).unwrap();
+
+ let mut pk = [0u8; 32];
+ get_sr25519_sk(sk_ed25519_expanded.as_mut_ptr());
+
+ ristretto_scalarmult(&sk_ed25519_expanded, &mut pk);
+
+ assert_eq!(hex::encode(pk), pk_expected);
+
+ let context = b"good";
+ let msg = b"test message";
+ let mut signature = [0u8; 64];
+
+ sign_sr25519_phase1(
+ secret.to_bytes().as_ptr(),
+ pk.as_ptr(),
+ context.as_ptr(),
+ context.len(),
+ msg.as_ptr(),
+ msg.len(),
+ signature.as_mut_ptr(),
+ );
+
+ let mut x = [0u8; 32];
+ x.copy_from_slice(&signature[32..64]);
+
+ ristretto_scalarmult(&x, &mut signature[0..32]);
+
+ sign_sr25519_phase2(
+ secret.to_bytes().as_ptr(),
+ pk.as_ptr(),
+ context.as_ptr(),
+ context.len(),
+ msg.as_ptr(),
+ msg.len(),
+ signature.as_mut_ptr(),
+ );
+
+ let keypair: Keypair = Keypair::from(secret);
+
+ let mut sigledger = [0u8; 64];
+ hex::decode_to_slice("48fdbe5cf3524bdd078ac711565d658a3053d10660749959883c4710f49d9948b2d5f829bea6800897dc6ea0150ca11075cc36b75bfcf3712aafb8e1bd10bf8f",&mut sigledger).expect("dec");
+
+ let self_sig = Signature::from_bytes(&signature).unwrap();
+ let self_sig_ledger = Signature::from_bytes(&sigledger).unwrap();
+
+ let vers = signing_context(context);
+
+ assert!(
+ keypair.verify(vers.bytes(msg), &self_sig).is_ok(),
+ "Verification of a valid signature failed!"
+ );
+ assert!(
+ keypair.verify(vers.bytes(msg), &self_sig_ledger).is_ok(),
+ "Verification of a valid signature from ledger failed!"
+ );
+ }
+
+ #[test]
+ fn get_public_key_c() {
+ init_logging();
+
+ let mut sk_ed25519_expanded = [
+ 0x00, 0x01, 0x02, 0x03, 04, 0x5, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 04, 0x5, 0x06,
+ 0x07, 0x00, 0x01, 0x02, 0x03, 04, 0x5, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 04, 0x5,
+ 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 04, 0x5, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 04,
+ 0x5, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 04, 0x5, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03,
+ 04, 0x5, 0x06, 0x07,
+ ];
+
+ let pk_expected = "b65abc66a8fdeac1197d03daa6c3791d0c0799a52db6b7127b1cd12d46e34364";
+
+ let mut pk = [0u8; 32];
+ get_sr25519_sk(sk_ed25519_expanded.as_mut_ptr());
+
+ ristretto_scalarmult(&sk_ed25519_expanded, &mut pk);
+
+ info!("{:?}", hex::encode(pk));
+ assert_eq!(hex::encode(pk), pk_expected);
+ }
+}
diff --git a/app/script_x.ld b/app/script_x.ld
new file mode 100644
index 0000000..0d174c4
--- /dev/null
+++ b/app/script_x.ld
@@ -0,0 +1,175 @@
+/*******************************************************************************
+* Ledger Blue - Secure firmware
+* (c) 2016, 2017, 2018, 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.
+********************************************************************************/
+
+/**
+ * Global chip memory layout and constants
+ *
+ */
+
+MEMORY
+{
+ DISCARD (rwx) : ORIGIN = 0xd0000000, LENGTH = 1M
+
+ FLASH (rx) : ORIGIN = 0xc0de0000, LENGTH = 400K
+ DATA (r) : ORIGIN = 0xc0de0000, LENGTH = 400K
+ SRAM (rwx) : ORIGIN = 0xda7a0000, LENGTH = 30K
+}
+
+PAGE_SIZE = 256;
+STACK_SIZE = 8192;
+END_STACK = ORIGIN(SRAM) + LENGTH(SRAM);
+
+ENTRY(main)
+
+SECTIONS
+{
+
+ /****************************************************************/
+ /* This section locates the code in FLASH */
+ /****************************************************************/
+
+ /** put text in Flash memory, VMA will be equal to LMA */
+ .text :
+ {
+ /* provide start code symbol, shall be zero */
+ _text = .;
+ _nvram = .;
+ PROVIDE(_nvram = . + ORIGIN(FLASH));
+
+ PROVIDE(_setjmp = setjmp); /*thanks clang*/
+
+ /* ensure main is always @ 0xC0D00000 */
+ *(.boot*)
+
+ /* place the other code and rodata defined BUT nvram variables that are displaced in a r/w area */
+ *(.text*)
+ *(.rodata)
+ *(.rodata.[^N]*) /*.data.rel.ro* not here to detect invalid PIC usage */
+ *(.rodata.N[^_]*)
+
+ . = ALIGN(4);
+
+ /* all code placed */
+ _etext = .;
+
+ . = ALIGN(PAGE_SIZE);
+
+ _nvram_data = .;
+
+ /* NVM data (ex-filesystem) */
+ *(.bss.N_* .rodata.N_*)
+
+ . = ALIGN(PAGE_SIZE);
+ _envram_data = .;
+ /* _nvram_data_size = _envram_data - _nvram_data; */
+ _install_parameters = .;
+ PROVIDE(N_install_parameters = .);
+ _envram = .;
+ PROVIDE(_envram = . + ORIGIN(FLASH));
+
+ } > FLASH = 0x00
+
+ .data (NOLOAD):
+ {
+ . = ALIGN(4);
+
+ /**
+ * Place RAM initialized variables
+ */
+ _data = .;
+
+ *(vtable)
+ *(.data*)
+
+ _edata = .;
+
+ } > DISCARD /*> SRAM AT>FLASH = 0x00 */
+
+ .bss :
+ {
+ /**
+ * Place RAM uninitialized variables
+ */
+ _bss = .;
+ *(.bss*)
+ _ebss = .;
+
+
+ /**
+ * Reserve stack size
+ */
+ . = ALIGN(4);
+ app_stack_canary = .;
+ PROVIDE(app_stack_canary = .);
+ . += 4;
+ _stack_validation = .;
+ . = _stack_validation + STACK_SIZE;
+ _stack = ABSOLUTE(END_STACK) - STACK_SIZE;
+ PROVIDE( _stack = ABSOLUTE(END_STACK) - STACK_SIZE);
+ _estack = ABSOLUTE(END_STACK);
+ PROVIDE( _estack = ABSOLUTE(END_STACK) );
+
+ } > SRAM = 0x00
+
+ /****************************************************************/
+ /* DEBUG */
+ /****************************************************************/
+
+ /* remove the debugging information from the standard libraries */
+ DEBUG (NOLOAD) :
+ {
+ libc.a ( * )
+ libm.a ( * )
+ libgcc.a ( * )
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ } > DISCARD
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+
+}
diff --git a/app/src/addr.c b/app/src/addr.c
new file mode 100644
index 0000000..e3999ae
--- /dev/null
+++ b/app/src/addr.c
@@ -0,0 +1,59 @@
+/*******************************************************************************
+* (c) 2020 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#include
+#include "coin.h"
+#include "zxerror.h"
+#include "zxmacros.h"
+#include "app_mode.h"
+#include "crypto.h"
+
+zxerr_t addr_getNumItems(uint8_t *num_items) {
+ zemu_log_stack("addr_getNumItems");
+ *num_items = 1;
+ if (app_mode_expert()) {
+ *num_items = 2;
+ }
+ return zxerr_ok;
+}
+
+zxerr_t addr_getItem(int8_t displayIdx,
+ char *outKey, uint16_t outKeyLen,
+ char *outVal, uint16_t outValLen,
+ uint8_t pageIdx, uint8_t *pageCount) {
+ char buffer[30];
+ snprintf(buffer, sizeof(buffer), "addr_getItem %d/%d", displayIdx, pageIdx);
+ zemu_log_stack(buffer);
+ switch (displayIdx) {
+ case 0:
+ snprintf(outKey, outKeyLen, "Address");
+ pageString(outVal, outValLen, (char *) (G_io_apdu_buffer + PK_LEN_25519), pageIdx, pageCount);
+ return zxerr_ok;
+ case 1: {
+ if (!app_mode_expert()) {
+ return zxerr_no_data;
+ }
+
+ snprintf(outKey, outKeyLen, "Your Path");
+ char buffer[300];
+ bip32_to_str(buffer, sizeof(buffer), hdPath, HDPATH_LEN_DEFAULT);
+ pageString(outVal, outValLen, buffer, pageIdx, pageCount);
+ return zxerr_ok;
+ }
+ default:
+ return zxerr_no_data;
+ }
+}
diff --git a/app/src/addr.h b/app/src/addr.h
new file mode 100644
index 0000000..0140671
--- /dev/null
+++ b/app/src/addr.h
@@ -0,0 +1,34 @@
+/*******************************************************************************
+* (c) 2020 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/// Return the number of items in the address view
+zxerr_t addr_getNumItems(uint8_t *num_items);
+
+/// Gets an specific item from the address view (including paging)
+zxerr_t addr_getItem(int8_t displayIdx,
+ char *outKey, uint16_t outKeyLen,
+ char *outValue, uint16_t outValueLen,
+ uint8_t pageIdx, uint8_t *pageCount);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/app/src/apdu_handler.c b/app/src/apdu_handler.c
new file mode 100644
index 0000000..22fed50
--- /dev/null
+++ b/app/src/apdu_handler.c
@@ -0,0 +1,301 @@
+/*******************************************************************************
+* (c) 2018, 2019 Zondax GmbH
+* (c) 2016 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 "app_main.h"
+
+#include
+#include
+#include
+#include
+
+#include "view.h"
+#include "actions.h"
+#include "tx.h"
+#include "addr.h"
+#include "crypto.h"
+#include "coin.h"
+#include "zxmacros.h"
+#include "secret.h"
+#include "app_mode.h"
+
+static bool tx_initialized = false;
+
+void extractHDPath(uint32_t rx, uint32_t offset) {
+ if ((rx - offset) < sizeof(uint32_t) * HDPATH_LEN_DEFAULT) {
+ THROW(APDU_CODE_WRONG_LENGTH);
+ }
+
+ MEMCPY(hdPath, G_io_apdu_buffer + offset, sizeof(uint32_t) * HDPATH_LEN_DEFAULT);
+
+ const bool mainnet = hdPath[0] == HDPATH_0_DEFAULT &&
+ hdPath[1] == HDPATH_1_DEFAULT;
+
+ if (!mainnet) {
+ THROW(APDU_CODE_DATA_INVALID);
+ }
+
+#ifdef APP_SECRET_MODE_ENABLED
+ if (app_mode_secret()) {
+ hdPath[1] = HDPATH_1_RECOVERY;
+ }
+#endif
+}
+
+__Z_INLINE bool process_chunk(volatile uint32_t *tx, uint32_t rx) {
+ zemu_log("process_chunk\n");
+ const uint8_t payloadType = G_io_apdu_buffer[OFFSET_PAYLOAD_TYPE];
+#ifndef SUPPORT_SR25519
+ if (G_io_apdu_buffer[OFFSET_P2] != 0) {
+ THROW(APDU_CODE_INVALIDP1P2);
+ }
+#endif
+ if (rx < OFFSET_DATA) {
+ THROW(APDU_CODE_WRONG_LENGTH);
+ }
+
+ uint32_t added;
+ switch (payloadType) {
+ case 0:
+ zemu_log("process_chunk - init\n");
+ tx_initialize();
+ tx_reset();
+ extractHDPath(rx, OFFSET_DATA);
+ tx_initialized = true;
+ return false;
+ case 1:
+ if (!tx_initialized) {
+ THROW(APDU_CODE_TX_NOT_INITIALIZED);
+ }
+ zemu_log("process_chunk - add \n");
+ added = tx_append(&(G_io_apdu_buffer[OFFSET_DATA]), rx - OFFSET_DATA);
+ if (added != rx - OFFSET_DATA) {
+ tx_initialized = false;
+ THROW(APDU_CODE_OUTPUT_BUFFER_TOO_SMALL);
+ }
+ return false;
+ case 2:
+ if (!tx_initialized) {
+ THROW(APDU_CODE_TX_NOT_INITIALIZED);
+ }
+ zemu_log("process_chunk - end \n");
+ added = tx_append(&(G_io_apdu_buffer[OFFSET_DATA]), rx - OFFSET_DATA);
+ if (added != rx - OFFSET_DATA) {
+ tx_initialized = false;
+ THROW(APDU_CODE_OUTPUT_BUFFER_TOO_SMALL);
+ }
+ tx_initialized = false;
+ return true;
+ }
+
+ THROW(APDU_CODE_INVALIDP1P2);
+}
+
+__Z_INLINE void handle_getversion(volatile uint32_t *flags, volatile uint32_t *tx) {
+ G_io_apdu_buffer[0] = 0;
+
+#if defined(APP_TESTING)
+ G_io_apdu_buffer[0] = 0x01;
+#endif
+
+ G_io_apdu_buffer[1] = (LEDGER_MAJOR_VERSION >> 8) & 0xFF;
+ G_io_apdu_buffer[2] = (LEDGER_MAJOR_VERSION >> 0) & 0xFF;
+
+ G_io_apdu_buffer[3] = (LEDGER_MINOR_VERSION >> 8) & 0xFF;
+ G_io_apdu_buffer[4] = (LEDGER_MINOR_VERSION >> 0) & 0xFF;
+
+ G_io_apdu_buffer[5] = (LEDGER_PATCH_VERSION >> 8) & 0xFF;
+ G_io_apdu_buffer[6] = (LEDGER_PATCH_VERSION >> 0) & 0xFF;
+
+ G_io_apdu_buffer[7] = !IS_UX_ALLOWED;
+
+ G_io_apdu_buffer[8] = (TARGET_ID >> 24) & 0xFF;
+ G_io_apdu_buffer[9] = (TARGET_ID >> 16) & 0xFF;
+ G_io_apdu_buffer[10] = (TARGET_ID >> 8) & 0xFF;
+ G_io_apdu_buffer[11] = (TARGET_ID >> 0) & 0xFF;
+
+ *tx += 12;
+ THROW(APDU_CODE_OK);
+}
+
+__Z_INLINE void handleGetAddr(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) {
+ extractHDPath(rx, OFFSET_DATA);
+
+ const uint8_t requireConfirmation = G_io_apdu_buffer[OFFSET_P1];
+ const uint8_t addr_type = G_io_apdu_buffer[OFFSET_P2];
+ const key_kind_e key_type = get_key_type(addr_type);
+
+ zxerr_t zxerr = app_fill_address(key_type);
+ if(zxerr != zxerr_ok){
+ *tx = 0;
+ THROW(APDU_CODE_DATA_INVALID);
+ }
+ if (requireConfirmation) {
+ view_review_init(addr_getItem, addr_getNumItems, app_reply_address);
+ view_review_show();
+ *flags |= IO_ASYNCH_REPLY;
+ return;
+ }
+ *tx = action_addrResponseLen;
+ THROW(APDU_CODE_OK);
+}
+
+#ifdef SUPPORT_SR25519
+__Z_INLINE void handleSignSr25519(volatile uint32_t *flags, volatile uint32_t *tx) {
+ zxerr_t err = app_sign_sr25519();
+ if(err != zxerr_ok){
+ *tx = 0;
+ THROW(APDU_CODE_DATA_INVALID);
+ }
+
+ CHECK_APP_CANARY()
+
+ const char *error_msg = tx_parse();
+ CHECK_APP_CANARY()
+ if (error_msg != NULL) {
+ int error_msg_length = strlen(error_msg);
+ MEMCPY(G_io_apdu_buffer, error_msg, error_msg_length);
+ *tx += (error_msg_length);
+ THROW(APDU_CODE_DATA_INVALID);
+ }
+
+ view_review_init(tx_getItem, tx_getNumItems, app_return_sr25519);
+ view_review_show();
+ *flags |= IO_ASYNCH_REPLY;
+}
+#endif
+
+__Z_INLINE void handleSignEd25519(volatile uint32_t *flags, volatile uint32_t *tx) {
+ const char *error_msg = tx_parse();
+ CHECK_APP_CANARY()
+ if (error_msg != NULL) {
+ int error_msg_length = strlen(error_msg);
+ MEMCPY(G_io_apdu_buffer, error_msg, error_msg_length);
+ *tx += (error_msg_length);
+ THROW(APDU_CODE_DATA_INVALID);
+ }
+
+ view_review_init(tx_getItem, tx_getNumItems, app_sign_ed25519);
+ view_review_show();
+ *flags |= IO_ASYNCH_REPLY;
+}
+
+__Z_INLINE void handleSign(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) {
+ zemu_log("handleSign\n");
+ if (!process_chunk(tx, rx)) {
+ THROW(APDU_CODE_OK);
+ }
+ if (app_mode_secret()) {
+ app_mode_set_secret(false);
+ }
+ const uint8_t addr_type = G_io_apdu_buffer[OFFSET_P2];
+ const key_kind_e key_type = get_key_type(addr_type);
+
+ *tx = 0;
+ switch (key_type) {
+ case key_ed25519:
+ handleSignEd25519(flags, tx);
+ break;
+#ifdef SUPPORT_SR25519
+ case key_sr25519:
+ handleSignSr25519(flags, tx);
+ break;
+#endif
+ default: {
+ THROW(APDU_CODE_DATA_INVALID);
+ }
+ }
+}
+
+#if defined(APP_TESTING)
+void handleTest(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) {
+ THROW(APDU_CODE_OK);
+}
+#endif
+
+void handleApdu(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) {
+ uint16_t sw = 0;
+
+ BEGIN_TRY
+ {
+ TRY
+ {
+ if (G_io_apdu_buffer[OFFSET_CLA] != CLA) {
+ THROW(APDU_CODE_CLA_NOT_SUPPORTED);
+ }
+
+ if (rx < APDU_MIN_LENGTH) {
+ THROW(APDU_CODE_WRONG_LENGTH);
+ }
+
+ switch (G_io_apdu_buffer[OFFSET_INS]) {
+ case INS_GET_VERSION: {
+ handle_getversion(flags, tx);
+ break;
+ }
+
+ case INS_GET_ADDR: {
+ if( os_global_pin_is_validated() != BOLOS_UX_OK ) {
+ THROW(APDU_CODE_COMMAND_NOT_ALLOWED);
+ }
+ handleGetAddr(flags, tx, rx);
+ break;
+ }
+
+ case INS_SIGN: {
+ if( os_global_pin_is_validated() != BOLOS_UX_OK ) {
+ THROW(APDU_CODE_COMMAND_NOT_ALLOWED);
+ }
+ handleSign(flags, tx, rx);
+ break;
+ }
+
+#if defined(APP_TESTING)
+ case INS_TEST: {
+ handleTest(flags, tx, rx);
+ THROW(APDU_CODE_OK);
+ break;
+ }
+#endif
+ default:
+ THROW(APDU_CODE_INS_NOT_SUPPORTED);
+ }
+ }
+ CATCH(EXCEPTION_IO_RESET)
+ {
+ THROW(EXCEPTION_IO_RESET);
+ }
+ CATCH_OTHER(e)
+ {
+ switch (e & 0xF000) {
+ case 0x6000:
+ case APDU_CODE_OK:
+ sw = e;
+ break;
+ default:
+ sw = 0x6800 | (e & 0x7FF);
+ break;
+ }
+ G_io_apdu_buffer[*tx] = sw >> 8;
+ G_io_apdu_buffer[*tx + 1] = sw;
+ *tx += 2;
+ }
+ FINALLY
+ {
+ }
+ }
+ END_TRY;
+}
diff --git a/app/src/c_api/rust.c b/app/src/c_api/rust.c
new file mode 100644
index 0000000..a120270
--- /dev/null
+++ b/app/src/c_api/rust.c
@@ -0,0 +1,13 @@
+#include
+#include
+#include
+
+#if defined (TARGET_NANOS)
+void cx_rng_no_throw(uint8_t *buffer, size_t len);
+
+unsigned char *cx_rng(uint8_t *buffer, size_t len)
+{
+ cx_rng_no_throw(buffer, len);
+ return buffer;
+}
+#endif
diff --git a/app/src/coin.h b/app/src/coin.h
new file mode 100644
index 0000000..2cc14f3
--- /dev/null
+++ b/app/src/coin.h
@@ -0,0 +1,65 @@
+/*******************************************************************************
+* (c) 2020 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CLA 0x98
+
+#define HDPATH_LEN_DEFAULT 5
+#define HDPATH_0_DEFAULT (0x80000000 | 0x2c)
+#define HDPATH_1_DEFAULT (0x80000000 | 0x3eb) // 1003 - Nodle
+#define HDPATH_1_RECOVERY (0x80000000 | 0x162) // 354 - Polkadot
+
+#define SK_LEN_25519 64u
+#define SCALAR_LEN_ED25519 32u
+#define SIG_PLUS_TYPE_LEN 65u
+
+#define PK_LEN_25519 32u
+#define MAX_SIGN_SIZE 256u
+#define BLAKE2B_DIGEST_SIZE 32u
+
+typedef enum {
+ key_ed25519 = 0,
+
+#if defined(SUPPORT_SR25519)
+ key_sr25519 = 1
+#endif
+
+} key_kind_e;
+
+// Coin Specific
+#define PK_ADDRESS_TYPE 37
+#define SUPPORTED_TX_VERSION_CURRENT LEDGER_MAJOR_VERSION
+#define SUPPORTED_TX_VERSION_PREVIOUS (LEDGER_MAJOR_VERSION - 1)
+#define SUPPORTED_SPEC_VERSION (LEDGER_MINOR_VERSION + 0)
+#define SUPPORTED_MINIMUM_SPEC_VERSION 52
+
+#define COIN_AMOUNT_DECIMAL_PLACES 12
+
+#define COIN_GENESIS_HASH "0000000000000000000000000000000000000000000000000000000000000000"
+#define COIN_NAME "Nodle"
+#define COIN_TICKER "NODL"
+
+#define COIN_SECRET_REQUIRED_CLICKS 0
+
+#include "coin_standard.h"
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/app/src/coin_standard.h b/app/src/coin_standard.h
new file mode 100644
index 0000000..05793cb
--- /dev/null
+++ b/app/src/coin_standard.h
@@ -0,0 +1,38 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include
+
+
+#define HDPATH_2_DEFAULT (0x80000000u | 0u)
+#define HDPATH_3_DEFAULT (0u)
+#define HDPATH_4_DEFAULT (0u)
+
+#define MENU_MAIN_APP_LINE1 "Nodle"
+#define MENU_MAIN_APP_LINE2 "Ready"
+#define MENU_MAIN_APP_LINE2_SECRET "KSM RECOVERY"
+#define APPVERSION_LINE1 "Nodle"
+#define APPVERSION_LINE2 "v" APPVERSION
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/app/src/common/actions.c b/app/src/common/actions.c
new file mode 100644
index 0000000..893d234
--- /dev/null
+++ b/app/src/common/actions.c
@@ -0,0 +1,20 @@
+/*******************************************************************************
+* (c) 2016 Ledger
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#include "actions.h"
+
+uint16_t action_addrResponseLen;
diff --git a/app/src/common/actions.h b/app/src/common/actions.h
new file mode 100644
index 0000000..8cc5bd7
--- /dev/null
+++ b/app/src/common/actions.h
@@ -0,0 +1,117 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma once
+
+#include
+#include "crypto.h"
+#include "tx.h"
+#include "apdu_codes.h"
+#include
+#include "coin.h"
+#include "zxerror.h"
+
+extern uint16_t action_addrResponseLen;
+extern uint16_t action_signResponseLen;
+
+#ifdef SUPPORT_SR25519
+__Z_INLINE zxerr_t app_sign_sr25519() {
+ const uint8_t *message = tx_get_buffer();
+ const uint16_t messageLength = tx_get_buffer_length();
+ uint16_t replyLen = 0;
+ zxerr_t zxerr;
+ zxerr = crypto_sign_sr25519_prephase(G_io_apdu_buffer, IO_APDU_BUFFER_SIZE - 3, message, messageLength);
+ if (zxerr != zxerr_ok) {
+ MEMZERO(G_io_apdu_buffer, IO_APDU_BUFFER_SIZE);
+ return zxerr;
+ }
+ zxerr = crypto_sign_sr25519(G_io_apdu_buffer, IO_APDU_BUFFER_SIZE - 3, &replyLen);
+ return zxerr;
+}
+#endif
+
+__Z_INLINE void app_sign_ed25519() {
+ const uint8_t *message = tx_get_buffer();
+ const uint16_t messageLength = tx_get_buffer_length();
+ uint16_t replyLen = 0;
+ zxerr_t err = crypto_sign_ed25519(G_io_apdu_buffer, IO_APDU_BUFFER_SIZE - 3,
+ message, messageLength, &replyLen);
+ if (err != zxerr_ok) {
+ set_code(G_io_apdu_buffer, 0, APDU_CODE_SIGN_VERIFY_ERROR);
+ io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, 2);
+ } else {
+ set_code(G_io_apdu_buffer, SIG_PLUS_TYPE_LEN, APDU_CODE_OK);
+ io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, SIG_PLUS_TYPE_LEN + 2);
+ }
+}
+
+#ifdef SUPPORT_SR25519
+__Z_INLINE void app_return_sr25519() {
+ MEMCPY(G_io_apdu_buffer, (void *) &N_sr25519_signdata.signature, SIG_PLUS_TYPE_LEN);
+ zxerr_t zxerr = zeroize_sr25519_signdata();
+
+ if (zxerr != zxerr_ok) {
+ set_code(G_io_apdu_buffer, 0, APDU_CODE_SIGN_VERIFY_ERROR);
+ io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, 2);
+ } else {
+ set_code(G_io_apdu_buffer, SIG_PLUS_TYPE_LEN, APDU_CODE_OK);
+ io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, SIG_PLUS_TYPE_LEN + 2);
+ }
+}
+#endif
+
+__Z_INLINE void app_reject() {
+ zeroize_sr25519_signdata();
+ set_code(G_io_apdu_buffer, 0, APDU_CODE_COMMAND_NOT_ALLOWED);
+ io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, 2);
+}
+
+__Z_INLINE zxerr_t app_fill_address(key_kind_e addressKind) {
+ // Put data directly in the apdu buffer
+ MEMZERO(G_io_apdu_buffer, IO_APDU_BUFFER_SIZE);
+ CHECK_ZXERR(crypto_fillAddress(addressKind,
+ G_io_apdu_buffer, IO_APDU_BUFFER_SIZE - 2,
+ &action_addrResponseLen));
+ return zxerr_ok;
+}
+
+__Z_INLINE key_kind_e get_key_type(uint8_t num) {
+#ifdef SUPPORT_SR25519
+ switch (num) {
+ case 0x00:
+ return key_ed25519;
+ case 0x01:
+ return key_sr25519;
+ }
+ return 0xff;
+#else
+ return key_ed25519;
+#endif
+}
+
+__Z_INLINE void app_reply_error() {
+ zeroize_sr25519_signdata();
+ set_code(G_io_apdu_buffer, 0, APDU_CODE_DATA_INVALID);
+ io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, 2);
+}
+
+__Z_INLINE void app_reply_address() {
+ if (action_addrResponseLen == 0) {
+ app_reply_error();
+ return;
+ }
+ set_code(G_io_apdu_buffer, action_addrResponseLen, APDU_CODE_OK);
+ io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, action_addrResponseLen + 2);
+}
diff --git a/app/src/common/app_main.c b/app/src/common/app_main.c
new file mode 100644
index 0000000..d28d9bc
--- /dev/null
+++ b/app/src/common/app_main.c
@@ -0,0 +1,203 @@
+/*******************************************************************************
+* (c) 2018, 2019 Zondax GmbH
+* (c) 2016 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 "app_main.h"
+
+#include
+#include
+#include
+#include
+
+#include "view.h"
+#include "actions.h"
+#include "tx.h"
+#include "crypto.h"
+#include "coin.h"
+#include "zxmacros.h"
+#include "app_mode.h"
+
+unsigned char G_io_seproxyhal_spi_buffer[IO_SEPROXYHAL_BUFFER_SIZE_B];
+
+unsigned char io_event(unsigned char channel) {
+ UNUSED(channel);
+
+ switch (G_io_seproxyhal_spi_buffer[0]) {
+ case SEPROXYHAL_TAG_FINGER_EVENT: //
+ UX_FINGER_EVENT(G_io_seproxyhal_spi_buffer);
+ break;
+
+ case SEPROXYHAL_TAG_BUTTON_PUSH_EVENT: // for Nano S
+ UX_BUTTON_PUSH_EVENT(G_io_seproxyhal_spi_buffer);
+ break;
+
+ case SEPROXYHAL_TAG_DISPLAY_PROCESSED_EVENT:
+ if (!UX_DISPLAYED())
+ UX_DISPLAYED_EVENT();
+ break;
+
+ case SEPROXYHAL_TAG_TICKER_EVENT: { //
+ UX_TICKER_EVENT(G_io_seproxyhal_spi_buffer, {
+ if (UX_ALLOWED) {
+ UX_REDISPLAY();
+ }
+ });
+ break;
+ }
+
+ // unknown events are acknowledged
+ default:
+ UX_DEFAULT_EVENT();
+ break;
+ }
+ if (!io_seproxyhal_spi_is_status_sent()) {
+ io_seproxyhal_general_status();
+ }
+ return 1; // DO NOT reset the current APDU transport
+}
+
+unsigned short io_exchange_al(unsigned char channel, unsigned short tx_len) {
+ switch (channel & ~(IO_FLAGS)) {
+ case CHANNEL_KEYBOARD:
+ break;
+
+ // multiplexed io exchange over a SPI channel and TLV encapsulated protocol
+ case CHANNEL_SPI:
+ if (tx_len) {
+ io_seproxyhal_spi_send(G_io_apdu_buffer, tx_len);
+
+ if (channel & IO_RESET_AFTER_REPLIED) {
+ reset();
+ }
+ return 0; // nothing received from the master so far (it's a tx
+ // transaction)
+ } else {
+ return io_seproxyhal_spi_recv(G_io_apdu_buffer, sizeof(G_io_apdu_buffer), 0);
+ }
+
+ default:
+ THROW(INVALID_PARAMETER);
+ }
+ return 0;
+}
+
+void handle_generic_apdu(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) {
+ UNUSED(flags);
+
+ if (rx > 4 && MEMCMP(G_io_apdu_buffer, "\xE0\x01\x00\x00", 4) == 0) {
+ // Respond to get device info command
+ uint8_t *p = G_io_apdu_buffer;
+ // Target ID 4 bytes
+ p[0] = (TARGET_ID >> 24) & 0xFF;
+ p[1] = (TARGET_ID >> 16) & 0xFF;
+ p[2] = (TARGET_ID >> 8) & 0xFF;
+ p[3] = (TARGET_ID >> 0) & 0xFF;
+ p += 4;
+ // SE Version [length][non-terminated string]
+ *p = os_version(p + 1, 64);
+ p = p + 1 + *p;
+ // Flags [length][flags]
+ *p = 0;
+ p++;
+ // MCU Version [length][non-terminated string]
+ *p = os_seph_version(p + 1, 64);
+ p = p + 1 + *p;
+
+ *tx = p - G_io_apdu_buffer;
+ THROW(APDU_CODE_OK);
+ }
+}
+
+void app_init() {
+ io_seproxyhal_init();
+
+#ifdef TARGET_NANOX
+ // grab the current plane mode setting
+ G_io_app.plane_mode = os_setting_get(OS_SETTING_PLANEMODE, NULL, 0);
+#endif // TARGET_NANOX
+
+ USB_power(0);
+ USB_power(1);
+ app_mode_reset();
+ zeroize_sr25519_signdata();
+ view_idle_show(0, NULL);
+
+#ifdef HAVE_BLE
+ // Enable Bluetooth
+ BLE_power(0, NULL);
+ BLE_power(1, "Nano X");
+#endif // HAVE_BLE
+
+}
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wmissing-noreturn"
+
+void app_main() {
+ volatile uint32_t rx = 0, tx = 0, flags = 0;
+
+ for (;;) {
+ volatile uint16_t sw = 0;
+
+ BEGIN_TRY;
+ {
+ TRY;
+ {
+ rx = tx;
+ tx = 0;
+
+ rx = io_exchange(CHANNEL_APDU | flags, rx);
+ flags = 0;
+ CHECK_APP_CANARY()
+
+ if (rx == 0)
+ THROW(APDU_CODE_EMPTY_BUFFER);
+
+ handle_generic_apdu(&flags, &tx, rx);
+ CHECK_APP_CANARY()
+
+ handleApdu(&flags, &tx, rx);
+ CHECK_APP_CANARY()
+ }
+ CATCH(EXCEPTION_IO_RESET)
+ {
+ // reset IO and UX before continuing
+ app_init();
+ continue;
+ }
+ CATCH_OTHER(e);
+ {
+ switch (e & 0xF000) {
+ case 0x6000:
+ case 0x9000:
+ sw = e;
+ break;
+ default:
+ sw = 0x6800 | (e & 0x7FF);
+ break;
+ }
+ G_io_apdu_buffer[tx] = sw >> 8;
+ G_io_apdu_buffer[tx + 1] = sw;
+ tx += 2;
+ }
+ FINALLY;
+ {}
+ }
+ END_TRY;
+ }
+}
+
+#pragma clang diagnostic pop
diff --git a/app/src/common/app_main.h b/app/src/common/app_main.h
new file mode 100644
index 0000000..4d21bb7
--- /dev/null
+++ b/app/src/common/app_main.h
@@ -0,0 +1,50 @@
+/*******************************************************************************
+* (c) 2016 Ledger
+* (c) 2018 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma once
+
+#include
+#include "apdu_codes.h"
+
+#define OFFSET_CLA 0
+#define OFFSET_INS 1 //< Instruction offset
+#define OFFSET_P1 2 //< P1
+#define OFFSET_P2 3 //< P2
+#define OFFSET_DATA_LEN 4 //< Data Length
+#define OFFSET_DATA 5 //< Data offset
+
+#define APDU_MIN_LENGTH 5
+
+#define OFFSET_PAYLOAD_TYPE OFFSET_P1
+
+#define INS_GET_VERSION 0x00
+#define INS_GET_ADDR 0x01
+#define INS_SIGN 0x02
+
+#define INS_ALLOWLIST_GET_PUBKEY 0x90
+#define INS_ALLOWLIST_SET_PUBKEY 0x91
+#define INS_ALLOWLIST_GET_HASH 0x92
+#define INS_ALLOWLIST_UPLOAD 0x93
+
+#if defined(APP_TESTING)
+#define INS_TEST 0xFF
+#endif
+
+void app_init();
+
+void app_main();
+
+void handleApdu(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx);
diff --git a/app/src/common/main.c b/app/src/common/main.c
new file mode 100644
index 0000000..87150f0
--- /dev/null
+++ b/app/src/common/main.c
@@ -0,0 +1,43 @@
+/*******************************************************************************
+* (c) 2016 Ledger
+* (c) 2018, 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#include "app_main.h"
+#include "view.h"
+
+#include
+
+__attribute__((section(".boot"))) int
+main(void) {
+ // exit critical section
+ __asm volatile("cpsie i");
+
+ view_init();
+ os_boot();
+
+ BEGIN_TRY
+ {
+ TRY
+ {
+ app_init();
+ app_main();
+ }
+ CATCH_OTHER(e)
+ {}
+ FINALLY
+ {}
+ }
+ END_TRY;
+}
diff --git a/app/src/common/parser.h b/app/src/common/parser.h
new file mode 100644
index 0000000..2ba3aa9
--- /dev/null
+++ b/app/src/common/parser.h
@@ -0,0 +1,45 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "parser_impl.h"
+
+const char *parser_getErrorDescription(parser_error_t err);
+
+//// parses a tx buffer
+parser_error_t parser_parse(parser_context_t *ctx, const uint8_t *data, size_t dataLen, parser_tx_t *tx_obj);
+
+//// verifies tx fields
+parser_error_t parser_validate(const parser_context_t *ctx);
+
+//// returns the number of items in the current parsing context
+parser_error_t parser_getNumItems(const parser_context_t *ctx, uint8_t *num_items);
+
+// retrieves a readable output for each field / page
+parser_error_t parser_getItem(const parser_context_t *ctx,
+ uint8_t displayIdx,
+ char *outKey, uint16_t outKeyLen,
+ char *outVal, uint16_t outValLen,
+ uint8_t pageIdx, uint8_t *pageCount);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/app/src/common/parser_common.h b/app/src/common/parser_common.h
new file mode 100644
index 0000000..9e06875
--- /dev/null
+++ b/app/src/common/parser_common.h
@@ -0,0 +1,66 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "parser_txdef.h"
+#include
+#include
+
+#define CHECK_PARSER_ERR(__CALL) { \
+ parser_error_t __err = __CALL; \
+ CHECK_APP_CANARY() \
+ if (__err!=parser_ok) return __err;}
+
+typedef enum {
+ // Generic errors
+ parser_ok = 0,
+ parser_no_data,
+ parser_init_context_empty,
+ parser_display_idx_out_of_range,
+ parser_display_page_out_of_range,
+ parser_unexpected_error,
+ // Coin specific
+ parser_unexpected_address_type,
+ parser_spec_not_supported,
+ parser_tx_version_not_supported,
+ parser_not_allowed,
+ parser_not_supported,
+ parser_unexpected_buffer_end,
+ parser_unexpected_value,
+ parser_value_out_of_range,
+ parser_value_too_many_bytes,
+ parser_unexpected_module,
+ parser_unexpected_callIndex,
+ parser_unexpected_unparsed_bytes,
+ parser_print_not_supported,
+ parser_tx_nesting_limit_reached,
+ parser_tx_call_vec_too_large,
+} parser_error_t;
+
+typedef struct {
+ const uint8_t *buffer;
+ uint16_t bufferLen;
+ uint16_t offset;
+ parser_tx_t *tx_obj;
+} parser_context_t;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/app/src/common/tx.c b/app/src/common/tx.c
new file mode 100644
index 0000000..b05c192
--- /dev/null
+++ b/app/src/common/tx.c
@@ -0,0 +1,141 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#include "tx.h"
+#include "apdu_codes.h"
+#include "buffering.h"
+#include "parser.h"
+#include
+#include "zxmacros.h"
+#include "zbuffer.h"
+
+#if defined(TARGET_NANOX)
+#define RAM_BUFFER_SIZE 8192
+#define FLASH_BUFFER_SIZE 16384
+#elif defined(TARGET_NANOS)
+#define RAM_BUFFER_SIZE 0
+#define FLASH_BUFFER_SIZE 8192
+#endif
+
+// Ram
+uint8_t ram_buffer[RAM_BUFFER_SIZE];
+
+// Flash
+typedef struct {
+ uint8_t buffer[FLASH_BUFFER_SIZE];
+} storage_t;
+
+#if defined(TARGET_NANOS) || defined(TARGET_NANOX)
+storage_t NV_CONST N_appdata_impl __attribute__ ((aligned(64)));
+#define N_appdata (*(NV_VOLATILE storage_t *)PIC(&N_appdata_impl))
+#endif
+
+parser_context_t ctx_parsed_tx;
+
+void tx_initialize() {
+ buffering_init(
+ ram_buffer,
+ sizeof(ram_buffer),
+ (uint8_t *) N_appdata.buffer,
+ sizeof(N_appdata.buffer)
+ );
+}
+
+void tx_reset() {
+ buffering_reset();
+}
+
+uint32_t tx_append(unsigned char *buffer, uint32_t length) {
+ return buffering_append(buffer, length);
+}
+
+uint32_t tx_get_buffer_length() {
+ return buffering_get_buffer()->pos;
+}
+
+uint8_t *tx_get_buffer() {
+ return buffering_get_buffer()->data;
+}
+
+const char *tx_parse() {
+ parser_tx_t *tx_obj;
+
+ zb_allocate(sizeof(parser_tx_t));
+ zb_get((uint8_t **) &tx_obj);
+
+ uint8_t err = parser_parse(
+ &ctx_parsed_tx,
+ tx_get_buffer(),
+ tx_get_buffer_length(),
+ tx_obj);
+
+ if (err != parser_ok) {
+ return parser_getErrorDescription(err);
+ }
+
+ err = parser_validate(&ctx_parsed_tx);
+ CHECK_APP_CANARY()
+
+ if (err != parser_ok) {
+ return parser_getErrorDescription(err);
+ }
+
+ return NULL;
+}
+
+void tx_parse_reset() {
+ zb_deallocate();
+}
+
+zxerr_t tx_getNumItems(uint8_t *num_items) {
+ parser_error_t err = parser_getNumItems(&ctx_parsed_tx, num_items);
+
+ if (err != parser_ok) {
+ return zxerr_no_data;
+ }
+
+ return zxerr_ok;
+}
+
+zxerr_t tx_getItem(int8_t displayIdx,
+ char *outKey, uint16_t outKeyLen,
+ char *outVal, uint16_t outValLen,
+ uint8_t pageIdx, uint8_t *pageCount) {
+ uint8_t numItems = 0;
+
+ CHECK_ZXERR(tx_getNumItems(&numItems))
+
+ if (displayIdx < 0 || displayIdx > numItems) {
+ return zxerr_no_data;
+ }
+
+ parser_error_t err = parser_getItem(&ctx_parsed_tx,
+ displayIdx,
+ outKey, outKeyLen,
+ outVal, outValLen,
+ pageIdx, pageCount);
+
+ // Convert error codes
+ if (err == parser_no_data ||
+ err == parser_display_idx_out_of_range ||
+ err == parser_display_page_out_of_range)
+ return zxerr_no_data;
+
+ if (err != parser_ok)
+ return zxerr_unknown;
+
+ return zxerr_ok;
+}
diff --git a/app/src/common/tx.h b/app/src/common/tx.h
new file mode 100644
index 0000000..b84b915
--- /dev/null
+++ b/app/src/common/tx.h
@@ -0,0 +1,54 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma once
+
+#include "os.h"
+#include "coin.h"
+#include "zxerror.h"
+
+void tx_initialize();
+
+/// Clears the transaction buffer
+void tx_reset();
+
+/// Appends buffer to the end of the current transaction buffer
+/// Transaction buffer will grow until it reaches the maximum allowed size
+/// \param buffer
+/// \param length
+/// \return It returns an error message if the buffer is too small.
+uint32_t tx_append(unsigned char *buffer, uint32_t length);
+
+/// Returns size of the raw json transaction buffer
+/// \return
+uint32_t tx_get_buffer_length();
+
+/// Returns the raw json transaction buffer
+/// \return
+uint8_t *tx_get_buffer();
+
+/// Parse message stored in transaction buffer
+/// This function should be called as soon as full buffer data is loaded.
+/// \return It returns NULL if data is valid or error message otherwise.
+const char *tx_parse();
+
+/// Return the number of items in the transaction
+zxerr_t tx_getNumItems(uint8_t *num_items);
+
+/// Gets an specific item from the transaction (including paging)
+zxerr_t tx_getItem(int8_t displayIdx,
+ char *outKey, uint16_t outKeyLen,
+ char *outValue, uint16_t outValueLen,
+ uint8_t pageIdx, uint8_t *pageCount);
diff --git a/app/src/crypto.c b/app/src/crypto.c
new file mode 100644
index 0000000..e782886
--- /dev/null
+++ b/app/src/crypto.c
@@ -0,0 +1,252 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#include "crypto.h"
+#include "base58.h"
+#include "coin.h"
+#include "cx.h"
+#include "rslib.h"
+#include "zxmacros.h"
+#include "ristretto.h"
+
+uint16_t sr25519_signdataLen;
+uint32_t hdPath[HDPATH_LEN_DEFAULT];
+
+zxerr_t crypto_extractPublicKey(key_kind_e addressKind, const uint32_t path[HDPATH_LEN_DEFAULT],
+ uint8_t *pubKey, uint16_t pubKeyLen) {
+ cx_ecfp_public_key_t cx_publicKey;
+ cx_ecfp_private_key_t cx_privateKey;
+ uint8_t privateKeyData[SK_LEN_25519];
+ MEMZERO(privateKeyData, SK_LEN_25519);
+
+ if (pubKeyLen < PK_LEN_25519) {
+ return zxerr_invalid_crypto_settings;
+ }
+
+ zxerr_t err = zxerr_ok;
+ BEGIN_TRY
+ {
+ TRY
+ {
+ // Generate keys
+ os_perso_derive_node_bip32_seed_key(
+ HDW_NORMAL,
+ CX_CURVE_Ed25519,
+ path,
+ HDPATH_LEN_DEFAULT,
+ privateKeyData,
+ NULL,
+ NULL,
+ 0);
+
+ switch (addressKind) {
+ case key_ed25519: {
+ cx_ecfp_init_private_key(CX_CURVE_Ed25519, privateKeyData, 32, &cx_privateKey);
+ cx_ecfp_init_public_key(CX_CURVE_Ed25519, NULL, 0, &cx_publicKey);
+ cx_ecfp_generate_pair(CX_CURVE_Ed25519, &cx_publicKey, &cx_privateKey, 1);
+ for (unsigned int i = 0; i < PK_LEN_25519; i++) {
+ pubKey[i] = cx_publicKey.W[64 - i];
+ }
+
+ if ((cx_publicKey.W[PK_LEN_25519] & 1) != 0) {
+ pubKey[31] |= 0x80;
+ }
+ break;
+ }
+#ifdef SUPPORT_SR25519
+ case key_sr25519:
+ get_sr25519_sk(privateKeyData);
+ crypto_scalarmult_ristretto255_base_sdk(pubKey, privateKeyData);
+ break;
+#endif
+ default:
+ err = zxerr_invalid_crypto_settings;
+ break;
+ }
+ }
+ CATCH_ALL
+ {
+ err = zxerr_unknown;
+ }
+ FINALLY
+ {
+ MEMZERO(&cx_privateKey, sizeof(cx_privateKey));
+ MEMZERO(privateKeyData, SK_LEN_25519);
+ }
+ }
+ END_TRY;
+
+ return err;
+}
+
+zxerr_t crypto_sign_ed25519(uint8_t *signature, uint16_t signatureMaxlen,
+ const uint8_t *message, uint16_t messageLen,
+ uint16_t *signatureLen) {
+ const uint8_t *toSign = message;
+ uint8_t messageDigest[BLAKE2B_DIGEST_SIZE];
+
+ if (messageLen > MAX_SIGN_SIZE) {
+ // Hash it
+ cx_blake2b_t ctx;
+ cx_blake2b_init(&ctx, 256);
+ cx_hash(&ctx.header, CX_LAST, message, messageLen, messageDigest, BLAKE2B_DIGEST_SIZE);
+ toSign = messageDigest;
+ messageLen = BLAKE2B_DIGEST_SIZE;
+ }
+
+ cx_ecfp_private_key_t cx_privateKey;
+ uint8_t privateKeyData[SK_LEN_25519];
+ int signatureLength = 0;
+ unsigned int info = 0;
+
+ zxerr_t err = zxerr_ok;
+ BEGIN_TRY
+ {
+ TRY
+ {
+ // Generate keys
+ os_perso_derive_node_bip32_seed_key(
+ HDW_NORMAL,
+ CX_CURVE_Ed25519,
+ hdPath,
+ HDPATH_LEN_DEFAULT,
+ privateKeyData,
+ NULL,
+ NULL,
+ 0);
+
+ cx_ecfp_init_private_key(CX_CURVE_Ed25519, privateKeyData, SCALAR_LEN_ED25519, &cx_privateKey);
+
+ // Sign
+ *signature = PREFIX_SIGNATURE_TYPE_ED25519;
+ signatureLength = cx_eddsa_sign(&cx_privateKey,
+ CX_LAST,
+ CX_SHA512,
+ toSign,
+ messageLen,
+ NULL,
+ 0,
+ signature + 1,
+ signatureMaxlen - 1,
+ &info);
+
+ }
+ CATCH_ALL
+ {
+ *signatureLen = 0;
+ err = zxerr_unknown;
+ };
+ FINALLY
+ {
+ MEMZERO(&cx_privateKey, sizeof(cx_privateKey));
+ MEMZERO(privateKeyData, SK_LEN_25519);
+ MEMZERO(signature + signatureLength + 1, signatureMaxlen - signatureLength - 1);
+ }
+ }
+ END_TRY;
+ return err;
+}
+
+#ifdef SUPPORT_SR25519
+zxerr_t crypto_sign_sr25519_prephase(uint8_t *buffer, uint16_t bufferLen,
+ const uint8_t *message, uint16_t messageLen) {
+ if (messageLen > MAX_SIGN_SIZE) {
+ uint8_t messageDigest[BLAKE2B_DIGEST_SIZE];
+ cx_blake2b_t *ctx = (cx_blake2b_t *) buffer;
+ cx_blake2b_init(ctx, 256);
+ cx_hash(&ctx->header, CX_LAST, message, messageLen, messageDigest, BLAKE2B_DIGEST_SIZE);
+ MEMCPY_NV((void *) &N_sr25519_signdata.signdata, messageDigest, BLAKE2B_DIGEST_SIZE);
+ sr25519_signdataLen = BLAKE2B_DIGEST_SIZE;
+ } else {
+ MEMCPY_NV((void *) &N_sr25519_signdata.signdata, (void *) message, messageLen);
+ sr25519_signdataLen = messageLen;
+ }
+
+ MEMZERO(buffer, bufferLen);
+ uint8_t privateKeyData[SK_LEN_25519];
+ MEMZERO(privateKeyData, SK_LEN_25519);
+ os_perso_derive_node_bip32_seed_key(
+ HDW_NORMAL,
+ CX_CURVE_Ed25519,
+ hdPath,
+ HDPATH_LEN_DEFAULT,
+ privateKeyData,
+ NULL,
+ NULL,
+ 0);
+
+ uint8_t pubkey[PK_LEN_25519];
+ MEMZERO(pubkey, PK_LEN_25519);
+ get_sr25519_sk(privateKeyData);
+ crypto_scalarmult_ristretto255_base_sdk(pubkey, privateKeyData);
+ MEMCPY_NV((void *) &N_sr25519_signdata.sk, privateKeyData, SK_LEN_25519);
+ MEMCPY_NV((void *) &N_sr25519_signdata.pk, pubkey, PK_LEN_25519);
+ MEMZERO(buffer, bufferLen);
+ return zxerr_ok;
+}
+
+zxerr_t crypto_sign_sr25519(uint8_t *signature, uint16_t signatureMaxlen,
+ uint16_t *signatureLen) {
+
+ BEGIN_TRY
+ {
+ TRY
+ {
+ if (signatureMaxlen < MIN_BUFFER_LENGTH) {
+ CLOSE_TRY;
+ return zxerr_invalid_crypto_settings;
+ }
+ *signature = PREFIX_SIGNATURE_TYPE_SR25519;
+ sign_sr25519_phase1((uint8_t *) &N_sr25519_signdata.sk, (uint8_t *) &N_sr25519_signdata.pk, NULL, 0,
+ (uint8_t *) &N_sr25519_signdata.signdata, sr25519_signdataLen, signature + 1);
+ crypto_scalarmult_ristretto255_base_sdk(signature + 1, signature + 1 + PK_LEN_25519);
+ sign_sr25519_phase2((uint8_t *) &N_sr25519_signdata.sk, (uint8_t *) &N_sr25519_signdata.pk, NULL, 0,
+ (uint8_t *) &N_sr25519_signdata.signdata, sr25519_signdataLen, signature + 1);
+ MEMCPY_NV((void *) &N_sr25519_signdata.signature, signature, SIG_PLUS_TYPE_LEN);
+ }
+ CATCH_ALL
+ {
+ CLOSE_TRY;
+ return zxerr_unknown;
+ };
+ FINALLY
+ {
+ MEMZERO(signature + SIG_PLUS_TYPE_LEN, signatureMaxlen - SIG_PLUS_TYPE_LEN);
+ }
+ }
+ END_TRY;
+ return zxerr_ok;
+}
+#endif
+
+zxerr_t crypto_fillAddress(key_kind_e addressKind, uint8_t *buffer, uint16_t bufferLen, uint16_t *addrResponseLen) {
+ if (bufferLen < PK_LEN_25519 + SS58_ADDRESS_MAX_LEN) {
+ return zxerr_unknown;
+ }
+ MEMZERO(buffer, bufferLen);
+ CHECK_ZXERR(crypto_extractPublicKey(addressKind, hdPath, buffer, bufferLen));
+
+ size_t outLen = crypto_SS58EncodePubkey(buffer + PK_LEN_25519,
+ bufferLen - PK_LEN_25519,
+ PK_ADDRESS_TYPE, buffer);
+ if (outLen == 0) {
+ MEMZERO(buffer, bufferLen);
+ return zxerr_unknown;
+ }
+
+ *addrResponseLen = PK_LEN_25519 + outLen;
+ return zxerr_ok;
+}
diff --git a/app/src/crypto.h b/app/src/crypto.h
new file mode 100644
index 0000000..20643e7
--- /dev/null
+++ b/app/src/crypto.h
@@ -0,0 +1,99 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include "coin.h"
+#include
+#include
+#include "zxerror.h"
+
+#ifdef SUPPORT_SR25519
+// Flash
+typedef struct {
+ uint8_t sk[SK_LEN_25519];
+ uint8_t pk[PK_LEN_25519];
+ uint8_t signdata[MAX_SIGN_SIZE];
+ uint8_t signature[SIG_PLUS_TYPE_LEN];
+} sr25519_signdata_t;
+
+extern uint16_t sr25519_signdataLen;
+
+#if defined(TARGET_NANOS) || defined(TARGET_NANOX)
+sr25519_signdata_t NV_CONST N_srdata_impl __attribute__ ((aligned(64)));
+#define N_sr25519_signdata (*(NV_VOLATILE sr25519_signdata_t *)PIC(&N_srdata_impl))
+#endif
+
+zxerr_t zeroize_sr25519_signdata() {
+ uint8_t dummysk[SK_LEN_25519];
+ MEMZERO(dummysk, SK_LEN_25519);
+ uint8_t dummypk[PK_LEN_25519];
+ MEMZERO(dummypk, PK_LEN_25519);
+ uint8_t dummysigndata[MAX_SIGN_SIZE];
+ MEMZERO(dummysigndata, MAX_SIGN_SIZE);
+ uint8_t dummysignature[SIG_PLUS_TYPE_LEN];
+ MEMZERO(dummysignature, SIG_PLUS_TYPE_LEN);
+
+ MEMCPY_NV((void *) &N_sr25519_signdata.sk, dummysk, SK_LEN_25519);
+ MEMCPY_NV((void *) &N_sr25519_signdata.pk, dummypk, PK_LEN_25519);
+ MEMCPY_NV((void *) &N_sr25519_signdata.signdata, dummysigndata, MAX_SIGN_SIZE);
+ MEMCPY_NV((void *) &N_sr25519_signdata.signature, dummysignature, SIG_PLUS_TYPE_LEN);
+ sr25519_signdataLen = 0;
+ return zxerr_ok;
+}
+
+#else
+
+zxerr_t zeroize_sr25519_signdata() {
+ return zxerr_ok;
+}
+
+#endif
+
+//#define SS58_BLAKE_PREFIX (const unsigned char *) "SS58PRE"
+//#define SS58_BLAKE_PREFIX_LEN 7
+#define SS58_ADDRESS_MAX_LEN 60u
+
+#define PREFIX_SIGNATURE_TYPE_ED25519 0
+#define PREFIX_SIGNATURE_TYPE_SR25519 1
+#define PREFIX_SIGNATURE_TYPE_EDCSA 2
+#define MIN_BUFFER_LENGTH 235
+#define START_BUFFER 33
+
+extern uint32_t hdPath[HDPATH_LEN_DEFAULT];
+
+uint8_t crypto_SS58EncodePubkey(uint8_t *buffer, uint16_t buffer_len,
+ uint8_t addressType, const uint8_t *pubkey);
+
+zxerr_t crypto_fillAddress(key_kind_e addressKind, uint8_t *buffer, uint16_t bufferLen, uint16_t *addrResponseLen);
+
+zxerr_t crypto_sign_sr25519_prephase(uint8_t *buffer, uint16_t bufferLen, const uint8_t *message, uint16_t messageLen);
+
+zxerr_t crypto_sign_sr25519(uint8_t *signature, uint16_t signatureMaxlen,
+ uint16_t *signatureLen);
+
+zxerr_t crypto_sign_ed25519(uint8_t *signature, uint16_t signatureMaxlen,
+ const uint8_t *message, uint16_t messageLen,
+ uint16_t *signatureLen);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/app/src/crypto_helper.c b/app/src/crypto_helper.c
new file mode 100644
index 0000000..199414c
--- /dev/null
+++ b/app/src/crypto_helper.c
@@ -0,0 +1,73 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#include "crypto_helper.h"
+#include "base58.h"
+
+#if defined(TARGET_NANOS) || defined(TARGET_NANOX)
+#include "cx.h"
+
+int ss58hash(const unsigned char *in, unsigned int inLen,
+ unsigned char *out, unsigned int outLen) {
+
+ cx_blake2b_t ctx;
+ cx_blake2b_init(&ctx, 512);
+ cx_hash(&ctx.header, 0, SS58_BLAKE_PREFIX, SS58_BLAKE_PREFIX_LEN, NULL, 0);
+ cx_hash(&ctx.header, CX_LAST, in, inLen, out, outLen);
+
+ return 0;
+}
+#else
+
+#include
+#include "blake2.h"
+
+int ss58hash(const unsigned char *in, unsigned int inLen,
+ unsigned char *out, unsigned int outLen) {
+ blake2b_state s;
+ blake2b_init(&s, 64);
+ blake2b_update(&s, SS58_BLAKE_PREFIX, SS58_BLAKE_PREFIX_LEN);
+ blake2b_update(&s, in, inLen);
+ blake2b_final(&s, out, outLen);
+ return 0;
+}
+
+#endif
+
+uint8_t crypto_SS58EncodePubkey(uint8_t *buffer, uint16_t buffer_len,
+ uint8_t addressType, const uint8_t *pubkey) {
+ if (buffer == NULL || buffer_len < SS58_ADDRESS_MAX_LEN) {
+ return 0;
+ }
+ if (pubkey == NULL) {
+ return 0;
+ }
+ MEMZERO(buffer, buffer_len);
+
+ uint8_t unencoded[35];
+ uint8_t hash[64];
+
+ unencoded[0] = addressType; // address type
+ MEMCPY(unencoded + 1, pubkey, 32); // account id
+ ss58hash((uint8_t *) unencoded, 33, hash, 64);
+ unencoded[33] = hash[0];
+ unencoded[34] = hash[1];
+
+ size_t outLen = buffer_len;
+ encode_base58(unencoded, 35, buffer, &outLen);
+
+ return outLen;
+}
diff --git a/app/src/crypto_helper.h b/app/src/crypto_helper.h
new file mode 100644
index 0000000..090875f
--- /dev/null
+++ b/app/src/crypto_helper.h
@@ -0,0 +1,38 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include "coin.h"
+#include
+#include
+#include "zxerror.h"
+
+#define SS58_BLAKE_PREFIX (const unsigned char *) "SS58PRE"
+#define SS58_BLAKE_PREFIX_LEN 7
+#define SS58_ADDRESS_MAX_LEN 60u
+
+uint8_t crypto_SS58EncodePubkey(uint8_t *buffer, uint16_t buffer_len,
+ uint8_t addressType, const uint8_t *pubkey);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/app/src/parser.c b/app/src/parser.c
new file mode 100644
index 0000000..58d9a65
--- /dev/null
+++ b/app/src/parser.c
@@ -0,0 +1,256 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#include
+#include
+#include "zbuffer.h"
+#include "app_mode.h"
+#include "parser.h"
+#include "coin.h"
+#include "substrate_dispatch.h"
+
+#if defined(TARGET_NANOX)
+// For some reason NanoX requires this function
+void __assert_fail(const char * assertion, const char * file, unsigned int line, const char * function){
+ while(1) {};
+}
+#endif
+
+#define FIELD_FIXED_TOTAL_COUNT 7
+
+#define FIELD_METHOD 0
+#define FIELD_NETWORK 1
+#define FIELD_NONCE 2
+#define FIELD_TIP 3
+#define FIELD_ERA_PHASE 4
+#define FIELD_ERA_PERIOD 5
+#define FIELD_BLOCK_HASH 6
+
+#define EXPERT_FIELDS_TOTAL_COUNT 5
+
+parser_error_t parser_parse(parser_context_t *ctx, const uint8_t *data, size_t dataLen, parser_tx_t *tx_obj) {
+ CHECK_PARSER_ERR(parser_init(ctx, data, dataLen))
+ ctx->tx_obj = tx_obj;
+ ctx->tx_obj->nestCallIdx.slotIdx = 0;
+ ctx->tx_obj->nestCallIdx._lenBuffer = 0;
+ ctx->tx_obj->nestCallIdx._ptr = NULL;
+ ctx->tx_obj->nestCallIdx._nextPtr = NULL;
+ ctx->tx_obj->nestCallIdx.isTail = true;
+ parser_error_t err = _readTx(ctx, ctx->tx_obj);
+ CTX_CHECK_AVAIL(ctx, 0)
+ zb_check_canary();
+
+ return err;
+}
+
+__Z_INLINE bool parser_show_expert_fields() {
+ return app_mode_expert();
+}
+
+bool parser_show_tip(const parser_context_t *ctx){
+ if (ctx->tx_obj->tip.value.len <= 4) {
+ uint64_t v;
+ _getValue(&ctx->tx_obj->tip.value, &v);
+ if ( v == 0 ){
+ return false;
+ }
+ }
+ return true;
+}
+
+parser_error_t parser_validate(const parser_context_t *ctx) {
+ // Iterate through all items to check that all can be shown and are valid
+ uint8_t numItems = 0;
+ CHECK_PARSER_ERR(parser_getNumItems(ctx, &numItems))
+
+ char tmpKey[40];
+ char tmpVal[40];
+
+ for (uint8_t idx = 0; idx < numItems; idx++) {
+ uint8_t pageCount = 0;
+ CHECK_PARSER_ERR(parser_getItem(ctx, idx, tmpKey, sizeof(tmpKey), tmpVal, sizeof(tmpVal), 0, &pageCount))
+ }
+
+ return parser_ok;
+}
+
+parser_error_t parser_getNumItems(const parser_context_t *ctx, uint8_t *num_items) {
+ uint8_t methodArgCount = _getMethod_NumItems(ctx->tx_obj->transactionVersion,
+ ctx->tx_obj->callIndex.moduleIdx,
+ ctx->tx_obj->callIndex.idx);
+
+ uint8_t total = FIELD_FIXED_TOTAL_COUNT;
+ if(!parser_show_tip(ctx)){
+ total -= 1;
+ }
+ if(!parser_show_expert_fields()){
+ total -= EXPERT_FIELDS_TOTAL_COUNT;
+
+ for (uint8_t argIdx = 0; argIdx < methodArgCount; argIdx++) {
+ bool isArgExpert = _getMethod_ItemIsExpert(ctx->tx_obj->transactionVersion,
+ ctx->tx_obj->callIndex.moduleIdx,
+ ctx->tx_obj->callIndex.idx, argIdx);
+ if(isArgExpert) {
+ methodArgCount--;
+ }
+ }
+ }
+
+ *num_items = total + methodArgCount;
+ return parser_ok;
+}
+
+parser_error_t parser_getItem(const parser_context_t *ctx,
+ uint8_t displayIdx,
+ char *outKey, uint16_t outKeyLen,
+ char *outVal, uint16_t outValLen,
+ uint8_t pageIdx, uint8_t *pageCount) {
+ MEMZERO(outKey, outKeyLen);
+ MEMZERO(outVal, outValLen);
+ snprintf(outKey, outKeyLen, "?");
+ snprintf(outVal, outValLen, "?");
+ *pageCount = 1;
+
+ uint8_t numItems;
+ CHECK_PARSER_ERR(parser_getNumItems(ctx, &numItems))
+ CHECK_APP_CANARY()
+
+ if (displayIdx < 0 || displayIdx >= numItems) {
+ return parser_no_data;
+ }
+
+ parser_error_t err = parser_ok;
+ if (displayIdx == FIELD_METHOD) {
+ snprintf(outKey, outKeyLen, "%s", _getMethod_ModuleName(ctx->tx_obj->transactionVersion, ctx->tx_obj->callIndex.moduleIdx));
+ snprintf(outVal, outValLen, "%s", _getMethod_Name(ctx->tx_obj->transactionVersion,
+ ctx->tx_obj->callIndex.moduleIdx,
+ ctx->tx_obj->callIndex.idx));
+ return err;
+ }
+
+ // VARIABLE ARGUMENTS
+ uint8_t methodArgCount = _getMethod_NumItems(ctx->tx_obj->transactionVersion,
+ ctx->tx_obj->callIndex.moduleIdx,
+ ctx->tx_obj->callIndex.idx);
+ uint8_t argIdx = displayIdx - 1;
+
+
+ if (!parser_show_expert_fields()) {
+ // Search for the next non expert item
+ while ((argIdx < methodArgCount) && _getMethod_ItemIsExpert(ctx->tx_obj->transactionVersion,
+ ctx->tx_obj->callIndex.moduleIdx,
+ ctx->tx_obj->callIndex.idx, argIdx)) {
+ argIdx++;
+ displayIdx++;
+ }
+ }
+
+ if (argIdx < methodArgCount) {
+ snprintf(outKey, outKeyLen, "%s",
+ _getMethod_ItemName(ctx->tx_obj->transactionVersion,
+ ctx->tx_obj->callIndex.moduleIdx,
+ ctx->tx_obj->callIndex.idx,
+ argIdx));
+
+ err = _getMethod_ItemValue(ctx->tx_obj->transactionVersion,
+ &ctx->tx_obj->method,
+ ctx->tx_obj->callIndex.moduleIdx, ctx->tx_obj->callIndex.idx, argIdx,
+ outVal, outValLen,
+ pageIdx, pageCount);
+ return err;
+ } else {
+ // CONTINUE WITH FIXED ARGUMENTS
+ displayIdx -= methodArgCount;
+ if( displayIdx == FIELD_NETWORK ){
+ if (_getAddressType() == PK_ADDRESS_TYPE) {
+ if(parser_show_expert_fields()){
+ snprintf(outKey, outKeyLen, "Chain");
+ snprintf(outVal, outValLen, COIN_NAME);
+ return err;
+ }
+ }else {
+ snprintf(outKey, outKeyLen, "Genesis Hash");
+ _toStringHash(&ctx->tx_obj->genesisHash,
+ outVal, outValLen,
+ pageIdx, pageCount);
+ return err;
+ }
+ }
+
+ if( !parser_show_expert_fields() ){
+ displayIdx++;
+ }
+
+ if( displayIdx == FIELD_NONCE && parser_show_expert_fields()) {
+ snprintf(outKey, outKeyLen, "Nonce");
+ return _toStringCompactIndex(&ctx->tx_obj->nonce,
+ outVal, outValLen,
+ pageIdx, pageCount);
+ }
+
+ if( !parser_show_expert_fields() ){
+ displayIdx++;
+ }
+
+ if( displayIdx == FIELD_TIP && parser_show_tip(ctx)) {
+ snprintf(outKey, outKeyLen, "Tip");
+ err = _toStringCompactBalance(&ctx->tx_obj->tip,
+ outVal, outValLen,
+ pageIdx, pageCount);
+ if( err != parser_ok ) return err;
+ number_inplace_trimming(outVal, 1);
+ return err;
+ }
+
+ if(!parser_show_tip(ctx)){
+ displayIdx++;
+ }
+
+ if( displayIdx == FIELD_ERA_PHASE && parser_show_expert_fields() ) {
+ snprintf(outKey, outKeyLen, "Era Phase");
+ uint64_to_str(outVal, outValLen, ctx->tx_obj->era.phase);
+ return err;
+ }
+
+ if( !parser_show_expert_fields() ){
+ displayIdx++;
+ }
+
+ if( displayIdx == FIELD_ERA_PERIOD && parser_show_expert_fields() ) {
+ snprintf(outKey, outKeyLen, "Era Period");
+ uint64_to_str(outVal, outValLen, ctx->tx_obj->era.period);
+ return err;
+ }
+
+ if( !parser_show_expert_fields() ){
+ displayIdx++;
+ }
+
+ if( displayIdx == FIELD_BLOCK_HASH && parser_show_expert_fields() ) {
+ snprintf(outKey, outKeyLen, "Block");
+ _toStringHash(&ctx->tx_obj->blockHash,
+ outVal, outValLen,
+ pageIdx, pageCount);
+ return err;
+ }
+
+ return parser_no_data;
+ }
+
+}
+
+
+
diff --git a/app/src/parser_impl.c b/app/src/parser_impl.c
new file mode 100644
index 0000000..838670f
--- /dev/null
+++ b/app/src/parser_impl.c
@@ -0,0 +1,521 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#include
+#include "parser_impl.h"
+#include "parser_txdef.h"
+#include "coin.h"
+#include "crypto_helper.h"
+#include "bignum.h"
+#include "substrate_types.h"
+#include "substrate_dispatch.h"
+
+parser_error_t parser_init_context(parser_context_t *ctx,
+ const uint8_t *buffer,
+ uint16_t bufferSize) {
+ ctx->offset = 0;
+ ctx->buffer = NULL;
+ ctx->bufferLen = 0;
+
+ if (bufferSize == 0 || buffer == NULL) {
+ // Not available, use defaults
+ return parser_init_context_empty;
+ }
+
+ ctx->buffer = buffer;
+ ctx->bufferLen = bufferSize;
+ return parser_ok;
+}
+
+parser_error_t parser_init(parser_context_t *ctx, const uint8_t *buffer, uint16_t bufferSize) {
+ CHECK_PARSER_ERR(parser_init_context(ctx, buffer, bufferSize))
+ return parser_ok;
+}
+
+const char *parser_getErrorDescription(parser_error_t err) {
+ switch (err) {
+ // General errors
+ case parser_ok:
+ return "No error";
+ case parser_no_data:
+ return "No more data";
+ case parser_init_context_empty:
+ return "Initialized empty context";
+ case parser_display_idx_out_of_range:
+ return "display_idx_out_of_range";
+ case parser_display_page_out_of_range:
+ return "display_page_out_of_range";
+ // Coin specific
+ case parser_spec_not_supported:
+ return "Spec version not supported";
+ case parser_tx_version_not_supported:
+ return "Txn version not supported";
+ case parser_not_allowed:
+ return "Not allowed";
+ case parser_not_supported:
+ return "Not supported";
+ case parser_unexpected_buffer_end:
+ return "Unexpected buffer end";
+ case parser_unexpected_value:
+ return "Unexpected value";
+ case parser_value_out_of_range:
+ return "Value out of range";
+ case parser_value_too_many_bytes:
+ return "Value too many bytes";
+ case parser_unexpected_module:
+ return "Unexpected module";
+ case parser_unexpected_callIndex:
+ return "Unexpected call index";
+ case parser_unexpected_unparsed_bytes:
+ return "Unexpected unparsed bytes";
+ case parser_print_not_supported:
+ return "Value cannot be printed";
+ case parser_tx_nesting_limit_reached:
+ return "Max nested calls reached";
+ case parser_tx_call_vec_too_large:
+ return "Call vector exceeds limit";
+ default:
+ return "Unrecognized error code";
+ }
+}
+
+GEN_DEF_READFIX_UNSIGNED(8)
+
+GEN_DEF_READFIX_UNSIGNED(16)
+
+GEN_DEF_READFIX_UNSIGNED(32)
+
+GEN_DEF_READFIX_UNSIGNED(64)
+
+parser_error_t _readBool(parser_context_t *c, pd_bool_t *v) {
+ CHECK_INPUT();
+
+ const uint8_t p = *(c->buffer + c->offset);
+ CTX_CHECK_AND_ADVANCE(c, 1)
+
+ switch (p) {
+ case 0x00:
+ *v = bool_false;
+ break;
+ case 0x01:
+ *v = bool_true;
+ break;
+ default:
+ return parser_unexpected_value;
+ }
+ return parser_ok;
+}
+
+parser_error_t _readCompactInt(parser_context_t *c, compactInt_t *v) {
+ CHECK_INPUT();
+
+ v->ptr = c->buffer + c->offset;
+ const uint8_t mode = *v->ptr & 0x03u; // get mode from two least significant bits
+
+ uint64_t tmp;
+ switch (mode) {
+ case 0: // single byte
+ v->len = 1;
+ CTX_CHECK_AND_ADVANCE(c, v->len)
+ _getValue(v, &tmp);
+ break;
+ case 1: // 2-byte
+ v->len = 2;
+ CTX_CHECK_AND_ADVANCE(c, v->len)
+ _getValue(v, &tmp);
+ break;
+ case 2: // 4-byte
+ v->len = 4;
+ CTX_CHECK_AND_ADVANCE(c, v->len)
+ _getValue(v, &tmp);
+ break;
+ case 3: // bigint
+ v->len = (*v->ptr >> 2u) + 4 + 1;
+ CTX_CHECK_AND_ADVANCE(c, v->len)
+ break;
+ default:
+ // this is actually impossible
+ return parser_unexpected_value;
+ }
+
+ return parser_ok;
+}
+
+parser_error_t _getValue(const compactInt_t *c, uint64_t *v) {
+ *v = 0;
+
+ switch (c->len) {
+ case 1:
+ *v = (*c->ptr) >> 2u;
+ break;
+ case 2:
+ *v = (*c->ptr) >> 2u;
+ *v += *(c->ptr + 1) << 6u;
+ if (*v < 64) {
+ return parser_value_out_of_range;
+ }
+ break;
+ case 4:
+ *v = (*c->ptr) >> 2u;
+ *v += *(c->ptr + 1) << 6u;
+ *v += *(c->ptr + 2) << (8u + 6u);
+ *v += *(c->ptr + 3) << (16u + 6u);
+ if (*v < 16383) {
+ return parser_value_out_of_range;
+ }
+ break;
+ default:
+ return parser_value_out_of_range;
+ }
+
+ return parser_ok;
+}
+
+parser_error_t _toStringCompactInt(const compactInt_t *c,
+ uint8_t decimalPlaces,
+ char postfix,
+ char prefix[],
+ char *outValue, uint16_t outValueLen,
+ uint8_t pageIdx, uint8_t *pageCount) {
+ char bufferUI[200];
+ MEMZERO(outValue, outValueLen);
+ MEMZERO(bufferUI, sizeof(bufferUI));
+ *pageCount = 1;
+
+ if (c->len <= 4) {
+ uint64_t v;
+ _getValue(c, &v);
+ if (uint64_to_str(bufferUI, sizeof(bufferUI), v) != NULL) {
+ return parser_unexpected_value;
+ }
+ } else {
+ // This is longer number
+ uint8_t bcdOut[100];
+ const uint16_t bcdOutLen = sizeof(bcdOut);
+
+ bignumLittleEndian_to_bcd(bcdOut, bcdOutLen, c->ptr + 1, c->len - 1);
+ if (!bignumLittleEndian_bcdprint(bufferUI, sizeof(bufferUI), bcdOut, bcdOutLen))
+ return parser_unexpected_buffer_end;
+ }
+
+ // Format number
+ if (intstr_to_fpstr_inplace(bufferUI, sizeof(bufferUI), decimalPlaces) == 0){
+ return parser_unexpected_value;
+ }
+
+ // Add prefix
+ if (strlen(prefix) > 0) {
+ size_t size = strlen(bufferUI) + strlen(prefix) + 2;
+ char _tmpBuffer[200];
+ MEMZERO(_tmpBuffer, sizeof(_tmpBuffer));
+ strcat(_tmpBuffer, prefix);
+ strcat(_tmpBuffer, " ");
+ strcat(_tmpBuffer, bufferUI);
+ // print length: strlen(value) + strlen(prefix) + strlen(" ") + strlen("\0")
+ MEMZERO(bufferUI, sizeof(bufferUI));
+ snprintf(bufferUI, size, "%s", _tmpBuffer);
+ }
+
+ // Add postfix
+ if (postfix > 32 && postfix < 127) {
+ const uint16_t p = strlen(bufferUI);
+ bufferUI[p] = postfix;
+ }
+
+ pageString(outValue, outValueLen, bufferUI, pageIdx, pageCount);
+
+ return parser_ok;
+}
+
+//////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////
+
+parser_error_t _readCallIndex(parser_context_t *c, pd_CallIndex_t *v) {
+ CHECK_INPUT();
+
+ CHECK_ERROR(_readUInt8(c, &v->moduleIdx));
+ CHECK_ERROR(_readUInt8(c, &v->idx));
+ return parser_ok;
+}
+
+parser_error_t _readEra(parser_context_t *c, pd_ExtrinsicEra_t *v) {
+ CHECK_INPUT();
+ // https://github.com/paritytech/substrate/blob/fc3adc87dc806237eb7371c1d21055eea1702be0/core/sr-primitives/src/generic/era.rs#L117
+
+ v->type = eEraImmortal;
+
+ uint8_t first;
+ CHECK_ERROR(_readUInt8(c, &first));
+ if (first == 0) { return parser_ok; }
+
+ v->type = eEraMortal;
+ uint64_t encoded = first;
+ CHECK_ERROR(_readUInt8(c, &first));
+ encoded += (uint64_t) first << 8u;
+
+ v->period = 2U << (encoded % (1u << 4u));
+ uint64_t quantize_factor = (v->period >> 12u);
+ quantize_factor = (quantize_factor == 0 ? 1 : quantize_factor);
+
+ v->phase = (encoded >> 4u) * quantize_factor;
+
+ if (v->period >= 4 && v->phase < v->period) {
+ return parser_ok;
+ }
+
+ return parser_unexpected_value;
+}
+
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+
+parser_error_t _readCompactIndex(parser_context_t *c, pd_CompactIndex_t *v) {
+ CHECK_INPUT();
+ CHECK_ERROR(_readCompactInt(c, &v->index));
+ return parser_ok;
+}
+
+parser_error_t _readCompactBalance(parser_context_t *c, pd_CompactBalance_t *v) {
+ CHECK_INPUT();
+ CHECK_ERROR(_readCompactInt(c, &v->value));
+ return parser_ok;
+}
+
+parser_error_t _toStringCompactIndex(const pd_CompactIndex_t *v,
+ char *outValue, uint16_t outValueLen,
+ uint8_t pageIdx, uint8_t *pageCount) {
+ return _toStringCompactInt(&v->index, 0, 0, "", outValue, outValueLen, pageIdx, pageCount);
+}
+
+parser_error_t _toStringCompactBalance(const pd_CompactBalance_t *v,
+ char *outValue, uint16_t outValueLen,
+ uint8_t pageIdx, uint8_t *pageCount) {
+ CHECK_ERROR(_toStringCompactInt(&v->value, COIN_AMOUNT_DECIMAL_PLACES, 0, COIN_TICKER, outValue, outValueLen, pageIdx, pageCount))
+ number_inplace_trimming(outValue, 1);
+ return parser_ok;
+}
+
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+
+parser_error_t _checkVersions(parser_context_t *c) {
+ // Methods are not length delimited so in order to retrieve the specVersion
+ // it is necessary to parse from the back.
+ // The transaction is expect to end in
+ // [4 bytes] specVersion
+ // [4 bytes] transactionVersion
+ // [32 bytes] genesisHash
+ // [32 bytes] blockHash
+ const uint16_t specOffsetFromBack = 4 + 4 + 32 + 32;
+ if (c->bufferLen < specOffsetFromBack) {
+ return parser_unexpected_buffer_end;
+ }
+
+ uint8_t *p = (uint8_t *) (c->buffer + c->bufferLen - specOffsetFromBack);
+ uint32_t specVersion = 0;
+ specVersion += (uint32_t) p[0] << 0u;
+ specVersion += (uint32_t) p[1] << 8u;
+ specVersion += (uint32_t) p[2] << 16u;
+ specVersion += (uint32_t) p[3] << 24u;
+
+ p += 4;
+ uint32_t transactionVersion = 0;
+ transactionVersion += (uint32_t) p[0] << 0u;
+ transactionVersion += (uint32_t) p[1] << 8u;
+ transactionVersion += (uint32_t) p[2] << 16u;
+ transactionVersion += (uint32_t) p[3] << 24u;
+
+ if (transactionVersion != (SUPPORTED_TX_VERSION_CURRENT) &&
+ transactionVersion != (SUPPORTED_TX_VERSION_PREVIOUS) ) {
+ return parser_tx_version_not_supported;
+ }
+
+ if (specVersion < SUPPORTED_MINIMUM_SPEC_VERSION) {
+ return parser_spec_not_supported;
+ }
+
+ c->tx_obj->specVersion = specVersion;
+ c->tx_obj->transactionVersion = transactionVersion;
+
+ return parser_ok;
+}
+
+uint8_t __address_type;
+
+uint8_t _getAddressType() {
+ return __address_type;
+}
+
+uint8_t _detectAddressType(const parser_context_t *c) {
+ char hashstr[65];
+ uint8_t pc;
+
+ if (c->tx_obj->genesisHash._ptr != NULL) {
+ _toStringHash(&c->tx_obj->genesisHash, hashstr, 65, 0, &pc);
+
+ // Compare with known genesis hashes
+ if (strcmp(hashstr, COIN_GENESIS_HASH) == 0) {
+ return PK_ADDRESS_TYPE;
+ }
+ }
+
+ return 42;
+}
+
+parser_error_t _readTx(parser_context_t *c, parser_tx_t *v) {
+ CHECK_INPUT();
+
+ // Reverse parse to retrieve spec before forward parsing
+ CHECK_ERROR(_checkVersions(c));
+
+ // Now forward parse
+ CHECK_ERROR(_readCallIndex(c, &v->callIndex));
+ CHECK_ERROR(_readMethod(c, v->callIndex.moduleIdx, v->callIndex.idx, &v->method));
+ CHECK_ERROR(_readEra(c, &v->era));
+ CHECK_ERROR(_readCompactIndex(c, &v->nonce));
+ CHECK_ERROR(_readCompactBalance(c, &v->tip));
+ CHECK_ERROR(_readUInt32(c, &v->specVersion));
+ CHECK_ERROR(_readUInt32(c, &v->transactionVersion));
+ CHECK_ERROR(_readHash(c, &v->genesisHash));
+ CHECK_ERROR(_readHash(c, &v->blockHash));
+
+ if (c->offset < c->bufferLen) {
+ return parser_unexpected_unparsed_bytes;
+ }
+
+ if (c->offset > c->bufferLen) {
+ return parser_unexpected_buffer_end;
+ }
+
+ __address_type = _detectAddressType(c);
+
+ return parser_ok;
+}
+
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+
+parser_error_t _readAddress(parser_context_t *c, pd_Address_t *v) {
+ CHECK_INPUT();
+ // Based on
+ // https://github.com/paritytech/substrate/blob/fc3adc87dc806237eb7371c1d21055eea1702be0/srml/indices/src/address.rs#L66
+
+ uint8_t tmp;
+ CHECK_ERROR(_readUInt8(c, &tmp));
+
+ switch (tmp) {
+ case 0xFF: {
+ v->type = eAddressId;
+ v->idPtr = c->buffer + c->offset;
+ CTX_CHECK_AND_ADVANCE(c, 32);
+ break;
+ }
+ case 0xFE: {
+ compactInt_t ci;
+ CHECK_ERROR(_readCompactInt(c, &ci));
+
+ v->type = eAddressIndex;
+ CHECK_ERROR(_getValue(&ci, &v->idx));
+
+ if (v->idx <= 0xffffffffu) {
+ return parser_unexpected_value;
+ }
+ break;
+ }
+ case 0xFD: {
+ uint32_t tmpval;
+ CHECK_ERROR(_readUInt32(c, &tmpval));
+ v->type = eAddressIndex;
+ v->idx = tmpval;
+ if (v->idx <= 0xFFFF) {
+ return parser_unexpected_value;
+ }
+ break;
+ }
+ case 0xFC: {
+ uint16_t tmpval;
+ CHECK_ERROR(_readUInt16(c, &tmpval));
+ v->type = eAddressIndex;
+ v->idx = tmpval;
+ if (v->idx <= 0xEF) {
+ return parser_unexpected_value;
+ }
+ break;
+ }
+ default:
+ if (tmp <= 0xEF) {
+ v->type = eAddressIndex;
+ v->idx = tmp;
+ return parser_ok;
+ }
+
+ return parser_unexpected_value;
+ }
+
+ return parser_ok;
+}
+
+parser_error_t _toStringPubkeyAsAddress(const uint8_t *pubkey,
+ char *outValue, uint16_t outValueLen,
+ uint8_t pageIdx, uint8_t *pageCount) {
+ char bufferUI[200];
+
+ if (crypto_SS58EncodePubkey((uint8_t *) bufferUI, sizeof(bufferUI), __address_type, pubkey) == 0) {
+ return parser_no_data;
+ }
+
+ pageString(outValue, outValueLen, bufferUI, pageIdx, pageCount);
+ if (pageIdx >= *pageCount) {
+ return parser_no_data;
+ }
+ return parser_ok;
+}
+
+parser_error_t _toStringAddress(const pd_Address_t *v,
+ char *outValue, uint16_t outValueLen,
+ uint8_t pageIdx, uint8_t *pageCount) {
+ MEMZERO(outValue, outValueLen);
+ if (v == NULL) {
+ return parser_ok;
+ }
+
+ *pageCount = 1;
+ switch (v->type) {
+ case eAddressIndex:
+ return parser_not_supported;
+ case eAddressId: {
+ return _toStringPubkeyAsAddress(v->idPtr,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ }
+ }
+
+ return parser_ok;
+}
diff --git a/app/src/parser_impl.h b/app/src/parser_impl.h
new file mode 100644
index 0000000..2f79e8c
--- /dev/null
+++ b/app/src/parser_impl.h
@@ -0,0 +1,198 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma once
+
+#include "parser_common.h"
+#include
+#include "zxtypes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include
+#include
+
+
+// Checks that there are at least SIZE bytes available in the buffer
+#define CTX_CHECK_AVAIL(CTX, SIZE) \
+ if ( (CTX) == NULL || ((CTX)->offset + SIZE) > (CTX)->bufferLen) { return parser_unexpected_buffer_end; }
+
+#define CTX_CHECK_AND_ADVANCE(CTX, SIZE) \
+ CTX_CHECK_AVAIL((CTX), (SIZE)) \
+ (CTX)->offset += (SIZE);
+
+// Checks function input is valid
+#define CHECK_INPUT() \
+ if (v == NULL) { return parser_no_data; } \
+ CTX_CHECK_AVAIL(c, 1) // Checks that there is something available in the buffer
+
+#define CLEAN_AND_CHECK() \
+ MEMZERO(outValue, outValueLen); \
+ if (v == NULL) { *pageCount = 0; return parser_no_data; }
+
+#define GEN_DEF_READARRAY(SIZE) \
+ v->_ptr = c->buffer + c->offset; \
+ CTX_CHECK_AND_ADVANCE(c, SIZE) \
+ return parser_ok;
+
+#define GEN_DEF_TOSTRING_ARRAY(SIZE) \
+ CLEAN_AND_CHECK(); \
+ if (v->_ptr == NULL || outValueLen == 0 ) return parser_unexpected_buffer_end; \
+ const uint16_t outLenNormalized = (outValueLen - 1) / 2; \
+ *pageCount = SIZE / outLenNormalized; \
+ if (SIZE % outLenNormalized != 0) *pageCount+=1; \
+ const uint16_t pageOffset = pageIdx * outLenNormalized; \
+ uint16_t loopmax = outLenNormalized; \
+ if (loopmax > SIZE - pageOffset) loopmax = SIZE - pageOffset; \
+ for (uint16_t i = 0; i < loopmax; i++) { \
+ const uint16_t offset = i << 1u; \
+ const uint8_t *c = v->_ptr + pageOffset; \
+ snprintf(outValue + offset, outValueLen - offset, "%02x", c[i]); \
+ } \
+ return parser_ok;
+
+#define GEN_DEF_TOSTRING_ENUM(NAME) \
+(*pageCount)++; \
+if(pageIdx == 0) { snprintf(outValue, outValueLen, NAME ); \
+return parser_ok; \
+} \
+pageIdx--; \
+
+#define GEN_DEC_READFIX_UNSIGNED(BITS) parser_error_t _readUInt ## BITS(parser_context_t *ctx, uint ## BITS ##_t *value)
+#define GEN_DEF_READFIX_UNSIGNED(BITS) parser_error_t _readUInt ## BITS(parser_context_t *ctx, uint ## BITS ##_t *value) \
+{ \
+ if (value == NULL) return parser_no_data; \
+ *value = 0u; \
+ for(uint8_t i=0u; i < (BITS##u>>3u); i++, ctx->offset++) { \
+ if (ctx->offset >= ctx->bufferLen) return parser_unexpected_buffer_end; \
+ *value += (uint ## BITS ##_t) *(ctx->buffer + ctx->offset) << (8u*i); \
+ } \
+ return parser_ok; \
+}
+
+GEN_DEC_READFIX_UNSIGNED(8);
+GEN_DEC_READFIX_UNSIGNED(16);
+GEN_DEC_READFIX_UNSIGNED(32);
+GEN_DEC_READFIX_UNSIGNED(64);
+
+#define GEN_DEF_READVECTOR(TYPE) \
+ pd_##TYPE##_t dummy; \
+ compactInt_t clen; \
+ CHECK_PARSER_ERR(_readCompactInt(c, &clen)); \
+ CHECK_PARSER_ERR(_getValue(&clen, &v->_len)); \
+ v->_ptr = c->buffer + c->offset; \
+ v->_lenBuffer = c->offset; \
+ for (uint64_t i = 0; i < v->_len; i++ ) CHECK_ERROR(_read##TYPE(c, &dummy)); \
+ v->_lenBuffer = c->offset - v->_lenBuffer; \
+ return parser_ok;
+
+#define GEN_DEF_READVECTOR_VERSION(TYPE, VERSION) \
+ pd_##TYPE##_V##VERSION##_t dummy; \
+ compactInt_t clen; \
+ CHECK_PARSER_ERR(_readCompactInt(c, &clen)); \
+ CHECK_PARSER_ERR(_getValue(&clen, &v->_len)); \
+ v->_ptr = c->buffer + c->offset; \
+ v->_lenBuffer = c->offset; \
+ for (uint64_t i = 0; i < v->_len; i++ ) CHECK_ERROR(_read##TYPE##_V##VERSION (c, &dummy)); \
+ v->_lenBuffer = c->offset - v->_lenBuffer; \
+ return parser_ok;
+
+#define GEN_DEF_READVECTOR_ITEM(VEC, TYPE, INDEX, VALUE) \
+ parser_context_t ctx; \
+ parser_init(&ctx, VEC._ptr, VEC._lenBuffer); \
+ compactInt_t clen; \
+ CHECK_PARSER_ERR(_readCompactInt(&ctx, &clen)); \
+ if ((INDEX) >= VEC._len) return parser_no_data; \
+ for (uint64_t i = 0; i < VEC._len; i++ ) CHECK_PARSER_ERR(_read_cro_##TYPE(&ctx, &VALUE)); \
+ return parser_ok;
+
+#define GEN_DEF_TOSTRING_VECTOR(TYPE) \
+ CLEAN_AND_CHECK() \
+ /* count number of pages, then output specific */ \
+ *pageCount = 0; \
+ pd_##TYPE##_t tmp; \
+ parser_context_t ctx; \
+ uint8_t chunkPageCount; \
+ uint16_t currentPage, currentTotalPage = 0; \
+ if(v->_len == 0) { \
+ *pageCount = 1; \
+ snprintf(outValue, outValueLen, ""); \
+ return parser_ok; \
+ } \
+ /* We need to do it twice because there is no memory to keep intermediate results*/ \
+ /* First count*/ \
+ parser_init(&ctx, v->_ptr, v->_lenBuffer);\
+ for (uint16_t i = 0; i < v->_len; i++) {\
+ CHECK_ERROR(_read##TYPE(&ctx, &tmp));\
+ CHECK_ERROR(_toString##TYPE(&tmp, outValue, outValueLen, 0, &chunkPageCount));\
+ (*pageCount)+=chunkPageCount;\
+ }\
+ /* Then iterate until we can print the corresponding chunk*/ \
+ parser_init(&ctx, v->_ptr, v->_lenBuffer);\
+ for (uint16_t i = 0; i < v->_len; i++) {\
+ CHECK_ERROR(_read##TYPE(&ctx, &tmp));\
+ chunkPageCount = 1;\
+ currentPage = 0;\
+ while (currentPage < chunkPageCount) {\
+ CHECK_ERROR(_toString##TYPE(&tmp, outValue, outValueLen, currentPage, &chunkPageCount));\
+ if (currentTotalPage == pageIdx) { return parser_ok; } \
+ currentPage++;\
+ currentTotalPage++;\
+ }\
+ };\
+ return parser_print_not_supported;
+
+parser_error_t parser_init(parser_context_t *ctx, const uint8_t *buffer, uint16_t bufferSize);
+
+parser_error_t _readBool(parser_context_t *c, pd_bool_t *value);
+
+parser_error_t _readCompactInt(parser_context_t *c, compactInt_t *v);
+
+parser_error_t _readCompactBalance(parser_context_t *c, pd_CompactBalance_t *v);
+
+parser_error_t _getValue(const compactInt_t *c, uint64_t *v);
+
+parser_error_t _readCallIndex(parser_context_t *c, pd_CallIndex_t *v);
+
+parser_error_t _readEra(parser_context_t *c, pd_ExtrinsicEra_t *v);
+
+parser_error_t _readTx(parser_context_t *c, parser_tx_t *v);
+
+uint8_t _getAddressType();
+
+parser_error_t _toStringCompactInt(const compactInt_t *c, uint8_t decimalPlaces,
+ char postfix,
+ char prefix[],
+ char *outValue, uint16_t outValueLen,
+ uint8_t pageIdx, uint8_t *pageCount);
+
+parser_error_t _toStringCompactIndex(const pd_CompactIndex_t *v,
+ char *outValue, uint16_t outValueLen,
+ uint8_t pageIdx, uint8_t *pageCount);
+
+parser_error_t _toStringPubkeyAsAddress(const uint8_t *pubkey,
+ char *outValue, uint16_t outValueLen,
+ uint8_t pageIdx, uint8_t *pageCount);
+
+parser_error_t _toStringCompactBalance(const pd_CompactBalance_t *v,
+ char *outValue, uint16_t outValueLen,
+ uint8_t pageIdx, uint8_t *pageCount);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/app/src/parser_txdef.c b/app/src/parser_txdef.c
new file mode 100644
index 0000000..7a345ec
--- /dev/null
+++ b/app/src/parser_txdef.c
@@ -0,0 +1,17 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#include
+#include "parser_txdef.h"
diff --git a/app/src/parser_txdef.h b/app/src/parser_txdef.h
new file mode 100644
index 0000000..738cf5d
--- /dev/null
+++ b/app/src/parser_txdef.h
@@ -0,0 +1,52 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include
+#include "substrate_methods.h"
+
+#ifdef TARGET_NANOX
+#define MAX_CALL_NESTING_SIZE 6
+#define MAX_CALL_VEC_SIZE 6
+#else
+#define MAX_CALL_NESTING_SIZE 2
+#define MAX_CALL_VEC_SIZE 5
+#endif
+
+typedef struct {
+ pd_CallIndex_t callIndex;
+ pd_Method_t method;
+
+ pd_ExtrinsicEra_t era;
+ pd_CompactIndex_t nonce;
+ pd_CompactBalance_t tip;
+ uint32_t specVersion;
+ uint32_t transactionVersion;
+
+ pd_Hash_t genesisHash;
+ pd_Hash_t blockHash;
+
+ pd_NestCallIdx_t nestCallIdx;
+} parser_tx_t;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/app/src/ristretto.c b/app/src/ristretto.c
new file mode 100644
index 0000000..5953134
--- /dev/null
+++ b/app/src/ristretto.c
@@ -0,0 +1,273 @@
+/*******************************************************************************
+* (c) 2021 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#include
+#include "ristretto.h"
+#include "cx.h"
+#include "rslib.h"
+
+unsigned char const ED25519_GEN[ED25519_SDKPOINT_BYTES] = {
+ //uncompressed
+ 0x04,
+ //x
+ 0x21, 0x69, 0x36, 0xd3, 0xcd, 0x6e, 0x53, 0xfe, 0xc0, 0xa4, 0xe2, 0x31, 0xfd, 0xd6, 0xdc, 0x5c,
+ 0x69, 0x2c, 0xc7, 0x60, 0x95, 0x25, 0xa7, 0xb2, 0xc9, 0x56, 0x2d, 0x60, 0x8f, 0x25, 0xd5, 0x1a,
+ //y
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x58
+};
+
+unsigned char const ED25519_FIELD_SIZE[ED25519_SCALAR_BYTES] = {
+ // q: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed
+ 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xed};
+
+unsigned char const ED25519_POW225[ED25519_SCALAR_BYTES] = {
+ // (q-5)/8
+ 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd};
+
+unsigned char const ED25519_FIELD_ZERO[ED25519_SCALAR_BYTES] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const fe25519_sdk fe25519_sqrtm1_sdk = {
+ 0x2b, 0x83, 0x24, 0x80, 0x4f, 0xc1, 0xdf, 0x0b, 0x2b, 0x4d,
+ 0x00, 0x99, 0x3d, 0xfb, 0xd7, 0xa7, 0x2f, 0x43, 0x18, 0x06,
+ 0xad, 0x2f, 0xe4, 0x78, 0xc4, 0xee, 0x1b, 0x27, 0x4a, 0x0e, 0xa0, 0xb0
+};
+
+const fe25519_sdk ed25519_invsqrtamd_sdk = {
+ 0x78, 0x6c, 0x89, 0x05, 0xcf, 0xaf, 0xfc, 0xa2, 0x16, 0xc2,
+ 0x7b, 0x91, 0xfe, 0x01, 0xd8, 0x40, 0x9d, 0x2f, 0x16, 0x17,
+ 0x5a, 0x41, 0x72, 0xbe, 0x99, 0xc8, 0xfd, 0xaa, 0x80, 0x5d, 0x40, 0xea
+};
+
+void fe25519_add_sdk(fe25519_sdk h, const fe25519_sdk f, const fe25519_sdk g)
+{
+ cx_math_addm(h, f, g, ED25519_FIELD_SIZE, ED25519_SCALAR_BYTES);
+}
+
+void fe25519_sub_sdk(fe25519_sdk h, const fe25519_sdk f, const fe25519_sdk g)
+{
+ cx_math_subm(h, f, g, ED25519_FIELD_SIZE, ED25519_SCALAR_BYTES);
+}
+
+void fe25519_mul_sdk(fe25519_sdk h, const fe25519_sdk f, const fe25519_sdk g)
+{
+ cx_math_multm(h, f, g, ED25519_FIELD_SIZE, ED25519_SCALAR_BYTES);
+}
+
+void fe25519_sq_sdk(fe25519_sdk h, const fe25519_sdk f)
+{
+ cx_math_multm(h, f, f, ED25519_FIELD_SIZE, ED25519_SCALAR_BYTES);
+}
+
+void fe25519_1_sdk(fe25519_sdk h)
+{
+ MEMZERO(&h[0], sizeof(fe25519_sdk));
+ h[ED25519_SCALAR_BYTES-1] = 1;
+}
+
+int fe25519_iszero_sdk(fe25519_sdk h)
+{
+ return cx_math_is_zero(h,ED25519_SCALAR_BYTES);
+}
+
+int fe25519_isnegative_sdk(const fe25519_sdk f)
+{
+ return f[ED25519_SCALAR_BYTES-1] & 1;
+}
+
+void fe25519_neg_sdk(fe25519_sdk h, const fe25519_sdk f)
+{
+ cx_math_subm(h, ED25519_FIELD_ZERO, f, ED25519_FIELD_SIZE, ED25519_SCALAR_BYTES);
+}
+
+void fe25519_copy_sdk(const fe25519_sdk h, const fe25519_sdk f)
+{
+ MEMCPY((void *) h, f, sizeof(fe25519_sdk));
+}
+
+//TODO: check this for constant-time
+void fe25519_cmov_sdk(fe25519_sdk f, const fe25519_sdk g, unsigned int b)
+{
+ uint8_t mask = (uint8_t) (-(int8_t) b);
+ uint8_t h[ED25519_SCALAR_BYTES];
+ uint8_t x[ED25519_SCALAR_BYTES];
+ for(int i = 0; i < ED25519_SCALAR_BYTES; i++){
+ h[i] = f[i];
+ x[i] = h[i] ^ g[i];
+ x[i] &= mask;
+ f[i] = f[i] ^ x[i];
+ }
+}
+
+void fe25519_cneg_sdk(fe25519_sdk h, const fe25519_sdk f, unsigned int b)
+{
+ fe25519_sdk negf;
+
+ fe25519_neg_sdk(negf, f);
+ fe25519_copy_sdk(h, f);
+ fe25519_cmov_sdk(h, negf, b);
+}
+
+void fe25519_abs_sdk(fe25519_sdk h, const fe25519_sdk f)
+{
+ fe25519_cneg_sdk(h, f, fe25519_isnegative_sdk(f));
+}
+
+void fe25519_tobytes_sdk(unsigned char *s, const fe25519_sdk f)
+{
+ uint8_t tmp = 0;
+ MEMCPY(s, f, sizeof(fe25519_sdk));
+ SWAP_ENDIAN(&s[0], tmp);
+}
+
+void fe25519_pow22523_sdk(fe25519_sdk out, const fe25519_sdk z)
+{
+ cx_math_powm(out, z, ED25519_POW225, ED25519_SCALAR_BYTES, ED25519_FIELD_SIZE, ED25519_SCALAR_BYTES);
+}
+
+int ristretto255_sqrt_ratio_m1_sdk(fe25519_sdk x, const fe25519_sdk u, const fe25519_sdk v)
+{
+ fe25519_sdk v3;
+ fe25519_sdk vxx;
+ fe25519_sdk m_root_check, p_root_check, f_root_check;
+ fe25519_sdk x_sqrtm1;
+ int has_m_root, has_p_root, has_f_root;
+
+ fe25519_sq_sdk(v3, v);
+ fe25519_mul_sdk(v3, v3, v); /* v3 = v^3 */
+ fe25519_sq_sdk(x, v3);
+ fe25519_mul_sdk(x, x, u);
+ fe25519_mul_sdk(x, x, v); /* x = uv^7 */
+
+ fe25519_pow22523_sdk(x, x); /* x = (uv^7)^((q-5)/8) */
+ fe25519_mul_sdk(x, x, v3);
+ fe25519_mul_sdk(x, x, u); /* x = uv^3(uv^7)^((q-5)/8) */
+
+ fe25519_sq_sdk(vxx, x);
+ fe25519_mul_sdk(vxx, vxx, v); /* vx^2 */
+ fe25519_sub_sdk(m_root_check, vxx, u); /* vx^2-u */
+ fe25519_add_sdk(p_root_check, vxx, u); /* vx^2+u */
+ fe25519_mul_sdk(f_root_check, u, fe25519_sqrtm1_sdk); /* u*sqrt(-1) */
+ fe25519_add_sdk(f_root_check, vxx, f_root_check); /* vx^2+u*sqrt(-1) */
+ has_m_root = fe25519_iszero_sdk(m_root_check);
+ has_p_root = fe25519_iszero_sdk(p_root_check);
+ has_f_root = fe25519_iszero_sdk(f_root_check);
+ fe25519_mul_sdk(x_sqrtm1,x, fe25519_sqrtm1_sdk);
+
+ fe25519_cmov_sdk(x, x_sqrtm1, has_p_root | has_f_root);
+ fe25519_abs_sdk(x, x);
+
+ return has_m_root | has_p_root;
+}
+
+void ristretto255_p3_tobytes_sdk(fe25519_sdk s, const ge25519_p3_sdk *h)
+{
+ fe25519_sdk den1, den2;
+ fe25519_sdk den_inv;
+ fe25519_sdk eden;
+ fe25519_sdk inv_sqrt;
+ fe25519_sdk ix, iy;
+ fe25519_sdk one;
+ fe25519_sdk s_;
+ fe25519_sdk t_z_inv;
+ fe25519_sdk u1, u2;
+ fe25519_sdk u1_u2u2;
+ fe25519_sdk x_, y_;
+ fe25519_sdk x_z_inv;
+ fe25519_sdk z_inv;
+ fe25519_sdk zmy;
+ int rotate;
+
+ fe25519_add_sdk(u1, h->Z, h->Y); /* u1 = Z+Y */
+ fe25519_sub_sdk(zmy, h->Z, h->Y); /* zmy = Z-Y */
+ fe25519_mul_sdk(u1, u1, zmy); /* u1 = (Z+Y)*(Z-Y) */
+ fe25519_mul_sdk(u2, h->X, h->Y); /* u2 = X*Y */
+
+ fe25519_sq_sdk(u1_u2u2, u2); /* u1_u2u2 = u2^2 */
+ fe25519_mul_sdk(u1_u2u2, u1, u1_u2u2); /* u1_u2u2 = u1*u2^2 */
+
+ fe25519_1_sdk(one);
+ ristretto255_sqrt_ratio_m1_sdk(inv_sqrt, one, u1_u2u2);
+
+ fe25519_mul_sdk(den1, inv_sqrt, u1);
+ fe25519_mul_sdk(den2, inv_sqrt, u2);
+ fe25519_mul_sdk(z_inv, den1, den2);
+ fe25519_mul_sdk(z_inv, z_inv, h->T);
+
+ fe25519_mul_sdk(ix, h->X, fe25519_sqrtm1_sdk);
+ fe25519_mul_sdk(iy, h->Y, fe25519_sqrtm1_sdk);
+
+ fe25519_mul_sdk(eden, den1, ed25519_invsqrtamd_sdk);
+
+ fe25519_mul_sdk(t_z_inv, h->T, z_inv);
+ rotate = fe25519_isnegative_sdk(t_z_inv);
+
+ fe25519_copy_sdk(x_, h->X);
+ fe25519_copy_sdk(y_, h->Y);
+ fe25519_copy_sdk(den_inv, den2);
+
+ fe25519_cmov_sdk(x_, iy, rotate);
+
+ fe25519_cmov_sdk(y_, ix, rotate);
+ fe25519_cmov_sdk(den_inv, eden, rotate);
+
+ fe25519_mul_sdk(x_z_inv, x_, z_inv);
+ fe25519_cneg_sdk(y_, y_, fe25519_isnegative_sdk(x_z_inv));
+
+ fe25519_sub_sdk(s_, h->Z, y_);
+ fe25519_mul_sdk(s_, den_inv, s_);
+ fe25519_abs_sdk(s, s_);
+}
+
+
+int crypto_scalarmult_ristretto255_base_sdk(unsigned char *q,const unsigned char *n)
+{
+ unsigned char *t = q;
+ unsigned int i;
+ for (i = 0; i < ED25519_SCALAR_BYTES; ++i) {
+ t[i] = n[ED25519_SCALAR_BYTES-1-i];
+ }
+ t[0] &= 127;
+
+ uint8_t Pxy[ED25519_SDKPOINT_BYTES];
+ memcpy(Pxy, ED25519_GEN, sizeof(Pxy));
+ cx_ecfp_scalar_mult(CX_CURVE_Ed25519, Pxy, sizeof(Pxy), t, ED25519_SCALAR_BYTES);
+
+ ge25519_p3_sdk Q_sdk;
+ MEMZERO(&Q_sdk, sizeof(ge25519_p3_sdk));
+ MEMCPY(Q_sdk.X, &Pxy[1],ED25519_SCALAR_BYTES);
+ MEMCPY(Q_sdk.Y, &Pxy[1+ED25519_SCALAR_BYTES],ED25519_SCALAR_BYTES);
+ fe25519_1_sdk(Q_sdk.Z);
+ fe25519_mul_sdk(Q_sdk.T, Q_sdk.X,Q_sdk.Y);
+
+ fe25519_sdk s;
+
+ ristretto255_p3_tobytes_sdk(s, &Q_sdk);
+
+ if (fe25519_iszero_sdk(s)) {
+ return -1;
+ }
+
+ fe25519_tobytes_sdk(q,s);
+
+ return 0;
+}
\ No newline at end of file
diff --git a/app/src/ristretto.h b/app/src/ristretto.h
new file mode 100644
index 0000000..abfa9f2
--- /dev/null
+++ b/app/src/ristretto.h
@@ -0,0 +1,43 @@
+/*******************************************************************************
+* (c) 2021 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#define ED25519_SCALAR_BYTES 32
+#define RISTRETTO_BYTES 32
+#define ED25519_SDKPOINT_BYTES 65
+
+typedef unsigned char fe25519_sdk[ED25519_SCALAR_BYTES];
+
+typedef struct {
+ fe25519_sdk X;
+ fe25519_sdk Y;
+ fe25519_sdk Z;
+ fe25519_sdk T;
+} ge25519_p3_sdk;
+
+#define SWAP_BYTES(x, y, tmp) { \
+ tmp = x; \
+ x = y; \
+ y = tmp;\
+}
+
+#define SWAP_ENDIAN(x, tmp) { \
+ for (int i = 0; i < ED25519_SCALAR_BYTES/2; i++){ \
+ SWAP_BYTES(*(x + i), *(x + (ED25519_SCALAR_BYTES-1-i)), tmp); \
+ } \
+}
+
+void ristretto255_p3_tobytes_sdk(unsigned char *s, const ge25519_p3_sdk *h);
+int crypto_scalarmult_ristretto255_base_sdk(unsigned char *q, const unsigned char *n);
\ No newline at end of file
diff --git a/app/src/secret.c b/app/src/secret.c
new file mode 100644
index 0000000..6efc258
--- /dev/null
+++ b/app/src/secret.c
@@ -0,0 +1,64 @@
+/*******************************************************************************
+* (c) 2020 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#include "os.h"
+#include "cx.h"
+#include "coin.h"
+#include "app_main.h"
+#include "tx.h"
+#include "view.h"
+#include "app_mode.h"
+
+void secret_accept() {
+#ifdef APP_SECRET_MODE_ENABLED
+ app_mode_set_secret(true);
+ view_idle_show(0, NULL);
+#endif
+}
+
+static char *secret_message =
+ "USE AT YOUR OWN RISK!! "
+ "You are about to enable the KSM recovery mode."
+ "If you are not sure why you are here, reject or unplug your device immediately."
+ "Activating this mode will temporarily allow you to sign transactions using Polkadot keys";
+
+zxerr_t secret_getNumItems(uint8_t *num_items) {
+ zemu_log_stack("secret_getNumItems");
+ *num_items = 1;
+ return zxerr_ok;
+}
+
+zxerr_t secret_getItem(int8_t displayIdx,
+ char *outKey, uint16_t outKeyLen,
+ char *outVal, uint16_t outValLen,
+ uint8_t pageIdx, uint8_t *pageCount) {
+ if (displayIdx != 0) {
+ return zxerr_no_data;
+ }
+
+ snprintf(outKey, outKeyLen, "WARNING!");
+ pageString(outVal, outValLen, (char *) PIC(secret_message), pageIdx, pageCount);
+ return zxerr_ok;
+}
+
+zxerr_t secret_enabled() {
+#ifdef APP_SECRET_MODE_ENABLED
+ zemu_log("RECOVERY TRIGGERED");
+ view_review_init(secret_getItem, secret_getNumItems, secret_accept);
+ view_review_show();
+#endif
+ return zxerr_ok;
+}
diff --git a/app/src/secret.h b/app/src/secret.h
new file mode 100644
index 0000000..678d40c
--- /dev/null
+++ b/app/src/secret.h
@@ -0,0 +1,37 @@
+/*******************************************************************************
+* (c) 2018 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma once
+
+#include "zxmacros.h"
+#include
+#include "zxerror.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+zxerr_t secret_enabled();
+
+zxerr_t secret_getNumItems(uint8_t *num_items);
+
+zxerr_t secret_getItem(int8_t displayIdx,
+ char *outKey, uint16_t outKeyLen,
+ char *outValue, uint16_t outValueLen,
+ uint8_t pageIdx, uint8_t *pageCount);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/app/src/substrate_dispatch.c b/app/src/substrate_dispatch.c
new file mode 100644
index 0000000..184a72c
--- /dev/null
+++ b/app/src/substrate_dispatch.c
@@ -0,0 +1,107 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#include "substrate_dispatch.h"
+#include "parser_impl.h"
+
+#include "zxmacros.h"
+#include
+
+parser_error_t _readMethod(
+ parser_context_t* c,
+ uint8_t moduleIdx,
+ uint8_t callIdx,
+ pd_Method_t* method)
+{
+ switch (c->tx_obj->transactionVersion) {
+ case 3:
+ return _readMethod_V3(c, moduleIdx, callIdx, &method->V3);
+ default:
+ return parser_not_supported;
+ }
+}
+
+uint8_t _getMethod_NumItems(uint32_t transactionVersion, uint8_t moduleIdx, uint8_t callIdx)
+{
+ switch (transactionVersion) {
+ case 3:
+ return _getMethod_NumItems_V3(moduleIdx, callIdx);
+ default:
+ return parser_not_supported;
+ }
+}
+
+const char* _getMethod_ModuleName(uint32_t transactionVersion, uint8_t moduleIdx)
+{
+ switch (transactionVersion) {
+ case 3:
+ return _getMethod_ModuleName_V3(moduleIdx);
+ default:
+ return NULL;
+ }
+}
+
+const char* _getMethod_Name(uint32_t transactionVersion, uint8_t moduleIdx, uint8_t callIdx)
+{
+ switch (transactionVersion) {
+ case 3:
+ return _getMethod_Name_V3(moduleIdx, callIdx);
+ default:
+ return 0;
+ }
+}
+
+const char* _getMethod_ItemName(uint32_t transactionVersion, uint8_t moduleIdx, uint8_t callIdx, uint8_t itemIdx)
+{
+ switch (transactionVersion) {
+ case 3:
+ return _getMethod_ItemName_V3(moduleIdx, callIdx, itemIdx);
+ default:
+ return NULL;
+ }
+}
+
+parser_error_t _getMethod_ItemValue(uint32_t transactionVersion, pd_Method_t* m, uint8_t moduleIdx, uint8_t callIdx,
+ uint8_t itemIdx, char* outValue, uint16_t outValueLen,
+ uint8_t pageIdx, uint8_t* pageCount)
+{
+ switch (transactionVersion) {
+ case 3:
+ return _getMethod_ItemValue_V3(&m->V3, moduleIdx, callIdx, itemIdx, outValue,
+ outValueLen, pageIdx, pageCount);
+ default:
+ return parser_not_supported;
+ }
+}
+
+bool _getMethod_ItemIsExpert(uint32_t transactionVersion, uint8_t moduleIdx, uint8_t callIdx, uint8_t itemIdx)
+{
+ switch (transactionVersion) {
+ case 3:
+ return _getMethod_ItemIsExpert_V3(moduleIdx, callIdx, itemIdx);
+ default:
+ return false;
+ }
+}
+
+bool _getMethod_IsNestingSupported(uint32_t transactionVersion, uint8_t moduleIdx, uint8_t callIdx)
+{
+ switch (transactionVersion) {
+ case 3:
+ return _getMethod_IsNestingSupported_V3(moduleIdx, callIdx);
+ default:
+ return false;
+ }
+}
diff --git a/app/src/substrate_dispatch.h b/app/src/substrate_dispatch.h
new file mode 100644
index 0000000..4a09f54
--- /dev/null
+++ b/app/src/substrate_dispatch.h
@@ -0,0 +1,60 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "parser_common.h"
+#include "stdbool.h"
+#include "substrate_dispatch_V3.h"
+#include
+#include
+
+#define GEN_GETCALL(CALL) _getpdCall_##CALL(ctx->tx_obj->transactionVersion)
+#define GEN_DEC_GETCALL(CALL) uint32_t _getpdCall_##CALL(uint32_t txVersion)
+#define GEN_DEF_GETCALL(CALL) \
+ uint32_t _getpdCall_##CALL(uint32_t txVersion) \
+ { \
+ switch (txVersion) { \
+ \
+ case 3: \
+ return PD_CALL_##CALL##_V3; \
+ \
+ default: \
+ return 0; \
+ } \
+ }
+
+parser_error_t _readMethod(parser_context_t* c, uint8_t moduleIdx, uint8_t callIdx, pd_Method_t* method);
+uint8_t _getMethod_NumItems(uint32_t transactionVersion, uint8_t moduleIdx, uint8_t callIdx);
+const char* _getMethod_ModuleName(uint32_t transactionVersion, uint8_t moduleIdx);
+const char* _getMethod_Name(uint32_t transactionVersion, uint8_t moduleIdx, uint8_t callIdx);
+const char* _getMethod_ItemName(uint32_t transactionVersion, uint8_t moduleIdx, uint8_t callIdx, uint8_t itemIdx);
+
+parser_error_t _getMethod_ItemValue(
+ uint32_t transactionVersion,
+ pd_Method_t* m, uint8_t moduleIdx, uint8_t callIdx, uint8_t itemIdx,
+ char* outValue, uint16_t outValueLen,
+ uint8_t pageIdx, uint8_t* pageCount);
+
+bool _getMethod_ItemIsExpert(uint32_t transactionVersion, uint8_t moduleIdx, uint8_t callIdx, uint8_t itemIdx);
+bool _getMethod_IsNestingSupported(uint32_t transactionVersion, uint8_t moduleIdx, uint8_t callIdx);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/app/src/substrate_dispatch_V3.c b/app/src/substrate_dispatch_V3.c
new file mode 100644
index 0000000..478c324
--- /dev/null
+++ b/app/src/substrate_dispatch_V3.c
@@ -0,0 +1,6262 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#include "substrate_dispatch_V3.h"
+#include "substrate_strings.h"
+#include "zxmacros.h"
+#include
+
+__Z_INLINE parser_error_t _readMethod_balances_transfer_V3(
+ parser_context_t* c, pd_balances_transfer_V3_t* m)
+{
+ CHECK_ERROR(_readLookupSource_V3(c, &m->dest))
+ CHECK_ERROR(_readCompactBalance(c, &m->value))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_balances_transfer_keep_alive_V3(
+ parser_context_t* c, pd_balances_transfer_keep_alive_V3_t* m)
+{
+ CHECK_ERROR(_readLookupSource_V3(c, &m->dest))
+ CHECK_ERROR(_readCompactBalance(c, &m->value))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_session_set_keys_V3(
+ parser_context_t* c, pd_session_set_keys_V3_t* m)
+{
+ CHECK_ERROR(_readKeys_V3(c, &m->keys))
+ CHECK_ERROR(_readBytes(c, &m->proof))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_session_purge_keys_V3(
+ parser_context_t* c, pd_session_purge_keys_V3_t* m)
+{
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_utility_batch_V3(
+ parser_context_t* c, pd_utility_batch_V3_t* m)
+{
+ CHECK_ERROR(_readVecCall(c, &m->calls))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_utility_batch_all_V3(
+ parser_context_t* c, pd_utility_batch_all_V3_t* m)
+{
+ CHECK_ERROR(_readVecCall(c, &m->calls))
+ return parser_ok;
+}
+
+#ifdef SUBSTRATE_PARSER_FULL
+__Z_INLINE parser_error_t _readMethod_system_fill_block_V3(
+ parser_context_t* c, pd_system_fill_block_V3_t* m)
+{
+ CHECK_ERROR(_readPerbill_V3(c, &m->_ratio))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_system_remark_V3(
+ parser_context_t* c, pd_system_remark_V3_t* m)
+{
+ CHECK_ERROR(_readBytes(c, &m->_remark))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_system_set_heap_pages_V3(
+ parser_context_t* c, pd_system_set_heap_pages_V3_t* m)
+{
+ CHECK_ERROR(_readu64(c, &m->pages))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_system_set_code_V3(
+ parser_context_t* c, pd_system_set_code_V3_t* m)
+{
+ CHECK_ERROR(_readBytes(c, &m->code))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_system_set_code_without_checks_V3(
+ parser_context_t* c, pd_system_set_code_without_checks_V3_t* m)
+{
+ CHECK_ERROR(_readBytes(c, &m->code))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_system_set_changes_trie_config_V3(
+ parser_context_t* c, pd_system_set_changes_trie_config_V3_t* m)
+{
+ CHECK_ERROR(_readOptionChangesTrieConfiguration_V3(c, &m->changes_trie_config))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_system_set_storage_V3(
+ parser_context_t* c, pd_system_set_storage_V3_t* m)
+{
+ CHECK_ERROR(_readVecKeyValue_V3(c, &m->items))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_system_kill_storage_V3(
+ parser_context_t* c, pd_system_kill_storage_V3_t* m)
+{
+ CHECK_ERROR(_readVecKey_V3(c, &m->keys))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_system_kill_prefix_V3(
+ parser_context_t* c, pd_system_kill_prefix_V3_t* m)
+{
+ CHECK_ERROR(_readKey_V3(c, &m->prefix))
+ CHECK_ERROR(_readu32(c, &m->_subkeys))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_timestamp_set_V3(
+ parser_context_t* c, pd_timestamp_set_V3_t* m)
+{
+ CHECK_ERROR(_readCompactMoment_V3(c, &m->now))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_indices_claim_V3(
+ parser_context_t* c, pd_indices_claim_V3_t* m)
+{
+ CHECK_ERROR(_readAccountIndex_V3(c, &m->index))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_indices_transfer_V3(
+ parser_context_t* c, pd_indices_transfer_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->new_))
+ CHECK_ERROR(_readAccountIndex_V3(c, &m->index))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_indices_free_V3(
+ parser_context_t* c, pd_indices_free_V3_t* m)
+{
+ CHECK_ERROR(_readAccountIndex_V3(c, &m->index))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_indices_force_transfer_V3(
+ parser_context_t* c, pd_indices_force_transfer_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->new_))
+ CHECK_ERROR(_readAccountIndex_V3(c, &m->index))
+ CHECK_ERROR(_readbool(c, &m->freeze))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_indices_freeze_V3(
+ parser_context_t* c, pd_indices_freeze_V3_t* m)
+{
+ CHECK_ERROR(_readAccountIndex_V3(c, &m->index))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_balances_set_balance_V3(
+ parser_context_t* c, pd_balances_set_balance_V3_t* m)
+{
+ CHECK_ERROR(_readLookupSource_V3(c, &m->who))
+ CHECK_ERROR(_readCompactBalance(c, &m->new_free))
+ CHECK_ERROR(_readCompactBalance(c, &m->new_reserved))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_balances_force_transfer_V3(
+ parser_context_t* c, pd_balances_force_transfer_V3_t* m)
+{
+ CHECK_ERROR(_readLookupSource_V3(c, &m->source))
+ CHECK_ERROR(_readLookupSource_V3(c, &m->dest))
+ CHECK_ERROR(_readCompactBalance(c, &m->value))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_babe_report_equivocation_V3(
+ parser_context_t* c, pd_babe_report_equivocation_V3_t* m)
+{
+ CHECK_ERROR(_readBabeEquivocationProof_V3(c, &m->equivocation_proof))
+ CHECK_ERROR(_readKeyOwnerProof_V3(c, &m->key_owner_proof))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_babe_report_equivocation_unsigned_V3(
+ parser_context_t* c, pd_babe_report_equivocation_unsigned_V3_t* m)
+{
+ CHECK_ERROR(_readBabeEquivocationProof_V3(c, &m->equivocation_proof))
+ CHECK_ERROR(_readKeyOwnerProof_V3(c, &m->key_owner_proof))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_grandpa_report_equivocation_V3(
+ parser_context_t* c, pd_grandpa_report_equivocation_V3_t* m)
+{
+ CHECK_ERROR(_readGrandpaEquivocationProof_V3(c, &m->equivocation_proof))
+ CHECK_ERROR(_readKeyOwnerProof_V3(c, &m->key_owner_proof))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_grandpa_report_equivocation_unsigned_V3(
+ parser_context_t* c, pd_grandpa_report_equivocation_unsigned_V3_t* m)
+{
+ CHECK_ERROR(_readGrandpaEquivocationProof_V3(c, &m->equivocation_proof))
+ CHECK_ERROR(_readKeyOwnerProof_V3(c, &m->key_owner_proof))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_grandpa_note_stalled_V3(
+ parser_context_t* c, pd_grandpa_note_stalled_V3_t* m)
+{
+ CHECK_ERROR(_readBlockNumber(c, &m->delay))
+ CHECK_ERROR(_readBlockNumber(c, &m->best_finalized_block_number))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_authorship_set_uncles_V3(
+ parser_context_t* c, pd_authorship_set_uncles_V3_t* m)
+{
+ CHECK_ERROR(_readVecHeader(c, &m->new_uncles))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_imonline_heartbeat_V3(
+ parser_context_t* c, pd_imonline_heartbeat_V3_t* m)
+{
+ CHECK_ERROR(_readHeartbeat(c, &m->heartbeat))
+ CHECK_ERROR(_readSignature_V3(c, &m->_signature))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_validatorsset_add_member_V3(
+ parser_context_t* c, pd_validatorsset_add_member_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->who))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_validatorsset_remove_member_V3(
+ parser_context_t* c, pd_validatorsset_remove_member_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->who))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_validatorsset_swap_member_V3(
+ parser_context_t* c, pd_validatorsset_swap_member_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->remove))
+ CHECK_ERROR(_readAccountId_V3(c, &m->add))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_validatorsset_reset_members_V3(
+ parser_context_t* c, pd_validatorsset_reset_members_V3_t* m)
+{
+ CHECK_ERROR(_readVecAccountId_V3(c, &m->members))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_validatorsset_change_key_V3(
+ parser_context_t* c, pd_validatorsset_change_key_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->new_))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_validatorsset_set_prime_V3(
+ parser_context_t* c, pd_validatorsset_set_prime_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->who))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_validatorsset_clear_prime_V3(
+ parser_context_t* c, pd_validatorsset_clear_prime_V3_t* m)
+{
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_technicalcommittee_set_members_V3(
+ parser_context_t* c, pd_technicalcommittee_set_members_V3_t* m)
+{
+ CHECK_ERROR(_readVecAccountId_V3(c, &m->new_members))
+ CHECK_ERROR(_readOptionAccountId_V3(c, &m->prime))
+ CHECK_ERROR(_readMemberCount_V3(c, &m->old_count))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_technicalcommittee_execute_V3(
+ parser_context_t* c, pd_technicalcommittee_execute_V3_t* m)
+{
+ CHECK_ERROR(_readProposal(c, &m->proposal))
+ CHECK_ERROR(_readCompactu32(c, &m->length_bound))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_technicalcommittee_propose_V3(
+ parser_context_t* c, pd_technicalcommittee_propose_V3_t* m)
+{
+ CHECK_ERROR(_readCompactMemberCount_V3(c, &m->threshold))
+ CHECK_ERROR(_readProposal(c, &m->proposal))
+ CHECK_ERROR(_readCompactu32(c, &m->length_bound))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_technicalcommittee_vote_V3(
+ parser_context_t* c, pd_technicalcommittee_vote_V3_t* m)
+{
+ CHECK_ERROR(_readHash(c, &m->proposal))
+ CHECK_ERROR(_readCompactProposalIndex_V3(c, &m->index))
+ CHECK_ERROR(_readbool(c, &m->approve))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_technicalcommittee_close_V3(
+ parser_context_t* c, pd_technicalcommittee_close_V3_t* m)
+{
+ CHECK_ERROR(_readHash(c, &m->proposal_hash))
+ CHECK_ERROR(_readCompactProposalIndex_V3(c, &m->index))
+ CHECK_ERROR(_readCompactWeight_V3(c, &m->proposal_weight_bound))
+ CHECK_ERROR(_readCompactu32(c, &m->length_bound))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_technicalcommittee_disapprove_proposal_V3(
+ parser_context_t* c, pd_technicalcommittee_disapprove_proposal_V3_t* m)
+{
+ CHECK_ERROR(_readHash(c, &m->proposal_hash))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_technicalmembership_add_member_V3(
+ parser_context_t* c, pd_technicalmembership_add_member_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->who))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_technicalmembership_remove_member_V3(
+ parser_context_t* c, pd_technicalmembership_remove_member_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->who))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_technicalmembership_swap_member_V3(
+ parser_context_t* c, pd_technicalmembership_swap_member_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->remove))
+ CHECK_ERROR(_readAccountId_V3(c, &m->add))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_technicalmembership_reset_members_V3(
+ parser_context_t* c, pd_technicalmembership_reset_members_V3_t* m)
+{
+ CHECK_ERROR(_readVecAccountId_V3(c, &m->members))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_technicalmembership_change_key_V3(
+ parser_context_t* c, pd_technicalmembership_change_key_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->new_))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_technicalmembership_set_prime_V3(
+ parser_context_t* c, pd_technicalmembership_set_prime_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->who))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_technicalmembership_clear_prime_V3(
+ parser_context_t* c, pd_technicalmembership_clear_prime_V3_t* m)
+{
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_financialcommittee_set_members_V3(
+ parser_context_t* c, pd_financialcommittee_set_members_V3_t* m)
+{
+ CHECK_ERROR(_readVecAccountId_V3(c, &m->new_members))
+ CHECK_ERROR(_readOptionAccountId_V3(c, &m->prime))
+ CHECK_ERROR(_readMemberCount_V3(c, &m->old_count))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_financialcommittee_execute_V3(
+ parser_context_t* c, pd_financialcommittee_execute_V3_t* m)
+{
+ CHECK_ERROR(_readProposal(c, &m->proposal))
+ CHECK_ERROR(_readCompactu32(c, &m->length_bound))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_financialcommittee_propose_V3(
+ parser_context_t* c, pd_financialcommittee_propose_V3_t* m)
+{
+ CHECK_ERROR(_readCompactMemberCount_V3(c, &m->threshold))
+ CHECK_ERROR(_readProposal(c, &m->proposal))
+ CHECK_ERROR(_readCompactu32(c, &m->length_bound))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_financialcommittee_vote_V3(
+ parser_context_t* c, pd_financialcommittee_vote_V3_t* m)
+{
+ CHECK_ERROR(_readHash(c, &m->proposal))
+ CHECK_ERROR(_readCompactProposalIndex_V3(c, &m->index))
+ CHECK_ERROR(_readbool(c, &m->approve))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_financialcommittee_close_V3(
+ parser_context_t* c, pd_financialcommittee_close_V3_t* m)
+{
+ CHECK_ERROR(_readHash(c, &m->proposal_hash))
+ CHECK_ERROR(_readCompactProposalIndex_V3(c, &m->index))
+ CHECK_ERROR(_readCompactWeight_V3(c, &m->proposal_weight_bound))
+ CHECK_ERROR(_readCompactu32(c, &m->length_bound))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_financialcommittee_disapprove_proposal_V3(
+ parser_context_t* c, pd_financialcommittee_disapprove_proposal_V3_t* m)
+{
+ CHECK_ERROR(_readHash(c, &m->proposal_hash))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_financialmembership_add_member_V3(
+ parser_context_t* c, pd_financialmembership_add_member_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->who))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_financialmembership_remove_member_V3(
+ parser_context_t* c, pd_financialmembership_remove_member_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->who))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_financialmembership_swap_member_V3(
+ parser_context_t* c, pd_financialmembership_swap_member_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->remove))
+ CHECK_ERROR(_readAccountId_V3(c, &m->add))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_financialmembership_reset_members_V3(
+ parser_context_t* c, pd_financialmembership_reset_members_V3_t* m)
+{
+ CHECK_ERROR(_readVecAccountId_V3(c, &m->members))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_financialmembership_change_key_V3(
+ parser_context_t* c, pd_financialmembership_change_key_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->new_))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_financialmembership_set_prime_V3(
+ parser_context_t* c, pd_financialmembership_set_prime_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->who))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_financialmembership_clear_prime_V3(
+ parser_context_t* c, pd_financialmembership_clear_prime_V3_t* m)
+{
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_rootcommittee_set_members_V3(
+ parser_context_t* c, pd_rootcommittee_set_members_V3_t* m)
+{
+ CHECK_ERROR(_readVecAccountId_V3(c, &m->new_members))
+ CHECK_ERROR(_readOptionAccountId_V3(c, &m->prime))
+ CHECK_ERROR(_readMemberCount_V3(c, &m->old_count))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_rootcommittee_execute_V3(
+ parser_context_t* c, pd_rootcommittee_execute_V3_t* m)
+{
+ CHECK_ERROR(_readProposal(c, &m->proposal))
+ CHECK_ERROR(_readCompactu32(c, &m->length_bound))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_rootcommittee_propose_V3(
+ parser_context_t* c, pd_rootcommittee_propose_V3_t* m)
+{
+ CHECK_ERROR(_readCompactMemberCount_V3(c, &m->threshold))
+ CHECK_ERROR(_readProposal(c, &m->proposal))
+ CHECK_ERROR(_readCompactu32(c, &m->length_bound))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_rootcommittee_vote_V3(
+ parser_context_t* c, pd_rootcommittee_vote_V3_t* m)
+{
+ CHECK_ERROR(_readHash(c, &m->proposal))
+ CHECK_ERROR(_readCompactProposalIndex_V3(c, &m->index))
+ CHECK_ERROR(_readbool(c, &m->approve))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_rootcommittee_close_V3(
+ parser_context_t* c, pd_rootcommittee_close_V3_t* m)
+{
+ CHECK_ERROR(_readHash(c, &m->proposal_hash))
+ CHECK_ERROR(_readCompactProposalIndex_V3(c, &m->index))
+ CHECK_ERROR(_readCompactWeight_V3(c, &m->proposal_weight_bound))
+ CHECK_ERROR(_readCompactu32(c, &m->length_bound))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_rootcommittee_disapprove_proposal_V3(
+ parser_context_t* c, pd_rootcommittee_disapprove_proposal_V3_t* m)
+{
+ CHECK_ERROR(_readHash(c, &m->proposal_hash))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_rootmembership_add_member_V3(
+ parser_context_t* c, pd_rootmembership_add_member_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->who))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_rootmembership_remove_member_V3(
+ parser_context_t* c, pd_rootmembership_remove_member_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->who))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_rootmembership_swap_member_V3(
+ parser_context_t* c, pd_rootmembership_swap_member_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->remove))
+ CHECK_ERROR(_readAccountId_V3(c, &m->add))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_rootmembership_reset_members_V3(
+ parser_context_t* c, pd_rootmembership_reset_members_V3_t* m)
+{
+ CHECK_ERROR(_readVecAccountId_V3(c, &m->members))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_rootmembership_change_key_V3(
+ parser_context_t* c, pd_rootmembership_change_key_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->new_))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_rootmembership_set_prime_V3(
+ parser_context_t* c, pd_rootmembership_set_prime_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->who))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_rootmembership_clear_prime_V3(
+ parser_context_t* c, pd_rootmembership_clear_prime_V3_t* m)
+{
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_scheduler_schedule_V3(
+ parser_context_t* c, pd_scheduler_schedule_V3_t* m)
+{
+ CHECK_ERROR(_readBlockNumber(c, &m->when))
+ CHECK_ERROR(_readOptionPeriod_V3(c, &m->maybe_periodic))
+ CHECK_ERROR(_readPriority_V3(c, &m->priority))
+ CHECK_ERROR(_readCall(c, &m->call))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_scheduler_cancel_V3(
+ parser_context_t* c, pd_scheduler_cancel_V3_t* m)
+{
+ CHECK_ERROR(_readBlockNumber(c, &m->when))
+ CHECK_ERROR(_readu32(c, &m->index))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_scheduler_schedule_named_V3(
+ parser_context_t* c, pd_scheduler_schedule_named_V3_t* m)
+{
+ CHECK_ERROR(_readBytes(c, &m->id))
+ CHECK_ERROR(_readBlockNumber(c, &m->when))
+ CHECK_ERROR(_readOptionPeriod_V3(c, &m->maybe_periodic))
+ CHECK_ERROR(_readPriority_V3(c, &m->priority))
+ CHECK_ERROR(_readCall(c, &m->call))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_scheduler_cancel_named_V3(
+ parser_context_t* c, pd_scheduler_cancel_named_V3_t* m)
+{
+ CHECK_ERROR(_readBytes(c, &m->id))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_scheduler_schedule_after_V3(
+ parser_context_t* c, pd_scheduler_schedule_after_V3_t* m)
+{
+ CHECK_ERROR(_readBlockNumber(c, &m->after))
+ CHECK_ERROR(_readOptionPeriod_V3(c, &m->maybe_periodic))
+ CHECK_ERROR(_readPriority_V3(c, &m->priority))
+ CHECK_ERROR(_readCall(c, &m->call))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_scheduler_schedule_named_after_V3(
+ parser_context_t* c, pd_scheduler_schedule_named_after_V3_t* m)
+{
+ CHECK_ERROR(_readBytes(c, &m->id))
+ CHECK_ERROR(_readBlockNumber(c, &m->after))
+ CHECK_ERROR(_readOptionPeriod_V3(c, &m->maybe_periodic))
+ CHECK_ERROR(_readPriority_V3(c, &m->priority))
+ CHECK_ERROR(_readCall(c, &m->call))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_amendments_propose_V3(
+ parser_context_t* c, pd_amendments_propose_V3_t* m)
+{
+ CHECK_ERROR(_readAmendment_V3(c, &m->amendment))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_amendments_veto_V3(
+ parser_context_t* c, pd_amendments_veto_V3_t* m)
+{
+ CHECK_ERROR(_readu64(c, &m->amendment_id))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_mandate_apply_V3(
+ parser_context_t* c, pd_mandate_apply_V3_t* m)
+{
+ CHECK_ERROR(_readCall(c, &m->call))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_companyreserve_spend_V3(
+ parser_context_t* c, pd_companyreserve_spend_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->to))
+ CHECK_ERROR(_readBalanceOf(c, &m->amount))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_companyreserve_tip_V3(
+ parser_context_t* c, pd_companyreserve_tip_V3_t* m)
+{
+ CHECK_ERROR(_readBalanceOf(c, &m->amount))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_companyreserve_apply_as_V3(
+ parser_context_t* c, pd_companyreserve_apply_as_V3_t* m)
+{
+ CHECK_ERROR(_readCall(c, &m->call))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_internationalreserve_spend_V3(
+ parser_context_t* c, pd_internationalreserve_spend_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->to))
+ CHECK_ERROR(_readBalanceOf(c, &m->amount))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_internationalreserve_tip_V3(
+ parser_context_t* c, pd_internationalreserve_tip_V3_t* m)
+{
+ CHECK_ERROR(_readBalanceOf(c, &m->amount))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_internationalreserve_apply_as_V3(
+ parser_context_t* c, pd_internationalreserve_apply_as_V3_t* m)
+{
+ CHECK_ERROR(_readCall(c, &m->call))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_usareserve_spend_V3(
+ parser_context_t* c, pd_usareserve_spend_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->to))
+ CHECK_ERROR(_readBalanceOf(c, &m->amount))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_usareserve_tip_V3(
+ parser_context_t* c, pd_usareserve_tip_V3_t* m)
+{
+ CHECK_ERROR(_readBalanceOf(c, &m->amount))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_usareserve_apply_as_V3(
+ parser_context_t* c, pd_usareserve_apply_as_V3_t* m)
+{
+ CHECK_ERROR(_readCall(c, &m->call))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_vesting_claim_V3(
+ parser_context_t* c, pd_vesting_claim_V3_t* m)
+{
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_vesting_add_vesting_schedule_V3(
+ parser_context_t* c, pd_vesting_add_vesting_schedule_V3_t* m)
+{
+ CHECK_ERROR(_readLookupSource_V3(c, &m->dest))
+ CHECK_ERROR(_readVestingScheduleOf_V3(c, &m->schedule))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_vesting_cancel_all_vesting_schedules_V3(
+ parser_context_t* c, pd_vesting_cancel_all_vesting_schedules_V3_t* m)
+{
+ CHECK_ERROR(_readLookupSource_V3(c, &m->who))
+ CHECK_ERROR(_readLookupSource_V3(c, &m->funds_collector))
+ CHECK_ERROR(_readbool(c, &m->limit_to_free_balance))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_identity_add_registrar_V3(
+ parser_context_t* c, pd_identity_add_registrar_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->account))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_identity_set_identity_V3(
+ parser_context_t* c, pd_identity_set_identity_V3_t* m)
+{
+ CHECK_ERROR(_readIdentityInfo_V3(c, &m->info))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_identity_set_subs_V3(
+ parser_context_t* c, pd_identity_set_subs_V3_t* m)
+{
+ CHECK_ERROR(_readVecTupleAccountIdData_V3(c, &m->subs))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_identity_clear_identity_V3(
+ parser_context_t* c, pd_identity_clear_identity_V3_t* m)
+{
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_identity_request_judgement_V3(
+ parser_context_t* c, pd_identity_request_judgement_V3_t* m)
+{
+ CHECK_ERROR(_readCompactRegistrarIndex_V3(c, &m->reg_index))
+ CHECK_ERROR(_readCompactBalanceOf(c, &m->max_fee))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_identity_cancel_request_V3(
+ parser_context_t* c, pd_identity_cancel_request_V3_t* m)
+{
+ CHECK_ERROR(_readRegistrarIndex_V3(c, &m->reg_index))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_identity_set_fee_V3(
+ parser_context_t* c, pd_identity_set_fee_V3_t* m)
+{
+ CHECK_ERROR(_readCompactRegistrarIndex_V3(c, &m->index))
+ CHECK_ERROR(_readCompactBalanceOf(c, &m->fee))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_identity_set_account_id_V3(
+ parser_context_t* c, pd_identity_set_account_id_V3_t* m)
+{
+ CHECK_ERROR(_readCompactRegistrarIndex_V3(c, &m->index))
+ CHECK_ERROR(_readAccountId_V3(c, &m->new_))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_identity_set_fields_V3(
+ parser_context_t* c, pd_identity_set_fields_V3_t* m)
+{
+ CHECK_ERROR(_readCompactRegistrarIndex_V3(c, &m->index))
+ CHECK_ERROR(_readIdentityFields_V3(c, &m->fields))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_identity_provide_judgement_V3(
+ parser_context_t* c, pd_identity_provide_judgement_V3_t* m)
+{
+ CHECK_ERROR(_readCompactRegistrarIndex_V3(c, &m->reg_index))
+ CHECK_ERROR(_readLookupSource_V3(c, &m->target))
+ CHECK_ERROR(_readIdentityJudgement_V3(c, &m->judgement))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_identity_kill_identity_V3(
+ parser_context_t* c, pd_identity_kill_identity_V3_t* m)
+{
+ CHECK_ERROR(_readLookupSource_V3(c, &m->target))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_identity_add_sub_V3(
+ parser_context_t* c, pd_identity_add_sub_V3_t* m)
+{
+ CHECK_ERROR(_readLookupSource_V3(c, &m->sub))
+ CHECK_ERROR(_readData(c, &m->data))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_identity_rename_sub_V3(
+ parser_context_t* c, pd_identity_rename_sub_V3_t* m)
+{
+ CHECK_ERROR(_readLookupSource_V3(c, &m->sub))
+ CHECK_ERROR(_readData(c, &m->data))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_identity_remove_sub_V3(
+ parser_context_t* c, pd_identity_remove_sub_V3_t* m)
+{
+ CHECK_ERROR(_readLookupSource_V3(c, &m->sub))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_identity_quit_sub_V3(
+ parser_context_t* c, pd_identity_quit_sub_V3_t* m)
+{
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_recovery_as_recovered_V3(
+ parser_context_t* c, pd_recovery_as_recovered_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->account))
+ CHECK_ERROR(_readCall(c, &m->call))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_recovery_set_recovered_V3(
+ parser_context_t* c, pd_recovery_set_recovered_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->lost))
+ CHECK_ERROR(_readAccountId_V3(c, &m->rescuer))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_recovery_create_recovery_V3(
+ parser_context_t* c, pd_recovery_create_recovery_V3_t* m)
+{
+ CHECK_ERROR(_readVecAccountId_V3(c, &m->friends))
+ CHECK_ERROR(_readu16(c, &m->threshold))
+ CHECK_ERROR(_readBlockNumber(c, &m->delay_period))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_recovery_initiate_recovery_V3(
+ parser_context_t* c, pd_recovery_initiate_recovery_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->account))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_recovery_vouch_recovery_V3(
+ parser_context_t* c, pd_recovery_vouch_recovery_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->lost))
+ CHECK_ERROR(_readAccountId_V3(c, &m->rescuer))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_recovery_claim_recovery_V3(
+ parser_context_t* c, pd_recovery_claim_recovery_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->account))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_recovery_close_recovery_V3(
+ parser_context_t* c, pd_recovery_close_recovery_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->rescuer))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_recovery_remove_recovery_V3(
+ parser_context_t* c, pd_recovery_remove_recovery_V3_t* m)
+{
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_recovery_cancel_recovered_V3(
+ parser_context_t* c, pd_recovery_cancel_recovered_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->account))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_utility_as_derivative_V3(
+ parser_context_t* c, pd_utility_as_derivative_V3_t* m)
+{
+ CHECK_ERROR(_readu16(c, &m->index))
+ CHECK_ERROR(_readCall(c, &m->call))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_proxy_proxy_V3(
+ parser_context_t* c, pd_proxy_proxy_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->real))
+ CHECK_ERROR(_readOptionProxyType_V3(c, &m->force_proxy_type))
+ CHECK_ERROR(_readCall(c, &m->call))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_proxy_add_proxy_V3(
+ parser_context_t* c, pd_proxy_add_proxy_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->delegate))
+ CHECK_ERROR(_readProxyType_V3(c, &m->proxy_type))
+ CHECK_ERROR(_readBlockNumber(c, &m->delay))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_proxy_remove_proxy_V3(
+ parser_context_t* c, pd_proxy_remove_proxy_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->delegate))
+ CHECK_ERROR(_readProxyType_V3(c, &m->proxy_type))
+ CHECK_ERROR(_readBlockNumber(c, &m->delay))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_proxy_remove_proxies_V3(
+ parser_context_t* c, pd_proxy_remove_proxies_V3_t* m)
+{
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_proxy_anonymous_V3(
+ parser_context_t* c, pd_proxy_anonymous_V3_t* m)
+{
+ CHECK_ERROR(_readProxyType_V3(c, &m->proxy_type))
+ CHECK_ERROR(_readBlockNumber(c, &m->delay))
+ CHECK_ERROR(_readu16(c, &m->index))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_proxy_kill_anonymous_V3(
+ parser_context_t* c, pd_proxy_kill_anonymous_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->spawner))
+ CHECK_ERROR(_readProxyType_V3(c, &m->proxy_type))
+ CHECK_ERROR(_readu16(c, &m->index))
+ CHECK_ERROR(_readCompactBlockNumber(c, &m->height))
+ CHECK_ERROR(_readCompactu32(c, &m->ext_index))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_proxy_announce_V3(
+ parser_context_t* c, pd_proxy_announce_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->real))
+ CHECK_ERROR(_readCallHashOf_V3(c, &m->call_hash))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_proxy_remove_announcement_V3(
+ parser_context_t* c, pd_proxy_remove_announcement_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->real))
+ CHECK_ERROR(_readCallHashOf_V3(c, &m->call_hash))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_proxy_reject_announcement_V3(
+ parser_context_t* c, pd_proxy_reject_announcement_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->delegate))
+ CHECK_ERROR(_readCallHashOf_V3(c, &m->call_hash))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_proxy_proxy_announced_V3(
+ parser_context_t* c, pd_proxy_proxy_announced_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->delegate))
+ CHECK_ERROR(_readAccountId_V3(c, &m->real))
+ CHECK_ERROR(_readOptionProxyType_V3(c, &m->force_proxy_type))
+ CHECK_ERROR(_readCall(c, &m->call))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_multisig_as_multi_threshold_1_V3(
+ parser_context_t* c, pd_multisig_as_multi_threshold_1_V3_t* m)
+{
+ CHECK_ERROR(_readVecAccountId_V3(c, &m->other_signatories))
+ CHECK_ERROR(_readCall(c, &m->call))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_multisig_as_multi_V3(
+ parser_context_t* c, pd_multisig_as_multi_V3_t* m)
+{
+ CHECK_ERROR(_readu16(c, &m->threshold))
+ CHECK_ERROR(_readVecAccountId_V3(c, &m->other_signatories))
+ CHECK_ERROR(_readOptionTimepoint_V3(c, &m->maybe_timepoint))
+ CHECK_ERROR(_readOpaqueCall_V3(c, &m->call))
+ CHECK_ERROR(_readbool(c, &m->store_call))
+ CHECK_ERROR(_readWeight_V3(c, &m->max_weight))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_multisig_approve_as_multi_V3(
+ parser_context_t* c, pd_multisig_approve_as_multi_V3_t* m)
+{
+ CHECK_ERROR(_readu16(c, &m->threshold))
+ CHECK_ERROR(_readVecAccountId_V3(c, &m->other_signatories))
+ CHECK_ERROR(_readOptionTimepoint_V3(c, &m->maybe_timepoint))
+ CHECK_ERROR(_readu8_array_32_V3(c, &m->call_hash))
+ CHECK_ERROR(_readWeight_V3(c, &m->max_weight))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_multisig_cancel_as_multi_V3(
+ parser_context_t* c, pd_multisig_cancel_as_multi_V3_t* m)
+{
+ CHECK_ERROR(_readu16(c, &m->threshold))
+ CHECK_ERROR(_readVecAccountId_V3(c, &m->other_signatories))
+ CHECK_ERROR(_readTimepoint_V3(c, &m->timepoint))
+ CHECK_ERROR(_readu8_array_32_V3(c, &m->call_hash))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_contracts_update_schedule_V3(
+ parser_context_t* c, pd_contracts_update_schedule_V3_t* m)
+{
+ CHECK_ERROR(_readSchedule_V3(c, &m->schedule))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_contracts_call_V3(
+ parser_context_t* c, pd_contracts_call_V3_t* m)
+{
+ CHECK_ERROR(_readLookupSource_V3(c, &m->dest))
+ CHECK_ERROR(_readCompactBalanceOf(c, &m->value))
+ CHECK_ERROR(_readCompactWeight_V3(c, &m->gas_limit))
+ CHECK_ERROR(_readBytes(c, &m->data))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_contracts_instantiate_with_code_V3(
+ parser_context_t* c, pd_contracts_instantiate_with_code_V3_t* m)
+{
+ CHECK_ERROR(_readCompactBalanceOf(c, &m->endowment))
+ CHECK_ERROR(_readCompactWeight_V3(c, &m->gas_limit))
+ CHECK_ERROR(_readBytes(c, &m->code))
+ CHECK_ERROR(_readBytes(c, &m->data))
+ CHECK_ERROR(_readBytes(c, &m->salt))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_contracts_instantiate_V3(
+ parser_context_t* c, pd_contracts_instantiate_V3_t* m)
+{
+ CHECK_ERROR(_readCompactBalanceOf(c, &m->endowment))
+ CHECK_ERROR(_readCompactWeight_V3(c, &m->gas_limit))
+ CHECK_ERROR(_readCodeHash_V3(c, &m->code_hash))
+ CHECK_ERROR(_readBytes(c, &m->data))
+ CHECK_ERROR(_readBytes(c, &m->salt))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_contracts_claim_surcharge_V3(
+ parser_context_t* c, pd_contracts_claim_surcharge_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->dest))
+ CHECK_ERROR(_readOptionAccountId_V3(c, &m->aux_sender))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_pkitcr_apply_V3(
+ parser_context_t* c, pd_pkitcr_apply_V3_t* m)
+{
+ CHECK_ERROR(_readBytes(c, &m->metadata))
+ CHECK_ERROR(_readBalanceOf(c, &m->deposit))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_pkitcr_counter_V3(
+ parser_context_t* c, pd_pkitcr_counter_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->member))
+ CHECK_ERROR(_readBalanceOf(c, &m->deposit))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_pkitcr_vote_V3(
+ parser_context_t* c, pd_pkitcr_vote_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->member))
+ CHECK_ERROR(_readbool(c, &m->supporting))
+ CHECK_ERROR(_readBalanceOf(c, &m->deposit))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_pkitcr_challenge_V3(
+ parser_context_t* c, pd_pkitcr_challenge_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->member))
+ CHECK_ERROR(_readBalanceOf(c, &m->deposit))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_pkirootoftrust_book_slot_V3(
+ parser_context_t* c, pd_pkirootoftrust_book_slot_V3_t* m)
+{
+ CHECK_ERROR(_readCertificateId_V3(c, &m->certificate_id))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_pkirootoftrust_renew_slot_V3(
+ parser_context_t* c, pd_pkirootoftrust_renew_slot_V3_t* m)
+{
+ CHECK_ERROR(_readCertificateId_V3(c, &m->certificate_id))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_pkirootoftrust_revoke_slot_V3(
+ parser_context_t* c, pd_pkirootoftrust_revoke_slot_V3_t* m)
+{
+ CHECK_ERROR(_readCertificateId_V3(c, &m->certificate_id))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_pkirootoftrust_revoke_child_V3(
+ parser_context_t* c, pd_pkirootoftrust_revoke_child_V3_t* m)
+{
+ CHECK_ERROR(_readCertificateId_V3(c, &m->root))
+ CHECK_ERROR(_readCertificateId_V3(c, &m->child))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_emergencyshutdown_toggle_V3(
+ parser_context_t* c, pd_emergencyshutdown_toggle_V3_t* m)
+{
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_allocations_allocate_V3(
+ parser_context_t* c, pd_allocations_allocate_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->to))
+ CHECK_ERROR(_readBalanceOf(c, &m->amount))
+ CHECK_ERROR(_readBytes(c, &m->proof))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_allocationsoracles_add_member_V3(
+ parser_context_t* c, pd_allocationsoracles_add_member_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->who))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_allocationsoracles_remove_member_V3(
+ parser_context_t* c, pd_allocationsoracles_remove_member_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->who))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_allocationsoracles_swap_member_V3(
+ parser_context_t* c, pd_allocationsoracles_swap_member_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->remove))
+ CHECK_ERROR(_readAccountId_V3(c, &m->add))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_allocationsoracles_reset_members_V3(
+ parser_context_t* c, pd_allocationsoracles_reset_members_V3_t* m)
+{
+ CHECK_ERROR(_readVecAccountId_V3(c, &m->members))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_allocationsoracles_change_key_V3(
+ parser_context_t* c, pd_allocationsoracles_change_key_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->new_))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_allocationsoracles_set_prime_V3(
+ parser_context_t* c, pd_allocationsoracles_set_prime_V3_t* m)
+{
+ CHECK_ERROR(_readAccountId_V3(c, &m->who))
+ return parser_ok;
+}
+
+__Z_INLINE parser_error_t _readMethod_allocationsoracles_clear_prime_V3(
+ parser_context_t* c, pd_allocationsoracles_clear_prime_V3_t* m)
+{
+ return parser_ok;
+}
+
+#endif
+
+parser_error_t _readMethod_V3(
+ parser_context_t* c,
+ uint8_t moduleIdx,
+ uint8_t callIdx,
+ pd_Method_V3_t* method)
+{
+ uint16_t callPrivIdx = ((uint16_t)moduleIdx << 8u) + callIdx;
+
+ switch (callPrivIdx) {
+
+ case 768: /* module 3 call 0 */
+ CHECK_ERROR(_readMethod_balances_transfer_V3(c, &method->nested.balances_transfer_V3))
+ break;
+ case 771: /* module 3 call 3 */
+ CHECK_ERROR(_readMethod_balances_transfer_keep_alive_V3(c, &method->nested.balances_transfer_keep_alive_V3))
+ break;
+ case 3072: /* module 12 call 0 */
+ CHECK_ERROR(_readMethod_session_set_keys_V3(c, &method->basic.session_set_keys_V3))
+ break;
+ case 3073: /* module 12 call 1 */
+ CHECK_ERROR(_readMethod_session_purge_keys_V3(c, &method->basic.session_purge_keys_V3))
+ break;
+ case 7680: /* module 30 call 0 */
+ CHECK_ERROR(_readMethod_utility_batch_V3(c, &method->basic.utility_batch_V3))
+ break;
+ case 7682: /* module 30 call 2 */
+ CHECK_ERROR(_readMethod_utility_batch_all_V3(c, &method->basic.utility_batch_all_V3))
+ break;
+
+#ifdef SUBSTRATE_PARSER_FULL
+ case 0: /* module 0 call 0 */
+ CHECK_ERROR(_readMethod_system_fill_block_V3(c, &method->nested.system_fill_block_V3))
+ break;
+ case 1: /* module 0 call 1 */
+ CHECK_ERROR(_readMethod_system_remark_V3(c, &method->nested.system_remark_V3))
+ break;
+ case 2: /* module 0 call 2 */
+ CHECK_ERROR(_readMethod_system_set_heap_pages_V3(c, &method->nested.system_set_heap_pages_V3))
+ break;
+ case 3: /* module 0 call 3 */
+ CHECK_ERROR(_readMethod_system_set_code_V3(c, &method->nested.system_set_code_V3))
+ break;
+ case 4: /* module 0 call 4 */
+ CHECK_ERROR(_readMethod_system_set_code_without_checks_V3(c, &method->nested.system_set_code_without_checks_V3))
+ break;
+ case 5: /* module 0 call 5 */
+ CHECK_ERROR(_readMethod_system_set_changes_trie_config_V3(c, &method->nested.system_set_changes_trie_config_V3))
+ break;
+ case 6: /* module 0 call 6 */
+ CHECK_ERROR(_readMethod_system_set_storage_V3(c, &method->nested.system_set_storage_V3))
+ break;
+ case 7: /* module 0 call 7 */
+ CHECK_ERROR(_readMethod_system_kill_storage_V3(c, &method->nested.system_kill_storage_V3))
+ break;
+ case 8: /* module 0 call 8 */
+ CHECK_ERROR(_readMethod_system_kill_prefix_V3(c, &method->nested.system_kill_prefix_V3))
+ break;
+ case 256: /* module 1 call 0 */
+ CHECK_ERROR(_readMethod_timestamp_set_V3(c, &method->basic.timestamp_set_V3))
+ break;
+ case 512: /* module 2 call 0 */
+ CHECK_ERROR(_readMethod_indices_claim_V3(c, &method->basic.indices_claim_V3))
+ break;
+ case 513: /* module 2 call 1 */
+ CHECK_ERROR(_readMethod_indices_transfer_V3(c, &method->basic.indices_transfer_V3))
+ break;
+ case 514: /* module 2 call 2 */
+ CHECK_ERROR(_readMethod_indices_free_V3(c, &method->basic.indices_free_V3))
+ break;
+ case 515: /* module 2 call 3 */
+ CHECK_ERROR(_readMethod_indices_force_transfer_V3(c, &method->basic.indices_force_transfer_V3))
+ break;
+ case 516: /* module 2 call 4 */
+ CHECK_ERROR(_readMethod_indices_freeze_V3(c, &method->basic.indices_freeze_V3))
+ break;
+ case 769: /* module 3 call 1 */
+ CHECK_ERROR(_readMethod_balances_set_balance_V3(c, &method->nested.balances_set_balance_V3))
+ break;
+ case 770: /* module 3 call 2 */
+ CHECK_ERROR(_readMethod_balances_force_transfer_V3(c, &method->nested.balances_force_transfer_V3))
+ break;
+ case 1536: /* module 6 call 0 */
+ CHECK_ERROR(_readMethod_babe_report_equivocation_V3(c, &method->basic.babe_report_equivocation_V3))
+ break;
+ case 1537: /* module 6 call 1 */
+ CHECK_ERROR(_readMethod_babe_report_equivocation_unsigned_V3(c, &method->basic.babe_report_equivocation_unsigned_V3))
+ break;
+ case 1792: /* module 7 call 0 */
+ CHECK_ERROR(_readMethod_grandpa_report_equivocation_V3(c, &method->basic.grandpa_report_equivocation_V3))
+ break;
+ case 1793: /* module 7 call 1 */
+ CHECK_ERROR(_readMethod_grandpa_report_equivocation_unsigned_V3(c, &method->basic.grandpa_report_equivocation_unsigned_V3))
+ break;
+ case 1794: /* module 7 call 2 */
+ CHECK_ERROR(_readMethod_grandpa_note_stalled_V3(c, &method->basic.grandpa_note_stalled_V3))
+ break;
+ case 2048: /* module 8 call 0 */
+ CHECK_ERROR(_readMethod_authorship_set_uncles_V3(c, &method->basic.authorship_set_uncles_V3))
+ break;
+ case 2304: /* module 9 call 0 */
+ CHECK_ERROR(_readMethod_imonline_heartbeat_V3(c, &method->basic.imonline_heartbeat_V3))
+ break;
+ case 2816: /* module 11 call 0 */
+ CHECK_ERROR(_readMethod_validatorsset_add_member_V3(c, &method->basic.validatorsset_add_member_V3))
+ break;
+ case 2817: /* module 11 call 1 */
+ CHECK_ERROR(_readMethod_validatorsset_remove_member_V3(c, &method->basic.validatorsset_remove_member_V3))
+ break;
+ case 2818: /* module 11 call 2 */
+ CHECK_ERROR(_readMethod_validatorsset_swap_member_V3(c, &method->basic.validatorsset_swap_member_V3))
+ break;
+ case 2819: /* module 11 call 3 */
+ CHECK_ERROR(_readMethod_validatorsset_reset_members_V3(c, &method->basic.validatorsset_reset_members_V3))
+ break;
+ case 2820: /* module 11 call 4 */
+ CHECK_ERROR(_readMethod_validatorsset_change_key_V3(c, &method->basic.validatorsset_change_key_V3))
+ break;
+ case 2821: /* module 11 call 5 */
+ CHECK_ERROR(_readMethod_validatorsset_set_prime_V3(c, &method->basic.validatorsset_set_prime_V3))
+ break;
+ case 2822: /* module 11 call 6 */
+ CHECK_ERROR(_readMethod_validatorsset_clear_prime_V3(c, &method->basic.validatorsset_clear_prime_V3))
+ break;
+ case 3840: /* module 15 call 0 */
+ CHECK_ERROR(_readMethod_technicalcommittee_set_members_V3(c, &method->basic.technicalcommittee_set_members_V3))
+ break;
+ case 3841: /* module 15 call 1 */
+ CHECK_ERROR(_readMethod_technicalcommittee_execute_V3(c, &method->basic.technicalcommittee_execute_V3))
+ break;
+ case 3842: /* module 15 call 2 */
+ CHECK_ERROR(_readMethod_technicalcommittee_propose_V3(c, &method->basic.technicalcommittee_propose_V3))
+ break;
+ case 3843: /* module 15 call 3 */
+ CHECK_ERROR(_readMethod_technicalcommittee_vote_V3(c, &method->basic.technicalcommittee_vote_V3))
+ break;
+ case 3844: /* module 15 call 4 */
+ CHECK_ERROR(_readMethod_technicalcommittee_close_V3(c, &method->basic.technicalcommittee_close_V3))
+ break;
+ case 3845: /* module 15 call 5 */
+ CHECK_ERROR(_readMethod_technicalcommittee_disapprove_proposal_V3(c, &method->basic.technicalcommittee_disapprove_proposal_V3))
+ break;
+ case 4096: /* module 16 call 0 */
+ CHECK_ERROR(_readMethod_technicalmembership_add_member_V3(c, &method->basic.technicalmembership_add_member_V3))
+ break;
+ case 4097: /* module 16 call 1 */
+ CHECK_ERROR(_readMethod_technicalmembership_remove_member_V3(c, &method->basic.technicalmembership_remove_member_V3))
+ break;
+ case 4098: /* module 16 call 2 */
+ CHECK_ERROR(_readMethod_technicalmembership_swap_member_V3(c, &method->basic.technicalmembership_swap_member_V3))
+ break;
+ case 4099: /* module 16 call 3 */
+ CHECK_ERROR(_readMethod_technicalmembership_reset_members_V3(c, &method->basic.technicalmembership_reset_members_V3))
+ break;
+ case 4100: /* module 16 call 4 */
+ CHECK_ERROR(_readMethod_technicalmembership_change_key_V3(c, &method->basic.technicalmembership_change_key_V3))
+ break;
+ case 4101: /* module 16 call 5 */
+ CHECK_ERROR(_readMethod_technicalmembership_set_prime_V3(c, &method->basic.technicalmembership_set_prime_V3))
+ break;
+ case 4102: /* module 16 call 6 */
+ CHECK_ERROR(_readMethod_technicalmembership_clear_prime_V3(c, &method->basic.technicalmembership_clear_prime_V3))
+ break;
+ case 4352: /* module 17 call 0 */
+ CHECK_ERROR(_readMethod_financialcommittee_set_members_V3(c, &method->basic.financialcommittee_set_members_V3))
+ break;
+ case 4353: /* module 17 call 1 */
+ CHECK_ERROR(_readMethod_financialcommittee_execute_V3(c, &method->basic.financialcommittee_execute_V3))
+ break;
+ case 4354: /* module 17 call 2 */
+ CHECK_ERROR(_readMethod_financialcommittee_propose_V3(c, &method->basic.financialcommittee_propose_V3))
+ break;
+ case 4355: /* module 17 call 3 */
+ CHECK_ERROR(_readMethod_financialcommittee_vote_V3(c, &method->basic.financialcommittee_vote_V3))
+ break;
+ case 4356: /* module 17 call 4 */
+ CHECK_ERROR(_readMethod_financialcommittee_close_V3(c, &method->basic.financialcommittee_close_V3))
+ break;
+ case 4357: /* module 17 call 5 */
+ CHECK_ERROR(_readMethod_financialcommittee_disapprove_proposal_V3(c, &method->basic.financialcommittee_disapprove_proposal_V3))
+ break;
+ case 4608: /* module 18 call 0 */
+ CHECK_ERROR(_readMethod_financialmembership_add_member_V3(c, &method->basic.financialmembership_add_member_V3))
+ break;
+ case 4609: /* module 18 call 1 */
+ CHECK_ERROR(_readMethod_financialmembership_remove_member_V3(c, &method->basic.financialmembership_remove_member_V3))
+ break;
+ case 4610: /* module 18 call 2 */
+ CHECK_ERROR(_readMethod_financialmembership_swap_member_V3(c, &method->basic.financialmembership_swap_member_V3))
+ break;
+ case 4611: /* module 18 call 3 */
+ CHECK_ERROR(_readMethod_financialmembership_reset_members_V3(c, &method->basic.financialmembership_reset_members_V3))
+ break;
+ case 4612: /* module 18 call 4 */
+ CHECK_ERROR(_readMethod_financialmembership_change_key_V3(c, &method->basic.financialmembership_change_key_V3))
+ break;
+ case 4613: /* module 18 call 5 */
+ CHECK_ERROR(_readMethod_financialmembership_set_prime_V3(c, &method->basic.financialmembership_set_prime_V3))
+ break;
+ case 4614: /* module 18 call 6 */
+ CHECK_ERROR(_readMethod_financialmembership_clear_prime_V3(c, &method->basic.financialmembership_clear_prime_V3))
+ break;
+ case 4864: /* module 19 call 0 */
+ CHECK_ERROR(_readMethod_rootcommittee_set_members_V3(c, &method->basic.rootcommittee_set_members_V3))
+ break;
+ case 4865: /* module 19 call 1 */
+ CHECK_ERROR(_readMethod_rootcommittee_execute_V3(c, &method->basic.rootcommittee_execute_V3))
+ break;
+ case 4866: /* module 19 call 2 */
+ CHECK_ERROR(_readMethod_rootcommittee_propose_V3(c, &method->basic.rootcommittee_propose_V3))
+ break;
+ case 4867: /* module 19 call 3 */
+ CHECK_ERROR(_readMethod_rootcommittee_vote_V3(c, &method->basic.rootcommittee_vote_V3))
+ break;
+ case 4868: /* module 19 call 4 */
+ CHECK_ERROR(_readMethod_rootcommittee_close_V3(c, &method->basic.rootcommittee_close_V3))
+ break;
+ case 4869: /* module 19 call 5 */
+ CHECK_ERROR(_readMethod_rootcommittee_disapprove_proposal_V3(c, &method->basic.rootcommittee_disapprove_proposal_V3))
+ break;
+ case 5120: /* module 20 call 0 */
+ CHECK_ERROR(_readMethod_rootmembership_add_member_V3(c, &method->basic.rootmembership_add_member_V3))
+ break;
+ case 5121: /* module 20 call 1 */
+ CHECK_ERROR(_readMethod_rootmembership_remove_member_V3(c, &method->basic.rootmembership_remove_member_V3))
+ break;
+ case 5122: /* module 20 call 2 */
+ CHECK_ERROR(_readMethod_rootmembership_swap_member_V3(c, &method->basic.rootmembership_swap_member_V3))
+ break;
+ case 5123: /* module 20 call 3 */
+ CHECK_ERROR(_readMethod_rootmembership_reset_members_V3(c, &method->basic.rootmembership_reset_members_V3))
+ break;
+ case 5124: /* module 20 call 4 */
+ CHECK_ERROR(_readMethod_rootmembership_change_key_V3(c, &method->basic.rootmembership_change_key_V3))
+ break;
+ case 5125: /* module 20 call 5 */
+ CHECK_ERROR(_readMethod_rootmembership_set_prime_V3(c, &method->basic.rootmembership_set_prime_V3))
+ break;
+ case 5126: /* module 20 call 6 */
+ CHECK_ERROR(_readMethod_rootmembership_clear_prime_V3(c, &method->basic.rootmembership_clear_prime_V3))
+ break;
+ case 5376: /* module 21 call 0 */
+ CHECK_ERROR(_readMethod_scheduler_schedule_V3(c, &method->basic.scheduler_schedule_V3))
+ break;
+ case 5377: /* module 21 call 1 */
+ CHECK_ERROR(_readMethod_scheduler_cancel_V3(c, &method->basic.scheduler_cancel_V3))
+ break;
+ case 5378: /* module 21 call 2 */
+ CHECK_ERROR(_readMethod_scheduler_schedule_named_V3(c, &method->basic.scheduler_schedule_named_V3))
+ break;
+ case 5379: /* module 21 call 3 */
+ CHECK_ERROR(_readMethod_scheduler_cancel_named_V3(c, &method->basic.scheduler_cancel_named_V3))
+ break;
+ case 5380: /* module 21 call 4 */
+ CHECK_ERROR(_readMethod_scheduler_schedule_after_V3(c, &method->basic.scheduler_schedule_after_V3))
+ break;
+ case 5381: /* module 21 call 5 */
+ CHECK_ERROR(_readMethod_scheduler_schedule_named_after_V3(c, &method->basic.scheduler_schedule_named_after_V3))
+ break;
+ case 5632: /* module 22 call 0 */
+ CHECK_ERROR(_readMethod_amendments_propose_V3(c, &method->basic.amendments_propose_V3))
+ break;
+ case 5633: /* module 22 call 1 */
+ CHECK_ERROR(_readMethod_amendments_veto_V3(c, &method->basic.amendments_veto_V3))
+ break;
+ case 5888: /* module 23 call 0 */
+ CHECK_ERROR(_readMethod_mandate_apply_V3(c, &method->basic.mandate_apply_V3))
+ break;
+ case 6144: /* module 24 call 0 */
+ CHECK_ERROR(_readMethod_companyreserve_spend_V3(c, &method->basic.companyreserve_spend_V3))
+ break;
+ case 6145: /* module 24 call 1 */
+ CHECK_ERROR(_readMethod_companyreserve_tip_V3(c, &method->basic.companyreserve_tip_V3))
+ break;
+ case 6146: /* module 24 call 2 */
+ CHECK_ERROR(_readMethod_companyreserve_apply_as_V3(c, &method->basic.companyreserve_apply_as_V3))
+ break;
+ case 6400: /* module 25 call 0 */
+ CHECK_ERROR(_readMethod_internationalreserve_spend_V3(c, &method->basic.internationalreserve_spend_V3))
+ break;
+ case 6401: /* module 25 call 1 */
+ CHECK_ERROR(_readMethod_internationalreserve_tip_V3(c, &method->basic.internationalreserve_tip_V3))
+ break;
+ case 6402: /* module 25 call 2 */
+ CHECK_ERROR(_readMethod_internationalreserve_apply_as_V3(c, &method->basic.internationalreserve_apply_as_V3))
+ break;
+ case 6656: /* module 26 call 0 */
+ CHECK_ERROR(_readMethod_usareserve_spend_V3(c, &method->basic.usareserve_spend_V3))
+ break;
+ case 6657: /* module 26 call 1 */
+ CHECK_ERROR(_readMethod_usareserve_tip_V3(c, &method->basic.usareserve_tip_V3))
+ break;
+ case 6658: /* module 26 call 2 */
+ CHECK_ERROR(_readMethod_usareserve_apply_as_V3(c, &method->basic.usareserve_apply_as_V3))
+ break;
+ case 6912: /* module 27 call 0 */
+ CHECK_ERROR(_readMethod_vesting_claim_V3(c, &method->basic.vesting_claim_V3))
+ break;
+ case 6913: /* module 27 call 1 */
+ CHECK_ERROR(_readMethod_vesting_add_vesting_schedule_V3(c, &method->basic.vesting_add_vesting_schedule_V3))
+ break;
+ case 6914: /* module 27 call 2 */
+ CHECK_ERROR(_readMethod_vesting_cancel_all_vesting_schedules_V3(c, &method->basic.vesting_cancel_all_vesting_schedules_V3))
+ break;
+ case 7168: /* module 28 call 0 */
+ CHECK_ERROR(_readMethod_identity_add_registrar_V3(c, &method->basic.identity_add_registrar_V3))
+ break;
+ case 7169: /* module 28 call 1 */
+ CHECK_ERROR(_readMethod_identity_set_identity_V3(c, &method->basic.identity_set_identity_V3))
+ break;
+ case 7170: /* module 28 call 2 */
+ CHECK_ERROR(_readMethod_identity_set_subs_V3(c, &method->basic.identity_set_subs_V3))
+ break;
+ case 7171: /* module 28 call 3 */
+ CHECK_ERROR(_readMethod_identity_clear_identity_V3(c, &method->basic.identity_clear_identity_V3))
+ break;
+ case 7172: /* module 28 call 4 */
+ CHECK_ERROR(_readMethod_identity_request_judgement_V3(c, &method->basic.identity_request_judgement_V3))
+ break;
+ case 7173: /* module 28 call 5 */
+ CHECK_ERROR(_readMethod_identity_cancel_request_V3(c, &method->basic.identity_cancel_request_V3))
+ break;
+ case 7174: /* module 28 call 6 */
+ CHECK_ERROR(_readMethod_identity_set_fee_V3(c, &method->basic.identity_set_fee_V3))
+ break;
+ case 7175: /* module 28 call 7 */
+ CHECK_ERROR(_readMethod_identity_set_account_id_V3(c, &method->basic.identity_set_account_id_V3))
+ break;
+ case 7176: /* module 28 call 8 */
+ CHECK_ERROR(_readMethod_identity_set_fields_V3(c, &method->basic.identity_set_fields_V3))
+ break;
+ case 7177: /* module 28 call 9 */
+ CHECK_ERROR(_readMethod_identity_provide_judgement_V3(c, &method->basic.identity_provide_judgement_V3))
+ break;
+ case 7178: /* module 28 call 10 */
+ CHECK_ERROR(_readMethod_identity_kill_identity_V3(c, &method->basic.identity_kill_identity_V3))
+ break;
+ case 7179: /* module 28 call 11 */
+ CHECK_ERROR(_readMethod_identity_add_sub_V3(c, &method->basic.identity_add_sub_V3))
+ break;
+ case 7180: /* module 28 call 12 */
+ CHECK_ERROR(_readMethod_identity_rename_sub_V3(c, &method->basic.identity_rename_sub_V3))
+ break;
+ case 7181: /* module 28 call 13 */
+ CHECK_ERROR(_readMethod_identity_remove_sub_V3(c, &method->basic.identity_remove_sub_V3))
+ break;
+ case 7182: /* module 28 call 14 */
+ CHECK_ERROR(_readMethod_identity_quit_sub_V3(c, &method->basic.identity_quit_sub_V3))
+ break;
+ case 7424: /* module 29 call 0 */
+ CHECK_ERROR(_readMethod_recovery_as_recovered_V3(c, &method->basic.recovery_as_recovered_V3))
+ break;
+ case 7425: /* module 29 call 1 */
+ CHECK_ERROR(_readMethod_recovery_set_recovered_V3(c, &method->basic.recovery_set_recovered_V3))
+ break;
+ case 7426: /* module 29 call 2 */
+ CHECK_ERROR(_readMethod_recovery_create_recovery_V3(c, &method->basic.recovery_create_recovery_V3))
+ break;
+ case 7427: /* module 29 call 3 */
+ CHECK_ERROR(_readMethod_recovery_initiate_recovery_V3(c, &method->basic.recovery_initiate_recovery_V3))
+ break;
+ case 7428: /* module 29 call 4 */
+ CHECK_ERROR(_readMethod_recovery_vouch_recovery_V3(c, &method->basic.recovery_vouch_recovery_V3))
+ break;
+ case 7429: /* module 29 call 5 */
+ CHECK_ERROR(_readMethod_recovery_claim_recovery_V3(c, &method->basic.recovery_claim_recovery_V3))
+ break;
+ case 7430: /* module 29 call 6 */
+ CHECK_ERROR(_readMethod_recovery_close_recovery_V3(c, &method->basic.recovery_close_recovery_V3))
+ break;
+ case 7431: /* module 29 call 7 */
+ CHECK_ERROR(_readMethod_recovery_remove_recovery_V3(c, &method->basic.recovery_remove_recovery_V3))
+ break;
+ case 7432: /* module 29 call 8 */
+ CHECK_ERROR(_readMethod_recovery_cancel_recovered_V3(c, &method->basic.recovery_cancel_recovered_V3))
+ break;
+ case 7681: /* module 30 call 1 */
+ CHECK_ERROR(_readMethod_utility_as_derivative_V3(c, &method->basic.utility_as_derivative_V3))
+ break;
+ case 7936: /* module 31 call 0 */
+ CHECK_ERROR(_readMethod_proxy_proxy_V3(c, &method->nested.proxy_proxy_V3))
+ break;
+ case 7937: /* module 31 call 1 */
+ CHECK_ERROR(_readMethod_proxy_add_proxy_V3(c, &method->basic.proxy_add_proxy_V3))
+ break;
+ case 7938: /* module 31 call 2 */
+ CHECK_ERROR(_readMethod_proxy_remove_proxy_V3(c, &method->basic.proxy_remove_proxy_V3))
+ break;
+ case 7939: /* module 31 call 3 */
+ CHECK_ERROR(_readMethod_proxy_remove_proxies_V3(c, &method->basic.proxy_remove_proxies_V3))
+ break;
+ case 7940: /* module 31 call 4 */
+ CHECK_ERROR(_readMethod_proxy_anonymous_V3(c, &method->basic.proxy_anonymous_V3))
+ break;
+ case 7941: /* module 31 call 5 */
+ CHECK_ERROR(_readMethod_proxy_kill_anonymous_V3(c, &method->basic.proxy_kill_anonymous_V3))
+ break;
+ case 7942: /* module 31 call 6 */
+ CHECK_ERROR(_readMethod_proxy_announce_V3(c, &method->basic.proxy_announce_V3))
+ break;
+ case 7943: /* module 31 call 7 */
+ CHECK_ERROR(_readMethod_proxy_remove_announcement_V3(c, &method->basic.proxy_remove_announcement_V3))
+ break;
+ case 7944: /* module 31 call 8 */
+ CHECK_ERROR(_readMethod_proxy_reject_announcement_V3(c, &method->basic.proxy_reject_announcement_V3))
+ break;
+ case 7945: /* module 31 call 9 */
+ CHECK_ERROR(_readMethod_proxy_proxy_announced_V3(c, &method->basic.proxy_proxy_announced_V3))
+ break;
+ case 8192: /* module 32 call 0 */
+ CHECK_ERROR(_readMethod_multisig_as_multi_threshold_1_V3(c, &method->nested.multisig_as_multi_threshold_1_V3))
+ break;
+ case 8193: /* module 32 call 1 */
+ CHECK_ERROR(_readMethod_multisig_as_multi_V3(c, &method->nested.multisig_as_multi_V3))
+ break;
+ case 8194: /* module 32 call 2 */
+ CHECK_ERROR(_readMethod_multisig_approve_as_multi_V3(c, &method->nested.multisig_approve_as_multi_V3))
+ break;
+ case 8195: /* module 32 call 3 */
+ CHECK_ERROR(_readMethod_multisig_cancel_as_multi_V3(c, &method->nested.multisig_cancel_as_multi_V3))
+ break;
+ case 8448: /* module 33 call 0 */
+ CHECK_ERROR(_readMethod_contracts_update_schedule_V3(c, &method->basic.contracts_update_schedule_V3))
+ break;
+ case 8449: /* module 33 call 1 */
+ CHECK_ERROR(_readMethod_contracts_call_V3(c, &method->basic.contracts_call_V3))
+ break;
+ case 8450: /* module 33 call 2 */
+ CHECK_ERROR(_readMethod_contracts_instantiate_with_code_V3(c, &method->basic.contracts_instantiate_with_code_V3))
+ break;
+ case 8451: /* module 33 call 3 */
+ CHECK_ERROR(_readMethod_contracts_instantiate_V3(c, &method->basic.contracts_instantiate_V3))
+ break;
+ case 8452: /* module 33 call 4 */
+ CHECK_ERROR(_readMethod_contracts_claim_surcharge_V3(c, &method->basic.contracts_claim_surcharge_V3))
+ break;
+ case 8704: /* module 34 call 0 */
+ CHECK_ERROR(_readMethod_pkitcr_apply_V3(c, &method->basic.pkitcr_apply_V3))
+ break;
+ case 8705: /* module 34 call 1 */
+ CHECK_ERROR(_readMethod_pkitcr_counter_V3(c, &method->basic.pkitcr_counter_V3))
+ break;
+ case 8706: /* module 34 call 2 */
+ CHECK_ERROR(_readMethod_pkitcr_vote_V3(c, &method->basic.pkitcr_vote_V3))
+ break;
+ case 8707: /* module 34 call 3 */
+ CHECK_ERROR(_readMethod_pkitcr_challenge_V3(c, &method->basic.pkitcr_challenge_V3))
+ break;
+ case 8960: /* module 35 call 0 */
+ CHECK_ERROR(_readMethod_pkirootoftrust_book_slot_V3(c, &method->basic.pkirootoftrust_book_slot_V3))
+ break;
+ case 8961: /* module 35 call 1 */
+ CHECK_ERROR(_readMethod_pkirootoftrust_renew_slot_V3(c, &method->basic.pkirootoftrust_renew_slot_V3))
+ break;
+ case 8962: /* module 35 call 2 */
+ CHECK_ERROR(_readMethod_pkirootoftrust_revoke_slot_V3(c, &method->basic.pkirootoftrust_revoke_slot_V3))
+ break;
+ case 8963: /* module 35 call 3 */
+ CHECK_ERROR(_readMethod_pkirootoftrust_revoke_child_V3(c, &method->basic.pkirootoftrust_revoke_child_V3))
+ break;
+ case 9216: /* module 36 call 0 */
+ CHECK_ERROR(_readMethod_emergencyshutdown_toggle_V3(c, &method->basic.emergencyshutdown_toggle_V3))
+ break;
+ case 9472: /* module 37 call 0 */
+ CHECK_ERROR(_readMethod_allocations_allocate_V3(c, &method->basic.allocations_allocate_V3))
+ break;
+ case 9728: /* module 38 call 0 */
+ CHECK_ERROR(_readMethod_allocationsoracles_add_member_V3(c, &method->basic.allocationsoracles_add_member_V3))
+ break;
+ case 9729: /* module 38 call 1 */
+ CHECK_ERROR(_readMethod_allocationsoracles_remove_member_V3(c, &method->basic.allocationsoracles_remove_member_V3))
+ break;
+ case 9730: /* module 38 call 2 */
+ CHECK_ERROR(_readMethod_allocationsoracles_swap_member_V3(c, &method->basic.allocationsoracles_swap_member_V3))
+ break;
+ case 9731: /* module 38 call 3 */
+ CHECK_ERROR(_readMethod_allocationsoracles_reset_members_V3(c, &method->basic.allocationsoracles_reset_members_V3))
+ break;
+ case 9732: /* module 38 call 4 */
+ CHECK_ERROR(_readMethod_allocationsoracles_change_key_V3(c, &method->basic.allocationsoracles_change_key_V3))
+ break;
+ case 9733: /* module 38 call 5 */
+ CHECK_ERROR(_readMethod_allocationsoracles_set_prime_V3(c, &method->basic.allocationsoracles_set_prime_V3))
+ break;
+ case 9734: /* module 38 call 6 */
+ CHECK_ERROR(_readMethod_allocationsoracles_clear_prime_V3(c, &method->basic.allocationsoracles_clear_prime_V3))
+ break;
+#endif
+ default:
+ return parser_not_supported;
+ }
+
+ return parser_ok;
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+
+const char* _getMethod_ModuleName_V3(uint8_t moduleIdx)
+{
+ switch (moduleIdx) {
+ case 3:
+ return STR_MO_BALANCES;
+ case 12:
+ return STR_MO_SESSION;
+ case 30:
+ return STR_MO_UTILITY;
+#ifdef SUBSTRATE_PARSER_FULL
+ case 0:
+ return STR_MO_SYSTEM;
+ case 1:
+ return STR_MO_TIMESTAMP;
+ case 2:
+ return STR_MO_INDICES;
+ case 5:
+ return STR_MO_RANDOMNESSCOLLECTIVEFLIP;
+ case 6:
+ return STR_MO_BABE;
+ case 7:
+ return STR_MO_GRANDPA;
+ case 8:
+ return STR_MO_AUTHORSHIP;
+ case 9:
+ return STR_MO_IMONLINE;
+ case 10:
+ return STR_MO_OFFENCES;
+ case 11:
+ return STR_MO_VALIDATORSSET;
+ case 14:
+ return STR_MO_AUTHORITYDISCOVERY;
+ case 15:
+ return STR_MO_TECHNICALCOMMITTEE;
+ case 16:
+ return STR_MO_TECHNICALMEMBERSHIP;
+ case 17:
+ return STR_MO_FINANCIALCOMMITTEE;
+ case 18:
+ return STR_MO_FINANCIALMEMBERSHIP;
+ case 19:
+ return STR_MO_ROOTCOMMITTEE;
+ case 20:
+ return STR_MO_ROOTMEMBERSHIP;
+ case 21:
+ return STR_MO_SCHEDULER;
+ case 22:
+ return STR_MO_AMENDMENTS;
+ case 23:
+ return STR_MO_MANDATE;
+ case 24:
+ return STR_MO_COMPANYRESERVE;
+ case 25:
+ return STR_MO_INTERNATIONALRESERVE;
+ case 26:
+ return STR_MO_USARESERVE;
+ case 27:
+ return STR_MO_VESTING;
+ case 28:
+ return STR_MO_IDENTITY;
+ case 29:
+ return STR_MO_RECOVERY;
+ case 31:
+ return STR_MO_PROXY;
+ case 32:
+ return STR_MO_MULTISIG;
+ case 33:
+ return STR_MO_CONTRACTS;
+ case 34:
+ return STR_MO_PKITCR;
+ case 35:
+ return STR_MO_PKIROOTOFTRUST;
+ case 36:
+ return STR_MO_EMERGENCYSHUTDOWN;
+ case 37:
+ return STR_MO_ALLOCATIONS;
+ case 38:
+ return STR_MO_ALLOCATIONSORACLES;
+#endif
+ default:
+ return NULL;
+ }
+
+ return NULL;
+}
+
+const char* _getMethod_Name_V3(uint8_t moduleIdx, uint8_t callIdx)
+{
+ uint16_t callPrivIdx = ((uint16_t)moduleIdx << 8u) + callIdx;
+
+ switch (callPrivIdx) {
+ case 768: /* module 3 call 0 */
+ return STR_ME_TRANSFER;
+ case 771: /* module 3 call 3 */
+ return STR_ME_TRANSFER_KEEP_ALIVE;
+ case 3072: /* module 12 call 0 */
+ return STR_ME_SET_KEYS;
+ case 3073: /* module 12 call 1 */
+ return STR_ME_PURGE_KEYS;
+ case 7680: /* module 30 call 0 */
+ return STR_ME_BATCH;
+ case 7682: /* module 30 call 2 */
+ return STR_ME_BATCH_ALL;
+#ifdef SUBSTRATE_PARSER_FULL
+ case 0: /* module 0 call 0 */
+ return STR_ME_FILL_BLOCK;
+ case 1: /* module 0 call 1 */
+ return STR_ME_REMARK;
+ case 2: /* module 0 call 2 */
+ return STR_ME_SET_HEAP_PAGES;
+ case 3: /* module 0 call 3 */
+ return STR_ME_SET_CODE;
+ case 4: /* module 0 call 4 */
+ return STR_ME_SET_CODE_WITHOUT_CHECKS;
+ case 5: /* module 0 call 5 */
+ return STR_ME_SET_CHANGES_TRIE_CONFIG;
+ case 6: /* module 0 call 6 */
+ return STR_ME_SET_STORAGE;
+ case 7: /* module 0 call 7 */
+ return STR_ME_KILL_STORAGE;
+ case 8: /* module 0 call 8 */
+ return STR_ME_KILL_PREFIX;
+ case 256: /* module 1 call 0 */
+ return STR_ME_SET;
+ case 512: /* module 2 call 0 */
+ return STR_ME_CLAIM;
+ case 513: /* module 2 call 1 */
+ return STR_ME_TRANSFER;
+ case 514: /* module 2 call 2 */
+ return STR_ME_FREE;
+ case 515: /* module 2 call 3 */
+ return STR_ME_FORCE_TRANSFER;
+ case 516: /* module 2 call 4 */
+ return STR_ME_FREEZE;
+ case 769: /* module 3 call 1 */
+ return STR_ME_SET_BALANCE;
+ case 770: /* module 3 call 2 */
+ return STR_ME_FORCE_TRANSFER;
+ case 1536: /* module 6 call 0 */
+ return STR_ME_REPORT_EQUIVOCATION;
+ case 1537: /* module 6 call 1 */
+ return STR_ME_REPORT_EQUIVOCATION_UNSIGNED;
+ case 1792: /* module 7 call 0 */
+ return STR_ME_REPORT_EQUIVOCATION;
+ case 1793: /* module 7 call 1 */
+ return STR_ME_REPORT_EQUIVOCATION_UNSIGNED;
+ case 1794: /* module 7 call 2 */
+ return STR_ME_NOTE_STALLED;
+ case 2048: /* module 8 call 0 */
+ return STR_ME_SET_UNCLES;
+ case 2304: /* module 9 call 0 */
+ return STR_ME_HEARTBEAT;
+ case 2816: /* module 11 call 0 */
+ return STR_ME_ADD_MEMBER;
+ case 2817: /* module 11 call 1 */
+ return STR_ME_REMOVE_MEMBER;
+ case 2818: /* module 11 call 2 */
+ return STR_ME_SWAP_MEMBER;
+ case 2819: /* module 11 call 3 */
+ return STR_ME_RESET_MEMBERS;
+ case 2820: /* module 11 call 4 */
+ return STR_ME_CHANGE_KEY;
+ case 2821: /* module 11 call 5 */
+ return STR_ME_SET_PRIME;
+ case 2822: /* module 11 call 6 */
+ return STR_ME_CLEAR_PRIME;
+ case 3840: /* module 15 call 0 */
+ return STR_ME_SET_MEMBERS;
+ case 3841: /* module 15 call 1 */
+ return STR_ME_EXECUTE;
+ case 3842: /* module 15 call 2 */
+ return STR_ME_PROPOSE;
+ case 3843: /* module 15 call 3 */
+ return STR_ME_VOTE;
+ case 3844: /* module 15 call 4 */
+ return STR_ME_CLOSE;
+ case 3845: /* module 15 call 5 */
+ return STR_ME_DISAPPROVE_PROPOSAL;
+ case 4096: /* module 16 call 0 */
+ return STR_ME_ADD_MEMBER;
+ case 4097: /* module 16 call 1 */
+ return STR_ME_REMOVE_MEMBER;
+ case 4098: /* module 16 call 2 */
+ return STR_ME_SWAP_MEMBER;
+ case 4099: /* module 16 call 3 */
+ return STR_ME_RESET_MEMBERS;
+ case 4100: /* module 16 call 4 */
+ return STR_ME_CHANGE_KEY;
+ case 4101: /* module 16 call 5 */
+ return STR_ME_SET_PRIME;
+ case 4102: /* module 16 call 6 */
+ return STR_ME_CLEAR_PRIME;
+ case 4352: /* module 17 call 0 */
+ return STR_ME_SET_MEMBERS;
+ case 4353: /* module 17 call 1 */
+ return STR_ME_EXECUTE;
+ case 4354: /* module 17 call 2 */
+ return STR_ME_PROPOSE;
+ case 4355: /* module 17 call 3 */
+ return STR_ME_VOTE;
+ case 4356: /* module 17 call 4 */
+ return STR_ME_CLOSE;
+ case 4357: /* module 17 call 5 */
+ return STR_ME_DISAPPROVE_PROPOSAL;
+ case 4608: /* module 18 call 0 */
+ return STR_ME_ADD_MEMBER;
+ case 4609: /* module 18 call 1 */
+ return STR_ME_REMOVE_MEMBER;
+ case 4610: /* module 18 call 2 */
+ return STR_ME_SWAP_MEMBER;
+ case 4611: /* module 18 call 3 */
+ return STR_ME_RESET_MEMBERS;
+ case 4612: /* module 18 call 4 */
+ return STR_ME_CHANGE_KEY;
+ case 4613: /* module 18 call 5 */
+ return STR_ME_SET_PRIME;
+ case 4614: /* module 18 call 6 */
+ return STR_ME_CLEAR_PRIME;
+ case 4864: /* module 19 call 0 */
+ return STR_ME_SET_MEMBERS;
+ case 4865: /* module 19 call 1 */
+ return STR_ME_EXECUTE;
+ case 4866: /* module 19 call 2 */
+ return STR_ME_PROPOSE;
+ case 4867: /* module 19 call 3 */
+ return STR_ME_VOTE;
+ case 4868: /* module 19 call 4 */
+ return STR_ME_CLOSE;
+ case 4869: /* module 19 call 5 */
+ return STR_ME_DISAPPROVE_PROPOSAL;
+ case 5120: /* module 20 call 0 */
+ return STR_ME_ADD_MEMBER;
+ case 5121: /* module 20 call 1 */
+ return STR_ME_REMOVE_MEMBER;
+ case 5122: /* module 20 call 2 */
+ return STR_ME_SWAP_MEMBER;
+ case 5123: /* module 20 call 3 */
+ return STR_ME_RESET_MEMBERS;
+ case 5124: /* module 20 call 4 */
+ return STR_ME_CHANGE_KEY;
+ case 5125: /* module 20 call 5 */
+ return STR_ME_SET_PRIME;
+ case 5126: /* module 20 call 6 */
+ return STR_ME_CLEAR_PRIME;
+ case 5376: /* module 21 call 0 */
+ return STR_ME_SCHEDULE;
+ case 5377: /* module 21 call 1 */
+ return STR_ME_CANCEL;
+ case 5378: /* module 21 call 2 */
+ return STR_ME_SCHEDULE_NAMED;
+ case 5379: /* module 21 call 3 */
+ return STR_ME_CANCEL_NAMED;
+ case 5380: /* module 21 call 4 */
+ return STR_ME_SCHEDULE_AFTER;
+ case 5381: /* module 21 call 5 */
+ return STR_ME_SCHEDULE_NAMED_AFTER;
+ case 5632: /* module 22 call 0 */
+ return STR_ME_PROPOSE;
+ case 5633: /* module 22 call 1 */
+ return STR_ME_VETO;
+ case 5888: /* module 23 call 0 */
+ return STR_ME_APPLY;
+ case 6144: /* module 24 call 0 */
+ return STR_ME_SPEND;
+ case 6145: /* module 24 call 1 */
+ return STR_ME_TIP;
+ case 6146: /* module 24 call 2 */
+ return STR_ME_APPLY_AS;
+ case 6400: /* module 25 call 0 */
+ return STR_ME_SPEND;
+ case 6401: /* module 25 call 1 */
+ return STR_ME_TIP;
+ case 6402: /* module 25 call 2 */
+ return STR_ME_APPLY_AS;
+ case 6656: /* module 26 call 0 */
+ return STR_ME_SPEND;
+ case 6657: /* module 26 call 1 */
+ return STR_ME_TIP;
+ case 6658: /* module 26 call 2 */
+ return STR_ME_APPLY_AS;
+ case 6912: /* module 27 call 0 */
+ return STR_ME_CLAIM;
+ case 6913: /* module 27 call 1 */
+ return STR_ME_ADD_VESTING_SCHEDULE;
+ case 6914: /* module 27 call 2 */
+ return STR_ME_CANCEL_ALL_VESTING_SCHEDULES;
+ case 7168: /* module 28 call 0 */
+ return STR_ME_ADD_REGISTRAR;
+ case 7169: /* module 28 call 1 */
+ return STR_ME_SET_IDENTITY;
+ case 7170: /* module 28 call 2 */
+ return STR_ME_SET_SUBS;
+ case 7171: /* module 28 call 3 */
+ return STR_ME_CLEAR_IDENTITY;
+ case 7172: /* module 28 call 4 */
+ return STR_ME_REQUEST_JUDGEMENT;
+ case 7173: /* module 28 call 5 */
+ return STR_ME_CANCEL_REQUEST;
+ case 7174: /* module 28 call 6 */
+ return STR_ME_SET_FEE;
+ case 7175: /* module 28 call 7 */
+ return STR_ME_SET_ACCOUNT_ID;
+ case 7176: /* module 28 call 8 */
+ return STR_ME_SET_FIELDS;
+ case 7177: /* module 28 call 9 */
+ return STR_ME_PROVIDE_JUDGEMENT;
+ case 7178: /* module 28 call 10 */
+ return STR_ME_KILL_IDENTITY;
+ case 7179: /* module 28 call 11 */
+ return STR_ME_ADD_SUB;
+ case 7180: /* module 28 call 12 */
+ return STR_ME_RENAME_SUB;
+ case 7181: /* module 28 call 13 */
+ return STR_ME_REMOVE_SUB;
+ case 7182: /* module 28 call 14 */
+ return STR_ME_QUIT_SUB;
+ case 7424: /* module 29 call 0 */
+ return STR_ME_AS_RECOVERED;
+ case 7425: /* module 29 call 1 */
+ return STR_ME_SET_RECOVERED;
+ case 7426: /* module 29 call 2 */
+ return STR_ME_CREATE_RECOVERY;
+ case 7427: /* module 29 call 3 */
+ return STR_ME_INITIATE_RECOVERY;
+ case 7428: /* module 29 call 4 */
+ return STR_ME_VOUCH_RECOVERY;
+ case 7429: /* module 29 call 5 */
+ return STR_ME_CLAIM_RECOVERY;
+ case 7430: /* module 29 call 6 */
+ return STR_ME_CLOSE_RECOVERY;
+ case 7431: /* module 29 call 7 */
+ return STR_ME_REMOVE_RECOVERY;
+ case 7432: /* module 29 call 8 */
+ return STR_ME_CANCEL_RECOVERED;
+ case 7681: /* module 30 call 1 */
+ return STR_ME_AS_DERIVATIVE;
+ case 7936: /* module 31 call 0 */
+ return STR_ME_PROXY;
+ case 7937: /* module 31 call 1 */
+ return STR_ME_ADD_PROXY;
+ case 7938: /* module 31 call 2 */
+ return STR_ME_REMOVE_PROXY;
+ case 7939: /* module 31 call 3 */
+ return STR_ME_REMOVE_PROXIES;
+ case 7940: /* module 31 call 4 */
+ return STR_ME_ANONYMOUS;
+ case 7941: /* module 31 call 5 */
+ return STR_ME_KILL_ANONYMOUS;
+ case 7942: /* module 31 call 6 */
+ return STR_ME_ANNOUNCE;
+ case 7943: /* module 31 call 7 */
+ return STR_ME_REMOVE_ANNOUNCEMENT;
+ case 7944: /* module 31 call 8 */
+ return STR_ME_REJECT_ANNOUNCEMENT;
+ case 7945: /* module 31 call 9 */
+ return STR_ME_PROXY_ANNOUNCED;
+ case 8192: /* module 32 call 0 */
+ return STR_ME_AS_MULTI_THRESHOLD_1;
+ case 8193: /* module 32 call 1 */
+ return STR_ME_AS_MULTI;
+ case 8194: /* module 32 call 2 */
+ return STR_ME_APPROVE_AS_MULTI;
+ case 8195: /* module 32 call 3 */
+ return STR_ME_CANCEL_AS_MULTI;
+ case 8448: /* module 33 call 0 */
+ return STR_ME_UPDATE_SCHEDULE;
+ case 8449: /* module 33 call 1 */
+ return STR_ME_CALL;
+ case 8450: /* module 33 call 2 */
+ return STR_ME_INSTANTIATE_WITH_CODE;
+ case 8451: /* module 33 call 3 */
+ return STR_ME_INSTANTIATE;
+ case 8452: /* module 33 call 4 */
+ return STR_ME_CLAIM_SURCHARGE;
+ case 8704: /* module 34 call 0 */
+ return STR_ME_APPLY;
+ case 8705: /* module 34 call 1 */
+ return STR_ME_COUNTER;
+ case 8706: /* module 34 call 2 */
+ return STR_ME_VOTE;
+ case 8707: /* module 34 call 3 */
+ return STR_ME_CHALLENGE;
+ case 8960: /* module 35 call 0 */
+ return STR_ME_BOOK_SLOT;
+ case 8961: /* module 35 call 1 */
+ return STR_ME_RENEW_SLOT;
+ case 8962: /* module 35 call 2 */
+ return STR_ME_REVOKE_SLOT;
+ case 8963: /* module 35 call 3 */
+ return STR_ME_REVOKE_CHILD;
+ case 9216: /* module 36 call 0 */
+ return STR_ME_TOGGLE;
+ case 9472: /* module 37 call 0 */
+ return STR_ME_ALLOCATE;
+ case 9728: /* module 38 call 0 */
+ return STR_ME_ADD_MEMBER;
+ case 9729: /* module 38 call 1 */
+ return STR_ME_REMOVE_MEMBER;
+ case 9730: /* module 38 call 2 */
+ return STR_ME_SWAP_MEMBER;
+ case 9731: /* module 38 call 3 */
+ return STR_ME_RESET_MEMBERS;
+ case 9732: /* module 38 call 4 */
+ return STR_ME_CHANGE_KEY;
+ case 9733: /* module 38 call 5 */
+ return STR_ME_SET_PRIME;
+ case 9734: /* module 38 call 6 */
+ return STR_ME_CLEAR_PRIME;
+#endif
+ default:
+ return NULL;
+ }
+
+ return NULL;
+}
+
+uint8_t _getMethod_NumItems_V3(uint8_t moduleIdx, uint8_t callIdx)
+{
+ uint16_t callPrivIdx = ((uint16_t)moduleIdx << 8u) + callIdx;
+
+ switch (callPrivIdx) {
+ case 768: /* module 3 call 0 */
+ return 2;
+ case 771: /* module 3 call 3 */
+ return 2;
+ case 3072: /* module 12 call 0 */
+ return 2;
+ case 3073: /* module 12 call 1 */
+ return 0;
+ case 7680: /* module 30 call 0 */
+ return 1;
+ case 7682: /* module 30 call 2 */
+ return 1;
+#ifdef SUBSTRATE_PARSER_FULL
+ case 0: /* module 0 call 0 */
+ return 1;
+ case 1: /* module 0 call 1 */
+ return 1;
+ case 2: /* module 0 call 2 */
+ return 1;
+ case 3: /* module 0 call 3 */
+ return 1;
+ case 4: /* module 0 call 4 */
+ return 1;
+ case 5: /* module 0 call 5 */
+ return 1;
+ case 6: /* module 0 call 6 */
+ return 1;
+ case 7: /* module 0 call 7 */
+ return 1;
+ case 8: /* module 0 call 8 */
+ return 2;
+ case 256: /* module 1 call 0 */
+ return 1;
+ case 512: /* module 2 call 0 */
+ return 1;
+ case 513: /* module 2 call 1 */
+ return 2;
+ case 514: /* module 2 call 2 */
+ return 1;
+ case 515: /* module 2 call 3 */
+ return 3;
+ case 516: /* module 2 call 4 */
+ return 1;
+ case 769: /* module 3 call 1 */
+ return 3;
+ case 770: /* module 3 call 2 */
+ return 3;
+ case 1536: /* module 6 call 0 */
+ return 2;
+ case 1537: /* module 6 call 1 */
+ return 2;
+ case 1792: /* module 7 call 0 */
+ return 2;
+ case 1793: /* module 7 call 1 */
+ return 2;
+ case 1794: /* module 7 call 2 */
+ return 2;
+ case 2048: /* module 8 call 0 */
+ return 1;
+ case 2304: /* module 9 call 0 */
+ return 2;
+ case 2816: /* module 11 call 0 */
+ return 1;
+ case 2817: /* module 11 call 1 */
+ return 1;
+ case 2818: /* module 11 call 2 */
+ return 2;
+ case 2819: /* module 11 call 3 */
+ return 1;
+ case 2820: /* module 11 call 4 */
+ return 1;
+ case 2821: /* module 11 call 5 */
+ return 1;
+ case 2822: /* module 11 call 6 */
+ return 0;
+ case 3840: /* module 15 call 0 */
+ return 3;
+ case 3841: /* module 15 call 1 */
+ return 2;
+ case 3842: /* module 15 call 2 */
+ return 3;
+ case 3843: /* module 15 call 3 */
+ return 3;
+ case 3844: /* module 15 call 4 */
+ return 4;
+ case 3845: /* module 15 call 5 */
+ return 1;
+ case 4096: /* module 16 call 0 */
+ return 1;
+ case 4097: /* module 16 call 1 */
+ return 1;
+ case 4098: /* module 16 call 2 */
+ return 2;
+ case 4099: /* module 16 call 3 */
+ return 1;
+ case 4100: /* module 16 call 4 */
+ return 1;
+ case 4101: /* module 16 call 5 */
+ return 1;
+ case 4102: /* module 16 call 6 */
+ return 0;
+ case 4352: /* module 17 call 0 */
+ return 3;
+ case 4353: /* module 17 call 1 */
+ return 2;
+ case 4354: /* module 17 call 2 */
+ return 3;
+ case 4355: /* module 17 call 3 */
+ return 3;
+ case 4356: /* module 17 call 4 */
+ return 4;
+ case 4357: /* module 17 call 5 */
+ return 1;
+ case 4608: /* module 18 call 0 */
+ return 1;
+ case 4609: /* module 18 call 1 */
+ return 1;
+ case 4610: /* module 18 call 2 */
+ return 2;
+ case 4611: /* module 18 call 3 */
+ return 1;
+ case 4612: /* module 18 call 4 */
+ return 1;
+ case 4613: /* module 18 call 5 */
+ return 1;
+ case 4614: /* module 18 call 6 */
+ return 0;
+ case 4864: /* module 19 call 0 */
+ return 3;
+ case 4865: /* module 19 call 1 */
+ return 2;
+ case 4866: /* module 19 call 2 */
+ return 3;
+ case 4867: /* module 19 call 3 */
+ return 3;
+ case 4868: /* module 19 call 4 */
+ return 4;
+ case 4869: /* module 19 call 5 */
+ return 1;
+ case 5120: /* module 20 call 0 */
+ return 1;
+ case 5121: /* module 20 call 1 */
+ return 1;
+ case 5122: /* module 20 call 2 */
+ return 2;
+ case 5123: /* module 20 call 3 */
+ return 1;
+ case 5124: /* module 20 call 4 */
+ return 1;
+ case 5125: /* module 20 call 5 */
+ return 1;
+ case 5126: /* module 20 call 6 */
+ return 0;
+ case 5376: /* module 21 call 0 */
+ return 4;
+ case 5377: /* module 21 call 1 */
+ return 2;
+ case 5378: /* module 21 call 2 */
+ return 5;
+ case 5379: /* module 21 call 3 */
+ return 1;
+ case 5380: /* module 21 call 4 */
+ return 4;
+ case 5381: /* module 21 call 5 */
+ return 5;
+ case 5632: /* module 22 call 0 */
+ return 1;
+ case 5633: /* module 22 call 1 */
+ return 1;
+ case 5888: /* module 23 call 0 */
+ return 1;
+ case 6144: /* module 24 call 0 */
+ return 2;
+ case 6145: /* module 24 call 1 */
+ return 1;
+ case 6146: /* module 24 call 2 */
+ return 1;
+ case 6400: /* module 25 call 0 */
+ return 2;
+ case 6401: /* module 25 call 1 */
+ return 1;
+ case 6402: /* module 25 call 2 */
+ return 1;
+ case 6656: /* module 26 call 0 */
+ return 2;
+ case 6657: /* module 26 call 1 */
+ return 1;
+ case 6658: /* module 26 call 2 */
+ return 1;
+ case 6912: /* module 27 call 0 */
+ return 0;
+ case 6913: /* module 27 call 1 */
+ return 2;
+ case 6914: /* module 27 call 2 */
+ return 3;
+ case 7168: /* module 28 call 0 */
+ return 1;
+ case 7169: /* module 28 call 1 */
+ return 1;
+ case 7170: /* module 28 call 2 */
+ return 1;
+ case 7171: /* module 28 call 3 */
+ return 0;
+ case 7172: /* module 28 call 4 */
+ return 2;
+ case 7173: /* module 28 call 5 */
+ return 1;
+ case 7174: /* module 28 call 6 */
+ return 2;
+ case 7175: /* module 28 call 7 */
+ return 2;
+ case 7176: /* module 28 call 8 */
+ return 2;
+ case 7177: /* module 28 call 9 */
+ return 3;
+ case 7178: /* module 28 call 10 */
+ return 1;
+ case 7179: /* module 28 call 11 */
+ return 2;
+ case 7180: /* module 28 call 12 */
+ return 2;
+ case 7181: /* module 28 call 13 */
+ return 1;
+ case 7182: /* module 28 call 14 */
+ return 0;
+ case 7424: /* module 29 call 0 */
+ return 2;
+ case 7425: /* module 29 call 1 */
+ return 2;
+ case 7426: /* module 29 call 2 */
+ return 3;
+ case 7427: /* module 29 call 3 */
+ return 1;
+ case 7428: /* module 29 call 4 */
+ return 2;
+ case 7429: /* module 29 call 5 */
+ return 1;
+ case 7430: /* module 29 call 6 */
+ return 1;
+ case 7431: /* module 29 call 7 */
+ return 0;
+ case 7432: /* module 29 call 8 */
+ return 1;
+ case 7681: /* module 30 call 1 */
+ return 2;
+ case 7936: /* module 31 call 0 */
+ return 3;
+ case 7937: /* module 31 call 1 */
+ return 3;
+ case 7938: /* module 31 call 2 */
+ return 3;
+ case 7939: /* module 31 call 3 */
+ return 0;
+ case 7940: /* module 31 call 4 */
+ return 3;
+ case 7941: /* module 31 call 5 */
+ return 5;
+ case 7942: /* module 31 call 6 */
+ return 2;
+ case 7943: /* module 31 call 7 */
+ return 2;
+ case 7944: /* module 31 call 8 */
+ return 2;
+ case 7945: /* module 31 call 9 */
+ return 4;
+ case 8192: /* module 32 call 0 */
+ return 2;
+ case 8193: /* module 32 call 1 */
+ return 6;
+ case 8194: /* module 32 call 2 */
+ return 5;
+ case 8195: /* module 32 call 3 */
+ return 4;
+ case 8448: /* module 33 call 0 */
+ return 1;
+ case 8449: /* module 33 call 1 */
+ return 4;
+ case 8450: /* module 33 call 2 */
+ return 5;
+ case 8451: /* module 33 call 3 */
+ return 5;
+ case 8452: /* module 33 call 4 */
+ return 2;
+ case 8704: /* module 34 call 0 */
+ return 2;
+ case 8705: /* module 34 call 1 */
+ return 2;
+ case 8706: /* module 34 call 2 */
+ return 3;
+ case 8707: /* module 34 call 3 */
+ return 2;
+ case 8960: /* module 35 call 0 */
+ return 1;
+ case 8961: /* module 35 call 1 */
+ return 1;
+ case 8962: /* module 35 call 2 */
+ return 1;
+ case 8963: /* module 35 call 3 */
+ return 2;
+ case 9216: /* module 36 call 0 */
+ return 0;
+ case 9472: /* module 37 call 0 */
+ return 3;
+ case 9728: /* module 38 call 0 */
+ return 1;
+ case 9729: /* module 38 call 1 */
+ return 1;
+ case 9730: /* module 38 call 2 */
+ return 2;
+ case 9731: /* module 38 call 3 */
+ return 1;
+ case 9732: /* module 38 call 4 */
+ return 1;
+ case 9733: /* module 38 call 5 */
+ return 1;
+ case 9734: /* module 38 call 6 */
+ return 0;
+#endif
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+const char* _getMethod_ItemName_V3(uint8_t moduleIdx, uint8_t callIdx, uint8_t itemIdx)
+{
+ uint16_t callPrivIdx = ((uint16_t)moduleIdx << 8u) + callIdx;
+
+ switch (callPrivIdx) {
+ case 768: /* module 3 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_dest;
+ case 1:
+ return STR_IT_value;
+ default:
+ return NULL;
+ }
+ case 771: /* module 3 call 3 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_dest;
+ case 1:
+ return STR_IT_value;
+ default:
+ return NULL;
+ }
+ case 3072: /* module 12 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_keys;
+ case 1:
+ return STR_IT_proof;
+ default:
+ return NULL;
+ }
+ case 3073: /* module 12 call 1 */
+ switch (itemIdx) {
+ default:
+ return NULL;
+ }
+ case 7680: /* module 30 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_calls;
+ default:
+ return NULL;
+ }
+ case 7682: /* module 30 call 2 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_calls;
+ default:
+ return NULL;
+ }
+#ifdef SUBSTRATE_PARSER_FULL
+ case 0: /* module 0 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT__ratio;
+ default:
+ return NULL;
+ }
+ case 1: /* module 0 call 1 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT__remark;
+ default:
+ return NULL;
+ }
+ case 2: /* module 0 call 2 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_pages;
+ default:
+ return NULL;
+ }
+ case 3: /* module 0 call 3 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_code;
+ default:
+ return NULL;
+ }
+ case 4: /* module 0 call 4 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_code;
+ default:
+ return NULL;
+ }
+ case 5: /* module 0 call 5 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_changes_trie_config;
+ default:
+ return NULL;
+ }
+ case 6: /* module 0 call 6 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_items;
+ default:
+ return NULL;
+ }
+ case 7: /* module 0 call 7 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_keys;
+ default:
+ return NULL;
+ }
+ case 8: /* module 0 call 8 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_prefix;
+ case 1:
+ return STR_IT__subkeys;
+ default:
+ return NULL;
+ }
+ case 256: /* module 1 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_now;
+ default:
+ return NULL;
+ }
+ case 512: /* module 2 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_index;
+ default:
+ return NULL;
+ }
+ case 513: /* module 2 call 1 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_new_;
+ case 1:
+ return STR_IT_index;
+ default:
+ return NULL;
+ }
+ case 514: /* module 2 call 2 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_index;
+ default:
+ return NULL;
+ }
+ case 515: /* module 2 call 3 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_new_;
+ case 1:
+ return STR_IT_index;
+ case 2:
+ return STR_IT_freeze;
+ default:
+ return NULL;
+ }
+ case 516: /* module 2 call 4 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_index;
+ default:
+ return NULL;
+ }
+ case 769: /* module 3 call 1 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_who;
+ case 1:
+ return STR_IT_new_free;
+ case 2:
+ return STR_IT_new_reserved;
+ default:
+ return NULL;
+ }
+ case 770: /* module 3 call 2 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_source;
+ case 1:
+ return STR_IT_dest;
+ case 2:
+ return STR_IT_value;
+ default:
+ return NULL;
+ }
+ case 1536: /* module 6 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_equivocation_proof;
+ case 1:
+ return STR_IT_key_owner_proof;
+ default:
+ return NULL;
+ }
+ case 1537: /* module 6 call 1 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_equivocation_proof;
+ case 1:
+ return STR_IT_key_owner_proof;
+ default:
+ return NULL;
+ }
+ case 1792: /* module 7 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_equivocation_proof;
+ case 1:
+ return STR_IT_key_owner_proof;
+ default:
+ return NULL;
+ }
+ case 1793: /* module 7 call 1 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_equivocation_proof;
+ case 1:
+ return STR_IT_key_owner_proof;
+ default:
+ return NULL;
+ }
+ case 1794: /* module 7 call 2 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_delay;
+ case 1:
+ return STR_IT_best_finalized_block_number;
+ default:
+ return NULL;
+ }
+ case 2048: /* module 8 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_new_uncles;
+ default:
+ return NULL;
+ }
+ case 2304: /* module 9 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_heartbeat;
+ case 1:
+ return STR_IT__signature;
+ default:
+ return NULL;
+ }
+ case 2816: /* module 11 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_who;
+ default:
+ return NULL;
+ }
+ case 2817: /* module 11 call 1 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_who;
+ default:
+ return NULL;
+ }
+ case 2818: /* module 11 call 2 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_remove;
+ case 1:
+ return STR_IT_add;
+ default:
+ return NULL;
+ }
+ case 2819: /* module 11 call 3 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_members;
+ default:
+ return NULL;
+ }
+ case 2820: /* module 11 call 4 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_new_;
+ default:
+ return NULL;
+ }
+ case 2821: /* module 11 call 5 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_who;
+ default:
+ return NULL;
+ }
+ case 2822: /* module 11 call 6 */
+ switch (itemIdx) {
+ default:
+ return NULL;
+ }
+ case 3840: /* module 15 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_new_members;
+ case 1:
+ return STR_IT_prime;
+ case 2:
+ return STR_IT_old_count;
+ default:
+ return NULL;
+ }
+ case 3841: /* module 15 call 1 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_proposal;
+ case 1:
+ return STR_IT_length_bound;
+ default:
+ return NULL;
+ }
+ case 3842: /* module 15 call 2 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_threshold;
+ case 1:
+ return STR_IT_proposal;
+ case 2:
+ return STR_IT_length_bound;
+ default:
+ return NULL;
+ }
+ case 3843: /* module 15 call 3 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_proposal;
+ case 1:
+ return STR_IT_index;
+ case 2:
+ return STR_IT_approve;
+ default:
+ return NULL;
+ }
+ case 3844: /* module 15 call 4 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_proposal_hash;
+ case 1:
+ return STR_IT_index;
+ case 2:
+ return STR_IT_proposal_weight_bound;
+ case 3:
+ return STR_IT_length_bound;
+ default:
+ return NULL;
+ }
+ case 3845: /* module 15 call 5 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_proposal_hash;
+ default:
+ return NULL;
+ }
+ case 4096: /* module 16 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_who;
+ default:
+ return NULL;
+ }
+ case 4097: /* module 16 call 1 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_who;
+ default:
+ return NULL;
+ }
+ case 4098: /* module 16 call 2 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_remove;
+ case 1:
+ return STR_IT_add;
+ default:
+ return NULL;
+ }
+ case 4099: /* module 16 call 3 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_members;
+ default:
+ return NULL;
+ }
+ case 4100: /* module 16 call 4 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_new_;
+ default:
+ return NULL;
+ }
+ case 4101: /* module 16 call 5 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_who;
+ default:
+ return NULL;
+ }
+ case 4102: /* module 16 call 6 */
+ switch (itemIdx) {
+ default:
+ return NULL;
+ }
+ case 4352: /* module 17 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_new_members;
+ case 1:
+ return STR_IT_prime;
+ case 2:
+ return STR_IT_old_count;
+ default:
+ return NULL;
+ }
+ case 4353: /* module 17 call 1 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_proposal;
+ case 1:
+ return STR_IT_length_bound;
+ default:
+ return NULL;
+ }
+ case 4354: /* module 17 call 2 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_threshold;
+ case 1:
+ return STR_IT_proposal;
+ case 2:
+ return STR_IT_length_bound;
+ default:
+ return NULL;
+ }
+ case 4355: /* module 17 call 3 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_proposal;
+ case 1:
+ return STR_IT_index;
+ case 2:
+ return STR_IT_approve;
+ default:
+ return NULL;
+ }
+ case 4356: /* module 17 call 4 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_proposal_hash;
+ case 1:
+ return STR_IT_index;
+ case 2:
+ return STR_IT_proposal_weight_bound;
+ case 3:
+ return STR_IT_length_bound;
+ default:
+ return NULL;
+ }
+ case 4357: /* module 17 call 5 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_proposal_hash;
+ default:
+ return NULL;
+ }
+ case 4608: /* module 18 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_who;
+ default:
+ return NULL;
+ }
+ case 4609: /* module 18 call 1 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_who;
+ default:
+ return NULL;
+ }
+ case 4610: /* module 18 call 2 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_remove;
+ case 1:
+ return STR_IT_add;
+ default:
+ return NULL;
+ }
+ case 4611: /* module 18 call 3 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_members;
+ default:
+ return NULL;
+ }
+ case 4612: /* module 18 call 4 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_new_;
+ default:
+ return NULL;
+ }
+ case 4613: /* module 18 call 5 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_who;
+ default:
+ return NULL;
+ }
+ case 4614: /* module 18 call 6 */
+ switch (itemIdx) {
+ default:
+ return NULL;
+ }
+ case 4864: /* module 19 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_new_members;
+ case 1:
+ return STR_IT_prime;
+ case 2:
+ return STR_IT_old_count;
+ default:
+ return NULL;
+ }
+ case 4865: /* module 19 call 1 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_proposal;
+ case 1:
+ return STR_IT_length_bound;
+ default:
+ return NULL;
+ }
+ case 4866: /* module 19 call 2 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_threshold;
+ case 1:
+ return STR_IT_proposal;
+ case 2:
+ return STR_IT_length_bound;
+ default:
+ return NULL;
+ }
+ case 4867: /* module 19 call 3 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_proposal;
+ case 1:
+ return STR_IT_index;
+ case 2:
+ return STR_IT_approve;
+ default:
+ return NULL;
+ }
+ case 4868: /* module 19 call 4 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_proposal_hash;
+ case 1:
+ return STR_IT_index;
+ case 2:
+ return STR_IT_proposal_weight_bound;
+ case 3:
+ return STR_IT_length_bound;
+ default:
+ return NULL;
+ }
+ case 4869: /* module 19 call 5 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_proposal_hash;
+ default:
+ return NULL;
+ }
+ case 5120: /* module 20 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_who;
+ default:
+ return NULL;
+ }
+ case 5121: /* module 20 call 1 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_who;
+ default:
+ return NULL;
+ }
+ case 5122: /* module 20 call 2 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_remove;
+ case 1:
+ return STR_IT_add;
+ default:
+ return NULL;
+ }
+ case 5123: /* module 20 call 3 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_members;
+ default:
+ return NULL;
+ }
+ case 5124: /* module 20 call 4 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_new_;
+ default:
+ return NULL;
+ }
+ case 5125: /* module 20 call 5 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_who;
+ default:
+ return NULL;
+ }
+ case 5126: /* module 20 call 6 */
+ switch (itemIdx) {
+ default:
+ return NULL;
+ }
+ case 5376: /* module 21 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_when;
+ case 1:
+ return STR_IT_maybe_periodic;
+ case 2:
+ return STR_IT_priority;
+ case 3:
+ return STR_IT_call;
+ default:
+ return NULL;
+ }
+ case 5377: /* module 21 call 1 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_when;
+ case 1:
+ return STR_IT_index;
+ default:
+ return NULL;
+ }
+ case 5378: /* module 21 call 2 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_id;
+ case 1:
+ return STR_IT_when;
+ case 2:
+ return STR_IT_maybe_periodic;
+ case 3:
+ return STR_IT_priority;
+ case 4:
+ return STR_IT_call;
+ default:
+ return NULL;
+ }
+ case 5379: /* module 21 call 3 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_id;
+ default:
+ return NULL;
+ }
+ case 5380: /* module 21 call 4 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_after;
+ case 1:
+ return STR_IT_maybe_periodic;
+ case 2:
+ return STR_IT_priority;
+ case 3:
+ return STR_IT_call;
+ default:
+ return NULL;
+ }
+ case 5381: /* module 21 call 5 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_id;
+ case 1:
+ return STR_IT_after;
+ case 2:
+ return STR_IT_maybe_periodic;
+ case 3:
+ return STR_IT_priority;
+ case 4:
+ return STR_IT_call;
+ default:
+ return NULL;
+ }
+ case 5632: /* module 22 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_amendment;
+ default:
+ return NULL;
+ }
+ case 5633: /* module 22 call 1 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_amendment_id;
+ default:
+ return NULL;
+ }
+ case 5888: /* module 23 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_call;
+ default:
+ return NULL;
+ }
+ case 6144: /* module 24 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_to;
+ case 1:
+ return STR_IT_amount;
+ default:
+ return NULL;
+ }
+ case 6145: /* module 24 call 1 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_amount;
+ default:
+ return NULL;
+ }
+ case 6146: /* module 24 call 2 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_call;
+ default:
+ return NULL;
+ }
+ case 6400: /* module 25 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_to;
+ case 1:
+ return STR_IT_amount;
+ default:
+ return NULL;
+ }
+ case 6401: /* module 25 call 1 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_amount;
+ default:
+ return NULL;
+ }
+ case 6402: /* module 25 call 2 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_call;
+ default:
+ return NULL;
+ }
+ case 6656: /* module 26 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_to;
+ case 1:
+ return STR_IT_amount;
+ default:
+ return NULL;
+ }
+ case 6657: /* module 26 call 1 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_amount;
+ default:
+ return NULL;
+ }
+ case 6658: /* module 26 call 2 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_call;
+ default:
+ return NULL;
+ }
+ case 6912: /* module 27 call 0 */
+ switch (itemIdx) {
+ default:
+ return NULL;
+ }
+ case 6913: /* module 27 call 1 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_dest;
+ case 1:
+ return STR_IT_schedule;
+ default:
+ return NULL;
+ }
+ case 6914: /* module 27 call 2 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_who;
+ case 1:
+ return STR_IT_funds_collector;
+ case 2:
+ return STR_IT_limit_to_free_balance;
+ default:
+ return NULL;
+ }
+ case 7168: /* module 28 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_account;
+ default:
+ return NULL;
+ }
+ case 7169: /* module 28 call 1 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_info;
+ default:
+ return NULL;
+ }
+ case 7170: /* module 28 call 2 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_subs;
+ default:
+ return NULL;
+ }
+ case 7171: /* module 28 call 3 */
+ switch (itemIdx) {
+ default:
+ return NULL;
+ }
+ case 7172: /* module 28 call 4 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_reg_index;
+ case 1:
+ return STR_IT_max_fee;
+ default:
+ return NULL;
+ }
+ case 7173: /* module 28 call 5 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_reg_index;
+ default:
+ return NULL;
+ }
+ case 7174: /* module 28 call 6 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_index;
+ case 1:
+ return STR_IT_fee;
+ default:
+ return NULL;
+ }
+ case 7175: /* module 28 call 7 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_index;
+ case 1:
+ return STR_IT_new_;
+ default:
+ return NULL;
+ }
+ case 7176: /* module 28 call 8 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_index;
+ case 1:
+ return STR_IT_fields;
+ default:
+ return NULL;
+ }
+ case 7177: /* module 28 call 9 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_reg_index;
+ case 1:
+ return STR_IT_target;
+ case 2:
+ return STR_IT_judgement;
+ default:
+ return NULL;
+ }
+ case 7178: /* module 28 call 10 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_target;
+ default:
+ return NULL;
+ }
+ case 7179: /* module 28 call 11 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_sub;
+ case 1:
+ return STR_IT_data;
+ default:
+ return NULL;
+ }
+ case 7180: /* module 28 call 12 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_sub;
+ case 1:
+ return STR_IT_data;
+ default:
+ return NULL;
+ }
+ case 7181: /* module 28 call 13 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_sub;
+ default:
+ return NULL;
+ }
+ case 7182: /* module 28 call 14 */
+ switch (itemIdx) {
+ default:
+ return NULL;
+ }
+ case 7424: /* module 29 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_account;
+ case 1:
+ return STR_IT_call;
+ default:
+ return NULL;
+ }
+ case 7425: /* module 29 call 1 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_lost;
+ case 1:
+ return STR_IT_rescuer;
+ default:
+ return NULL;
+ }
+ case 7426: /* module 29 call 2 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_friends;
+ case 1:
+ return STR_IT_threshold;
+ case 2:
+ return STR_IT_delay_period;
+ default:
+ return NULL;
+ }
+ case 7427: /* module 29 call 3 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_account;
+ default:
+ return NULL;
+ }
+ case 7428: /* module 29 call 4 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_lost;
+ case 1:
+ return STR_IT_rescuer;
+ default:
+ return NULL;
+ }
+ case 7429: /* module 29 call 5 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_account;
+ default:
+ return NULL;
+ }
+ case 7430: /* module 29 call 6 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_rescuer;
+ default:
+ return NULL;
+ }
+ case 7431: /* module 29 call 7 */
+ switch (itemIdx) {
+ default:
+ return NULL;
+ }
+ case 7432: /* module 29 call 8 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_account;
+ default:
+ return NULL;
+ }
+ case 7681: /* module 30 call 1 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_index;
+ case 1:
+ return STR_IT_call;
+ default:
+ return NULL;
+ }
+ case 7936: /* module 31 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_real;
+ case 1:
+ return STR_IT_force_proxy_type;
+ case 2:
+ return STR_IT_call;
+ default:
+ return NULL;
+ }
+ case 7937: /* module 31 call 1 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_delegate;
+ case 1:
+ return STR_IT_proxy_type;
+ case 2:
+ return STR_IT_delay;
+ default:
+ return NULL;
+ }
+ case 7938: /* module 31 call 2 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_delegate;
+ case 1:
+ return STR_IT_proxy_type;
+ case 2:
+ return STR_IT_delay;
+ default:
+ return NULL;
+ }
+ case 7939: /* module 31 call 3 */
+ switch (itemIdx) {
+ default:
+ return NULL;
+ }
+ case 7940: /* module 31 call 4 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_proxy_type;
+ case 1:
+ return STR_IT_delay;
+ case 2:
+ return STR_IT_index;
+ default:
+ return NULL;
+ }
+ case 7941: /* module 31 call 5 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_spawner;
+ case 1:
+ return STR_IT_proxy_type;
+ case 2:
+ return STR_IT_index;
+ case 3:
+ return STR_IT_height;
+ case 4:
+ return STR_IT_ext_index;
+ default:
+ return NULL;
+ }
+ case 7942: /* module 31 call 6 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_real;
+ case 1:
+ return STR_IT_call_hash;
+ default:
+ return NULL;
+ }
+ case 7943: /* module 31 call 7 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_real;
+ case 1:
+ return STR_IT_call_hash;
+ default:
+ return NULL;
+ }
+ case 7944: /* module 31 call 8 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_delegate;
+ case 1:
+ return STR_IT_call_hash;
+ default:
+ return NULL;
+ }
+ case 7945: /* module 31 call 9 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_delegate;
+ case 1:
+ return STR_IT_real;
+ case 2:
+ return STR_IT_force_proxy_type;
+ case 3:
+ return STR_IT_call;
+ default:
+ return NULL;
+ }
+ case 8192: /* module 32 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_other_signatories;
+ case 1:
+ return STR_IT_call;
+ default:
+ return NULL;
+ }
+ case 8193: /* module 32 call 1 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_threshold;
+ case 1:
+ return STR_IT_other_signatories;
+ case 2:
+ return STR_IT_maybe_timepoint;
+ case 3:
+ return STR_IT_call;
+ case 4:
+ return STR_IT_store_call;
+ case 5:
+ return STR_IT_max_weight;
+ default:
+ return NULL;
+ }
+ case 8194: /* module 32 call 2 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_threshold;
+ case 1:
+ return STR_IT_other_signatories;
+ case 2:
+ return STR_IT_maybe_timepoint;
+ case 3:
+ return STR_IT_call_hash;
+ case 4:
+ return STR_IT_max_weight;
+ default:
+ return NULL;
+ }
+ case 8195: /* module 32 call 3 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_threshold;
+ case 1:
+ return STR_IT_other_signatories;
+ case 2:
+ return STR_IT_timepoint;
+ case 3:
+ return STR_IT_call_hash;
+ default:
+ return NULL;
+ }
+ case 8448: /* module 33 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_schedule;
+ default:
+ return NULL;
+ }
+ case 8449: /* module 33 call 1 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_dest;
+ case 1:
+ return STR_IT_value;
+ case 2:
+ return STR_IT_gas_limit;
+ case 3:
+ return STR_IT_data;
+ default:
+ return NULL;
+ }
+ case 8450: /* module 33 call 2 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_endowment;
+ case 1:
+ return STR_IT_gas_limit;
+ case 2:
+ return STR_IT_code;
+ case 3:
+ return STR_IT_data;
+ case 4:
+ return STR_IT_salt;
+ default:
+ return NULL;
+ }
+ case 8451: /* module 33 call 3 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_endowment;
+ case 1:
+ return STR_IT_gas_limit;
+ case 2:
+ return STR_IT_code_hash;
+ case 3:
+ return STR_IT_data;
+ case 4:
+ return STR_IT_salt;
+ default:
+ return NULL;
+ }
+ case 8452: /* module 33 call 4 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_dest;
+ case 1:
+ return STR_IT_aux_sender;
+ default:
+ return NULL;
+ }
+ case 8704: /* module 34 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_metadata;
+ case 1:
+ return STR_IT_deposit;
+ default:
+ return NULL;
+ }
+ case 8705: /* module 34 call 1 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_member;
+ case 1:
+ return STR_IT_deposit;
+ default:
+ return NULL;
+ }
+ case 8706: /* module 34 call 2 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_member;
+ case 1:
+ return STR_IT_supporting;
+ case 2:
+ return STR_IT_deposit;
+ default:
+ return NULL;
+ }
+ case 8707: /* module 34 call 3 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_member;
+ case 1:
+ return STR_IT_deposit;
+ default:
+ return NULL;
+ }
+ case 8960: /* module 35 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_certificate_id;
+ default:
+ return NULL;
+ }
+ case 8961: /* module 35 call 1 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_certificate_id;
+ default:
+ return NULL;
+ }
+ case 8962: /* module 35 call 2 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_certificate_id;
+ default:
+ return NULL;
+ }
+ case 8963: /* module 35 call 3 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_root;
+ case 1:
+ return STR_IT_child;
+ default:
+ return NULL;
+ }
+ case 9216: /* module 36 call 0 */
+ switch (itemIdx) {
+ default:
+ return NULL;
+ }
+ case 9472: /* module 37 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_to;
+ case 1:
+ return STR_IT_amount;
+ case 2:
+ return STR_IT_proof;
+ default:
+ return NULL;
+ }
+ case 9728: /* module 38 call 0 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_who;
+ default:
+ return NULL;
+ }
+ case 9729: /* module 38 call 1 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_who;
+ default:
+ return NULL;
+ }
+ case 9730: /* module 38 call 2 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_remove;
+ case 1:
+ return STR_IT_add;
+ default:
+ return NULL;
+ }
+ case 9731: /* module 38 call 3 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_members;
+ default:
+ return NULL;
+ }
+ case 9732: /* module 38 call 4 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_new_;
+ default:
+ return NULL;
+ }
+ case 9733: /* module 38 call 5 */
+ switch (itemIdx) {
+ case 0:
+ return STR_IT_who;
+ default:
+ return NULL;
+ }
+ case 9734: /* module 38 call 6 */
+ switch (itemIdx) {
+ default:
+ return NULL;
+ }
+#endif
+ default:
+ return NULL;
+ }
+
+ return NULL;
+}
+
+parser_error_t _getMethod_ItemValue_V3(
+ pd_Method_V3_t* m,
+ uint8_t moduleIdx, uint8_t callIdx, uint8_t itemIdx,
+ char* outValue, uint16_t outValueLen,
+ uint8_t pageIdx, uint8_t* pageCount)
+{
+ uint16_t callPrivIdx = ((uint16_t)moduleIdx << 8u) + callIdx;
+
+ switch (callPrivIdx) {
+ case 768: /* module 3 call 0 */
+ switch (itemIdx) {
+ case 0: /* balances_transfer_V3 - dest */;
+ return _toStringLookupSource_V3(
+ &m->nested.balances_transfer_V3.dest,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* balances_transfer_V3 - value */;
+ return _toStringCompactBalance(
+ &m->nested.balances_transfer_V3.value,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 771: /* module 3 call 3 */
+ switch (itemIdx) {
+ case 0: /* balances_transfer_keep_alive_V3 - dest */;
+ return _toStringLookupSource_V3(
+ &m->nested.balances_transfer_keep_alive_V3.dest,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* balances_transfer_keep_alive_V3 - value */;
+ return _toStringCompactBalance(
+ &m->nested.balances_transfer_keep_alive_V3.value,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 3072: /* module 12 call 0 */
+ switch (itemIdx) {
+ case 0: /* session_set_keys_V3 - keys */;
+ return _toStringKeys_V3(
+ &m->basic.session_set_keys_V3.keys,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* session_set_keys_V3 - proof */;
+ return _toStringBytes(
+ &m->basic.session_set_keys_V3.proof,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 3073: /* module 12 call 1 */
+ switch (itemIdx) {
+ default:
+ return parser_no_data;
+ }
+ case 7680: /* module 30 call 0 */
+ switch (itemIdx) {
+ case 0: /* utility_batch_V3 - calls */;
+ return _toStringVecCall(
+ &m->basic.utility_batch_V3.calls,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7682: /* module 30 call 2 */
+ switch (itemIdx) {
+ case 0: /* utility_batch_all_V3 - calls */;
+ return _toStringVecCall(
+ &m->basic.utility_batch_all_V3.calls,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+#ifdef SUBSTRATE_PARSER_FULL
+ case 0: /* module 0 call 0 */
+ switch (itemIdx) {
+ case 0: /* system_fill_block_V3 - _ratio */;
+ return _toStringPerbill_V3(
+ &m->nested.system_fill_block_V3._ratio,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 1: /* module 0 call 1 */
+ switch (itemIdx) {
+ case 0: /* system_remark_V3 - _remark */;
+ return _toStringBytes(
+ &m->nested.system_remark_V3._remark,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 2: /* module 0 call 2 */
+ switch (itemIdx) {
+ case 0: /* system_set_heap_pages_V3 - pages */;
+ return _toStringu64(
+ &m->nested.system_set_heap_pages_V3.pages,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 3: /* module 0 call 3 */
+ switch (itemIdx) {
+ case 0: /* system_set_code_V3 - code */;
+ return _toStringBytes(
+ &m->nested.system_set_code_V3.code,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 4: /* module 0 call 4 */
+ switch (itemIdx) {
+ case 0: /* system_set_code_without_checks_V3 - code */;
+ return _toStringBytes(
+ &m->nested.system_set_code_without_checks_V3.code,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 5: /* module 0 call 5 */
+ switch (itemIdx) {
+ case 0: /* system_set_changes_trie_config_V3 - changes_trie_config */;
+ return _toStringOptionChangesTrieConfiguration_V3(
+ &m->nested.system_set_changes_trie_config_V3.changes_trie_config,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 6: /* module 0 call 6 */
+ switch (itemIdx) {
+ case 0: /* system_set_storage_V3 - items */;
+ return _toStringVecKeyValue_V3(
+ &m->nested.system_set_storage_V3.items,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7: /* module 0 call 7 */
+ switch (itemIdx) {
+ case 0: /* system_kill_storage_V3 - keys */;
+ return _toStringVecKey_V3(
+ &m->nested.system_kill_storage_V3.keys,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 8: /* module 0 call 8 */
+ switch (itemIdx) {
+ case 0: /* system_kill_prefix_V3 - prefix */;
+ return _toStringKey_V3(
+ &m->nested.system_kill_prefix_V3.prefix,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* system_kill_prefix_V3 - _subkeys */;
+ return _toStringu32(
+ &m->nested.system_kill_prefix_V3._subkeys,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 256: /* module 1 call 0 */
+ switch (itemIdx) {
+ case 0: /* timestamp_set_V3 - now */;
+ return _toStringCompactMoment_V3(
+ &m->basic.timestamp_set_V3.now,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 512: /* module 2 call 0 */
+ switch (itemIdx) {
+ case 0: /* indices_claim_V3 - index */;
+ return _toStringAccountIndex_V3(
+ &m->basic.indices_claim_V3.index,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 513: /* module 2 call 1 */
+ switch (itemIdx) {
+ case 0: /* indices_transfer_V3 - new_ */;
+ return _toStringAccountId_V3(
+ &m->basic.indices_transfer_V3.new_,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* indices_transfer_V3 - index */;
+ return _toStringAccountIndex_V3(
+ &m->basic.indices_transfer_V3.index,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 514: /* module 2 call 2 */
+ switch (itemIdx) {
+ case 0: /* indices_free_V3 - index */;
+ return _toStringAccountIndex_V3(
+ &m->basic.indices_free_V3.index,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 515: /* module 2 call 3 */
+ switch (itemIdx) {
+ case 0: /* indices_force_transfer_V3 - new_ */;
+ return _toStringAccountId_V3(
+ &m->basic.indices_force_transfer_V3.new_,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* indices_force_transfer_V3 - index */;
+ return _toStringAccountIndex_V3(
+ &m->basic.indices_force_transfer_V3.index,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* indices_force_transfer_V3 - freeze */;
+ return _toStringbool(
+ &m->basic.indices_force_transfer_V3.freeze,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 516: /* module 2 call 4 */
+ switch (itemIdx) {
+ case 0: /* indices_freeze_V3 - index */;
+ return _toStringAccountIndex_V3(
+ &m->basic.indices_freeze_V3.index,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 769: /* module 3 call 1 */
+ switch (itemIdx) {
+ case 0: /* balances_set_balance_V3 - who */;
+ return _toStringLookupSource_V3(
+ &m->nested.balances_set_balance_V3.who,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* balances_set_balance_V3 - new_free */;
+ return _toStringCompactBalance(
+ &m->nested.balances_set_balance_V3.new_free,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* balances_set_balance_V3 - new_reserved */;
+ return _toStringCompactBalance(
+ &m->nested.balances_set_balance_V3.new_reserved,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 770: /* module 3 call 2 */
+ switch (itemIdx) {
+ case 0: /* balances_force_transfer_V3 - source */;
+ return _toStringLookupSource_V3(
+ &m->nested.balances_force_transfer_V3.source,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* balances_force_transfer_V3 - dest */;
+ return _toStringLookupSource_V3(
+ &m->nested.balances_force_transfer_V3.dest,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* balances_force_transfer_V3 - value */;
+ return _toStringCompactBalance(
+ &m->nested.balances_force_transfer_V3.value,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 1536: /* module 6 call 0 */
+ switch (itemIdx) {
+ case 0: /* babe_report_equivocation_V3 - equivocation_proof */;
+ return _toStringBabeEquivocationProof_V3(
+ &m->basic.babe_report_equivocation_V3.equivocation_proof,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* babe_report_equivocation_V3 - key_owner_proof */;
+ return _toStringKeyOwnerProof_V3(
+ &m->basic.babe_report_equivocation_V3.key_owner_proof,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 1537: /* module 6 call 1 */
+ switch (itemIdx) {
+ case 0: /* babe_report_equivocation_unsigned_V3 - equivocation_proof */;
+ return _toStringBabeEquivocationProof_V3(
+ &m->basic.babe_report_equivocation_unsigned_V3.equivocation_proof,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* babe_report_equivocation_unsigned_V3 - key_owner_proof */;
+ return _toStringKeyOwnerProof_V3(
+ &m->basic.babe_report_equivocation_unsigned_V3.key_owner_proof,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 1792: /* module 7 call 0 */
+ switch (itemIdx) {
+ case 0: /* grandpa_report_equivocation_V3 - equivocation_proof */;
+ return _toStringGrandpaEquivocationProof_V3(
+ &m->basic.grandpa_report_equivocation_V3.equivocation_proof,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* grandpa_report_equivocation_V3 - key_owner_proof */;
+ return _toStringKeyOwnerProof_V3(
+ &m->basic.grandpa_report_equivocation_V3.key_owner_proof,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 1793: /* module 7 call 1 */
+ switch (itemIdx) {
+ case 0: /* grandpa_report_equivocation_unsigned_V3 - equivocation_proof */;
+ return _toStringGrandpaEquivocationProof_V3(
+ &m->basic.grandpa_report_equivocation_unsigned_V3.equivocation_proof,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* grandpa_report_equivocation_unsigned_V3 - key_owner_proof */;
+ return _toStringKeyOwnerProof_V3(
+ &m->basic.grandpa_report_equivocation_unsigned_V3.key_owner_proof,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 1794: /* module 7 call 2 */
+ switch (itemIdx) {
+ case 0: /* grandpa_note_stalled_V3 - delay */;
+ return _toStringBlockNumber(
+ &m->basic.grandpa_note_stalled_V3.delay,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* grandpa_note_stalled_V3 - best_finalized_block_number */;
+ return _toStringBlockNumber(
+ &m->basic.grandpa_note_stalled_V3.best_finalized_block_number,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 2048: /* module 8 call 0 */
+ switch (itemIdx) {
+ case 0: /* authorship_set_uncles_V3 - new_uncles */;
+ return _toStringVecHeader(
+ &m->basic.authorship_set_uncles_V3.new_uncles,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 2304: /* module 9 call 0 */
+ switch (itemIdx) {
+ case 0: /* imonline_heartbeat_V3 - heartbeat */;
+ return _toStringHeartbeat(
+ &m->basic.imonline_heartbeat_V3.heartbeat,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* imonline_heartbeat_V3 - _signature */;
+ return _toStringSignature_V3(
+ &m->basic.imonline_heartbeat_V3._signature,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 2816: /* module 11 call 0 */
+ switch (itemIdx) {
+ case 0: /* validatorsset_add_member_V3 - who */;
+ return _toStringAccountId_V3(
+ &m->basic.validatorsset_add_member_V3.who,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 2817: /* module 11 call 1 */
+ switch (itemIdx) {
+ case 0: /* validatorsset_remove_member_V3 - who */;
+ return _toStringAccountId_V3(
+ &m->basic.validatorsset_remove_member_V3.who,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 2818: /* module 11 call 2 */
+ switch (itemIdx) {
+ case 0: /* validatorsset_swap_member_V3 - remove */;
+ return _toStringAccountId_V3(
+ &m->basic.validatorsset_swap_member_V3.remove,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* validatorsset_swap_member_V3 - add */;
+ return _toStringAccountId_V3(
+ &m->basic.validatorsset_swap_member_V3.add,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 2819: /* module 11 call 3 */
+ switch (itemIdx) {
+ case 0: /* validatorsset_reset_members_V3 - members */;
+ return _toStringVecAccountId_V3(
+ &m->basic.validatorsset_reset_members_V3.members,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 2820: /* module 11 call 4 */
+ switch (itemIdx) {
+ case 0: /* validatorsset_change_key_V3 - new_ */;
+ return _toStringAccountId_V3(
+ &m->basic.validatorsset_change_key_V3.new_,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 2821: /* module 11 call 5 */
+ switch (itemIdx) {
+ case 0: /* validatorsset_set_prime_V3 - who */;
+ return _toStringAccountId_V3(
+ &m->basic.validatorsset_set_prime_V3.who,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 2822: /* module 11 call 6 */
+ switch (itemIdx) {
+ default:
+ return parser_no_data;
+ }
+ case 3840: /* module 15 call 0 */
+ switch (itemIdx) {
+ case 0: /* technicalcommittee_set_members_V3 - new_members */;
+ return _toStringVecAccountId_V3(
+ &m->basic.technicalcommittee_set_members_V3.new_members,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* technicalcommittee_set_members_V3 - prime */;
+ return _toStringOptionAccountId_V3(
+ &m->basic.technicalcommittee_set_members_V3.prime,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* technicalcommittee_set_members_V3 - old_count */;
+ return _toStringMemberCount_V3(
+ &m->basic.technicalcommittee_set_members_V3.old_count,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 3841: /* module 15 call 1 */
+ switch (itemIdx) {
+ case 0: /* technicalcommittee_execute_V3 - proposal */;
+ return _toStringProposal(
+ &m->basic.technicalcommittee_execute_V3.proposal,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* technicalcommittee_execute_V3 - length_bound */;
+ return _toStringCompactu32(
+ &m->basic.technicalcommittee_execute_V3.length_bound,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 3842: /* module 15 call 2 */
+ switch (itemIdx) {
+ case 0: /* technicalcommittee_propose_V3 - threshold */;
+ return _toStringCompactMemberCount_V3(
+ &m->basic.technicalcommittee_propose_V3.threshold,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* technicalcommittee_propose_V3 - proposal */;
+ return _toStringProposal(
+ &m->basic.technicalcommittee_propose_V3.proposal,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* technicalcommittee_propose_V3 - length_bound */;
+ return _toStringCompactu32(
+ &m->basic.technicalcommittee_propose_V3.length_bound,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 3843: /* module 15 call 3 */
+ switch (itemIdx) {
+ case 0: /* technicalcommittee_vote_V3 - proposal */;
+ return _toStringHash(
+ &m->basic.technicalcommittee_vote_V3.proposal,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* technicalcommittee_vote_V3 - index */;
+ return _toStringCompactProposalIndex_V3(
+ &m->basic.technicalcommittee_vote_V3.index,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* technicalcommittee_vote_V3 - approve */;
+ return _toStringbool(
+ &m->basic.technicalcommittee_vote_V3.approve,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 3844: /* module 15 call 4 */
+ switch (itemIdx) {
+ case 0: /* technicalcommittee_close_V3 - proposal_hash */;
+ return _toStringHash(
+ &m->basic.technicalcommittee_close_V3.proposal_hash,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* technicalcommittee_close_V3 - index */;
+ return _toStringCompactProposalIndex_V3(
+ &m->basic.technicalcommittee_close_V3.index,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* technicalcommittee_close_V3 - proposal_weight_bound */;
+ return _toStringCompactWeight_V3(
+ &m->basic.technicalcommittee_close_V3.proposal_weight_bound,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 3: /* technicalcommittee_close_V3 - length_bound */;
+ return _toStringCompactu32(
+ &m->basic.technicalcommittee_close_V3.length_bound,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 3845: /* module 15 call 5 */
+ switch (itemIdx) {
+ case 0: /* technicalcommittee_disapprove_proposal_V3 - proposal_hash */;
+ return _toStringHash(
+ &m->basic.technicalcommittee_disapprove_proposal_V3.proposal_hash,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 4096: /* module 16 call 0 */
+ switch (itemIdx) {
+ case 0: /* technicalmembership_add_member_V3 - who */;
+ return _toStringAccountId_V3(
+ &m->basic.technicalmembership_add_member_V3.who,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 4097: /* module 16 call 1 */
+ switch (itemIdx) {
+ case 0: /* technicalmembership_remove_member_V3 - who */;
+ return _toStringAccountId_V3(
+ &m->basic.technicalmembership_remove_member_V3.who,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 4098: /* module 16 call 2 */
+ switch (itemIdx) {
+ case 0: /* technicalmembership_swap_member_V3 - remove */;
+ return _toStringAccountId_V3(
+ &m->basic.technicalmembership_swap_member_V3.remove,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* technicalmembership_swap_member_V3 - add */;
+ return _toStringAccountId_V3(
+ &m->basic.technicalmembership_swap_member_V3.add,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 4099: /* module 16 call 3 */
+ switch (itemIdx) {
+ case 0: /* technicalmembership_reset_members_V3 - members */;
+ return _toStringVecAccountId_V3(
+ &m->basic.technicalmembership_reset_members_V3.members,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 4100: /* module 16 call 4 */
+ switch (itemIdx) {
+ case 0: /* technicalmembership_change_key_V3 - new_ */;
+ return _toStringAccountId_V3(
+ &m->basic.technicalmembership_change_key_V3.new_,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 4101: /* module 16 call 5 */
+ switch (itemIdx) {
+ case 0: /* technicalmembership_set_prime_V3 - who */;
+ return _toStringAccountId_V3(
+ &m->basic.technicalmembership_set_prime_V3.who,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 4102: /* module 16 call 6 */
+ switch (itemIdx) {
+ default:
+ return parser_no_data;
+ }
+ case 4352: /* module 17 call 0 */
+ switch (itemIdx) {
+ case 0: /* financialcommittee_set_members_V3 - new_members */;
+ return _toStringVecAccountId_V3(
+ &m->basic.financialcommittee_set_members_V3.new_members,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* financialcommittee_set_members_V3 - prime */;
+ return _toStringOptionAccountId_V3(
+ &m->basic.financialcommittee_set_members_V3.prime,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* financialcommittee_set_members_V3 - old_count */;
+ return _toStringMemberCount_V3(
+ &m->basic.financialcommittee_set_members_V3.old_count,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 4353: /* module 17 call 1 */
+ switch (itemIdx) {
+ case 0: /* financialcommittee_execute_V3 - proposal */;
+ return _toStringProposal(
+ &m->basic.financialcommittee_execute_V3.proposal,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* financialcommittee_execute_V3 - length_bound */;
+ return _toStringCompactu32(
+ &m->basic.financialcommittee_execute_V3.length_bound,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 4354: /* module 17 call 2 */
+ switch (itemIdx) {
+ case 0: /* financialcommittee_propose_V3 - threshold */;
+ return _toStringCompactMemberCount_V3(
+ &m->basic.financialcommittee_propose_V3.threshold,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* financialcommittee_propose_V3 - proposal */;
+ return _toStringProposal(
+ &m->basic.financialcommittee_propose_V3.proposal,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* financialcommittee_propose_V3 - length_bound */;
+ return _toStringCompactu32(
+ &m->basic.financialcommittee_propose_V3.length_bound,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 4355: /* module 17 call 3 */
+ switch (itemIdx) {
+ case 0: /* financialcommittee_vote_V3 - proposal */;
+ return _toStringHash(
+ &m->basic.financialcommittee_vote_V3.proposal,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* financialcommittee_vote_V3 - index */;
+ return _toStringCompactProposalIndex_V3(
+ &m->basic.financialcommittee_vote_V3.index,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* financialcommittee_vote_V3 - approve */;
+ return _toStringbool(
+ &m->basic.financialcommittee_vote_V3.approve,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 4356: /* module 17 call 4 */
+ switch (itemIdx) {
+ case 0: /* financialcommittee_close_V3 - proposal_hash */;
+ return _toStringHash(
+ &m->basic.financialcommittee_close_V3.proposal_hash,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* financialcommittee_close_V3 - index */;
+ return _toStringCompactProposalIndex_V3(
+ &m->basic.financialcommittee_close_V3.index,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* financialcommittee_close_V3 - proposal_weight_bound */;
+ return _toStringCompactWeight_V3(
+ &m->basic.financialcommittee_close_V3.proposal_weight_bound,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 3: /* financialcommittee_close_V3 - length_bound */;
+ return _toStringCompactu32(
+ &m->basic.financialcommittee_close_V3.length_bound,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 4357: /* module 17 call 5 */
+ switch (itemIdx) {
+ case 0: /* financialcommittee_disapprove_proposal_V3 - proposal_hash */;
+ return _toStringHash(
+ &m->basic.financialcommittee_disapprove_proposal_V3.proposal_hash,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 4608: /* module 18 call 0 */
+ switch (itemIdx) {
+ case 0: /* financialmembership_add_member_V3 - who */;
+ return _toStringAccountId_V3(
+ &m->basic.financialmembership_add_member_V3.who,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 4609: /* module 18 call 1 */
+ switch (itemIdx) {
+ case 0: /* financialmembership_remove_member_V3 - who */;
+ return _toStringAccountId_V3(
+ &m->basic.financialmembership_remove_member_V3.who,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 4610: /* module 18 call 2 */
+ switch (itemIdx) {
+ case 0: /* financialmembership_swap_member_V3 - remove */;
+ return _toStringAccountId_V3(
+ &m->basic.financialmembership_swap_member_V3.remove,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* financialmembership_swap_member_V3 - add */;
+ return _toStringAccountId_V3(
+ &m->basic.financialmembership_swap_member_V3.add,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 4611: /* module 18 call 3 */
+ switch (itemIdx) {
+ case 0: /* financialmembership_reset_members_V3 - members */;
+ return _toStringVecAccountId_V3(
+ &m->basic.financialmembership_reset_members_V3.members,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 4612: /* module 18 call 4 */
+ switch (itemIdx) {
+ case 0: /* financialmembership_change_key_V3 - new_ */;
+ return _toStringAccountId_V3(
+ &m->basic.financialmembership_change_key_V3.new_,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 4613: /* module 18 call 5 */
+ switch (itemIdx) {
+ case 0: /* financialmembership_set_prime_V3 - who */;
+ return _toStringAccountId_V3(
+ &m->basic.financialmembership_set_prime_V3.who,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 4614: /* module 18 call 6 */
+ switch (itemIdx) {
+ default:
+ return parser_no_data;
+ }
+ case 4864: /* module 19 call 0 */
+ switch (itemIdx) {
+ case 0: /* rootcommittee_set_members_V3 - new_members */;
+ return _toStringVecAccountId_V3(
+ &m->basic.rootcommittee_set_members_V3.new_members,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* rootcommittee_set_members_V3 - prime */;
+ return _toStringOptionAccountId_V3(
+ &m->basic.rootcommittee_set_members_V3.prime,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* rootcommittee_set_members_V3 - old_count */;
+ return _toStringMemberCount_V3(
+ &m->basic.rootcommittee_set_members_V3.old_count,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 4865: /* module 19 call 1 */
+ switch (itemIdx) {
+ case 0: /* rootcommittee_execute_V3 - proposal */;
+ return _toStringProposal(
+ &m->basic.rootcommittee_execute_V3.proposal,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* rootcommittee_execute_V3 - length_bound */;
+ return _toStringCompactu32(
+ &m->basic.rootcommittee_execute_V3.length_bound,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 4866: /* module 19 call 2 */
+ switch (itemIdx) {
+ case 0: /* rootcommittee_propose_V3 - threshold */;
+ return _toStringCompactMemberCount_V3(
+ &m->basic.rootcommittee_propose_V3.threshold,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* rootcommittee_propose_V3 - proposal */;
+ return _toStringProposal(
+ &m->basic.rootcommittee_propose_V3.proposal,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* rootcommittee_propose_V3 - length_bound */;
+ return _toStringCompactu32(
+ &m->basic.rootcommittee_propose_V3.length_bound,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 4867: /* module 19 call 3 */
+ switch (itemIdx) {
+ case 0: /* rootcommittee_vote_V3 - proposal */;
+ return _toStringHash(
+ &m->basic.rootcommittee_vote_V3.proposal,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* rootcommittee_vote_V3 - index */;
+ return _toStringCompactProposalIndex_V3(
+ &m->basic.rootcommittee_vote_V3.index,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* rootcommittee_vote_V3 - approve */;
+ return _toStringbool(
+ &m->basic.rootcommittee_vote_V3.approve,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 4868: /* module 19 call 4 */
+ switch (itemIdx) {
+ case 0: /* rootcommittee_close_V3 - proposal_hash */;
+ return _toStringHash(
+ &m->basic.rootcommittee_close_V3.proposal_hash,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* rootcommittee_close_V3 - index */;
+ return _toStringCompactProposalIndex_V3(
+ &m->basic.rootcommittee_close_V3.index,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* rootcommittee_close_V3 - proposal_weight_bound */;
+ return _toStringCompactWeight_V3(
+ &m->basic.rootcommittee_close_V3.proposal_weight_bound,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 3: /* rootcommittee_close_V3 - length_bound */;
+ return _toStringCompactu32(
+ &m->basic.rootcommittee_close_V3.length_bound,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 4869: /* module 19 call 5 */
+ switch (itemIdx) {
+ case 0: /* rootcommittee_disapprove_proposal_V3 - proposal_hash */;
+ return _toStringHash(
+ &m->basic.rootcommittee_disapprove_proposal_V3.proposal_hash,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 5120: /* module 20 call 0 */
+ switch (itemIdx) {
+ case 0: /* rootmembership_add_member_V3 - who */;
+ return _toStringAccountId_V3(
+ &m->basic.rootmembership_add_member_V3.who,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 5121: /* module 20 call 1 */
+ switch (itemIdx) {
+ case 0: /* rootmembership_remove_member_V3 - who */;
+ return _toStringAccountId_V3(
+ &m->basic.rootmembership_remove_member_V3.who,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 5122: /* module 20 call 2 */
+ switch (itemIdx) {
+ case 0: /* rootmembership_swap_member_V3 - remove */;
+ return _toStringAccountId_V3(
+ &m->basic.rootmembership_swap_member_V3.remove,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* rootmembership_swap_member_V3 - add */;
+ return _toStringAccountId_V3(
+ &m->basic.rootmembership_swap_member_V3.add,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 5123: /* module 20 call 3 */
+ switch (itemIdx) {
+ case 0: /* rootmembership_reset_members_V3 - members */;
+ return _toStringVecAccountId_V3(
+ &m->basic.rootmembership_reset_members_V3.members,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 5124: /* module 20 call 4 */
+ switch (itemIdx) {
+ case 0: /* rootmembership_change_key_V3 - new_ */;
+ return _toStringAccountId_V3(
+ &m->basic.rootmembership_change_key_V3.new_,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 5125: /* module 20 call 5 */
+ switch (itemIdx) {
+ case 0: /* rootmembership_set_prime_V3 - who */;
+ return _toStringAccountId_V3(
+ &m->basic.rootmembership_set_prime_V3.who,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 5126: /* module 20 call 6 */
+ switch (itemIdx) {
+ default:
+ return parser_no_data;
+ }
+ case 5376: /* module 21 call 0 */
+ switch (itemIdx) {
+ case 0: /* scheduler_schedule_V3 - when */;
+ return _toStringBlockNumber(
+ &m->basic.scheduler_schedule_V3.when,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* scheduler_schedule_V3 - maybe_periodic */;
+ return _toStringOptionPeriod_V3(
+ &m->basic.scheduler_schedule_V3.maybe_periodic,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* scheduler_schedule_V3 - priority */;
+ return _toStringPriority_V3(
+ &m->basic.scheduler_schedule_V3.priority,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 3: /* scheduler_schedule_V3 - call */;
+ return _toStringCall(
+ &m->basic.scheduler_schedule_V3.call,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 5377: /* module 21 call 1 */
+ switch (itemIdx) {
+ case 0: /* scheduler_cancel_V3 - when */;
+ return _toStringBlockNumber(
+ &m->basic.scheduler_cancel_V3.when,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* scheduler_cancel_V3 - index */;
+ return _toStringu32(
+ &m->basic.scheduler_cancel_V3.index,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 5378: /* module 21 call 2 */
+ switch (itemIdx) {
+ case 0: /* scheduler_schedule_named_V3 - id */;
+ return _toStringBytes(
+ &m->basic.scheduler_schedule_named_V3.id,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* scheduler_schedule_named_V3 - when */;
+ return _toStringBlockNumber(
+ &m->basic.scheduler_schedule_named_V3.when,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* scheduler_schedule_named_V3 - maybe_periodic */;
+ return _toStringOptionPeriod_V3(
+ &m->basic.scheduler_schedule_named_V3.maybe_periodic,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 3: /* scheduler_schedule_named_V3 - priority */;
+ return _toStringPriority_V3(
+ &m->basic.scheduler_schedule_named_V3.priority,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 4: /* scheduler_schedule_named_V3 - call */;
+ return _toStringCall(
+ &m->basic.scheduler_schedule_named_V3.call,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 5379: /* module 21 call 3 */
+ switch (itemIdx) {
+ case 0: /* scheduler_cancel_named_V3 - id */;
+ return _toStringBytes(
+ &m->basic.scheduler_cancel_named_V3.id,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 5380: /* module 21 call 4 */
+ switch (itemIdx) {
+ case 0: /* scheduler_schedule_after_V3 - after */;
+ return _toStringBlockNumber(
+ &m->basic.scheduler_schedule_after_V3.after,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* scheduler_schedule_after_V3 - maybe_periodic */;
+ return _toStringOptionPeriod_V3(
+ &m->basic.scheduler_schedule_after_V3.maybe_periodic,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* scheduler_schedule_after_V3 - priority */;
+ return _toStringPriority_V3(
+ &m->basic.scheduler_schedule_after_V3.priority,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 3: /* scheduler_schedule_after_V3 - call */;
+ return _toStringCall(
+ &m->basic.scheduler_schedule_after_V3.call,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 5381: /* module 21 call 5 */
+ switch (itemIdx) {
+ case 0: /* scheduler_schedule_named_after_V3 - id */;
+ return _toStringBytes(
+ &m->basic.scheduler_schedule_named_after_V3.id,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* scheduler_schedule_named_after_V3 - after */;
+ return _toStringBlockNumber(
+ &m->basic.scheduler_schedule_named_after_V3.after,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* scheduler_schedule_named_after_V3 - maybe_periodic */;
+ return _toStringOptionPeriod_V3(
+ &m->basic.scheduler_schedule_named_after_V3.maybe_periodic,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 3: /* scheduler_schedule_named_after_V3 - priority */;
+ return _toStringPriority_V3(
+ &m->basic.scheduler_schedule_named_after_V3.priority,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 4: /* scheduler_schedule_named_after_V3 - call */;
+ return _toStringCall(
+ &m->basic.scheduler_schedule_named_after_V3.call,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 5632: /* module 22 call 0 */
+ switch (itemIdx) {
+ case 0: /* amendments_propose_V3 - amendment */;
+ return _toStringAmendment_V3(
+ &m->basic.amendments_propose_V3.amendment,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 5633: /* module 22 call 1 */
+ switch (itemIdx) {
+ case 0: /* amendments_veto_V3 - amendment_id */;
+ return _toStringu64(
+ &m->basic.amendments_veto_V3.amendment_id,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 5888: /* module 23 call 0 */
+ switch (itemIdx) {
+ case 0: /* mandate_apply_V3 - call */;
+ return _toStringCall(
+ &m->basic.mandate_apply_V3.call,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 6144: /* module 24 call 0 */
+ switch (itemIdx) {
+ case 0: /* companyreserve_spend_V3 - to */;
+ return _toStringAccountId_V3(
+ &m->basic.companyreserve_spend_V3.to,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* companyreserve_spend_V3 - amount */;
+ return _toStringBalanceOf(
+ &m->basic.companyreserve_spend_V3.amount,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 6145: /* module 24 call 1 */
+ switch (itemIdx) {
+ case 0: /* companyreserve_tip_V3 - amount */;
+ return _toStringBalanceOf(
+ &m->basic.companyreserve_tip_V3.amount,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 6146: /* module 24 call 2 */
+ switch (itemIdx) {
+ case 0: /* companyreserve_apply_as_V3 - call */;
+ return _toStringCall(
+ &m->basic.companyreserve_apply_as_V3.call,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 6400: /* module 25 call 0 */
+ switch (itemIdx) {
+ case 0: /* internationalreserve_spend_V3 - to */;
+ return _toStringAccountId_V3(
+ &m->basic.internationalreserve_spend_V3.to,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* internationalreserve_spend_V3 - amount */;
+ return _toStringBalanceOf(
+ &m->basic.internationalreserve_spend_V3.amount,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 6401: /* module 25 call 1 */
+ switch (itemIdx) {
+ case 0: /* internationalreserve_tip_V3 - amount */;
+ return _toStringBalanceOf(
+ &m->basic.internationalreserve_tip_V3.amount,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 6402: /* module 25 call 2 */
+ switch (itemIdx) {
+ case 0: /* internationalreserve_apply_as_V3 - call */;
+ return _toStringCall(
+ &m->basic.internationalreserve_apply_as_V3.call,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 6656: /* module 26 call 0 */
+ switch (itemIdx) {
+ case 0: /* usareserve_spend_V3 - to */;
+ return _toStringAccountId_V3(
+ &m->basic.usareserve_spend_V3.to,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* usareserve_spend_V3 - amount */;
+ return _toStringBalanceOf(
+ &m->basic.usareserve_spend_V3.amount,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 6657: /* module 26 call 1 */
+ switch (itemIdx) {
+ case 0: /* usareserve_tip_V3 - amount */;
+ return _toStringBalanceOf(
+ &m->basic.usareserve_tip_V3.amount,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 6658: /* module 26 call 2 */
+ switch (itemIdx) {
+ case 0: /* usareserve_apply_as_V3 - call */;
+ return _toStringCall(
+ &m->basic.usareserve_apply_as_V3.call,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 6912: /* module 27 call 0 */
+ switch (itemIdx) {
+ default:
+ return parser_no_data;
+ }
+ case 6913: /* module 27 call 1 */
+ switch (itemIdx) {
+ case 0: /* vesting_add_vesting_schedule_V3 - dest */;
+ return _toStringLookupSource_V3(
+ &m->basic.vesting_add_vesting_schedule_V3.dest,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* vesting_add_vesting_schedule_V3 - schedule */;
+ return _toStringVestingScheduleOf_V3(
+ &m->basic.vesting_add_vesting_schedule_V3.schedule,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 6914: /* module 27 call 2 */
+ switch (itemIdx) {
+ case 0: /* vesting_cancel_all_vesting_schedules_V3 - who */;
+ return _toStringLookupSource_V3(
+ &m->basic.vesting_cancel_all_vesting_schedules_V3.who,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* vesting_cancel_all_vesting_schedules_V3 - funds_collector */;
+ return _toStringLookupSource_V3(
+ &m->basic.vesting_cancel_all_vesting_schedules_V3.funds_collector,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* vesting_cancel_all_vesting_schedules_V3 - limit_to_free_balance */;
+ return _toStringbool(
+ &m->basic.vesting_cancel_all_vesting_schedules_V3.limit_to_free_balance,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7168: /* module 28 call 0 */
+ switch (itemIdx) {
+ case 0: /* identity_add_registrar_V3 - account */;
+ return _toStringAccountId_V3(
+ &m->basic.identity_add_registrar_V3.account,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7169: /* module 28 call 1 */
+ switch (itemIdx) {
+ case 0: /* identity_set_identity_V3 - info */;
+ return _toStringIdentityInfo_V3(
+ &m->basic.identity_set_identity_V3.info,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7170: /* module 28 call 2 */
+ switch (itemIdx) {
+ case 0: /* identity_set_subs_V3 - subs */;
+ return _toStringVecTupleAccountIdData_V3(
+ &m->basic.identity_set_subs_V3.subs,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7171: /* module 28 call 3 */
+ switch (itemIdx) {
+ default:
+ return parser_no_data;
+ }
+ case 7172: /* module 28 call 4 */
+ switch (itemIdx) {
+ case 0: /* identity_request_judgement_V3 - reg_index */;
+ return _toStringCompactRegistrarIndex_V3(
+ &m->basic.identity_request_judgement_V3.reg_index,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* identity_request_judgement_V3 - max_fee */;
+ return _toStringCompactBalanceOf(
+ &m->basic.identity_request_judgement_V3.max_fee,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7173: /* module 28 call 5 */
+ switch (itemIdx) {
+ case 0: /* identity_cancel_request_V3 - reg_index */;
+ return _toStringRegistrarIndex_V3(
+ &m->basic.identity_cancel_request_V3.reg_index,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7174: /* module 28 call 6 */
+ switch (itemIdx) {
+ case 0: /* identity_set_fee_V3 - index */;
+ return _toStringCompactRegistrarIndex_V3(
+ &m->basic.identity_set_fee_V3.index,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* identity_set_fee_V3 - fee */;
+ return _toStringCompactBalanceOf(
+ &m->basic.identity_set_fee_V3.fee,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7175: /* module 28 call 7 */
+ switch (itemIdx) {
+ case 0: /* identity_set_account_id_V3 - index */;
+ return _toStringCompactRegistrarIndex_V3(
+ &m->basic.identity_set_account_id_V3.index,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* identity_set_account_id_V3 - new_ */;
+ return _toStringAccountId_V3(
+ &m->basic.identity_set_account_id_V3.new_,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7176: /* module 28 call 8 */
+ switch (itemIdx) {
+ case 0: /* identity_set_fields_V3 - index */;
+ return _toStringCompactRegistrarIndex_V3(
+ &m->basic.identity_set_fields_V3.index,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* identity_set_fields_V3 - fields */;
+ return _toStringIdentityFields_V3(
+ &m->basic.identity_set_fields_V3.fields,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7177: /* module 28 call 9 */
+ switch (itemIdx) {
+ case 0: /* identity_provide_judgement_V3 - reg_index */;
+ return _toStringCompactRegistrarIndex_V3(
+ &m->basic.identity_provide_judgement_V3.reg_index,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* identity_provide_judgement_V3 - target */;
+ return _toStringLookupSource_V3(
+ &m->basic.identity_provide_judgement_V3.target,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* identity_provide_judgement_V3 - judgement */;
+ return _toStringIdentityJudgement_V3(
+ &m->basic.identity_provide_judgement_V3.judgement,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7178: /* module 28 call 10 */
+ switch (itemIdx) {
+ case 0: /* identity_kill_identity_V3 - target */;
+ return _toStringLookupSource_V3(
+ &m->basic.identity_kill_identity_V3.target,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7179: /* module 28 call 11 */
+ switch (itemIdx) {
+ case 0: /* identity_add_sub_V3 - sub */;
+ return _toStringLookupSource_V3(
+ &m->basic.identity_add_sub_V3.sub,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* identity_add_sub_V3 - data */;
+ return _toStringData(
+ &m->basic.identity_add_sub_V3.data,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7180: /* module 28 call 12 */
+ switch (itemIdx) {
+ case 0: /* identity_rename_sub_V3 - sub */;
+ return _toStringLookupSource_V3(
+ &m->basic.identity_rename_sub_V3.sub,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* identity_rename_sub_V3 - data */;
+ return _toStringData(
+ &m->basic.identity_rename_sub_V3.data,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7181: /* module 28 call 13 */
+ switch (itemIdx) {
+ case 0: /* identity_remove_sub_V3 - sub */;
+ return _toStringLookupSource_V3(
+ &m->basic.identity_remove_sub_V3.sub,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7182: /* module 28 call 14 */
+ switch (itemIdx) {
+ default:
+ return parser_no_data;
+ }
+ case 7424: /* module 29 call 0 */
+ switch (itemIdx) {
+ case 0: /* recovery_as_recovered_V3 - account */;
+ return _toStringAccountId_V3(
+ &m->basic.recovery_as_recovered_V3.account,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* recovery_as_recovered_V3 - call */;
+ return _toStringCall(
+ &m->basic.recovery_as_recovered_V3.call,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7425: /* module 29 call 1 */
+ switch (itemIdx) {
+ case 0: /* recovery_set_recovered_V3 - lost */;
+ return _toStringAccountId_V3(
+ &m->basic.recovery_set_recovered_V3.lost,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* recovery_set_recovered_V3 - rescuer */;
+ return _toStringAccountId_V3(
+ &m->basic.recovery_set_recovered_V3.rescuer,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7426: /* module 29 call 2 */
+ switch (itemIdx) {
+ case 0: /* recovery_create_recovery_V3 - friends */;
+ return _toStringVecAccountId_V3(
+ &m->basic.recovery_create_recovery_V3.friends,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* recovery_create_recovery_V3 - threshold */;
+ return _toStringu16(
+ &m->basic.recovery_create_recovery_V3.threshold,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* recovery_create_recovery_V3 - delay_period */;
+ return _toStringBlockNumber(
+ &m->basic.recovery_create_recovery_V3.delay_period,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7427: /* module 29 call 3 */
+ switch (itemIdx) {
+ case 0: /* recovery_initiate_recovery_V3 - account */;
+ return _toStringAccountId_V3(
+ &m->basic.recovery_initiate_recovery_V3.account,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7428: /* module 29 call 4 */
+ switch (itemIdx) {
+ case 0: /* recovery_vouch_recovery_V3 - lost */;
+ return _toStringAccountId_V3(
+ &m->basic.recovery_vouch_recovery_V3.lost,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* recovery_vouch_recovery_V3 - rescuer */;
+ return _toStringAccountId_V3(
+ &m->basic.recovery_vouch_recovery_V3.rescuer,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7429: /* module 29 call 5 */
+ switch (itemIdx) {
+ case 0: /* recovery_claim_recovery_V3 - account */;
+ return _toStringAccountId_V3(
+ &m->basic.recovery_claim_recovery_V3.account,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7430: /* module 29 call 6 */
+ switch (itemIdx) {
+ case 0: /* recovery_close_recovery_V3 - rescuer */;
+ return _toStringAccountId_V3(
+ &m->basic.recovery_close_recovery_V3.rescuer,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7431: /* module 29 call 7 */
+ switch (itemIdx) {
+ default:
+ return parser_no_data;
+ }
+ case 7432: /* module 29 call 8 */
+ switch (itemIdx) {
+ case 0: /* recovery_cancel_recovered_V3 - account */;
+ return _toStringAccountId_V3(
+ &m->basic.recovery_cancel_recovered_V3.account,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7681: /* module 30 call 1 */
+ switch (itemIdx) {
+ case 0: /* utility_as_derivative_V3 - index */;
+ return _toStringu16(
+ &m->basic.utility_as_derivative_V3.index,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* utility_as_derivative_V3 - call */;
+ return _toStringCall(
+ &m->basic.utility_as_derivative_V3.call,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7936: /* module 31 call 0 */
+ switch (itemIdx) {
+ case 0: /* proxy_proxy_V3 - real */;
+ return _toStringAccountId_V3(
+ &m->nested.proxy_proxy_V3.real,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* proxy_proxy_V3 - force_proxy_type */;
+ return _toStringOptionProxyType_V3(
+ &m->nested.proxy_proxy_V3.force_proxy_type,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* proxy_proxy_V3 - call */;
+ return _toStringCall(
+ &m->nested.proxy_proxy_V3.call,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7937: /* module 31 call 1 */
+ switch (itemIdx) {
+ case 0: /* proxy_add_proxy_V3 - delegate */;
+ return _toStringAccountId_V3(
+ &m->basic.proxy_add_proxy_V3.delegate,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* proxy_add_proxy_V3 - proxy_type */;
+ return _toStringProxyType_V3(
+ &m->basic.proxy_add_proxy_V3.proxy_type,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* proxy_add_proxy_V3 - delay */;
+ return _toStringBlockNumber(
+ &m->basic.proxy_add_proxy_V3.delay,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7938: /* module 31 call 2 */
+ switch (itemIdx) {
+ case 0: /* proxy_remove_proxy_V3 - delegate */;
+ return _toStringAccountId_V3(
+ &m->basic.proxy_remove_proxy_V3.delegate,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* proxy_remove_proxy_V3 - proxy_type */;
+ return _toStringProxyType_V3(
+ &m->basic.proxy_remove_proxy_V3.proxy_type,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* proxy_remove_proxy_V3 - delay */;
+ return _toStringBlockNumber(
+ &m->basic.proxy_remove_proxy_V3.delay,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7939: /* module 31 call 3 */
+ switch (itemIdx) {
+ default:
+ return parser_no_data;
+ }
+ case 7940: /* module 31 call 4 */
+ switch (itemIdx) {
+ case 0: /* proxy_anonymous_V3 - proxy_type */;
+ return _toStringProxyType_V3(
+ &m->basic.proxy_anonymous_V3.proxy_type,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* proxy_anonymous_V3 - delay */;
+ return _toStringBlockNumber(
+ &m->basic.proxy_anonymous_V3.delay,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* proxy_anonymous_V3 - index */;
+ return _toStringu16(
+ &m->basic.proxy_anonymous_V3.index,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7941: /* module 31 call 5 */
+ switch (itemIdx) {
+ case 0: /* proxy_kill_anonymous_V3 - spawner */;
+ return _toStringAccountId_V3(
+ &m->basic.proxy_kill_anonymous_V3.spawner,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* proxy_kill_anonymous_V3 - proxy_type */;
+ return _toStringProxyType_V3(
+ &m->basic.proxy_kill_anonymous_V3.proxy_type,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* proxy_kill_anonymous_V3 - index */;
+ return _toStringu16(
+ &m->basic.proxy_kill_anonymous_V3.index,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 3: /* proxy_kill_anonymous_V3 - height */;
+ return _toStringCompactBlockNumber(
+ &m->basic.proxy_kill_anonymous_V3.height,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 4: /* proxy_kill_anonymous_V3 - ext_index */;
+ return _toStringCompactu32(
+ &m->basic.proxy_kill_anonymous_V3.ext_index,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7942: /* module 31 call 6 */
+ switch (itemIdx) {
+ case 0: /* proxy_announce_V3 - real */;
+ return _toStringAccountId_V3(
+ &m->basic.proxy_announce_V3.real,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* proxy_announce_V3 - call_hash */;
+ return _toStringCallHashOf_V3(
+ &m->basic.proxy_announce_V3.call_hash,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7943: /* module 31 call 7 */
+ switch (itemIdx) {
+ case 0: /* proxy_remove_announcement_V3 - real */;
+ return _toStringAccountId_V3(
+ &m->basic.proxy_remove_announcement_V3.real,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* proxy_remove_announcement_V3 - call_hash */;
+ return _toStringCallHashOf_V3(
+ &m->basic.proxy_remove_announcement_V3.call_hash,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7944: /* module 31 call 8 */
+ switch (itemIdx) {
+ case 0: /* proxy_reject_announcement_V3 - delegate */;
+ return _toStringAccountId_V3(
+ &m->basic.proxy_reject_announcement_V3.delegate,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* proxy_reject_announcement_V3 - call_hash */;
+ return _toStringCallHashOf_V3(
+ &m->basic.proxy_reject_announcement_V3.call_hash,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 7945: /* module 31 call 9 */
+ switch (itemIdx) {
+ case 0: /* proxy_proxy_announced_V3 - delegate */;
+ return _toStringAccountId_V3(
+ &m->basic.proxy_proxy_announced_V3.delegate,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* proxy_proxy_announced_V3 - real */;
+ return _toStringAccountId_V3(
+ &m->basic.proxy_proxy_announced_V3.real,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* proxy_proxy_announced_V3 - force_proxy_type */;
+ return _toStringOptionProxyType_V3(
+ &m->basic.proxy_proxy_announced_V3.force_proxy_type,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 3: /* proxy_proxy_announced_V3 - call */;
+ return _toStringCall(
+ &m->basic.proxy_proxy_announced_V3.call,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 8192: /* module 32 call 0 */
+ switch (itemIdx) {
+ case 0: /* multisig_as_multi_threshold_1_V3 - other_signatories */;
+ return _toStringVecAccountId_V3(
+ &m->nested.multisig_as_multi_threshold_1_V3.other_signatories,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* multisig_as_multi_threshold_1_V3 - call */;
+ return _toStringCall(
+ &m->nested.multisig_as_multi_threshold_1_V3.call,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 8193: /* module 32 call 1 */
+ switch (itemIdx) {
+ case 0: /* multisig_as_multi_V3 - threshold */;
+ return _toStringu16(
+ &m->nested.multisig_as_multi_V3.threshold,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* multisig_as_multi_V3 - other_signatories */;
+ return _toStringVecAccountId_V3(
+ &m->nested.multisig_as_multi_V3.other_signatories,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* multisig_as_multi_V3 - maybe_timepoint */;
+ return _toStringOptionTimepoint_V3(
+ &m->nested.multisig_as_multi_V3.maybe_timepoint,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 3: /* multisig_as_multi_V3 - call */;
+ return _toStringOpaqueCall_V3(
+ &m->nested.multisig_as_multi_V3.call,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 4: /* multisig_as_multi_V3 - store_call */;
+ return _toStringbool(
+ &m->nested.multisig_as_multi_V3.store_call,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 5: /* multisig_as_multi_V3 - max_weight */;
+ return _toStringWeight_V3(
+ &m->nested.multisig_as_multi_V3.max_weight,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 8194: /* module 32 call 2 */
+ switch (itemIdx) {
+ case 0: /* multisig_approve_as_multi_V3 - threshold */;
+ return _toStringu16(
+ &m->nested.multisig_approve_as_multi_V3.threshold,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* multisig_approve_as_multi_V3 - other_signatories */;
+ return _toStringVecAccountId_V3(
+ &m->nested.multisig_approve_as_multi_V3.other_signatories,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* multisig_approve_as_multi_V3 - maybe_timepoint */;
+ return _toStringOptionTimepoint_V3(
+ &m->nested.multisig_approve_as_multi_V3.maybe_timepoint,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 3: /* multisig_approve_as_multi_V3 - call_hash */;
+ return _toStringu8_array_32_V3(
+ &m->nested.multisig_approve_as_multi_V3.call_hash,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 4: /* multisig_approve_as_multi_V3 - max_weight */;
+ return _toStringWeight_V3(
+ &m->nested.multisig_approve_as_multi_V3.max_weight,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 8195: /* module 32 call 3 */
+ switch (itemIdx) {
+ case 0: /* multisig_cancel_as_multi_V3 - threshold */;
+ return _toStringu16(
+ &m->nested.multisig_cancel_as_multi_V3.threshold,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* multisig_cancel_as_multi_V3 - other_signatories */;
+ return _toStringVecAccountId_V3(
+ &m->nested.multisig_cancel_as_multi_V3.other_signatories,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* multisig_cancel_as_multi_V3 - timepoint */;
+ return _toStringTimepoint_V3(
+ &m->nested.multisig_cancel_as_multi_V3.timepoint,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 3: /* multisig_cancel_as_multi_V3 - call_hash */;
+ return _toStringu8_array_32_V3(
+ &m->nested.multisig_cancel_as_multi_V3.call_hash,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 8448: /* module 33 call 0 */
+ switch (itemIdx) {
+ case 0: /* contracts_update_schedule_V3 - schedule */;
+ return _toStringSchedule_V3(
+ &m->basic.contracts_update_schedule_V3.schedule,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 8449: /* module 33 call 1 */
+ switch (itemIdx) {
+ case 0: /* contracts_call_V3 - dest */;
+ return _toStringLookupSource_V3(
+ &m->basic.contracts_call_V3.dest,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* contracts_call_V3 - value */;
+ return _toStringCompactBalanceOf(
+ &m->basic.contracts_call_V3.value,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* contracts_call_V3 - gas_limit */;
+ return _toStringCompactWeight_V3(
+ &m->basic.contracts_call_V3.gas_limit,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 3: /* contracts_call_V3 - data */;
+ return _toStringBytes(
+ &m->basic.contracts_call_V3.data,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 8450: /* module 33 call 2 */
+ switch (itemIdx) {
+ case 0: /* contracts_instantiate_with_code_V3 - endowment */;
+ return _toStringCompactBalanceOf(
+ &m->basic.contracts_instantiate_with_code_V3.endowment,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* contracts_instantiate_with_code_V3 - gas_limit */;
+ return _toStringCompactWeight_V3(
+ &m->basic.contracts_instantiate_with_code_V3.gas_limit,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* contracts_instantiate_with_code_V3 - code */;
+ return _toStringBytes(
+ &m->basic.contracts_instantiate_with_code_V3.code,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 3: /* contracts_instantiate_with_code_V3 - data */;
+ return _toStringBytes(
+ &m->basic.contracts_instantiate_with_code_V3.data,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 4: /* contracts_instantiate_with_code_V3 - salt */;
+ return _toStringBytes(
+ &m->basic.contracts_instantiate_with_code_V3.salt,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 8451: /* module 33 call 3 */
+ switch (itemIdx) {
+ case 0: /* contracts_instantiate_V3 - endowment */;
+ return _toStringCompactBalanceOf(
+ &m->basic.contracts_instantiate_V3.endowment,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* contracts_instantiate_V3 - gas_limit */;
+ return _toStringCompactWeight_V3(
+ &m->basic.contracts_instantiate_V3.gas_limit,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* contracts_instantiate_V3 - code_hash */;
+ return _toStringCodeHash_V3(
+ &m->basic.contracts_instantiate_V3.code_hash,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 3: /* contracts_instantiate_V3 - data */;
+ return _toStringBytes(
+ &m->basic.contracts_instantiate_V3.data,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 4: /* contracts_instantiate_V3 - salt */;
+ return _toStringBytes(
+ &m->basic.contracts_instantiate_V3.salt,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 8452: /* module 33 call 4 */
+ switch (itemIdx) {
+ case 0: /* contracts_claim_surcharge_V3 - dest */;
+ return _toStringAccountId_V3(
+ &m->basic.contracts_claim_surcharge_V3.dest,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* contracts_claim_surcharge_V3 - aux_sender */;
+ return _toStringOptionAccountId_V3(
+ &m->basic.contracts_claim_surcharge_V3.aux_sender,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 8704: /* module 34 call 0 */
+ switch (itemIdx) {
+ case 0: /* pkitcr_apply_V3 - metadata */;
+ return _toStringBytes(
+ &m->basic.pkitcr_apply_V3.metadata,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* pkitcr_apply_V3 - deposit */;
+ return _toStringBalanceOf(
+ &m->basic.pkitcr_apply_V3.deposit,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 8705: /* module 34 call 1 */
+ switch (itemIdx) {
+ case 0: /* pkitcr_counter_V3 - member */;
+ return _toStringAccountId_V3(
+ &m->basic.pkitcr_counter_V3.member,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* pkitcr_counter_V3 - deposit */;
+ return _toStringBalanceOf(
+ &m->basic.pkitcr_counter_V3.deposit,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 8706: /* module 34 call 2 */
+ switch (itemIdx) {
+ case 0: /* pkitcr_vote_V3 - member */;
+ return _toStringAccountId_V3(
+ &m->basic.pkitcr_vote_V3.member,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* pkitcr_vote_V3 - supporting */;
+ return _toStringbool(
+ &m->basic.pkitcr_vote_V3.supporting,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* pkitcr_vote_V3 - deposit */;
+ return _toStringBalanceOf(
+ &m->basic.pkitcr_vote_V3.deposit,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 8707: /* module 34 call 3 */
+ switch (itemIdx) {
+ case 0: /* pkitcr_challenge_V3 - member */;
+ return _toStringAccountId_V3(
+ &m->basic.pkitcr_challenge_V3.member,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* pkitcr_challenge_V3 - deposit */;
+ return _toStringBalanceOf(
+ &m->basic.pkitcr_challenge_V3.deposit,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 8960: /* module 35 call 0 */
+ switch (itemIdx) {
+ case 0: /* pkirootoftrust_book_slot_V3 - certificate_id */;
+ return _toStringCertificateId_V3(
+ &m->basic.pkirootoftrust_book_slot_V3.certificate_id,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 8961: /* module 35 call 1 */
+ switch (itemIdx) {
+ case 0: /* pkirootoftrust_renew_slot_V3 - certificate_id */;
+ return _toStringCertificateId_V3(
+ &m->basic.pkirootoftrust_renew_slot_V3.certificate_id,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 8962: /* module 35 call 2 */
+ switch (itemIdx) {
+ case 0: /* pkirootoftrust_revoke_slot_V3 - certificate_id */;
+ return _toStringCertificateId_V3(
+ &m->basic.pkirootoftrust_revoke_slot_V3.certificate_id,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 8963: /* module 35 call 3 */
+ switch (itemIdx) {
+ case 0: /* pkirootoftrust_revoke_child_V3 - root */;
+ return _toStringCertificateId_V3(
+ &m->basic.pkirootoftrust_revoke_child_V3.root,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* pkirootoftrust_revoke_child_V3 - child */;
+ return _toStringCertificateId_V3(
+ &m->basic.pkirootoftrust_revoke_child_V3.child,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 9216: /* module 36 call 0 */
+ switch (itemIdx) {
+ default:
+ return parser_no_data;
+ }
+ case 9472: /* module 37 call 0 */
+ switch (itemIdx) {
+ case 0: /* allocations_allocate_V3 - to */;
+ return _toStringAccountId_V3(
+ &m->basic.allocations_allocate_V3.to,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* allocations_allocate_V3 - amount */;
+ return _toStringBalanceOf(
+ &m->basic.allocations_allocate_V3.amount,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 2: /* allocations_allocate_V3 - proof */;
+ return _toStringBytes(
+ &m->basic.allocations_allocate_V3.proof,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 9728: /* module 38 call 0 */
+ switch (itemIdx) {
+ case 0: /* allocationsoracles_add_member_V3 - who */;
+ return _toStringAccountId_V3(
+ &m->basic.allocationsoracles_add_member_V3.who,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 9729: /* module 38 call 1 */
+ switch (itemIdx) {
+ case 0: /* allocationsoracles_remove_member_V3 - who */;
+ return _toStringAccountId_V3(
+ &m->basic.allocationsoracles_remove_member_V3.who,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 9730: /* module 38 call 2 */
+ switch (itemIdx) {
+ case 0: /* allocationsoracles_swap_member_V3 - remove */;
+ return _toStringAccountId_V3(
+ &m->basic.allocationsoracles_swap_member_V3.remove,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ case 1: /* allocationsoracles_swap_member_V3 - add */;
+ return _toStringAccountId_V3(
+ &m->basic.allocationsoracles_swap_member_V3.add,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 9731: /* module 38 call 3 */
+ switch (itemIdx) {
+ case 0: /* allocationsoracles_reset_members_V3 - members */;
+ return _toStringVecAccountId_V3(
+ &m->basic.allocationsoracles_reset_members_V3.members,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 9732: /* module 38 call 4 */
+ switch (itemIdx) {
+ case 0: /* allocationsoracles_change_key_V3 - new_ */;
+ return _toStringAccountId_V3(
+ &m->basic.allocationsoracles_change_key_V3.new_,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 9733: /* module 38 call 5 */
+ switch (itemIdx) {
+ case 0: /* allocationsoracles_set_prime_V3 - who */;
+ return _toStringAccountId_V3(
+ &m->basic.allocationsoracles_set_prime_V3.who,
+ outValue, outValueLen,
+ pageIdx, pageCount);
+ default:
+ return parser_no_data;
+ }
+ case 9734: /* module 38 call 6 */
+ switch (itemIdx) {
+ default:
+ return parser_no_data;
+ }
+#endif
+ default:
+ return parser_ok;
+ }
+
+ return parser_ok;
+}
+
+bool _getMethod_ItemIsExpert_V3(uint8_t moduleIdx, uint8_t callIdx, uint8_t itemIdx)
+{
+ uint16_t callPrivIdx = ((uint16_t)moduleIdx << 8u) + callIdx;
+
+ switch (callPrivIdx) {
+
+ default:
+ return false;
+ }
+}
+
+bool _getMethod_IsNestingSupported_V3(uint8_t moduleIdx, uint8_t callIdx)
+{
+ uint16_t callPrivIdx = ((uint16_t)moduleIdx << 8u) + callIdx;
+
+ switch (callPrivIdx) {
+ case 256: // Timestamp:Set
+ case 512: // Indices:Claim
+ case 513: // Indices:Transfer
+ case 514: // Indices:Free
+ case 515: // Indices:Force transfer
+ case 516: // Indices:Freeze
+ case 1536: // Babe:Report equivocation
+ case 1537: // Babe:Report equivocation unsigned
+ case 1792: // Grandpa:Report equivocation
+ case 1793: // Grandpa:Report equivocation unsigned
+ case 1794: // Grandpa:Note stalled
+ case 2048: // Authorship:Set uncles
+ case 2304: // ImOnline:Heartbeat
+ case 2816: // ValidatorsSet:Add member
+ case 2817: // ValidatorsSet:Remove member
+ case 2818: // ValidatorsSet:Swap member
+ case 2819: // ValidatorsSet:Reset members
+ case 2820: // ValidatorsSet:Change key
+ case 2821: // ValidatorsSet:Set prime
+ case 2822: // ValidatorsSet:Clear prime
+ case 3072: // Session:Set keys
+ case 3073: // Session:Purge keys
+ case 3840: // TechnicalCommittee:Set members
+ case 3841: // TechnicalCommittee:Execute
+ case 3842: // TechnicalCommittee:Propose
+ case 3843: // TechnicalCommittee:Vote
+ case 3844: // TechnicalCommittee:Close
+ case 3845: // TechnicalCommittee:Disapprove proposal
+ case 4096: // TechnicalMembership:Add member
+ case 4097: // TechnicalMembership:Remove member
+ case 4098: // TechnicalMembership:Swap member
+ case 4099: // TechnicalMembership:Reset members
+ case 4100: // TechnicalMembership:Change key
+ case 4101: // TechnicalMembership:Set prime
+ case 4102: // TechnicalMembership:Clear prime
+ case 4352: // FinancialCommittee:Set members
+ case 4353: // FinancialCommittee:Execute
+ case 4354: // FinancialCommittee:Propose
+ case 4355: // FinancialCommittee:Vote
+ case 4356: // FinancialCommittee:Close
+ case 4357: // FinancialCommittee:Disapprove proposal
+ case 4608: // FinancialMembership:Add member
+ case 4609: // FinancialMembership:Remove member
+ case 4610: // FinancialMembership:Swap member
+ case 4611: // FinancialMembership:Reset members
+ case 4612: // FinancialMembership:Change key
+ case 4613: // FinancialMembership:Set prime
+ case 4614: // FinancialMembership:Clear prime
+ case 4864: // RootCommittee:Set members
+ case 4865: // RootCommittee:Execute
+ case 4866: // RootCommittee:Propose
+ case 4867: // RootCommittee:Vote
+ case 4868: // RootCommittee:Close
+ case 4869: // RootCommittee:Disapprove proposal
+ case 5120: // RootMembership:Add member
+ case 5121: // RootMembership:Remove member
+ case 5122: // RootMembership:Swap member
+ case 5123: // RootMembership:Reset members
+ case 5124: // RootMembership:Change key
+ case 5125: // RootMembership:Set prime
+ case 5126: // RootMembership:Clear prime
+ case 5376: // Scheduler:Schedule
+ case 5377: // Scheduler:Cancel
+ case 5378: // Scheduler:Schedule named
+ case 5379: // Scheduler:Cancel named
+ case 5380: // Scheduler:Schedule after
+ case 5381: // Scheduler:Schedule named after
+ case 5632: // Amendments:Propose
+ case 5633: // Amendments:Veto
+ case 5888: // Mandate:Apply
+ case 6144: // CompanyReserve:Spend
+ case 6145: // CompanyReserve:Tip
+ case 6146: // CompanyReserve:Apply as
+ case 6400: // InternationalReserve:Spend
+ case 6401: // InternationalReserve:Tip
+ case 6402: // InternationalReserve:Apply as
+ case 6656: // UsaReserve:Spend
+ case 6657: // UsaReserve:Tip
+ case 6658: // UsaReserve:Apply as
+ case 6912: // Vesting:Claim
+ case 6913: // Vesting:Add vesting schedule
+ case 6914: // Vesting:Cancel all vesting schedules
+ case 7168: // Identity:Add registrar
+ case 7169: // Identity:Set identity
+ case 7170: // Identity:Set subs
+ case 7171: // Identity:Clear identity
+ case 7172: // Identity:Request judgement
+ case 7173: // Identity:Cancel request
+ case 7174: // Identity:Set fee
+ case 7175: // Identity:Set account id
+ case 7176: // Identity:Set fields
+ case 7177: // Identity:Provide judgement
+ case 7178: // Identity:Kill identity
+ case 7179: // Identity:Add sub
+ case 7180: // Identity:Rename sub
+ case 7181: // Identity:Remove sub
+ case 7182: // Identity:Quit sub
+ case 7424: // Recovery:As recovered
+ case 7425: // Recovery:Set recovered
+ case 7426: // Recovery:Create recovery
+ case 7427: // Recovery:Initiate recovery
+ case 7428: // Recovery:Vouch recovery
+ case 7429: // Recovery:Claim recovery
+ case 7430: // Recovery:Close recovery
+ case 7431: // Recovery:Remove recovery
+ case 7432: // Recovery:Cancel recovered
+ case 7680: // Utility:Batch
+ case 7681: // Utility:As derivative
+ case 7682: // Utility:Batch all
+ case 7937: // Proxy:Add proxy
+ case 7938: // Proxy:Remove proxy
+ case 7939: // Proxy:Remove proxies
+ case 7940: // Proxy:Anonymous
+ case 7941: // Proxy:Kill anonymous
+ case 7942: // Proxy:Announce
+ case 7943: // Proxy:Remove announcement
+ case 7944: // Proxy:Reject announcement
+ case 7945: // Proxy:Proxy announced
+ case 8448: // Contracts:Update schedule
+ case 8449: // Contracts:Call
+ case 8450: // Contracts:Instantiate with code
+ case 8451: // Contracts:Instantiate
+ case 8452: // Contracts:Claim surcharge
+ case 8704: // PkiTcr:Apply
+ case 8705: // PkiTcr:Counter
+ case 8706: // PkiTcr:Vote
+ case 8707: // PkiTcr:Challenge
+ case 8960: // PkiRootOfTrust:Book slot
+ case 8961: // PkiRootOfTrust:Renew slot
+ case 8962: // PkiRootOfTrust:Revoke slot
+ case 8963: // PkiRootOfTrust:Revoke child
+ case 9216: // EmergencyShutdown:Toggle
+ case 9472: // Allocations:Allocate
+ case 9728: // AllocationsOracles:Add member
+ case 9729: // AllocationsOracles:Remove member
+ case 9730: // AllocationsOracles:Swap member
+ case 9731: // AllocationsOracles:Reset members
+ case 9732: // AllocationsOracles:Change key
+ case 9733: // AllocationsOracles:Set prime
+ case 9734: // AllocationsOracles:Clear prime
+ return false;
+ default:
+ return true;
+ }
+}
diff --git a/app/src/substrate_dispatch_V3.h b/app/src/substrate_dispatch_V3.h
new file mode 100644
index 0000000..27d9d2e
--- /dev/null
+++ b/app/src/substrate_dispatch_V3.h
@@ -0,0 +1,49 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "parser_impl.h"
+#include "stdbool.h"
+#include "substrate_functions.h"
+#include "substrate_functions_V3.h"
+#include
+#include
+
+parser_error_t _readMethod_V3(parser_context_t* c, uint8_t moduleIdx, uint8_t callIdx, pd_Method_V3_t* method);
+
+const char* _getMethod_ModuleName_V3(uint8_t moduleIdx);
+
+const char* _getMethod_Name_V3(uint8_t moduleIdx, uint8_t callIdx);
+
+const char* _getMethod_ItemName_V3(uint8_t moduleIdx, uint8_t callIdx, uint8_t itemIdx);
+
+uint8_t _getMethod_NumItems_V3(uint8_t moduleIdx, uint8_t callIdx);
+
+parser_error_t _getMethod_ItemValue_V3(
+ pd_Method_V3_t* m, uint8_t moduleIdx, uint8_t callIdx, uint8_t itemIdx,
+ char* outValue, uint16_t outValueLen,
+ uint8_t pageIdx, uint8_t* pageCount);
+
+bool _getMethod_ItemIsExpert_V3(uint8_t moduleIdx, uint8_t callIdx, uint8_t itemIdx);
+bool _getMethod_IsNestingSupported_V3(uint8_t moduleIdx, uint8_t callIdx);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/app/src/substrate_functions.h b/app/src/substrate_functions.h
new file mode 100644
index 0000000..2562a63
--- /dev/null
+++ b/app/src/substrate_functions.h
@@ -0,0 +1,227 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include
+
+// Common read functions
+
+parser_error_t _readbool(parser_context_t* c, pd_bool_t* v);
+parser_error_t _readu8(parser_context_t* c, pd_u8_t* v);
+parser_error_t _readu16(parser_context_t* c, pd_u16_t* v);
+parser_error_t _readu32(parser_context_t* c, pd_u32_t* v);
+parser_error_t _readu64(parser_context_t* c, pd_u64_t* v);
+parser_error_t _readBlockNumber(parser_context_t* c, pd_BlockNumber_t* v);
+parser_error_t _readCompactu32(parser_context_t* c, pd_Compactu32_t* v);
+parser_error_t _readCompactu64(parser_context_t* c, pd_Compactu64_t* v);
+parser_error_t _readCallImpl(parser_context_t* c, pd_Call_t* v, pd_MethodNested_t* m);
+
+parser_error_t _readData(parser_context_t* c, pd_Data_t* v);
+parser_error_t _readTupleDataData(parser_context_t* c, pd_TupleDataData_t* v);
+parser_error_t _readu8_array_20(parser_context_t* c, pd_u8_array_20_t* v);
+parser_error_t _readBalance(parser_context_t* c, pd_Balance_t* v);
+parser_error_t _readBytes(parser_context_t* c, pd_Bytes_t* v);
+parser_error_t _readCall(parser_context_t* c, pd_Call_t* v);
+parser_error_t _readHeader(parser_context_t* c, pd_Header_t* v);
+parser_error_t _readOptionu8_array_20(parser_context_t* c, pd_Optionu8_array_20_t* v);
+parser_error_t _readVecTupleDataData(parser_context_t* c, pd_VecTupleDataData_t* v);
+parser_error_t _readBalanceOf(parser_context_t* c, pd_BalanceOf_t* v);
+parser_error_t _readProposal(parser_context_t* c, pd_Proposal_t* v);
+parser_error_t _readVecCall(parser_context_t* c, pd_VecCall_t* v);
+parser_error_t _readCompactBalanceOf(parser_context_t* c, pd_CompactBalanceOf_t* v);
+parser_error_t _readCompactBlockNumber(parser_context_t* c, pd_CompactBlockNumber_t* v);
+parser_error_t _readHash(parser_context_t* c, pd_Hash_t* v);
+parser_error_t _readHeartbeat(parser_context_t* c, pd_Heartbeat_t* v);
+parser_error_t _readVecHeader(parser_context_t* c, pd_VecHeader_t* v);
+
+// Common toString functions
+
+parser_error_t _toStringu8(
+ const pd_u8_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringu16(
+ const pd_u16_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringu32(
+ const pd_u32_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringu64(
+ const pd_u64_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringbool(
+ const pd_bool_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringBlockNumber(
+ const pd_BlockNumber_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringCompactu32(
+ const pd_Compactu32_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringData(
+ const pd_Data_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringTupleDataData(
+ const pd_TupleDataData_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringu8_array_20(
+ const pd_u8_array_20_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringBalance(
+ const pd_Balance_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringBytes(
+ const pd_Bytes_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringCall(
+ const pd_Call_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringHeader(
+ const pd_Header_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringOptionu8_array_20(
+ const pd_Optionu8_array_20_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringVecTupleDataData(
+ const pd_VecTupleDataData_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringBalanceOf(
+ const pd_BalanceOf_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringProposal(
+ const pd_Proposal_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringVecCall(
+ const pd_VecCall_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringCompactBalanceOf(
+ const pd_CompactBalanceOf_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringCompactBlockNumber(
+ const pd_CompactBlockNumber_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringHash(
+ const pd_Hash_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringHeartbeat(
+ const pd_Heartbeat_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringVecHeader(
+ const pd_VecHeader_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/app/src/substrate_functions_V3.h b/app/src/substrate_functions_V3.h
new file mode 100644
index 0000000..9d8f132
--- /dev/null
+++ b/app/src/substrate_functions_V3.h
@@ -0,0 +1,409 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "parser_common.h"
+#include "substrate_methods_V3.h"
+#include "substrate_types_V3.h"
+#include
+#include
+
+// Read functions
+parser_error_t _readAccountId_V3(parser_context_t* c, pd_AccountId_V3_t* v);
+parser_error_t _readAccountIndex_V3(parser_context_t* c, pd_AccountIndex_V3_t* v);
+parser_error_t _readAmendment_V3(parser_context_t* c, pd_Amendment_V3_t* v);
+parser_error_t _readBabeEquivocationProof_V3(parser_context_t* c, pd_BabeEquivocationProof_V3_t* v);
+parser_error_t _readCallHashOf_V3(parser_context_t* c, pd_CallHashOf_V3_t* v);
+parser_error_t _readCertificateId_V3(parser_context_t* c, pd_CertificateId_V3_t* v);
+parser_error_t _readChangesTrieConfiguration_V3(parser_context_t* c, pd_ChangesTrieConfiguration_V3_t* v);
+parser_error_t _readCodeHash_V3(parser_context_t* c, pd_CodeHash_V3_t* v);
+parser_error_t _readCompactAccountIndex_V3(parser_context_t* c, pd_CompactAccountIndex_V3_t* v);
+parser_error_t _readCompactMemberCount_V3(parser_context_t* c, pd_CompactMemberCount_V3_t* v);
+parser_error_t _readCompactMoment_V3(parser_context_t* c, pd_CompactMoment_V3_t* v);
+parser_error_t _readCompactProposalIndex_V3(parser_context_t* c, pd_CompactProposalIndex_V3_t* v);
+parser_error_t _readCompactRegistrarIndex_V3(parser_context_t* c, pd_CompactRegistrarIndex_V3_t* v);
+parser_error_t _readCompactWeight_V3(parser_context_t* c, pd_CompactWeight_V3_t* v);
+parser_error_t _readGrandpaEquivocationProof_V3(parser_context_t* c, pd_GrandpaEquivocationProof_V3_t* v);
+parser_error_t _readIdentityFields_V3(parser_context_t* c, pd_IdentityFields_V3_t* v);
+parser_error_t _readIdentityInfo_V3(parser_context_t* c, pd_IdentityInfo_V3_t* v);
+parser_error_t _readIdentityJudgement_V3(parser_context_t* c, pd_IdentityJudgement_V3_t* v);
+parser_error_t _readKeyOwnerProof_V3(parser_context_t* c, pd_KeyOwnerProof_V3_t* v);
+parser_error_t _readKeyValue_V3(parser_context_t* c, pd_KeyValue_V3_t* v);
+parser_error_t _readKey_V3(parser_context_t* c, pd_Key_V3_t* v);
+parser_error_t _readKeys_V3(parser_context_t* c, pd_Keys_V3_t* v);
+parser_error_t _readLookupSource_V3(parser_context_t* c, pd_LookupSource_V3_t* v);
+parser_error_t _readMemberCount_V3(parser_context_t* c, pd_MemberCount_V3_t* v);
+parser_error_t _readOpaqueCall_V3(parser_context_t* c, pd_OpaqueCall_V3_t* v);
+parser_error_t _readOptionAccountId_V3(parser_context_t* c, pd_OptionAccountId_V3_t* v);
+parser_error_t _readOptionChangesTrieConfiguration_V3(parser_context_t* c, pd_OptionChangesTrieConfiguration_V3_t* v);
+parser_error_t _readOptionPeriod_V3(parser_context_t* c, pd_OptionPeriod_V3_t* v);
+parser_error_t _readOptionProxyType_V3(parser_context_t* c, pd_OptionProxyType_V3_t* v);
+parser_error_t _readOptionTimepoint_V3(parser_context_t* c, pd_OptionTimepoint_V3_t* v);
+parser_error_t _readPerbill_V3(parser_context_t* c, pd_Perbill_V3_t* v);
+parser_error_t _readPeriod_V3(parser_context_t* c, pd_Period_V3_t* v);
+parser_error_t _readPriority_V3(parser_context_t* c, pd_Priority_V3_t* v);
+parser_error_t _readProxyType_V3(parser_context_t* c, pd_ProxyType_V3_t* v);
+parser_error_t _readRegistrarIndex_V3(parser_context_t* c, pd_RegistrarIndex_V3_t* v);
+parser_error_t _readSchedule_V3(parser_context_t* c, pd_Schedule_V3_t* v);
+parser_error_t _readSignature_V3(parser_context_t* c, pd_Signature_V3_t* v);
+parser_error_t _readStreamDependency_V3(parser_context_t* c, pd_StreamDependency_V3_t* v);
+parser_error_t _readTimepoint_V3(parser_context_t* c, pd_Timepoint_V3_t* v);
+parser_error_t _readTupleAccountIdData_V3(parser_context_t* c, pd_TupleAccountIdData_V3_t* v);
+parser_error_t _readVecAccountId_V3(parser_context_t* c, pd_VecAccountId_V3_t* v);
+parser_error_t _readVecKeyValue_V3(parser_context_t* c, pd_VecKeyValue_V3_t* v);
+parser_error_t _readVecKey_V3(parser_context_t* c, pd_VecKey_V3_t* v);
+parser_error_t _readVecTupleAccountIdData_V3(parser_context_t* c, pd_VecTupleAccountIdData_V3_t* v);
+parser_error_t _readVestingScheduleOf_V3(parser_context_t* c, pd_VestingScheduleOf_V3_t* v);
+parser_error_t _readWeight_V3(parser_context_t* c, pd_Weight_V3_t* v);
+parser_error_t _readu8_array_32_V3(parser_context_t* c, pd_u8_array_32_V3_t* v);
+
+// toString functions
+parser_error_t _toStringAccountId_V3(
+ const pd_AccountId_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringAccountIndex_V3(
+ const pd_AccountIndex_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringAmendment_V3(
+ const pd_Amendment_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringBabeEquivocationProof_V3(
+ const pd_BabeEquivocationProof_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringCallHashOf_V3(
+ const pd_CallHashOf_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringCertificateId_V3(
+ const pd_CertificateId_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringChangesTrieConfiguration_V3(
+ const pd_ChangesTrieConfiguration_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringCodeHash_V3(
+ const pd_CodeHash_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringCompactAccountIndex_V3(
+ const pd_CompactAccountIndex_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringCompactMemberCount_V3(
+ const pd_CompactMemberCount_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringCompactMoment_V3(
+ const pd_CompactMoment_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringCompactProposalIndex_V3(
+ const pd_CompactProposalIndex_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringCompactRegistrarIndex_V3(
+ const pd_CompactRegistrarIndex_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringCompactWeight_V3(
+ const pd_CompactWeight_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringGrandpaEquivocationProof_V3(
+ const pd_GrandpaEquivocationProof_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringIdentityFields_V3(
+ const pd_IdentityFields_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringIdentityInfo_V3(
+ const pd_IdentityInfo_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringIdentityJudgement_V3(
+ const pd_IdentityJudgement_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringKeyOwnerProof_V3(
+ const pd_KeyOwnerProof_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringKeyValue_V3(
+ const pd_KeyValue_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringKey_V3(
+ const pd_Key_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringKeys_V3(
+ const pd_Keys_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringLookupSource_V3(
+ const pd_LookupSource_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringMemberCount_V3(
+ const pd_MemberCount_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringOpaqueCall_V3(
+ const pd_OpaqueCall_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringOptionAccountId_V3(
+ const pd_OptionAccountId_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringOptionChangesTrieConfiguration_V3(
+ const pd_OptionChangesTrieConfiguration_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringOptionPeriod_V3(
+ const pd_OptionPeriod_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringOptionProxyType_V3(
+ const pd_OptionProxyType_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringOptionTimepoint_V3(
+ const pd_OptionTimepoint_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringPerbill_V3(
+ const pd_Perbill_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringPeriod_V3(
+ const pd_Period_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringPriority_V3(
+ const pd_Priority_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringProxyType_V3(
+ const pd_ProxyType_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringRegistrarIndex_V3(
+ const pd_RegistrarIndex_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringSchedule_V3(
+ const pd_Schedule_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringSignature_V3(
+ const pd_Signature_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringStreamDependency_V3(
+ const pd_StreamDependency_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringTimepoint_V3(
+ const pd_Timepoint_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringTupleAccountIdData_V3(
+ const pd_TupleAccountIdData_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringVecAccountId_V3(
+ const pd_VecAccountId_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringVecKeyValue_V3(
+ const pd_VecKeyValue_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringVecKey_V3(
+ const pd_VecKey_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringVecTupleAccountIdData_V3(
+ const pd_VecTupleAccountIdData_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringVestingScheduleOf_V3(
+ const pd_VestingScheduleOf_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringWeight_V3(
+ const pd_Weight_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+parser_error_t _toStringu8_array_32_V3(
+ const pd_u8_array_32_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/app/src/substrate_methods.h b/app/src/substrate_methods.h
new file mode 100644
index 0000000..d7c87c9
--- /dev/null
+++ b/app/src/substrate_methods.h
@@ -0,0 +1,42 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wextern-c-compat"
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include
+
+#define GET_PD_CALL(CALL, VERSION) (PD_CALL_##CALL##_V##VERSION)
+
+#include "substrate_methods_V3.h"
+#include "substrate_types_V3.h"
+
+typedef union {
+ pd_Method_V3_t V3;
+} pd_Method_t;
+
+typedef union {
+ pd_MethodNested_V3_t V3;
+} pd_MethodNested_t;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/app/src/substrate_methods_V3.h b/app/src/substrate_methods_V3.h
new file mode 100644
index 0000000..aae814e
--- /dev/null
+++ b/app/src/substrate_methods_V3.h
@@ -0,0 +1,1166 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wextern-c-compat"
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "substrate_types.h"
+#include "substrate_types_V3.h"
+#include
+#include
+
+#define PD_CALL_SYSTEM_V3 0
+#define PD_CALL_TIMESTAMP_V3 1
+#define PD_CALL_INDICES_V3 2
+#define PD_CALL_BALANCES_V3 3
+#define PD_CALL_RANDOMNESSCOLLECTIVEFLIP_V3 5
+#define PD_CALL_BABE_V3 6
+#define PD_CALL_GRANDPA_V3 7
+#define PD_CALL_AUTHORSHIP_V3 8
+#define PD_CALL_IMONLINE_V3 9
+#define PD_CALL_OFFENCES_V3 10
+#define PD_CALL_VALIDATORSSET_V3 11
+#define PD_CALL_SESSION_V3 12
+#define PD_CALL_AUTHORITYDISCOVERY_V3 14
+#define PD_CALL_TECHNICALCOMMITTEE_V3 15
+#define PD_CALL_TECHNICALMEMBERSHIP_V3 16
+#define PD_CALL_FINANCIALCOMMITTEE_V3 17
+#define PD_CALL_FINANCIALMEMBERSHIP_V3 18
+#define PD_CALL_ROOTCOMMITTEE_V3 19
+#define PD_CALL_ROOTMEMBERSHIP_V3 20
+#define PD_CALL_SCHEDULER_V3 21
+#define PD_CALL_AMENDMENTS_V3 22
+#define PD_CALL_MANDATE_V3 23
+#define PD_CALL_COMPANYRESERVE_V3 24
+#define PD_CALL_INTERNATIONALRESERVE_V3 25
+#define PD_CALL_USARESERVE_V3 26
+#define PD_CALL_VESTING_V3 27
+#define PD_CALL_IDENTITY_V3 28
+#define PD_CALL_RECOVERY_V3 29
+#define PD_CALL_UTILITY_V3 30
+#define PD_CALL_PROXY_V3 31
+#define PD_CALL_MULTISIG_V3 32
+#define PD_CALL_CONTRACTS_V3 33
+#define PD_CALL_PKITCR_V3 34
+#define PD_CALL_PKIROOTOFTRUST_V3 35
+#define PD_CALL_EMERGENCYSHUTDOWN_V3 36
+#define PD_CALL_ALLOCATIONS_V3 37
+#define PD_CALL_ALLOCATIONSORACLES_V3 38
+
+#define PD_CALL_SESSION_SET_KEYS_V3 0
+typedef struct {
+ pd_Keys_V3_t keys;
+ pd_Bytes_t proof;
+} pd_session_set_keys_V3_t;
+
+#define PD_CALL_SESSION_PURGE_KEYS_V3 1
+typedef struct {
+} pd_session_purge_keys_V3_t;
+
+#define PD_CALL_UTILITY_BATCH_V3 0
+typedef struct {
+ pd_VecCall_t calls;
+} pd_utility_batch_V3_t;
+
+#define PD_CALL_UTILITY_BATCH_ALL_V3 2
+typedef struct {
+ pd_VecCall_t calls;
+} pd_utility_batch_all_V3_t;
+
+#ifdef SUBSTRATE_PARSER_FULL
+#define PD_CALL_TIMESTAMP_SET_V3 0
+typedef struct {
+ pd_CompactMoment_V3_t now;
+} pd_timestamp_set_V3_t;
+
+#define PD_CALL_INDICES_CLAIM_V3 0
+typedef struct {
+ pd_AccountIndex_V3_t index;
+} pd_indices_claim_V3_t;
+
+#define PD_CALL_INDICES_TRANSFER_V3 1
+typedef struct {
+ pd_AccountId_V3_t new_;
+ pd_AccountIndex_V3_t index;
+} pd_indices_transfer_V3_t;
+
+#define PD_CALL_INDICES_FREE_V3 2
+typedef struct {
+ pd_AccountIndex_V3_t index;
+} pd_indices_free_V3_t;
+
+#define PD_CALL_INDICES_FORCE_TRANSFER_V3 3
+typedef struct {
+ pd_AccountId_V3_t new_;
+ pd_AccountIndex_V3_t index;
+ pd_bool_t freeze;
+} pd_indices_force_transfer_V3_t;
+
+#define PD_CALL_INDICES_FREEZE_V3 4
+typedef struct {
+ pd_AccountIndex_V3_t index;
+} pd_indices_freeze_V3_t;
+
+#define PD_CALL_BABE_REPORT_EQUIVOCATION_V3 0
+typedef struct {
+ pd_BabeEquivocationProof_V3_t equivocation_proof;
+ pd_KeyOwnerProof_V3_t key_owner_proof;
+} pd_babe_report_equivocation_V3_t;
+
+#define PD_CALL_BABE_REPORT_EQUIVOCATION_UNSIGNED_V3 1
+typedef struct {
+ pd_BabeEquivocationProof_V3_t equivocation_proof;
+ pd_KeyOwnerProof_V3_t key_owner_proof;
+} pd_babe_report_equivocation_unsigned_V3_t;
+
+#define PD_CALL_GRANDPA_REPORT_EQUIVOCATION_V3 0
+typedef struct {
+ pd_GrandpaEquivocationProof_V3_t equivocation_proof;
+ pd_KeyOwnerProof_V3_t key_owner_proof;
+} pd_grandpa_report_equivocation_V3_t;
+
+#define PD_CALL_GRANDPA_REPORT_EQUIVOCATION_UNSIGNED_V3 1
+typedef struct {
+ pd_GrandpaEquivocationProof_V3_t equivocation_proof;
+ pd_KeyOwnerProof_V3_t key_owner_proof;
+} pd_grandpa_report_equivocation_unsigned_V3_t;
+
+#define PD_CALL_GRANDPA_NOTE_STALLED_V3 2
+typedef struct {
+ pd_BlockNumber_t delay;
+ pd_BlockNumber_t best_finalized_block_number;
+} pd_grandpa_note_stalled_V3_t;
+
+#define PD_CALL_AUTHORSHIP_SET_UNCLES_V3 0
+typedef struct {
+ pd_VecHeader_t new_uncles;
+} pd_authorship_set_uncles_V3_t;
+
+#define PD_CALL_IMONLINE_HEARTBEAT_V3 0
+typedef struct {
+ pd_Heartbeat_t heartbeat;
+ pd_Signature_V3_t _signature;
+} pd_imonline_heartbeat_V3_t;
+
+#define PD_CALL_VALIDATORSSET_ADD_MEMBER_V3 0
+typedef struct {
+ pd_AccountId_V3_t who;
+} pd_validatorsset_add_member_V3_t;
+
+#define PD_CALL_VALIDATORSSET_REMOVE_MEMBER_V3 1
+typedef struct {
+ pd_AccountId_V3_t who;
+} pd_validatorsset_remove_member_V3_t;
+
+#define PD_CALL_VALIDATORSSET_SWAP_MEMBER_V3 2
+typedef struct {
+ pd_AccountId_V3_t remove;
+ pd_AccountId_V3_t add;
+} pd_validatorsset_swap_member_V3_t;
+
+#define PD_CALL_VALIDATORSSET_RESET_MEMBERS_V3 3
+typedef struct {
+ pd_VecAccountId_V3_t members;
+} pd_validatorsset_reset_members_V3_t;
+
+#define PD_CALL_VALIDATORSSET_CHANGE_KEY_V3 4
+typedef struct {
+ pd_AccountId_V3_t new_;
+} pd_validatorsset_change_key_V3_t;
+
+#define PD_CALL_VALIDATORSSET_SET_PRIME_V3 5
+typedef struct {
+ pd_AccountId_V3_t who;
+} pd_validatorsset_set_prime_V3_t;
+
+#define PD_CALL_VALIDATORSSET_CLEAR_PRIME_V3 6
+typedef struct {
+} pd_validatorsset_clear_prime_V3_t;
+
+#define PD_CALL_TECHNICALCOMMITTEE_SET_MEMBERS_V3 0
+typedef struct {
+ pd_VecAccountId_V3_t new_members;
+ pd_OptionAccountId_V3_t prime;
+ pd_MemberCount_V3_t old_count;
+} pd_technicalcommittee_set_members_V3_t;
+
+#define PD_CALL_TECHNICALCOMMITTEE_EXECUTE_V3 1
+typedef struct {
+ pd_Proposal_t proposal;
+ pd_Compactu32_t length_bound;
+} pd_technicalcommittee_execute_V3_t;
+
+#define PD_CALL_TECHNICALCOMMITTEE_PROPOSE_V3 2
+typedef struct {
+ pd_CompactMemberCount_V3_t threshold;
+ pd_Proposal_t proposal;
+ pd_Compactu32_t length_bound;
+} pd_technicalcommittee_propose_V3_t;
+
+#define PD_CALL_TECHNICALCOMMITTEE_VOTE_V3 3
+typedef struct {
+ pd_Hash_t proposal;
+ pd_CompactProposalIndex_V3_t index;
+ pd_bool_t approve;
+} pd_technicalcommittee_vote_V3_t;
+
+#define PD_CALL_TECHNICALCOMMITTEE_CLOSE_V3 4
+typedef struct {
+ pd_Hash_t proposal_hash;
+ pd_CompactProposalIndex_V3_t index;
+ pd_CompactWeight_V3_t proposal_weight_bound;
+ pd_Compactu32_t length_bound;
+} pd_technicalcommittee_close_V3_t;
+
+#define PD_CALL_TECHNICALCOMMITTEE_DISAPPROVE_PROPOSAL_V3 5
+typedef struct {
+ pd_Hash_t proposal_hash;
+} pd_technicalcommittee_disapprove_proposal_V3_t;
+
+#define PD_CALL_TECHNICALMEMBERSHIP_ADD_MEMBER_V3 0
+typedef struct {
+ pd_AccountId_V3_t who;
+} pd_technicalmembership_add_member_V3_t;
+
+#define PD_CALL_TECHNICALMEMBERSHIP_REMOVE_MEMBER_V3 1
+typedef struct {
+ pd_AccountId_V3_t who;
+} pd_technicalmembership_remove_member_V3_t;
+
+#define PD_CALL_TECHNICALMEMBERSHIP_SWAP_MEMBER_V3 2
+typedef struct {
+ pd_AccountId_V3_t remove;
+ pd_AccountId_V3_t add;
+} pd_technicalmembership_swap_member_V3_t;
+
+#define PD_CALL_TECHNICALMEMBERSHIP_RESET_MEMBERS_V3 3
+typedef struct {
+ pd_VecAccountId_V3_t members;
+} pd_technicalmembership_reset_members_V3_t;
+
+#define PD_CALL_TECHNICALMEMBERSHIP_CHANGE_KEY_V3 4
+typedef struct {
+ pd_AccountId_V3_t new_;
+} pd_technicalmembership_change_key_V3_t;
+
+#define PD_CALL_TECHNICALMEMBERSHIP_SET_PRIME_V3 5
+typedef struct {
+ pd_AccountId_V3_t who;
+} pd_technicalmembership_set_prime_V3_t;
+
+#define PD_CALL_TECHNICALMEMBERSHIP_CLEAR_PRIME_V3 6
+typedef struct {
+} pd_technicalmembership_clear_prime_V3_t;
+
+#define PD_CALL_FINANCIALCOMMITTEE_SET_MEMBERS_V3 0
+typedef struct {
+ pd_VecAccountId_V3_t new_members;
+ pd_OptionAccountId_V3_t prime;
+ pd_MemberCount_V3_t old_count;
+} pd_financialcommittee_set_members_V3_t;
+
+#define PD_CALL_FINANCIALCOMMITTEE_EXECUTE_V3 1
+typedef struct {
+ pd_Proposal_t proposal;
+ pd_Compactu32_t length_bound;
+} pd_financialcommittee_execute_V3_t;
+
+#define PD_CALL_FINANCIALCOMMITTEE_PROPOSE_V3 2
+typedef struct {
+ pd_CompactMemberCount_V3_t threshold;
+ pd_Proposal_t proposal;
+ pd_Compactu32_t length_bound;
+} pd_financialcommittee_propose_V3_t;
+
+#define PD_CALL_FINANCIALCOMMITTEE_VOTE_V3 3
+typedef struct {
+ pd_Hash_t proposal;
+ pd_CompactProposalIndex_V3_t index;
+ pd_bool_t approve;
+} pd_financialcommittee_vote_V3_t;
+
+#define PD_CALL_FINANCIALCOMMITTEE_CLOSE_V3 4
+typedef struct {
+ pd_Hash_t proposal_hash;
+ pd_CompactProposalIndex_V3_t index;
+ pd_CompactWeight_V3_t proposal_weight_bound;
+ pd_Compactu32_t length_bound;
+} pd_financialcommittee_close_V3_t;
+
+#define PD_CALL_FINANCIALCOMMITTEE_DISAPPROVE_PROPOSAL_V3 5
+typedef struct {
+ pd_Hash_t proposal_hash;
+} pd_financialcommittee_disapprove_proposal_V3_t;
+
+#define PD_CALL_FINANCIALMEMBERSHIP_ADD_MEMBER_V3 0
+typedef struct {
+ pd_AccountId_V3_t who;
+} pd_financialmembership_add_member_V3_t;
+
+#define PD_CALL_FINANCIALMEMBERSHIP_REMOVE_MEMBER_V3 1
+typedef struct {
+ pd_AccountId_V3_t who;
+} pd_financialmembership_remove_member_V3_t;
+
+#define PD_CALL_FINANCIALMEMBERSHIP_SWAP_MEMBER_V3 2
+typedef struct {
+ pd_AccountId_V3_t remove;
+ pd_AccountId_V3_t add;
+} pd_financialmembership_swap_member_V3_t;
+
+#define PD_CALL_FINANCIALMEMBERSHIP_RESET_MEMBERS_V3 3
+typedef struct {
+ pd_VecAccountId_V3_t members;
+} pd_financialmembership_reset_members_V3_t;
+
+#define PD_CALL_FINANCIALMEMBERSHIP_CHANGE_KEY_V3 4
+typedef struct {
+ pd_AccountId_V3_t new_;
+} pd_financialmembership_change_key_V3_t;
+
+#define PD_CALL_FINANCIALMEMBERSHIP_SET_PRIME_V3 5
+typedef struct {
+ pd_AccountId_V3_t who;
+} pd_financialmembership_set_prime_V3_t;
+
+#define PD_CALL_FINANCIALMEMBERSHIP_CLEAR_PRIME_V3 6
+typedef struct {
+} pd_financialmembership_clear_prime_V3_t;
+
+#define PD_CALL_ROOTCOMMITTEE_SET_MEMBERS_V3 0
+typedef struct {
+ pd_VecAccountId_V3_t new_members;
+ pd_OptionAccountId_V3_t prime;
+ pd_MemberCount_V3_t old_count;
+} pd_rootcommittee_set_members_V3_t;
+
+#define PD_CALL_ROOTCOMMITTEE_EXECUTE_V3 1
+typedef struct {
+ pd_Proposal_t proposal;
+ pd_Compactu32_t length_bound;
+} pd_rootcommittee_execute_V3_t;
+
+#define PD_CALL_ROOTCOMMITTEE_PROPOSE_V3 2
+typedef struct {
+ pd_CompactMemberCount_V3_t threshold;
+ pd_Proposal_t proposal;
+ pd_Compactu32_t length_bound;
+} pd_rootcommittee_propose_V3_t;
+
+#define PD_CALL_ROOTCOMMITTEE_VOTE_V3 3
+typedef struct {
+ pd_Hash_t proposal;
+ pd_CompactProposalIndex_V3_t index;
+ pd_bool_t approve;
+} pd_rootcommittee_vote_V3_t;
+
+#define PD_CALL_ROOTCOMMITTEE_CLOSE_V3 4
+typedef struct {
+ pd_Hash_t proposal_hash;
+ pd_CompactProposalIndex_V3_t index;
+ pd_CompactWeight_V3_t proposal_weight_bound;
+ pd_Compactu32_t length_bound;
+} pd_rootcommittee_close_V3_t;
+
+#define PD_CALL_ROOTCOMMITTEE_DISAPPROVE_PROPOSAL_V3 5
+typedef struct {
+ pd_Hash_t proposal_hash;
+} pd_rootcommittee_disapprove_proposal_V3_t;
+
+#define PD_CALL_ROOTMEMBERSHIP_ADD_MEMBER_V3 0
+typedef struct {
+ pd_AccountId_V3_t who;
+} pd_rootmembership_add_member_V3_t;
+
+#define PD_CALL_ROOTMEMBERSHIP_REMOVE_MEMBER_V3 1
+typedef struct {
+ pd_AccountId_V3_t who;
+} pd_rootmembership_remove_member_V3_t;
+
+#define PD_CALL_ROOTMEMBERSHIP_SWAP_MEMBER_V3 2
+typedef struct {
+ pd_AccountId_V3_t remove;
+ pd_AccountId_V3_t add;
+} pd_rootmembership_swap_member_V3_t;
+
+#define PD_CALL_ROOTMEMBERSHIP_RESET_MEMBERS_V3 3
+typedef struct {
+ pd_VecAccountId_V3_t members;
+} pd_rootmembership_reset_members_V3_t;
+
+#define PD_CALL_ROOTMEMBERSHIP_CHANGE_KEY_V3 4
+typedef struct {
+ pd_AccountId_V3_t new_;
+} pd_rootmembership_change_key_V3_t;
+
+#define PD_CALL_ROOTMEMBERSHIP_SET_PRIME_V3 5
+typedef struct {
+ pd_AccountId_V3_t who;
+} pd_rootmembership_set_prime_V3_t;
+
+#define PD_CALL_ROOTMEMBERSHIP_CLEAR_PRIME_V3 6
+typedef struct {
+} pd_rootmembership_clear_prime_V3_t;
+
+#define PD_CALL_SCHEDULER_SCHEDULE_V3 0
+typedef struct {
+ pd_BlockNumber_t when;
+ pd_OptionPeriod_V3_t maybe_periodic;
+ pd_Priority_V3_t priority;
+ pd_Call_t call;
+} pd_scheduler_schedule_V3_t;
+
+#define PD_CALL_SCHEDULER_CANCEL_V3 1
+typedef struct {
+ pd_BlockNumber_t when;
+ pd_u32_t index;
+} pd_scheduler_cancel_V3_t;
+
+#define PD_CALL_SCHEDULER_SCHEDULE_NAMED_V3 2
+typedef struct {
+ pd_Bytes_t id;
+ pd_BlockNumber_t when;
+ pd_OptionPeriod_V3_t maybe_periodic;
+ pd_Priority_V3_t priority;
+ pd_Call_t call;
+} pd_scheduler_schedule_named_V3_t;
+
+#define PD_CALL_SCHEDULER_CANCEL_NAMED_V3 3
+typedef struct {
+ pd_Bytes_t id;
+} pd_scheduler_cancel_named_V3_t;
+
+#define PD_CALL_SCHEDULER_SCHEDULE_AFTER_V3 4
+typedef struct {
+ pd_BlockNumber_t after;
+ pd_OptionPeriod_V3_t maybe_periodic;
+ pd_Priority_V3_t priority;
+ pd_Call_t call;
+} pd_scheduler_schedule_after_V3_t;
+
+#define PD_CALL_SCHEDULER_SCHEDULE_NAMED_AFTER_V3 5
+typedef struct {
+ pd_Bytes_t id;
+ pd_BlockNumber_t after;
+ pd_OptionPeriod_V3_t maybe_periodic;
+ pd_Priority_V3_t priority;
+ pd_Call_t call;
+} pd_scheduler_schedule_named_after_V3_t;
+
+#define PD_CALL_AMENDMENTS_PROPOSE_V3 0
+typedef struct {
+ pd_Amendment_V3_t amendment;
+} pd_amendments_propose_V3_t;
+
+#define PD_CALL_AMENDMENTS_VETO_V3 1
+typedef struct {
+ pd_u64_t amendment_id;
+} pd_amendments_veto_V3_t;
+
+#define PD_CALL_MANDATE_APPLY_V3 0
+typedef struct {
+ pd_Call_t call;
+} pd_mandate_apply_V3_t;
+
+#define PD_CALL_COMPANYRESERVE_SPEND_V3 0
+typedef struct {
+ pd_AccountId_V3_t to;
+ pd_BalanceOf_t amount;
+} pd_companyreserve_spend_V3_t;
+
+#define PD_CALL_COMPANYRESERVE_TIP_V3 1
+typedef struct {
+ pd_BalanceOf_t amount;
+} pd_companyreserve_tip_V3_t;
+
+#define PD_CALL_COMPANYRESERVE_APPLY_AS_V3 2
+typedef struct {
+ pd_Call_t call;
+} pd_companyreserve_apply_as_V3_t;
+
+#define PD_CALL_INTERNATIONALRESERVE_SPEND_V3 0
+typedef struct {
+ pd_AccountId_V3_t to;
+ pd_BalanceOf_t amount;
+} pd_internationalreserve_spend_V3_t;
+
+#define PD_CALL_INTERNATIONALRESERVE_TIP_V3 1
+typedef struct {
+ pd_BalanceOf_t amount;
+} pd_internationalreserve_tip_V3_t;
+
+#define PD_CALL_INTERNATIONALRESERVE_APPLY_AS_V3 2
+typedef struct {
+ pd_Call_t call;
+} pd_internationalreserve_apply_as_V3_t;
+
+#define PD_CALL_USARESERVE_SPEND_V3 0
+typedef struct {
+ pd_AccountId_V3_t to;
+ pd_BalanceOf_t amount;
+} pd_usareserve_spend_V3_t;
+
+#define PD_CALL_USARESERVE_TIP_V3 1
+typedef struct {
+ pd_BalanceOf_t amount;
+} pd_usareserve_tip_V3_t;
+
+#define PD_CALL_USARESERVE_APPLY_AS_V3 2
+typedef struct {
+ pd_Call_t call;
+} pd_usareserve_apply_as_V3_t;
+
+#define PD_CALL_VESTING_CLAIM_V3 0
+typedef struct {
+} pd_vesting_claim_V3_t;
+
+#define PD_CALL_VESTING_ADD_VESTING_SCHEDULE_V3 1
+typedef struct {
+ pd_LookupSource_V3_t dest;
+ pd_VestingScheduleOf_V3_t schedule;
+} pd_vesting_add_vesting_schedule_V3_t;
+
+#define PD_CALL_VESTING_CANCEL_ALL_VESTING_SCHEDULES_V3 2
+typedef struct {
+ pd_LookupSource_V3_t who;
+ pd_LookupSource_V3_t funds_collector;
+ pd_bool_t limit_to_free_balance;
+} pd_vesting_cancel_all_vesting_schedules_V3_t;
+
+#define PD_CALL_IDENTITY_ADD_REGISTRAR_V3 0
+typedef struct {
+ pd_AccountId_V3_t account;
+} pd_identity_add_registrar_V3_t;
+
+#define PD_CALL_IDENTITY_SET_IDENTITY_V3 1
+typedef struct {
+ pd_IdentityInfo_V3_t info;
+} pd_identity_set_identity_V3_t;
+
+#define PD_CALL_IDENTITY_SET_SUBS_V3 2
+typedef struct {
+ pd_VecTupleAccountIdData_V3_t subs;
+} pd_identity_set_subs_V3_t;
+
+#define PD_CALL_IDENTITY_CLEAR_IDENTITY_V3 3
+typedef struct {
+} pd_identity_clear_identity_V3_t;
+
+#define PD_CALL_IDENTITY_REQUEST_JUDGEMENT_V3 4
+typedef struct {
+ pd_CompactRegistrarIndex_V3_t reg_index;
+ pd_CompactBalanceOf_t max_fee;
+} pd_identity_request_judgement_V3_t;
+
+#define PD_CALL_IDENTITY_CANCEL_REQUEST_V3 5
+typedef struct {
+ pd_RegistrarIndex_V3_t reg_index;
+} pd_identity_cancel_request_V3_t;
+
+#define PD_CALL_IDENTITY_SET_FEE_V3 6
+typedef struct {
+ pd_CompactRegistrarIndex_V3_t index;
+ pd_CompactBalanceOf_t fee;
+} pd_identity_set_fee_V3_t;
+
+#define PD_CALL_IDENTITY_SET_ACCOUNT_ID_V3 7
+typedef struct {
+ pd_CompactRegistrarIndex_V3_t index;
+ pd_AccountId_V3_t new_;
+} pd_identity_set_account_id_V3_t;
+
+#define PD_CALL_IDENTITY_SET_FIELDS_V3 8
+typedef struct {
+ pd_CompactRegistrarIndex_V3_t index;
+ pd_IdentityFields_V3_t fields;
+} pd_identity_set_fields_V3_t;
+
+#define PD_CALL_IDENTITY_PROVIDE_JUDGEMENT_V3 9
+typedef struct {
+ pd_CompactRegistrarIndex_V3_t reg_index;
+ pd_LookupSource_V3_t target;
+ pd_IdentityJudgement_V3_t judgement;
+} pd_identity_provide_judgement_V3_t;
+
+#define PD_CALL_IDENTITY_KILL_IDENTITY_V3 10
+typedef struct {
+ pd_LookupSource_V3_t target;
+} pd_identity_kill_identity_V3_t;
+
+#define PD_CALL_IDENTITY_ADD_SUB_V3 11
+typedef struct {
+ pd_LookupSource_V3_t sub;
+ pd_Data_t data;
+} pd_identity_add_sub_V3_t;
+
+#define PD_CALL_IDENTITY_RENAME_SUB_V3 12
+typedef struct {
+ pd_LookupSource_V3_t sub;
+ pd_Data_t data;
+} pd_identity_rename_sub_V3_t;
+
+#define PD_CALL_IDENTITY_REMOVE_SUB_V3 13
+typedef struct {
+ pd_LookupSource_V3_t sub;
+} pd_identity_remove_sub_V3_t;
+
+#define PD_CALL_IDENTITY_QUIT_SUB_V3 14
+typedef struct {
+} pd_identity_quit_sub_V3_t;
+
+#define PD_CALL_RECOVERY_AS_RECOVERED_V3 0
+typedef struct {
+ pd_AccountId_V3_t account;
+ pd_Call_t call;
+} pd_recovery_as_recovered_V3_t;
+
+#define PD_CALL_RECOVERY_SET_RECOVERED_V3 1
+typedef struct {
+ pd_AccountId_V3_t lost;
+ pd_AccountId_V3_t rescuer;
+} pd_recovery_set_recovered_V3_t;
+
+#define PD_CALL_RECOVERY_CREATE_RECOVERY_V3 2
+typedef struct {
+ pd_VecAccountId_V3_t friends;
+ pd_u16_t threshold;
+ pd_BlockNumber_t delay_period;
+} pd_recovery_create_recovery_V3_t;
+
+#define PD_CALL_RECOVERY_INITIATE_RECOVERY_V3 3
+typedef struct {
+ pd_AccountId_V3_t account;
+} pd_recovery_initiate_recovery_V3_t;
+
+#define PD_CALL_RECOVERY_VOUCH_RECOVERY_V3 4
+typedef struct {
+ pd_AccountId_V3_t lost;
+ pd_AccountId_V3_t rescuer;
+} pd_recovery_vouch_recovery_V3_t;
+
+#define PD_CALL_RECOVERY_CLAIM_RECOVERY_V3 5
+typedef struct {
+ pd_AccountId_V3_t account;
+} pd_recovery_claim_recovery_V3_t;
+
+#define PD_CALL_RECOVERY_CLOSE_RECOVERY_V3 6
+typedef struct {
+ pd_AccountId_V3_t rescuer;
+} pd_recovery_close_recovery_V3_t;
+
+#define PD_CALL_RECOVERY_REMOVE_RECOVERY_V3 7
+typedef struct {
+} pd_recovery_remove_recovery_V3_t;
+
+#define PD_CALL_RECOVERY_CANCEL_RECOVERED_V3 8
+typedef struct {
+ pd_AccountId_V3_t account;
+} pd_recovery_cancel_recovered_V3_t;
+
+#define PD_CALL_UTILITY_AS_DERIVATIVE_V3 1
+typedef struct {
+ pd_u16_t index;
+ pd_Call_t call;
+} pd_utility_as_derivative_V3_t;
+
+#define PD_CALL_PROXY_ADD_PROXY_V3 1
+typedef struct {
+ pd_AccountId_V3_t delegate;
+ pd_ProxyType_V3_t proxy_type;
+ pd_BlockNumber_t delay;
+} pd_proxy_add_proxy_V3_t;
+
+#define PD_CALL_PROXY_REMOVE_PROXY_V3 2
+typedef struct {
+ pd_AccountId_V3_t delegate;
+ pd_ProxyType_V3_t proxy_type;
+ pd_BlockNumber_t delay;
+} pd_proxy_remove_proxy_V3_t;
+
+#define PD_CALL_PROXY_REMOVE_PROXIES_V3 3
+typedef struct {
+} pd_proxy_remove_proxies_V3_t;
+
+#define PD_CALL_PROXY_ANONYMOUS_V3 4
+typedef struct {
+ pd_ProxyType_V3_t proxy_type;
+ pd_BlockNumber_t delay;
+ pd_u16_t index;
+} pd_proxy_anonymous_V3_t;
+
+#define PD_CALL_PROXY_KILL_ANONYMOUS_V3 5
+typedef struct {
+ pd_AccountId_V3_t spawner;
+ pd_ProxyType_V3_t proxy_type;
+ pd_u16_t index;
+ pd_CompactBlockNumber_t height;
+ pd_Compactu32_t ext_index;
+} pd_proxy_kill_anonymous_V3_t;
+
+#define PD_CALL_PROXY_ANNOUNCE_V3 6
+typedef struct {
+ pd_AccountId_V3_t real;
+ pd_CallHashOf_V3_t call_hash;
+} pd_proxy_announce_V3_t;
+
+#define PD_CALL_PROXY_REMOVE_ANNOUNCEMENT_V3 7
+typedef struct {
+ pd_AccountId_V3_t real;
+ pd_CallHashOf_V3_t call_hash;
+} pd_proxy_remove_announcement_V3_t;
+
+#define PD_CALL_PROXY_REJECT_ANNOUNCEMENT_V3 8
+typedef struct {
+ pd_AccountId_V3_t delegate;
+ pd_CallHashOf_V3_t call_hash;
+} pd_proxy_reject_announcement_V3_t;
+
+#define PD_CALL_PROXY_PROXY_ANNOUNCED_V3 9
+typedef struct {
+ pd_AccountId_V3_t delegate;
+ pd_AccountId_V3_t real;
+ pd_OptionProxyType_V3_t force_proxy_type;
+ pd_Call_t call;
+} pd_proxy_proxy_announced_V3_t;
+
+#define PD_CALL_CONTRACTS_UPDATE_SCHEDULE_V3 0
+typedef struct {
+ pd_Schedule_V3_t schedule;
+} pd_contracts_update_schedule_V3_t;
+
+#define PD_CALL_CONTRACTS_CALL_V3 1
+typedef struct {
+ pd_LookupSource_V3_t dest;
+ pd_CompactBalanceOf_t value;
+ pd_CompactWeight_V3_t gas_limit;
+ pd_Bytes_t data;
+} pd_contracts_call_V3_t;
+
+#define PD_CALL_CONTRACTS_INSTANTIATE_WITH_CODE_V3 2
+typedef struct {
+ pd_CompactBalanceOf_t endowment;
+ pd_CompactWeight_V3_t gas_limit;
+ pd_Bytes_t code;
+ pd_Bytes_t data;
+ pd_Bytes_t salt;
+} pd_contracts_instantiate_with_code_V3_t;
+
+#define PD_CALL_CONTRACTS_INSTANTIATE_V3 3
+typedef struct {
+ pd_CompactBalanceOf_t endowment;
+ pd_CompactWeight_V3_t gas_limit;
+ pd_CodeHash_V3_t code_hash;
+ pd_Bytes_t data;
+ pd_Bytes_t salt;
+} pd_contracts_instantiate_V3_t;
+
+#define PD_CALL_CONTRACTS_CLAIM_SURCHARGE_V3 4
+typedef struct {
+ pd_AccountId_V3_t dest;
+ pd_OptionAccountId_V3_t aux_sender;
+} pd_contracts_claim_surcharge_V3_t;
+
+#define PD_CALL_PKITCR_APPLY_V3 0
+typedef struct {
+ pd_Bytes_t metadata;
+ pd_BalanceOf_t deposit;
+} pd_pkitcr_apply_V3_t;
+
+#define PD_CALL_PKITCR_COUNTER_V3 1
+typedef struct {
+ pd_AccountId_V3_t member;
+ pd_BalanceOf_t deposit;
+} pd_pkitcr_counter_V3_t;
+
+#define PD_CALL_PKITCR_VOTE_V3 2
+typedef struct {
+ pd_AccountId_V3_t member;
+ pd_bool_t supporting;
+ pd_BalanceOf_t deposit;
+} pd_pkitcr_vote_V3_t;
+
+#define PD_CALL_PKITCR_CHALLENGE_V3 3
+typedef struct {
+ pd_AccountId_V3_t member;
+ pd_BalanceOf_t deposit;
+} pd_pkitcr_challenge_V3_t;
+
+#define PD_CALL_PKIROOTOFTRUST_BOOK_SLOT_V3 0
+typedef struct {
+ pd_CertificateId_V3_t certificate_id;
+} pd_pkirootoftrust_book_slot_V3_t;
+
+#define PD_CALL_PKIROOTOFTRUST_RENEW_SLOT_V3 1
+typedef struct {
+ pd_CertificateId_V3_t certificate_id;
+} pd_pkirootoftrust_renew_slot_V3_t;
+
+#define PD_CALL_PKIROOTOFTRUST_REVOKE_SLOT_V3 2
+typedef struct {
+ pd_CertificateId_V3_t certificate_id;
+} pd_pkirootoftrust_revoke_slot_V3_t;
+
+#define PD_CALL_PKIROOTOFTRUST_REVOKE_CHILD_V3 3
+typedef struct {
+ pd_CertificateId_V3_t root;
+ pd_CertificateId_V3_t child;
+} pd_pkirootoftrust_revoke_child_V3_t;
+
+#define PD_CALL_EMERGENCYSHUTDOWN_TOGGLE_V3 0
+typedef struct {
+} pd_emergencyshutdown_toggle_V3_t;
+
+#define PD_CALL_ALLOCATIONS_ALLOCATE_V3 0
+typedef struct {
+ pd_AccountId_V3_t to;
+ pd_BalanceOf_t amount;
+ pd_Bytes_t proof;
+} pd_allocations_allocate_V3_t;
+
+#define PD_CALL_ALLOCATIONSORACLES_ADD_MEMBER_V3 0
+typedef struct {
+ pd_AccountId_V3_t who;
+} pd_allocationsoracles_add_member_V3_t;
+
+#define PD_CALL_ALLOCATIONSORACLES_REMOVE_MEMBER_V3 1
+typedef struct {
+ pd_AccountId_V3_t who;
+} pd_allocationsoracles_remove_member_V3_t;
+
+#define PD_CALL_ALLOCATIONSORACLES_SWAP_MEMBER_V3 2
+typedef struct {
+ pd_AccountId_V3_t remove;
+ pd_AccountId_V3_t add;
+} pd_allocationsoracles_swap_member_V3_t;
+
+#define PD_CALL_ALLOCATIONSORACLES_RESET_MEMBERS_V3 3
+typedef struct {
+ pd_VecAccountId_V3_t members;
+} pd_allocationsoracles_reset_members_V3_t;
+
+#define PD_CALL_ALLOCATIONSORACLES_CHANGE_KEY_V3 4
+typedef struct {
+ pd_AccountId_V3_t new_;
+} pd_allocationsoracles_change_key_V3_t;
+
+#define PD_CALL_ALLOCATIONSORACLES_SET_PRIME_V3 5
+typedef struct {
+ pd_AccountId_V3_t who;
+} pd_allocationsoracles_set_prime_V3_t;
+
+#define PD_CALL_ALLOCATIONSORACLES_CLEAR_PRIME_V3 6
+typedef struct {
+} pd_allocationsoracles_clear_prime_V3_t;
+
+#endif
+
+typedef union {
+ pd_session_set_keys_V3_t session_set_keys_V3;
+ pd_session_purge_keys_V3_t session_purge_keys_V3;
+ pd_utility_batch_V3_t utility_batch_V3;
+ pd_utility_batch_all_V3_t utility_batch_all_V3;
+#ifdef SUBSTRATE_PARSER_FULL
+ pd_timestamp_set_V3_t timestamp_set_V3;
+ pd_indices_claim_V3_t indices_claim_V3;
+ pd_indices_transfer_V3_t indices_transfer_V3;
+ pd_indices_free_V3_t indices_free_V3;
+ pd_indices_force_transfer_V3_t indices_force_transfer_V3;
+ pd_indices_freeze_V3_t indices_freeze_V3;
+ pd_babe_report_equivocation_V3_t babe_report_equivocation_V3;
+ pd_babe_report_equivocation_unsigned_V3_t babe_report_equivocation_unsigned_V3;
+ pd_grandpa_report_equivocation_V3_t grandpa_report_equivocation_V3;
+ pd_grandpa_report_equivocation_unsigned_V3_t grandpa_report_equivocation_unsigned_V3;
+ pd_grandpa_note_stalled_V3_t grandpa_note_stalled_V3;
+ pd_authorship_set_uncles_V3_t authorship_set_uncles_V3;
+ pd_imonline_heartbeat_V3_t imonline_heartbeat_V3;
+ pd_validatorsset_add_member_V3_t validatorsset_add_member_V3;
+ pd_validatorsset_remove_member_V3_t validatorsset_remove_member_V3;
+ pd_validatorsset_swap_member_V3_t validatorsset_swap_member_V3;
+ pd_validatorsset_reset_members_V3_t validatorsset_reset_members_V3;
+ pd_validatorsset_change_key_V3_t validatorsset_change_key_V3;
+ pd_validatorsset_set_prime_V3_t validatorsset_set_prime_V3;
+ pd_validatorsset_clear_prime_V3_t validatorsset_clear_prime_V3;
+ pd_technicalcommittee_set_members_V3_t technicalcommittee_set_members_V3;
+ pd_technicalcommittee_execute_V3_t technicalcommittee_execute_V3;
+ pd_technicalcommittee_propose_V3_t technicalcommittee_propose_V3;
+ pd_technicalcommittee_vote_V3_t technicalcommittee_vote_V3;
+ pd_technicalcommittee_close_V3_t technicalcommittee_close_V3;
+ pd_technicalcommittee_disapprove_proposal_V3_t technicalcommittee_disapprove_proposal_V3;
+ pd_technicalmembership_add_member_V3_t technicalmembership_add_member_V3;
+ pd_technicalmembership_remove_member_V3_t technicalmembership_remove_member_V3;
+ pd_technicalmembership_swap_member_V3_t technicalmembership_swap_member_V3;
+ pd_technicalmembership_reset_members_V3_t technicalmembership_reset_members_V3;
+ pd_technicalmembership_change_key_V3_t technicalmembership_change_key_V3;
+ pd_technicalmembership_set_prime_V3_t technicalmembership_set_prime_V3;
+ pd_technicalmembership_clear_prime_V3_t technicalmembership_clear_prime_V3;
+ pd_financialcommittee_set_members_V3_t financialcommittee_set_members_V3;
+ pd_financialcommittee_execute_V3_t financialcommittee_execute_V3;
+ pd_financialcommittee_propose_V3_t financialcommittee_propose_V3;
+ pd_financialcommittee_vote_V3_t financialcommittee_vote_V3;
+ pd_financialcommittee_close_V3_t financialcommittee_close_V3;
+ pd_financialcommittee_disapprove_proposal_V3_t financialcommittee_disapprove_proposal_V3;
+ pd_financialmembership_add_member_V3_t financialmembership_add_member_V3;
+ pd_financialmembership_remove_member_V3_t financialmembership_remove_member_V3;
+ pd_financialmembership_swap_member_V3_t financialmembership_swap_member_V3;
+ pd_financialmembership_reset_members_V3_t financialmembership_reset_members_V3;
+ pd_financialmembership_change_key_V3_t financialmembership_change_key_V3;
+ pd_financialmembership_set_prime_V3_t financialmembership_set_prime_V3;
+ pd_financialmembership_clear_prime_V3_t financialmembership_clear_prime_V3;
+ pd_rootcommittee_set_members_V3_t rootcommittee_set_members_V3;
+ pd_rootcommittee_execute_V3_t rootcommittee_execute_V3;
+ pd_rootcommittee_propose_V3_t rootcommittee_propose_V3;
+ pd_rootcommittee_vote_V3_t rootcommittee_vote_V3;
+ pd_rootcommittee_close_V3_t rootcommittee_close_V3;
+ pd_rootcommittee_disapprove_proposal_V3_t rootcommittee_disapprove_proposal_V3;
+ pd_rootmembership_add_member_V3_t rootmembership_add_member_V3;
+ pd_rootmembership_remove_member_V3_t rootmembership_remove_member_V3;
+ pd_rootmembership_swap_member_V3_t rootmembership_swap_member_V3;
+ pd_rootmembership_reset_members_V3_t rootmembership_reset_members_V3;
+ pd_rootmembership_change_key_V3_t rootmembership_change_key_V3;
+ pd_rootmembership_set_prime_V3_t rootmembership_set_prime_V3;
+ pd_rootmembership_clear_prime_V3_t rootmembership_clear_prime_V3;
+ pd_scheduler_schedule_V3_t scheduler_schedule_V3;
+ pd_scheduler_cancel_V3_t scheduler_cancel_V3;
+ pd_scheduler_schedule_named_V3_t scheduler_schedule_named_V3;
+ pd_scheduler_cancel_named_V3_t scheduler_cancel_named_V3;
+ pd_scheduler_schedule_after_V3_t scheduler_schedule_after_V3;
+ pd_scheduler_schedule_named_after_V3_t scheduler_schedule_named_after_V3;
+ pd_amendments_propose_V3_t amendments_propose_V3;
+ pd_amendments_veto_V3_t amendments_veto_V3;
+ pd_mandate_apply_V3_t mandate_apply_V3;
+ pd_companyreserve_spend_V3_t companyreserve_spend_V3;
+ pd_companyreserve_tip_V3_t companyreserve_tip_V3;
+ pd_companyreserve_apply_as_V3_t companyreserve_apply_as_V3;
+ pd_internationalreserve_spend_V3_t internationalreserve_spend_V3;
+ pd_internationalreserve_tip_V3_t internationalreserve_tip_V3;
+ pd_internationalreserve_apply_as_V3_t internationalreserve_apply_as_V3;
+ pd_usareserve_spend_V3_t usareserve_spend_V3;
+ pd_usareserve_tip_V3_t usareserve_tip_V3;
+ pd_usareserve_apply_as_V3_t usareserve_apply_as_V3;
+ pd_vesting_claim_V3_t vesting_claim_V3;
+ pd_vesting_add_vesting_schedule_V3_t vesting_add_vesting_schedule_V3;
+ pd_vesting_cancel_all_vesting_schedules_V3_t vesting_cancel_all_vesting_schedules_V3;
+ pd_identity_add_registrar_V3_t identity_add_registrar_V3;
+ pd_identity_set_identity_V3_t identity_set_identity_V3;
+ pd_identity_set_subs_V3_t identity_set_subs_V3;
+ pd_identity_clear_identity_V3_t identity_clear_identity_V3;
+ pd_identity_request_judgement_V3_t identity_request_judgement_V3;
+ pd_identity_cancel_request_V3_t identity_cancel_request_V3;
+ pd_identity_set_fee_V3_t identity_set_fee_V3;
+ pd_identity_set_account_id_V3_t identity_set_account_id_V3;
+ pd_identity_set_fields_V3_t identity_set_fields_V3;
+ pd_identity_provide_judgement_V3_t identity_provide_judgement_V3;
+ pd_identity_kill_identity_V3_t identity_kill_identity_V3;
+ pd_identity_add_sub_V3_t identity_add_sub_V3;
+ pd_identity_rename_sub_V3_t identity_rename_sub_V3;
+ pd_identity_remove_sub_V3_t identity_remove_sub_V3;
+ pd_identity_quit_sub_V3_t identity_quit_sub_V3;
+ pd_recovery_as_recovered_V3_t recovery_as_recovered_V3;
+ pd_recovery_set_recovered_V3_t recovery_set_recovered_V3;
+ pd_recovery_create_recovery_V3_t recovery_create_recovery_V3;
+ pd_recovery_initiate_recovery_V3_t recovery_initiate_recovery_V3;
+ pd_recovery_vouch_recovery_V3_t recovery_vouch_recovery_V3;
+ pd_recovery_claim_recovery_V3_t recovery_claim_recovery_V3;
+ pd_recovery_close_recovery_V3_t recovery_close_recovery_V3;
+ pd_recovery_remove_recovery_V3_t recovery_remove_recovery_V3;
+ pd_recovery_cancel_recovered_V3_t recovery_cancel_recovered_V3;
+ pd_utility_as_derivative_V3_t utility_as_derivative_V3;
+ pd_proxy_add_proxy_V3_t proxy_add_proxy_V3;
+ pd_proxy_remove_proxy_V3_t proxy_remove_proxy_V3;
+ pd_proxy_remove_proxies_V3_t proxy_remove_proxies_V3;
+ pd_proxy_anonymous_V3_t proxy_anonymous_V3;
+ pd_proxy_kill_anonymous_V3_t proxy_kill_anonymous_V3;
+ pd_proxy_announce_V3_t proxy_announce_V3;
+ pd_proxy_remove_announcement_V3_t proxy_remove_announcement_V3;
+ pd_proxy_reject_announcement_V3_t proxy_reject_announcement_V3;
+ pd_proxy_proxy_announced_V3_t proxy_proxy_announced_V3;
+ pd_contracts_update_schedule_V3_t contracts_update_schedule_V3;
+ pd_contracts_call_V3_t contracts_call_V3;
+ pd_contracts_instantiate_with_code_V3_t contracts_instantiate_with_code_V3;
+ pd_contracts_instantiate_V3_t contracts_instantiate_V3;
+ pd_contracts_claim_surcharge_V3_t contracts_claim_surcharge_V3;
+ pd_pkitcr_apply_V3_t pkitcr_apply_V3;
+ pd_pkitcr_counter_V3_t pkitcr_counter_V3;
+ pd_pkitcr_vote_V3_t pkitcr_vote_V3;
+ pd_pkitcr_challenge_V3_t pkitcr_challenge_V3;
+ pd_pkirootoftrust_book_slot_V3_t pkirootoftrust_book_slot_V3;
+ pd_pkirootoftrust_renew_slot_V3_t pkirootoftrust_renew_slot_V3;
+ pd_pkirootoftrust_revoke_slot_V3_t pkirootoftrust_revoke_slot_V3;
+ pd_pkirootoftrust_revoke_child_V3_t pkirootoftrust_revoke_child_V3;
+ pd_emergencyshutdown_toggle_V3_t emergencyshutdown_toggle_V3;
+ pd_allocations_allocate_V3_t allocations_allocate_V3;
+ pd_allocationsoracles_add_member_V3_t allocationsoracles_add_member_V3;
+ pd_allocationsoracles_remove_member_V3_t allocationsoracles_remove_member_V3;
+ pd_allocationsoracles_swap_member_V3_t allocationsoracles_swap_member_V3;
+ pd_allocationsoracles_reset_members_V3_t allocationsoracles_reset_members_V3;
+ pd_allocationsoracles_change_key_V3_t allocationsoracles_change_key_V3;
+ pd_allocationsoracles_set_prime_V3_t allocationsoracles_set_prime_V3;
+ pd_allocationsoracles_clear_prime_V3_t allocationsoracles_clear_prime_V3;
+#endif
+} pd_MethodBasic_V3_t;
+
+#define PD_CALL_BALANCES_TRANSFER_V3 0
+typedef struct {
+ pd_LookupSource_V3_t dest;
+ pd_CompactBalance_t value;
+} pd_balances_transfer_V3_t;
+
+#define PD_CALL_BALANCES_TRANSFER_KEEP_ALIVE_V3 3
+typedef struct {
+ pd_LookupSource_V3_t dest;
+ pd_CompactBalance_t value;
+} pd_balances_transfer_keep_alive_V3_t;
+
+#ifdef SUBSTRATE_PARSER_FULL
+#define PD_CALL_SYSTEM_FILL_BLOCK_V3 0
+typedef struct {
+ pd_Perbill_V3_t _ratio;
+} pd_system_fill_block_V3_t;
+
+#define PD_CALL_SYSTEM_REMARK_V3 1
+typedef struct {
+ pd_Bytes_t _remark;
+} pd_system_remark_V3_t;
+
+#define PD_CALL_SYSTEM_SET_HEAP_PAGES_V3 2
+typedef struct {
+ pd_u64_t pages;
+} pd_system_set_heap_pages_V3_t;
+
+#define PD_CALL_SYSTEM_SET_CODE_V3 3
+typedef struct {
+ pd_Bytes_t code;
+} pd_system_set_code_V3_t;
+
+#define PD_CALL_SYSTEM_SET_CODE_WITHOUT_CHECKS_V3 4
+typedef struct {
+ pd_Bytes_t code;
+} pd_system_set_code_without_checks_V3_t;
+
+#define PD_CALL_SYSTEM_SET_CHANGES_TRIE_CONFIG_V3 5
+typedef struct {
+ pd_OptionChangesTrieConfiguration_V3_t changes_trie_config;
+} pd_system_set_changes_trie_config_V3_t;
+
+#define PD_CALL_SYSTEM_SET_STORAGE_V3 6
+typedef struct {
+ pd_VecKeyValue_V3_t items;
+} pd_system_set_storage_V3_t;
+
+#define PD_CALL_SYSTEM_KILL_STORAGE_V3 7
+typedef struct {
+ pd_VecKey_V3_t keys;
+} pd_system_kill_storage_V3_t;
+
+#define PD_CALL_SYSTEM_KILL_PREFIX_V3 8
+typedef struct {
+ pd_Key_V3_t prefix;
+ pd_u32_t _subkeys;
+} pd_system_kill_prefix_V3_t;
+
+#define PD_CALL_BALANCES_SET_BALANCE_V3 1
+typedef struct {
+ pd_LookupSource_V3_t who;
+ pd_CompactBalance_t new_free;
+ pd_CompactBalance_t new_reserved;
+} pd_balances_set_balance_V3_t;
+
+#define PD_CALL_BALANCES_FORCE_TRANSFER_V3 2
+typedef struct {
+ pd_LookupSource_V3_t source;
+ pd_LookupSource_V3_t dest;
+ pd_CompactBalance_t value;
+} pd_balances_force_transfer_V3_t;
+
+#define PD_CALL_PROXY_PROXY_V3 0
+typedef struct {
+ pd_AccountId_V3_t real;
+ pd_OptionProxyType_V3_t force_proxy_type;
+ pd_Call_t call;
+} pd_proxy_proxy_V3_t;
+
+#define PD_CALL_MULTISIG_AS_MULTI_THRESHOLD_1_V3 0
+typedef struct {
+ pd_VecAccountId_V3_t other_signatories;
+ pd_Call_t call;
+} pd_multisig_as_multi_threshold_1_V3_t;
+
+#define PD_CALL_MULTISIG_AS_MULTI_V3 1
+typedef struct {
+ pd_u16_t threshold;
+ pd_VecAccountId_V3_t other_signatories;
+ pd_OptionTimepoint_V3_t maybe_timepoint;
+ pd_OpaqueCall_V3_t call;
+ pd_bool_t store_call;
+ pd_Weight_V3_t max_weight;
+} pd_multisig_as_multi_V3_t;
+
+#define PD_CALL_MULTISIG_APPROVE_AS_MULTI_V3 2
+typedef struct {
+ pd_u16_t threshold;
+ pd_VecAccountId_V3_t other_signatories;
+ pd_OptionTimepoint_V3_t maybe_timepoint;
+ pd_u8_array_32_V3_t call_hash;
+ pd_Weight_V3_t max_weight;
+} pd_multisig_approve_as_multi_V3_t;
+
+#define PD_CALL_MULTISIG_CANCEL_AS_MULTI_V3 3
+typedef struct {
+ pd_u16_t threshold;
+ pd_VecAccountId_V3_t other_signatories;
+ pd_Timepoint_V3_t timepoint;
+ pd_u8_array_32_V3_t call_hash;
+} pd_multisig_cancel_as_multi_V3_t;
+
+#endif
+
+typedef union {
+ pd_balances_transfer_V3_t balances_transfer_V3;
+ pd_balances_transfer_keep_alive_V3_t balances_transfer_keep_alive_V3;
+#ifdef SUBSTRATE_PARSER_FULL
+ pd_system_fill_block_V3_t system_fill_block_V3;
+ pd_system_remark_V3_t system_remark_V3;
+ pd_system_set_heap_pages_V3_t system_set_heap_pages_V3;
+ pd_system_set_code_V3_t system_set_code_V3;
+ pd_system_set_code_without_checks_V3_t system_set_code_without_checks_V3;
+ pd_system_set_changes_trie_config_V3_t system_set_changes_trie_config_V3;
+ pd_system_set_storage_V3_t system_set_storage_V3;
+ pd_system_kill_storage_V3_t system_kill_storage_V3;
+ pd_system_kill_prefix_V3_t system_kill_prefix_V3;
+ pd_balances_set_balance_V3_t balances_set_balance_V3;
+ pd_balances_force_transfer_V3_t balances_force_transfer_V3;
+ pd_proxy_proxy_V3_t proxy_proxy_V3;
+ pd_multisig_as_multi_threshold_1_V3_t multisig_as_multi_threshold_1_V3;
+ pd_multisig_as_multi_V3_t multisig_as_multi_V3;
+ pd_multisig_approve_as_multi_V3_t multisig_approve_as_multi_V3;
+ pd_multisig_cancel_as_multi_V3_t multisig_cancel_as_multi_V3;
+#endif
+} pd_MethodNested_V3_t;
+
+typedef union {
+ pd_MethodBasic_V3_t basic;
+ pd_MethodNested_V3_t nested;
+} pd_Method_V3_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#pragma clang diagnostic pop
diff --git a/app/src/substrate_strings.h b/app/src/substrate_strings.h
new file mode 100644
index 0000000..d55d489
--- /dev/null
+++ b/app/src/substrate_strings.h
@@ -0,0 +1,553 @@
+/*******************************************************************************
+* (c) 2021 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Modules names
+static const char* STR_MO_SYSTEM = "System";
+static const char* STR_MO_BABE = "Babe";
+static const char* STR_MO_TIMESTAMP = "Timestamp";
+static const char* STR_MO_INDICES = "Indices";
+static const char* STR_MO_BALANCES = "Balances";
+static const char* STR_MO_AUTHORSHIP = "Authorship";
+static const char* STR_MO_STAKING = "Staking";
+static const char* STR_MO_OFFENCES = "Offences";
+static const char* STR_MO_SESSION = "Session";
+static const char* STR_MO_GRANDPA = "Grandpa";
+static const char* STR_MO_IMONLINE = "Imonline";
+static const char* STR_MO_AUTHORITYDISCOVERY = "Authoritydiscovery";
+static const char* STR_MO_DEMOCRACY = "Democracy";
+static const char* STR_MO_COUNCIL = "Council";
+static const char* STR_MO_TECHNICALCOMMITTEE = "Technicalcommittee";
+static const char* STR_MO_ELECTIONSPHRAGMEN = "Electionsphragmen";
+static const char* STR_MO_TECHNICALMEMBERSHIP = "Technicalmembership";
+static const char* STR_MO_TREASURY = "Treasury";
+static const char* STR_MO_CLAIMS = "Claims";
+static const char* STR_MO_UTILITY = "Utility";
+static const char* STR_MO_IDENTITY = "Identity";
+static const char* STR_MO_SOCIETY = "Society";
+static const char* STR_MO_RECOVERY = "Recovery";
+static const char* STR_MO_VESTING = "Vesting";
+static const char* STR_MO_SCHEDULER = "Scheduler";
+static const char* STR_MO_PROXY = "Proxy";
+static const char* STR_MO_MULTISIG = "Multisig";
+static const char* STR_MO_BOUNTIES = "Bounties";
+static const char* STR_MO_TIPS = "Tips";
+static const char* STR_MO_ELECTIONPROVIDERMULTIPHASE = "Electionprovidermultiphase";
+static const char* STR_MO_PHRAGMENELECTION = "Phragmenelection";
+static const char* STR_MO_GILT = "Gilt";
+static const char* STR_MO_PARACHAINSCONFIGURATION = "Parachainsconfiguration";
+static const char* STR_MO_PARASSHARED = "Parasshared";
+static const char* STR_MO_PARASINCLUSION = "Parasinclusion";
+static const char* STR_MO_PARASINHERENT = "Parasinherent";
+static const char* STR_MO_PARASSCHEDULER = "Parasscheduler";
+static const char* STR_MO_PARAS = "Paras";
+static const char* STR_MO_PARASINITIALIZER = "Parasinitializer";
+static const char* STR_MO_PARASDMP = "Parasdmp";
+static const char* STR_MO_PARASUMP = "Parasump";
+static const char* STR_MO_PARASHRMP = "Parashrmp";
+static const char* STR_MO_PARASSESSIONINFO = "Parassessioninfo";
+static const char* STR_MO_REGISTRAR = "Registrar";
+static const char* STR_MO_SLOTS = "Slots";
+static const char* STR_MO_AUCTIONS = "Auctions";
+static const char* STR_MO_CROWDLOAN = "Crowdloan";
+static const char* STR_MO_XCMPALLET = "Xcmpallet";
+static const char* STR_MO_RANDOMNESSCOLLECTIVEFLIP = "Randomnesscollectiveflip";
+static const char* STR_MO_VALIDATORSSET = "Validatorsset";
+static const char* STR_MO_FINANCIALCOMMITTEE = "Financialcommittee";
+static const char* STR_MO_FINANCIALMEMBERSHIP = "Financialmembership";
+static const char* STR_MO_ROOTCOMMITTEE = "Rootcommittee";
+static const char* STR_MO_ROOTMEMBERSHIP = "Rootmembership";
+static const char* STR_MO_AMENDMENTS = "Amendments";
+static const char* STR_MO_MANDATE = "Mandate";
+static const char* STR_MO_COMPANYRESERVE = "Companyreserve";
+static const char* STR_MO_INTERNATIONALRESERVE = "Internationalreserve";
+static const char* STR_MO_USARESERVE = "Usareserve";
+static const char* STR_MO_CONTRACTS = "Contracts";
+static const char* STR_MO_PKITCR = "Pkitcr";
+static const char* STR_MO_PKIROOTOFTRUST = "Pkirootoftrust";
+static const char* STR_MO_EMERGENCYSHUTDOWN = "Emergencyshutdown";
+static const char* STR_MO_ALLOCATIONS = "Allocations";
+static const char* STR_MO_ALLOCATIONSORACLES = "Allocationsoracles";
+
+// Methods names
+static const char* STR_ME_FILL_BLOCK = "Fill block";
+static const char* STR_ME_REMARK = "Remark";
+static const char* STR_ME_SET_HEAP_PAGES = "Set heap pages";
+static const char* STR_ME_SET_CODE = "Set code";
+static const char* STR_ME_SET_CODE_WITHOUT_CHECKS = "Set code without checks";
+static const char* STR_ME_SET_CHANGES_TRIE_CONFIG = "Set changes trie config";
+static const char* STR_ME_SET_STORAGE = "Set storage";
+static const char* STR_ME_KILL_STORAGE = "Kill storage";
+static const char* STR_ME_KILL_PREFIX = "Kill prefix";
+static const char* STR_ME_REPORT_EQUIVOCATION = "Report equivocation";
+static const char* STR_ME_REPORT_EQUIVOCATION_UNSIGNED = "Report equivocation unsigned";
+static const char* STR_ME_SET = "Set";
+static const char* STR_ME_CLAIM = "Claim";
+static const char* STR_ME_TRANSFER = "Transfer";
+static const char* STR_ME_FREE = "Free";
+static const char* STR_ME_FORCE_TRANSFER = "Force transfer";
+static const char* STR_ME_FREEZE = "Freeze";
+static const char* STR_ME_SET_BALANCE = "Set balance";
+static const char* STR_ME_TRANSFER_KEEP_ALIVE = "Transfer keep alive";
+static const char* STR_ME_SET_UNCLES = "Set uncles";
+static const char* STR_ME_BOND = "Bond";
+static const char* STR_ME_BOND_EXTRA = "Bond extra";
+static const char* STR_ME_UNBOND = "Unbond";
+static const char* STR_ME_WITHDRAW_UNBONDED = "Withdraw Unbonded";
+static const char* STR_ME_VALIDATE = "Validate";
+static const char* STR_ME_NOMINATE = "Nominate";
+static const char* STR_ME_CHILL = "Chill";
+static const char* STR_ME_SET_PAYEE = "Set payee";
+static const char* STR_ME_SET_CONTROLLER = "Set controller";
+static const char* STR_ME_SET_VALIDATOR_COUNT = "Set validator count";
+static const char* STR_ME_INCREASE_VALIDATOR_COUNT = "Increase validator count";
+static const char* STR_ME_SCALE_VALIDATOR_COUNT = "Scale validator count";
+static const char* STR_ME_FORCE_NO_ERAS = "Force no eras";
+static const char* STR_ME_FORCE_NEW_ERA = "Force new era";
+static const char* STR_ME_SET_INVULNERABLES = "Set invulnerables";
+static const char* STR_ME_FORCE_UNSTAKE = "Force unstake";
+static const char* STR_ME_FORCE_NEW_ERA_ALWAYS = "Force new era always";
+static const char* STR_ME_CANCEL_DEFERRED_SLASH = "Cancel deferred slash";
+static const char* STR_ME_PAYOUT_STAKERS = "Payout stakers";
+static const char* STR_ME_REBOND = "Rebond";
+static const char* STR_ME_SET_HISTORY_DEPTH = "Set history depth";
+static const char* STR_ME_REAP_STASH = "Reap stash";
+static const char* STR_ME_SUBMIT_ELECTION_SOLUTION = "Submit election solution";
+static const char* STR_ME_SUBMIT_ELECTION_SOLUTION_UNSIGNED = "Submit election solution unsigned";
+static const char* STR_ME_KICK = "Kick";
+static const char* STR_ME_SET_KEYS = "Set keys";
+static const char* STR_ME_PURGE_KEYS = "Purge keys";
+static const char* STR_ME_NOTE_STALLED = "Note stalled";
+static const char* STR_ME_HEARTBEAT = "Heartbeat";
+static const char* STR_ME_PROPOSE = "Propose";
+static const char* STR_ME_SECOND = "Second";
+static const char* STR_ME_VOTE = "Vote";
+static const char* STR_ME_EMERGENCY_CANCEL = "Emergency cancel";
+static const char* STR_ME_EXTERNAL_PROPOSE = "External propose";
+static const char* STR_ME_EXTERNAL_PROPOSE_MAJORITY = "External propose majority";
+static const char* STR_ME_EXTERNAL_PROPOSE_DEFAULT = "External propose default";
+static const char* STR_ME_FAST_TRACK = "Fast track";
+static const char* STR_ME_VETO_EXTERNAL = "Veto external";
+static const char* STR_ME_CANCEL_REFERENDUM = "Cancel referendum";
+static const char* STR_ME_CANCEL_QUEUED = "Cancel queued";
+static const char* STR_ME_DELEGATE = "Delegate";
+static const char* STR_ME_UNDELEGATE = "Undelegate";
+static const char* STR_ME_CLEAR_PUBLIC_PROPOSALS = "Clear public proposals";
+static const char* STR_ME_NOTE_PREIMAGE = "Note preimage";
+static const char* STR_ME_NOTE_PREIMAGE_OPERATIONAL = "Note preimage operational";
+static const char* STR_ME_NOTE_IMMINENT_PREIMAGE = "Note imminent preimage";
+static const char* STR_ME_NOTE_IMMINENT_PREIMAGE_OPERATIONAL = "Note imminent preimage operational";
+static const char* STR_ME_REAP_PREIMAGE = "Reap preimage";
+static const char* STR_ME_UNLOCK = "Unlock";
+static const char* STR_ME_REMOVE_VOTE = "Remove vote";
+static const char* STR_ME_REMOVE_OTHER_VOTE = "Remove other vote";
+static const char* STR_ME_ENACT_PROPOSAL = "Enact proposal";
+static const char* STR_ME_BLACKLIST = "Blacklist";
+static const char* STR_ME_CANCEL_PROPOSAL = "Cancel proposal";
+static const char* STR_ME_SET_MEMBERS = "Set members";
+static const char* STR_ME_EXECUTE = "Execute";
+static const char* STR_ME_CLOSE = "Close";
+static const char* STR_ME_DISAPPROVE_PROPOSAL = "Disapprove proposal";
+static const char* STR_ME_REMOVE_VOTER = "Remove voter";
+static const char* STR_ME_SUBMIT_CANDIDACY = "Submit candidacy";
+static const char* STR_ME_RENOUNCE_CANDIDACY = "Renounce candidacy";
+static const char* STR_ME_REMOVE_MEMBER = "Remove member";
+static const char* STR_ME_CLEAN_DEFUNCT_VOTERS = "Clean defunct voters";
+static const char* STR_ME_ADD_MEMBER = "Add member";
+static const char* STR_ME_SWAP_MEMBER = "Swap member";
+static const char* STR_ME_RESET_MEMBERS = "Reset members";
+static const char* STR_ME_CHANGE_KEY = "Change key";
+static const char* STR_ME_SET_PRIME = "Set prime";
+static const char* STR_ME_CLEAR_PRIME = "Clear prime";
+static const char* STR_ME_PROPOSE_SPEND = "Propose spend";
+static const char* STR_ME_REJECT_PROPOSAL = "Reject proposal";
+static const char* STR_ME_APPROVE_PROPOSAL = "Approve proposal";
+static const char* STR_ME_MINT_CLAIM = "Mint claim";
+static const char* STR_ME_CLAIM_ATTEST = "Claim attest";
+static const char* STR_ME_ATTEST = "Attest";
+static const char* STR_ME_MOVE_CLAIM = "Move claim";
+static const char* STR_ME_BATCH = "Batch";
+static const char* STR_ME_AS_DERIVATIVE = "As derivative";
+static const char* STR_ME_BATCH_ALL = "Batch all";
+static const char* STR_ME_ADD_REGISTRAR = "Add registrar";
+static const char* STR_ME_SET_IDENTITY = "Set identity";
+static const char* STR_ME_SET_SUBS = "Set subs";
+static const char* STR_ME_CLEAR_IDENTITY = "Clear identity";
+static const char* STR_ME_REQUEST_JUDGEMENT = "Request judgement";
+static const char* STR_ME_CANCEL_REQUEST = "Cancel request";
+static const char* STR_ME_SET_FEE = "Set fee";
+static const char* STR_ME_SET_ACCOUNT_ID = "Set account id";
+static const char* STR_ME_SET_FIELDS = "Set fields";
+static const char* STR_ME_PROVIDE_JUDGEMENT = "Provide judgement";
+static const char* STR_ME_KILL_IDENTITY = "Kill identity";
+static const char* STR_ME_ADD_SUB = "Add sub";
+static const char* STR_ME_RENAME_SUB = "Rename sub";
+static const char* STR_ME_REMOVE_SUB = "Remove sub";
+static const char* STR_ME_QUIT_SUB = "Quit sub";
+static const char* STR_ME_BID = "Bid";
+static const char* STR_ME_UNBID = "Unbid";
+static const char* STR_ME_VOUCH = "Vouch";
+static const char* STR_ME_UNVOUCH = "Unvouch";
+static const char* STR_ME_DEFENDER_VOTE = "Defender vote";
+static const char* STR_ME_PAYOUT = "Payout";
+static const char* STR_ME_FOUND = "Found";
+static const char* STR_ME_UNFOUND = "Unfound";
+static const char* STR_ME_JUDGE_SUSPENDED_MEMBER = "Judge suspended member";
+static const char* STR_ME_JUDGE_SUSPENDED_CANDIDATE = "Judge suspended candidate";
+static const char* STR_ME_SET_MAX_MEMBERS = "Set max members";
+static const char* STR_ME_AS_RECOVERED = "As recovered";
+static const char* STR_ME_SET_RECOVERED = "Set recovered";
+static const char* STR_ME_CREATE_RECOVERY = "Create recovery";
+static const char* STR_ME_INITIATE_RECOVERY = "Initiate recovery";
+static const char* STR_ME_VOUCH_RECOVERY = "Vouch recovery";
+static const char* STR_ME_CLAIM_RECOVERY = "Claim recovery";
+static const char* STR_ME_CLOSE_RECOVERY = "Close recovery";
+static const char* STR_ME_REMOVE_RECOVERY = "Remove recovery";
+static const char* STR_ME_CANCEL_RECOVERED = "Cancel recovered";
+static const char* STR_ME_VEST = "Vest";
+static const char* STR_ME_VEST_OTHER = "Vest other";
+static const char* STR_ME_VESTED_TRANSFER = "Vested transfer";
+static const char* STR_ME_FORCE_VESTED_TRANSFER = "Force vested transfer";
+static const char* STR_ME_SCHEDULE = "Schedule";
+static const char* STR_ME_CANCEL = "Cancel";
+static const char* STR_ME_SCHEDULE_NAMED = "Schedule named";
+static const char* STR_ME_CANCEL_NAMED = "Cancel named";
+static const char* STR_ME_SCHEDULE_AFTER = "Schedule after";
+static const char* STR_ME_SCHEDULE_NAMED_AFTER = "Schedule named after";
+static const char* STR_ME_PROXY = "Proxy";
+static const char* STR_ME_ADD_PROXY = "Add proxy";
+static const char* STR_ME_REMOVE_PROXY = "Remove proxy";
+static const char* STR_ME_REMOVE_PROXIES = "Remove proxies";
+static const char* STR_ME_ANONYMOUS = "Anonymous";
+static const char* STR_ME_KILL_ANONYMOUS = "Kill anonymous";
+static const char* STR_ME_ANNOUNCE = "Announce";
+static const char* STR_ME_REMOVE_ANNOUNCEMENT = "Remove announcement";
+static const char* STR_ME_REJECT_ANNOUNCEMENT = "Reject announcement";
+static const char* STR_ME_PROXY_ANNOUNCED = "Proxy announced";
+static const char* STR_ME_AS_MULTI_THRESHOLD_1 = "As multi threshold 1";
+static const char* STR_ME_AS_MULTI = "As multi";
+static const char* STR_ME_APPROVE_AS_MULTI = "Approve as multi";
+static const char* STR_ME_CANCEL_AS_MULTI = "Cancel as multi";
+static const char* STR_ME_PROPOSE_BOUNTY = "Propose bounty";
+static const char* STR_ME_APPROVE_BOUNTY = "Approve bounty";
+static const char* STR_ME_PROPOSE_CURATOR = "Propose curator";
+static const char* STR_ME_UNASSIGN_CURATOR = "Unassign curator";
+static const char* STR_ME_ACCEPT_CURATOR = "Accept curator";
+static const char* STR_ME_AWARD_BOUNTY = "Award bounty";
+static const char* STR_ME_CLAIM_BOUNTY = "Claim bounty";
+static const char* STR_ME_CLOSE_BOUNTY = "Close bounty";
+static const char* STR_ME_EXTEND_BOUNTY_EXPIRY = "Extend bounty expiry";
+static const char* STR_ME_REPORT_AWESOME = "Report awesome";
+static const char* STR_ME_RETRACT_TIP = "Retract tip";
+static const char* STR_ME_TIP_NEW = "Tip new";
+static const char* STR_ME_TIP = "Tip";
+static const char* STR_ME_CLOSE_TIP = "Close tip";
+static const char* STR_ME_SLASH_TIP = "Slash tip";
+static const char* STR_ME_SUBMIT_UNSIGNED = "Submit unsigned";
+static const char* STR_ME_REMARK_WITH_EVENT = "Remark with event";
+static const char* STR_ME_PLAN_CONFIG_CHANGE = "Plan config change";
+static const char* STR_ME_PLACE_BID = "Place bid";
+static const char* STR_ME_RETRACT_BID = "Retract bid";
+static const char* STR_ME_SET_TARGET = "Set target";
+static const char* STR_ME_THAW = "Thaw";
+static const char* STR_ME_SET_VALIDATION_UPGRADE_FREQUENCY = "Set validation upgrade frequency";
+static const char* STR_ME_SET_VALIDATION_UPGRADE_DELAY = "Set validation upgrade delay";
+static const char* STR_ME_SET_CODE_RETENTION_PERIOD = "Set code retention period";
+static const char* STR_ME_SET_MAX_CODE_SIZE = "Set max code size";
+static const char* STR_ME_SET_MAX_POV_SIZE = "Set max pov size";
+static const char* STR_ME_SET_MAX_HEAD_DATA_SIZE = "Set max head data size";
+static const char* STR_ME_SET_PARATHREAD_CORES = "Set parathread cores";
+static const char* STR_ME_SET_PARATHREAD_RETRIES = "Set parathread retries";
+static const char* STR_ME_SET_GROUP_ROTATION_FREQUENCY = "Set group rotation frequency";
+static const char* STR_ME_SET_CHAIN_AVAILABILITY_PERIOD = "Set chain availability period";
+static const char* STR_ME_SET_THREAD_AVAILABILITY_PERIOD = "Set thread availability period";
+static const char* STR_ME_SET_SCHEDULING_LOOKAHEAD = "Set scheduling lookahead";
+static const char* STR_ME_SET_MAX_VALIDATORS_PER_CORE = "Set max validators per core";
+static const char* STR_ME_SET_MAX_VALIDATORS = "Set max validators";
+static const char* STR_ME_SET_DISPUTE_PERIOD = "Set dispute period";
+static const char* STR_ME_SET_DISPUTE_POST_CONCLUSION_ACCEPTANCE_PERIOD = "Set dispute post conclusion acceptance period";
+static const char* STR_ME_SET_DISPUTE_MAX_SPAM_SLOTS = "Set dispute max spam slots";
+static const char* STR_ME_SET_DISPUTE_CONCLUSION_BY_TIME_OUT_PERIOD = "Set dispute conclusion by time out period";
+static const char* STR_ME_SET_NO_SHOW_SLOTS = "Set no show slots";
+static const char* STR_ME_SET_N_DELAY_TRANCHES = "Set n delay tranches";
+static const char* STR_ME_SET_ZEROTH_DELAY_TRANCHE_WIDTH = "Set zeroth delay tranche width";
+static const char* STR_ME_SET_NEEDED_APPROVALS = "Set needed approvals";
+static const char* STR_ME_SET_RELAY_VRF_MODULO_SAMPLES = "Set relay vrf modulo samples";
+static const char* STR_ME_SET_MAX_UPWARD_QUEUE_COUNT = "Set max upward queue count";
+static const char* STR_ME_SET_MAX_UPWARD_QUEUE_SIZE = "Set max upward queue size";
+static const char* STR_ME_SET_MAX_DOWNWARD_MESSAGE_SIZE = "Set max downward message size";
+static const char* STR_ME_SET_PREFERRED_DISPATCHABLE_UPWARD_MESSAGES_STEP_WEIGHT = "Set preferred dispatchable upward messages step weight";
+static const char* STR_ME_SET_MAX_UPWARD_MESSAGE_SIZE = "Set max upward message size";
+static const char* STR_ME_SET_MAX_UPWARD_MESSAGE_NUM_PER_CANDIDATE = "Set max upward message num per candidate";
+static const char* STR_ME_SET_HRMP_OPEN_REQUEST_TTL = "Set hrmp open request ttl";
+static const char* STR_ME_SET_HRMP_SENDER_DEPOSIT = "Set hrmp sender deposit";
+static const char* STR_ME_SET_HRMP_RECIPIENT_DEPOSIT = "Set hrmp recipient deposit";
+static const char* STR_ME_SET_HRMP_CHANNEL_MAX_CAPACITY = "Set hrmp channel max capacity";
+static const char* STR_ME_SET_HRMP_CHANNEL_MAX_TOTAL_SIZE = "Set hrmp channel max total size";
+static const char* STR_ME_SET_HRMP_MAX_PARACHAIN_INBOUND_CHANNELS = "Set hrmp max parachain inbound channels";
+static const char* STR_ME_SET_HRMP_MAX_PARATHREAD_INBOUND_CHANNELS = "Set hrmp max parathread inbound channels";
+static const char* STR_ME_SET_HRMP_CHANNEL_MAX_MESSAGE_SIZE = "Set hrmp channel max message size";
+static const char* STR_ME_SET_HRMP_MAX_PARACHAIN_OUTBOUND_CHANNELS = "Set hrmp max parachain outbound channels";
+static const char* STR_ME_SET_HRMP_MAX_PARATHREAD_OUTBOUND_CHANNELS = "Set hrmp max parathread outbound channels";
+static const char* STR_ME_SET_HRMP_MAX_MESSAGE_NUM_PER_CANDIDATE = "Set hrmp max message num per candidate";
+static const char* STR_ME_ENTER = "Enter";
+static const char* STR_ME_FORCE_SET_CURRENT_CODE = "Force set current code";
+static const char* STR_ME_FORCE_SET_CURRENT_HEAD = "Force set current head";
+static const char* STR_ME_FORCE_SCHEDULE_CODE_UPGRADE = "Force schedule code upgrade";
+static const char* STR_ME_FORCE_NOTE_NEW_HEAD = "Force note new head";
+static const char* STR_ME_FORCE_QUEUE_ACTION = "Force queue action";
+static const char* STR_ME_FORCE_APPROVE = "Force approve";
+static const char* STR_ME_HRMP_INIT_OPEN_CHANNEL = "Hrmp init open channel";
+static const char* STR_ME_HRMP_ACCEPT_OPEN_CHANNEL = "Hrmp accept open channel";
+static const char* STR_ME_HRMP_CLOSE_CHANNEL = "Hrmp close channel";
+static const char* STR_ME_FORCE_CLEAN_HRMP = "Force clean hrmp";
+static const char* STR_ME_FORCE_PROCESS_HRMP_OPEN = "Force process hrmp open";
+static const char* STR_ME_FORCE_PROCESS_HRMP_CLOSE = "Force process hrmp close";
+static const char* STR_ME_REGISTER = "Register";
+static const char* STR_ME_FORCE_REGISTER = "Force register";
+static const char* STR_ME_DEREGISTER = "Deregister";
+static const char* STR_ME_SWAP = "Swap";
+static const char* STR_ME_FORCE_REMOVE_LOCK = "Force remove lock";
+static const char* STR_ME_RESERVE = "Reserve";
+static const char* STR_ME_FORCE_LEASE = "Force lease";
+static const char* STR_ME_CLEAR_ALL_LEASES = "Clear all leases";
+static const char* STR_ME_TRIGGER_ONBOARD = "Trigger onboard";
+static const char* STR_ME_NEW_AUCTION = "New auction";
+static const char* STR_ME_CANCEL_AUCTION = "Cancel auction";
+static const char* STR_ME_CREATE = "Create";
+static const char* STR_ME_CONTRIBUTE = "Contribute";
+static const char* STR_ME_WITHDRAW = "Withdraw";
+static const char* STR_ME_REFUND = "Refund";
+static const char* STR_ME_DISSOLVE = "Dissolve";
+static const char* STR_ME_EDIT = "Edit";
+static const char* STR_ME_ADD_MEMO = "Add memo";
+static const char* STR_ME_POKE = "Poke";
+static const char* STR_ME_SEND = "Send";
+static const char* STR_ME_TELEPORT_ASSETS = "Teleport assets";
+static const char* STR_ME_VETO = "Veto";
+static const char* STR_ME_APPLY = "Apply";
+static const char* STR_ME_SPEND = "Spend";
+static const char* STR_ME_APPLY_AS = "Apply as";
+static const char* STR_ME_ADD_VESTING_SCHEDULE = "Add vesting schedule";
+static const char* STR_ME_CANCEL_ALL_VESTING_SCHEDULES = "Cancel all vesting schedules";
+static const char* STR_ME_UPDATE_SCHEDULE = "Update schedule";
+static const char* STR_ME_CALL = "Call";
+static const char* STR_ME_INSTANTIATE_WITH_CODE = "Instantiate with code";
+static const char* STR_ME_INSTANTIATE = "Instantiate";
+static const char* STR_ME_CLAIM_SURCHARGE = "Claim surcharge";
+static const char* STR_ME_COUNTER = "Counter";
+static const char* STR_ME_CHALLENGE = "Challenge";
+static const char* STR_ME_BOOK_SLOT = "Book slot";
+static const char* STR_ME_RENEW_SLOT = "Renew slot";
+static const char* STR_ME_REVOKE_SLOT = "Revoke slot";
+static const char* STR_ME_REVOKE_CHILD = "Revoke child";
+static const char* STR_ME_TOGGLE = "Toggle";
+static const char* STR_ME_ALLOCATE = "Allocate";
+
+// Items names
+static const char* STR_IT__ratio = "Ratio";
+static const char* STR_IT__remark = "Remark";
+static const char* STR_IT_pages = "Pages";
+static const char* STR_IT_code = "Code";
+static const char* STR_IT_changes_trie_config = "Changes trie config";
+static const char* STR_IT_items = "Items";
+static const char* STR_IT_keys = "Keys";
+static const char* STR_IT_prefix = "Prefix";
+static const char* STR_IT__subkeys = "Subkeys";
+static const char* STR_IT_equivocation_proof = "Equivocation proof";
+static const char* STR_IT_key_owner_proof = "Key owner proof";
+static const char* STR_IT_now = "Now";
+static const char* STR_IT_index = "Index";
+static const char* STR_IT_new_ = "New";
+static const char* STR_IT_freeze = "Freeze";
+static const char* STR_IT_dest = "Dest";
+static const char* STR_IT_value = "Amount";
+static const char* STR_IT_who = "Who";
+static const char* STR_IT_new_free = "New free";
+static const char* STR_IT_new_reserved = "New reserved";
+static const char* STR_IT_source = "Source";
+static const char* STR_IT_new_uncles = "New uncles";
+static const char* STR_IT_controller = "Controller";
+static const char* STR_IT_payee = "Payee";
+static const char* STR_IT_max_additional = "Amount";
+static const char* STR_IT_num_slashing_spans = "Num slashing spans";
+static const char* STR_IT_prefs = "Prefs";
+static const char* STR_IT_targets = "Targets";
+static const char* STR_IT_additional = "Additional";
+static const char* STR_IT_factor = "Factor";
+static const char* STR_IT_invulnerables = "Invulnerables";
+static const char* STR_IT_stash = "Stash";
+static const char* STR_IT_era = "Era";
+static const char* STR_IT_slash_indices = "Slash indices";
+static const char* STR_IT_validator_stash = "Validator stash";
+static const char* STR_IT_new_history_depth = "New history depth";
+static const char* STR_IT__era_items_deleted = "Era items deleted";
+static const char* STR_IT_winners = "Winners";
+static const char* STR_IT_compact = "Compact";
+static const char* STR_IT_score = "Score";
+static const char* STR_IT_size = "Size";
+static const char* STR_IT_proof = "Proof";
+static const char* STR_IT_delay = "Delay";
+static const char* STR_IT_best_finalized_block_number = "Best finalized block number";
+static const char* STR_IT_heartbeat = "Heartbeat";
+static const char* STR_IT__signature = "Signature";
+static const char* STR_IT_proposal_hash = "Proposal hash";
+static const char* STR_IT_proposal = "Proposal";
+static const char* STR_IT_seconds_upper_bound = "Seconds upper bound";
+static const char* STR_IT_ref_index = "Ref index";
+static const char* STR_IT_vote = "Vote";
+static const char* STR_IT_voting_period = "Voting period";
+static const char* STR_IT_which = "Which";
+static const char* STR_IT_to = "To";
+static const char* STR_IT_conviction = "Conviction";
+static const char* STR_IT_balance = "Balance";
+static const char* STR_IT_encoded_proposal = "Encoded proposal";
+static const char* STR_IT_proposal_len_upper_bound = "Proposal len upper bound";
+static const char* STR_IT_target = "Target";
+static const char* STR_IT_maybe_ref_index = "Maybe ref index";
+static const char* STR_IT_prop_index = "Prop index";
+static const char* STR_IT_new_members = "New members";
+static const char* STR_IT_prime = "Prime";
+static const char* STR_IT_old_count = "Old count";
+static const char* STR_IT_length_bound = "Length bound";
+static const char* STR_IT_threshold = "Threshold";
+static const char* STR_IT_approve = "Approve";
+static const char* STR_IT_proposal_weight_bound = "Proposal weight bound";
+static const char* STR_IT_votes = "Votes";
+static const char* STR_IT_candidate_count = "Candidate count";
+static const char* STR_IT_renouncing = "Renouncing";
+static const char* STR_IT_has_replacement = "Has replacement";
+static const char* STR_IT__num_voters = "Num voters";
+static const char* STR_IT__num_defunct = "Num defunct";
+static const char* STR_IT_remove = "Remove";
+static const char* STR_IT_add = "Add";
+static const char* STR_IT_members = "Members";
+static const char* STR_IT_beneficiary = "Beneficiary";
+static const char* STR_IT_proposal_id = "Proposal id";
+static const char* STR_IT_ethereum_signature = "Ethereum signature";
+static const char* STR_IT_vesting_schedule = "Vesting schedule";
+static const char* STR_IT_statement = "Statement";
+static const char* STR_IT_old = "Old";
+static const char* STR_IT_maybe_preclaim = "Maybe preclaim";
+static const char* STR_IT_calls = "Calls";
+static const char* STR_IT_call = "Call";
+static const char* STR_IT_account = "Account";
+static const char* STR_IT_info = "Info";
+static const char* STR_IT_subs = "Subs";
+static const char* STR_IT_reg_index = "Reg index";
+static const char* STR_IT_max_fee = "Max fee";
+static const char* STR_IT_fee = "Fee";
+static const char* STR_IT_fields = "Fields";
+static const char* STR_IT_judgement = "Judgement";
+static const char* STR_IT_sub = "Sub";
+static const char* STR_IT_data = "Data";
+static const char* STR_IT_pos = "Pos";
+static const char* STR_IT_tip = "Tip";
+static const char* STR_IT_candidate = "Candidate";
+static const char* STR_IT_founder = "Founder";
+static const char* STR_IT_max_members = "Max members";
+static const char* STR_IT_rules = "Rules";
+static const char* STR_IT_forgive = "Forgive";
+static const char* STR_IT_max = "Max";
+static const char* STR_IT_lost = "Lost";
+static const char* STR_IT_rescuer = "Rescuer";
+static const char* STR_IT_friends = "Friends";
+static const char* STR_IT_delay_period = "Delay period";
+static const char* STR_IT_schedule = "Schedule";
+static const char* STR_IT_when = "When";
+static const char* STR_IT_maybe_periodic = "Maybe periodic";
+static const char* STR_IT_priority = "Priority";
+static const char* STR_IT_id = "Id";
+static const char* STR_IT_after = "After";
+static const char* STR_IT_real = "Real";
+static const char* STR_IT_force_proxy_type = "Force proxy type";
+static const char* STR_IT_delegate = "Delegate";
+static const char* STR_IT_proxy_type = "Proxy type";
+static const char* STR_IT_spawner = "Spawner";
+static const char* STR_IT_height = "Height";
+static const char* STR_IT_ext_index = "Ext index";
+static const char* STR_IT_call_hash = "Call hash";
+static const char* STR_IT_other_signatories = "Other signatories";
+static const char* STR_IT_maybe_timepoint = "Maybe timepoint";
+static const char* STR_IT_store_call = "Store call";
+static const char* STR_IT_max_weight = "Max weight";
+static const char* STR_IT_timepoint = "Timepoint";
+static const char* STR_IT_description = "Description";
+static const char* STR_IT_bounty_id = "Bounty id";
+static const char* STR_IT_curator = "Curator";
+static const char* STR_IT_reason = "Reason";
+static const char* STR_IT_hash = "Hash";
+static const char* STR_IT_tip_value = "Tip value";
+static const char* STR_IT_solution = "Solution";
+static const char* STR_IT_witness = "Witness";
+static const char* STR_IT_remark = "Remark";
+static const char* STR_IT_config = "Config";
+static const char* STR_IT_amount = "Amount";
+static const char* STR_IT_duration = "Duration";
+static const char* STR_IT_para = "Para";
+static const char* STR_IT_new_code = "New code";
+static const char* STR_IT_new_head = "New head";
+static const char* STR_IT_expected_at = "Expected at";
+static const char* STR_IT_up_to = "Up to";
+static const char* STR_IT_recipient = "Recipient";
+static const char* STR_IT_proposed_max_capacity = "Proposed max capacity";
+static const char* STR_IT_proposed_max_message_size = "Proposed max message size";
+static const char* STR_IT_sender = "Sender";
+static const char* STR_IT_channel_id = "Channel id";
+static const char* STR_IT_genesis_head = "Genesis head";
+static const char* STR_IT_validation_code = "Validation code";
+static const char* STR_IT_deposit = "Deposit";
+static const char* STR_IT_other = "Other";
+static const char* STR_IT_leaser = "Leaser";
+static const char* STR_IT_period_begin = "Period begin";
+static const char* STR_IT_period_count = "Period count";
+static const char* STR_IT_lease_period_index = "Lease period index";
+static const char* STR_IT_auction_index = "Auction index";
+static const char* STR_IT_first_slot = "First slot";
+static const char* STR_IT_last_slot = "Last slot";
+static const char* STR_IT_cap = "Cap";
+static const char* STR_IT_first_period = "First period";
+static const char* STR_IT_last_period = "Last period";
+static const char* STR_IT_end = "End";
+static const char* STR_IT_verifier = "Verifier";
+static const char* STR_IT_signature = "Signature";
+static const char* STR_IT_memo = "Memo";
+static const char* STR_IT_message = "Message";
+static const char* STR_IT_assets = "Assets";
+static const char* STR_IT_dest_weight = "Dest weight";
+static const char* STR_IT_amendment = "Amendment";
+static const char* STR_IT_amendment_id = "Amendment id";
+static const char* STR_IT_funds_collector = "Funds collector";
+static const char* STR_IT_limit_to_free_balance = "Limit to free balance";
+static const char* STR_IT_gas_limit = "Gas limit";
+static const char* STR_IT_endowment = "Endowment";
+static const char* STR_IT_salt = "Salt";
+static const char* STR_IT_code_hash = "Code hash";
+static const char* STR_IT_aux_sender = "Aux sender";
+static const char* STR_IT_metadata = "Metadata";
+static const char* STR_IT_member = "Member";
+static const char* STR_IT_supporting = "Supporting";
+static const char* STR_IT_certificate_id = "Certificate id";
+static const char* STR_IT_root = "Root";
+static const char* STR_IT_child = "Child";
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/app/src/substrate_types.c b/app/src/substrate_types.c
new file mode 100644
index 0000000..220a265
--- /dev/null
+++ b/app/src/substrate_types.c
@@ -0,0 +1,778 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#include "bignum.h"
+#include "coin.h"
+#include "parser_impl.h"
+
+#include "substrate_dispatch.h"
+#include
+#include
+#include
+#include
+
+parser_error_t _readbool(parser_context_t* c, pd_bool_t* v)
+{
+ return _readUInt8(c, v);
+}
+
+parser_error_t _readu8(parser_context_t* c, pd_u8_t* v)
+{
+ return _readUInt8(c, v);
+}
+
+parser_error_t _readu16(parser_context_t* c, pd_u16_t* v)
+{
+ return _readUInt16(c, v);
+}
+
+parser_error_t _readu32(parser_context_t* c, pd_u32_t* v)
+{
+ return _readUInt32(c, v);
+}
+
+parser_error_t _readu64(parser_context_t* c, pd_u64_t* v)
+{
+ return _readUInt64(c, v);
+}
+
+parser_error_t _readBlockNumber(parser_context_t* c, pd_BlockNumber_t* v)
+{
+ return _readUInt32(c, v);
+}
+
+parser_error_t _readCompactu32(parser_context_t* c, pd_Compactu32_t* v)
+{
+ return _readCompactInt(c, v);
+}
+
+parser_error_t _readCompactu64(parser_context_t* c, pd_Compactu64_t* v)
+{
+ return _readCompactInt(c, v);
+}
+
+parser_error_t _readCallImpl(parser_context_t* c, pd_Call_t* v, pd_MethodNested_t* m)
+{
+ // If it's the first Call, store a pointer to it
+ if (c->tx_obj->nestCallIdx._ptr == NULL) {
+ c->tx_obj->nestCallIdx._ptr = c->buffer + c->offset;
+ c->tx_obj->nestCallIdx._lenBuffer = c->bufferLen - c->offset;
+ } else {
+ // If _ptr is not null, and landed here, means we're inside a nested call.
+ // We stored the pointer to the first Call and now we store
+ // the pointer to the 'next' Call.
+ if (c->tx_obj->nestCallIdx._nextPtr == NULL) {
+ c->tx_obj->nestCallIdx._nextPtr = c->buffer + c->offset;
+ }
+ }
+
+ // To keep track on how many nested Calls we have
+ c->tx_obj->nestCallIdx.slotIdx++;
+ if (c->tx_obj->nestCallIdx.slotIdx > MAX_CALL_NESTING_SIZE) {
+ return parser_tx_nesting_limit_reached;
+ }
+
+ CHECK_ERROR(_readCallIndex(c, &v->callIndex));
+
+ if (!_getMethod_IsNestingSupported(c->tx_obj->transactionVersion, v->callIndex.moduleIdx, v->callIndex.idx)) {
+ return parser_not_supported;
+ }
+
+ // Read and check the contained method on this Call
+ CHECK_ERROR(_readMethod(c, v->callIndex.moduleIdx, v->callIndex.idx, (pd_Method_t*)m))
+
+ // The instance of 'v' corresponding to the upper call on the stack (persisted variable)
+ // will end up having the pointer to the first Call and to the 'next' one if exists.
+ v->_txVerPtr = &c->tx_obj->transactionVersion;
+ v->nestCallIdx._lenBuffer = c->tx_obj->nestCallIdx._lenBuffer;
+ v->nestCallIdx._ptr = c->tx_obj->nestCallIdx._ptr;
+ v->nestCallIdx._nextPtr = c->tx_obj->nestCallIdx._nextPtr;
+
+ return parser_ok;
+}
+
+///////////////////////////////////
+///////////////////////////////////
+///////////////////////////////////
+parser_error_t _readCompactBlockNumber(parser_context_t* c, pd_CompactBlockNumber_t* v)
+{
+ return _readCompactInt(c, v);
+}
+
+parser_error_t _readData(parser_context_t* c, pd_Data_t* v)
+{
+ CHECK_INPUT();
+ MEMZERO(v, sizeof(pd_Data_t));
+ CHECK_ERROR(_readUInt8(c, (uint8_t*)&v->type))
+
+ v->_ptr = NULL;
+ v->_len = 0;
+
+ // based on:
+ // https://github.com/paritytech/substrate/blob/effe489951d1edab9d34846b1eefdfaf9511dab9/frame/identity/src/lib.rs#L139
+ switch (v->type) {
+ case Data_e_NONE: {
+ v->_ptr = NULL;
+ v->_len = 0;
+ return parser_ok;
+ }
+ case Data_e_BLAKETWO256U8_32:
+ case Data_e_SHA256_U8_32:
+ case Data_e_KECCAK256_U8_32:
+ case Data_e_SHATHREE256_U8_32:
+ return parser_not_supported;
+ default: {
+ if (v->type > Data_e_NONE && v->type <= Data_e_RAW_VECU8) {
+ const uint8_t bufferSize = ((uint8_t)v->type - 1);
+ v->_ptr = c->buffer + c->offset;
+ v->_len = bufferSize;
+ CTX_CHECK_AND_ADVANCE(c, v->_len);
+ return parser_ok;
+ }
+ return parser_not_supported;
+ }
+ }
+}
+
+parser_error_t _readTupleDataData(parser_context_t* c, pd_TupleDataData_t* v)
+{
+ CHECK_INPUT();
+ CHECK_ERROR(_readData(c, &v->data1))
+ CHECK_ERROR(_readData(c, &v->data2))
+ return parser_ok;
+}
+
+parser_error_t _readu8_array_20(parser_context_t* c, pd_u8_array_20_t* v) {
+ GEN_DEF_READARRAY(20)
+}
+
+parser_error_t _readBalance(parser_context_t* c, pd_Balance_t* v) {
+ GEN_DEF_READARRAY(16)
+}
+
+parser_error_t _readBytes(parser_context_t* c, pd_Bytes_t* v)
+{
+ CHECK_INPUT()
+
+ compactInt_t clen;
+ CHECK_ERROR(_readCompactInt(c, &clen))
+ CHECK_ERROR(_getValue(&clen, &v->_len))
+
+ v->_ptr = c->buffer + c->offset;
+ CTX_CHECK_AND_ADVANCE(c, v->_len);
+ return parser_ok;
+}
+
+parser_error_t _readCall(parser_context_t* c, pd_Call_t* v)
+{
+ pd_MethodNested_t _method;
+ if (c->tx_obj->nestCallIdx.isTail) {
+ c->tx_obj->nestCallIdx.isTail = false;
+ v->nestCallIdx.isTail = true;
+ } else {
+ v->nestCallIdx.isTail = false;
+ }
+
+ CHECK_ERROR(_readCallImpl(c, v, &_method))
+ if (c->tx_obj->nestCallIdx._ptr != NULL && c->tx_obj->nestCallIdx._nextPtr != NULL) {
+ v->nestCallIdx._ptr = c->tx_obj->nestCallIdx._ptr;
+ v->nestCallIdx._nextPtr = c->tx_obj->nestCallIdx._nextPtr;
+ }
+ v->nestCallIdx.slotIdx = c->tx_obj->nestCallIdx.slotIdx;
+ return parser_ok;
+}
+
+parser_error_t _readHeader(parser_context_t* c, pd_Header_t* v)
+{
+ return parser_not_supported;
+}
+
+parser_error_t _readBalanceOf(parser_context_t* c, pd_BalanceOf_t* v)
+{
+ return _readBalance(c, &v->value);
+}
+
+parser_error_t _readProposal(parser_context_t* c, pd_Proposal_t* v)
+{
+ return _readCall(c, &v->call);
+}
+
+parser_error_t _readVecCall(parser_context_t* c, pd_VecCall_t* v)
+{
+ compactInt_t clen;
+ pd_Call_t dummy;
+ CHECK_PARSER_ERR(_readCompactInt(c, &clen));
+ CHECK_PARSER_ERR(_getValue(&clen, &v->_len));
+
+ if (v->_len > MAX_CALL_VEC_SIZE) {
+ return parser_tx_call_vec_too_large;
+ }
+
+ v->_ptr = c->buffer + c->offset;
+ v->_lenBuffer = c->offset;
+ if (v->_len == 0) {
+ return parser_unexpected_buffer_end;
+ }
+
+ for (uint64_t i = 0; i < v->_len; i++) {
+ c->tx_obj->nestCallIdx.slotIdx = 0;
+ CHECK_ERROR(_readCall(c, &dummy))
+ }
+ v->_lenBuffer = c->offset - v->_lenBuffer;
+ v->callTxVersion = c->tx_obj->transactionVersion;
+
+ return parser_ok;
+}
+
+parser_error_t _readCompactBalanceOf(parser_context_t* c, pd_CompactBalanceOf_t* v)
+{
+ CHECK_INPUT();
+ CHECK_ERROR(_readCompactInt(c, &v->value));
+ return parser_ok;
+}
+
+parser_error_t _readHash(parser_context_t* c, pd_Hash_t* v) {
+ GEN_DEF_READARRAY(32)
+}
+
+parser_error_t _readHeartbeat(parser_context_t* c, pd_Heartbeat_t* v)
+{
+ return parser_not_supported;
+}
+
+parser_error_t _readVecHeader(parser_context_t* c, pd_VecHeader_t* v) {
+ GEN_DEF_READVECTOR(Header)
+}
+
+parser_error_t _readVecTupleDataData(parser_context_t* c, pd_VecTupleDataData_t* v) {
+ GEN_DEF_READVECTOR(TupleDataData)
+}
+
+parser_error_t _readOptionu8_array_20(parser_context_t* c, pd_Optionu8_array_20_t* v)
+{
+ CHECK_ERROR(_readUInt8(c, &v->some))
+ if (v->some > 0) {
+ CHECK_ERROR(_readu8_array_20(c, &v->contained))
+ }
+ return parser_ok;
+}
+
+///////////////////////////////////
+///////////////////////////////////
+///////////////////////////////////
+
+parser_error_t _toStringbool(
+ const pd_bool_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+
+ *pageCount = 1;
+ switch (*v) {
+ case 0:
+ snprintf(outValue, outValueLen, "False");
+ return parser_ok;
+ case 1:
+ snprintf(outValue, outValueLen, "True");
+ return parser_ok;
+ }
+
+ return parser_not_supported;
+}
+
+parser_error_t _toStringu8(
+ const pd_u8_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+ char bufferUI[50];
+
+ uint64_to_str(bufferUI, sizeof(bufferUI), *v);
+ pageString(outValue, outValueLen, bufferUI, pageIdx, pageCount);
+ return parser_ok;
+}
+
+parser_error_t _toStringu16(
+ const pd_u16_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+ char bufferUI[50];
+
+ uint64_to_str(bufferUI, sizeof(bufferUI), *v);
+ pageString(outValue, outValueLen, bufferUI, pageIdx, pageCount);
+ return parser_ok;
+}
+
+parser_error_t _toStringu32(
+ const pd_u32_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+ char bufferUI[100];
+
+ uint64_to_str(bufferUI, sizeof(bufferUI), *v);
+ pageString(outValue, outValueLen, bufferUI, pageIdx, pageCount);
+ return parser_ok;
+}
+
+parser_error_t _toStringu64(
+ const pd_u64_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+ char bufferUI[100];
+
+ uint64_to_str(bufferUI, sizeof(bufferUI), *v);
+ pageString(outValue, outValueLen, bufferUI, pageIdx, pageCount);
+ return parser_ok;
+}
+
+parser_error_t _toStringBlockNumber(
+ const pd_BlockNumber_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ return _toStringu32(v, outValue, outValueLen, pageIdx, pageCount);
+}
+
+parser_error_t _toStringCompactu32(
+ const pd_Compactu32_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ return _toStringCompactInt(v, 0, 0, "", outValue, outValueLen, pageIdx, pageCount);
+}
+
+///////////////////////////////////
+///////////////////////////////////
+///////////////////////////////////
+
+parser_error_t _toStringCompactBlockNumber(
+ const pd_CompactBlockNumber_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ return _toStringCompactInt(v, 0, 0, "", outValue, outValueLen, pageIdx, pageCount);
+}
+
+parser_error_t _toStringData(
+ const pd_Data_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+
+ if (v->_ptr == NULL || v->_len == 0) {
+ return parser_unexpected_value;
+ }
+
+ if (v->type > Data_e_NONE && v->type <= Data_e_RAW_VECU8) {
+ const uint8_t bufferSize = ((uint8_t)v->type - 1);
+ GEN_DEF_TOSTRING_ARRAY(bufferSize)
+ }
+
+ switch (v->type) {
+ case Data_e_NONE:
+ *pageCount = 1;
+ snprintf(outValue, outValueLen, "None");
+ return parser_ok;
+ case Data_e_RAW_VECU8:
+ // This should have been handled before (1..33)
+ return parser_unexpected_value;
+ case Data_e_BLAKETWO256U8_32:
+ case Data_e_SHA256_U8_32:
+ case Data_e_KECCAK256_U8_32:
+ case Data_e_SHATHREE256_U8_32:
+ default:
+ break;
+ }
+
+ return parser_print_not_supported;
+}
+
+parser_error_t _toStringTupleDataData(
+ const pd_TupleDataData_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+
+ uint8_t pages[2];
+ CHECK_ERROR(_toStringData(&v->data1, outValue, outValueLen, 0, &pages[0]))
+ CHECK_ERROR(_toStringData(&v->data2, outValue, outValueLen, 0, &pages[1]))
+
+ *pageCount = 0;
+ for (uint8_t i = 0; i < (uint8_t)sizeof(pages); i++) {
+ *pageCount += pages[i];
+ }
+
+ if (pageIdx > *pageCount) {
+ return parser_display_idx_out_of_range;
+ }
+
+ if (pageIdx < pages[0]) {
+ CHECK_ERROR(_toStringData(&v->data1, outValue, outValueLen, pageIdx, &pages[0]))
+ return parser_ok;
+ }
+ pageIdx -= pages[0];
+
+ /////////
+ /////////
+
+ if (pageIdx < pages[1]) {
+ CHECK_ERROR(_toStringData(&v->data2, outValue, outValueLen, pageIdx, &pages[1]))
+ return parser_ok;
+ }
+ pageIdx -= pages[1];
+
+ return parser_display_idx_out_of_range;
+}
+
+parser_error_t _toStringu8_array_20(
+ const pd_u8_array_20_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount) {
+ GEN_DEF_TOSTRING_ARRAY(20)
+}
+
+parser_error_t _toStringBalance(
+ const pd_Balance_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+
+ char bufferUI[200];
+ MEMSET(outValue, 0, outValueLen);
+ MEMSET(bufferUI, 0, sizeof(bufferUI));
+ *pageCount = 1;
+
+ uint8_t bcdOut[100];
+ const uint16_t bcdOutLen = sizeof(bcdOut);
+
+ bignumLittleEndian_to_bcd(bcdOut, bcdOutLen, v->_ptr, 16);
+ if (!bignumLittleEndian_bcdprint(bufferUI, sizeof(bufferUI), bcdOut, bcdOutLen)) {
+ return parser_unexpected_buffer_end;
+ }
+
+ // Format number
+ if (intstr_to_fpstr_inplace(bufferUI, sizeof(bufferUI), COIN_AMOUNT_DECIMAL_PLACES) == 0) {
+ return parser_unexpected_value;
+ }
+
+ number_inplace_trimming(bufferUI, 1);
+ size_t size = strlen(bufferUI) + strlen(COIN_TICKER) + 2;
+ char _tmpBuffer[200];
+ MEMZERO(_tmpBuffer, sizeof(_tmpBuffer));
+ strcat(_tmpBuffer, COIN_TICKER);
+ strcat(_tmpBuffer, " ");
+ strcat(_tmpBuffer, bufferUI);
+ // print length: strlen(value) + strlen(COIN_TICKER) + strlen(" ") + nullChar
+ MEMZERO(bufferUI, sizeof(bufferUI));
+ snprintf(bufferUI, size, "%s", _tmpBuffer);
+
+ pageString(outValue, outValueLen, bufferUI, pageIdx, pageCount);
+ return parser_ok;
+}
+
+parser_error_t _toStringBytes(
+ const pd_Bytes_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ GEN_DEF_TOSTRING_ARRAY(v->_len);
+}
+
+parser_error_t _toStringCall(
+ const pd_Call_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+ *pageCount = 1;
+
+ parser_context_t ctx;
+
+ const uint8_t* buffer;
+ if (v->nestCallIdx.isTail) {
+ buffer = v->nestCallIdx._ptr;
+ } else {
+ buffer = v->nestCallIdx._nextPtr;
+ }
+
+ parser_init(&ctx, buffer, v->nestCallIdx._lenBuffer);
+ parser_tx_t _txObj;
+
+ pd_Call_t _call;
+ _call.nestCallIdx.isTail = false;
+
+ ctx.tx_obj = &_txObj;
+ _txObj.transactionVersion = *v->_txVerPtr;
+
+ ctx.tx_obj->nestCallIdx._ptr = NULL;
+ ctx.tx_obj->nestCallIdx._nextPtr = NULL;
+ ctx.tx_obj->nestCallIdx._lenBuffer = 0;
+ ctx.tx_obj->nestCallIdx.slotIdx = 0;
+ ctx.tx_obj->nestCallIdx.isTail = false;
+
+ // Read the Call, so we get the contained Method
+ parser_error_t err = _readCallImpl(&ctx, &_call, (pd_MethodNested_t*)&_txObj.method);
+ if (err != parser_ok) {
+ return err;
+ }
+
+ // Get num items of this current Call
+ uint8_t callNumItems = _getMethod_NumItems(*v->_txVerPtr, v->callIndex.moduleIdx, v->callIndex.idx);
+
+ // Count how many pages this call has (including nested ones if they exists)
+ for (uint8_t i = 0; i < callNumItems; i++) {
+ uint8_t itemPages = 0;
+ _getMethod_ItemValue(*v->_txVerPtr, &_txObj.method, _call.callIndex.moduleIdx, _call.callIndex.idx, i,
+ outValue, outValueLen, 0, &itemPages);
+ (*pageCount) += itemPages;
+ }
+
+ zb_check_canary();
+
+ if (pageIdx == 0) {
+ snprintf(outValue, outValueLen, "%s", _getMethod_Name(*v->_txVerPtr, v->callIndex.moduleIdx, v->callIndex.idx));
+ return parser_ok;
+ }
+
+ pageIdx--;
+
+ if (pageIdx > *pageCount) {
+ return parser_display_idx_out_of_range;
+ }
+
+ for (uint8_t i = 0; i < callNumItems; i++) {
+ uint8_t itemPages = 0;
+ _getMethod_ItemValue(*v->_txVerPtr, &_txObj.method, v->callIndex.moduleIdx, v->callIndex.idx, i,
+ outValue, outValueLen, 0, &itemPages);
+
+ if (pageIdx < itemPages) {
+ uint8_t tmp;
+ _getMethod_ItemValue(*v->_txVerPtr, &_txObj.method, v->callIndex.moduleIdx, v->callIndex.idx, i,
+ outValue, outValueLen, pageIdx, &tmp);
+ return parser_ok;
+ }
+
+ pageIdx -= itemPages;
+ }
+
+ return parser_display_idx_out_of_range;
+}
+
+parser_error_t _toStringHeader(
+ const pd_Header_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+ return parser_print_not_supported;
+}
+
+parser_error_t _toStringBalanceOf(
+ const pd_BalanceOf_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ return _toStringBalance(&v->value, outValue, outValueLen, pageIdx, pageCount);
+}
+
+parser_error_t _toStringProposal(
+ const pd_Proposal_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ return _toStringCall(&v->call, outValue, outValueLen, pageIdx, pageCount);
+}
+
+parser_error_t _toStringVecCall(
+ const pd_VecCall_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+ /* count number of pages, then output specific */
+ *pageCount = 0;
+ uint8_t chunkPageCount;
+ uint16_t currentPage, currentTotalPage = 0;
+ /* We need to do it twice because there is no memory to keep intermediate results*/
+ /* First count*/
+ parser_context_t ctx;
+ parser_init(&ctx, v->_ptr, v->_lenBuffer);
+ parser_tx_t _txObj;
+ pd_Call_t _call;
+ ctx.tx_obj = &_txObj;
+ _txObj.transactionVersion = v->callTxVersion;
+ _call._txVerPtr = &v->callTxVersion;
+ _call.nestCallIdx.isTail = true;
+
+ ctx.tx_obj->nestCallIdx.slotIdx = 0;
+ ctx.tx_obj->nestCallIdx._lenBuffer = 0;
+ ctx.tx_obj->nestCallIdx._ptr = NULL;
+ ctx.tx_obj->nestCallIdx._nextPtr = NULL;
+ ctx.tx_obj->nestCallIdx.isTail = true;
+
+ for (uint16_t i = 0; i < v->_len; i++) {
+ ctx.tx_obj->nestCallIdx._ptr = NULL;
+ ctx.tx_obj->nestCallIdx._nextPtr = NULL;
+ ctx.tx_obj->nestCallIdx.slotIdx = 0;
+ CHECK_ERROR(_readCallImpl(&ctx, &_call, (pd_MethodNested_t*)&_txObj.method));
+ CHECK_ERROR(_toStringCall(&_call, outValue, outValueLen, 0, &chunkPageCount));
+ (*pageCount) += chunkPageCount;
+ }
+
+ /* Then iterate until we can print the corresponding chunk*/
+ parser_init(&ctx, v->_ptr, v->_lenBuffer);
+ for (uint16_t i = 0; i < v->_len; i++) {
+ ctx.tx_obj->nestCallIdx._ptr = NULL;
+ ctx.tx_obj->nestCallIdx._nextPtr = NULL;
+ ctx.tx_obj->nestCallIdx.slotIdx = 0;
+ CHECK_ERROR(_readCallImpl(&ctx, &_call, (pd_MethodNested_t*)&_txObj.method));
+ chunkPageCount = 1;
+ currentPage = 0;
+ while (currentPage < chunkPageCount) {
+ CHECK_ERROR(_toStringCall(&_call, outValue, outValueLen, currentPage, &chunkPageCount));
+ if (currentTotalPage == pageIdx) {
+ return parser_ok;
+ }
+ currentPage++;
+ currentTotalPage++;
+ }
+ }
+
+ return parser_print_not_supported;
+}
+
+parser_error_t _toStringCompactBalanceOf(
+ const pd_CompactBalanceOf_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CHECK_ERROR(_toStringCompactInt(&v->value, COIN_AMOUNT_DECIMAL_PLACES, 0, COIN_TICKER, outValue, outValueLen, pageIdx, pageCount))
+ number_inplace_trimming(outValue, 1);
+ return parser_ok;
+}
+
+parser_error_t _toStringHash(
+ const pd_Hash_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount) {
+ GEN_DEF_TOSTRING_ARRAY(32)
+}
+
+parser_error_t _toStringHeartbeat(
+ const pd_Heartbeat_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+ return parser_print_not_supported;
+}
+
+parser_error_t _toStringVecHeader(
+ const pd_VecHeader_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount) {
+ GEN_DEF_TOSTRING_VECTOR(Header)
+}
+
+parser_error_t _toStringVecTupleDataData(
+ const pd_VecTupleDataData_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ GEN_DEF_TOSTRING_VECTOR(TupleDataData);
+}
+
+parser_error_t _toStringOptionu8_array_20(
+ const pd_Optionu8_array_20_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+
+ *pageCount = 1;
+ if (v->some > 0) {
+ CHECK_ERROR(_toStringu8_array_20(
+ &v->contained,
+ outValue, outValueLen,
+ pageIdx, pageCount));
+ } else {
+ snprintf(outValue, outValueLen, "None");
+ }
+ return parser_ok;
+}
+
+///////////////////////////////////
+///////////////////////////////////
+///////////////////////////////////
diff --git a/app/src/substrate_types.h b/app/src/substrate_types.h
new file mode 100644
index 0000000..9861c91
--- /dev/null
+++ b/app/src/substrate_types.h
@@ -0,0 +1,216 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "stdbool.h"
+#include
+#include
+
+// https://github.com/paritytech/substrate/blob/effe489951d1edab9d34846b1eefdfaf9511dab9/frame/identity/src/lib.rs
+#define Data_e_NONE 0
+#define Data_e_RAW_VECU8 33
+#define Data_e_BLAKETWO256U8_32 34
+#define Data_e_SHA256_U8_32 35
+#define Data_e_KECCAK256_U8_32 36
+#define Data_e_SHATHREE256_U8_32 37
+
+typedef uint8_t pd_bool_t;
+typedef uint8_t pd_u8_t;
+typedef uint16_t pd_u16_t;
+typedef uint32_t pd_u32_t;
+typedef uint64_t pd_u64_t;
+typedef uint32_t pd_BlockNumber_t;
+
+#define CHECK_ERROR(FUNC_CALL) \
+ { \
+ parser_error_t err = FUNC_CALL; \
+ if (err != parser_ok) \
+ return err; \
+ }
+
+typedef struct {
+ uint8_t moduleIdx;
+ uint8_t idx;
+} pd_CallIndex_t;
+
+typedef enum {
+ eEraImmortal = 0,
+ eEraMortal = 1
+} pd_ExtrinsicEra_e;
+
+// This type has a non-standard serialization
+// core/sr-primitives/src/generic/era.rs
+typedef struct {
+ pd_ExtrinsicEra_e type;
+ uint64_t period;
+ uint64_t phase;
+} pd_ExtrinsicEra_t;
+
+typedef struct {
+ const uint8_t* ptr;
+ uint8_t len;
+} compactInt_t;
+
+typedef struct {
+ uint32_t _lenBuffer;
+ const uint8_t* _ptr; // Pointer to actual
+ const uint8_t* _nextPtr; // Pointer to next Call
+ uint8_t slotIdx; // Count of nested calls
+ bool isTail;
+} pd_NestCallIdx_t;
+
+////////////////////////
+// Common types
+////////////////////////
+
+typedef struct {
+ uint8_t type;
+ const uint8_t* _ptr;
+ uint8_t _len;
+} pd_Data_t;
+
+typedef struct {
+ pd_Data_t data1;
+ pd_Data_t data2;
+} pd_TupleDataData_t;
+
+typedef struct {
+ const uint8_t* _ptr;
+} pd_u8_array_20_t;
+
+typedef struct {
+ const uint8_t* _ptr;
+} pd_Balance_t;
+
+typedef struct {
+ uint64_t _len;
+ const uint8_t* _ptr;
+} pd_Bytes_t;
+
+typedef struct {
+ pd_CallIndex_t callIndex;
+ const uint32_t* _txVerPtr;
+ pd_NestCallIdx_t nestCallIdx;
+} pd_Call_t;
+
+typedef struct {
+ // TODO: Not implemented
+ uint8_t _NOT_IMPLEMENTED__DO_NOT_USE;
+} pd_Header_t;
+
+typedef struct {
+ uint8_t some;
+ pd_u8_array_20_t contained;
+} pd_Optionu8_array_20_t;
+
+typedef struct {
+ uint64_t _len;
+ const uint8_t* _ptr;
+ uint64_t _lenBuffer;
+} pd_VecTupleDataData_t;
+
+typedef struct {
+ pd_Balance_t value;
+} pd_BalanceOf_t;
+
+typedef struct {
+ pd_Call_t call;
+} pd_Proposal_t;
+
+typedef struct {
+ uint64_t _len;
+ const uint8_t* _ptr;
+ uint64_t _lenBuffer;
+ uint32_t callTxVersion;
+} pd_VecCall_t;
+
+typedef struct {
+ compactInt_t value;
+} pd_CompactBalanceOf_t;
+
+typedef compactInt_t pd_CompactBlockNumber_t;
+
+typedef struct {
+ const uint8_t* _ptr;
+} pd_Hash_t;
+
+typedef struct {
+ // TODO: Not implemented
+ uint8_t _NOT_IMPLEMENTED__DO_NOT_USE;
+} pd_Heartbeat_t;
+
+typedef struct {
+ uint64_t _len;
+ const uint8_t* _ptr;
+ uint64_t _lenBuffer;
+} pd_VecHeader_t;
+
+////////////////////////
+// /Common types
+////////////////////////
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wextern-c-compat"
+#pragma clang diagnostic pop
+
+////////////////////////
+// Types that require out of order declaration
+////////////////////////
+
+typedef enum {
+ eAddressIndex = 0,
+ eAddressId = 1
+} pd_Address_e;
+
+typedef struct {
+ pd_Address_e type;
+ uint64_t idx;
+ const uint8_t* idPtr;
+} pd_Address_t;
+
+typedef struct {
+ compactInt_t index;
+} pd_CompactIndex_t;
+
+typedef struct {
+ compactInt_t value;
+} pd_CompactBalance_t;
+
+////////////////////////
+////////////////////////
+////////////////////////
+////////////////////////
+
+typedef compactInt_t pd_Compactu32_t; // u32
+typedef compactInt_t pd_Compactu64_t; // u64
+typedef compactInt_t pd_CompactAssignments_t;
+typedef compactInt_t pd_CompactBountyIndex_t;
+typedef compactInt_t pd_CompactEraIndex_t;
+typedef compactInt_t pd_CompactMemberCount_t;
+typedef compactInt_t pd_CompactMoment_t;
+typedef compactInt_t pd_CompactPropIndex_t;
+typedef compactInt_t pd_CompactProposalIndex_t;
+typedef compactInt_t pd_CompactReferendumIndex_t;
+typedef compactInt_t pd_CompactRegistrarIndex_t;
+typedef compactInt_t pd_CompactWeight_t;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/app/src/substrate_types_V3.c b/app/src/substrate_types_V3.c
new file mode 100644
index 0000000..c23bd1a
--- /dev/null
+++ b/app/src/substrate_types_V3.c
@@ -0,0 +1,1111 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#include "bignum.h"
+#include "coin.h"
+#include "parser_impl.h"
+#include "substrate_dispatch_V3.h"
+#include "substrate_strings.h"
+
+#include
+#include
+#include
+
+parser_error_t _readCompactMemberCount_V3(parser_context_t* c, pd_CompactMemberCount_V3_t* v)
+{
+ return _readCompactInt(c, v);
+}
+
+parser_error_t _readCompactMoment_V3(parser_context_t* c, pd_CompactMoment_V3_t* v)
+{
+ return _readCompactInt(c, v);
+}
+
+parser_error_t _readCompactProposalIndex_V3(parser_context_t* c, pd_CompactProposalIndex_V3_t* v)
+{
+ return _readCompactInt(c, v);
+}
+
+parser_error_t _readCompactRegistrarIndex_V3(parser_context_t* c, pd_CompactRegistrarIndex_V3_t* v)
+{
+ return _readCompactInt(c, v);
+}
+
+parser_error_t _readCompactWeight_V3(parser_context_t* c, pd_CompactWeight_V3_t* v)
+{
+ return _readCompactInt(c, v);
+}
+
+parser_error_t _readAccountId_V3(parser_context_t* c, pd_AccountId_V3_t* v) {
+ GEN_DEF_READARRAY(32)
+}
+
+parser_error_t _readAccountIndex_V3(parser_context_t* c, pd_AccountIndex_V3_t* v)
+{
+ return _readUInt32(c, &v->value);
+}
+
+parser_error_t _readAmendment_V3(parser_context_t* c, pd_Amendment_V3_t* v)
+{
+ return parser_not_supported;
+}
+
+parser_error_t _readBabeEquivocationProof_V3(parser_context_t* c, pd_BabeEquivocationProof_V3_t* v)
+{
+ return parser_not_supported;
+}
+
+parser_error_t _readCallHashOf_V3(parser_context_t* c, pd_CallHashOf_V3_t* v) {
+ GEN_DEF_READARRAY(32)
+}
+
+parser_error_t _readCertificateId_V3(parser_context_t* c, pd_CertificateId_V3_t* v)
+{
+ return parser_not_supported;
+}
+
+parser_error_t _readChangesTrieConfiguration_V3(parser_context_t* c, pd_ChangesTrieConfiguration_V3_t* v)
+{
+ CHECK_ERROR(_readu32(c, &v->digest_interval))
+ CHECK_ERROR(_readu32(c, &v->digest_levels))
+ return parser_ok;
+}
+
+parser_error_t _readCodeHash_V3(parser_context_t* c, pd_CodeHash_V3_t* v)
+{
+ return parser_not_supported;
+}
+
+parser_error_t _readCompactAccountIndex_V3(parser_context_t* c, pd_CompactAccountIndex_V3_t* v)
+{
+ return _readCompactInt(c, &v->value);
+}
+
+parser_error_t _readGrandpaEquivocationProof_V3(parser_context_t* c, pd_GrandpaEquivocationProof_V3_t* v)
+{
+ return parser_not_supported;
+}
+
+parser_error_t _readIdentityFields_V3(parser_context_t* c, pd_IdentityFields_V3_t* v)
+{
+ return parser_not_supported;
+}
+
+parser_error_t _readIdentityInfo_V3(parser_context_t* c, pd_IdentityInfo_V3_t* v)
+{
+ CHECK_ERROR(_readVecTupleDataData(c, &v->additional));
+ CHECK_ERROR(_readData(c, &v->display));
+ CHECK_ERROR(_readData(c, &v->legal));
+ CHECK_ERROR(_readData(c, &v->web));
+ CHECK_ERROR(_readData(c, &v->riot));
+ CHECK_ERROR(_readData(c, &v->email));
+ CHECK_ERROR(_readOptionu8_array_20(c, &v->pgp_fingerprint));
+ CHECK_ERROR(_readData(c, &v->image));
+ CHECK_ERROR(_readData(c, &v->twitter));
+ return parser_ok;
+}
+
+parser_error_t _readIdentityJudgement_V3(parser_context_t* c, pd_IdentityJudgement_V3_t* v)
+{
+ return parser_not_supported;
+}
+
+parser_error_t _readKeyOwnerProof_V3(parser_context_t* c, pd_KeyOwnerProof_V3_t* v)
+{
+ return parser_not_supported;
+}
+
+parser_error_t _readKeyValue_V3(parser_context_t* c, pd_KeyValue_V3_t* v) {
+ GEN_DEF_READARRAY(32)
+}
+
+parser_error_t _readKey_V3(parser_context_t* c, pd_Key_V3_t* v) {
+ GEN_DEF_READARRAY(32)
+}
+
+parser_error_t _readKeys_V3(parser_context_t* c, pd_Keys_V3_t* v) {
+ GEN_DEF_READARRAY(6 * 32)
+}
+
+parser_error_t _readLookupSource_V3(parser_context_t* c, pd_LookupSource_V3_t* v)
+{
+ CHECK_INPUT();
+ CHECK_ERROR(_readUInt8(c, &v->value))
+ switch (v->value) {
+ case 0: // Id
+ CHECK_ERROR(_readAccountId_V3(c, &v->id))
+ break;
+ case 1: // Index
+ CHECK_ERROR(_readCompactAccountIndex_V3(c, &v->index))
+ break;
+ case 2: // Raw
+ CHECK_ERROR(_readBytes(c, &v->raw))
+ break;
+ case 3: // Address32
+ GEN_DEF_READARRAY(32)
+ case 4: // Address20
+ GEN_DEF_READARRAY(20)
+ default:
+ return parser_unexpected_value;
+ }
+
+ return parser_ok;
+}
+
+parser_error_t _readMemberCount_V3(parser_context_t* c, pd_MemberCount_V3_t* v)
+{
+ return _readUInt32(c, &v->value);
+}
+
+parser_error_t _readOpaqueCall_V3(parser_context_t* c, pd_OpaqueCall_V3_t* v)
+{
+ // Encoded as Byte[], array size comes first
+ uint8_t size;
+ CHECK_ERROR(_readUInt8(c, &size))
+ return _readCall(c, &v->call);
+}
+
+parser_error_t _readPerbill_V3(parser_context_t* c, pd_Perbill_V3_t* v)
+{
+ return _readUInt32(c, &v->value);
+}
+
+parser_error_t _readPeriod_V3(parser_context_t* c, pd_Period_V3_t* v)
+{
+ return _readUInt64(c, &v->value);
+}
+
+parser_error_t _readPriority_V3(parser_context_t* c, pd_Priority_V3_t* v)
+{
+ CHECK_ERROR(_readu32(c, &v->stream_id))
+ CHECK_ERROR(_readStreamDependency_V3(c, &v->dependency))
+ return parser_ok;
+}
+
+parser_error_t _readProxyType_V3(parser_context_t* c, pd_ProxyType_V3_t* v)
+{
+ CHECK_INPUT()
+
+ CHECK_ERROR(_readUInt8(c, &v->value))
+ if (v->value > 3) {
+ return parser_value_out_of_range;
+ }
+
+ return parser_ok;
+}
+
+parser_error_t _readRegistrarIndex_V3(parser_context_t* c, pd_RegistrarIndex_V3_t* v)
+{
+ return _readUInt32(c, &v->value);
+}
+
+parser_error_t _readSchedule_V3(parser_context_t* c, pd_Schedule_V3_t* v)
+{
+ return parser_not_supported;
+}
+
+parser_error_t _readSignature_V3(parser_context_t* c, pd_Signature_V3_t* v) {
+ GEN_DEF_READARRAY(64)
+}
+
+parser_error_t _readStreamDependency_V3(parser_context_t* c, pd_StreamDependency_V3_t* v)
+{
+ CHECK_ERROR(_readu32(c, &v->dependency_id))
+ CHECK_ERROR(_readUInt8(c, &v->weight))
+ CHECK_ERROR(_readbool(c, &v->is_exclusive))
+ return parser_ok;
+}
+
+parser_error_t _readTimepoint_V3(parser_context_t* c, pd_Timepoint_V3_t* v)
+{
+ CHECK_ERROR(_readBlockNumber(c, &v->height))
+ CHECK_ERROR(_readu32(c, &v->index))
+ return parser_ok;
+}
+
+parser_error_t _readTupleAccountIdData_V3(parser_context_t* c, pd_TupleAccountIdData_V3_t* v)
+{
+ return parser_not_supported;
+}
+
+parser_error_t _readVestingScheduleOf_V3(parser_context_t* c, pd_VestingScheduleOf_V3_t* v)
+{
+ return parser_not_supported;
+}
+
+parser_error_t _readWeight_V3(parser_context_t* c, pd_Weight_V3_t* v)
+{
+ return _readUInt64(c, &v->value);
+}
+
+parser_error_t _readu8_array_32_V3(parser_context_t* c, pd_u8_array_32_V3_t* v) {
+ GEN_DEF_READARRAY(32)
+}
+
+parser_error_t _readVecAccountId_V3(parser_context_t* c, pd_VecAccountId_V3_t* v) {
+ GEN_DEF_READVECTOR(AccountId_V3)
+}
+
+parser_error_t _readVecKeyValue_V3(parser_context_t* c, pd_VecKeyValue_V3_t* v) {
+ GEN_DEF_READVECTOR(KeyValue_V3)
+}
+
+parser_error_t _readVecKey_V3(parser_context_t* c, pd_VecKey_V3_t* v) {
+ GEN_DEF_READVECTOR(Key_V3)
+}
+
+parser_error_t _readVecTupleAccountIdData_V3(parser_context_t* c, pd_VecTupleAccountIdData_V3_t* v) {
+ GEN_DEF_READVECTOR(TupleAccountIdData_V3)
+}
+
+parser_error_t _readOptionAccountId_V3(parser_context_t* c, pd_OptionAccountId_V3_t* v)
+{
+ CHECK_ERROR(_readUInt8(c, &v->some))
+ if (v->some > 0) {
+ CHECK_ERROR(_readAccountId_V3(c, &v->contained))
+ }
+ return parser_ok;
+}
+
+parser_error_t _readOptionChangesTrieConfiguration_V3(parser_context_t* c, pd_OptionChangesTrieConfiguration_V3_t* v)
+{
+ CHECK_ERROR(_readUInt8(c, &v->some))
+ if (v->some > 0) {
+ CHECK_ERROR(_readChangesTrieConfiguration_V3(c, &v->contained))
+ }
+ return parser_ok;
+}
+
+parser_error_t _readOptionPeriod_V3(parser_context_t* c, pd_OptionPeriod_V3_t* v)
+{
+ CHECK_ERROR(_readUInt8(c, &v->some))
+ if (v->some > 0) {
+ CHECK_ERROR(_readPeriod_V3(c, &v->contained))
+ }
+ return parser_ok;
+}
+
+parser_error_t _readOptionProxyType_V3(parser_context_t* c, pd_OptionProxyType_V3_t* v)
+{
+ CHECK_ERROR(_readUInt8(c, &v->some))
+ if (v->some > 0) {
+ CHECK_ERROR(_readProxyType_V3(c, &v->contained))
+ }
+ return parser_ok;
+}
+
+parser_error_t _readOptionTimepoint_V3(parser_context_t* c, pd_OptionTimepoint_V3_t* v)
+{
+ CHECK_ERROR(_readUInt8(c, &v->some))
+ if (v->some > 0) {
+ CHECK_ERROR(_readTimepoint_V3(c, &v->contained))
+ }
+ return parser_ok;
+}
+
+///////////////////////////////////
+///////////////////////////////////
+///////////////////////////////////
+
+parser_error_t _toStringCompactMemberCount_V3(
+ const pd_CompactMemberCount_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ return _toStringCompactInt(v, 0, 0, "", outValue, outValueLen, pageIdx, pageCount);
+}
+
+parser_error_t _toStringCompactMoment_V3(
+ const pd_CompactMoment_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ return _toStringCompactInt(v, 0, 0, "", outValue, outValueLen, pageIdx, pageCount);
+}
+
+parser_error_t _toStringCompactProposalIndex_V3(
+ const pd_CompactProposalIndex_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ return _toStringCompactInt(v, 0, 0, "", outValue, outValueLen, pageIdx, pageCount);
+}
+
+parser_error_t _toStringCompactRegistrarIndex_V3(
+ const pd_CompactRegistrarIndex_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ return _toStringCompactInt(v, 0, 0, "", outValue, outValueLen, pageIdx, pageCount);
+}
+
+parser_error_t _toStringCompactWeight_V3(
+ const pd_CompactWeight_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ return _toStringCompactInt(v, 0, 0, "", outValue, outValueLen, pageIdx, pageCount);
+}
+
+parser_error_t _toStringAccountId_V3(
+ const pd_AccountId_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ return _toStringPubkeyAsAddress(v->_ptr, outValue, outValueLen, pageIdx, pageCount);
+}
+
+parser_error_t _toStringAccountIndex_V3(
+ const pd_AccountIndex_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ return _toStringu32(&v->value, outValue, outValueLen, pageIdx, pageCount);
+}
+
+parser_error_t _toStringAmendment_V3(
+ const pd_Amendment_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+ return parser_print_not_supported;
+}
+
+parser_error_t _toStringBabeEquivocationProof_V3(
+ const pd_BabeEquivocationProof_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+ return parser_print_not_supported;
+}
+
+parser_error_t _toStringCallHashOf_V3(
+ const pd_CallHashOf_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount) {
+ GEN_DEF_TOSTRING_ARRAY(32)
+}
+
+parser_error_t _toStringCertificateId_V3(
+ const pd_CertificateId_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+ return parser_print_not_supported;
+}
+
+parser_error_t _toStringChangesTrieConfiguration_V3(
+ const pd_ChangesTrieConfiguration_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ // Get all pages first
+ uint8_t pages[2];
+ CHECK_ERROR(_toStringu32(&v->digest_interval, outValue, outValueLen, 0, &pages[0]))
+ CHECK_ERROR(_toStringu32(&v->digest_levels, outValue, outValueLen, 0, &pages[1]))
+
+ *pageCount = pages[0] + pages[1];
+ if (pageIdx > *pageCount) {
+ return parser_display_idx_out_of_range;
+ }
+
+ if (pageIdx < pages[0]) {
+ CHECK_ERROR(_toStringu32(&v->digest_interval, outValue, outValueLen, pageIdx, &pages[0]))
+ return parser_ok;
+ }
+ pageIdx -= pages[0];
+
+ if (pageIdx < pages[1]) {
+ CHECK_ERROR(_toStringu32(&v->digest_levels, outValue, outValueLen, pageIdx, &pages[1]))
+ return parser_ok;
+ }
+
+ return parser_display_idx_out_of_range;
+}
+
+parser_error_t _toStringCodeHash_V3(
+ const pd_CodeHash_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+ return parser_print_not_supported;
+}
+
+parser_error_t _toStringCompactAccountIndex_V3(
+ const pd_CompactAccountIndex_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ return _toStringCompactInt(&v->value, 0, 0, "", outValue, outValueLen, pageIdx, pageCount);
+}
+
+parser_error_t _toStringGrandpaEquivocationProof_V3(
+ const pd_GrandpaEquivocationProof_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+ return parser_print_not_supported;
+}
+
+parser_error_t _toStringIdentityFields_V3(
+ const pd_IdentityFields_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+ return parser_print_not_supported;
+}
+
+parser_error_t _toStringIdentityInfo_V3(
+ const pd_IdentityInfo_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+
+ // First measure number of pages
+ uint8_t pages[9];
+ CHECK_ERROR(_toStringVecTupleDataData(&v->additional, outValue, outValueLen, 0, &pages[0]))
+ CHECK_ERROR(_toStringData(&v->display, outValue, outValueLen, 0, &pages[1]))
+ CHECK_ERROR(_toStringData(&v->legal, outValue, outValueLen, 0, &pages[2]))
+ CHECK_ERROR(_toStringData(&v->web, outValue, outValueLen, 0, &pages[3]))
+ CHECK_ERROR(_toStringData(&v->riot, outValue, outValueLen, 0, &pages[4]))
+ CHECK_ERROR(_toStringData(&v->email, outValue, outValueLen, 0, &pages[5]))
+ CHECK_ERROR(_toStringOptionu8_array_20(&v->pgp_fingerprint, outValue, outValueLen, 0, &pages[6]))
+ CHECK_ERROR(_toStringData(&v->image, outValue, outValueLen, 0, &pages[7]))
+ CHECK_ERROR(_toStringData(&v->twitter, outValue, outValueLen, 0, &pages[8]))
+
+ *pageCount = 0;
+ for (uint8_t i = 0; i < (uint8_t)sizeof(pages); i++) {
+ *pageCount += pages[i];
+ }
+
+ if (pageIdx > *pageCount) {
+ return parser_display_idx_out_of_range;
+ }
+
+ if (pageIdx < pages[0]) {
+ CHECK_ERROR(_toStringVecTupleDataData(&v->additional, outValue, outValueLen, pageIdx, &pages[0]))
+ return parser_ok;
+ }
+ pageIdx -= pages[0];
+
+ /////////
+ /////////
+
+ if (pageIdx < pages[1]) {
+ CHECK_ERROR(_toStringData(&v->display, outValue, outValueLen, pageIdx, &pages[1]))
+ return parser_ok;
+ }
+ pageIdx -= pages[1];
+
+ /////////
+ /////////
+
+ if (pageIdx < pages[2]) {
+ CHECK_ERROR(_toStringData(&v->legal, outValue, outValueLen, pageIdx, &pages[2]))
+ return parser_ok;
+ }
+ pageIdx -= pages[2];
+
+ /////////
+ /////////
+
+ if (pageIdx < pages[3]) {
+ CHECK_ERROR(_toStringData(&v->web, outValue, outValueLen, pageIdx, &pages[3]))
+ return parser_ok;
+ }
+ pageIdx -= pages[3];
+
+ /////////
+ /////////
+
+ if (pageIdx < pages[4]) {
+ CHECK_ERROR(_toStringData(&v->riot, outValue, outValueLen, pageIdx, &pages[4]))
+ return parser_ok;
+ }
+ pageIdx -= pages[4];
+
+ /////////
+ /////////
+
+ if (pageIdx < pages[5]) {
+ CHECK_ERROR(_toStringData(&v->email, outValue, outValueLen, pageIdx, &pages[5]))
+ return parser_ok;
+ }
+ pageIdx -= pages[5];
+
+ /////////
+ /////////
+
+ if (pageIdx < pages[6]) {
+ CHECK_ERROR(_toStringOptionu8_array_20(&v->pgp_fingerprint, outValue, outValueLen, pageIdx, &pages[6]))
+ return parser_ok;
+ }
+ pageIdx -= pages[6];
+
+ /////////
+ /////////
+
+ if (pageIdx < pages[7]) {
+ CHECK_ERROR(_toStringData(&v->image, outValue, outValueLen, pageIdx, &pages[7]))
+ return parser_ok;
+ }
+ pageIdx -= pages[7];
+
+ /////////
+ /////////
+
+ if (pageIdx < pages[8]) {
+ CHECK_ERROR(_toStringData(&v->twitter, outValue, outValueLen, pageIdx, &pages[8]))
+ return parser_ok;
+ }
+ pageIdx -= pages[8];
+
+ return parser_display_idx_out_of_range;
+}
+
+parser_error_t _toStringIdentityJudgement_V3(
+ const pd_IdentityJudgement_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+ return parser_print_not_supported;
+}
+
+parser_error_t _toStringKeyOwnerProof_V3(
+ const pd_KeyOwnerProof_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+ return parser_print_not_supported;
+}
+
+parser_error_t _toStringKeyValue_V3(
+ const pd_KeyValue_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+
+ return parser_print_not_supported;
+}
+
+parser_error_t _toStringKey_V3(
+ const pd_Key_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+
+ return parser_print_not_supported;
+}
+
+parser_error_t _toStringKeys_V3(
+ const pd_Keys_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount) {
+ GEN_DEF_TOSTRING_ARRAY(4 * 32)
+}
+
+parser_error_t _toStringLookupSource_V3(
+ const pd_LookupSource_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+ switch (v->value) {
+ case 0: // Id
+ CHECK_ERROR(_toStringAccountId_V3(&v->id, outValue, outValueLen, pageIdx, pageCount))
+ break;
+ case 1: // Index
+ CHECK_ERROR(_toStringCompactAccountIndex_V3(&v->index, outValue, outValueLen, pageIdx, pageCount))
+ break;
+ case 2: // Raw
+ CHECK_ERROR(_toStringBytes(&v->raw, outValue, outValueLen, pageIdx, pageCount))
+ break;
+ case 3: // Address32
+ {
+ GEN_DEF_TOSTRING_ARRAY(32)
+ }
+ case 4: // Address20
+ {
+ GEN_DEF_TOSTRING_ARRAY(20)
+ }
+ default:
+ return parser_not_supported;
+ }
+
+ return parser_ok;
+}
+
+parser_error_t _toStringMemberCount_V3(
+ const pd_MemberCount_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ return _toStringu32(&v->value, outValue, outValueLen, pageIdx, pageCount);
+}
+
+parser_error_t _toStringOpaqueCall_V3(
+ const pd_OpaqueCall_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ return _toStringCall(&v->call, outValue, outValueLen, pageIdx, pageCount);
+}
+
+parser_error_t _toStringPerbill_V3(
+ const pd_Perbill_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ char bufferUI[100];
+ char ratioBuffer[80];
+ MEMSET(outValue, 0, outValueLen);
+ MEMSET(ratioBuffer, 0, sizeof(ratioBuffer));
+ MEMSET(bufferUI, 0, sizeof(bufferUI));
+ *pageCount = 1;
+
+ if (fpuint64_to_str(ratioBuffer, sizeof(ratioBuffer), v->value, 7) == 0) {
+ return parser_unexpected_value;
+ }
+
+ snprintf(bufferUI, sizeof(bufferUI), "%s%%", ratioBuffer);
+ pageString(outValue, outValueLen, bufferUI, pageIdx, pageCount);
+ return parser_ok;
+}
+
+parser_error_t _toStringPeriod_V3(
+ const pd_Period_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ return _toStringu64(&v->value, outValue, outValueLen, pageIdx, pageCount);
+}
+
+parser_error_t _toStringPriority_V3(
+ const pd_Priority_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ // Get all pages first
+ uint8_t pages[2];
+ CHECK_ERROR(_toStringu32(&v->stream_id, outValue, outValueLen, 0, &pages[0]))
+ CHECK_ERROR(_toStringStreamDependency_V3(&v->dependency, outValue, outValueLen, 0, &pages[1]))
+
+ *pageCount = pages[0] + pages[1];
+ if (pageIdx > *pageCount) {
+ return parser_display_idx_out_of_range;
+ }
+
+ if (pageIdx < pages[0]) {
+ CHECK_ERROR(_toStringu32(&v->stream_id, outValue, outValueLen, pageIdx, &pages[0]))
+ return parser_ok;
+ }
+ pageIdx -= pages[0];
+
+ if (pageIdx < pages[1]) {
+ CHECK_ERROR(_toStringStreamDependency_V3(&v->dependency, outValue, outValueLen, pageIdx, &pages[1]))
+ return parser_ok;
+ }
+
+ return parser_display_idx_out_of_range;
+}
+
+parser_error_t _toStringProxyType_V3(
+ const pd_ProxyType_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+
+ *pageCount = 1;
+ switch (v->value) {
+ case 0:
+ snprintf(outValue, outValueLen, "Any");
+ break;
+ case 1:
+ snprintf(outValue, outValueLen, "NonTransfer");
+ break;
+ case 2:
+ snprintf(outValue, outValueLen, "Governance");
+ break;
+ case 3:
+ snprintf(outValue, outValueLen, "Staking");
+ break;
+ default:
+ return parser_print_not_supported;
+ }
+
+ return parser_ok;
+}
+
+parser_error_t _toStringRegistrarIndex_V3(
+ const pd_RegistrarIndex_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ return _toStringu32(&v->value, outValue, outValueLen, pageIdx, pageCount);
+}
+
+parser_error_t _toStringSchedule_V3(
+ const pd_Schedule_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+ return parser_print_not_supported;
+}
+
+parser_error_t _toStringSignature_V3(
+ const pd_Signature_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount) {
+ GEN_DEF_TOSTRING_ARRAY(64)
+}
+
+parser_error_t _toStringStreamDependency_V3(
+ const pd_StreamDependency_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+
+ // Index + count pages
+ uint8_t pages[3];
+ CHECK_ERROR(_toStringu32(&v->dependency_id, outValue, outValueLen, 0, &pages[0]))
+ CHECK_ERROR(_toStringu16((const pd_u16_t*)&v->weight, outValue, outValueLen, 0, &pages[1]))
+ CHECK_ERROR(_toStringbool(&v->is_exclusive, outValue, outValueLen, 0, &pages[2]))
+
+ *pageCount = pages[0] + pages[1] + pages[2];
+ if (pageIdx > *pageCount) {
+ return parser_display_idx_out_of_range;
+ }
+
+ if (pageIdx < pages[0]) {
+ CHECK_ERROR(_toStringu32(&v->dependency_id, outValue, outValueLen, pageIdx, &pages[0]))
+ return parser_ok;
+ }
+ pageIdx -= pages[0];
+
+ //////
+ if (pageIdx < pages[1]) {
+ CHECK_ERROR(_toStringu16((const pd_u16_t*)&v->weight, outValue, outValueLen, pageIdx, &pages[1]))
+ return parser_ok;
+ }
+ pageIdx -= pages[1];
+
+ //////
+ if (pageIdx < pages[2]) {
+ CHECK_ERROR(_toStringbool(&v->is_exclusive, outValue, outValueLen, pageIdx, &pages[2]))
+ return parser_ok;
+ }
+
+ return parser_display_idx_out_of_range;
+}
+
+parser_error_t _toStringTimepoint_V3(
+ const pd_Timepoint_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+
+ // Index + count pages
+ uint8_t pages[2];
+ CHECK_ERROR(_toStringBlockNumber(&v->height, outValue, outValueLen, 0, &pages[0]))
+ CHECK_ERROR(_toStringu32(&v->index, outValue, outValueLen, 0, &pages[1]))
+
+ *pageCount = pages[0] + pages[1];
+ if (pageIdx > *pageCount) {
+ return parser_display_idx_out_of_range;
+ }
+
+ if (pageIdx < pages[0]) {
+ CHECK_ERROR(_toStringBlockNumber(&v->height, outValue, outValueLen, pageIdx, &pages[0]))
+ return parser_ok;
+ }
+ pageIdx -= pages[0];
+
+ //////
+ if (pageIdx < pages[1]) {
+ CHECK_ERROR(_toStringu32(&v->index, outValue, outValueLen, pageIdx, &pages[1]))
+ return parser_ok;
+ }
+
+ return parser_display_idx_out_of_range;
+}
+
+parser_error_t _toStringTupleAccountIdData_V3(
+ const pd_TupleAccountIdData_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+ return parser_print_not_supported;
+}
+
+parser_error_t _toStringVestingScheduleOf_V3(
+ const pd_VestingScheduleOf_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+ return parser_print_not_supported;
+}
+
+parser_error_t _toStringWeight_V3(
+ const pd_Weight_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ return _toStringu64(&v->value, outValue, outValueLen, pageIdx, pageCount);
+}
+
+parser_error_t _toStringu8_array_32_V3(
+ const pd_u8_array_32_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount) {
+ GEN_DEF_TOSTRING_ARRAY(32)
+}
+
+parser_error_t _toStringVecAccountId_V3(
+ const pd_VecAccountId_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ GEN_DEF_TOSTRING_VECTOR(AccountId_V3);
+}
+
+parser_error_t _toStringVecKeyValue_V3(
+ const pd_VecKeyValue_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ GEN_DEF_TOSTRING_VECTOR(KeyValue_V3);
+}
+
+parser_error_t _toStringVecKey_V3(
+ const pd_VecKey_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ GEN_DEF_TOSTRING_VECTOR(Key_V3);
+}
+
+parser_error_t _toStringVecTupleAccountIdData_V3(
+ const pd_VecTupleAccountIdData_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ GEN_DEF_TOSTRING_VECTOR(TupleAccountIdData_V3);
+}
+
+parser_error_t _toStringOptionAccountId_V3(
+ const pd_OptionAccountId_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+
+ *pageCount = 1;
+ if (v->some > 0) {
+ CHECK_ERROR(_toStringAccountId_V3(
+ &v->contained,
+ outValue, outValueLen,
+ pageIdx, pageCount));
+ } else {
+ snprintf(outValue, outValueLen, "None");
+ }
+ return parser_ok;
+}
+
+parser_error_t _toStringOptionChangesTrieConfiguration_V3(
+ const pd_OptionChangesTrieConfiguration_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+
+ *pageCount = 1;
+ if (v->some > 0) {
+ CHECK_ERROR(_toStringChangesTrieConfiguration_V3(
+ &v->contained,
+ outValue, outValueLen,
+ pageIdx, pageCount));
+ } else {
+ snprintf(outValue, outValueLen, "None");
+ }
+ return parser_ok;
+}
+
+parser_error_t _toStringOptionPeriod_V3(
+ const pd_OptionPeriod_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+
+ *pageCount = 1;
+ if (v->some > 0) {
+ CHECK_ERROR(_toStringPeriod_V3(
+ &v->contained,
+ outValue, outValueLen,
+ pageIdx, pageCount));
+ } else {
+ snprintf(outValue, outValueLen, "None");
+ }
+ return parser_ok;
+}
+
+parser_error_t _toStringOptionProxyType_V3(
+ const pd_OptionProxyType_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+
+ *pageCount = 1;
+ if (v->some > 0) {
+ CHECK_ERROR(_toStringProxyType_V3(
+ &v->contained,
+ outValue, outValueLen,
+ pageIdx, pageCount));
+ } else {
+ snprintf(outValue, outValueLen, "None");
+ }
+ return parser_ok;
+}
+
+parser_error_t _toStringOptionTimepoint_V3(
+ const pd_OptionTimepoint_V3_t* v,
+ char* outValue,
+ uint16_t outValueLen,
+ uint8_t pageIdx,
+ uint8_t* pageCount)
+{
+ CLEAN_AND_CHECK()
+
+ *pageCount = 1;
+ if (v->some > 0) {
+ CHECK_ERROR(_toStringTimepoint_V3(
+ &v->contained,
+ outValue, outValueLen,
+ pageIdx, pageCount));
+ } else {
+ snprintf(outValue, outValueLen, "None");
+ }
+ return parser_ok;
+}
diff --git a/app/src/substrate_types_V3.h b/app/src/substrate_types_V3.h
new file mode 100644
index 0000000..ed5e692
--- /dev/null
+++ b/app/src/substrate_types_V3.h
@@ -0,0 +1,253 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "substrate_types.h"
+#include
+#include
+
+// Based
+// https://github.com/paritytech/substrate/blob/master/node/primitives/src/lib.rs
+
+typedef struct {
+ const uint8_t* _ptr;
+} pd_AccountId_V3_t;
+
+typedef struct {
+ pd_u32_t digest_interval;
+ pd_u32_t digest_levels;
+} pd_ChangesTrieConfiguration_V3_t;
+
+typedef struct {
+ compactInt_t value;
+} pd_CompactAccountIndex_V3_t;
+
+typedef struct {
+ const uint8_t* _ptr;
+} pd_KeyValue_V3_t;
+
+typedef struct {
+ const uint8_t* _ptr;
+} pd_Key_V3_t;
+
+typedef struct {
+ uint64_t value;
+} pd_Period_V3_t;
+
+typedef struct {
+ uint8_t value;
+} pd_ProxyType_V3_t;
+
+typedef struct {
+ pd_u32_t dependency_id;
+ uint8_t weight;
+ pd_bool_t is_exclusive;
+} pd_StreamDependency_V3_t;
+
+typedef struct {
+ pd_BlockNumber_t height;
+ uint32_t index;
+} pd_Timepoint_V3_t;
+
+typedef struct {
+ // TODO: Not implemented
+ uint8_t _NOT_IMPLEMENTED__DO_NOT_USE;
+} pd_TupleAccountIdData_V3_t;
+
+typedef struct {
+ // https://github.com/paritytech/substrate/blob/effe489951d1edab9d34846b1eefdfaf9511dab9/frame/identity/src/lib.rs#L276
+ pd_VecTupleDataData_t additional;
+ pd_Data_t display;
+ pd_Data_t legal;
+ pd_Data_t web;
+ pd_Data_t riot;
+ pd_Data_t email;
+ pd_Optionu8_array_20_t pgp_fingerprint;
+ pd_Data_t image;
+ pd_Data_t twitter;
+} pd_IdentityInfo_V3_t;
+
+typedef struct {
+ uint8_t value;
+ union {
+ pd_AccountId_V3_t id;
+ pd_CompactAccountIndex_V3_t index;
+ pd_Bytes_t raw;
+ const uint8_t* _ptr;
+ };
+} pd_LookupSource_V3_t;
+
+typedef struct {
+ pd_Call_t call;
+} pd_OpaqueCall_V3_t;
+
+typedef struct {
+ uint8_t some;
+ pd_ChangesTrieConfiguration_V3_t contained;
+} pd_OptionChangesTrieConfiguration_V3_t;
+
+typedef struct {
+ uint8_t some;
+ pd_Timepoint_V3_t contained;
+} pd_OptionTimepoint_V3_t;
+
+typedef struct {
+ uint32_t stream_id;
+ pd_StreamDependency_V3_t dependency;
+} pd_Priority_V3_t;
+
+typedef struct {
+ uint32_t value;
+} pd_AccountIndex_V3_t;
+
+typedef struct {
+ // TODO: Not implemented
+ uint8_t _NOT_IMPLEMENTED__DO_NOT_USE;
+} pd_Amendment_V3_t;
+
+typedef struct {
+ // TODO: Not implemented
+ uint8_t _NOT_IMPLEMENTED__DO_NOT_USE;
+} pd_BabeEquivocationProof_V3_t;
+
+typedef struct {
+ const uint8_t* _ptr;
+} pd_CallHashOf_V3_t;
+
+typedef struct {
+ // TODO: Not implemented
+ uint8_t _NOT_IMPLEMENTED__DO_NOT_USE;
+} pd_CertificateId_V3_t;
+
+typedef struct {
+ // TODO: Not implemented
+ uint8_t _NOT_IMPLEMENTED__DO_NOT_USE;
+} pd_CodeHash_V3_t;
+
+typedef compactInt_t pd_CompactMemberCount_V3_t;
+
+typedef compactInt_t pd_CompactMoment_V3_t;
+
+typedef compactInt_t pd_CompactProposalIndex_V3_t;
+
+typedef compactInt_t pd_CompactRegistrarIndex_V3_t;
+
+typedef compactInt_t pd_CompactWeight_V3_t;
+
+typedef struct {
+ // TODO: Not implemented
+ uint8_t _NOT_IMPLEMENTED__DO_NOT_USE;
+} pd_GrandpaEquivocationProof_V3_t;
+
+typedef struct {
+ // TODO: Not implemented
+ uint8_t _NOT_IMPLEMENTED__DO_NOT_USE;
+} pd_IdentityFields_V3_t;
+
+typedef struct {
+ // TODO: Not implemented
+ uint8_t _NOT_IMPLEMENTED__DO_NOT_USE;
+} pd_IdentityJudgement_V3_t;
+
+typedef struct {
+ // TODO: Not implemented
+ uint8_t _NOT_IMPLEMENTED__DO_NOT_USE;
+} pd_KeyOwnerProof_V3_t;
+
+typedef struct {
+ const uint8_t* _ptr;
+} pd_Keys_V3_t;
+
+typedef struct {
+ uint32_t value;
+} pd_MemberCount_V3_t;
+
+typedef struct {
+ uint8_t some;
+ pd_AccountId_V3_t contained;
+} pd_OptionAccountId_V3_t;
+
+typedef struct {
+ uint8_t some;
+ pd_Period_V3_t contained;
+} pd_OptionPeriod_V3_t;
+
+typedef struct {
+ uint8_t some;
+ pd_ProxyType_V3_t contained;
+} pd_OptionProxyType_V3_t;
+
+typedef struct {
+ uint32_t value;
+} pd_Perbill_V3_t;
+
+typedef struct {
+ uint32_t value;
+} pd_RegistrarIndex_V3_t;
+
+typedef struct {
+ // TODO: Not implemented
+ uint8_t _NOT_IMPLEMENTED__DO_NOT_USE;
+} pd_Schedule_V3_t;
+
+typedef struct {
+ const uint8_t* _ptr;
+} pd_Signature_V3_t;
+
+typedef struct {
+ uint64_t _len;
+ const uint8_t* _ptr;
+ uint64_t _lenBuffer;
+} pd_VecAccountId_V3_t;
+
+typedef struct {
+ uint64_t _len;
+ const uint8_t* _ptr;
+ uint64_t _lenBuffer;
+} pd_VecKeyValue_V3_t;
+
+typedef struct {
+ uint64_t _len;
+ const uint8_t* _ptr;
+ uint64_t _lenBuffer;
+} pd_VecKey_V3_t;
+
+typedef struct {
+ uint64_t _len;
+ const uint8_t* _ptr;
+ uint64_t _lenBuffer;
+} pd_VecTupleAccountIdData_V3_t;
+
+typedef struct {
+ // TODO: Not implemented
+ uint8_t _NOT_IMPLEMENTED__DO_NOT_USE;
+} pd_VestingScheduleOf_V3_t;
+
+typedef struct {
+ uint64_t value;
+} pd_Weight_V3_t;
+
+typedef struct {
+ const uint8_t* _ptr;
+} pd_u8_array_32_V3_t;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/cmake/cmake-modules b/cmake/cmake-modules
new file mode 160000
index 0000000..cf2e087
--- /dev/null
+++ b/cmake/cmake-modules
@@ -0,0 +1 @@
+Subproject commit cf2e087039f81d13e687cf6c2b1b382b9c1e756f
diff --git a/cmake/conan/CMakeLists.txt b/cmake/conan/CMakeLists.txt
new file mode 100644
index 0000000..4899e70
--- /dev/null
+++ b/cmake/conan/CMakeLists.txt
@@ -0,0 +1,12 @@
+# Download automatically, you can also just copy the conan.cmake file
+
+if (NOT EXISTS "${CMAKE_BINARY_DIR}/conan.cmake")
+ message(STATUS "Downloading conan.cmake from https://github.com/conan-io/cmake-conan")
+ file(DOWNLOAD "https://raw.githubusercontent.com/conan-io/cmake-conan/v0.13/conan.cmake"
+ "${CMAKE_BINARY_DIR}/conan.cmake")
+endif ()
+include(${CMAKE_BINARY_DIR}/conan.cmake)
+
+conan_check(REQUIRED)
+
+conan_cmake_run(CONANFILE conanfile.txt BASIC_SETUP CMAKE_TARGETS BUILD missing)
diff --git a/cmake/gtest/CMakeLists.txt b/cmake/gtest/CMakeLists.txt
new file mode 100644
index 0000000..5962ac3
--- /dev/null
+++ b/cmake/gtest/CMakeLists.txt
@@ -0,0 +1,32 @@
+##############################
+# Google Test
+# Based on instructions in https://github.com/google/googletest/tree/master/googletest#incorporating-into-an-existing-cmake-project
+# Download and unpack googletest at configure time
+configure_file(CMakeLists.txt.gtest.in ${CMAKE_BINARY_DIR}/googletest-download/CMakeLists.txt)
+
+execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
+ RESULT_VARIABLE result
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download)
+if (result)
+ message(FATAL_ERROR "CMake step for googletest failed: ${result}")
+endif ()
+
+execute_process(COMMAND ${CMAKE_COMMAND} --build .
+ RESULT_VARIABLE result
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download)
+if (result)
+ message(FATAL_ERROR "Build step for googletest failed: ${result}")
+endif ()
+
+# Prevent overriding the parent project's compiler/linker settings on Windows
+set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
+
+add_subdirectory(
+ ${CMAKE_BINARY_DIR}/googletest-src
+ ${CMAKE_BINARY_DIR}/googletest-build
+)
+
+if (CMAKE_VERSION VERSION_LESS 2.8.11)
+ include_directories("${gtest_SOURCE_DIR}/include")
+ include_directories("${gtest_SOURCE_DIR}/include")
+endif ()
diff --git a/cmake/gtest/CMakeLists.txt.gtest.in b/cmake/gtest/CMakeLists.txt.gtest.in
new file mode 100644
index 0000000..202d3c3
--- /dev/null
+++ b/cmake/gtest/CMakeLists.txt.gtest.in
@@ -0,0 +1,16 @@
+# Based on https://github.com/google/googletest/tree/master/googletest#incorporating-into-an-existing-cmake-project
+cmake_minimum_required(VERSION 2.8.2)
+
+project(googletest-download NONE)
+
+include(ExternalProject)
+ExternalProject_Add(googletest
+ GIT_REPOSITORY https://github.com/google/googletest.git
+ GIT_TAG master
+ SOURCE_DIR "${CMAKE_BINARY_DIR}/googletest-src"
+ BINARY_DIR "${CMAKE_BINARY_DIR}/googletest-build"
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ TEST_COMMAND ""
+ )
diff --git a/conanfile.txt b/conanfile.txt
new file mode 100644
index 0000000..0d3d2a7
--- /dev/null
+++ b/conanfile.txt
@@ -0,0 +1,6 @@
+[requires]
+jsoncpp/1.9.3
+fmt/7.0.2
+
+[generators]
+cmake
diff --git a/deps/BLAKE2 b/deps/BLAKE2
new file mode 160000
index 0000000..997fa5b
--- /dev/null
+++ b/deps/BLAKE2
@@ -0,0 +1 @@
+Subproject commit 997fa5ba1e14b52c554fb03ce39e579e6f27b90c
diff --git a/deps/ledger-zxlib/.circleci/config.yml b/deps/ledger-zxlib/.circleci/config.yml
new file mode 100644
index 0000000..0c981f7
--- /dev/null
+++ b/deps/ledger-zxlib/.circleci/config.yml
@@ -0,0 +1,19 @@
+version: 2
+jobs:
+ build:
+ docker:
+ - image: ubuntu:18.04
+ steps:
+ - run:
+ name: Install dependencies
+ command: apt update && apt-get -y install build-essential git sudo wget cmake libssl-dev libgmp-dev autoconf libtool
+ - checkout
+ - run: git submodule update --init --recursive
+ - run: cmake . && make
+ - run: export GTEST_COLOR=1 && ctest -VV
+
+workflows:
+ version: 2
+ build_all:
+ jobs:
+ - build
diff --git a/deps/ledger-zxlib/.editorconfig b/deps/ledger-zxlib/.editorconfig
new file mode 100644
index 0000000..2d7db14
--- /dev/null
+++ b/deps/ledger-zxlib/.editorconfig
@@ -0,0 +1,16 @@
+# top-most EditorConfig file
+root = true
+
+[*]
+charset = utf-8
+trim_trailing_whitespace = true
+end_of_line = lf
+insert_final_newline = true
+
+[*.{c,h,cpp,hpp}]
+indent_style = space
+indent_size = 4
+
+[*.{yml,sh}]
+indent_style = space
+indent_size = 2
diff --git a/deps/ledger-zxlib/.gitignore b/deps/ledger-zxlib/.gitignore
new file mode 100644
index 0000000..d3d05a3
--- /dev/null
+++ b/deps/ledger-zxlib/.gitignore
@@ -0,0 +1,4 @@
+
+\.idea/
+
+cmake-build-debug/
diff --git a/deps/ledger-zxlib/CMakeLists.txt b/deps/ledger-zxlib/CMakeLists.txt
new file mode 100644
index 0000000..a8937e7
--- /dev/null
+++ b/deps/ledger-zxlib/CMakeLists.txt
@@ -0,0 +1,57 @@
+#*******************************************************************************
+#* (c) 2018 Zondax GmbH
+#*
+#* Licensed under the Apache License, Version 2.0 (the "License");
+#* you may not use this file except in compliance with the License.
+#* You may obtain a copy of the License at
+#*
+#* http://www.apache.org/licenses/LICENSE-2.0
+#*
+#* Unless required by applicable law or agreed to in writing, software
+#* distributed under the License is distributed on an "AS IS" BASIS,
+#* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#* See the License for the specific language governing permissions and
+#* limitations under the License.
+#********************************************************************************
+cmake_minimum_required(VERSION 3.0)
+project(ledger-zxlib)
+
+set(CMAKE_CXX_STANDARD 11)
+
+add_subdirectory(cmake/gtest)
+
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}/include
+)
+
+###############
+
+file(GLOB_RECURSE ZXLIB_SRC
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/*.c
+ )
+
+file(GLOB_RECURSE TESTS_SRC
+ ${CMAKE_CURRENT_SOURCE_DIR}/tests/*.cpp
+ )
+
+###############
+set(BUILD_TESTS OFF CACHE BOOL "Enables tests")
+
+add_library(zxlib STATIC ${ZXLIB_SRC})
+target_include_directories(zxlib PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+enable_testing()
+
+add_executable(zxlib_tests
+ ${TESTS_SRC}
+ )
+
+target_include_directories(zxlib_tests PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}/include
+ ${gtest_SOURCE_DIR}/include
+ ${gmock_SOURCE_DIR}/include
+ )
+
+target_link_libraries(zxlib_tests gtest_main zxlib)
+
+add_test(ZXLIB_TESTS zxlib_tests)
diff --git a/deps/ledger-zxlib/LICENSE b/deps/ledger-zxlib/LICENSE
new file mode 100644
index 0000000..0fa613e
--- /dev/null
+++ b/deps/ledger-zxlib/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 2018-2020 Zondax GmbH
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/deps/ledger-zxlib/README.md b/deps/ledger-zxlib/README.md
new file mode 100644
index 0000000..9dabbf5
--- /dev/null
+++ b/deps/ledger-zxlib/README.md
@@ -0,0 +1,5 @@
+# ledger-zxlib
+
+[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
+[![CircleCI](https://circleci.com/gh/Zondax/ledger-zxlib/tree/master.svg?style=shield)](https://circleci.com/gh/Zondax/ledger-zxlib/tree/master)
+[![CodeFactor](https://www.codefactor.io/repository/github/zondax/ledger-zxlib/badge)](https://www.codefactor.io/repository/github/zondax/ledger-zxlib)
diff --git a/deps/ledger-zxlib/app/common/view.c b/deps/ledger-zxlib/app/common/view.c
new file mode 100644
index 0000000..8fc8d41
--- /dev/null
+++ b/deps/ledger-zxlib/app/common/view.c
@@ -0,0 +1,298 @@
+/*******************************************************************************
+* (c) 2018, 2019 Zondax GmbH
+* (c) 2016 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 "view.h"
+#include "coin.h"
+#include "view_internal.h"
+#include "crypto.h"
+
+#include "actions.h"
+#include "apdu_codes.h"
+#include "ux.h"
+#include "bagl.h"
+#include "zxmacros.h"
+#include "view_templates.h"
+#include "tx.h"
+#include "addr.h"
+#include "app_mode.h"
+#include "zxerror.h"
+
+#include
+#include
+#include
+
+view_t viewdata;
+
+void h_approve(unsigned int _) {
+ zemu_log_stack("h_approve");
+
+ UNUSED(_);
+ view_idle_show(0, NULL);
+ UX_WAIT();
+ if (viewdata.viewfuncAccept != NULL) {
+ viewdata.viewfuncAccept();
+ }
+}
+
+void h_reject(unsigned int _) {
+ zemu_log_stack("h_reject");
+
+ UNUSED(_);
+ view_idle_show(0, NULL);
+ UX_WAIT();
+ app_reject();
+}
+
+void h_error_accept(unsigned int _) {
+ UNUSED(_);
+ view_idle_show(0, NULL);
+ UX_WAIT();
+ app_reply_error();
+}
+
+///////////////////////////////////
+// Paging related
+
+void h_paging_init() {
+ zemu_log_stack("h_paging_init");
+
+ viewdata.itemIdx = 0;
+ viewdata.pageIdx = 0;
+ viewdata.pageCount = 1;
+}
+
+bool h_paging_can_increase() {
+ if (viewdata.pageIdx + 1 < viewdata.pageCount) {
+ zemu_log_stack("h_paging_can_increase");
+ return true;
+ }
+
+ // passed page count, go to next index
+ if (viewdata.itemCount > 0 && viewdata.itemIdx < (viewdata.itemCount - 1 + INCLUDE_ACTIONS_COUNT)) {
+ zemu_log_stack("h_paging_can_increase");
+ return true;
+ }
+
+ zemu_log_stack("h_paging_can_increase NO");
+ return false;
+}
+
+void h_paging_increase() {
+ zemu_log_stack("h_paging_increase");
+
+ if (viewdata.pageIdx + 1 < viewdata.pageCount) {
+ // increase page
+ viewdata.pageIdx++;
+ return;
+ }
+
+ // passed page count, go to next index
+ if (viewdata.itemCount > 0 && viewdata.itemIdx < (viewdata.itemCount - 1 + INCLUDE_ACTIONS_COUNT)) {
+ viewdata.itemIdx++;
+ viewdata.pageIdx = 0;
+ }
+}
+
+bool h_paging_can_decrease() {
+ if (viewdata.pageIdx != 0) {
+ zemu_log_stack("h_paging_can_decrease");
+ return true;
+ }
+
+ if (viewdata.itemIdx > 0) {
+ zemu_log_stack("h_paging_can_decrease");
+ return true;
+ }
+
+ zemu_log_stack("h_paging_can_decrease NO");
+ return false;
+}
+
+void h_paging_decrease() {
+ char buffer[50];
+ snprintf(buffer, sizeof(buffer), "h_paging_decrease Idx %d", viewdata.itemIdx);
+ zemu_log_stack(buffer);
+
+ if (viewdata.pageIdx != 0) {
+ viewdata.pageIdx--;
+ zemu_log_stack("page--");
+ return;
+ }
+
+ if (viewdata.itemIdx > 0) {
+ viewdata.itemIdx--;
+ zemu_log_stack("item--");
+ // jump to last page. update will cap this value
+ viewdata.pageIdx = 255;
+ }
+}
+
+///////////////////////////////////
+// Paging related
+
+#ifdef INCLUDE_ACTIONS_AS_ITEMS
+bool is_accept_item(){
+ return viewdata.itemIdx == viewdata.itemCount - 1;
+}
+
+void set_accept_item(){
+ viewdata.itemIdx = viewdata.itemCount - 1;
+ viewdata.pageIdx = 0;
+}
+
+bool is_reject_item(){
+ return viewdata.itemIdx == viewdata.itemCount;
+}
+#endif
+
+void h_review_action() {
+#ifdef INCLUDE_ACTIONS_AS_ITEMS
+ if( is_accept_item() ){
+ zemu_log_stack("action_accept");
+ h_approve(1);
+ return;
+ }
+
+ if( is_reject_item() ){
+ zemu_log_stack("action_reject");
+ h_reject(1);
+ return;
+ }
+
+ zemu_log_stack("quick accept");
+ if (app_mode_expert()) {
+ set_accept_item();
+ h_review_update();
+ return;
+ }
+#endif
+};
+
+zxerr_t h_review_update_data() {
+ if (viewdata.viewfuncGetNumItems == NULL) {
+ zemu_log_stack("h_review_update_data - GetNumItems==NULL");
+ return zxerr_no_data;
+ }
+
+ char buffer[20];
+ snprintf(buffer, sizeof(buffer), "update Idx %d/%d", viewdata.itemIdx, viewdata.pageIdx);
+ zemu_log_stack(buffer);
+
+#ifdef INCLUDE_ACTIONS_AS_ITEMS
+ viewdata.pageCount = 1;
+
+ if( is_accept_item() ){
+ snprintf(viewdata.key, MAX_CHARS_PER_KEY_LINE, "%s","");
+ snprintf(viewdata.value, MAX_CHARS_PER_VALUE1_LINE, "%s", APPROVE_LABEL);
+ splitValueField();
+ zemu_log_stack("show_accept_action - accept item");
+ viewdata.pageIdx = 0;
+ return zxerr_ok;
+ }
+
+ if( is_reject_item() ){
+ snprintf(viewdata.key, MAX_CHARS_PER_KEY_LINE, "%s", "");
+ snprintf(viewdata.value, MAX_CHARS_PER_VALUE1_LINE, "%s", REJECT_LABEL);
+ splitValueField();
+ zemu_log_stack("show_reject_action - reject item");
+ viewdata.pageIdx = 0;
+ return zxerr_ok;
+ }
+#endif
+
+ do {
+ viewdata.pageCount = 1;
+ CHECK_ZXERR(viewdata.viewfuncGetNumItems(&viewdata.itemCount))
+
+ // be sure we are not out of bounds
+ CHECK_ZXERR(viewdata.viewfuncGetItem(
+ viewdata.itemIdx,
+ viewdata.key, MAX_CHARS_PER_KEY_LINE,
+ viewdata.value, MAX_CHARS_PER_VALUE1_LINE,
+ 0, &viewdata.pageCount))
+ if (viewdata.pageCount != 0 && viewdata.pageIdx > viewdata.pageCount) {
+ // try again and get last page
+ viewdata.pageIdx = viewdata.pageCount - 1;
+ }
+ CHECK_ZXERR(viewdata.viewfuncGetItem(
+ viewdata.itemIdx,
+ viewdata.key, MAX_CHARS_PER_KEY_LINE,
+ viewdata.value, MAX_CHARS_PER_VALUE1_LINE,
+ viewdata.pageIdx, &viewdata.pageCount))
+
+ viewdata.itemCount++;
+
+ if (viewdata.pageCount > 1) {
+ uint8_t keyLen = strlen(viewdata.key);
+ if (keyLen < MAX_CHARS_PER_KEY_LINE) {
+ snprintf(viewdata.key + keyLen,
+ MAX_CHARS_PER_KEY_LINE - keyLen,
+ " [%d/%d]",
+ viewdata.pageIdx + 1,
+ viewdata.pageCount);
+ }
+ }
+
+ if (viewdata.pageCount == 0) {
+ h_paging_increase();
+ }
+ } while (viewdata.pageCount == 0);
+
+ splitValueField();
+ return zxerr_ok;
+}
+
+///////////////////////////////////
+// General
+
+void io_seproxyhal_display(const bagl_element_t *element) {
+ io_seproxyhal_display_default((bagl_element_t *) element);
+}
+
+void view_init(void) {
+ UX_INIT();
+#ifdef APP_SECRET_MODE_ENABLED
+ viewdata.secret_click_count = 0;
+#endif
+}
+
+void view_idle_show(uint8_t item_idx, char *statusString) {
+ view_idle_show_impl(item_idx, statusString);
+}
+
+void view_message_show(char *title, char *message) {
+ view_message_impl(title, message);
+}
+
+void view_review_init(viewfunc_getItem_t viewfuncGetItem,
+ viewfunc_getNumItems_t viewfuncGetNumItems,
+ viewfunc_accept_t viewfuncAccept) {
+ viewdata.viewfuncGetItem = viewfuncGetItem;
+ viewdata.viewfuncGetNumItems = viewfuncGetNumItems;
+ viewdata.viewfuncAccept = viewfuncAccept;
+}
+
+void view_review_show() {
+ view_review_show_impl();
+}
+
+void view_error_show() {
+ snprintf(viewdata.key, MAX_CHARS_PER_KEY_LINE, "ERROR");
+ snprintf(viewdata.value, MAX_CHARS_PER_VALUE1_LINE, "SHOWING DATA");
+ splitValueField();
+ view_error_show_impl();
+}
diff --git a/deps/ledger-zxlib/app/common/view.h b/deps/ledger-zxlib/app/common/view.h
new file mode 100644
index 0000000..21a3e42
--- /dev/null
+++ b/deps/ledger-zxlib/app/common/view.h
@@ -0,0 +1,59 @@
+/*******************************************************************************
+* (c) 2018-2020 Zondax GmbH
+* (c) 2016 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 "coin.h"
+#include "zxerror.h"
+
+#if defined(LEDGER_SPECIFIC)
+#include "bolos_target.h"
+#if defined(BOLOS_SDK)
+#include "os.h"
+#include "cx.h"
+#endif
+#endif
+
+typedef zxerr_t (*viewfunc_getNumItems_t)(uint8_t *num_items);
+
+typedef zxerr_t (*viewfunc_getItem_t)(int8_t displayIdx,
+ char *outKey, uint16_t outKeyLen,
+ char *outVal, uint16_t outValLen,
+ uint8_t pageIdx, uint8_t *pageCount);
+
+typedef void (*viewfunc_accept_t)();
+
+#ifdef APP_SECRET_MODE_ENABLED
+zxerr_t secret_enabled();
+#endif
+
+/// view_init (initializes UI)
+void view_init();
+
+/// view_idle_show (idle view - main menu + status)
+void view_idle_show(uint8_t item_idx, char *statusString);
+
+void view_message_show(char *title, char *message);
+
+/// view_error (error view)
+void view_error_show();
+
+void view_review_init(viewfunc_getItem_t viewfuncGetItem,
+ viewfunc_getNumItems_t viewfuncGetNumItems,
+ viewfunc_accept_t viewfuncAccept);
+
+void view_review_show();
diff --git a/deps/ledger-zxlib/app/common/view_internal.h b/deps/ledger-zxlib/app/common/view_internal.h
new file mode 100644
index 0000000..d946838
--- /dev/null
+++ b/deps/ledger-zxlib/app/common/view_internal.h
@@ -0,0 +1,127 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+* (c) 2016 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 "coin.h"
+#include "zxerror.h"
+#include "view.h"
+
+#define CUR_FLOW G_ux.flow_stack[G_ux.stack_count-1]
+
+#if defined(TARGET_NANOX)
+#define MAX_CHARS_PER_KEY_LINE 64
+#define MAX_CHARS_PER_VALUE1_LINE 4096
+#define MAX_CHARS_HEXMESSAGE 160
+#else
+#define MAX_CHARS_PER_KEY_LINE (17+1)
+#define MAX_CHARS_PER_VALUE_LINE (17)
+#define MAX_CHARS_PER_VALUE1_LINE (2*MAX_CHARS_PER_VALUE_LINE+1)
+#define MAX_CHARS_PER_VALUE2_LINE (MAX_CHARS_PER_VALUE_LINE+1)
+#define MAX_CHARS_HEXMESSAGE 40
+#endif
+
+// This takes data from G_io_apdu_buffer that is prefilled with the address
+
+#define APPROVE_LABEL "APPROVE"
+#define REJECT_LABEL "REJECT"
+
+#if defined(TARGET_NANOS)
+#define INCLUDE_ACTIONS_AS_ITEMS 2
+#define INCLUDE_ACTIONS_COUNT (INCLUDE_ACTIONS_AS_ITEMS-1)
+#else
+#define INCLUDE_ACTIONS_COUNT 0
+#endif
+
+typedef struct {
+ struct {
+ char key[MAX_CHARS_PER_KEY_LINE];
+ char value[MAX_CHARS_PER_VALUE1_LINE];
+#if defined(TARGET_NANOS)
+ char value2[MAX_CHARS_PER_VALUE2_LINE];
+#endif
+ };
+ viewfunc_getItem_t viewfuncGetItem;
+ viewfunc_getNumItems_t viewfuncGetNumItems;
+ viewfunc_accept_t viewfuncAccept;
+
+#ifdef APP_SECRET_MODE_ENABLED
+ uint8_t secret_click_count;
+#endif
+ uint8_t itemIdx;
+ uint8_t itemCount;
+ uint8_t pageIdx;
+ uint8_t pageCount;
+} view_t;
+
+typedef enum {
+ view_action_unknown,
+ view_action_accept,
+ view_action_reject,
+} view_action_t;
+
+extern view_t viewdata;
+
+#define print_title(...) snprintf(viewdata.title, sizeof(viewdata.title), __VA_ARGS__)
+#define print_key(...) snprintf(viewdata.key, sizeof(viewdata.key), __VA_ARGS__);
+#define print_value(...) snprintf(viewdata.value, sizeof(viewdata.value), __VA_ARGS__);
+
+#if defined(TARGET_NANOS)
+#define print_value2(...) snprintf(viewdata.value2, sizeof(viewdata.value2), __VA_ARGS__);
+#endif
+
+void splitValueField();
+
+///////////////////////////////////////////////
+///////////////////////////////////////////////
+///////////////////////////////////////////////
+///////////////////////////////////////////////
+///////////////////////////////////////////////
+///////////////////////////////////////////////
+///////////////////////////////////////////////
+///////////////////////////////////////////////
+
+void view_idle_show_impl(uint8_t item_idx, char *statusString);
+
+void view_message_impl(char *title, char *message);
+
+void view_error_show_impl();
+
+void h_paging_init();
+
+bool h_paging_can_increase();
+
+void h_paging_increase();
+
+bool h_paging_can_decrease();
+
+void h_paging_decrease();
+
+void view_review_show_impl();
+
+void h_approve(unsigned int _);
+
+void h_reject(unsigned int _);
+
+void h_review_action();
+
+void h_review_update();
+
+void h_error_accept(unsigned int _);
+
+zxerr_t h_review_update_data();
diff --git a/deps/ledger-zxlib/app/common/view_s.c b/deps/ledger-zxlib/app/common/view_s.c
new file mode 100644
index 0000000..15c5c28
--- /dev/null
+++ b/deps/ledger-zxlib/app/common/view_s.c
@@ -0,0 +1,280 @@
+/*******************************************************************************
+* (c) 2018, 2019 Zondax GmbH
+* (c) 2016 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 "app_mode.h"
+#include "view.h"
+#include "view_internal.h"
+#include "apdu_codes.h"
+#include "ux.h"
+#include "bagl.h"
+#include "zxmacros.h"
+#include "view_templates.h"
+
+#include
+#include
+
+#if defined(TARGET_NANOS)
+
+void h_expert_toggle();
+void h_expert_update();
+void h_review_button_left();
+void h_review_button_right();
+void h_review_button_both();
+
+#ifdef APP_SECRET_MODE_ENABLED
+void h_secret_click();
+#endif
+
+ux_state_t ux;
+
+void os_exit(uint32_t id) {
+ (void)id;
+ os_sched_exit(0);
+}
+
+const ux_menu_entry_t menu_main[] = {
+ {NULL, NULL, 0, &C_icon_app, MENU_MAIN_APP_LINE1, viewdata.key, 33, 12},
+ {NULL, h_expert_toggle, 0, &C_icon_app, "Expert mode:", viewdata.value, 33, 12},
+ {NULL, NULL, 0, &C_icon_app, APPVERSION_LINE1, APPVERSION_LINE2, 33, 12},
+
+ {NULL,
+#ifdef APP_SECRET_MODE_ENABLED
+ h_secret_click,
+#else
+ NULL,
+#endif
+ 0, &C_icon_app, "Developed by:", "Zondax.ch", 33, 12},
+
+ {NULL, NULL, 0, &C_icon_app, "License: ", "Apache 2.0", 33, 12},
+ {NULL, os_exit, 0, &C_icon_dashboard, "Quit", NULL, 50, 29},
+ UX_MENU_END
+};
+
+static const bagl_element_t view_message[] = {
+ UI_BACKGROUND,
+ UI_LabelLine(UIID_LABEL + 0, 0, 8, UI_SCREEN_WIDTH, UI_11PX, UI_WHITE, UI_BLACK, viewdata.key),
+ UI_LabelLine(UIID_LABEL + 1, 0, 19, UI_SCREEN_WIDTH, UI_11PX, UI_WHITE, UI_BLACK, viewdata.value),
+};
+
+static const bagl_element_t view_review[] = {
+ UI_BACKGROUND_LEFT_RIGHT_ICONS,
+ UI_LabelLine(UIID_LABEL + 0, 0, 8, UI_SCREEN_WIDTH, UI_11PX, UI_WHITE, UI_BLACK, viewdata.key),
+ UI_LabelLine(UIID_LABEL + 1, 0, 19, UI_SCREEN_WIDTH, UI_11PX, UI_WHITE, UI_BLACK, viewdata.value),
+ UI_LabelLine(UIID_LABEL + 2, 0, 30, UI_SCREEN_WIDTH, UI_11PX, UI_WHITE, UI_BLACK, viewdata.value2),
+};
+
+static const bagl_element_t view_error[] = {
+ UI_FillRectangle(0, 0, 0, UI_SCREEN_WIDTH, UI_SCREEN_HEIGHT, 0x000000, 0xFFFFFF),
+ UI_Icon(0, 128 - 7, 0, 7, 7, BAGL_GLYPH_ICON_CHECK),
+ UI_LabelLine(UIID_LABEL + 0, 0, 8, UI_SCREEN_WIDTH, UI_11PX, UI_WHITE, UI_BLACK, viewdata.key),
+ UI_LabelLine(UIID_LABEL + 0, 0, 19, UI_SCREEN_WIDTH, UI_11PX, UI_WHITE, UI_BLACK, viewdata.value),
+ UI_LabelLineScrolling(UIID_LABELSCROLL, 0, 30, 128, UI_11PX, UI_WHITE, UI_BLACK, viewdata.value2),
+};
+
+static unsigned int view_error_button(unsigned int button_mask, unsigned int button_mask_counter) {
+ UNUSED(button_mask_counter);
+ switch (button_mask) {
+ case BUTTON_EVT_RELEASED | BUTTON_LEFT | BUTTON_RIGHT:
+ case BUTTON_EVT_RELEASED | BUTTON_LEFT:
+ break;
+ case BUTTON_EVT_RELEASED | BUTTON_RIGHT:
+ h_error_accept(0);
+ break;
+ }
+ return 0;
+}
+
+static unsigned int view_message_button(unsigned int button_mask, unsigned int button_mask_counter) {
+ UNUSED(button_mask_counter);
+ switch (button_mask) {
+ case BUTTON_EVT_RELEASED | BUTTON_LEFT | BUTTON_RIGHT:
+ case BUTTON_EVT_RELEASED | BUTTON_LEFT:
+ case BUTTON_EVT_RELEASED | BUTTON_RIGHT:
+ break;
+ }
+ return 0;
+}
+
+static unsigned int view_review_button(unsigned int button_mask, unsigned int button_mask_counter) {
+ UNUSED(button_mask_counter);
+ switch (button_mask) {
+ case BUTTON_EVT_RELEASED | BUTTON_LEFT | BUTTON_RIGHT:
+ h_review_button_both();
+ break;
+ case BUTTON_EVT_RELEASED | BUTTON_LEFT:
+ // Press left to progress to the previous element
+ h_review_button_left();
+ break;
+
+ case BUTTON_EVT_RELEASED | BUTTON_RIGHT:
+ // Press right to progress to the next element
+ h_review_button_right();
+ break;
+ }
+ return 0;
+}
+
+const bagl_element_t *view_prepro(const bagl_element_t *element) {
+ switch (element->component.userid) {
+ case UIID_ICONLEFT:
+ if (!h_paging_can_decrease()){
+ return NULL;
+ }
+ UX_CALLBACK_SET_INTERVAL(2000);
+ break;
+ case UIID_ICONRIGHT:
+ if (!h_paging_can_increase()){
+ return NULL;
+ }
+ UX_CALLBACK_SET_INTERVAL(2000);
+ break;
+ case UIID_LABELSCROLL:
+ UX_CALLBACK_SET_INTERVAL(
+ MAX(3000, 1000 + bagl_label_roundtrip_duration_ms(element, 7))
+ );
+ break;
+ }
+ return element;
+}
+
+const bagl_element_t *view_prepro_idle(const bagl_element_t *element) {
+ switch (element->component.userid) {
+ case UIID_ICONLEFT:
+ case UIID_ICONRIGHT:
+ return NULL;
+ }
+ return element;
+}
+
+void h_review_update() {
+ zxerr_t err = h_review_update_data();
+ switch(err) {
+ case zxerr_ok:
+ UX_DISPLAY(view_review, view_prepro);
+ break;
+ default:
+ view_error_show();
+ UX_WAIT();
+ break;
+ }
+}
+
+void h_review_button_left() {
+ zemu_log_stack("h_review_button_left");
+ h_paging_decrease();
+ h_review_update();
+}
+
+void h_review_button_right() {
+ zemu_log_stack("h_review_button_right");
+ h_paging_increase();
+ h_review_update();
+}
+
+void h_review_button_both() {
+ zemu_log_stack("h_review_button_left");
+ h_review_action();
+}
+
+void splitValueField() {
+ print_value2("");
+ uint16_t vlen = strlen(viewdata.value);
+ if (vlen > MAX_CHARS_PER_VALUE2_LINE - 1) {
+ strcpy(viewdata.value2, viewdata.value + MAX_CHARS_PER_VALUE_LINE);
+ viewdata.value[MAX_CHARS_PER_VALUE_LINE] = 0;
+ }
+}
+
+//////////////////////////
+//////////////////////////
+//////////////////////////
+//////////////////////////
+//////////////////////////
+
+void view_idle_show_impl(uint8_t item_idx, char *statusString) {
+ if (statusString == NULL ) {
+ snprintf(viewdata.key, MAX_CHARS_PER_VALUE_LINE, "%s", MENU_MAIN_APP_LINE2);
+#ifdef APP_SECRET_MODE_ENABLED
+ if (app_mode_secret()) {
+ snprintf(viewdata.key, MAX_CHARS_PER_VALUE_LINE, "%s", MENU_MAIN_APP_LINE2_SECRET);
+ }
+#endif
+ } else {
+ snprintf(viewdata.key, MAX_CHARS_PER_VALUE_LINE, "%s", statusString);
+ }
+ h_expert_update();
+ UX_MENU_DISPLAY(item_idx, menu_main, NULL);
+}
+
+void view_message_impl(char *title, char *message) {
+ snprintf(viewdata.key, MAX_CHARS_PER_VALUE_LINE, "%s", title);
+ snprintf(viewdata.value, MAX_CHARS_PER_VALUE_LINE, "%s", message);
+ UX_DISPLAY(view_message, view_prepro_idle);
+}
+
+void view_error_show_impl() {
+ UX_DISPLAY(view_error, view_prepro);
+}
+
+void h_expert_toggle() {
+ app_mode_set_expert(!app_mode_expert());
+ view_idle_show(1, NULL);
+}
+
+#ifdef APP_SECRET_MODE_ENABLED
+void h_secret_click() {
+ if (COIN_SECRET_REQUIRED_CLICKS == 0) {
+ // There is no secret mode
+ return;
+ }
+
+ viewdata.secret_click_count++;
+
+ char buffer[50];
+ snprintf(buffer, sizeof(buffer), "secret click %d\n", viewdata.secret_click_count);
+ zemu_log(buffer);
+
+ if (viewdata.secret_click_count >= COIN_SECRET_REQUIRED_CLICKS) {
+ secret_enabled();
+ viewdata.secret_click_count = 0;
+ }
+}
+#endif
+
+void h_expert_update() {
+ snprintf(viewdata.value, MAX_CHARS_PER_VALUE_LINE, "disabled");
+ if (app_mode_expert()) {
+ snprintf(viewdata.value, MAX_CHARS_PER_VALUE_LINE, "enabled");
+ }
+}
+
+void view_review_show_impl() {
+ zemu_log_stack("view_review_show_impl");
+
+ h_paging_init();
+
+ zxerr_t err = h_review_update_data();
+ switch(err) {
+ case zxerr_ok:
+ UX_DISPLAY(view_review, view_prepro);
+ break;
+ default:
+ view_error_show();
+ break;
+ }
+}
+#endif
diff --git a/deps/ledger-zxlib/app/common/view_x.c b/deps/ledger-zxlib/app/common/view_x.c
new file mode 100644
index 0000000..58ce39d
--- /dev/null
+++ b/deps/ledger-zxlib/app/common/view_x.c
@@ -0,0 +1,265 @@
+/*******************************************************************************
+* (c) 2018, 2019 Zondax GmbH
+* (c) 2016 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 "app_mode.h"
+#include "view.h"
+#include "view_internal.h"
+#include "actions.h"
+#include "apdu_codes.h"
+#include "glyphs.h"
+#include "bagl.h"
+#include "zxmacros.h"
+#include "view_templates.h"
+#include "tx.h"
+
+#ifdef APP_SECRET_MODE_ENABLED
+#include "secret.h"
+#endif
+
+#include
+#include
+
+#if defined(TARGET_NANOX)
+
+void h_expert_toggle();
+void h_expert_update();
+void h_review_loop_start();
+void h_review_loop_inside();
+void h_review_loop_end();
+
+#ifdef APP_SECRET_MODE_ENABLED
+void h_secret_click();
+#endif
+
+#include "ux.h"
+ux_state_t G_ux;
+bolos_ux_params_t G_ux_params;
+uint8_t flow_inside_loop;
+
+
+UX_STEP_NOCB(ux_idle_flow_1_step, pbb, { &C_icon_app, MENU_MAIN_APP_LINE1, viewdata.key,});
+UX_STEP_CB_INIT(ux_idle_flow_2_step, bn, h_expert_update(), h_expert_toggle(), { "Expert mode:", viewdata.value, });
+UX_STEP_NOCB(ux_idle_flow_3_step, bn, { APPVERSION_LINE1, APPVERSION_LINE2, });
+
+#ifdef APP_SECRET_MODE_ENABLED
+UX_STEP_CB(ux_idle_flow_4_step, bn, h_secret_click(), { "Developed by:", "Zondax.ch", });
+#else
+UX_STEP_NOCB(ux_idle_flow_4_step, bn, { "Developed by:", "Zondax.ch", });
+#endif
+
+UX_STEP_NOCB(ux_idle_flow_5_step, bn, { "License:", "Apache 2.0", });
+UX_STEP_CB(ux_idle_flow_6_step, pb, os_sched_exit(-1), { &C_icon_dashboard, "Quit",});
+
+const ux_flow_step_t *const ux_idle_flow [] = {
+ &ux_idle_flow_1_step,
+ &ux_idle_flow_2_step,
+ &ux_idle_flow_3_step,
+ &ux_idle_flow_4_step,
+ &ux_idle_flow_5_step,
+ &ux_idle_flow_6_step,
+ FLOW_END_STEP,
+};
+
+///////////
+
+UX_STEP_NOCB(ux_error_flow_1_step, bnnn_paging, { .title = viewdata.key, .text = viewdata.value, });
+UX_STEP_VALID(ux_error_flow_2_step, pb, h_error_accept(0), { &C_icon_validate_14, "Ok"});
+
+UX_FLOW(
+ ux_error_flow,
+ &ux_error_flow_1_step,
+ &ux_error_flow_2_step
+);
+
+///////////
+
+UX_FLOW_DEF_NOCB(ux_review_flow_1_review_title, pbb, { &C_icon_app, "Please", "review",});
+UX_STEP_INIT(ux_review_flow_2_start_step, NULL, NULL, { h_review_loop_start(); });
+UX_STEP_NOCB_INIT(ux_review_flow_2_step, bnnn_paging, { h_review_loop_inside(); }, { .title = viewdata.key, .text = viewdata.value, });
+UX_STEP_INIT(ux_review_flow_2_end_step, NULL, NULL, { h_review_loop_end(); });
+UX_STEP_VALID(ux_review_flow_3_step, pb, h_approve(0), { &C_icon_validate_14, APPROVE_LABEL });
+UX_STEP_VALID(ux_review_flow_4_step, pb, h_reject(0), { &C_icon_crossmark, REJECT_LABEL });
+
+const ux_flow_step_t *const ux_review_flow[] = {
+ &ux_review_flow_1_review_title,
+ &ux_review_flow_2_start_step,
+ &ux_review_flow_2_step,
+ &ux_review_flow_2_end_step,
+ &ux_review_flow_3_step,
+ &ux_review_flow_4_step,
+ FLOW_END_STEP,
+};
+
+//////////////////////////
+//////////////////////////
+//////////////////////////
+//////////////////////////
+//////////////////////////
+
+void h_review_update() {
+ zxerr_t err = h_review_update_data();
+ switch(err) {
+ case zxerr_ok:
+ case zxerr_no_data:
+ break;
+ default:
+ view_error_show();
+ break;
+ }
+}
+
+void h_review_loop_start() {
+ if (flow_inside_loop) {
+ // coming from right
+
+ if (!h_paging_can_decrease()) {
+ // exit to the left
+ flow_inside_loop = 0;
+ ux_flow_prev();
+ return;
+ }
+
+ h_paging_decrease();
+ } else {
+ // coming from left
+ h_paging_init();
+ }
+
+ h_review_update();
+
+ ux_flow_next();
+}
+
+void h_review_loop_inside() {
+ flow_inside_loop = 1;
+}
+
+void h_review_loop_end() {
+ if (flow_inside_loop) {
+ // coming from left
+ h_paging_increase();
+ zxerr_t err = h_review_update_data();
+
+ switch(err) {
+ case zxerr_ok:
+ ux_layout_bnnn_paging_reset();
+ break;
+ case zxerr_no_data: {
+ flow_inside_loop = 0;
+ ux_flow_next();
+ return;
+ }
+ default:
+ view_error_show();
+ break;
+ }
+ } else {
+ // coming from right
+ h_paging_decrease();
+ h_review_update();
+ }
+
+ // move to prev flow but trick paging to show first page
+ CUR_FLOW.prev_index = CUR_FLOW.index-2;
+ CUR_FLOW.index--;
+ ux_flow_relayout();
+}
+
+void splitValueField() {
+ uint16_t vlen = strlen(viewdata.value);
+ if (vlen == 0 ) {
+ strcpy(viewdata.value, " ");
+ }
+}
+
+void h_expert_toggle() {
+ app_mode_set_expert(!app_mode_expert());
+ ux_flow_init(0, ux_idle_flow, &ux_idle_flow_2_step);
+}
+
+void h_expert_update() {
+ snprintf(viewdata.value, MAX_CHARS_PER_VALUE1_LINE, "disabled");
+ if (app_mode_expert()) {
+ snprintf(viewdata.value, MAX_CHARS_PER_VALUE1_LINE, "enabled");
+ }
+}
+
+#ifdef APP_SECRET_MODE_ENABLED
+void h_secret_click() {
+ if (COIN_SECRET_REQUIRED_CLICKS == 0) {
+ // There is no secret mode
+ return;
+ }
+
+ viewdata.secret_click_count++;
+
+ char buffer[50];
+ snprintf(buffer, sizeof(buffer), "secret click %d\n", viewdata.secret_click_count);
+ zemu_log(buffer);
+
+ if (viewdata.secret_click_count >= COIN_SECRET_REQUIRED_CLICKS) {
+ secret_enabled();
+ viewdata.secret_click_count = 0;
+ return;
+ }
+
+ ux_flow_init(0, ux_idle_flow, &ux_idle_flow_4_step);
+}
+#endif
+
+//////////////////////////
+//////////////////////////
+//////////////////////////
+//////////////////////////
+//////////////////////////
+
+void view_idle_show_impl(uint8_t item_idx, char *statusString) {
+ if (statusString == NULL ) {
+ if (app_mode_secret()) {
+ snprintf(viewdata.key, MAX_CHARS_PER_KEY_LINE, "%s", MENU_MAIN_APP_LINE2_SECRET);
+ } else {
+ snprintf(viewdata.key, MAX_CHARS_PER_KEY_LINE, "%s", MENU_MAIN_APP_LINE2);
+ }
+ } else {
+ snprintf(viewdata.key, MAX_CHARS_PER_KEY_LINE, "%s", statusString);
+ }
+
+ if(G_ux.stack_count == 0) {
+ ux_stack_push();
+ }
+ ux_flow_init(0, ux_idle_flow, NULL);
+}
+
+void view_review_show_impl(){
+ h_paging_init();
+ h_paging_decrease();
+ ////
+ flow_inside_loop = 0;
+ if(G_ux.stack_count == 0) {
+ ux_stack_push();
+ }
+ ux_flow_init(0, ux_review_flow, NULL);
+}
+
+void view_error_show_impl() {
+ ux_layout_bnnn_paging_reset();
+ if(G_ux.stack_count == 0) {
+ ux_stack_push();
+ }
+ ux_flow_init(0, ux_error_flow, NULL);
+}
+#endif
diff --git a/deps/ledger-zxlib/cmake/gtest/CMakeLists.txt b/deps/ledger-zxlib/cmake/gtest/CMakeLists.txt
new file mode 100644
index 0000000..4f7a8ee
--- /dev/null
+++ b/deps/ledger-zxlib/cmake/gtest/CMakeLists.txt
@@ -0,0 +1,31 @@
+##############################
+# Google Test
+# Based on instructions in https://github.com/google/googletest/tree/master/googletest#incorporating-into-an-existing-cmake-project
+# Download and unpack googletest at configure time
+configure_file(CMakeLists.txt.gtest.in ${CMAKE_BINARY_DIR}/googletest-download/CMakeLists.txt)
+
+execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
+ RESULT_VARIABLE result
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download)
+if (result)
+ message(FATAL_ERROR "CMake step for googletest failed: ${result}")
+endif ()
+
+execute_process(COMMAND ${CMAKE_COMMAND} --build .
+ RESULT_VARIABLE result
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download)
+if (result)
+ message(FATAL_ERROR "Build step for googletest failed: ${result}")
+endif ()
+
+# Prevent overriding the parent project's compiler/linker settings on Windows
+set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
+
+add_subdirectory(
+ ${CMAKE_BINARY_DIR}/googletest-src
+ ${CMAKE_BINARY_DIR}/googletest-build
+)
+
+if (CMAKE_VERSION VERSION_LESS 2.8.11)
+ include_directories("${gtest_SOURCE_DIR}/include")
+endif ()
diff --git a/deps/ledger-zxlib/cmake/gtest/CMakeLists.txt.gtest.in b/deps/ledger-zxlib/cmake/gtest/CMakeLists.txt.gtest.in
new file mode 100644
index 0000000..f074ccf
--- /dev/null
+++ b/deps/ledger-zxlib/cmake/gtest/CMakeLists.txt.gtest.in
@@ -0,0 +1,16 @@
+# Based on https://github.com/google/googletest/tree/master/googletest#incorporating-into-an-existing-cmake-project
+cmake_minimum_required(VERSION 2.8.2)
+
+project(googletest-download NONE)
+
+include(ExternalProject)
+ExternalProject_Add(googletest
+ GIT_REPOSITORY https://github.com/google/googletest.git
+ GIT_TAG master
+ SOURCE_DIR "${CMAKE_BINARY_DIR}/googletest-src"
+ BINARY_DIR "${CMAKE_BINARY_DIR}/googletest-build"
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ TEST_COMMAND ""
+ )
diff --git a/deps/ledger-zxlib/dockerized_build.mk b/deps/ledger-zxlib/dockerized_build.mk
new file mode 100644
index 0000000..9b4e09f
--- /dev/null
+++ b/deps/ledger-zxlib/dockerized_build.mk
@@ -0,0 +1,291 @@
+#*******************************************************************************
+#* (c) 2019-2021 Zondax GmbH
+#*
+#* Licensed under the Apache License, Version 2.0 (the "License");
+#* you may not use this file except in compliance with the License.
+#* You may obtain a copy of the License at
+#*
+#* http://www.apache.org/licenses/LICENSE-2.0
+#*
+#* Unless required by applicable law or agreed to in writing, software
+#* distributed under the License is distributed on an "AS IS" BASIS,
+#* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#* See the License for the specific language governing permissions and
+#* limitations under the License.
+#********************************************************************************
+
+.PHONY: all deps build clean load delete check_python show_info_recovery_mode
+
+TESTS_ZEMU_DIR?=$(CURDIR)/tests_zemu
+EXAMPLE_VUE_DIR?=$(CURDIR)/example_vue
+TESTS_JS_PACKAGE?=
+TESTS_JS_DIR?=
+
+LEDGER_SRC=$(CURDIR)/app
+DOCKER_APP_SRC=/project
+DOCKER_APP_BIN=$(DOCKER_APP_SRC)/app/bin/app.elf
+
+DOCKER_BOLOS_SDKS=/project/deps/nanos-secure-sdk
+DOCKER_BOLOS_SDKX=/project/deps/nanox-secure-sdk
+
+# Note: This is not an SSH key, and being public represents no risk
+SCP_PUBKEY=049bc79d139c70c83a4b19e8922e5ee3e0080bb14a2e8b0752aa42cda90a1463f689b0fa68c1c0246845c2074787b649d0d8a6c0b97d4607065eee3057bdf16b83
+SCP_PRIVKEY=ff701d781f43ce106f72dc26a46b6a83e053b5d07bb3d4ceab79c91ca822a66b
+
+INTERACTIVE:=$(shell [ -t 0 ] && echo 1)
+USERID:=$(shell id -u)
+$(info USERID : $(USERID))
+$(info TESTS_ZEMU_DIR : $(TESTS_ZEMU_DIR))
+$(info EXAMPLE_VUE_DIR : $(EXAMPLE_VUE_DIR))
+$(info TESTS_JS_DIR : $(TESTS_JS_DIR))
+$(info TESTS_JS_PACKAGE : $(TESTS_JS_PACKAGE))
+
+DOCKER_IMAGE=zondax/builder-bolos:latest
+
+ifdef INTERACTIVE
+INTERACTIVE_SETTING:="-i"
+TTY_SETTING:="-t"
+else
+INTERACTIVE_SETTING:=
+TTY_SETTING:=
+endif
+
+UNAME_S := $(shell uname -s)
+ifeq ($(UNAME_S),Linux)
+ NPROC=$(shell nproc)
+endif
+ifeq ($(UNAME_S),Darwin)
+ NPROC=$(shell sysctl -n hw.physicalcpu)
+endif
+
+define run_docker
+ docker run $(TTY_SETTING) $(INTERACTIVE_SETTING) --rm \
+ -e SCP_PRIVKEY=$(SCP_PRIVKEY) \
+ -e BOLOS_SDK=$(1) \
+ -e BOLOS_ENV=/opt/bolos \
+ -u $(USERID) \
+ -v $(shell pwd):/project \
+ -e SUPPORT_SR25519=$(SUPPORT_SR25519) \
+ -e SUBSTRATE_PARSER_FULL=$(SUBSTRATE_PARSER_FULL) \
+ -e COIN=$(COIN) \
+ -e APP_TESTING=$(APP_TESTING) \
+ $(DOCKER_IMAGE) "$(2)"
+endef
+
+all:
+ @$(MAKE) clean_output
+ @$(MAKE) clean_build
+ @$(MAKE) buildS
+ @$(MAKE) clean_build
+ @$(MAKE) buildX
+
+.PHONY: check_python
+check_python:
+ @python -c 'import sys; sys.exit(3-sys.version_info.major)' || (echo "The python command does not point to Python 3"; exit 1)
+
+.PHONY: deps
+deps: check_python
+ @echo "Install dependencies"
+ $(CURDIR)/deps/ledger-zxlib/scripts/install_deps.sh
+
+.PHONY: pull
+pull:
+ docker pull $(DOCKER_IMAGE)
+
+.PHONY: build_rustS
+build_rustS:
+ $(call run_docker,$(DOCKER_BOLOS_SDKS),make -C $(DOCKER_APP_SRC) rust)
+
+.PHONY: build_rustX
+build_rustX:
+ $(call run_docker,$(DOCKER_BOLOS_SDKX),make -C $(DOCKER_APP_SRC) rust)
+
+.PHONY: convert_icon
+convert_icon:
+ @convert $(LEDGER_SRC)/tmp.gif -monochrome -size 16x16 -depth 1 $(LEDGER_SRC)/nanos_icon.gif
+ @convert $(LEDGER_SRC)/nanos_icon.gif -crop 14x14+1+1 +repage -negate $(LEDGER_SRC)/nanox_icon.gif
+
+.PHONY: buildS
+buildS: build_rustS
+ $(call run_docker,$(DOCKER_BOLOS_SDKS),make -j $(NPROC) -C $(DOCKER_APP_SRC))
+
+.PHONY: buildX
+buildX: build_rustX
+ $(call run_docker,$(DOCKER_BOLOS_SDKX),make -j $(NPROC) -C $(DOCKER_APP_SRC))
+
+.PHONY: clean_output
+clean_output:
+ @echo "Removing output files"
+ @rm -f app/output/app* || true
+
+.PHONY: clean
+clean_build:
+ $(call run_docker,$(DOCKER_BOLOS_SDKS),make -C $(DOCKER_APP_SRC) clean)
+
+.PHONY: clean
+clean: clean_output clean_build
+
+.PHONY: listvariants
+listvariants:
+ $(call run_docker,$(DOCKER_BOLOS_SDKS),make -C $(DOCKER_APP_SRC) listvariants)
+
+.PHONY: shellS
+shellS:
+ $(call run_docker,$(DOCKER_BOLOS_SDKS) -t,bash)
+
+.PHONY: shellX
+shellX:
+ $(call run_docker,$(DOCKER_BOLOS_SDKX) -t,bash)
+
+.PHONY: load
+load:
+ ${LEDGER_SRC}/pkg/installer_s.sh load
+
+.PHONY: delete
+delete:
+ ${LEDGER_SRC}/pkg/installer_s.sh delete
+
+.PHONY: loadX
+loadX:
+ ${LEDGER_SRC}/pkg/installer_x.sh load
+
+.PHONY: deleteX
+deleteX:
+ ${LEDGER_SRC}/pkg/installer_x.sh delete
+
+.PHONY: show_info_recovery_mode
+show_info_recovery_mode:
+ @echo "This command requires a Ledger Nano S in recovery mode. To go into recovery mode, follow:"
+ @echo " 1. Settings -> Device -> Reset all and confirm"
+ @echo " 2. Unplug device, press and hold the right button, plug-in again"
+ @echo " 3. Navigate to the main menu"
+ @echo "If everything was correct, no PIN needs to be entered."
+
+# This target will initialize the device with the integration testing mnemonic
+.PHONY: dev_init
+dev_init: show_info_recovery_mode
+ @echo "Initializing device with test mnemonic! WARNING TAKES 2 MINUTES AND REQUIRES RECOVERY MODE"
+ @python -m ledgerblue.hostOnboard --apdu --id 0 --prefix "" --passphrase "" --pin 5555 --words "equip will roof matter pink blind book anxiety banner elbow sun young"
+
+# This target will initialize the device with the secondary integration testing mnemonic (Bob)
+.PHONY: dev_init_secondary
+dev_init_secondary: check_python show_info_recovery_mode
+ @echo "Initializing device with secondary test mnemonic! WARNING TAKES 2 MINUTES AND REQUIRES RECOVERY MODE"
+ @python -m ledgerblue.hostOnboard --apdu --id 0 --prefix "" --passphrase "" --pin 5555 --words "elite vote proof agree february step sibling sand grocery axis false cup"
+
+# This target will setup a custom developer certificate
+.PHONY: dev_ca
+dev_ca: check_python
+ @python -m ledgerblue.setupCustomCA --targetId 0x31100004 --public $(SCP_PUBKEY) --name zondax
+
+# This target will setup a custom developer certificate
+.PHONY: dev_caX
+dev_caX: check_python
+ @python -m ledgerblue.setupCustomCA --targetId 0x33000004 --public $(SCP_PUBKEY) --name zondax
+
+.PHONY: dev_ca_delete
+dev_ca_delete: check_python
+ @python -m ledgerblue.resetCustomCA --targetId 0x31100004
+
+# This target will setup a custom developer certificate
+.PHONY: dev_ca2
+dev_ca2: check_python
+ @python -m ledgerblue.setupCustomCA --targetId 0x33000004 --public $(SCP_PUBKEY) --name zondax
+
+.PHONY: dev_ca_delete2
+dev_ca_delete2: check_python
+ @python -m ledgerblue.resetCustomCA --targetId 0x33000004
+
+########################## VUE Section ###############################
+
+.PHONY: vue_install_js_link
+ifeq ($(TESTS_JS_DIR),)
+vue_install_js_link:
+ @echo "No local package defined"
+else
+vue_install_js_link:
+ # First unlink everything
+ cd $(TESTS_JS_DIR) && yarn unlink || true
+ cd $(EXAMPLE_VUE_DIR) && yarn unlink $(TESTS_JS_PACKAGE) || true
+# # Now build and link
+ cd $(TESTS_JS_DIR) && yarn install && yarn build && yarn link || true
+ cd $(EXAMPLE_VUE_DIR) && yarn link $(TESTS_JS_PACKAGE) && yarn install || true
+ @echo
+ # List linked packages
+ @echo
+ @cd $(EXAMPLE_VUE_DIR) && ( ls -l node_modules ; ls -l node_modules/@* ) | grep ^l || true
+ @echo
+endif
+
+.PHONY: vue
+vue: vue_install_js_link
+ cd $(EXAMPLE_VUE_DIR) && yarn install && yarn serve
+
+########################## VUE Section ###############################
+
+.PHONY: zemu_install_js_link
+ifeq ($(TESTS_JS_DIR),)
+zemu_install_js_link:
+ @echo "No local package defined"
+else
+zemu_install_js_link:
+ # First unlink everything
+ cd $(TESTS_JS_DIR) && yarn unlink || true
+ cd $(TESTS_ZEMU_DIR) && yarn unlink $(TESTS_JS_PACKAGE) || true
+ # Now build and link
+ cd $(TESTS_JS_DIR) && yarn install && yarn build && yarn link || true
+ cd $(TESTS_ZEMU_DIR) && yarn link $(TESTS_JS_PACKAGE) && yarn install || true
+ @echo
+ # List linked packages
+ @echo
+ @cd $(TESTS_ZEMU_DIR) && ( ls -l node_modules ; ls -l node_modules/@* ) | grep ^l || true
+ @echo
+endif
+
+.PHONY: zemu_install
+zemu_install: zemu_install_js_link
+ # and now install everything
+ cd $(TESTS_ZEMU_DIR) && yarn install
+
+.PHONY: zemu
+zemu:
+ cd $(TESTS_ZEMU_DIR)/tools && node debug.mjs $(COIN)
+
+.PHONY: zemu_val
+zemu_val:
+ cd $(TESTS_ZEMU_DIR)/tools && node debug_val.mjs
+
+.PHONY: zemu_debug
+zemu_debug:
+ cd $(TESTS_ZEMU_DIR)/tools && node debug.mjs $(COIN) debug
+
+########################## TEST Section ###############################
+
+.PHONY: zemu_test
+zemu_test:
+ cd $(TESTS_ZEMU_DIR) && yarn test$(COIN)
+
+.PHONY: rust_test
+rust_test:
+ cd app/rust && cargo test
+
+.PHONY: cpp_test
+cpp_test:
+ mkdir -p build && cd build && cmake -DCMAKE_BUILD_TYPE=Debug .. && make
+ cd build && GTEST_COLOR=1 ASAN_OPTIONS=detect_leaks=0 ctest -VV
+
+########################## FUZZING Section ###############################
+
+.PHONY: fuzz_build
+fuzz_build:
+ cmake -B build -DCMAKE_C_COMPILER=clang-11 -DCMAKE_CXX_COMPILER=clang++-11 -DCMAKE_BUILD_TYPE=Debug -DENABLE_FUZZING=1 -DENABLE_SANITIZERS=1 .
+ make -C build
+
+.PHONY: fuzz
+fuzz: fuzz_build
+ ./fuzz/run-fuzzers.py
+
+.PHONY: fuzz_crash
+fuzz_crash: FUZZ_LOGGING=1
+fuzz_crash: fuzz_build
+ ./fuzz/run-fuzz-crashes.py
diff --git a/deps/ledger-zxlib/include/apdu_codes.h b/deps/ledger-zxlib/include/apdu_codes.h
new file mode 100644
index 0000000..5f55265
--- /dev/null
+++ b/deps/ledger-zxlib/include/apdu_codes.h
@@ -0,0 +1,50 @@
+/*******************************************************************************
+* (c) 2018 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#pragma once
+
+#include "inttypes.h"
+#include "zxmacros.h"
+
+// Based on ISO7816
+
+#define APDU_CODE_OK 0x9000
+#define APDU_CODE_BUSY 0x9001
+
+#define APDU_CODE_EXECUTION_ERROR 0x6400
+
+#define APDU_CODE_WRONG_LENGTH 0x6700
+
+#define APDU_CODE_EMPTY_BUFFER 0x6982
+#define APDU_CODE_OUTPUT_BUFFER_TOO_SMALL 0x6983
+#define APDU_CODE_DATA_INVALID 0x6984
+#define APDU_CODE_CONDITIONS_NOT_SATISFIED 0x6985
+#define APDU_CODE_COMMAND_NOT_ALLOWED 0x6986
+#define APDU_CODE_TX_NOT_INITIALIZED 0x6987
+
+#define APDU_CODE_BAD_KEY_HANDLE 0x6A80
+#define APDU_CODE_INVALIDP1P2 0x6B00
+#define APDU_CODE_INS_NOT_SUPPORTED 0x6D00
+#define APDU_CODE_CLA_NOT_SUPPORTED 0x6E00
+
+#define APDU_CODE_UNKNOWN 0x6F00
+#define APDU_CODE_SIGN_VERIFY_ERROR 0x6F01
+
+
+__Z_INLINE void set_code(uint8_t *buffer, uint8_t offset, uint16_t value) {
+ *(buffer + offset) = (uint8_t) (value >> 8);
+ *(buffer + offset + 1) = (uint8_t) (value & 0xFF);
+}
diff --git a/deps/ledger-zxlib/include/app_mode.h b/deps/ledger-zxlib/include/app_mode.h
new file mode 100644
index 0000000..11c72e8
--- /dev/null
+++ b/deps/ledger-zxlib/include/app_mode.h
@@ -0,0 +1,37 @@
+/*******************************************************************************
+* (c) 2016 Ledger
+* (c) 2018 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma once
+#include "zxmacros.h"
+#include "stdbool.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void app_mode_reset();
+
+bool app_mode_expert();
+
+void app_mode_set_expert(uint8_t val);
+
+bool app_mode_secret();
+
+void app_mode_set_secret(uint8_t val);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/deps/ledger-zxlib/include/base58.h b/deps/ledger-zxlib/include/base58.h
new file mode 100644
index 0000000..b76412d
--- /dev/null
+++ b/deps/ledger-zxlib/include/base58.h
@@ -0,0 +1,38 @@
+/*******************************************************************************
+* Ledger App - Bitcoin Wallet
+* (c) 2019 Zondax GmbH
+* (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
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int decode_base58(const char *in, size_t length,
+ unsigned char *out, size_t *outlen);
+
+int encode_base58(const unsigned char *in, size_t length,
+ unsigned char *out, size_t *outlen);
+
+char encode_base58_clip(unsigned char v);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/deps/ledger-zxlib/include/base64.h b/deps/ledger-zxlib/include/base64.h
new file mode 100644
index 0000000..99bc7c0
--- /dev/null
+++ b/deps/ledger-zxlib/include/base64.h
@@ -0,0 +1,29 @@
+/*******************************************************************************
+* (c) 2020 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include
+
+uint16_t base64_encode(char *out, uint16_t outlen, const uint8_t *in, uint16_t inlen);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/deps/ledger-zxlib/include/bech32.h b/deps/ledger-zxlib/include/bech32.h
new file mode 100644
index 0000000..bd9fd14
--- /dev/null
+++ b/deps/ledger-zxlib/include/bech32.h
@@ -0,0 +1,39 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "zxerror.h"
+
+#define MAX_INPUT_SIZE 64
+
+// the following function encodes directly from bytes
+// it will internally convert from 8 to 5 bits and return a
+// zero-terminated string in output
+
+zxerr_t bech32EncodeFromBytes(char *out,
+ size_t out_len,
+ const char *hrp,
+ const uint8_t *in,
+ size_t in_len,
+ uint8_t pad);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/deps/ledger-zxlib/include/bignum.h b/deps/ledger-zxlib/include/bignum.h
new file mode 100644
index 0000000..9bf31f8
--- /dev/null
+++ b/deps/ledger-zxlib/include/bignum.h
@@ -0,0 +1,35 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include
+
+bool_t bignumLittleEndian_bcdprint(char *outBuffer, uint16_t outBufferLen, const uint8_t *inBCD, uint16_t inBCDLen);
+void bignumLittleEndian_to_bcd(uint8_t *bcdOut, uint16_t bcdOutLen, const uint8_t *binValue, uint16_t binValueLen);
+
+bool_t bignumBigEndian_bcdprint(char *outBuffer, uint16_t outBufferLen, const uint8_t *bcdIn, uint16_t bcdInLen);
+void bignumBigEndian_to_bcd(uint8_t *bcdOut, uint16_t bcdOutLen, const uint8_t *binValue, uint16_t binValueLen);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/deps/ledger-zxlib/include/bittools.h b/deps/ledger-zxlib/include/bittools.h
new file mode 100644
index 0000000..1903878
--- /dev/null
+++ b/deps/ledger-zxlib/include/bittools.h
@@ -0,0 +1,37 @@
+// This code has been adapted from:
+/* Copyright (c) 2017 Pieter Wuille
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int convert_bits(uint8_t *out,
+ size_t *outlen,
+ int outBits,
+ const uint8_t *in,
+ size_t inLen,
+ int inBits, int pad);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/deps/ledger-zxlib/include/buffering.h b/deps/ledger-zxlib/include/buffering.h
new file mode 100644
index 0000000..ec6e80c
--- /dev/null
+++ b/deps/ledger-zxlib/include/buffering.h
@@ -0,0 +1,67 @@
+/*******************************************************************************
+* (c) 2016 Ledger
+* (c) 2018 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include
+
+typedef struct {
+ uint8_t *data;
+ uint16_t size;
+ uint16_t pos;
+ uint8_t in_use: 1;
+} buffer_state_t;
+
+/// Initialize buffer
+/// \param ram_buffer
+/// \param ram_buffer_size
+/// \param flash_buffer
+/// \param flash_buffer_size
+void buffering_init(uint8_t *ram_buffer,
+ uint16_t ram_buffer_size,
+ uint8_t *flash_buffer,
+ uint16_t flash_buffer_size);
+
+/// Reset buffer
+void buffering_reset();
+
+/// Append data to the buffer
+/// \param data
+/// \param length
+/// \return the number of appended bytes
+int buffering_append(uint8_t *data, int length);
+
+/// buffering_get_ram_buffer
+/// \return
+buffer_state_t *buffering_get_ram_buffer();
+
+/// buffering_get_flash_buffer
+/// \return
+buffer_state_t *buffering_get_flash_buffer();
+
+/// buffering_get_buffer
+/// \return
+buffer_state_t *buffering_get_buffer();
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/deps/ledger-zxlib/include/hexutils.h b/deps/ledger-zxlib/include/hexutils.h
new file mode 100644
index 0000000..3cbaad8
--- /dev/null
+++ b/deps/ledger-zxlib/include/hexutils.h
@@ -0,0 +1,30 @@
+/*******************************************************************************
+* (c) 2018 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#pragma once
+
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+size_t parseHexString(uint8_t *out, uint16_t outLen, const char *input);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/deps/ledger-zxlib/include/segwit_addr.h b/deps/ledger-zxlib/include/segwit_addr.h
new file mode 100644
index 0000000..e7704ac
--- /dev/null
+++ b/deps/ledger-zxlib/include/segwit_addr.h
@@ -0,0 +1,101 @@
+/* Copyright (c) 2017 Pieter Wuille
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef _SEGWIT_ADDR_H_
+#define _SEGWIT_ADDR_H_ 1
+
+#include
+
+/** Encode a SegWit address
+ *
+ * Out: output: Pointer to a buffer of size 73 + strlen(hrp) that will be
+ * updated to contain the null-terminated address.
+ * In: hrp: Pointer to the null-terminated human readable part to use
+ * (chain/network specific).
+ * ver: Version of the witness program (between 0 and 16 inclusive).
+ * prog: Data bytes for the witness program (between 2 and 40 bytes).
+ * prog_len: Number of data bytes in prog.
+ * Returns 1 if successful.
+ */
+int segwit_addr_encode(
+ char *output,
+ const char *hrp,
+ int ver,
+ const uint8_t *prog,
+ size_t prog_len
+);
+
+/** Decode a SegWit address
+ *
+ * Out: ver: Pointer to an int that will be updated to contain the witness
+ * program version (between 0 and 16 inclusive).
+ * prog: Pointer to a buffer of size 40 that will be updated to
+ * contain the witness program bytes.
+ * prog_len: Pointer to a size_t that will be updated to contain the length
+ * of bytes in prog.
+ * hrp: Pointer to the null-terminated human readable part that is
+ * expected (chain/network specific).
+ * addr: Pointer to the null-terminated address.
+ * Returns 1 if successful.
+ */
+int segwit_addr_decode(
+ int* ver,
+ uint8_t* prog,
+ size_t* prog_len,
+ const char* hrp,
+ const char* addr
+);
+
+/** Encode a Bech32 string
+ *
+ * Out: output: Pointer to a buffer of size strlen(hrp) + data_len + 8 that
+ * will be updated to contain the null-terminated Bech32 string.
+ * In: hrp : Pointer to the null-terminated human readable part.
+ * data : Pointer to an array of 5-bit values.
+ * data_len: Length of the data array.
+ * Returns 1 if successful.
+ */
+int bech32_encode(
+ char *output,
+ const char *hrp,
+ const uint8_t *data,
+ size_t data_len
+);
+
+/** Decode a Bech32 string
+ *
+ * Out: hrp: Pointer to a buffer of size strlen(input) - 6. Will be
+ * updated to contain the null-terminated human readable part.
+ * data: Pointer to a buffer of size strlen(input) - 8 that will
+ * hold the encoded 5-bit data values.
+ * data_len: Pointer to a size_t that will be updated to be the number
+ * of entries in data.
+ * In: input: Pointer to a null-terminated Bech32 string.
+ * Returns 1 if succesful.
+ */
+int bech32_decode(
+ char *hrp,
+ uint8_t *data,
+ size_t *data_len,
+ const char *input
+);
+
+#endif
diff --git a/deps/ledger-zxlib/include/sigutils.h b/deps/ledger-zxlib/include/sigutils.h
new file mode 100644
index 0000000..862f809
--- /dev/null
+++ b/deps/ledger-zxlib/include/sigutils.h
@@ -0,0 +1,41 @@
+/*******************************************************************************
+* (c) 2020 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ no_error = 0,
+ invalid_derPrefix,
+ invalid_payloadLen,
+ invalid_rmaker,
+ invalid_rLen,
+ invalid_smarker,
+ invalid_sLen,
+} err_convert_e;
+
+err_convert_e convertDERtoRSV(const uint8_t *inSignatureDER,
+ unsigned int inInfo,
+ uint8_t *outR,
+ uint8_t *outS,
+ uint8_t *outV);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/deps/ledger-zxlib/include/timeutils.h b/deps/ledger-zxlib/include/timeutils.h
new file mode 100644
index 0000000..d291477
--- /dev/null
+++ b/deps/ledger-zxlib/include/timeutils.h
@@ -0,0 +1,62 @@
+/*******************************************************************************
+* (c) 2018 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include
+#include "zxmacros.h"
+#include "zxerror.h"
+
+__Z_INLINE const char *getMonth(uint8_t tm_mon) {
+ switch (tm_mon) {
+ case 1:
+ return "Jan";
+ case 2:
+ return "Feb";
+ case 3:
+ return "Mar";
+ case 4:
+ return "Apr";
+ case 5:
+ return "May";
+ case 6:
+ return "Jun";
+ case 7:
+ return "Jul";
+ case 8:
+ return "Aug";
+ case 9:
+ return "Sep";
+ case 10:
+ return "Oct";
+ case 11:
+ return "Nov";
+ case 12:
+ return "Dec";
+ default:
+ return "ERR";
+ }
+}
+
+zxerr_t printTime(char *out, uint16_t outLen, uint64_t t);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/deps/ledger-zxlib/include/utf8.h b/deps/ledger-zxlib/include/utf8.h
new file mode 100644
index 0000000..4a0ca69
--- /dev/null
+++ b/deps/ledger-zxlib/include/utf8.h
@@ -0,0 +1,1262 @@
+// The latest version of this library is available on GitHub;
+// https://github.com/sheredom/utf8.h
+
+// This is free and unencumbered software released into the public domain.
+//
+// Anyone is free to copy, modify, publish, use, compile, sell, or
+// distribute this software, either in source code form or as a compiled
+// binary, for any purpose, commercial or non-commercial, and by any
+// means.
+//
+// In jurisdictions that recognize copyright laws, the author or authors
+// of this software dedicate any and all copyright interest in the
+// software to the public domain. We make this dedication for the benefit
+// of the public at large and to the detriment of our heirs and
+// successors. We intend this dedication to be an overt act of
+// relinquishment in perpetuity of all present and future rights to this
+// software under copyright law.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+// For more information, please refer to
+
+#ifndef SHEREDOM_UTF8_H_INCLUDED
+#define SHEREDOM_UTF8_H_INCLUDED
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+
+// disable 'bytes padding added after construct' warning
+#pragma warning(disable : 4820)
+#endif
+
+#include
+#include
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+#if defined(_MSC_VER)
+typedef __int32 utf8_int32_t;
+#else
+#include
+typedef int32_t utf8_int32_t;
+#endif
+
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wold-style-cast"
+#pragma clang diagnostic ignored "-Wcast-qual"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(__clang__) || defined(__GNUC__)
+#define utf8_nonnull __attribute__((nonnull))
+#define utf8_pure __attribute__((pure))
+#define utf8_restrict __restrict__
+#define utf8_weak __attribute__((weak))
+#elif defined(_MSC_VER)
+#define utf8_nonnull
+#define utf8_pure
+#define utf8_restrict __restrict
+#define utf8_weak __inline
+#else
+#error Non clang, non gcc, non MSVC compiler found!
+#endif
+
+#ifdef __cplusplus
+#define utf8_null NULL
+#else
+#define utf8_null 0
+#endif
+
+// Return less than 0, 0, greater than 0 if src1 < src2, src1 == src2, src1 >
+// src2 respectively, case insensitive.
+utf8_nonnull utf8_pure utf8_weak int utf8casecmp(const void *src1,
+ const void *src2);
+
+// Append the utf8 string src onto the utf8 string dst.
+utf8_nonnull utf8_weak void *utf8cat(void *utf8_restrict dst,
+ const void *utf8_restrict src);
+
+// Find the first match of the utf8 codepoint chr in the utf8 string src.
+utf8_nonnull utf8_pure utf8_weak void *utf8chr(const void *src,
+ utf8_int32_t chr);
+
+// Return less than 0, 0, greater than 0 if src1 < src2,
+// src1 == src2, src1 > src2 respectively.
+utf8_nonnull utf8_pure utf8_weak int utf8cmp(const void *src1,
+ const void *src2);
+
+// Copy the utf8 string src onto the memory allocated in dst.
+utf8_nonnull utf8_weak void *utf8cpy(void *utf8_restrict dst,
+ const void *utf8_restrict src);
+
+// Number of utf8 codepoints in the utf8 string src that consists entirely
+// of utf8 codepoints not from the utf8 string reject.
+utf8_nonnull utf8_pure utf8_weak size_t utf8cspn(const void *src,
+ const void *reject);
+
+// Duplicate the utf8 string src by getting its size, malloc'ing a new buffer
+// copying over the data, and returning that. Or 0 if malloc failed.
+utf8_nonnull utf8_weak void *utf8dup(const void *src);
+
+// Number of utf8 codepoints in the utf8 string str,
+// excluding the null terminating byte.
+utf8_nonnull utf8_pure utf8_weak size_t utf8len(const void *str);
+
+// Return less than 0, 0, greater than 0 if src1 < src2, src1 == src2, src1 >
+// src2 respectively, case insensitive. Checking at most n bytes of each utf8
+// string.
+utf8_nonnull utf8_pure utf8_weak int utf8ncasecmp(const void *src1,
+ const void *src2, size_t n);
+
+// Append the utf8 string src onto the utf8 string dst,
+// writing at most n+1 bytes. Can produce an invalid utf8
+// string if n falls partway through a utf8 codepoint.
+utf8_nonnull utf8_weak void *utf8ncat(void *utf8_restrict dst,
+ const void *utf8_restrict src, size_t n);
+
+// Return less than 0, 0, greater than 0 if src1 < src2,
+// src1 == src2, src1 > src2 respectively. Checking at most n
+// bytes of each utf8 string.
+utf8_nonnull utf8_pure utf8_weak int utf8ncmp(const void *src1,
+ const void *src2, size_t n);
+
+// Copy the utf8 string src onto the memory allocated in dst.
+// Copies at most n bytes. If there is no terminating null byte in
+// the first n bytes of src, the string placed into dst will not be
+// null-terminated. If the size (in bytes) of src is less than n,
+// extra null terminating bytes are appended to dst such that at
+// total of n bytes are written. Can produce an invalid utf8
+// string if n falls partway through a utf8 codepoint.
+utf8_nonnull utf8_weak void *utf8ncpy(void *utf8_restrict dst,
+ const void *utf8_restrict src, size_t n);
+
+// Similar to utf8dup, except that at most n bytes of src are copied. If src is
+// longer than n, only n bytes are copied and a null byte is added.
+//
+// Returns a new string if successful, 0 otherwise
+utf8_nonnull utf8_weak void *utf8ndup(const void *src, size_t n);
+
+// Locates the first occurence in the utf8 string str of any byte in the
+// utf8 string accept, or 0 if no match was found.
+utf8_nonnull utf8_pure utf8_weak void *utf8pbrk(const void *str,
+ const void *accept);
+
+// Find the last match of the utf8 codepoint chr in the utf8 string src.
+utf8_nonnull utf8_pure utf8_weak void *utf8rchr(const void *src, int chr);
+
+// Number of bytes in the utf8 string str,
+// including the null terminating byte.
+utf8_nonnull utf8_pure utf8_weak size_t utf8size(const void *str);
+
+// Number of utf8 codepoints in the utf8 string src that consists entirely
+// of utf8 codepoints from the utf8 string accept.
+utf8_nonnull utf8_pure utf8_weak size_t utf8spn(const void *src,
+ const void *accept);
+
+// The position of the utf8 string needle in the utf8 string haystack.
+utf8_nonnull utf8_pure utf8_weak void *utf8str(const void *haystack,
+ const void *needle);
+
+// The position of the utf8 string needle in the utf8 string haystack, case
+// insensitive.
+utf8_nonnull utf8_pure utf8_weak void *utf8casestr(const void *haystack,
+ const void *needle);
+
+// Return 0 on success, or the position of the invalid
+// utf8 codepoint on failure.
+utf8_nonnull utf8_pure utf8_weak void *utf8valid(const void *str);
+
+// Sets out_codepoint to the next utf8 codepoint in str, and returns the address
+// of the utf8 codepoint after the current one in str.
+utf8_nonnull utf8_weak void *
+utf8codepoint(const void *utf8_restrict str,
+ utf8_int32_t *utf8_restrict out_codepoint);
+
+// Returns the size of the given codepoint in bytes.
+utf8_weak size_t utf8codepointsize(utf8_int32_t chr);
+
+// Write a codepoint to the given string, and return the address to the next
+// place after the written codepoint. Pass how many bytes left in the buffer to
+// n. If there is not enough space for the codepoint, this function returns
+// null.
+utf8_nonnull utf8_weak void *utf8catcodepoint(void *utf8_restrict str,
+ utf8_int32_t chr, size_t n);
+
+// Returns 1 if the given character is lowercase, or 0 if it is not.
+utf8_weak int utf8islower(utf8_int32_t chr);
+
+// Returns 1 if the given character is uppercase, or 0 if it is not.
+utf8_weak int utf8isupper(utf8_int32_t chr);
+
+// Transform the given string into all lowercase codepoints.
+utf8_nonnull utf8_weak void utf8lwr(void *utf8_restrict str);
+
+// Transform the given string into all uppercase codepoints.
+utf8_nonnull utf8_weak void utf8upr(void *utf8_restrict str);
+
+// Make a codepoint lower case if possible.
+utf8_weak utf8_int32_t utf8lwrcodepoint(utf8_int32_t cp);
+
+// Make a codepoint upper case if possible.
+utf8_weak utf8_int32_t utf8uprcodepoint(utf8_int32_t cp);
+
+#undef utf8_weak
+#undef utf8_pure
+#undef utf8_nonnull
+
+int utf8casecmp(const void *src1, const void *src2) {
+ utf8_int32_t src1_cp, src2_cp, src1_orig_cp, src2_orig_cp;
+
+ for (;;) {
+ src1 = utf8codepoint(src1, &src1_cp);
+ src2 = utf8codepoint(src2, &src2_cp);
+
+ // Take a copy of src1 & src2
+ src1_orig_cp = src1_cp;
+ src2_orig_cp = src2_cp;
+
+ // Lower the srcs if required
+ src1_cp = utf8lwrcodepoint(src1_cp);
+ src2_cp = utf8lwrcodepoint(src2_cp);
+
+ // Check if the lowered codepoints match
+ if ((0 == src1_orig_cp) && (0 == src2_orig_cp)) {
+ return 0;
+ } else if (src1_cp == src2_cp) {
+ continue;
+ }
+
+ // If they don't match, then we return which of the original's are less
+ if (src1_orig_cp < src2_orig_cp) {
+ return -1;
+ } else if (src1_orig_cp > src2_orig_cp) {
+ return 1;
+ }
+ }
+}
+
+void *utf8cat(void *utf8_restrict dst, const void *utf8_restrict src) {
+ char *d = (char *)dst;
+ const char *s = (const char *)src;
+
+ // find the null terminating byte in dst
+ while ('\0' != *d) {
+ d++;
+ }
+
+ // overwriting the null terminating byte in dst, append src byte-by-byte
+ while ('\0' != *s) {
+ *d++ = *s++;
+ }
+
+ // write out a new null terminating byte into dst
+ *d = '\0';
+
+ return dst;
+}
+
+void *utf8chr(const void *src, utf8_int32_t chr) {
+ char c[5] = {'\0', '\0', '\0', '\0', '\0'};
+
+ if (0 == chr) {
+ // being asked to return position of null terminating byte, so
+ // just run s to the end, and return!
+ const char *s = (const char *)src;
+ while ('\0' != *s) {
+ s++;
+ }
+ return (void *)s;
+ } else if (0 == ((utf8_int32_t)0xffffff80 & chr)) {
+ // 1-byte/7-bit ascii
+ // (0b0xxxxxxx)
+ c[0] = (char)chr;
+ } else if (0 == ((utf8_int32_t)0xfffff800 & chr)) {
+ // 2-byte/11-bit utf8 code point
+ // (0b110xxxxx 0b10xxxxxx)
+ c[0] = 0xc0 | (char)(chr >> 6);
+ c[1] = 0x80 | (char)(chr & 0x3f);
+ } else if (0 == ((utf8_int32_t)0xffff0000 & chr)) {
+ // 3-byte/16-bit utf8 code point
+ // (0b1110xxxx 0b10xxxxxx 0b10xxxxxx)
+ c[0] = 0xe0 | (char)(chr >> 12);
+ c[1] = 0x80 | (char)((chr >> 6) & 0x3f);
+ c[2] = 0x80 | (char)(chr & 0x3f);
+ } else { // if (0 == ((int)0xffe00000 & chr)) {
+ // 4-byte/21-bit utf8 code point
+ // (0b11110xxx 0b10xxxxxx 0b10xxxxxx 0b10xxxxxx)
+ c[0] = 0xf0 | (char)(chr >> 18);
+ c[1] = 0x80 | (char)((chr >> 12) & 0x3f);
+ c[2] = 0x80 | (char)((chr >> 6) & 0x3f);
+ c[3] = 0x80 | (char)(chr & 0x3f);
+ }
+
+ // we've made c into a 2 utf8 codepoint string, one for the chr we are
+ // seeking, another for the null terminating byte. Now use utf8str to
+ // search
+ return utf8str(src, c);
+}
+
+int utf8cmp(const void *src1, const void *src2) {
+ const unsigned char *s1 = (const unsigned char *)src1;
+ const unsigned char *s2 = (const unsigned char *)src2;
+
+ while (('\0' != *s1) || ('\0' != *s2)) {
+ if (*s1 < *s2) {
+ return -1;
+ } else if (*s1 > *s2) {
+ return 1;
+ }
+
+ s1++;
+ s2++;
+ }
+
+ // both utf8 strings matched
+ return 0;
+}
+
+int utf8coll(const void *src1, const void *src2);
+
+void *utf8cpy(void *utf8_restrict dst, const void *utf8_restrict src) {
+ char *d = (char *)dst;
+ const char *s = (const char *)src;
+
+ // overwriting anything previously in dst, write byte-by-byte
+ // from src
+ while ('\0' != *s) {
+ *d++ = *s++;
+ }
+
+ // append null terminating byte
+ *d = '\0';
+
+ return dst;
+}
+
+size_t utf8cspn(const void *src, const void *reject) {
+ const char *s = (const char *)src;
+ size_t chars = 0;
+
+ while ('\0' != *s) {
+ const char *r = (const char *)reject;
+ size_t offset = 0;
+
+ while ('\0' != *r) {
+ // checking that if *r is the start of a utf8 codepoint
+ // (it is not 0b10xxxxxx) and we have successfully matched
+ // a previous character (0 < offset) - we found a match
+ if ((0x80 != (0xc0 & *r)) && (0 < offset)) {
+ return chars;
+ } else {
+ if (*r == s[offset]) {
+ // part of a utf8 codepoint matched, so move our checking
+ // onwards to the next byte
+ offset++;
+ r++;
+ } else {
+ // r could be in the middle of an unmatching utf8 code point,
+ // so we need to march it on to the next character beginning,
+
+ do {
+ r++;
+ } while (0x80 == (0xc0 & *r));
+
+ // reset offset too as we found a mismatch
+ offset = 0;
+ }
+ }
+ }
+
+ // the current utf8 codepoint in src did not match reject, but src
+ // could have been partway through a utf8 codepoint, so we need to
+ // march it onto the next utf8 codepoint starting byte
+ do {
+ s++;
+ } while ((0x80 == (0xc0 & *s)));
+ chars++;
+ }
+
+ return chars;
+}
+
+size_t utf8size(const void *str);
+
+void *utf8dup(const void *src) {
+ const char *s = (const char *)src;
+ char *n = utf8_null;
+
+ // figure out how many bytes (including the terminator) we need to copy first
+ size_t bytes = utf8size(src);
+
+ n = (char *)malloc(bytes);
+
+ if (utf8_null == n) {
+ // out of memory so we bail
+ return utf8_null;
+ } else {
+ bytes = 0;
+
+ // copy src byte-by-byte into our new utf8 string
+ while ('\0' != s[bytes]) {
+ n[bytes] = s[bytes];
+ bytes++;
+ }
+
+ // append null terminating byte
+ n[bytes] = '\0';
+ return n;
+ }
+}
+
+void *utf8fry(const void *str);
+
+size_t utf8len(const void *str) {
+ const unsigned char *s = (const unsigned char *)str;
+ size_t length = 0;
+
+ while ('\0' != *s) {
+ if (0xf0 == (0xf8 & *s)) {
+ // 4-byte utf8 code point (began with 0b11110xxx)
+ s += 4;
+ } else if (0xe0 == (0xf0 & *s)) {
+ // 3-byte utf8 code point (began with 0b1110xxxx)
+ s += 3;
+ } else if (0xc0 == (0xe0 & *s)) {
+ // 2-byte utf8 code point (began with 0b110xxxxx)
+ s += 2;
+ } else { // if (0x00 == (0x80 & *s)) {
+ // 1-byte ascii (began with 0b0xxxxxxx)
+ s += 1;
+ }
+
+ // no matter the bytes we marched s forward by, it was
+ // only 1 utf8 codepoint
+ length++;
+ }
+
+ return length;
+}
+
+int utf8ncasecmp(const void *src1, const void *src2, size_t n) {
+ utf8_int32_t src1_cp, src2_cp, src1_orig_cp, src2_orig_cp;
+
+ do {
+ const unsigned char *const s1 = (const unsigned char *)src1;
+ const unsigned char *const s2 = (const unsigned char *)src2;
+
+ // first check that we have enough bytes left in n to contain an entire
+ // codepoint
+ if (0 == n) {
+ return 0;
+ }
+
+ if ((1 == n) && ((0xc0 == (0xe0 & *s1)) || (0xc0 == (0xe0 & *s2)))) {
+ const utf8_int32_t c1 = (0xe0 & *s1);
+ const utf8_int32_t c2 = (0xe0 & *s2);
+
+ if (c1 < c2) {
+ return -1;
+ } else if (c1 > c2) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
+ if ((2 >= n) && ((0xe0 == (0xf0 & *s1)) || (0xe0 == (0xf0 & *s2)))) {
+ const utf8_int32_t c1 = (0xf0 & *s1);
+ const utf8_int32_t c2 = (0xf0 & *s2);
+
+ if (c1 < c2) {
+ return -1;
+ } else if (c1 > c2) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
+ if ((3 >= n) && ((0xf0 == (0xf8 & *s1)) || (0xf0 == (0xf8 & *s2)))) {
+ const utf8_int32_t c1 = (0xf8 & *s1);
+ const utf8_int32_t c2 = (0xf8 & *s2);
+
+ if (c1 < c2) {
+ return -1;
+ } else if (c1 > c2) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
+ src1 = utf8codepoint(src1, &src1_cp);
+ src2 = utf8codepoint(src2, &src2_cp);
+ n -= utf8codepointsize(src1_cp);
+
+ // Take a copy of src1 & src2
+ src1_orig_cp = src1_cp;
+ src2_orig_cp = src2_cp;
+
+ // Lower srcs if required
+ src1_cp = utf8lwrcodepoint(src1_cp);
+ src2_cp = utf8lwrcodepoint(src2_cp);
+
+ // Check if the lowered codepoints match
+ if ((0 == src1_orig_cp) && (0 == src2_orig_cp)) {
+ return 0;
+ } else if (src1_cp == src2_cp) {
+ continue;
+ }
+
+ // If they don't match, then we return which of the original's are less
+ if (src1_orig_cp < src2_orig_cp) {
+ return -1;
+ } else if (src1_orig_cp > src2_orig_cp) {
+ return 1;
+ }
+ } while (0 < n);
+
+ // both utf8 strings matched
+ return 0;
+}
+
+void *utf8ncat(void *utf8_restrict dst, const void *utf8_restrict src,
+ size_t n) {
+ char *d = (char *)dst;
+ const char *s = (const char *)src;
+
+ // find the null terminating byte in dst
+ while ('\0' != *d) {
+ d++;
+ }
+
+ // overwriting the null terminating byte in dst, append src byte-by-byte
+ // stopping if we run out of space
+ do {
+ *d++ = *s++;
+ } while (('\0' != *s) && (0 != --n));
+
+ // write out a new null terminating byte into dst
+ *d = '\0';
+
+ return dst;
+}
+
+int utf8ncmp(const void *src1, const void *src2, size_t n) {
+ const unsigned char *s1 = (const unsigned char *)src1;
+ const unsigned char *s2 = (const unsigned char *)src2;
+
+ while ((0 != n--) && (('\0' != *s1) || ('\0' != *s2))) {
+ if (*s1 < *s2) {
+ return -1;
+ } else if (*s1 > *s2) {
+ return 1;
+ }
+
+ s1++;
+ s2++;
+ }
+
+ // both utf8 strings matched
+ return 0;
+}
+
+void *utf8ncpy(void *utf8_restrict dst, const void *utf8_restrict src,
+ size_t n) {
+ char *d = (char *)dst;
+ const char *s = (const char *)src;
+ size_t index;
+
+ // overwriting anything previously in dst, write byte-by-byte
+ // from src
+ for (index = 0; index < n; index++) {
+ d[index] = s[index];
+ if ('\0' == s[index]) {
+ break;
+ }
+ }
+
+ // append null terminating byte
+ for (; index < n; index++) {
+ d[index] = 0;
+ }
+
+ return dst;
+}
+
+void *utf8ndup(const void *src, size_t n) {
+ const char *s = (const char *)src;
+ char *c = utf8_null;
+ size_t bytes = 0;
+
+ // Find the end of the string or stop when n is reached
+ while ('\0' != s[bytes] && bytes < n) {
+ bytes++;
+ }
+
+ // In case bytes is actually less than n, we need to set it
+ // to be used later in the copy byte by byte.
+ n = bytes;
+
+ c = (char *)malloc(bytes + 1);
+ if (utf8_null == c) {
+ // out of memory so we bail
+ return utf8_null;
+ }
+
+ bytes = 0;
+
+ // copy src byte-by-byte into our new utf8 string
+ while ('\0' != s[bytes] && bytes < n) {
+ c[bytes] = s[bytes];
+ bytes++;
+ }
+
+ // append null terminating byte
+ c[bytes] = '\0';
+ return c;
+}
+
+void *utf8rchr(const void *src, int chr) {
+ const char *s = (const char *)src;
+ const char *match = utf8_null;
+ char c[5] = {'\0', '\0', '\0', '\0', '\0'};
+
+ if (0 == chr) {
+ // being asked to return position of null terminating byte, so
+ // just run s to the end, and return!
+ while ('\0' != *s) {
+ s++;
+ }
+ return (void *)s;
+ } else if (0 == ((int)0xffffff80 & chr)) {
+ // 1-byte/7-bit ascii
+ // (0b0xxxxxxx)
+ c[0] = (char)chr;
+ } else if (0 == ((int)0xfffff800 & chr)) {
+ // 2-byte/11-bit utf8 code point
+ // (0b110xxxxx 0b10xxxxxx)
+ c[0] = 0xc0 | (char)(chr >> 6);
+ c[1] = 0x80 | (char)(chr & 0x3f);
+ } else if (0 == ((int)0xffff0000 & chr)) {
+ // 3-byte/16-bit utf8 code point
+ // (0b1110xxxx 0b10xxxxxx 0b10xxxxxx)
+ c[0] = 0xe0 | (char)(chr >> 12);
+ c[1] = 0x80 | (char)((chr >> 6) & 0x3f);
+ c[2] = 0x80 | (char)(chr & 0x3f);
+ } else { // if (0 == ((int)0xffe00000 & chr)) {
+ // 4-byte/21-bit utf8 code point
+ // (0b11110xxx 0b10xxxxxx 0b10xxxxxx 0b10xxxxxx)
+ c[0] = 0xf0 | (char)(chr >> 18);
+ c[1] = 0x80 | (char)((chr >> 12) & 0x3f);
+ c[2] = 0x80 | (char)((chr >> 6) & 0x3f);
+ c[3] = 0x80 | (char)(chr & 0x3f);
+ }
+
+ // we've created a 2 utf8 codepoint string in c that is
+ // the utf8 character asked for by chr, and a null
+ // terminating byte
+
+ while ('\0' != *s) {
+ size_t offset = 0;
+
+ while (s[offset] == c[offset]) {
+ offset++;
+ }
+
+ if ('\0' == c[offset]) {
+ // we found a matching utf8 code point
+ match = s;
+ s += offset;
+ } else {
+ s += offset;
+
+ // need to march s along to next utf8 codepoint start
+ // (the next byte that doesn't match 0b10xxxxxx)
+ if ('\0' != *s) {
+ do {
+ s++;
+ } while (0x80 == (0xc0 & *s));
+ }
+ }
+ }
+
+ // return the last match we found (or 0 if no match was found)
+ return (void *)match;
+}
+
+void *utf8pbrk(const void *str, const void *accept) {
+ const char *s = (const char *)str;
+
+ while ('\0' != *s) {
+ const char *a = (const char *)accept;
+ size_t offset = 0;
+
+ while ('\0' != *a) {
+ // checking that if *a is the start of a utf8 codepoint
+ // (it is not 0b10xxxxxx) and we have successfully matched
+ // a previous character (0 < offset) - we found a match
+ if ((0x80 != (0xc0 & *a)) && (0 < offset)) {
+ return (void *)s;
+ } else {
+ if (*a == s[offset]) {
+ // part of a utf8 codepoint matched, so move our checking
+ // onwards to the next byte
+ offset++;
+ a++;
+ } else {
+ // r could be in the middle of an unmatching utf8 code point,
+ // so we need to march it on to the next character beginning,
+
+ do {
+ a++;
+ } while (0x80 == (0xc0 & *a));
+
+ // reset offset too as we found a mismatch
+ offset = 0;
+ }
+ }
+ }
+
+ // we found a match on the last utf8 codepoint
+ if (0 < offset) {
+ return (void *)s;
+ }
+
+ // the current utf8 codepoint in src did not match accept, but src
+ // could have been partway through a utf8 codepoint, so we need to
+ // march it onto the next utf8 codepoint starting byte
+ do {
+ s++;
+ } while ((0x80 == (0xc0 & *s)));
+ }
+
+ return utf8_null;
+}
+
+size_t utf8size(const void *str) {
+ const char *s = (const char *)str;
+ size_t size = 0;
+ while ('\0' != s[size]) {
+ size++;
+ }
+
+ // we are including the null terminating byte in the size calculation
+ size++;
+ return size;
+}
+
+size_t utf8spn(const void *src, const void *accept) {
+ const char *s = (const char *)src;
+ size_t chars = 0;
+
+ while ('\0' != *s) {
+ const char *a = (const char *)accept;
+ size_t offset = 0;
+
+ while ('\0' != *a) {
+ // checking that if *r is the start of a utf8 codepoint
+ // (it is not 0b10xxxxxx) and we have successfully matched
+ // a previous character (0 < offset) - we found a match
+ if ((0x80 != (0xc0 & *a)) && (0 < offset)) {
+ // found a match, so increment the number of utf8 codepoints
+ // that have matched and stop checking whether any other utf8
+ // codepoints in a match
+ chars++;
+ s += offset;
+ break;
+ } else {
+ if (*a == s[offset]) {
+ offset++;
+ a++;
+ } else {
+ // a could be in the middle of an unmatching utf8 codepoint,
+ // so we need to march it on to the next character beginning,
+ do {
+ a++;
+ } while (0x80 == (0xc0 & *a));
+
+ // reset offset too as we found a mismatch
+ offset = 0;
+ }
+ }
+ }
+
+ // if a got to its terminating null byte, then we didn't find a match.
+ // Return the current number of matched utf8 codepoints
+ if ('\0' == *a) {
+ return chars;
+ }
+ }
+
+ return chars;
+}
+
+void *utf8str(const void *haystack, const void *needle) {
+ const char *h = (const char *)haystack;
+ utf8_int32_t throwaway_codepoint;
+
+ // if needle has no utf8 codepoints before the null terminating
+ // byte then return haystack
+ if ('\0' == *((const char *)needle)) {
+ return (void *)haystack;
+ }
+
+ while ('\0' != *h) {
+ const char *maybeMatch = h;
+ const char *n = (const char *)needle;
+
+ while (*h == *n && (*h != '\0' && *n != '\0')) {
+ n++;
+ h++;
+ }
+
+ if ('\0' == *n) {
+ // we found the whole utf8 string for needle in haystack at
+ // maybeMatch, so return it
+ return (void *)maybeMatch;
+ } else {
+ // h could be in the middle of an unmatching utf8 codepoint,
+ // so we need to march it on to the next character beginning
+ // starting from the current character
+ h = (const char*)utf8codepoint(maybeMatch, &throwaway_codepoint);
+ }
+ }
+
+ // no match
+ return utf8_null;
+}
+
+void *utf8casestr(const void *haystack, const void *needle) {
+ const void *h = haystack;
+
+ // if needle has no utf8 codepoints before the null terminating
+ // byte then return haystack
+ if ('\0' == *((const char *)needle)) {
+ return (void *)haystack;
+ }
+
+ for (;;) {
+ const void *maybeMatch = h;
+ const void *n = needle;
+ utf8_int32_t h_cp, n_cp;
+
+ // Get the next code point and track it
+ const void *nextH = h = utf8codepoint(h, &h_cp);
+ n = utf8codepoint(n, &n_cp);
+
+ while ((0 != h_cp) && (0 != n_cp)) {
+ h_cp = utf8lwrcodepoint(h_cp);
+ n_cp = utf8lwrcodepoint(n_cp);
+
+ // if we find a mismatch, bail out!
+ if (h_cp != n_cp) {
+ break;
+ }
+
+ h = utf8codepoint(h, &h_cp);
+ n = utf8codepoint(n, &n_cp);
+ }
+
+ if (0 == n_cp) {
+ // we found the whole utf8 string for needle in haystack at
+ // maybeMatch, so return it
+ return (void *)maybeMatch;
+ }
+
+ if (0 == h_cp) {
+ // no match
+ return utf8_null;
+ }
+
+ // Roll back to the next code point in the haystack to test
+ h = nextH;
+ }
+}
+
+void *utf8valid(const void *str) {
+ const char *s = (const char *)str;
+
+ while ('\0' != *s) {
+ if (0xf0 == (0xf8 & *s)) {
+ // ensure each of the 3 following bytes in this 4-byte
+ // utf8 codepoint began with 0b10xxxxxx
+ if ((0x80 != (0xc0 & s[1])) || (0x80 != (0xc0 & s[2])) ||
+ (0x80 != (0xc0 & s[3]))) {
+ return (void *)s;
+ }
+
+ // ensure that our utf8 codepoint ended after 4 bytes
+ if (0x80 == (0xc0 & s[4])) {
+ return (void *)s;
+ }
+
+ // ensure that the top 5 bits of this 4-byte utf8
+ // codepoint were not 0, as then we could have used
+ // one of the smaller encodings
+ if ((0 == (0x07 & s[0])) && (0 == (0x30 & s[1]))) {
+ return (void *)s;
+ }
+
+ // 4-byte utf8 code point (began with 0b11110xxx)
+ s += 4;
+ } else if (0xe0 == (0xf0 & *s)) {
+ // ensure each of the 2 following bytes in this 3-byte
+ // utf8 codepoint began with 0b10xxxxxx
+ if ((0x80 != (0xc0 & s[1])) || (0x80 != (0xc0 & s[2]))) {
+ return (void *)s;
+ }
+
+ // ensure that our utf8 codepoint ended after 3 bytes
+ if (0x80 == (0xc0 & s[3])) {
+ return (void *)s;
+ }
+
+ // ensure that the top 5 bits of this 3-byte utf8
+ // codepoint were not 0, as then we could have used
+ // one of the smaller encodings
+ if ((0 == (0x0f & s[0])) && (0 == (0x20 & s[1]))) {
+ return (void *)s;
+ }
+
+ // 3-byte utf8 code point (began with 0b1110xxxx)
+ s += 3;
+ } else if (0xc0 == (0xe0 & *s)) {
+ // ensure the 1 following byte in this 2-byte
+ // utf8 codepoint began with 0b10xxxxxx
+ if (0x80 != (0xc0 & s[1])) {
+ return (void *)s;
+ }
+
+ // ensure that our utf8 codepoint ended after 2 bytes
+ if (0x80 == (0xc0 & s[2])) {
+ return (void *)s;
+ }
+
+ // ensure that the top 4 bits of this 2-byte utf8
+ // codepoint were not 0, as then we could have used
+ // one of the smaller encodings
+ if (0 == (0x1e & s[0])) {
+ return (void *)s;
+ }
+
+ // 2-byte utf8 code point (began with 0b110xxxxx)
+ s += 2;
+ } else if (0x00 == (0x80 & *s)) {
+ // 1-byte ascii (began with 0b0xxxxxxx)
+ s += 1;
+ } else {
+ // we have an invalid 0b1xxxxxxx utf8 code point entry
+ return (void *)s;
+ }
+ }
+
+ return utf8_null;
+}
+
+void *utf8codepoint(const void *utf8_restrict str,
+ utf8_int32_t *utf8_restrict out_codepoint) {
+ const char *s = (const char *)str;
+
+ if (0xf0 == (0xf8 & s[0])) {
+ // 4 byte utf8 codepoint
+ *out_codepoint = ((0x07 & s[0]) << 18) | ((0x3f & s[1]) << 12) |
+ ((0x3f & s[2]) << 6) | (0x3f & s[3]);
+ s += 4;
+ } else if (0xe0 == (0xf0 & s[0])) {
+ // 3 byte utf8 codepoint
+ *out_codepoint =
+ ((0x0f & s[0]) << 12) | ((0x3f & s[1]) << 6) | (0x3f & s[2]);
+ s += 3;
+ } else if (0xc0 == (0xe0 & s[0])) {
+ // 2 byte utf8 codepoint
+ *out_codepoint = ((0x1f & s[0]) << 6) | (0x3f & s[1]);
+ s += 2;
+ } else {
+ // 1 byte utf8 codepoint otherwise
+ *out_codepoint = s[0];
+ s += 1;
+ }
+
+ return (void *)s;
+}
+
+size_t utf8codepointsize(utf8_int32_t chr) {
+ if (0 == ((utf8_int32_t)0xffffff80 & chr)) {
+ return 1;
+ } else if (0 == ((utf8_int32_t)0xfffff800 & chr)) {
+ return 2;
+ } else if (0 == ((utf8_int32_t)0xffff0000 & chr)) {
+ return 3;
+ } else { // if (0 == ((int)0xffe00000 & chr)) {
+ return 4;
+ }
+}
+
+void *utf8catcodepoint(void *utf8_restrict str, utf8_int32_t chr, size_t n) {
+ char *s = (char *)str;
+
+ if (0 == ((utf8_int32_t)0xffffff80 & chr)) {
+ // 1-byte/7-bit ascii
+ // (0b0xxxxxxx)
+ if (n < 1) {
+ return utf8_null;
+ }
+ s[0] = (char)chr;
+ s += 1;
+ } else if (0 == ((utf8_int32_t)0xfffff800 & chr)) {
+ // 2-byte/11-bit utf8 code point
+ // (0b110xxxxx 0b10xxxxxx)
+ if (n < 2) {
+ return utf8_null;
+ }
+ s[0] = 0xc0 | (char)(chr >> 6);
+ s[1] = 0x80 | (char)(chr & 0x3f);
+ s += 2;
+ } else if (0 == ((utf8_int32_t)0xffff0000 & chr)) {
+ // 3-byte/16-bit utf8 code point
+ // (0b1110xxxx 0b10xxxxxx 0b10xxxxxx)
+ if (n < 3) {
+ return utf8_null;
+ }
+ s[0] = 0xe0 | (char)(chr >> 12);
+ s[1] = 0x80 | (char)((chr >> 6) & 0x3f);
+ s[2] = 0x80 | (char)(chr & 0x3f);
+ s += 3;
+ } else { // if (0 == ((int)0xffe00000 & chr)) {
+ // 4-byte/21-bit utf8 code point
+ // (0b11110xxx 0b10xxxxxx 0b10xxxxxx 0b10xxxxxx)
+ if (n < 4) {
+ return utf8_null;
+ }
+ s[0] = 0xf0 | (char)(chr >> 18);
+ s[1] = 0x80 | (char)((chr >> 12) & 0x3f);
+ s[2] = 0x80 | (char)((chr >> 6) & 0x3f);
+ s[3] = 0x80 | (char)(chr & 0x3f);
+ s += 4;
+ }
+
+ return s;
+}
+
+int utf8islower(utf8_int32_t chr) { return chr != utf8uprcodepoint(chr); }
+
+int utf8isupper(utf8_int32_t chr) { return chr != utf8lwrcodepoint(chr); }
+
+void utf8lwr(void *utf8_restrict str) {
+ void *p, *pn;
+ utf8_int32_t cp;
+
+ p = (char *)str;
+ pn = utf8codepoint(p, &cp);
+
+ while (cp != 0) {
+ const utf8_int32_t lwr_cp = utf8lwrcodepoint(cp);
+ const size_t size = utf8codepointsize(lwr_cp);
+
+ if (lwr_cp != cp) {
+ utf8catcodepoint(p, lwr_cp, size);
+ }
+
+ p = pn;
+ pn = utf8codepoint(p, &cp);
+ }
+}
+
+void utf8upr(void *utf8_restrict str) {
+ void *p, *pn;
+ utf8_int32_t cp;
+
+ p = (char *)str;
+ pn = utf8codepoint(p, &cp);
+
+ while (cp != 0) {
+ const utf8_int32_t lwr_cp = utf8uprcodepoint(cp);
+ const size_t size = utf8codepointsize(lwr_cp);
+
+ if (lwr_cp != cp) {
+ utf8catcodepoint(p, lwr_cp, size);
+ }
+
+ p = pn;
+ pn = utf8codepoint(p, &cp);
+ }
+}
+
+utf8_int32_t utf8lwrcodepoint(utf8_int32_t cp) {
+ if (((0x0041 <= cp) && (0x005a >= cp)) ||
+ ((0x00c0 <= cp) && (0x00d6 >= cp)) ||
+ ((0x00d8 <= cp) && (0x00de >= cp)) ||
+ ((0x0391 <= cp) && (0x03a1 >= cp)) ||
+ ((0x03a3 <= cp) && (0x03ab >= cp))) {
+ cp += 32;
+ } else if (((0x0100 <= cp) && (0x012f >= cp)) ||
+ ((0x0132 <= cp) && (0x0137 >= cp)) ||
+ ((0x014a <= cp) && (0x0177 >= cp)) ||
+ ((0x0182 <= cp) && (0x0185 >= cp)) ||
+ ((0x01a0 <= cp) && (0x01a5 >= cp)) ||
+ ((0x01de <= cp) && (0x01ef >= cp)) ||
+ ((0x01f8 <= cp) && (0x021f >= cp)) ||
+ ((0x0222 <= cp) && (0x0233 >= cp)) ||
+ ((0x0246 <= cp) && (0x024f >= cp)) ||
+ ((0x03d8 <= cp) && (0x03ef >= cp))) {
+ cp |= 0x1;
+ } else if (((0x0139 <= cp) && (0x0148 >= cp)) ||
+ ((0x0179 <= cp) && (0x017e >= cp)) ||
+ ((0x01af <= cp) && (0x01b0 >= cp)) ||
+ ((0x01b3 <= cp) && (0x01b6 >= cp)) ||
+ ((0x01cd <= cp) && (0x01dc >= cp))) {
+ cp += 1;
+ cp &= ~0x1;
+ } else {
+ switch (cp) {
+ default: break;
+ case 0x0178: cp = 0x00ff; break;
+ case 0x0243: cp = 0x0180; break;
+ case 0x018e: cp = 0x01dd; break;
+ case 0x023d: cp = 0x019a; break;
+ case 0x0220: cp = 0x019e; break;
+ case 0x01b7: cp = 0x0292; break;
+ case 0x01c4: cp = 0x01c6; break;
+ case 0x01c7: cp = 0x01c9; break;
+ case 0x01ca: cp = 0x01cc; break;
+ case 0x01f1: cp = 0x01f3; break;
+ case 0x01f7: cp = 0x01bf; break;
+ case 0x0187: cp = 0x0188; break;
+ case 0x018b: cp = 0x018c; break;
+ case 0x0191: cp = 0x0192; break;
+ case 0x0198: cp = 0x0199; break;
+ case 0x01a7: cp = 0x01a8; break;
+ case 0x01ac: cp = 0x01ad; break;
+ case 0x01af: cp = 0x01b0; break;
+ case 0x01b8: cp = 0x01b9; break;
+ case 0x01bc: cp = 0x01bd; break;
+ case 0x01f4: cp = 0x01f5; break;
+ case 0x023b: cp = 0x023c; break;
+ case 0x0241: cp = 0x0242; break;
+ case 0x03fd: cp = 0x037b; break;
+ case 0x03fe: cp = 0x037c; break;
+ case 0x03ff: cp = 0x037d; break;
+ case 0x037f: cp = 0x03f3; break;
+ case 0x0386: cp = 0x03ac; break;
+ case 0x0388: cp = 0x03ad; break;
+ case 0x0389: cp = 0x03ae; break;
+ case 0x038a: cp = 0x03af; break;
+ case 0x038c: cp = 0x03cc; break;
+ case 0x038e: cp = 0x03cd; break;
+ case 0x038f: cp = 0x03ce; break;
+ case 0x0370: cp = 0x0371; break;
+ case 0x0372: cp = 0x0373; break;
+ case 0x0376: cp = 0x0377; break;
+ case 0x03f4: cp = 0x03d1; break;
+ case 0x03cf: cp = 0x03d7; break;
+ case 0x03f9: cp = 0x03f2; break;
+ case 0x03f7: cp = 0x03f8; break;
+ case 0x03fa: cp = 0x03fb; break;
+ }
+ }
+
+ return cp;
+}
+
+utf8_int32_t utf8uprcodepoint(utf8_int32_t cp) {
+ if (((0x0061 <= cp) && (0x007a >= cp)) ||
+ ((0x00e0 <= cp) && (0x00f6 >= cp)) ||
+ ((0x00f8 <= cp) && (0x00fe >= cp)) ||
+ ((0x03b1 <= cp) && (0x03c1 >= cp)) ||
+ ((0x03c3 <= cp) && (0x03cb >= cp))) {
+ cp -= 32;
+ } else if (((0x0100 <= cp) && (0x012f >= cp)) ||
+ ((0x0132 <= cp) && (0x0137 >= cp)) ||
+ ((0x014a <= cp) && (0x0177 >= cp)) ||
+ ((0x0182 <= cp) && (0x0185 >= cp)) ||
+ ((0x01a0 <= cp) && (0x01a5 >= cp)) ||
+ ((0x01de <= cp) && (0x01ef >= cp)) ||
+ ((0x01f8 <= cp) && (0x021f >= cp)) ||
+ ((0x0222 <= cp) && (0x0233 >= cp)) ||
+ ((0x0246 <= cp) && (0x024f >= cp)) ||
+ ((0x03d8 <= cp) && (0x03ef >= cp))) {
+ cp &= ~0x1;
+ } else if (((0x0139 <= cp) && (0x0148 >= cp)) ||
+ ((0x0179 <= cp) && (0x017e >= cp)) ||
+ ((0x01af <= cp) && (0x01b0 >= cp)) ||
+ ((0x01b3 <= cp) && (0x01b6 >= cp)) ||
+ ((0x01cd <= cp) && (0x01dc >= cp))) {
+ cp -= 1;
+ cp |= 0x1;
+ } else {
+ switch (cp) {
+ default: break;
+ case 0x00ff: cp = 0x0178; break;
+ case 0x0180: cp = 0x0243; break;
+ case 0x01dd: cp = 0x018e; break;
+ case 0x019a: cp = 0x023d; break;
+ case 0x019e: cp = 0x0220; break;
+ case 0x0292: cp = 0x01b7; break;
+ case 0x01c6: cp = 0x01c4; break;
+ case 0x01c9: cp = 0x01c7; break;
+ case 0x01cc: cp = 0x01ca; break;
+ case 0x01f3: cp = 0x01f1; break;
+ case 0x01bf: cp = 0x01f7; break;
+ case 0x0188: cp = 0x0187; break;
+ case 0x018c: cp = 0x018b; break;
+ case 0x0192: cp = 0x0191; break;
+ case 0x0199: cp = 0x0198; break;
+ case 0x01a8: cp = 0x01a7; break;
+ case 0x01ad: cp = 0x01ac; break;
+ case 0x01b0: cp = 0x01af; break;
+ case 0x01b9: cp = 0x01b8; break;
+ case 0x01bd: cp = 0x01bc; break;
+ case 0x01f5: cp = 0x01f4; break;
+ case 0x023c: cp = 0x023b; break;
+ case 0x0242: cp = 0x0241; break;
+ case 0x037b: cp = 0x03fd; break;
+ case 0x037c: cp = 0x03fe; break;
+ case 0x037d: cp = 0x03ff; break;
+ case 0x03f3: cp = 0x037f; break;
+ case 0x03ac: cp = 0x0386; break;
+ case 0x03ad: cp = 0x0388; break;
+ case 0x03ae: cp = 0x0389; break;
+ case 0x03af: cp = 0x038a; break;
+ case 0x03cc: cp = 0x038c; break;
+ case 0x03cd: cp = 0x038e; break;
+ case 0x03ce: cp = 0x038f; break;
+ case 0x0371: cp = 0x0370; break;
+ case 0x0373: cp = 0x0372; break;
+ case 0x0377: cp = 0x0376; break;
+ case 0x03d1: cp = 0x03f4; break;
+ case 0x03d7: cp = 0x03cf; break;
+ case 0x03f2: cp = 0x03f9; break;
+ case 0x03f8: cp = 0x03f7; break;
+ case 0x03fb: cp = 0x03fa; break;
+ }
+ }
+
+ return cp;
+}
+
+#undef utf8_restrict
+#undef utf8_null
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+
+#endif // SHEREDOM_UTF8_H_INCLUDED
diff --git a/deps/ledger-zxlib/include/view_templates.h b/deps/ledger-zxlib/include/view_templates.h
new file mode 100644
index 0000000..e653b03
--- /dev/null
+++ b/deps/ledger-zxlib/include/view_templates.h
@@ -0,0 +1,168 @@
+/*******************************************************************************
+* (c) 2016 Ledger
+* (c) 2018 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma once
+
+#include
+
+#define UI_CENTER11PX BAGL_FONT_OPEN_SANS_REGULAR_11px | BAGL_FONT_ALIGNMENT_CENTER
+#define UI_CENTER11PX_BOLD BAGL_FONT_OPEN_SANS_EXTRABOLD_11px | BAGL_FONT_ALIGNMENT_CENTER
+#define UI_11PX 11
+
+#define DEFAULT_FONT BAGL_FONT_OPEN_SANS_LIGHT_16px | BAGL_FONT_ALIGNMENT_LEFT
+#define UI_WHITE 0xFFFFFF
+#define UI_BLACK 0x000000
+
+#define UIID_ICONLEFT 0x10
+#define UIID_ICONRIGHT 0x11
+#define UIID_LABEL 0x20
+#define UIID_LABELSCROLL 0x71
+
+#define UI_FillRectangle(id, x, y, w, h, fgcolor, bgcolor) \
+{ \
+ { \
+ BAGL_RECTANGLE, /* type */ \
+ id, /* usedid */ \
+ x, /* x */ \
+ y, /* y */ \
+ w, /* width */ \
+ h, /* height */ \
+ 0, /* stroke */ \
+ 0, /* radius */ \
+ BAGL_FILL, /* fill */ \
+ fgcolor, /* fgcolor */ \
+ bgcolor, /* bgcolor */ \
+ 0, /* font_id */ \
+ 0 /* icon_id */ \
+ }, \
+ NULL, /* text */ \
+}
+
+#define UI_LabelLine(id, x, y, w, h, fgcolor, bgcolor, text) \
+{ \
+ { \
+ BAGL_LABELINE, /* type */ \
+ id, /* usedid */ \
+ x, /* x */ \
+ y, /* y */ \
+ w, /* width */ \
+ h, /* height */ \
+ 0, /* stroke */ \
+ 0, /* radius */ \
+ 0, /* fill */ \
+ fgcolor, /* fgcolor */ \
+ bgcolor, /* bgcolor */ \
+ UI_CENTER11PX, /* font_id */ \
+ 0 /* icon_id */ \
+ }, \
+ text, /* text */ \
+}
+
+#define UI_LabelLineScrolling(id, x, y, w, h, fgcolor, bgcolor, text) \
+{ \
+ { \
+ BAGL_LABELINE, /* type */ \
+ id, /* usedid */ \
+ x, /* x */ \
+ y, /* y */ \
+ w, /* width */ \
+ h, /* height */ \
+ 5 | BAGL_STROKE_FLAG_ONESHOT, /* stroke | scr pause */ \
+ 0, /* radius */ \
+ 0, /* fill */ \
+ fgcolor, /* fgcolor */ \
+ bgcolor, /* bgcolor */ \
+ UI_CENTER11PX, /* font_id */ \
+ 50 /* icon_id / scroll speed */ \
+ }, \
+ text, /* text */ \
+}
+
+#if defined(TARGET_NANOX)
+#define UI_SCREEN_WIDTH 128
+#define UI_SCREEN_HEIGHT 64
+
+#define BAGL_GLYPH_ICON_LEFT ((const char*)&C_icon_left)
+#define BAGL_GLYPH_ICON_RIGHT ((const char*)&C_icon_right)
+#define BAGL_GLYPH_ICON_CROSS ((const char*)&C_icon_crossmark)
+#define BAGL_GLYPH_ICON_CHECK ((const char*)&C_icon_validate)
+
+#define UI_Icon(id, x, y, w, h, icon) \
+{ \
+ { \
+ BAGL_ICON, /* type */ \
+ id, /* usedid */ \
+ x, /* x */ \
+ y, /* y */ \
+ w, /* width */ \
+ h, /* height */ \
+ 0, /* stroke */ \
+ 0, /* radius */ \
+ 0, /* fill */ \
+ UI_WHITE, /* fgcolor */ \
+ UI_BLACK, /* bgcolor */ \
+ 0, /* font_id */ \
+ 0 /* icon_id */ \
+ }, \
+ icon, /* text */ \
+ 0, /* touch_area_brim */ \
+ 0, /* overfgcolor */ \
+ 0, /* overbgcolor */ \
+ NULL, /* tap */ \
+ NULL, /* out */ \
+ NULL, /* over */ \
+}
+
+#define UI_BACKGROUND \
+ UI_FillRectangle(0, 0, 0, UI_SCREEN_WIDTH, UI_SCREEN_HEIGHT, 0x000000, 0xFFFFFF)
+
+#define UI_BACKGROUND_LEFT_RIGHT_ICONS \
+ UI_BACKGROUND, \
+ UI_Icon(UIID_ICONLEFT, 2, 28, 4, 7, BAGL_GLYPH_ICON_LEFT), \
+ UI_Icon(UIID_ICONRIGHT, 122, 28, 4, 7, BAGL_GLYPH_ICON_RIGHT)
+
+#else
+#define UI_SCREEN_WIDTH 128
+#define UI_SCREEN_HEIGHT 32
+
+#define UI_Icon(id, x, y, w, h, icon) \
+{ \
+ { \
+ BAGL_ICON, /* type */ \
+ id, /* usedid */ \
+ x, /* x */ \
+ y, /* y */ \
+ w, /* width */ \
+ h, /* height */ \
+ 0, /* stroke */ \
+ 0, /* radius */ \
+ 0, /* fill */ \
+ UI_WHITE, /* fgcolor */ \
+ UI_BLACK, /* bgcolor */ \
+ 0, /* font_id */ \
+ icon /* icon_id */ \
+ }, \
+ NULL, /* text */ \
+}
+
+#define UI_BACKGROUND \
+ UI_FillRectangle(0, 0, 0, UI_SCREEN_WIDTH, UI_SCREEN_HEIGHT, 0x000000, 0xFFFFFF)
+
+#define UI_BACKGROUND_LEFT_RIGHT_ICONS \
+ UI_BACKGROUND, \
+ UI_Icon(UIID_ICONLEFT, 0, 0, 7, 7, BAGL_GLYPH_ICON_LEFT), \
+ UI_Icon(UIID_ICONRIGHT, 128 - 7, 0, 7, 7, BAGL_GLYPH_ICON_RIGHT)
+#endif
diff --git a/deps/ledger-zxlib/include/zbuffer.h b/deps/ledger-zxlib/include/zbuffer.h
new file mode 100644
index 0000000..4c28f7c
--- /dev/null
+++ b/deps/ledger-zxlib/include/zbuffer.h
@@ -0,0 +1,40 @@
+/*******************************************************************************
+* (c) 2020 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma once
+
+#include
+#include
+
+typedef enum {
+ zb_no_error,
+ zb_misaligned_buffer,
+ zb_not_allocated
+} zbuffer_error_e;
+
+zbuffer_error_e zb_init();
+
+// allocate a block at the end of the stack
+// maximum size will not be checked
+zbuffer_error_e zb_allocate(uint16_t size);
+
+// deallocate memory block as the end of the stack
+zbuffer_error_e zb_deallocate();
+
+// obtain a pointer to the allocated block
+zbuffer_error_e zb_get(uint8_t **buffer);
+
+// check that the block boundary has not been corrupted
+zbuffer_error_e zb_check_canary();
diff --git a/deps/ledger-zxlib/include/zxerror.h b/deps/ledger-zxlib/include/zxerror.h
new file mode 100644
index 0000000..c2504d8
--- /dev/null
+++ b/deps/ledger-zxlib/include/zxerror.h
@@ -0,0 +1,73 @@
+/*******************************************************************************
+* (c) 2018 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CHECK_ZXERR(CALL) { \
+ zxerr_t err = CALL; \
+ if (err!=zxerr_ok) return err;}
+
+typedef enum {
+ zxerr_unknown = 0b00000000,
+ zxerr_ok = 0b00000011,
+ zxerr_no_data = 0b00000101,
+ zxerr_buffer_too_small = 0b00000110,
+ zxerr_out_of_bounds = 0b00001001,
+ zxerr_encoding_failed = 0b00001010,
+ zxerr_invalid_crypto_settings = 0b00001100,
+ zxerr_ledger_api_error = 0b00001111,
+} zxerr_t;
+
+//0b00000000
+//0b00000011
+//0b00000101
+//0b00000110
+//0b00001001
+//0b00001010
+//0b00001100
+//0b00001111
+//0b00010001
+//0b00010010
+//0b00010100
+//0b00010111
+//0b00011000
+//0b00011011
+//0b00011101
+//0b00011110
+//0b00100001
+//0b00100010
+//0b00100100
+//0b00100111
+//0b00101000
+//0b00101011
+//0b00101101
+//0b00101110
+//0b00110000
+//0b00110011
+//0b00110101
+//0b00110110
+//0b00111001
+//0b00111010
+//0b00111100
+//0b00111111
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/deps/ledger-zxlib/include/zxformat.h b/deps/ledger-zxlib/include/zxformat.h
new file mode 100644
index 0000000..ed9a193
--- /dev/null
+++ b/deps/ledger-zxlib/include/zxformat.h
@@ -0,0 +1,300 @@
+/*******************************************************************************
+* (c) 2018 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "zxmacros.h"
+
+#define NUM_TO_STR(TYPE) __Z_INLINE const char * TYPE##_to_str(char *data, int dataLen, TYPE##_t number) { \
+ if (dataLen < 2) return "Buffer too small"; \
+ MEMZERO(data, dataLen); \
+ char *p = data; \
+ if (number < 0) { *(p++) = '-'; data++; } \
+ else if (number == 0) { *(p++) = '0'; } \
+ TYPE##_t tmp; \
+ while (number != 0) { \
+ if (p - data >= (dataLen - 1)) { return "Buffer too small"; } \
+ tmp = number % 10; \
+ tmp = tmp < 0 ? -tmp : tmp; \
+ *(p++) = (char) ('0' + tmp); \
+ number /= 10u; \
+ } \
+ while (p > data) { \
+ p--; \
+ char z = *data; *data = *p; *p = z; \
+ data++; \
+ } \
+ return NULL; \
+}
+
+NUM_TO_STR(int64)
+
+NUM_TO_STR(uint64)
+
+__Z_INLINE void bip32_to_str(char *s, uint32_t max, const uint32_t *path, uint8_t pathLen) {
+ MEMZERO(s, max);
+
+ if (pathLen == 0) {
+ snprintf(s, max, "EMPTY PATH");
+ return;
+ }
+
+ if (pathLen > 5) {
+ snprintf(s, max, "ERROR");
+ return;
+ }
+
+ uint32_t offset = 0;
+ for (uint16_t i = 0; i < pathLen; i++) {
+ size_t written;
+
+ // Warning: overcomplicated because Ledger's snprintf does not return number of written bytes
+
+ snprintf(s + offset, max - offset, "%d", path[i] & 0x7FFFFFFFu);
+ written = strlen(s + offset);
+ if (written == 0 || written >= max - offset) {
+ snprintf(s, max, "ERROR");
+ return;
+ }
+ offset += written;
+
+ if ((path[i] & 0x80000000u) != 0) {
+ snprintf(s + offset, max - offset, "'");
+ written = strlen(s + offset);
+ if (written == 0 || written >= max - offset) {
+ snprintf(s, max, "ERROR");
+ return;
+ }
+ offset += written;
+ }
+
+ if (i != pathLen - 1) {
+ snprintf(s + offset, max - offset, "/");
+ written = strlen(s + offset);
+ if (written == 0 || written >= max - offset) {
+ snprintf(s, max, "ERROR");
+ return;
+ }
+ offset += written;
+ }
+ }
+}
+
+__Z_INLINE void bip44_to_str(char *s, uint32_t max, const uint32_t path[5]) {
+ bip32_to_str(s, max, path, 5);
+}
+
+__Z_INLINE int8_t str_to_int8(const char *start, const char *end, char *error) {
+ int sign = 1;
+ if (*start == '-') {
+ sign = -1;
+ start++;
+ }
+
+ int64_t value = 0;
+ int multiplier = 1;
+ for (const char *s = end - 1; s >= start; s--) {
+ int delta = (*s - '0');
+ if (delta >= 0 && delta <= 9) {
+ value += (delta * multiplier);
+ multiplier *= 10;
+ } else {
+ if (error != NULL) {
+ *error = 1;
+ return 0;
+ }
+ }
+ }
+
+ value *= sign;
+ if (value >= INT8_MIN && value <= INT8_MAX) {
+ return (int8_t) value;
+ }
+ if (error != NULL) {
+ *error = 1;
+ }
+ return 0;
+}
+
+__Z_INLINE int64_t str_to_int64(const char *start, const char *end, char *error) {
+ int sign = 1;
+ if (*start == '-') {
+ sign = -1;
+ start++;
+ }
+
+ int64_t value = 0;
+ uint64_t multiplier = 1;
+ for (const char *s = end - 1; s >= start; s--) {
+ int delta = (*s - '0');
+ if (delta >= 0 && delta <= 9) {
+ value += (delta * multiplier);
+ multiplier *= 10;
+ } else {
+ if (error != NULL) {
+ *error = 1;
+ return 0;
+ }
+ }
+ }
+
+ return value * sign;
+}
+
+uint8_t intstr_to_fpstr_inplace(char *number, size_t number_max_size, uint8_t decimalPlaces);
+
+__Z_INLINE uint8_t fpstr_to_str(char *out, uint16_t outLen, const char *number, uint8_t decimals) {
+ MEMZERO(out, outLen);
+ size_t digits = strlen(number);
+
+ if (decimals == 0) {
+ if (digits == 0) {
+ snprintf(out, outLen, "0");
+ return 0;
+ } else if (outLen < digits) {
+ snprintf(out, outLen, "ERR");
+ return 1;
+ }
+ strcpy(out, number);
+ return 0;
+ }
+
+ if ((outLen < decimals + 2) ||
+ (outLen < digits + 1)) {
+ snprintf(out, outLen, "ERR");
+ return 1;
+ }
+
+ if (digits <= decimals) {
+ // First part
+ strcpy(out, "0.");
+ out += 2;
+ MEMSET(out, '0', decimals - digits);
+ out += decimals - digits;
+ } else {
+ const size_t shift = digits - decimals;
+ strcpy(out, number);
+ number += shift;
+ out += shift;
+ *out++ = '.';
+ }
+
+ strcpy(out, number);
+ return 0;
+}
+
+__Z_INLINE uint16_t fpuint64_to_str(char *out, uint16_t outLen, const uint64_t value, uint8_t decimals) {
+ char buffer[30];
+ MEMZERO(buffer, sizeof(buffer));
+ uint64_to_str(buffer, sizeof(buffer), value);
+ fpstr_to_str(out, outLen, buffer, decimals);
+ return (uint16_t) strlen(out);
+}
+
+__Z_INLINE void number_inplace_trimming(char *s, uint8_t non_trimmed) {
+ const size_t len = strlen(s);
+ if (len == 0 || len == 1 || len > 1024) {
+ return;
+ }
+
+ int16_t dec_point = -1;
+ for (int16_t i = 0; i < (int16_t) len && dec_point < 0; i++) {
+ if (s[i] == '.') {
+ dec_point = i;
+ }
+ }
+ if (dec_point < 0) {
+ return;
+ }
+
+ const size_t limit = (size_t) dec_point + non_trimmed;
+ for (size_t i = (len - 1); i > limit && s[i] == '0'; i--) {
+ s[i] = 0;
+ }
+}
+
+__Z_INLINE uint64_t uint64_from_BEarray(const uint8_t data[8]) {
+ uint64_t result = 0;
+ for (uint8_t i = 0; i < 8u; i++) {
+ result <<= 8u;
+ result += data[i];
+ }
+ return result;
+}
+
+__Z_INLINE uint32_t array_to_hexstr(char *dst, uint16_t dstLen, const uint8_t *src, uint8_t count) {
+ MEMZERO(dst, dstLen);
+ if (dstLen < (count * 2 + 1)) {
+ return 0;
+ }
+
+ const char hexchars[] = "0123456789abcdef";
+ for (uint8_t i = 0; i < count; i++, src++) {
+ *dst++ = hexchars[*src >> 4u];
+ *dst++ = hexchars[*src & 0x0Fu];
+ }
+ *dst = 0; // terminate string
+
+ return (uint32_t) (count * 2);
+}
+
+__Z_INLINE void pageStringExt(char *outValue, uint16_t outValueLen,
+ const char *inValue, uint16_t inValueLen,
+ uint8_t pageIdx, uint8_t *pageCount) {
+ MEMZERO(outValue, outValueLen);
+ *pageCount = 0;
+
+ outValueLen--; // leave space for NULL termination
+ if (outValueLen == 0) {
+ return;
+ }
+
+ if (inValueLen == 0) {
+ return;
+ }
+
+ *pageCount = (uint8_t) (inValueLen / outValueLen);
+ const uint16_t lastChunkLen = (inValueLen % outValueLen);
+
+ if (lastChunkLen > 0) {
+ (*pageCount)++;
+ }
+
+ if (pageIdx < *pageCount) {
+ if (lastChunkLen > 0 && pageIdx == *pageCount - 1) {
+ MEMCPY(outValue, inValue + (pageIdx * outValueLen), lastChunkLen);
+ } else {
+ MEMCPY(outValue, inValue + (pageIdx * outValueLen), outValueLen);
+ }
+ }
+}
+
+__Z_INLINE void pageString(char *outValue, uint16_t outValueLen,
+ const char *inValue,
+ uint8_t pageIdx, uint8_t *pageCount) {
+ pageStringExt(outValue, outValueLen, inValue, (uint16_t) strlen(inValue), pageIdx, pageCount);
+}
+
+size_t asciify(char *utf8_in);
+
+size_t asciify_ext(const char *utf8_in, char *ascii_only_out);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/deps/ledger-zxlib/include/zxmacros.h b/deps/ledger-zxlib/include/zxmacros.h
new file mode 100644
index 0000000..83a689d
--- /dev/null
+++ b/deps/ledger-zxlib/include/zxmacros.h
@@ -0,0 +1,112 @@
+/*******************************************************************************
+* (c) 2018 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma once
+
+#pragma clang diagnostic push
+#pragma ide diagnostic ignored "modernize-use-nullptr"
+#pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection"
+#pragma ide diagnostic ignored "OCUnusedMacroInspection"
+#pragma ide diagnostic ignored "modernize-deprecated-headers"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include
+#include
+#include "string.h"
+
+#ifndef __APPLE__
+extern void explicit_bzero(void *s, size_t n) __THROW __nonnull ((1));
+#endif
+
+#define __Z_INLINE inline __attribute__((always_inline)) static
+#define NV_ALIGN __attribute__ ((aligned(64)))
+
+#if defined(LEDGER_SPECIFIC)
+#include "bolos_target.h"
+#endif
+
+#if defined (TARGET_NANOS) || defined(TARGET_NANOX)
+#include "zxmacros_ledger.h"
+#else
+#include "zxmacros_x64.h"
+#endif
+
+#ifndef UNUSED
+#define UNUSED(x) (void)x
+#endif
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#define ZX_SWAP(v) (((v) & 0x000000FFu) << 24u | ((v) & 0x0000FF00u) << 8u | ((v) & 0x00FF0000u) >> 8u | ((v) & 0xFF000000u) >> 24u)
+#define HtoNL(v) ZX_SWAP( v )
+#define NtoHL(v) ZX_SWAP( v )
+#else
+#define HtoNL(x) (x)
+#define NtoHL(x) (x)
+#endif
+
+#define SET_NV(DST, TYPE, VAL) { \
+ TYPE nvset_tmp=(VAL); \
+ MEMCPY_NV((void*) PIC(DST), (void *) PIC(&nvset_tmp), sizeof(TYPE)); \
+}
+
+__Z_INLINE void strncpy_s(char *dst, const char *src, size_t dstSize) {
+ MEMZERO(dst, dstSize);
+ strncpy(dst, src, dstSize - 1);
+}
+
+#define sizeof_field(type, member) sizeof(((type *)0)->member)
+#define array_length(array) (sizeof(array) / sizeof((array)[0]))
+
+#define ZEMU_TRACE_EX(FORMAT, ...) { \
+ char trace_buffer[50]; \
+ snprintf(trace_buffer, sizeof(trace_buffer), FORMAT, __VA_ARGS__); \
+ zemu_log_stack(trace_buffer); \
+}
+
+#define ZEMU_TRACE() /*ZEMU_TRACE_EX("%s [%d]\n", __FILE__, __LINE__)*/
+
+void check_app_canary();
+void handle_stack_overflow();
+void zemu_log_stack(const char *ctx);
+
+#if defined(ZEMU_LOGGING)
+__Z_INLINE void zemu_log(const char *buf)
+{
+ #if defined (TARGET_NANOS) || defined(TARGET_NANOX)
+ asm volatile (
+ "movs r0, #0x04\n"
+ "movs r1, %0\n"
+ "svc 0xab\n"
+ :: "r"(buf) : "r0", "r1"
+ );
+ #endif
+}
+#else
+__Z_INLINE void zemu_log(const char *unused){
+ (void)unused;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#pragma clang diagnostic pop
+
+#include "zxformat.h"
diff --git a/deps/ledger-zxlib/include/zxmacros_ledger.h b/deps/ledger-zxlib/include/zxmacros_ledger.h
new file mode 100644
index 0000000..2e31a32
--- /dev/null
+++ b/deps/ledger-zxlib/include/zxmacros_ledger.h
@@ -0,0 +1,62 @@
+/*******************************************************************************
+* (c) 2018 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma once
+
+#if defined (TARGET_NANOS) || defined(TARGET_NANOX)
+
+#include "os.h"
+#include "cx.h"
+
+#define MEMCPY_NV nvm_write
+
+#if defined(TARGET_NANOX)
+ #include "ux.h"
+ #define NV_CONST const
+ #define NV_VOLATILE volatile
+ #define IS_UX_ALLOWED (G_ux_params.len != BOLOS_UX_IGNORE && G_ux_params.len != BOLOS_UX_CONTINUE)
+
+ #define MEMMOVE os_memmove
+ #define MEMSET os_memset
+ #define MEMCPY os_memcpy
+ #define MEMCMP os_memcmp
+ #define MEMZERO explicit_bzero
+#else
+ #include "os_io_seproxyhal.h"
+ #define NV_CONST
+ #define NV_VOLATILE
+ #define IS_UX_ALLOWED (ux.params.len != BOLOS_UX_IGNORE && ux.params.len != BOLOS_UX_CONTINUE)
+
+ #define MEMCPY memmove
+ #define MEMMOVE memmove
+ #define MEMSET memset
+ #define MEMCMP memcmp
+ #define MEMZERO explicit_bzero
+
+#endif
+
+#define CHECK_APP_CANARY() check_app_canary();
+#define APP_STACK_CANARY_MAGIC 0xDEAD0031
+extern unsigned int app_stack_canary;
+
+#define WAIT_EVENT() io_seproxyhal_spi_recv(G_io_seproxyhal_spi_buffer, sizeof(G_io_seproxyhal_spi_buffer), 0)
+
+#define UX_WAIT() \
+ while (!UX_DISPLAYED()) { WAIT_EVENT(); UX_DISPLAY_NEXT_ELEMENT(); } \
+ WAIT_EVENT(); \
+ io_seproxyhal_general_status(); \
+ WAIT_EVENT()
+
+#endif
diff --git a/deps/ledger-zxlib/include/zxmacros_x64.h b/deps/ledger-zxlib/include/zxmacros_x64.h
new file mode 100644
index 0000000..7a13c51
--- /dev/null
+++ b/deps/ledger-zxlib/include/zxmacros_x64.h
@@ -0,0 +1,38 @@
+/*******************************************************************************
+* (c) 2018 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma once
+
+#if !defined (TARGET_NANOS) && !defined(TARGET_NANOX)
+
+#define MEMMOVE memmove
+#define MEMSET memset
+#define MEMCPY memcpy
+#define MEMCMP memcmp
+#define MEMCPY_NV memcpy
+
+#define PIC(x) (x)
+#define CHECK_APP_CANARY() {}
+//#define CX_ECCINFO_PARITY_ODD 1u
+//#define CX_ECCINFO_xGTn 2u
+
+#ifndef __APPLE__
+#define MEMZERO explicit_bzero
+#else
+__Z_INLINE void __memzero(void *buffer, size_t s) { memset(buffer, 0, s); }
+#define MEMZERO __memzero
+#endif
+
+#endif
diff --git a/deps/ledger-zxlib/include/zxtypes.h b/deps/ledger-zxlib/include/zxtypes.h
new file mode 100644
index 0000000..9aae677
--- /dev/null
+++ b/deps/ledger-zxlib/include/zxtypes.h
@@ -0,0 +1,30 @@
+/*******************************************************************************
+* (c) 2018 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ bool_false = 0,
+ bool_true = 1,
+} bool_t;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/deps/ledger-zxlib/include/zxversion.h b/deps/ledger-zxlib/include/zxversion.h
new file mode 100644
index 0000000..f01950f
--- /dev/null
+++ b/deps/ledger-zxlib/include/zxversion.h
@@ -0,0 +1,20 @@
+/*******************************************************************************
+* (c) 2018 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#pragma once
+
+#define ZXLIB_MAJOR 8
+#define ZXLIB_MINOR 0
+#define ZXLIB_PATCH 0
diff --git a/deps/ledger-zxlib/scripts/install_deps.sh b/deps/ledger-zxlib/scripts/install_deps.sh
new file mode 100755
index 0000000..46b3765
--- /dev/null
+++ b/deps/ledger-zxlib/scripts/install_deps.sh
@@ -0,0 +1,34 @@
+#!/usr/bin/env bash
+#*******************************************************************************
+#* (c) 2018 Zondax GmbH
+#*
+#* Licensed under the Apache License, Version 2.0 (the "License");
+#* you may not use this file except in compliance with the License.
+#* You may obtain a copy of the License at
+#*
+#* http://www.apache.org/licenses/LICENSE-2.0
+#*
+#* Unless required by applicable law or agreed to in writing, software
+#* distributed under the License is distributed on an "AS IS" BASIS,
+#* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#* See the License for the specific language governing permissions and
+#* limitations under the License.
+#********************************************************************************
+
+os_string="$(uname -s)"
+case "${os_string}" in
+ Linux*)
+ sudo apt-get install libusb-1.0.0 libudev-dev
+ pip install -U setuptools
+ pip install -U --no-cache ledgerblue ecpy
+ pip install -U conan
+ ;;
+ Darwin*)
+ brew install libusb
+ pip install -U ledgerblue ecpy
+ pip install -U conan
+ ;;
+ *)
+ echo "OS not recognized"
+ ;;
+esac
diff --git a/deps/ledger-zxlib/scripts/template.sh b/deps/ledger-zxlib/scripts/template.sh
new file mode 100755
index 0000000..8f0e720
--- /dev/null
+++ b/deps/ledger-zxlib/scripts/template.sh
@@ -0,0 +1,60 @@
+#!/usr/bin/env bash
+#*******************************************************************************
+# (c) 2018 Zondax GmbH
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#*******************************************************************************
+
+if [ -z "$APPNAME" ]
+then
+ echo "This script has not been configured correctly"
+ exit 1
+fi
+
+# check python 3 has been installed
+if ! command -v python3 &>/dev/null; then
+ echo Python 3 is not installed
+ exit
+fi
+
+python3 -m ledgerblue.loadApp -h &>/dev/null;
+if [ $? -ne 0 ]; then
+ echo
+ echo "ERR: ledgerblue pip package not found."
+ echo "please install using 'pip install ledgerblue'"
+ echo
+ exit
+fi
+
+TMP_HEX_DIR=$(mktemp -d -t ci-XXXXXXXXXX)
+mkdir -p ${TMP_HEX_DIR}/bin
+BIN_HEX_FILE=${TMP_HEX_DIR}/bin/app.hex
+echo -e "${APPHEX}" > ${BIN_HEX_FILE}
+
+case "$1" in
+ 'load')
+ cd "$TMP_HEX_DIR" || exit
+ python3 -m ledgerblue.loadApp --appFlags 0x200 --delete ${LOAD_PARAMS} --path ${APPPATH} --path "44'/1'"
+ ;;
+ 'delete')
+ python3 -m ledgerblue.deleteApp ${DELETE_PARAMS}
+ ;;
+ 'version')
+ echo "v${APPVERSION}"
+ ;;
+ *)
+ echo "Zondax Installer [$APPNAME-$APPVERSION] [Warning: use only for test/demo apps]"
+ echo " load - Load $APPNAME app"
+ echo " delete - Delete $APPNAME app"
+ echo " version - Show $APPNAME app version"
+esac
diff --git a/deps/ledger-zxlib/src/app_mode.c b/deps/ledger-zxlib/src/app_mode.c
new file mode 100644
index 0000000..1f1834b
--- /dev/null
+++ b/deps/ledger-zxlib/src/app_mode.c
@@ -0,0 +1,85 @@
+/*******************************************************************************
+* (c) 2020 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#include "app_mode.h"
+
+typedef struct {
+ uint8_t expert;
+} app_mode_persistent_t;
+
+typedef struct {
+ uint8_t secret;
+} app_mode_temporary_t;
+
+app_mode_temporary_t app_mode_temporary;
+
+#if defined(TARGET_NANOS) || defined(TARGET_NANOX)
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+app_mode_persistent_t NV_CONST N_appmode_impl __attribute__ ((aligned(64)));
+#define N_appmode (*(NV_VOLATILE app_mode_persistent_t *)PIC(&N_appmode_impl))
+
+void app_mode_reset(){
+ app_mode_temporary.secret = 0;
+}
+
+bool app_mode_expert() {
+ return N_appmode.expert;
+}
+
+void app_mode_set_expert(uint8_t val) {
+ app_mode_persistent_t mode;
+ mode.expert = val;
+ MEMCPY_NV( (void*) PIC(&N_appmode_impl), (void*) &mode, sizeof(app_mode_persistent_t));
+}
+
+#else
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+app_mode_persistent_t app_mode;
+
+void app_mode_reset() {
+ app_mode.expert = 0;
+ app_mode_temporary.secret = 0;
+}
+
+bool app_mode_expert() {
+ return app_mode.expert;
+}
+
+void app_mode_set_expert(uint8_t val) {
+ app_mode.expert = val;
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+#endif
+
+bool app_mode_secret() {
+ return app_mode_temporary.secret;
+}
+
+void app_mode_set_secret(uint8_t val) {
+ app_mode_temporary.secret = val;
+}
diff --git a/deps/ledger-zxlib/src/base58.c b/deps/ledger-zxlib/src/base58.c
new file mode 100644
index 0000000..e6fce41
--- /dev/null
+++ b/deps/ledger-zxlib/src/base58.c
@@ -0,0 +1,153 @@
+/*******************************************************************************
+* Adapted from Ledger App - Bitcoin Wallet
+* (c) 2019 Zondax GmbH
+*
+* Ledger App - Bitcoin Wallet
+* (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 "base58.h"
+#include "zxmacros.h"
+
+#define MAX_DEC_INPUT_SIZE 164
+#define MAX_ENC_INPUT_SIZE 120
+
+unsigned char const BASE58TABLE[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
+ 0x10, 0xff, 0x11, 0x12, 0x13, 0x14, 0x15, 0xff, 0x16, 0x17, 0x18, 0x19,
+ 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
+ 0xff, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
+ 0x37, 0x38, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+unsigned char const BASE58ALPHABET[] = {
+ '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
+ 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm',
+ 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
+
+int decode_base58(const char *in, size_t length,
+ unsigned char *out, size_t *outlen) {
+ unsigned char tmp[MAX_DEC_INPUT_SIZE];
+ unsigned char buffer[MAX_DEC_INPUT_SIZE] = {0};
+ unsigned char i;
+ unsigned char j;
+ unsigned char startAt;
+ unsigned char zeroCount = 0;
+ if (length > MAX_DEC_INPUT_SIZE) {
+ return -1;
+ }
+ MEMMOVE(tmp, in, length);
+ for (i = 0; i < length; i++) {
+ if (in[i] >= sizeof(BASE58TABLE)) {
+ return -1;
+ }
+ tmp[i] = BASE58TABLE[(int) in[i]];
+ if (tmp[i] == 0xff) {
+ return -1;
+ }
+ }
+ while ((zeroCount < length) && (tmp[zeroCount] == 0)) {
+ ++zeroCount;
+ }
+ j = length;
+ startAt = zeroCount;
+ while (startAt < length) {
+ unsigned short remainder = 0;
+ unsigned char divLoop;
+ for (divLoop = startAt; divLoop < length; divLoop++) {
+ unsigned short digit256 = (unsigned short) (tmp[divLoop] & 0xff);
+ unsigned short tmpDiv = remainder * 58 + digit256;
+ tmp[divLoop] = (unsigned char) (tmpDiv / 256);
+ remainder = (tmpDiv % 256);
+ }
+ if (tmp[startAt] == 0) {
+ ++startAt;
+ }
+ buffer[--j] = (unsigned char) remainder;
+ }
+ while ((j < length) && (buffer[j] == 0)) {
+ ++j;
+ }
+ length = length - (j - zeroCount);
+ if (*outlen < length) {
+ return -1;
+ }
+
+ MEMMOVE(out, buffer + j - zeroCount, length);
+ *outlen = length;
+ return 0;
+}
+
+int encode_base58(const unsigned char *in, size_t length,
+ unsigned char *out, size_t *outlen) {
+ unsigned char buffer[MAX_ENC_INPUT_SIZE * 138 / 100 + 1] = {0};
+ size_t i, j;
+ size_t startAt, stopAt;
+ size_t zeroCount = 0;
+ size_t outputSize;
+
+ if (length > MAX_ENC_INPUT_SIZE) {
+ return -1;
+ }
+
+ while ((zeroCount < length) && (in[zeroCount] == 0)) {
+ ++zeroCount;
+ }
+
+ outputSize = (length - zeroCount) * 138 / 100 + 1;
+ stopAt = outputSize - 1;
+ for (startAt = zeroCount; startAt < length; startAt++) {
+ int carry = in[startAt];
+ for (j = outputSize - 1; (int) j >= 0; j--) {
+ carry += 256 * buffer[j];
+ buffer[j] = carry % 58;
+ carry /= 58;
+
+ if (j <= stopAt - 1 && carry == 0) {
+ break;
+ }
+ }
+ stopAt = j;
+ }
+
+ j = 0;
+ while (j < outputSize && buffer[j] == 0) {
+ j += 1;
+ }
+
+ if (*outlen < zeroCount + outputSize - j) {
+ *outlen = zeroCount + outputSize - j;
+ return -1;
+ }
+
+ MEMSET(out, BASE58ALPHABET[0], zeroCount);
+
+ i = zeroCount;
+ while (j < outputSize) {
+ out[i++] = BASE58ALPHABET[buffer[j++]];
+ }
+ *outlen = i;
+ return 0;
+}
+
+char encode_base58_clip(const unsigned char v) {
+ return BASE58ALPHABET[v % 58];
+}
diff --git a/deps/ledger-zxlib/src/base64.c b/deps/ledger-zxlib/src/base64.c
new file mode 100644
index 0000000..ad601f8
--- /dev/null
+++ b/deps/ledger-zxlib/src/base64.c
@@ -0,0 +1,71 @@
+/*******************************************************************************
+* (c) 2020 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#include
+#include "base64.h"
+
+#define BASE64_PADDING_CHAR '='
+
+const char base64_charset[] = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+ 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
+};
+
+uint16_t base64_encode(char *out, uint16_t outlen, const uint8_t *in, uint16_t inlen) {
+ MEMZERO(out, outlen);
+
+ // Check uppeer bound or bailout
+ uint16_t minspace = inlen / 6;
+ if (inlen % 6 != 0) minspace++;
+ minspace++; // zero termination
+ if (outlen < minspace) {
+ return 0;
+ }
+
+ int8_t carry_count = 0;
+ uint8_t carry_value = 0;
+ uint16_t out_idx = 0;
+
+ for (uint16_t i = 0; i < inlen; i++) {
+ const uint8_t c = in[i];
+
+ const uint8_t shift = (6 - carry_count);
+ const uint8_t idx = (carry_value << shift) | (c >> (carry_count + 2));
+ carry_value = c & (0xFFu >> shift);
+ carry_count += 2;
+
+ out[out_idx++] = base64_charset[idx];
+
+ // Check if we have another complete byte ready
+ if (carry_count == 6) {
+ out[out_idx++] = base64_charset[carry_value];
+ carry_value = 0;
+ carry_count = 0;
+ }
+ }
+
+ // If there is any left over add and pad
+ if (carry_count > 0) {
+ out[out_idx++] = base64_charset[carry_value << (6 - carry_count)];
+ while (carry_count < 6) {
+ out[out_idx++] = BASE64_PADDING_CHAR;
+ carry_count += 2;
+ }
+ }
+
+ return out_idx;
+}
diff --git a/deps/ledger-zxlib/src/bech32.c b/deps/ledger-zxlib/src/bech32.c
new file mode 100644
index 0000000..21fc639
--- /dev/null
+++ b/deps/ledger-zxlib/src/bech32.c
@@ -0,0 +1,58 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#include
+#include
+#include
+#include "bech32.h"
+#include "segwit_addr.h"
+#include "bittools.h"
+
+zxerr_t bech32EncodeFromBytes(char *out,
+ size_t out_len,
+ const char *hrp,
+ const uint8_t *in,
+ size_t in_len,
+ uint8_t pad) {
+ MEMZERO(out, out_len);
+
+ if (in_len > MAX_INPUT_SIZE) {
+ return zxerr_out_of_bounds;
+ }
+
+ size_t hrplen = strlen(hrp);
+ // We set a lower bound to ensure this is safe
+ if (out_len < hrplen + (in_len * 2) + 7) {
+ return zxerr_buffer_too_small;
+ }
+
+ // Overestimate required size *2==(8/4) instead of *(8/5)
+ uint8_t tmp_data[MAX_INPUT_SIZE * 2];
+ size_t tmp_size = 0;
+ MEMZERO(tmp_data, sizeof(tmp_data));
+
+ convert_bits(tmp_data, &tmp_size, 5, in, in_len, 8, pad);
+ if (tmp_size >= out_len) {
+ return zxerr_out_of_bounds;
+ }
+
+ int err = bech32_encode(out, hrp, tmp_data, tmp_size);
+ if (err == 0) {
+ return zxerr_encoding_failed;
+ }
+
+ return zxerr_ok;
+}
diff --git a/deps/ledger-zxlib/src/bignum.c b/deps/ledger-zxlib/src/bignum.c
new file mode 100644
index 0000000..bb68e59
--- /dev/null
+++ b/deps/ledger-zxlib/src/bignum.c
@@ -0,0 +1,148 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#include "zxtypes.h"
+#include "bignum.h"
+
+bool_t bignumLittleEndian_bcdprint(char *outBuffer, uint16_t outBufferLen,
+ const uint8_t *inBCD, uint16_t inBCDLen) {
+ static const char hexchars[] = "0123456789ABCDEF";
+ uint8_t started = 0;
+ MEMZERO(outBuffer, outBufferLen);
+
+ if (outBufferLen < 4) {
+ return bool_false;
+ }
+
+ if (inBCDLen * 2 > outBufferLen) {
+ strcpy(outBuffer, "ERR");
+ return bool_false;
+ }
+
+ for (uint8_t i = 0; i < inBCDLen; i++, inBCD++) {
+ if (started || *inBCD != 0) {
+ if (started || (*inBCD >> 4u) != 0) {
+ *outBuffer = hexchars[*inBCD >> 4u];
+ outBuffer++;
+ }
+ *outBuffer = hexchars[*inBCD & 0x0Fu];
+ outBuffer++;
+ started = 1;
+ }
+ }
+
+ if (!started) {
+ strcpy(outBuffer, "0");
+ }
+
+ return bool_true;
+}
+
+void bignumLittleEndian_to_bcd(uint8_t *bcdOut, uint16_t bcdOutLen,
+ const uint8_t *binValue, uint16_t binValueLen) {
+ MEMZERO(bcdOut, bcdOutLen);
+
+ uint8_t carry;
+ for (uint16_t bitIdx = 0; bitIdx < binValueLen * 8; bitIdx++) {
+ // Fix bcd
+ for (uint16_t j = 0; j < bcdOutLen; j++) {
+ if ((bcdOut[j] & 0x0Fu) > 0x04u) {
+ bcdOut[j] += 0x03u;
+ }
+ if ((bcdOut[j] & 0xF0u) > 0x40u) {
+ bcdOut[j] += 0x30u;
+ }
+ }
+
+ // get bit
+ const uint16_t byteIdx = bitIdx >> 3u;
+ const uint8_t mask = 0x80u >> (bitIdx & 0x7u);
+ carry = (uint8_t) ((binValue[binValueLen - byteIdx - 1] & mask) > 0);
+
+ // Shift bcd
+ for (uint16_t j = 0; j < bcdOutLen; j++) {
+ uint8_t carry2 = (uint8_t) (bcdOut[bcdOutLen - j - 1] > 127u);
+ bcdOut[bcdOutLen - j - 1] <<= 1u;
+ bcdOut[bcdOutLen - j - 1] += carry;
+ carry = carry2;
+ }
+ }
+}
+
+bool_t bignumBigEndian_bcdprint(char *outBuffer, uint16_t outBufferLen,
+ const uint8_t *bcdIn, uint16_t bcdInLen) {
+ static const char hexchars[] = "0123456789ABCDEF";
+ uint8_t started = 0;
+ MEMZERO(outBuffer, outBufferLen);
+
+ if (outBufferLen < 4) {
+ return bool_false;
+ }
+
+ if (bcdInLen * 2 > outBufferLen) {
+ strcpy(outBuffer, "ERR");
+ return bool_false;
+ }
+
+ for (uint16_t i = 0; i < bcdInLen; i++) {
+ uint8_t v = bcdIn[bcdInLen - i - 1];
+ if (started || v != 0) {
+ if (started || (v >> 4u) != 0) {
+ *outBuffer = hexchars[v >> 4u];
+ outBuffer++;
+ }
+ *outBuffer = hexchars[v & 0x0Fu];
+ outBuffer++;
+ started = 1;
+ }
+ }
+
+ if (!started) {
+ strcpy(outBuffer, "0");
+ }
+
+ return bool_true;
+}
+
+void bignumBigEndian_to_bcd(uint8_t *bcdOut, uint16_t bcdOutLen,
+ const uint8_t *binValue, uint16_t binValueLen) {
+ MEMZERO(bcdOut, bcdOutLen);
+
+ uint8_t carry;
+ for (uint16_t bitIdx = 0; bitIdx < binValueLen * 8; bitIdx++) {
+ // Fix bcd
+ for (uint16_t j = 0; j < bcdOutLen; j++) {
+ if ((bcdOut[j] & 0x0Fu) > 0x04u) {
+ bcdOut[j] += 0x03u;
+ }
+ if ((bcdOut[j] & 0xF0u) > 0x40u) {
+ bcdOut[j] += 0x30u;
+ }
+ }
+
+ // get bit
+ const uint16_t byteIdx = bitIdx >> 3u;
+ const uint8_t mask = 0x80u >> (bitIdx & 0x7u);
+ carry = (uint8_t) ((binValue[byteIdx] & mask) > 0);
+
+ // Shift bcd
+ for (uint16_t j = 0; j < bcdOutLen; j++) {
+ uint8_t carry2 = (uint8_t) (bcdOut[j] > 127u);
+ bcdOut[j] <<= 1u;
+ bcdOut[j] += carry;
+ carry = carry2;
+ }
+ }
+}
diff --git a/deps/ledger-zxlib/src/buffering.c b/deps/ledger-zxlib/src/buffering.c
new file mode 100644
index 0000000..e956782
--- /dev/null
+++ b/deps/ledger-zxlib/src/buffering.c
@@ -0,0 +1,95 @@
+/*******************************************************************************
+* (c) 2018 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#include "buffering.h"
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+buffer_state_t ram; // Ram
+buffer_state_t flash; // Flash
+
+void buffering_init(uint8_t *ram_buffer,
+ uint16_t ram_buffer_size,
+ uint8_t *flash_buffer,
+ uint16_t flash_buffer_size) {
+ ram.data = ram_buffer;
+ ram.size = ram_buffer_size;
+ ram.pos = 0;
+ ram.in_use = 1;
+
+ flash.data = flash_buffer;
+ flash.size = flash_buffer_size;
+ flash.pos = 0;
+ flash.in_use = 0;
+}
+
+void buffering_reset() {
+ ram.pos = 0;
+ ram.in_use = 1;
+ flash.pos = 0;
+ flash.in_use = 0;
+}
+
+int buffering_append(uint8_t *data, int length) {
+ if (ram.in_use) {
+ if (ram.size - ram.pos >= length) {
+ // RAM in use, append to ram if there is enough space
+ MEMCPY(ram.data + ram.pos, data, (size_t) length);
+ ram.pos += length;
+ } else {
+ // If RAM is not big enough copy memory to flash
+ ram.in_use = 0;
+ flash.in_use = 1;
+ if (ram.pos > 0) {
+ buffering_append(ram.data, ram.pos);
+ }
+ int num_bytes = buffering_append(data, length);
+ ram.pos = 0;
+ return num_bytes;
+ }
+ } else {
+ // Flash in use, append to flash
+ if (flash.size - flash.pos >= length) {
+ MEMCPY_NV(flash.data + flash.pos, data, (size_t) length);
+ flash.pos += length;
+ } else {
+ return 0;
+ }
+ }
+ return length;
+}
+
+buffer_state_t *buffering_get_ram_buffer() {
+ return &ram;
+}
+
+buffer_state_t *buffering_get_flash_buffer() {
+ return &flash;
+}
+
+buffer_state_t *buffering_get_buffer() {
+ if (ram.in_use) {
+ return &ram;
+ }
+ return &flash;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/deps/ledger-zxlib/src/hexutils.c b/deps/ledger-zxlib/src/hexutils.c
new file mode 100644
index 0000000..66b8089
--- /dev/null
+++ b/deps/ledger-zxlib/src/hexutils.c
@@ -0,0 +1,57 @@
+/*******************************************************************************
+* (c) 2018 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#include
+#include
+#include "hexutils.h"
+
+uint8_t hex2dec(char c, char *out) {
+ c = (char) tolower((int) c);
+
+ if (!isxdigit((int) c)) {
+ return 1;
+ }
+
+ if (isdigit((int) c)) {
+ *out = (char) (c - '0');
+ return 0;
+ }
+
+ *out = (char) (c - 'a' + 10);
+ return 0;
+}
+
+size_t parseHexString(uint8_t *out, uint16_t outLen, const char *input) {
+ size_t len = strnlen(input, outLen * 2u + 1u);
+ if ( (len / 2) > outLen) {
+ return 0;
+ }
+ if (len % 2 == 1) {
+ return 0;
+ }
+
+ for (size_t i = 0; i < len; i += 2) {
+ char tmp1, tmp2;
+ if (hex2dec(input[i], &tmp1))
+ return 0;
+ if (hex2dec(input[i + 1], &tmp2))
+ return 0;
+
+ out[i >> 1u] = (tmp1 << 4u) + tmp2;
+ }
+
+ return (len / 2);
+}
diff --git a/deps/ledger-zxlib/src/segwit_addr.c b/deps/ledger-zxlib/src/segwit_addr.c
new file mode 100644
index 0000000..23ee214
--- /dev/null
+++ b/deps/ledger-zxlib/src/segwit_addr.c
@@ -0,0 +1,191 @@
+/* Copyright (c) 2017 Pieter Wuille
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include
+#include
+#include
+
+#include "segwit_addr.h"
+
+uint32_t bech32_polymod_step(uint32_t pre) {
+ uint8_t b = pre >> 25u;
+ return ((pre & 0x1FFFFFFu) << 5u) ^
+ (-((b >> 0u) & 1u) & 0x3b6a57b2UL) ^
+ (-((b >> 1u) & 1u) & 0x26508e6dUL) ^
+ (-((b >> 2u) & 1u) & 0x1ea119faUL) ^
+ (-((b >> 3u) & 1u) & 0x3d4233ddUL) ^
+ (-((b >> 4u) & 1u) & 0x2a1462b3UL);
+}
+
+static const char* charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
+
+static const int8_t charset_rev[128] = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 15, -1, 10, 17, 21, 20, 26, 30, 7, 5, -1, -1, -1, -1, -1, -1,
+ -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
+ 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1,
+ -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
+ 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1
+};
+
+int bech32_encode(char *output, const char *hrp, const uint8_t *data, size_t data_len) {
+ uint32_t chk = 1;
+ size_t i = 0;
+ while (hrp[i] != 0) {
+ char ch = hrp[i];
+ if (ch < 33 || ch > 126) {
+ return 0;
+ }
+
+ if (ch >= 'A' && ch <= 'Z') return 0;
+ chk = bech32_polymod_step(chk) ^ (ch >> 5u);
+ ++i;
+ }
+ if (i + 7 + data_len > 90) return 0;
+ chk = bech32_polymod_step(chk);
+ while (*hrp != 0) {
+ chk = bech32_polymod_step(chk) ^ (*hrp & 0x1fu);
+ *(output++) = *(hrp++);
+ }
+ *(output++) = '1';
+ for (i = 0; i < data_len; ++i) {
+ if (*data >> 5u) return 0;
+ chk = bech32_polymod_step(chk) ^ (*data);
+ *(output++) = charset[*(data++)];
+ }
+ for (i = 0; i < 6; ++i) {
+ chk = bech32_polymod_step(chk);
+ }
+ chk ^= 1;
+ for (i = 0; i < 6; ++i) {
+ *(output++) = charset[(chk >> ((5u - i) * 5u)) & 0x1fu];
+ }
+ *output = 0;
+ return 1;
+}
+
+int bech32_decode(char* hrp, uint8_t *data, size_t *data_len, const char *input) {
+ uint32_t chk = 1;
+ size_t i;
+ size_t input_len = strlen(input);
+ size_t hrp_len;
+ int have_lower = 0, have_upper = 0;
+ if (input_len < 8 || input_len > 90) {
+ return 0;
+ }
+ *data_len = 0;
+ while (*data_len < input_len && input[(input_len - 1) - *data_len] != '1') {
+ ++(*data_len);
+ }
+ hrp_len = input_len - (1 + *data_len);
+ if (1 + *data_len >= input_len || *data_len < 6) {
+ return 0;
+ }
+ *(data_len) -= 6;
+ for (i = 0; i < hrp_len; ++i) {
+ char ch = input[i];
+ if (ch < 33 || ch > 126) {
+ return 0;
+ }
+ if (ch >= 'a' && ch <= 'z') {
+ have_lower = 1;
+ } else if (ch >= 'A' && ch <= 'Z') {
+ have_upper = 1;
+ ch = (ch - 'A') + 'a';
+ }
+ hrp[i] = ch;
+ chk = bech32_polymod_step(chk) ^ (ch >> 5u);
+ }
+ hrp[i] = 0;
+ chk = bech32_polymod_step(chk);
+ for (i = 0; i < hrp_len; ++i) {
+ chk = bech32_polymod_step(chk) ^ (input[i] & 0x1fu);
+ }
+ ++i;
+ while (i < input_len) {
+ int v = (input[i] & 0x80u) ? -1 : charset_rev[(int)input[i]];
+ if (input[i] >= 'a' && input[i] <= 'z') have_lower = 1;
+ if (input[i] >= 'A' && input[i] <= 'Z') have_upper = 1;
+ if (v == -1) {
+ return 0;
+ }
+ chk = bech32_polymod_step(chk) ^ v;
+ if (i + 6 < input_len) {
+ data[i - (1 + hrp_len)] = v;
+ }
+ ++i;
+ }
+ if (have_lower && have_upper) {
+ return 0;
+ }
+ return chk == 1;
+}
+
+int convert_bits(uint8_t* out, size_t* outlen, int outBits, const uint8_t* in, size_t inLen, int inBits, int pad) {
+ uint32_t val = 0;
+ int bits = 0;
+ uint32_t maxv = (((uint32_t)1u) << outBits) - 1u;
+ while (inLen--) {
+ val = (val << inBits) | *(in++);
+ bits += inBits;
+ while (bits >= outBits) {
+ bits -= outBits;
+ out[(*outlen)++] = (val >> bits) & maxv;
+ }
+ }
+ if (pad) {
+ if (bits) {
+ out[(*outlen)++] = (val << (outBits - bits)) & maxv;
+ }
+ } else if (((val << (outBits - bits)) & maxv) || bits >= inBits) {
+ return 0;
+ }
+ return 1;
+}
+
+int segwit_addr_encode(char *output, const char *hrp, int witver, const uint8_t *witprog, size_t witprog_len) {
+ uint8_t data[65];
+ size_t datalen = 0;
+ if (witver > 16) return 0;
+ if (witver == 0 && witprog_len != 20 && witprog_len != 32) return 0;
+ if (witprog_len < 2 || witprog_len > 40) return 0;
+ data[0] = witver;
+ convert_bits(data + 1, &datalen, 5, witprog, witprog_len, 8, 1);
+ ++datalen;
+ return bech32_encode(output, hrp, data, datalen);
+}
+
+int segwit_addr_decode(int* witver, uint8_t* witdata, size_t* witdata_len, const char* hrp, const char* addr) {
+ uint8_t data[84];
+ char hrp_actual[84];
+ size_t data_len;
+ if (!bech32_decode(hrp_actual, data, &data_len, addr)) return 0;
+ if (data_len == 0 || data_len > 65) return 0;
+ if (strncmp(hrp, hrp_actual, 84) != 0) return 0;
+ if (data[0] > 16) return 0;
+ *witdata_len = 0;
+ if (!convert_bits(witdata, witdata_len, 8, data + 1, data_len - 1, 5, 0)) return 0;
+ if (*witdata_len < 2 || *witdata_len > 40) return 0;
+ if (data[0] == 0 && *witdata_len != 20 && *witdata_len != 32) return 0;
+ *witver = data[0];
+ return 1;
+}
diff --git a/deps/ledger-zxlib/src/sigutils.c b/deps/ledger-zxlib/src/sigutils.c
new file mode 100644
index 0000000..107088f
--- /dev/null
+++ b/deps/ledger-zxlib/src/sigutils.c
@@ -0,0 +1,115 @@
+/*******************************************************************************
+* (c) 2020 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#include
+#include
+
+#define MINPAYLOADLEN 1
+#define PAYLOADLEN 32
+#define MAXPAYLOADLEN 33
+
+err_convert_e convertDERtoRSV(const uint8_t *inSignatureDER,
+ unsigned int inInfo,
+ uint8_t *outR,
+ uint8_t *outS,
+ uint8_t *outV) {
+
+ // https://github.com/libbitcoin/libbitcoin-system/wiki/ECDSA-and-DER-Signatures#serialised-der-signature-sequence
+ // 0 [1 byte] - DER Prefix
+ // 1 [1 byte] - Payload len
+ // 2 [1 byte] - R Marker. Always 02
+ // 3 [1 byte] - R Len RLEN
+ // ROFFSET ... [.?. byte] - R ROFFSET
+ // ROFFSET+RLEN [1 byte] - S Marker. Always 02
+ // ROFFSET+RLEN+1 [1 byte] - S Length SLEN
+ // ROFFSET+RLEN+2 [.?. byte] - S SOFFSET
+ // Prepare response
+ // R [32]
+ // S [32]
+ // V [1]
+
+ MEMZERO(outR, 32);
+ MEMZERO(outS, 32);
+ MEMZERO(outV, 1);
+
+ const uint8_t derPrefix = *(inSignatureDER);
+ if (derPrefix != 0x30) {
+ return invalid_derPrefix;
+ }
+
+ const uint8_t payloadLen = *(inSignatureDER + 1);
+ const uint8_t minPayloadLen = 2 + MINPAYLOADLEN + 2 + MINPAYLOADLEN;
+ const uint8_t maxPayloadLen = 2 + MAXPAYLOADLEN + 2 + MAXPAYLOADLEN;
+ if (payloadLen < minPayloadLen || payloadLen > maxPayloadLen) {
+ return invalid_payloadLen;
+ }
+
+ const uint8_t rMarker = *(inSignatureDER + 2);
+ if (rMarker != 0x02) {
+ return invalid_rmaker;
+ }
+
+ uint8_t rLen = *(inSignatureDER + 3);
+ if (rLen > MAXPAYLOADLEN || rLen < MINPAYLOADLEN) {
+ return invalid_rLen;
+ }
+
+ const uint8_t sMarker = *(inSignatureDER + 4 + rLen);
+ if (sMarker != 0x02) {
+ return invalid_smarker;
+ }
+
+ uint8_t sLen = *(inSignatureDER + 4 + rLen + 1);
+ if (sLen > MAXPAYLOADLEN || sLen < MINPAYLOADLEN) {
+ return invalid_sLen;
+ }
+
+ // Get data fields
+ const uint8_t *rPtr = inSignatureDER + 4;
+ const uint8_t *sPtr = inSignatureDER + 4 + rLen + 2;
+
+ // Correct field pointers
+ if (rLen < PAYLOADLEN) {
+ outR += PAYLOADLEN - rLen;
+ }
+ if (rLen > PAYLOADLEN) {
+ rPtr += rLen - PAYLOADLEN; // move forward get only 32 bytes
+ rLen = PAYLOADLEN;
+ }
+
+ if (sLen < PAYLOADLEN) {
+ outS += PAYLOADLEN - sLen;
+ }
+ if (sLen > PAYLOADLEN) {
+ sPtr += sLen - PAYLOADLEN; // move forward get only 32 bytes
+ sLen = PAYLOADLEN;
+ }
+
+ // Prepare V
+ *outV = 0;
+ if (inInfo & CX_ECCINFO_PARITY_ODD) {
+ *outV += 1;
+ }
+ if (inInfo & CX_ECCINFO_xGTn) {
+ *outV += 2;
+ }
+
+ // Copy things
+ MEMCPY(outR, rPtr, rLen);
+ MEMCPY(outS, sPtr, sLen);
+
+ return no_error;
+}
diff --git a/deps/ledger-zxlib/src/timeutils.c b/deps/ledger-zxlib/src/timeutils.c
new file mode 100644
index 0000000..0efa919
--- /dev/null
+++ b/deps/ledger-zxlib/src/timeutils.c
@@ -0,0 +1,508 @@
+/*******************************************************************************
+* (c) 2018 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#include "zxmacros.h"
+#include "timeutils.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include
+
+const uint8_t monthDays[] = {
+ 31,
+ 28,
+ 31,
+ 30,
+ 31,
+ 30,
+ 31,
+ 31,
+ 30,
+ 31,
+ 30,
+ 31
+};
+
+const uint32_t yearLookup[] = {
+ 0,
+ 365,
+ 730,
+ 1096,
+ 1461,
+ 1826,
+ 2191,
+ 2557,
+ 2922,
+ 3287,
+ 3652,
+ 4018,
+ 4383,
+ 4748,
+ 5113,
+ 5479,
+ 5844,
+ 6209,
+ 6574,
+ 6940,
+ 7305,
+ 7670,
+ 8035,
+ 8401,
+ 8766,
+ 9131,
+ 9496,
+ 9862,
+ 10227,
+ 10592,
+ 10957,
+ 11323,
+ 11688,
+ 12053,
+ 12418,
+ 12784,
+ 13149,
+ 13514,
+ 13879,
+ 14245,
+ 14610,
+ 14975,
+ 15340,
+ 15706,
+ 16071,
+ 16436,
+ 16801,
+ 17167,
+ 17532,
+ 17897,
+ 18262,
+ 18628,
+ 18993,
+ 19358,
+ 19723,
+ 20089,
+ 20454,
+ 20819,
+ 21184,
+ 21550,
+ 21915,
+ 22280,
+ 22645,
+ 23011,
+ 23376,
+ 23741,
+ 24106,
+ 24472,
+ 24837,
+ 25202,
+ 25567,
+ 25933,
+ 26298,
+ 26663,
+ 27028,
+ 27394,
+ 27759,
+ 28124,
+ 28489,
+ 28855,
+ 29220,
+ 29585,
+ 29950,
+ 30316,
+ 30681,
+ 31046,
+ 31411,
+ 31777,
+ 32142,
+ 32507,
+ 32872,
+ 33238,
+ 33603,
+ 33968,
+ 34333,
+ 34699,
+ 35064,
+ 35429,
+ 35794,
+ 36160,
+ 36525,
+ 36890,
+ 37255,
+ 37621,
+ 37986,
+ 38351,
+ 38716,
+ 39082,
+ 39447,
+ 39812,
+ 40177,
+ 40543,
+ 40908,
+ 41273,
+ 41638,
+ 42004,
+ 42369,
+ 42734,
+ 43099,
+ 43465,
+ 43830,
+ 44195,
+ 44560,
+ 44926,
+ 45291,
+ 45656,
+ 46021,
+ 46387,
+ 46752,
+ 47117,
+ 47482,
+ 47847,
+ 48212,
+ 48577,
+ 48942,
+ 49308,
+ 49673,
+ 50038,
+ 50403,
+ 50769,
+ 51134,
+ 51499,
+ 51864,
+ 52230,
+ 52595,
+ 52960,
+ 53325,
+ 53691,
+ 54056,
+ 54421,
+ 54786,
+ 55152,
+ 55517,
+ 55882,
+ 56247,
+ 56613,
+ 56978,
+ 57343,
+ 57708,
+ 58074,
+ 58439,
+ 58804,
+ 59169,
+ 59535,
+ 59900,
+ 60265,
+ 60630,
+ 60996,
+ 61361,
+ 61726,
+ 62091,
+ 62457,
+ 62822,
+ 63187,
+ 63552,
+ 63918,
+ 64283,
+ 64648,
+ 65013,
+ 65379,
+ 65744,
+ 66109,
+ 66474,
+ 66840,
+ 67205,
+ 67570,
+ 67935,
+ 68301,
+ 68666,
+ 69031,
+ 69396,
+ 69762,
+ 70127,
+ 70492,
+ 70857,
+ 71223,
+ 71588,
+ 71953,
+ 72318,
+ 72684,
+ 73049,
+ 73414,
+ 73779,
+ 74145,
+ 74510,
+ 74875,
+ 75240,
+ 75606,
+ 75971,
+ 76336,
+ 76701,
+ 77067,
+ 77432,
+ 77797,
+ 78162,
+ 78528,
+ 78893,
+ 79258,
+ 79623,
+ 79989,
+ 80354,
+ 80719,
+ 81084,
+ 81450,
+ 81815,
+ 82180,
+ 82545,
+ 82911,
+ 83276,
+ 83641,
+ 84006,
+ 84371,
+ 84736,
+ 85101,
+ 85466,
+ 85832,
+ 86197,
+ 86562,
+ 86927,
+ 87293,
+ 87658,
+ 88023,
+ 88388,
+ 88754,
+ 89119,
+ 89484,
+ 89849,
+ 90215,
+ 90580,
+ 90945,
+ 91310,
+ 91676,
+ 92041,
+ 92406,
+ 92771,
+ 93137,
+ 93502,
+ 93867,
+ 94232,
+ 94598,
+ 94963,
+ 95328,
+ 95693,
+ 96059,
+ 96424,
+ 96789,
+ 97154,
+ 97520,
+ 97885,
+ 98250,
+ 98615,
+ 98981,
+ 99346,
+ 99711,
+ 100076,
+ 100442,
+ 100807,
+ 101172,
+ 101537,
+ 101903,
+ 102268,
+ 102633,
+ 102998,
+ 103364,
+ 103729,
+ 104094,
+ 104459,
+ 104825,
+ 105190,
+ 105555,
+ 105920,
+ 106286,
+ 106651,
+ 107016,
+ 107381,
+ 107747,
+ 108112,
+ 108477,
+ 108842,
+ 109208,
+ 109573,
+ 109938,
+ 110303,
+ 110669,
+ 111034,
+ 111399,
+ 111764,
+ 112130,
+ 112495,
+ 112860,
+ 113225,
+ 113591,
+ 113956,
+ 114321,
+ 114686,
+ 115052,
+ 115417,
+ 115782,
+ 116147,
+ 116513,
+ 116878,
+ 117243,
+ 117608,
+ 117974,
+ 118339,
+ 118704,
+ 119069,
+ 119435,
+ 119800,
+ 120165,
+ 120530,
+ 120895,
+ 121260,
+ 121625,
+ 121990,
+ 122356,
+ 122721,
+ 123086,
+ 123451,
+ 123817,
+ 124182,
+ 124547,
+ 124912,
+ 125278,
+ 125643,
+ 126008,
+ 126373,
+ 126739,
+ 127104,
+ 127469,
+ 127834,
+ 128200,
+ 128565,
+ 128930,
+ 129295,
+ 129661,
+ 130026,
+ 130391,
+ 130756,
+ 131122,
+ 131487,
+ 131852,
+ 132217,
+ 132583,
+ 132948,
+ 133313,
+ 133678,
+ 134044,
+ 134409,
+ 134774,
+ 135139,
+ 135505,
+ 135870,
+ 136235,
+ 136600,
+ 136966,
+ 137331,
+ 137696,
+ 138061,
+ 138427,
+ 138792,
+ 139157,
+ 139522,
+ 139888,
+ 140253,
+ 140618,
+ 140983,
+ 141349,
+ 141714,
+ 142079,
+ 142444,
+ 142810,
+ 143175,
+ 143540,
+ 143905,
+ 144271,
+ 144636,
+ 145001,
+ 145366,
+ 145732,
+};
+
+// ARM does not implement gmtime. This is a simple alternative implementation
+// based on section 4.16
+// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html
+zxerr_t printTime(char *out, uint16_t outLen, uint64_t t) {
+ uint8_t tm_sec;
+ uint8_t tm_min;
+ uint8_t tm_hour;
+ uint16_t tm_day;
+ uint8_t tm_mon;
+ uint16_t tm_year;
+
+ tm_sec = (uint8_t) (t % 60);
+ t -= tm_sec;
+ t /= 60;
+
+ tm_min = (uint8_t) (t % 60);
+ t -= tm_min;
+ t /= 60;
+
+ tm_hour = (uint8_t) (t % 24);
+ t -= tm_hour;
+ t /= 24;
+
+ // Look up tm_year
+ tm_year = 0;
+ const uint16_t yearLookupSize = sizeof(yearLookup)/sizeof(yearLookup[0]);
+ while (tm_year < yearLookupSize && yearLookup[tm_year] <= t) tm_year++;
+
+ if (tm_year == 0 || tm_year == yearLookupSize) {
+ return zxerr_out_of_bounds;
+ }
+ tm_year--;
+
+ tm_day = (uint16_t) (t - yearLookup[tm_year] + 1);
+ tm_year = (uint16_t) (1970 + tm_year);
+
+ // Get day/month
+ uint8_t leap = (uint8_t) (tm_year % 4 == 0 && (tm_year % 100 != 0 || tm_year % 400 == 0) ? 1 : 0);
+
+ for (tm_mon = 0; tm_mon < 12; tm_mon++) {
+ uint8_t tmp = monthDays[tm_mon];
+ tmp += (tm_mon == 1 ? leap : 0);
+ if (tm_day <= tmp) {
+ break;
+ }
+ tm_day -= tmp;
+ }
+ tm_mon++;
+
+ const char *monthName = getMonth(tm_mon);
+
+ // YYYYmmdd HH:MM:SS
+ snprintf(out, outLen, "%02d%s%04d %02d:%02d:%02dUTC",
+ tm_day,
+ monthName,
+ tm_year,
+ tm_hour, tm_min, tm_sec
+ );
+
+ return zxerr_ok;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/deps/ledger-zxlib/src/zbuffer.c b/deps/ledger-zxlib/src/zbuffer.c
new file mode 100644
index 0000000..cbc7f61
--- /dev/null
+++ b/deps/ledger-zxlib/src/zbuffer.c
@@ -0,0 +1,88 @@
+/*******************************************************************************
+* (c) 2020 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#include "zbuffer.h"
+#include "zxmacros.h"
+
+typedef struct {
+ uint8_t *ptr;
+ uint16_t size;
+} zbuffer_t;
+
+zbuffer_t zbuffer_internal;
+
+#define CANARY_EXPECTED 0x987def82u
+
+zbuffer_error_e zb_get(uint8_t **buffer) {
+#if defined (TARGET_NANOS) || defined(TARGET_NANOX)
+ *buffer = NULL;
+ if (zbuffer_internal.size == 0 || zbuffer_internal.ptr == NULL) {
+ return zb_not_allocated;
+ }
+ *buffer = zbuffer_internal.ptr;
+#endif
+ return zb_no_error;
+}
+
+zbuffer_error_e zb_init() {
+#if defined (TARGET_NANOS) || defined(TARGET_NANOX)
+ zbuffer_internal.size = 0;
+ zbuffer_internal.ptr = NULL;
+#endif
+ return zb_no_error;
+}
+
+zbuffer_error_e zb_allocate(uint16_t size) {
+#if defined (TARGET_NANOS) || defined(TARGET_NANOX)
+ if (size % 4 != 0) {
+ size += size % 4;
+ }
+ zbuffer_internal.size = size;
+ zbuffer_internal.ptr = (uint8_t * )(&app_stack_canary + 4);
+
+ uint32_t *zb_canary = (uint32_t * )(zbuffer_internal.ptr + zbuffer_internal.size + 4);
+ *zb_canary = CANARY_EXPECTED;
+#endif
+ return zb_no_error;
+}
+
+zbuffer_error_e zb_deallocate() {
+#if defined (TARGET_NANOS) || defined(TARGET_NANOX)
+ if (zbuffer_internal.size == 0) {
+ return zb_not_allocated;
+ }
+
+ // Flush any information
+ MEMZERO(zbuffer_internal.ptr, zbuffer_internal.size);
+
+ zb_init();
+#endif
+ return zb_no_error;
+}
+
+zbuffer_error_e zb_check_canary() {
+#if defined (TARGET_NANOS) || defined(TARGET_NANOX)
+ CHECK_APP_CANARY();
+ if (zbuffer_internal.size != 0) {
+ // allocated
+ uint32_t *zb_canary = (uint32_t * )(zbuffer_internal.ptr + zbuffer_internal.size + 4);
+ if (*zb_canary != CANARY_EXPECTED) {
+ handle_stack_overflow();
+ }
+ }
+#endif
+ return zb_no_error;
+}
diff --git a/deps/ledger-zxlib/src/zxformat.c b/deps/ledger-zxlib/src/zxformat.c
new file mode 100644
index 0000000..ec061f5
--- /dev/null
+++ b/deps/ledger-zxlib/src/zxformat.c
@@ -0,0 +1,88 @@
+/*******************************************************************************
+* (c) 2020 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#include "zxformat.h"
+
+uint8_t intstr_to_fpstr_inplace(char *number, size_t number_max_size, uint8_t decimalPlaces) {
+ uint16_t numChars = strnlen(number, number_max_size);
+ MEMZERO(number + numChars, number_max_size - numChars);
+
+ if (number_max_size < 1) {
+ // No space to do anything
+ return 0;
+ }
+
+ if (number_max_size <= numChars) {
+ // No space to do anything
+ return 0;
+ }
+
+ if (numChars == 0) {
+ // Empty number, make a zero
+ snprintf(number, number_max_size, "0");
+ numChars = 1;
+ }
+
+ // Check all are numbers
+ uint16_t firstDigit = numChars;
+ for (int i = 0; i < numChars; i++) {
+ if (number[i] < '0' || number[i] > '9') {
+ snprintf(number, number_max_size, "ERR");
+ return 0;
+ }
+ if (number[i] != '0' && firstDigit > i) {
+ firstDigit = i;
+ }
+ }
+
+ // Trim any incorrect leading zeros
+ if (firstDigit == numChars) {
+ snprintf(number, number_max_size, "0");
+ numChars = 1;
+ } else {
+ // Trim leading zeros
+ MEMCPY(number, number + firstDigit, numChars - firstDigit);
+ MEMZERO(number + numChars - firstDigit, firstDigit);
+ }
+
+ // If there are no decimal places return
+ if (decimalPlaces == 0) {
+ return numChars;
+ }
+
+ // Now insert decimal point
+
+// 0123456789012 <-decimal places
+// abcd < numChars = 4
+// abcd < shift
+// 000000000abcd < fill
+// 0.00000000abcd < add decimal point
+
+ if (numChars < decimalPlaces + 1) {
+ // Move to end
+ const uint16_t padSize = decimalPlaces - numChars + 1;
+ MEMMOVE(number + padSize, number, numChars);
+ MEMSET(number, '0', padSize);
+ numChars = strlen(number);
+ }
+
+ // add decimal point
+ const uint16_t pointPosition = numChars - decimalPlaces;
+ MEMMOVE(number + pointPosition + 1, number + pointPosition, decimalPlaces); // shift content
+ number[pointPosition] = '.';
+
+ numChars = strlen(number);
+ return numChars;
+}
diff --git a/deps/ledger-zxlib/src/zxmacros.c b/deps/ledger-zxlib/src/zxmacros.c
new file mode 100644
index 0000000..118da66
--- /dev/null
+++ b/deps/ledger-zxlib/src/zxmacros.c
@@ -0,0 +1,69 @@
+/*******************************************************************************
+* (c) 2018 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#include "zxmacros.h"
+#include "utf8.h"
+
+size_t asciify(char *utf8_in_ascii_out) {
+ return asciify_ext(utf8_in_ascii_out, utf8_in_ascii_out);
+}
+
+size_t asciify_ext(const char *utf8_in, char *ascii_only_out) {
+ void *p = (void *) utf8_in;
+ char *q = ascii_only_out;
+
+ // utf8valid returns zero on success
+ while (*((char *) p) && utf8valid(p) == 0) {
+ utf8_int32_t tmp_codepoint = 0;
+ p = utf8codepoint(p, &tmp_codepoint);
+ *q = (char) ((tmp_codepoint >= 32 && tmp_codepoint <= (int32_t) 0x7F) ? tmp_codepoint : '.');
+ q++;
+ }
+
+ // Terminate string
+ *q = 0;
+ return q - ascii_only_out;
+}
+
+void handle_stack_overflow() {
+ zemu_log("!!!!!!!!!!!!!!!!!!!!!! CANARY TRIGGERED!!! STACK OVERFLOW DETECTED\n");
+#if defined (TARGET_NANOS) || defined(TARGET_NANOX)
+ io_seproxyhal_se_reset();
+#else
+ while (1);
+#endif
+}
+
+void check_app_canary() {
+#if defined (TARGET_NANOS) || defined(TARGET_NANOX)
+ if (app_stack_canary != APP_STACK_CANARY_MAGIC) handle_stack_overflow();
+#endif
+}
+
+void zemu_log_stack(const char *ctx) {
+#if defined(ZEMU_LOGGING) && (defined (TARGET_NANOS) || defined(TARGET_NANOX))
+#define STACK_SHIFT 20
+ void* p = NULL;
+ char buf[70];
+ snprintf(buf, sizeof(buf), "|SP| %p %p (%d) : %s\n",
+ &app_stack_canary,
+ ((void*)&p)+STACK_SHIFT,
+ (uint32_t)((void*)&p)+STACK_SHIFT - (uint32_t)&app_stack_canary,
+ ctx);
+ zemu_log(buf);
+#else
+ (void)ctx;
+#endif
+}
diff --git a/deps/ledger-zxlib/templates/Makefile.root b/deps/ledger-zxlib/templates/Makefile.root
new file mode 100644
index 0000000..7c21132
--- /dev/null
+++ b/deps/ledger-zxlib/templates/Makefile.root
@@ -0,0 +1,29 @@
+#*******************************************************************************
+#* (c) 2019 Zondax GmbH
+#*
+#* Licensed under the Apache License, Version 2.0 (the "License");
+#* you may not use this file except in compliance with the License.
+#* You may obtain a copy of the License at
+#*
+#* http://www.apache.org/licenses/LICENSE-2.0
+#*
+#* Unless required by applicable law or agreed to in writing, software
+#* distributed under the License is distributed on an "AS IS" BASIS,
+#* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#* See the License for the specific language governing permissions and
+#* limitations under the License.
+#********************************************************************************
+
+# We use BOLOS_SDK to determine the develoment environment that is being used
+# BOLOS_SDK IS DEFINED We use the plain Makefile for Ledger
+# BOLOS_SDK NOT DEFINED We use a containerized build approach
+
+ifeq ($(BOLOS_SDK),)
+include $(CURDIR)/deps/ledger-zxlib/cmake/dockerized_build.mk
+else
+default:
+ $(MAKE) -C app
+%:
+ $(info "Calling app Makefile for target $@")
+ COIN=$(COIN) $(MAKE) -C app $@
+endif
diff --git a/deps/ledger-zxlib/tests/asciify.cpp b/deps/ledger-zxlib/tests/asciify.cpp
new file mode 100644
index 0000000..245f0f9
--- /dev/null
+++ b/deps/ledger-zxlib/tests/asciify.cpp
@@ -0,0 +1,118 @@
+/*******************************************************************************
+* (c) 2018 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#include
+#include
+
+namespace {
+ TEST(ASCIIFY, pure) {
+ char input[] = "This is only ascii";
+ char have[50];
+
+ asciify_ext(input, have);
+
+ EXPECT_STREQ(input, have);
+ }
+
+ TEST(ASCIIFY, ascii_below_32) {
+ char input[] = "\05test";
+ char want[] = ".test";
+ char have[50];
+
+ EXPECT_EQ(5, strlen(input));
+
+ size_t ascii_len = asciify_ext(input, have);
+ std::cout << have << std::endl;
+
+ EXPECT_EQ(strlen(want), ascii_len);
+ EXPECT_STREQ(want, have);
+ }
+
+ TEST(ASCIIFY, extended) {
+ char input[] = "cumpleaños";
+ char want[] = "cumplea.os";
+ char have[50];
+
+ EXPECT_EQ(11, strlen(input));
+
+ size_t ascii_len = asciify_ext(input, have);
+ std::cout << have << std::endl;
+
+ EXPECT_EQ(strlen(want), ascii_len);
+ EXPECT_STREQ(want, have);
+ }
+
+ TEST(ASCIIFY, utf8) {
+ char input[] = "哈Something哈";
+ char want[] = ".Something.";
+ char have[50];
+
+ EXPECT_EQ(15, strlen(input));
+
+ size_t ascii_len = asciify_ext(input, have);
+ std::cout << have << std::endl;
+
+ EXPECT_EQ(strlen(want), ascii_len);
+ EXPECT_STREQ(want, have);
+ }
+
+ TEST(ASCIIFY, inplace_pure) {
+ char data[] = "This is only ascii";
+ char want[] = "This is only ascii";
+
+ asciify(data);
+ EXPECT_STREQ(want, data);
+ }
+
+ TEST(ASCIIFY, inplace_ascii_below_32) {
+ char data[] = "\05test";
+ char want[] = ".test";
+
+ EXPECT_EQ(5, strlen(data));
+
+ size_t ascii_len = asciify(data);
+ std::cout << data << std::endl;
+
+ EXPECT_EQ(strlen(want), ascii_len);
+ EXPECT_STREQ(want, data);
+ }
+
+ TEST(ASCIIFY, inplace_extended) {
+ char data[] = "cumpleaños";
+ char want[] = "cumplea.os";
+
+ EXPECT_EQ(11, strlen(data));
+
+ size_t ascii_len = asciify(data);
+ std::cout << data << std::endl;
+
+ EXPECT_EQ(strlen(want), ascii_len);
+ EXPECT_STREQ(want, data);
+ }
+
+ TEST(ASCIIFY, inplace_utf8) {
+ char data[] = "哈Something哈";
+ char want[] = ".Something.";
+
+ EXPECT_EQ(15, strlen(data));
+
+ size_t ascii_len = asciify(data);
+ std::cout << data << std::endl;
+
+ EXPECT_EQ(strlen(want), ascii_len);
+ EXPECT_STREQ(want, data);
+ }
+
+}
diff --git a/deps/ledger-zxlib/tests/base64.cpp b/deps/ledger-zxlib/tests/base64.cpp
new file mode 100644
index 0000000..fe24854
--- /dev/null
+++ b/deps/ledger-zxlib/tests/base64.cpp
@@ -0,0 +1,57 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#include
+#include "base64.h"
+
+namespace {
+ TEST(BASE64, basic_case) {
+ char out[100];
+ uint8_t data[] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19};
+
+ base64_encode(out, sizeof(out), data, 0);
+ EXPECT_STREQ(out, "");
+
+ base64_encode(out, sizeof(out), data, 1);
+ EXPECT_STREQ(out, "AQ==");
+
+ base64_encode(out, sizeof(out), data, 2);
+ EXPECT_STREQ(out, "AQM=");
+
+ base64_encode(out, sizeof(out), data, 3);
+ EXPECT_STREQ(out, "AQMF");
+
+ base64_encode(out, sizeof(out), data, 4);
+ EXPECT_STREQ(out, "AQMFBw==");
+
+ base64_encode(out, sizeof(out), data, 5);
+ EXPECT_STREQ(out, "AQMFBwk=");
+
+ base64_encode(out, sizeof(out), data, 6);
+ EXPECT_STREQ(out, "AQMFBwkL");
+
+ base64_encode(out, sizeof(out), data, 7);
+ EXPECT_STREQ(out, "AQMFBwkLDQ==");
+
+ base64_encode(out, sizeof(out), data, 8);
+ EXPECT_STREQ(out, "AQMFBwkLDQ8=");
+
+ base64_encode(out, sizeof(out), data, 9);
+ EXPECT_STREQ(out, "AQMFBwkLDQ8R");
+
+ base64_encode(out, sizeof(out), data, 10);
+ EXPECT_STREQ(out, "AQMFBwkLDQ8REw==");
+ };
+}
diff --git a/deps/ledger-zxlib/tests/bech32.cpp b/deps/ledger-zxlib/tests/bech32.cpp
new file mode 100644
index 0000000..4e79141
--- /dev/null
+++ b/deps/ledger-zxlib/tests/bech32.cpp
@@ -0,0 +1,83 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#include
+#include
+#include
+#include
+
+namespace {
+ TEST(BECH32, hex_to_address) {
+ char addr_out[100];
+ const char *hrp = "zx";
+
+ uint8_t data1[] = {1, 3, 5};
+ uint8_t data2[] = {1, 3, 5, 7, 9, 11, 13};
+
+ auto err = bech32EncodeFromBytes(addr_out, sizeof(addr_out), hrp, data1, sizeof(data1), 0);
+ ASSERT_EQ(err, zxerr_ok);
+ std::cout << addr_out << std::endl;
+ ASSERT_STREQ("zx1qypse825ac", addr_out);
+
+ err = bech32EncodeFromBytes(addr_out, sizeof(addr_out), hrp, data2, sizeof(data2), 0);
+ ASSERT_EQ(err, zxerr_ok);
+ std::cout << addr_out << std::endl;
+ ASSERT_STREQ("zx1qyps2pcfpvx20dk22", addr_out);
+
+ ///
+ err = bech32EncodeFromBytes(addr_out, sizeof(addr_out), hrp, data1, sizeof(data1), 1);
+ ASSERT_EQ(err, zxerr_ok);
+ std::cout << addr_out << std::endl;
+ ASSERT_STREQ("zx1qyps2ucfnzd", addr_out);
+
+ err = bech32EncodeFromBytes(addr_out, sizeof(addr_out), hrp, data2, sizeof(data2), 1);
+ ASSERT_EQ(err, zxerr_ok);
+ std::cout << addr_out << std::endl;
+ ASSERT_STREQ("zx1qyps2pcfpvxshamanz", addr_out);
+ }
+
+ TEST(BECH32, huge_input) {
+ char addr_out[200];
+ const char *hrp = "zx";
+
+ auto data = std::vector(1000, 0x55);
+
+ auto err = bech32EncodeFromBytes(addr_out, sizeof(addr_out), hrp, data.data(), data.size(),0);
+ ASSERT_EQ(err, zxerr_out_of_bounds);
+
+ std::cout << addr_out << std::endl;
+ }
+
+ TEST(BECH32, small_output) {
+ char addr_out[1000];
+ const char *hrp = "zx";
+
+ auto data = std::vector(32, 0x55);
+
+ MEMZERO(addr_out, sizeof(addr_out));
+
+ // declare size to be smaller
+ const size_t declared_size = 52;
+
+ auto err = bech32EncodeFromBytes(addr_out, declared_size, hrp, data.data(), data.size(), 0);
+ ASSERT_EQ(err, zxerr_buffer_too_small);
+
+ for (int i = declared_size; i < sizeof(addr_out); i++) {
+ ASSERT_EQ(addr_out[i], 0);
+ }
+
+ std::cout << addr_out << std::endl;
+ }
+}
diff --git a/deps/ledger-zxlib/tests/bip44path.cpp b/deps/ledger-zxlib/tests/bip44path.cpp
new file mode 100644
index 0000000..c4cb7a4
--- /dev/null
+++ b/deps/ledger-zxlib/tests/bip44path.cpp
@@ -0,0 +1,88 @@
+/*******************************************************************************
+* (c) 2018 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#include
+#include
+
+namespace {
+ TEST(MACROS, bip32empty) {
+ char buffer[100];
+ uint32_t path[] = {44, 60, 0, 0, 1};
+ bip32_to_str(buffer, sizeof(buffer), path, 0);
+ EXPECT_EQ("EMPTY PATH", std::string(buffer));
+ }
+
+ TEST(MACROS, bip32tooManyChildren) {
+ char buffer[100];
+ uint32_t path[] = {44, 60, 0, 0, 1};
+ bip32_to_str(buffer, sizeof(buffer), path, 200);
+ EXPECT_EQ("ERROR", std::string(buffer));
+ }
+
+ TEST(MACROS, bip32notEnoughSpaceInBuffer1) {
+ char buffer[6];
+ uint32_t path[] = {1234, 60, 0, 0, 1};
+ bip32_to_str(buffer, sizeof(buffer), path, 5);
+ EXPECT_EQ("ERROR", std::string(buffer));
+ }
+
+ TEST(MACROS, bip32notEnoughSpaceInBuffer2) {
+ char buffer[9];
+ uint32_t path[] = {1, 1, 1, 1, 1};
+ bip32_to_str(buffer, sizeof(buffer), path, 5);
+ EXPECT_EQ("ERROR", std::string(buffer));
+ }
+
+ TEST(MACROS, bip32notEnoughSpaceInBuffer3) {
+ char buffer[10];
+ uint32_t path[] = {1, 1, 1, 1, 0x80000001 };
+ bip32_to_str(buffer, sizeof(buffer), path, 5);
+ EXPECT_EQ("ERROR", std::string(buffer));
+ }
+
+ TEST(MACROS, bip32justEnoughSpaceInBuffer3) {
+ char buffer[10];
+ uint32_t path[] = {1, 1, 1, 1, 1};
+ bip32_to_str(buffer, sizeof(buffer), path, 5);
+ EXPECT_EQ("1/1/1/1/1", std::string(buffer));
+ }
+
+ TEST(MACROS, bip44path1) {
+ uint32_t path[] = {44, 60, 0, 0, 1};
+
+ char buffer[100];
+ bip44_to_str(buffer, sizeof(buffer), path);
+
+ EXPECT_EQ("44/60/0/0/1", std::string(buffer));
+ }
+
+ TEST(MACROS, bip44path2) {
+ uint32_t path[] = {0x8000002c, 60, 0, 0, 1};
+
+ char buffer[100];
+ bip44_to_str(buffer, sizeof(buffer), path);
+
+ EXPECT_EQ("44'/60/0/0/1", std::string(buffer));
+ }
+
+ TEST(MACROS, bip44path3) {
+ uint32_t path[] = {0x8000002c, 60, 0, 0, 0x80000001};
+
+ char buffer[100];
+ bip44_to_str(buffer, sizeof(buffer), path);
+
+ EXPECT_EQ("44'/60/0/0/1'", std::string(buffer));
+ }
+}
diff --git a/deps/ledger-zxlib/tests/buffering_tests.cpp b/deps/ledger-zxlib/tests/buffering_tests.cpp
new file mode 100644
index 0000000..c7292d1
--- /dev/null
+++ b/deps/ledger-zxlib/tests/buffering_tests.cpp
@@ -0,0 +1,229 @@
+/*******************************************************************************
+* (c) 2018 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#include "gtest/gtest.h"
+#include "buffering.h"
+
+namespace {
+
+ TEST(Buffering, SmallBuffer) {
+ uint8_t ram_buffer[100];
+ uint8_t flash_buffer[1000];
+
+ buffering_init(ram_buffer,
+ sizeof(ram_buffer),
+ flash_buffer,
+ sizeof(flash_buffer));
+
+ // Data is small enough to fit into ram buffer
+ uint8_t small[50];
+ auto num_bytes = buffering_append(small, sizeof(small));
+ EXPECT_EQ(sizeof(small), num_bytes) << "Append should not return error";
+
+ EXPECT_TRUE(buffering_get_ram_buffer()->in_use) << "Writing small buffer should only write to RAM";
+ EXPECT_FALSE(buffering_get_flash_buffer()->in_use) << "Writing big buffer should write data to FLASH";
+ EXPECT_EQ(50, buffering_get_ram_buffer()->pos) << "Wrong position of the written data in the ram buffer";
+ EXPECT_EQ(100, buffering_get_ram_buffer()->size) << "Wrong size of the ram buffer";
+ EXPECT_EQ(0, buffering_get_flash_buffer()->pos) << "Wrong position of the written data in the flash buffer";
+ EXPECT_EQ(1000, buffering_get_flash_buffer()->size) << "Wrong size of the flash buffer";
+ }
+
+ TEST(Buffering, BigBuffer) {
+ uint8_t ram_buffer[100];
+ uint8_t flash_buffer[1000];
+
+ buffering_init(ram_buffer,
+ sizeof(ram_buffer),
+ flash_buffer,
+ sizeof(flash_buffer));
+
+ // Data is too big to fit into ram buffer, it will be written directly to flash
+ uint8_t big[500];
+ auto num_bytes = buffering_append(big, sizeof(big));
+ EXPECT_EQ(sizeof(big), num_bytes) << "Append should not return error";
+
+ EXPECT_FALSE(buffering_get_ram_buffer()->in_use) << "Writing big buffer should write data to FLASH";
+ EXPECT_TRUE(buffering_get_flash_buffer()->in_use) << "Writing big buffer should write data to FLASH";
+ EXPECT_EQ(0, buffering_get_ram_buffer()->pos) << "Wrong position of the written data in the ram buffer";
+ EXPECT_EQ(100, buffering_get_ram_buffer()->size) << "Wrong size of the ram buffer";
+ EXPECT_EQ(500, buffering_get_flash_buffer()->pos) << "Wrong position of the written data in the flash buffer";
+ EXPECT_EQ(1000, buffering_get_flash_buffer()->size) << "Wrong size of the flash buffer";
+ }
+
+ TEST(Buffering, SmallBufferMultipleTimesWithinRam) {
+ uint8_t ram_buffer[100];
+ uint8_t flash_buffer[1000];
+
+ buffering_init(ram_buffer,
+ sizeof(ram_buffer),
+ flash_buffer,
+ sizeof(flash_buffer));
+
+ uint8_t small[40];
+ auto num_bytes = buffering_append(small, sizeof(small));
+ EXPECT_EQ(sizeof(small), num_bytes) << "Append should not return error";
+ EXPECT_TRUE(buffering_get_ram_buffer()->in_use) << "Writing small buffer should only write to RAM";
+ EXPECT_FALSE(buffering_get_flash_buffer()->in_use) << "Writing big buffer should write data to FLASH";
+
+ // Here we write another chunk which should not top over the ram buffer
+ buffering_append(small, sizeof(small));
+ EXPECT_TRUE(buffering_get_ram_buffer()->in_use) << "Writing small buffer should only write to RAM";
+ EXPECT_FALSE(buffering_get_flash_buffer()->in_use) << "Writing big buffer should write data to FLASH";
+
+ EXPECT_EQ(sizeof(small) * 2, buffering_get_ram_buffer()->pos) << "Data should be written to RAM";
+ EXPECT_EQ(100, buffering_get_ram_buffer()->size) << "Wrong size of the ram buffer";
+ EXPECT_EQ(0, buffering_get_flash_buffer()->pos) << "Data should be written to RAM";
+ EXPECT_EQ(1000, buffering_get_flash_buffer()->size) << "Wrong size of the flash buffer";
+ }
+
+ TEST(Buffering, SmallBufferMultipleTimesToFlash) {
+ uint8_t ram_buffer[100];
+ uint8_t flash_buffer[1000];
+
+ buffering_init(ram_buffer,
+ sizeof(ram_buffer),
+ flash_buffer,
+ sizeof(flash_buffer));
+
+ uint8_t small[100];
+ buffering_append(small, sizeof(small));
+ EXPECT_TRUE(buffering_get_ram_buffer()->in_use) << "Writing small buffer should only write to RAM";
+ EXPECT_FALSE(buffering_get_flash_buffer()->in_use) << "Writing big buffer should write data to FLASH";
+
+ // Here we append another small buffer, this time we're going to exceed ram's size
+ // data will be copied to nvram
+ buffering_append(small, sizeof(small));
+ EXPECT_FALSE(buffering_get_ram_buffer()->in_use) << "Data should be now in FLASH";
+ EXPECT_TRUE(buffering_get_flash_buffer()->in_use) << "Data should be now in FLASH";
+
+ EXPECT_EQ(0, buffering_get_ram_buffer()->pos) << "RAM buffer should be reset";
+ EXPECT_EQ(100, buffering_get_ram_buffer()->size) << "Wrong size of the ram buffer";
+ EXPECT_EQ(200, buffering_get_flash_buffer()->pos) << "Wrong position of the written data in the flash buffer";
+ EXPECT_EQ(1000, buffering_get_flash_buffer()->size) << "Wrong size of the flash buffer";
+ }
+
+ TEST(Buffering, SmallBufferMultipleTimes_CheckData) {
+ uint8_t ram_buffer[100];
+ uint8_t flash_buffer[1000];
+
+ buffering_init(ram_buffer,
+ sizeof(ram_buffer),
+ flash_buffer,
+ sizeof(flash_buffer));
+
+ uint8_t small1[100];
+ for (int i = 0; i < sizeof(small1); i++) {
+ small1[i] = i;
+ }
+ buffering_append(small1, sizeof(small1));
+
+ uint8_t small2[200];
+ for (int i = 0; i < sizeof(small2); i++) {
+ small2[i] = 100 - i;
+ }
+ auto num_bytes = buffering_append(small2, sizeof(small2));
+ EXPECT_EQ(sizeof(small2), num_bytes) << "Append should not return error";
+
+ // In this test we want to make sure that data is not compromised.
+ uint8_t *dst = buffering_get_flash_buffer()->data;
+ for (int i = 0; i < sizeof(small1) + sizeof(small2); i++) {
+ if (i < sizeof(small1)) {
+ EXPECT_EQ(dst[i], small1[i]) << "Wrong data written to FLASH";
+ } else {
+ EXPECT_EQ(dst[i], small2[i - sizeof(small1)]) << "Wrong data written to FLASH";
+ }
+ }
+ }
+
+ TEST(Buffering, Reset) {
+ uint8_t ram_buffer[100];
+ uint8_t flash_buffer[1000];
+
+ buffering_init(ram_buffer,
+ sizeof(ram_buffer),
+ flash_buffer,
+ sizeof(flash_buffer));
+
+ uint8_t big[1000];
+ auto num_bytes = buffering_append(big, sizeof(big));
+ EXPECT_EQ(sizeof(big), num_bytes) << "Append should not return error";
+
+ EXPECT_FALSE(buffering_get_ram_buffer()->in_use) << "Writing big buffer should only write to FLASH";
+ EXPECT_TRUE(buffering_get_flash_buffer()->in_use) << "Writing big buffer should only write to FLASH";
+
+ buffering_reset();
+
+ EXPECT_TRUE(buffering_get_ram_buffer()->in_use) << "After reset RAM should be enabled by default";
+ EXPECT_FALSE(buffering_get_flash_buffer()->in_use) << "After reset RAM should be enabled by default";
+ }
+
+ TEST(Buffering, NotEnoughRoomInFlash) {
+ uint8_t ram_buffer[100];
+ uint8_t flash_buffer[1000];
+
+ buffering_init(ram_buffer,
+ sizeof(ram_buffer),
+ flash_buffer,
+ sizeof(flash_buffer));
+
+ uint8_t big[1101];
+ auto num_bytes = buffering_append(big, sizeof(big));
+ EXPECT_EQ(0, num_bytes) << "Appending outside the bounds of the buffer should return error";
+ }
+
+ TEST(Buffering, NoFlashOnlyRAM) {
+ uint8_t ram_buffer[100];
+
+ buffering_init(ram_buffer,
+ sizeof(ram_buffer),
+ nullptr, 0);
+
+ uint8_t small[10];
+ auto num_bytes = buffering_append(small, sizeof(small));
+ EXPECT_EQ(10, num_bytes) << "Could not add to RAM";
+
+ num_bytes = buffering_append(small, sizeof(small));
+ EXPECT_EQ(10, num_bytes) << "Could not add to RAM";
+
+ num_bytes = buffering_append(small, sizeof(small));
+ EXPECT_EQ(10, num_bytes) << "Could not add to RAM";
+
+ auto state = buffering_get_buffer();
+ EXPECT_EQ(30, state->pos) << "Invalid buffer size";
+
+ uint8_t small2[70];
+ num_bytes = buffering_append(small2, sizeof(small2));
+ EXPECT_EQ(70, num_bytes);
+
+ state = buffering_get_buffer();
+ EXPECT_EQ(100, state->pos) << "Invalid buffer size";
+
+ num_bytes = buffering_append(small, sizeof(small));
+ EXPECT_EQ(0, num_bytes) << "Could add to RAM when it should have been impossible";
+ }
+
+ TEST(Buffering, NoFlash) {
+ uint8_t ram_buffer[100];
+
+ buffering_init(ram_buffer,
+ sizeof(ram_buffer),
+ nullptr, 0);
+
+ uint8_t big[1101];
+ auto num_bytes = buffering_append(big, sizeof(big));
+ EXPECT_EQ(0, num_bytes) << "Appending outside the bounds of the buffer should return error";
+ }
+}
diff --git a/deps/ledger-zxlib/tests/doubledabble.cpp b/deps/ledger-zxlib/tests/doubledabble.cpp
new file mode 100644
index 0000000..c0c3108
--- /dev/null
+++ b/deps/ledger-zxlib/tests/doubledabble.cpp
@@ -0,0 +1,164 @@
+/*******************************************************************************
+* (c) 2019 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#include "gmock/gmock.h"
+
+#include
+#include "bignum.h"
+
+using ::testing::TestWithParam;
+using ::testing::Values;
+
+typedef struct {
+ std::string hex;
+ std::string expectedOutput;
+} bignum_testcase_t;
+
+class BignumLittleEndianTests : public ::testing::TestWithParam {
+};
+
+class BignumBigEndianTests : public ::testing::TestWithParam {
+};
+
+INSTANTIATE_TEST_CASE_P
+
+(
+ BignumTestCases, BignumLittleEndianTests, testing::Values(
+ bignum_testcase_t{"00", "0"},
+ bignum_testcase_t{"01", "1"},
+ bignum_testcase_t{"0001", "256"},
+ bignum_testcase_t{"03E8", "59395"},
+ bignum_testcase_t{"E803", "1000"},
+ bignum_testcase_t{"10", "16"},
+ bignum_testcase_t{"FF01", "511"},
+ bignum_testcase_t{"0102", "513"},
+ bignum_testcase_t{"FFFF01", "131071"},
+ bignum_testcase_t{"a08601", "100000"},
+ bignum_testcase_t{"40420f", "1000000"},
+ bignum_testcase_t{"809698", "10000000"},
+ bignum_testcase_t{"002d3101", "20000000"},
+ bignum_testcase_t{"00e1f505", "100000000"},
+ bignum_testcase_t{"00407a10f35a", "100000000000000"},
+ bignum_testcase_t{"d2029649", "1234567890"},
+ bignum_testcase_t{"d20a3fce96f1cf8c9cb4378c37a4873f17621ebce404f5aa13",
+ "123456789012345678901234567890123456789012345678901234567890"}
+));
+
+// Check that bignums are printed properly (parametric tests)
+TEST_P(BignumLittleEndianTests, print) {
+ auto testcase = GetParam();
+
+ uint8_t inBuffer[100];
+ auto inBufferLen = parseHexString(inBuffer, sizeof(inBuffer), testcase.hex.c_str());
+
+ uint8_t bcdOut[100];
+ uint16_t bcdOutLen = sizeof(bcdOut);
+
+ bignumLittleEndian_to_bcd(bcdOut, bcdOutLen, inBuffer, static_cast(inBufferLen));
+
+ char bufferUI[300];
+ bignumLittleEndian_bcdprint(bufferUI, sizeof(bufferUI), bcdOut, bcdOutLen);
+ EXPECT_THAT(std::string(bufferUI), testing::Eq(testcase.expectedOutput));
+}
+
+// Check that bignums are printed properly (range tests)
+TEST(BignumLittleEndianTests, range) {
+ uint8_t inBuffer[100];
+
+ for (uint64_t i = 0; i < 10000; i++) {
+ std::stringstream s;
+ uint64_t tmp = i;
+ while (tmp != 0) {
+ s << std::setfill('0') << std::setw(2) << std::hex << tmp % 256;
+ tmp /= 256;
+ }
+ auto inBufferLen = parseHexString(inBuffer, sizeof(inBuffer), s.str().c_str());
+
+ uint8_t bcdOut[100];
+ uint16_t bcdOutLen = sizeof(bcdOut);
+ bignumLittleEndian_to_bcd(bcdOut, bcdOutLen, inBuffer, static_cast(inBufferLen));
+ char bufferUI[300];
+ bignumLittleEndian_bcdprint(bufferUI, sizeof(bufferUI), bcdOut, bcdOutLen);
+
+ std::stringstream expected;
+ expected << i;
+ EXPECT_THAT(std::string(bufferUI), testing::Eq(expected.str())) << s.str();
+ }
+}
+
+INSTANTIATE_TEST_CASE_P
+
+(
+ BignumTestCases, BignumBigEndianTests, testing::Values(
+ bignum_testcase_t{"00", "0"},
+ bignum_testcase_t{"01", "1"},
+ bignum_testcase_t{"0001", "1"},
+ bignum_testcase_t{"000001", "1"},
+ bignum_testcase_t{"03E8", "1000"},
+ bignum_testcase_t{"E803", "59395"},
+ bignum_testcase_t{"10", "16"},
+ bignum_testcase_t{"FF01", "65281"},
+ bignum_testcase_t{"01FF", "511"},
+ bignum_testcase_t{"0102", "258"},
+ bignum_testcase_t{"FFFF01", "16776961"},
+ bignum_testcase_t{"a08601", "10520065"},
+ bignum_testcase_t{"40420f", "4211215"},
+ bignum_testcase_t{"809698", "8427160"},
+ bignum_testcase_t{"002d3101", "2961665"},
+ bignum_testcase_t{"00e1f505", "14808325"},
+ bignum_testcase_t{"00407a10f35a", "276925838170"},
+ bignum_testcase_t{"d2029649", "3523384905"},
+ bignum_testcase_t{"d20a3fce96f1cf8c9cb4378c37a4873f17621ebce404f5aa13",
+ "1318442675213289749221432902819395197389189473307425559128595"}
+));
+
+// Check that bignums are printed properly (parametric tests)
+TEST_P(BignumBigEndianTests, print) {
+ auto testcase = GetParam();
+
+ uint8_t inBuffer[100];
+ auto inBufferLen = parseHexString(inBuffer, sizeof(inBuffer), testcase.hex.c_str());
+
+ uint8_t bcdOut[100];
+ uint16_t bcdOutLen = sizeof(bcdOut);
+ bignumBigEndian_to_bcd(bcdOut, bcdOutLen, inBuffer, static_cast(inBufferLen));
+
+ char bufferUI[300];
+ bignumBigEndian_bcdprint(bufferUI, sizeof(bufferUI), bcdOut, bcdOutLen);
+ EXPECT_THAT(std::string(bufferUI), testing::Eq(testcase.expectedOutput));
+}
+
+// Check that bignums are printed properly (range tests)
+TEST(BignumBigEndianTests, range) {
+ uint8_t inBuffer[100];
+
+ for (uint64_t i = 0; i < 2500; i += 7) {
+ std::stringstream s;
+ s << std::setfill('0') << std::setw(10) << std::hex << i;
+ std::cout << s.str() << std::endl;
+ auto inBufferLen = parseHexString(inBuffer, sizeof(inBuffer), s.str().c_str());
+
+ uint8_t bcdOut[100];
+ uint16_t bcdOutLen = sizeof(bcdOut);
+ bignumBigEndian_to_bcd(bcdOut, bcdOutLen, inBuffer, static_cast(inBufferLen));
+ char bufferUI[300];
+ bignumBigEndian_bcdprint(bufferUI, sizeof(bufferUI), bcdOut, bcdOutLen);
+
+ std::stringstream expected;
+ expected << i;
+ EXPECT_THAT(std::string(bufferUI), testing::Eq(expected.str())) << s.str();
+ }
+}
diff --git a/deps/ledger-zxlib/tests/hexutils.cpp b/deps/ledger-zxlib/tests/hexutils.cpp
new file mode 100644
index 0000000..e9d3ae4
--- /dev/null
+++ b/deps/ledger-zxlib/tests/hexutils.cpp
@@ -0,0 +1,51 @@
+/*******************************************************************************
+* (c) 2018 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#include "gmock/gmock.h"
+
+#include
+
+#include "hexutils.h"
+
+TEST(HEXUTILS, parseHexString) {
+ char s[] = "1234567890";
+ uint8_t data[100];
+
+ auto length = parseHexString(data, sizeof(data), s);
+
+ ASSERT_THAT(length, testing::Eq(5));
+
+ ASSERT_THAT(data[0], testing::Eq(0x12));
+ ASSERT_THAT(data[1], testing::Eq(0x34));
+ ASSERT_THAT(data[2], testing::Eq(0x56));
+ ASSERT_THAT(data[3], testing::Eq(0x78));
+ ASSERT_THAT(data[4], testing::Eq(0x90));
+}
+
+TEST(HEXUTILS, parseHexString2) {
+ char s[] = "be333be7ee";
+ uint8_t data[100];
+
+ auto length = parseHexString(data, sizeof(data), s);
+
+ ASSERT_THAT(length, testing::Eq(5));
+
+ ASSERT_THAT(data[0], testing::Eq(0xbe));
+ ASSERT_THAT(data[1], testing::Eq(0x33));
+ ASSERT_THAT(data[2], testing::Eq(0x3b));
+ ASSERT_THAT(data[3], testing::Eq(0xe7));
+ ASSERT_THAT(data[4], testing::Eq(0xee));
+}
diff --git a/deps/ledger-zxlib/tests/macros.cpp b/deps/ledger-zxlib/tests/macros.cpp
new file mode 100644
index 0000000..b6b11ff
--- /dev/null
+++ b/deps/ledger-zxlib/tests/macros.cpp
@@ -0,0 +1,495 @@
+/*******************************************************************************
+* (c) 2018 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#include
+#include
+
+namespace {
+ TEST(FORMAT, array_to_hexstr) {
+ uint8_t array1[] = {1, 3, 5};
+
+ char output[20];
+ memset(output, 1, 20);
+
+ array_to_hexstr(output, sizeof(output), array1, sizeof(array1));
+ EXPECT_EQ(memcmp(output, "010305", 2 * sizeof(array1)), 0);
+ EXPECT_EQ(output[2 * sizeof(array1)], 0);
+ }
+
+ TEST(FORMAT, fpuint64_to_str) {
+ char output[100];
+ printf("\n");
+
+ fpuint64_to_str(output, sizeof(output), 123, 5);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "0.00123");
+
+ fpuint64_to_str(output, sizeof(output), 1234, 5);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "0.01234");
+
+ fpuint64_to_str(output, sizeof(output), 12345, 5);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "0.12345");
+
+ fpuint64_to_str(output, sizeof(output), 123456, 5);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "1.23456");
+
+ fpuint64_to_str(output, sizeof(output), 1234567, 5);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "12.34567");
+ }
+
+ TEST(FORMAT, fpstr_to_str) {
+ char output[100];
+ printf("\n");
+
+ fpstr_to_str(output, sizeof(output), "", 0);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "0");
+
+ fpstr_to_str(output, sizeof(output), "1", 0);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "1");
+
+ fpstr_to_str(output, sizeof(output), "123", 0);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "123");
+
+ fpstr_to_str(output, sizeof(output), "", 5);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "0.00000");
+
+ fpstr_to_str(output, sizeof(output), "0", 5);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "0.00000");
+
+ fpstr_to_str(output, sizeof(output), "123", 5);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "0.00123");
+
+ fpstr_to_str(output, sizeof(output), "1234", 5);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "0.01234");
+
+ fpstr_to_str(output, sizeof(output), "12345", 5);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "0.12345");
+
+ fpstr_to_str(output, sizeof(output), "123456", 5);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "1.23456");
+
+ fpstr_to_str(output, sizeof(output), "1234567", 5);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "12.34567");
+ }
+
+ TEST(FORMAT, fpstr_to_str_BAD_zeros) {
+ char output[8];
+ printf("\n");
+
+ fpstr_to_str(output, sizeof(output), "", 5);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "0.00000");
+
+ fpstr_to_str(output, sizeof(output), "", 6);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "0.000000");
+
+ fpstr_to_str(output, sizeof(output), "", 7);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "ERR");
+
+ fpstr_to_str(output, sizeof(output), "", 8);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "ERR");
+ }
+
+ TEST(FORMAT, fpstr_to_str_BAD_short) {
+ char output[8];
+ printf("\n");
+
+ fpstr_to_str(output, sizeof(output), "123", 5);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "0.00123");
+
+ fpstr_to_str(output, sizeof(output), "123", 6);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "0.000123");
+
+ fpstr_to_str(output, sizeof(output), "123", 7);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "ERR");
+
+ fpstr_to_str(output, sizeof(output), "123", 8);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "ERR");
+ }
+
+ TEST(FORMAT, fpstr_to_str_BAD_long) {
+ char output[8];
+ printf("\n");
+
+ fpstr_to_str(output, sizeof(output), "123456", 5);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "1.23456");
+
+ fpstr_to_str(output, sizeof(output), "123456", 6);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "0.123456");
+
+ fpstr_to_str(output, sizeof(output), "123456", 7);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "ERR");
+
+ fpstr_to_str(output, sizeof(output), "12345", 7);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "ERR");
+
+ fpstr_to_str(output, sizeof(output), "12345", 2);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "123.45");
+
+ fpstr_to_str(output, sizeof(output), "123456", 2);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "1234.56");
+
+ fpstr_to_str(output, sizeof(output), "1234567", 2);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "12345.67");
+
+ fpstr_to_str(output, sizeof(output), "12345678", 2);
+ printf("%10s\n", output);
+ EXPECT_EQ(std::string(output), "ERR");
+ }
+
+ TEST(FORMAT, fpuint64_to_str_zeros) {
+ char output[100];
+ printf("\n");
+
+ fpuint64_to_str(output, sizeof(output), 0, 9);
+ printf("%11s\n", output);
+ EXPECT_EQ(std::string(output), "0.000000000");
+
+ fpuint64_to_str(output, sizeof(output), 0, 1);
+ printf("%11s\n", output);
+ EXPECT_EQ(std::string(output), "0.0");
+
+ fpuint64_to_str(output, sizeof(output), 1, 1);
+ printf("%11s\n", output);
+ EXPECT_EQ(std::string(output), "0.1");
+
+ fpuint64_to_str(output, sizeof(output), 10, 1);
+ printf("%11s\n", output);
+ EXPECT_EQ(std::string(output), "1.0");
+ }
+
+ TEST(FORMAT, number_trimming) {
+ char output[100];
+
+ strcpy(output, "0");
+ number_inplace_trimming(output);
+ EXPECT_EQ(std::string(output), "0");
+
+ strcpy(output, "10");
+ number_inplace_trimming(output);
+ EXPECT_EQ(std::string(output), "10");
+
+ strcpy(output, "10.10");
+ number_inplace_trimming(output);
+ EXPECT_EQ(std::string(output), "10.1");
+
+ strcpy(output, "0.0");
+ number_inplace_trimming(output);
+ EXPECT_EQ(std::string(output), "0.0");
+
+ strcpy(output, "0.00");
+ number_inplace_trimming(output);
+ EXPECT_EQ(std::string(output), "0.0");
+
+ strcpy(output, "0.01");
+ number_inplace_trimming(output);
+ EXPECT_EQ(std::string(output), "0.01");
+
+ strcpy(output, "0.010");
+ number_inplace_trimming(output);
+ EXPECT_EQ(std::string(output), "0.01");
+
+ strcpy(output, "0.010000");
+ number_inplace_trimming(output);
+ EXPECT_EQ(std::string(output), "0.01");
+ }
+
+ TEST(FORMAT, intstr_to_fpstr_inplace_trimming_leading) {
+ char number[100];
+ printf("\n");
+
+ strcpy(number, "0");
+ intstr_to_fpstr_inplace(number, sizeof(number), 0);
+ EXPECT_EQ(std::string(number), "0");
+
+ strcpy(number, "00");
+ intstr_to_fpstr_inplace(number, sizeof(number), 0);
+ EXPECT_EQ(std::string(number), "0");
+
+ strcpy(number, "0000");
+ intstr_to_fpstr_inplace(number, sizeof(number), 0);
+ EXPECT_EQ(std::string(number), "0");
+
+ strcpy(number, "00001");
+ intstr_to_fpstr_inplace(number, sizeof(number), 0);
+ EXPECT_EQ(std::string(number), "1");
+
+ strcpy(number, "000011");
+ intstr_to_fpstr_inplace(number, sizeof(number), 0);
+ EXPECT_EQ(std::string(number), "11");
+
+ strcpy(number, "10000");
+ intstr_to_fpstr_inplace(number, sizeof(number), 0);
+ EXPECT_EQ(std::string(number), "10000");
+ }
+
+ TEST(FORMAT, intstr_to_fpstr_inplace_empty) {
+ char number[100];
+ printf("\n");
+
+ strcpy(number, "");
+ intstr_to_fpstr_inplace(number, sizeof(number), 0);
+ EXPECT_EQ(std::string(number), "0");
+
+ strcpy(number, "");
+ intstr_to_fpstr_inplace(number, sizeof(number), 5);
+ EXPECT_EQ(std::string(number), "0.00000");
+
+ strcpy(number, "");
+ intstr_to_fpstr_inplace(number, sizeof(number), 10);
+ EXPECT_EQ(std::string(number), "0.0000000000");
+ }
+
+ TEST(FORMAT, intstr_to_fpstr_inplace) {
+ char number[100];
+ printf("\n");
+
+ strcpy(number, "1");
+ intstr_to_fpstr_inplace(number, sizeof(number), 0);
+ EXPECT_EQ(std::string(number), "1");
+
+ strcpy(number, "123");
+ intstr_to_fpstr_inplace(number, sizeof(number), 0);
+ EXPECT_EQ(std::string(number), "123");
+
+ strcpy(number, "0");
+ intstr_to_fpstr_inplace(number, sizeof(number), 5);
+ EXPECT_EQ(std::string(number), "0.00000");
+
+ strcpy(number, "123");
+ intstr_to_fpstr_inplace(number, sizeof(number), 5);
+ EXPECT_EQ(std::string(number), "0.00123");
+
+ strcpy(number, "1234");
+ intstr_to_fpstr_inplace(number, sizeof(number), 5);
+ EXPECT_EQ(std::string(number), "0.01234");
+
+ strcpy(number, "12345");
+ intstr_to_fpstr_inplace(number, sizeof(number), 5);
+ EXPECT_EQ(std::string(number), "0.12345");
+
+ strcpy(number, "123456");
+ intstr_to_fpstr_inplace(number, sizeof(number), 5);
+ EXPECT_EQ(std::string(number), "1.23456");
+
+ strcpy(number, "1234567");
+ intstr_to_fpstr_inplace(number, sizeof(number), 5);
+ EXPECT_EQ(std::string(number), "12.34567");
+ }
+
+ TEST(INT64_TO_STR, Zero) {
+ char temp[10];
+ const char *error = int64_to_str(temp, sizeof(temp), int64_t(0));
+ EXPECT_STREQ(temp, "0");
+ EXPECT_TRUE(error == nullptr);
+ }
+
+ TEST(INT64_TO_STR, Positive_1234) {
+ char temp[10];
+ const char *error = int64_to_str(temp, sizeof(temp), int64_t(1234));
+ EXPECT_STREQ(temp, "1234");
+ EXPECT_TRUE(error == nullptr);
+ }
+
+ TEST(INT64_TO_STR, Negative_1234) {
+ char temp[10];
+ const char *error = int64_to_str(temp, sizeof(temp), int64_t(-1234));
+ EXPECT_STREQ(temp, "-1234");
+ EXPECT_TRUE(error == nullptr);
+ }
+
+ TEST(INT64_TO_STR, TooSmall_0) {
+ char temp[1];
+ const char *error = int64_to_str(temp, sizeof(temp), int64_t(0));
+ EXPECT_STREQ("Buffer too small", error);
+ }
+
+ TEST(INT64_TO_STR, FitsJust) {
+ char temp[4];
+ const char *error = int64_to_str(temp, sizeof(temp), int64_t(999));
+ EXPECT_STREQ(temp, "999");
+ EXPECT_TRUE(error == nullptr);
+ }
+
+ TEST(INT64_TO_STR, TooSmall_10) {
+ char temp[2];
+ const char *error = int64_to_str(temp, sizeof(temp), int64_t(10));
+ EXPECT_STREQ("Buffer too small", error);
+ }
+
+ TEST(INT64_TO_STR, Max) {
+ char temp[20];
+ const char *error = int64_to_str(temp, sizeof(temp), std::numeric_limits::max());
+ EXPECT_STREQ(temp, "9223372036854775807");
+ EXPECT_TRUE(error == nullptr);
+ }
+
+ TEST(INT64_TO_STR, Min) {
+ char temp[21];
+ const char *error = int64_to_str(temp, sizeof(temp), std::numeric_limits::min());
+ EXPECT_STREQ(temp, "-9223372036854775808");
+ EXPECT_TRUE(error == nullptr);
+ }
+
+ TEST(STR_TO_INT8, Min) {
+ char numberStr[] = "-128";
+ char error = 0;
+ int8_t number = str_to_int8(numberStr, numberStr + strlen(numberStr), &error);
+ EXPECT_EQ(-128, number);
+ EXPECT_EQ(0, error);
+ }
+
+ TEST(STR_TO_INT8, Max) {
+ char numberStr[] = "127";
+ char error = 0;
+ int8_t number = str_to_int8(numberStr, numberStr + strlen(numberStr), &error);
+ EXPECT_EQ(127, number);
+ EXPECT_EQ(0, error);
+ }
+
+ TEST(STR_TO_INT8, Zero) {
+ char numberStr[] = "0";
+ char error = 0;
+ int8_t number = str_to_int8(numberStr, numberStr + strlen(numberStr), &error);
+ EXPECT_EQ(0, number);
+ EXPECT_EQ(0, error);
+ }
+
+ TEST(STR_TO_INT8, Hundred) {
+ char numberStr[] = "100";
+ char error = 0;
+ int8_t number = str_to_int8(numberStr, numberStr + strlen(numberStr), &error);
+ EXPECT_EQ(100, number);
+ EXPECT_EQ(0, error);
+ }
+
+ TEST(STR_TO_INT8, NegHundred) {
+ char numberStr[] = "-100";
+ char error = 0;
+ int8_t number = str_to_int8(numberStr, numberStr + strlen(numberStr), &error);
+ EXPECT_EQ(-100, number);
+ EXPECT_EQ(0, error);
+ }
+
+ TEST(STR_TO_INT8, OutsideBoundsPositive) {
+ char numberStr[] = "128";
+ char error = 0;
+ str_to_int8(numberStr, numberStr + strlen(numberStr), &error);
+ EXPECT_EQ(1, error);
+ }
+
+ TEST(STR_TO_INT8, OutsideBoundsNegative) {
+ char numberStr[] = "-129";
+ char error = 0;
+ str_to_int8(numberStr, numberStr + strlen(numberStr), &error);
+ EXPECT_EQ(1, error);
+ }
+
+ TEST(STR_TO_INT8, DummyData_Positive) {
+ char numberStr[] = "100b0";
+ char error = 0;
+ str_to_int8(numberStr, numberStr + strlen(numberStr), &error);
+ EXPECT_EQ(1, error);
+ }
+
+ TEST(STR_TO_INT8, DummyData_Negative) {
+ char numberStr[] = "-1002xx";
+ char error = 0;
+ str_to_int8(numberStr, numberStr + strlen(numberStr), &error);
+ EXPECT_EQ(1, error);
+ }
+
+ TEST(STR_TO_INT64, Min) {
+ char numberStr[] = "-9223372036854775807";
+ char error = 0;
+ int64_t number = str_to_int64(numberStr, numberStr + strlen(numberStr), &error);
+ EXPECT_EQ(-9223372036854775807, number);
+ EXPECT_EQ(0, error);
+ }
+
+ TEST(STR_TO_INT64, Max) {
+ char numberStr[] = "9223372036854775807";
+ char error = 0;
+ int64_t number = str_to_int64(numberStr, numberStr + strlen(numberStr), &error);
+ EXPECT_EQ(9223372036854775807, number);
+ EXPECT_EQ(0, error);
+ }
+
+ TEST(STR_TO_INT64, Zero) {
+ char numberStr[] = "0";
+ char error = 0;
+ int64_t number = str_to_int64(numberStr, numberStr + strlen(numberStr), &error);
+ EXPECT_EQ(0, number);
+ EXPECT_EQ(0, error);
+ }
+
+ TEST(STR_TO_INT64, Hundred) {
+ char numberStr[] = "100";
+ char error = 0;
+ int64_t number = str_to_int64(numberStr, numberStr + strlen(numberStr), &error);
+ EXPECT_EQ(100, number);
+ EXPECT_EQ(0, error);
+ }
+
+ TEST(STR_TO_INT64, NegHundred) {
+ char numberStr[] = "-100";
+ char error = 0;
+ int64_t number = str_to_int64(numberStr, numberStr + strlen(numberStr), &error);
+ EXPECT_EQ(-100, number);
+ EXPECT_EQ(0, error);
+ }
+
+ TEST(STR_TO_INT64, DummyData_Positive) {
+ char numberStr[] = "100b0";
+ char error = 0;
+ str_to_int64(numberStr, numberStr + strlen(numberStr), &error);
+ EXPECT_EQ(1, error);
+ }
+
+ TEST(STR_TO_INT64, DummyData_Negative) {
+ char numberStr[] = "-1002xx";
+ char error = 0;
+ str_to_int64(numberStr, numberStr + strlen(numberStr), &error);
+ EXPECT_EQ(1, error);
+ }
+}
diff --git a/deps/ledger-zxlib/tests/sigutils.cpp b/deps/ledger-zxlib/tests/sigutils.cpp
new file mode 100644
index 0000000..764d84e
--- /dev/null
+++ b/deps/ledger-zxlib/tests/sigutils.cpp
@@ -0,0 +1,132 @@
+/*******************************************************************************
+* (c) 2020 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+
+#include "gmock/gmock.h"
+#include
+#include
+#include
+
+#include "sigutils.h"
+
+TEST(SIGUTILS, convertBasic) {
+ char inSignatureDERStr[] = "304402206878b5690514437a2342405029426cc2b25b4a03fc396fef845d656cf62bad2c022018610a8d37e3384245176ab49ddbdbe8da4133f661bf5ea7ad4e3d2b912d856f01";
+ auto inSignatureDER = std::vector(71);
+
+ auto length = parseHexString(inSignatureDER.data(), inSignatureDER.size(), inSignatureDERStr);
+ EXPECT_EQ(length, sizeof(inSignatureDERStr) / 2);
+
+ uint8_t R[32];
+ uint8_t S[32];
+ uint8_t V;
+
+ auto ret = convertDERtoRSV(inSignatureDER.data(), 0, R, S, &V);
+ EXPECT_EQ(ret, 0);
+
+ char inSignatureDERStr_R[] = "6878b5690514437a2342405029426cc2b25b4a03fc396fef845d656cf62bad2c";
+ char inSignatureDERStr_S[] = "18610a8d37e3384245176ab49ddbdbe8da4133f661bf5ea7ad4e3d2b912d856f";
+ auto inSignatureDER_R = std::vector(32);
+ auto inSignatureDER_S = std::vector(32);
+ parseHexString(inSignatureDER_R.data(), inSignatureDER_R.size(), inSignatureDERStr_R);
+ parseHexString(inSignatureDER_S.data(), inSignatureDER_S.size(), inSignatureDERStr_S);
+
+ EXPECT_THAT(R, ::testing::ElementsAreArray(inSignatureDER_R));
+ EXPECT_THAT(S, ::testing::ElementsAreArray(inSignatureDER_S));
+}
+
+TEST(SIGUTILS, convertBasic2) {
+ char inSignatureDERStr[] = "30430220035942178e9e8d447cf9e6886f99c41bf942fb2880fd79aa2d4626489ec7821b021f6b3277dea0355c161d20a120ec9165500b5c9a2cd0fce1c4b8a5260bf6831f";
+ auto inSignatureDER = std::vector(71);
+
+ auto length = parseHexString(inSignatureDER.data(), inSignatureDER.size(), inSignatureDERStr);
+ EXPECT_EQ(length, sizeof(inSignatureDERStr) / 2);
+
+ uint8_t R[32];
+ uint8_t S[32];
+ uint8_t V;
+
+ auto ret = convertDERtoRSV(inSignatureDER.data(), 0, R, S, &V);
+ EXPECT_EQ(ret, 0);
+
+ char inSignatureDERStr_R[] = "035942178e9e8d447cf9e6886f99c41bf942fb2880fd79aa2d4626489ec7821b";
+ char inSignatureDERStr_S[] = "006b3277dea0355c161d20a120ec9165500b5c9a2cd0fce1c4b8a5260bf6831f";
+ auto inSignatureDER_R = std::vector(32);
+ auto inSignatureDER_S = std::vector(32);
+ parseHexString(inSignatureDER_R.data(), inSignatureDER_R.size(), inSignatureDERStr_R);
+ parseHexString(inSignatureDER_S.data(), inSignatureDER_S.size(), inSignatureDERStr_S);
+
+ char buffer[100];
+ array_to_hexstr(buffer, sizeof(buffer), R, (int16_t) sizeof(R));
+ std::cout << buffer << std::endl;
+ array_to_hexstr(buffer, sizeof(buffer), S, (int16_t) sizeof(S));
+ std::cout << buffer << std::endl;
+
+ EXPECT_THAT(R, ::testing::ElementsAreArray(inSignatureDER_R));
+ EXPECT_THAT(S, ::testing::ElementsAreArray(inSignatureDER_S));
+}
+
+TEST(SIGUTILS, convertBasic3) {
+ char inSignatureDERStr[] = "3045022100e9b508a9cd66410b43992c01622cf9e1a6aa1353d836d7f428a6d1317f96f27d02200ca01cee5480388bad3802c08e0bcf357c091f3a5921e1e5d1e0e115dd14ff23";
+ auto inSignatureDER = std::vector(71);
+
+ auto length = parseHexString(inSignatureDER.data(), inSignatureDER.size(), inSignatureDERStr);
+ EXPECT_EQ(length, sizeof(inSignatureDERStr) / 2);
+
+ uint8_t R[32];
+ uint8_t S[32];
+ uint8_t V;
+
+ auto ret = convertDERtoRSV(inSignatureDER.data(), 0, R, S, &V);
+ EXPECT_EQ(ret, 0);
+
+ char inSignatureDERStr_R[] = "e9b508a9cd66410b43992c01622cf9e1a6aa1353d836d7f428a6d1317f96f27d";
+ char inSignatureDERStr_S[] = "0ca01cee5480388bad3802c08e0bcf357c091f3a5921e1e5d1e0e115dd14ff23";
+ auto inSignatureDER_R = std::vector(32);
+ auto inSignatureDER_S = std::vector(32);
+ parseHexString(inSignatureDER_R.data(), inSignatureDER_R.size(), inSignatureDERStr_R);
+ parseHexString(inSignatureDER_S.data(), inSignatureDER_S.size(), inSignatureDERStr_S);
+
+ EXPECT_THAT(R, ::testing::ElementsAreArray(inSignatureDER_R));
+ EXPECT_THAT(S, ::testing::ElementsAreArray(inSignatureDER_S));
+}
+
+TEST(SIGUTILS, convertShort1) {
+ char inSignatureDERStr[] = "3041021e544670fe5627f2d483484582284f627d9cfd1e0ab123984e81611a8da4fc021f6d99f9afd3c4fa62cee8dff21786f9c23c8d2f524d8fd363acc6c6567dc380";
+ char inSignatureDERStr_R[] = "0000544670fe5627f2d483484582284f627d9cfd1e0ab123984e81611a8da4fc";
+ char inSignatureDERStr_S[] = "006d99f9afd3c4fa62cee8dff21786f9c23c8d2f524d8fd363acc6c6567dc380";
+
+ auto inSignatureDER = std::vector(sizeof(inSignatureDERStr));
+
+ auto length = parseHexString(inSignatureDER.data(), inSignatureDER.size(), inSignatureDERStr);
+ EXPECT_EQ(length, sizeof(inSignatureDERStr) / 2);
+
+ uint8_t R[32];
+ uint8_t S[32];
+ uint8_t V;
+
+ auto ret = convertDERtoRSV(inSignatureDER.data(), 0, R, S, &V);
+ EXPECT_EQ(ret, 0);
+
+
+ char R_str[200];
+ char S_str[200];
+ array_to_hexstr(R_str, sizeof(R_str), R, 32);
+ std::cout << R_str << std::endl;
+ array_to_hexstr(S_str, sizeof(S_str), S, 32);
+ std::cout << S_str << std::endl;
+
+ EXPECT_STREQ(R_str, inSignatureDERStr_R);
+ EXPECT_STREQ(S_str, inSignatureDERStr_S);
+}
diff --git a/deps/ledger-zxlib/tests/timeutils.cpp b/deps/ledger-zxlib/tests/timeutils.cpp
new file mode 100644
index 0000000..6cf1bfd
--- /dev/null
+++ b/deps/ledger-zxlib/tests/timeutils.cpp
@@ -0,0 +1,92 @@
+/*******************************************************************************
+* (c) 2018 Zondax GmbH
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+********************************************************************************/
+#include
+#include
+#include
+
+namespace {
+ TEST(TIMEUTILS, basic) {
+ uint64_t t = 1104937465;
+ char output[50];
+
+ zxerr_t err = printTime(output, sizeof(output), t);
+
+ EXPECT_EQ(err, zxerr_ok);
+ EXPECT_STREQ(output, "05Jan2005 15:04:25UTC");
+ }
+
+ TEST(TIMEUTILS, yearlookup) {
+ struct tm t = {0}; // Initalize to all 0's
+ for (uint64_t year = 70; year < 470; year++) {
+ t.tm_year = year; // This is year-1900, so 112 = 2012
+ t.tm_mon = 0;
+ t.tm_mday = 1;
+ t.tm_hour = 0;
+ t.tm_min = 0;
+ t.tm_sec = 0;
+ setenv("TZ", "UTC", 1);
+ time_t timeSinceEpoch = mktime(&t);
+
+ const uint32_t day = 60*60*24;
+ uint64_t daysSinceStart = timeSinceEpoch / day;
+
+ std::cout << " " << daysSinceStart << ", " << std::endl;
+ }
+ }
+
+ TEST(TIMEUTILS, loop) {
+ char output[50];
+ char expected_output[50];
+
+ for (uint64_t t = 0; t < 8640000000; t += 1234567) {
+ zxerr_t err = printTime(output, sizeof(output), t);
+ EXPECT_EQ(err, zxerr_ok);
+ time_t tmp = t;
+ auto expected = gmtime(&tmp);
+ snprintf(expected_output, sizeof(expected_output), "%02d%s%d %02d:%02d:%02dUTC",
+ expected->tm_mday,
+ getMonth(expected->tm_mon + 1),
+ expected->tm_year + 1900,
+ expected->tm_hour,
+ expected->tm_min,
+ expected->tm_sec
+ );
+
+ std::cout << t << " " << output << " " << expected_output << std::endl;
+
+ EXPECT_STREQ(output, expected_output);
+ }
+ }
+
+ TEST(TIMEUTILS, zero) {
+ uint64_t t = 0;
+ char output[50];
+
+ zxerr_t err = printTime(output, sizeof(output), t);
+
+ EXPECT_EQ(err, zxerr_ok);
+ EXPECT_STREQ(output, "01Jan1970 00:00:00UTC");
+ }
+
+ TEST(TIMEUTILS, huge) {
+ uint64_t t = 86400ULL * 365ULL * 5000ULL;
+ char output[50];
+
+ zxerr_t err = printTime(output, sizeof(output), t);
+
+ EXPECT_EQ(err, zxerr_out_of_bounds);
+ }
+}
diff --git a/deps/nanos-secure-sdk b/deps/nanos-secure-sdk
new file mode 160000
index 0000000..1a20ae6
--- /dev/null
+++ b/deps/nanos-secure-sdk
@@ -0,0 +1 @@
+Subproject commit 1a20ae6b83329c6c0107eec0a3002a199355abbb
diff --git a/deps/nanox-secure-sdk b/deps/nanox-secure-sdk
new file mode 160000
index 0000000..a79eaf9
--- /dev/null
+++ b/deps/nanox-secure-sdk
@@ -0,0 +1 @@
+Subproject commit a79eaf92aef434a5e63caca6b238fd00db523c8f
diff --git a/docs/APDUSPEC.md b/docs/APDUSPEC.md
new file mode 100644
index 0000000..d97801e
--- /dev/null
+++ b/docs/APDUSPEC.md
@@ -0,0 +1,203 @@
+# Nodle App
+
+## General structure
+
+The general structure of commands and responses is as follows:
+
+### Commands
+
+| Field | Type | Content | Note |
+| :------ | :------- | :--------------------- | ---- |
+| CLA | byte (1) | Application Identifier | 0x98 |
+| INS | byte (1) | Instruction ID | |
+| P1 | byte (1) | Parameter 1 | |
+| P2 | byte (1) | Parameter 2 | |
+| L | byte (1) | Bytes in payload | |
+| PAYLOAD | byte (L) | Payload | |
+
+### Response
+
+| Field | Type | Content | Note |
+| ------- | -------- | ----------- | ------------------------ |
+| ANSWER | byte (?) | Answer | depends on the command |
+| SW1-SW2 | byte (2) | Return code | see list of return codes |
+
+### Return codes
+
+| Return code | Description |
+| ----------- | ----------------------- |
+| 0x6400 | Execution Error |
+| 0x6982 | Empty buffer |
+| 0x6983 | Output buffer too small |
+| 0x6986 | Command not allowed |
+| 0x6D00 | INS not supported |
+| 0x6E00 | CLA not supported |
+| 0x6F00 | Unknown |
+| 0x9000 | Success |
+
+---
+
+## Command definition
+
+### GET_VERSION
+
+#### Command
+
+| Field | Type | Content | Expected |
+| ----- | -------- | ---------------------- | -------- |
+| CLA | byte (1) | Application Identifier | 0x98 |
+| INS | byte (1) | Instruction ID | 0x00 |
+| P1 | byte (1) | Parameter 1 | ignored |
+| P2 | byte (1) | Parameter 2 | ignored |
+| L | byte (1) | Bytes in payload | 0 |
+
+#### Response
+
+| Field | Type | Content | Note |
+| ------- | -------- | ---------------- | ------------------------------- |
+| TEST | byte (1) | Test Mode | 0xFF means test mode is enabled |
+| MAJOR | byte (2) | Version Major | 0..65535 |
+| MINOR | byte (2) | Version Minor | 0..65535 |
+| PATCH | byte (2) | Version Patch | 0..65535 |
+| LOCKED | byte (1) | Device is locked | |
+| SW1-SW2 | byte (2) | Return code | see list of return codes |
+
+---
+
+### INS_GET_ADDR_ED25519
+
+#### Command
+
+| Field | Type | Content | Expected |
+| ------- | -------- | ------------------------- | ---------- |
+| CLA | byte (1) | Application Identifier | 0x98 |
+| INS | byte (1) | Instruction ID | 0x01 |
+| P1 | byte (1) | Request User confirmation | No = 0 |
+| P2 | byte (1) | Parameter 2 | ignored |
+| L | byte (1) | Bytes in payload | (depends) |
+| Path[0] | byte (4) | Derivation Path Data | 0x80000000 | 44 |
+| Path[1] | byte (4) | Derivation Path Data | 0x80000000 | 434 |
+| Path[2] | byte (4) | Derivation Path Data | ? |
+| Path[3] | byte (4) | Derivation Path Data | ? |
+| Path[4] | byte (4) | Derivation Path Data | ? |
+
+#### Response
+
+| Field | Type | Content | Note |
+| ------- | --------- | ----------- | ------------------------ |
+| PK | byte (32) | Public Key | |
+| ADDR | byte (??) | address | |
+| SW1-SW2 | byte (2) | Return code | see list of return codes |
+
+---
+
+### INS_GET_ADDR_SR25519
+
+#### Command
+
+| Field | Type | Content | Expected |
+| ------- | -------- | ------------------------- | ---------- |
+| CLA | byte (1) | Application Identifier | 0x98 |
+| INS | byte (1) | Instruction ID | 0x11 |
+| P1 | byte (1) | Request User confirmation | No = 0 |
+| P2 | byte (1) | Parameter 2 | ignored |
+| L | byte (1) | Bytes in payload | (depends) |
+| Path[0] | byte (4) | Derivation Path Data | 0x80000000 | 44 |
+| Path[1] | byte (4) | Derivation Path Data | 0x80000000 | 434 |
+| Path[2] | byte (4) | Derivation Path Data | ? |
+| Path[3] | byte (4) | Derivation Path Data | ? |
+| Path[4] | byte (4) | Derivation Path Data | ? |
+
+#### Response
+
+| Field | Type | Content | Note |
+| ------- | --------- | ----------- | ------------------------ |
+| PK | byte (32) | Public Key | |
+| ADDR | byte (??) | DOT address | |
+| SW1-SW2 | byte (2) | Return code | see list of return codes |
+
+---
+
+### INS_SIGN_ED25519
+
+#### Command
+
+| Field | Type | Content | Expected |
+| ----- | -------- | ---------------------- | --------- |
+| CLA | byte (1) | Application Identifier | 0x98 |
+| INS | byte (1) | Instruction ID | 0x02 |
+| P1 | byte (1) | Payload desc | 0 = init |
+| | | | 1 = add |
+| | | | 2 = last |
+| P2 | byte (1) | ---- | not used |
+| L | byte (1) | Bytes in payload | (depends) |
+
+The first packet/chunk includes only the derivation path
+
+All other packets/chunks contain data chunks that are described below
+
+##### First Packet
+
+| Field | Type | Content | Expected |
+| ------- | -------- | -------------------- | -------- |
+| Path[0] | byte (4) | Derivation Path Data | 44 |
+| Path[1] | byte (4) | Derivation Path Data | 434 |
+| Path[2] | byte (4) | Derivation Path Data | ? |
+| Path[3] | byte (4) | Derivation Path Data | ? |
+| Path[4] | byte (4) | Derivation Path Data | ? |
+
+##### Other Chunks/Packets
+
+| Field | Type | Content | Expected |
+| ------- | -------- | --------------- | -------- |
+| Message | bytes... | Message to Sign | |
+
+#### Response
+
+| Field | Type | Content | Note |
+| ------- | --------- | ----------- | ------------------------ |
+| SIG | byte (65) | Signature | |
+| SW1-SW2 | byte (2) | Return code | see list of return codes |
+
+---
+
+### INS_SIGN_SR25519
+
+#### Command
+
+| Field | Type | Content | Expected |
+| ----- | -------- | ---------------------- | --------- |
+| CLA | byte (1) | Application Identifier | 0x98 |
+| INS | byte (1) | Instruction ID | 0x12 |
+| P1 | byte (1) | Payload desc | 0 = init |
+| | | | 1 = add |
+| | | | 2 = last |
+| P2 | byte (1) | ---- | not used |
+| L | byte (1) | Bytes in payload | (depends) |
+
+The first packet/chunk includes only the derivation path
+
+All other packets/chunks contain data chunks that are described below
+
+##### First Packet
+
+| Field | Type | Content | Expected |
+| ------- | -------- | -------------------- | -------- |
+| Path[0] | byte (4) | Derivation Path Data | 44 |
+| Path[1] | byte (4) | Derivation Path Data | 434 |
+| Path[2] | byte (4) | Derivation Path Data | ? |
+| Path[3] | byte (4) | Derivation Path Data | ? |
+| Path[4] | byte (4) | Derivation Path Data | ? |
+
+##### Other Chunks/Packets
+
+| Field | Type | Content | Expected |
+| ------- | -------- | --------------- | -------- |
+| Message | bytes... | Message to Sign | |
+
+#### Response
+
+| Field | Type | Content | Note |
+| ------- | --------- | ----------- | ------------------------ |
+| SIG | byte (65) | Signature | |
+| SW1-SW2 | byte (2) | Return code | see list of return codes |
diff --git a/docs/build.md b/docs/build.md
new file mode 100644
index 0000000..bad2cd3
--- /dev/null
+++ b/docs/build.md
@@ -0,0 +1,181 @@
+Tip:
+
+- In releases, you will find a precompiled test app. If you are just curious, you can run `install_app.sh` and avoid building.
+
+## Download and install
+
+*Once the app is approved by Ledger, it will be available in their app store (Ledger Live).
+You can get builds generated by CircleCI from the release tab. THESE ARE UNVETTED DEVELOPMENT RELEASES*
+
+Download a release from Releases. You only need `installer_s.sh`
+
+If the file is not executable, run
+```sh
+chmod +x ./installer_s.sh
+```
+
+then run:
+
+```sh
+./installer_s.sh load
+```
+
+# Development
+
+## Preconditions
+
+- Be sure you checkout submodules too:
+
+ ```
+ git submodule update --init --recursive
+ ```
+
+- Install Docker CE
+ - Instructions can be found here: https://docs.docker.com/install/
+
+- We only officially support Ubuntu. Install the following packages:
+ ```
+ sudo apt update && apt-get -y install build-essential git wget cmake \
+ libssl-dev libgmp-dev autoconf libtool
+ ```
+
+- Install `node > v14.0`. We typically recommend using `n`
+
+- You will need python 3 and then run
+ - `make deps`
+
+ - The current repository keeps track of Ledger's SDK but it is possible to override it by changing the git submodule.
+
+*Warning*: Some IDEs may not use the same python interpreter or virtual enviroment as the one you used when running `pip`.
+If you see conan is not found, check that you installed the package in the same interpreter as the one that launches `cmake`.
+
+## How to build ?
+
+> We like clion or vscode but let's have some reproducible command line steps
+>
+
+- Building the app itself
+
+ If you installed the what is described above, just run:
+ ```bash
+ make
+ ```
+
+## Running tests
+
+- Running rust tests (x64)
+
+ If you installed the what is described above, just run:
+ ```bash
+ make rust_test
+ ```
+
+- Running C/C++ tests (x64)
+
+ If you installed the what is described above, just run:
+ ```bash
+ make cpp_test
+ ```
+
+- Running device emulation+integration tests!!
+
+ ```bash
+ Use Zemu! Explained below!
+ ```
+
+## How to test with Zemu?
+
+> What is Zemu?? Great you asked!!
+> As part of this project, we are making public a beta version of our internal testing+emulation framework for Ledger apps.
+>
+> Npm Package here: https://www.npmjs.com/package/@zondax/zemu
+>
+> Repo here: https://github.com/Zondax/zemu
+
+Let's go! First install everything:
+> At this moment, if you change the app you will need to run `make` before running the test again.
+
+```bash
+make zemu_install
+```
+
+Then you can run JS tests:
+
+```bash
+make zemu_test
+```
+
+To run a single specific test:
+
+> At the moment, the recommendation is to run from the IDE. Remember to run `make` if you change the app.
+
+## Using a real device
+
+### How to prepare your DEVELOPMENT! device:
+
+> You can use an emulated device for development. This is only required if you are using a physical device
+>
+> **Please do not use a Ledger device with funds for development purposes.**
+>>
+> **Have a separate and marked device that is used ONLY for development and testing**
+
+There are a few additional steps that increase reproducibility and simplify development:
+
+**1 - Ensure your device works in your OS**
+- In Linux hosts it might be necessary to adjust udev rules, etc.
+
+ Refer to Ledger documentation: https://support.ledger.com/hc/en-us/articles/115005165269-Fix-connection-issues
+
+**2 - Set a test mnemonic**
+
+Many of our integration tests expect the device to be configured with a known test mnemonic.
+
+- Plug your device while pressing the right button
+
+- Your device will show "Recovery" in the screen
+
+- Double click
+
+- Run `make dev_init`. This will take about 2 minutes. The device will be initialized to:
+
+ ```
+ PIN: 5555
+ Mnemonic: equip will roof matter pink blind book anxiety banner elbow sun young
+ ```
+
+**3 - Add a development certificate**
+
+- Plug your device while pressing the right button
+
+- Your device will show "Recovery" in the screen
+
+- Click both buttons at the same time
+
+- Enter your pin if necessary
+
+- Run `make dev_ca`. The device will receive a development certificate to avoid constant manual confirmations.
+
+## Building the Ledger App
+
+### Loading into your development device
+
+The Makefile will build the firmware in a docker container and leave the binary in the correct directory.
+
+- Build
+
+ ```
+ make # Builds the app
+ ```
+
+- Upload to a device
+
+ The following command will upload the application to the ledger:
+
+ _Warning: The application will be deleted before uploading._
+ ```
+ make load # Builds and loads the app to the device
+ ```
+
+## APDU Specifications
+
+- [APDU Protocol](APDUSPEC.md)
diff --git a/docs/supported_3.52.x.md b/docs/supported_3.52.x.md
new file mode 100644
index 0000000..c97bb84
--- /dev/null
+++ b/docs/supported_3.52.x.md
@@ -0,0 +1,357 @@
+# Nodle 3.52.x
+
+## System
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|fill_block | | :white_check_mark: | :white_check_mark: | `Perbill` _ratio
|
+|remark | | :white_check_mark: | :white_check_mark: | `Bytes` _remark
|
+|set_heap_pages | | :white_check_mark: | :white_check_mark: | `u64` pages
|
+|set_code | | :white_check_mark: | :white_check_mark: | `Bytes` code
|
+|set_code_without_checks | | :white_check_mark: | :white_check_mark: | `Bytes` code
|
+|set_changes_trie_config | | | | `Option` changes_trie_config
|
+|set_storage | | | | `Vec` items
|
+|kill_storage | | | | `Vec` keys
|
+|kill_prefix | | | | `Key` prefix
`u32` _subkeys
|
+
+## Timestamp
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|set | | :white_check_mark: | | `Compact` now
|
+
+## Indices
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|claim | | :white_check_mark: | | `AccountIndex` index
|
+|transfer | | :white_check_mark: | | `AccountId` new
`AccountIndex` index
|
+|free | | :white_check_mark: | | `AccountIndex` index
|
+|force_transfer | | :white_check_mark: | | `AccountId` new
`AccountIndex` index
`bool` freeze
|
+|freeze | | :white_check_mark: | | `AccountIndex` index
|
+
+## Balances
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|transfer | :white_check_mark: | :white_check_mark: | :white_check_mark: | `LookupSource` dest
`Compact` value
|
+|set_balance | | :white_check_mark: | :white_check_mark: | `LookupSource` who
`Compact` new_free
`Compact` new_reserved
|
+|force_transfer | | :white_check_mark: | :white_check_mark: | `LookupSource` source
`LookupSource` dest
`Compact` value
|
+|transfer_keep_alive | :white_check_mark: | :white_check_mark: | :white_check_mark: | `LookupSource` dest
`Compact` value
|
+
+## TransactionPayment
+
+Empty
+
+## RandomnessCollectiveFlip
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+
+## Babe
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|report_equivocation | | | | `BabeEquivocationProof` equivocation_proof
`KeyOwnerProof` key_owner_proof
|
+|report_equivocation_unsigned | | | | `BabeEquivocationProof` equivocation_proof
`KeyOwnerProof` key_owner_proof
|
+
+## Grandpa
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|report_equivocation | | | | `GrandpaEquivocationProof` equivocation_proof
`KeyOwnerProof` key_owner_proof
|
+|report_equivocation_unsigned | | | | `GrandpaEquivocationProof` equivocation_proof
`KeyOwnerProof` key_owner_proof
|
+|note_stalled | | :white_check_mark: | | `BlockNumber` delay
`BlockNumber` best_finalized_block_number
|
+
+## Authorship
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|set_uncles | | | | `Vec` new_uncles
|
+
+## ImOnline
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|heartbeat | | | | `Heartbeat` heartbeat
`Signature` _signature
|
+
+## Offences
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+
+## ValidatorsSet
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|add_member | | :white_check_mark: | | `AccountId` who
|
+|remove_member | | :white_check_mark: | | `AccountId` who
|
+|swap_member | | :white_check_mark: | | `AccountId` remove
`AccountId` add
|
+|reset_members | | :white_check_mark: | | `Vec` members
|
+|change_key | | :white_check_mark: | | `AccountId` new
|
+|set_prime | | :white_check_mark: | | `AccountId` who
|
+|clear_prime | | :white_check_mark: | | |
+
+## Session
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|set_keys | :white_check_mark: | | | `Keys` keys
`Bytes` proof
|
+|purge_keys | :white_check_mark: | :white_check_mark: | | |
+
+## Historical
+
+Empty
+
+## AuthorityDiscovery
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+
+## TechnicalCommittee
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|set_members | | :white_check_mark: | | `Vec` new_members
`Option` prime
`MemberCount` old_count
|
+|execute | | | | `Proposal` proposal
`Compact` length_bound
|
+|propose | | | | `Compact` threshold
`Proposal` proposal
`Compact` length_bound
|
+|vote | | :white_check_mark: | | `Hash` proposal
`Compact` index
`bool` approve
|
+|close | | :white_check_mark: | | `Hash` proposal_hash
`Compact` index
`Compact` proposal_weight_bound
`Compact` length_bound
|
+|disapprove_proposal | | :white_check_mark: | | `Hash` proposal_hash
|
+
+## TechnicalMembership
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|add_member | | :white_check_mark: | | `AccountId` who
|
+|remove_member | | :white_check_mark: | | `AccountId` who
|
+|swap_member | | :white_check_mark: | | `AccountId` remove
`AccountId` add
|
+|reset_members | | :white_check_mark: | | `Vec` members
|
+|change_key | | :white_check_mark: | | `AccountId` new
|
+|set_prime | | :white_check_mark: | | `AccountId` who
|
+|clear_prime | | :white_check_mark: | | |
+
+## FinancialCommittee
+
+| Name | Light | XL | Nesting | Arguments |
+| :---------- |:------------:|:--------:|:--------:|:--------|
+|set_members | | :white_check_mark: | | `Vec` new_members
`Option` prime
`MemberCount` old_count
|
+|execute | | :white_check_mark: | | `Proposal` proposal
`Compact` length_bound
|
+|propose | | :white_check_mark: | | `Compact` threshold
`Proposal` proposal
`Compact` length_bound
|
+|vote | | :white_check_mark: | | `Hash` proposal
`Compact` index