diff --git a/.appveyor b/.appveyor new file mode 100644 index 00000000..7c88bb0c --- /dev/null +++ b/.appveyor @@ -0,0 +1,17 @@ +version: 1.0.{build} + +image: Visual Studio 2017 + +environment: + matrix: + - CONFIGURATION: Debug + - CONFIGURATION: Release + +before_build: + - cmake -D UNIT_TEST=ON -G "Visual Studio 15 2017 Win64" . + +build: + project: $(APPVEYOR_BUILD_FOLDER)\ark_cpp_client.sln + +test_script: +- cmd: '%APPVEYOR_BUILD_FOLDER%\Bin\%CONFIGURATION%\ark_cpp_client.exe' diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 00000000..966eca37 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,17 @@ +version: 1.0.{build} + +image: Visual Studio 2017 + +environment: + matrix: + - CONFIGURATION: Debug + - CONFIGURATION: Release + +before_build: + - cmake -D UNIT_TEST=ON -G "Visual Studio 15 2017 Win64" . + +build: + project: $(APPVEYOR_BUILD_FOLDER)\ark_cpp_client.sln + +test_script: +- cmd: '%APPVEYOR_BUILD_FOLDER%\test\%CONFIGURATION%\ark_cpp_client_tests.exe' diff --git a/.codacy.yml b/.codacy.yml new file mode 100644 index 00000000..3d8896e2 --- /dev/null +++ b/.codacy.yml @@ -0,0 +1,4 @@ +--- +exclude_paths: + - '*.sh' + - '*.md' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4a16c021..865127e3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,50 +3,55 @@ name: Test on: push: branches: - - "**" + - "*" + - "*/*" pull_request: - types: [opened] + types: [ready_for_review, synchronize, opened] jobs: - arduino-default: + arduino: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - name: Make scripts executable run: sudo chmod -R +x ./.github/workflows/test/*.sh - - name: Install + - name: Install Dependencies run: ./.github/workflows/test/install_arduino.sh - - name: Build + - name: Build Arduino Sketch run: ./.github/workflows/test/script_arduino.sh - linux-default: + platformio: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - - name: Make scripts executable - run: sudo chmod -R +x ./.github/workflows/test/*.sh - - name: Install - run: ./.github/workflows/test/install_platform_io.sh + - name: Install Dependencies + run: | + sudo pip install -U platformio + platformio update - name: Build - run: ./.github/workflows/test/script_platform_io.sh + run: | + platformio run + platformio run -d ./test + linux-gcc7: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - - name: Install dependencies + - name: Install Dependencies run: | - sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test - sudo apt-get update - sudo apt-get -y install g++-7 lcov cmake openssl - - name: Make scripts executable - run: sudo chmod -R +x ./.github/workflows/test/*.sh - - name: Environment variables - run: CC=gcc-7 && CXX=g++-7 + sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test + sudo apt-get update + sudo apt-get -y install g++-7 lcov cmake openssl - name: Build - run: ./.github/workflows/test/script_desktop.sh + run: | + mkdir build && cd build + cmake -DCMAKE_BUILD_TYPE=Coverage -DUNIT_TEST=ON .. + cmake --build . + - name: Run Tests + run: ./build/test/ark_cpp_client_tests - name: Codecov upload run: bash <(curl -s https://codecov.io/bash) -t ${{ secrets.CODECOV_TOKEN }} @@ -55,16 +60,19 @@ jobs: steps: - uses: actions/checkout@v1 - - name: Install dependencies + - name: Install Dependencies run: | - sudo apt-get update - sudo apt-get -y install clang-5.0 clang-format-5.0 clang-tidy-5.0 lcov cmake openssl + sudo apt-get update + sudo apt-get -y install clang-5.0 clang-format-5.0 clang-tidy-5.0 lcov cmake openssl - name: Make scripts executable run: sudo chmod -R +x ./.github/workflows/test/*.sh - - name: Environment variables - run: CC=clang-5.0 && CXX=clang++-5.0 - name: Build - run: ./.github/workflows/test/script_desktop.sh + run: | + mkdir build && cd build + cmake -DUNIT_TEST=ON .. + cmake --build . + - name: Run Tests + run: ./build/test/ark_cpp_client_tests - name: Clang Tidy run: ./.github/workflows/test/clang_tidy.sh - name: Clang Format @@ -76,9 +84,12 @@ jobs: steps: - uses: actions/checkout@v1 - run: COMPILER=clang++ - - name: Install dependencies - run: brew install cmake lcov - - name: Make scripts executable - run: sudo chmod -R +x ./.github/workflows/test/*.sh + - name: Install Dependencies + run: brew install cmake - name: Build - run: ./.github/workflows/test/script_desktop.sh + run: | + mkdir build && cd build + cmake -DUNIT_TEST=ON .. + cmake --build . + - name: Run Tests + run: ./build/test/ark_cpp_client_tests diff --git a/.github/workflows/test/clang_format.sh b/.github/workflows/test/clang_format.sh index 19c7f38c..d75cab85 100644 --- a/.github/workflows/test/clang_format.sh +++ b/.github/workflows/test/clang_format.sh @@ -1,6 +1,6 @@ #!/bin/bash -ex -grep -nr '\s$' src test examples .gitignore .gitmodules 2>&1 > /dev/null +grep -nr '\s$' src test .gitignore 2>&1 > /dev/null if $?; then echo Trailing whitespace found, aborting exit 1 diff --git a/.github/workflows/test/clang_tidy.sh b/.github/workflows/test/clang_tidy.sh index ae917a5e..8508d2dc 100644 --- a/.github/workflows/test/clang_tidy.sh +++ b/.github/workflows/test/clang_tidy.sh @@ -1,5 +1,7 @@ +#!/bin/bash + # run clang tidy -cmake -DENABLE_CLANG_TIDY=ON . +cmake -DENABLE_CLANG_TIDY=ON -DUNIT_TEST=ON . make tidy > output.txt #if [[ -n $(grep "warning: " output.txt) ]] || [[ -n $(grep "error: " output.txt) ]]; then # for now only fail the test on errors. Change this as project matures diff --git a/.github/workflows/test/script_arduino.sh b/.github/workflows/test/script_arduino.sh index 06a8c8de..4815d2c3 100644 --- a/.github/workflows/test/script_arduino.sh +++ b/.github/workflows/test/script_arduino.sh @@ -3,6 +3,6 @@ bash ./extras/ARDUINO_IDE.sh --auto mkdir -p ~/Arduino/libraries/cpp-client/ -mv ~/project/* ~/Arduino/libraries/cpp-client +mv ${GITHUB_WORKSPACE}/* ~/Arduino/libraries/cpp-client arduino-cli compile --output temp.bin -b esp32:esp32:esp32 ~/Arduino/libraries/cpp-client/examples/arduino/ESP32/ESP32.ino --debug diff --git a/.gitignore b/.gitignore index 7c7eb12d..ea7068b2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,8 @@ /.history /.vs -/.vscode /bin +build /lib /_Base /CMakeFiles @@ -23,15 +23,11 @@ /test/.vscode /test/lib/readme.txt .DS_Store -/src/Ark-Cpp-Client-lib.dir -/src/CMakeFiles -/src/cmake_install.cmake -/src/Ark-Cpp-Client-lib.vcxproj.filters -/src/Ark-Cpp-Client-lib.vcxproj -/src/Ark-Cpp-Client-lib.sln +/src/ark_cpp_client.vcxproj.filters +/src/ark_cpp_client.vcxproj +/src/ark_cpp_client.sln /src/ALL_BUILD.vcxproj.filters /src/ALL_BUILD.vcxproj -/test/Ark-Cpp-Client-tests.dir /Win32 /test/NightlyMemoryCheck.vcxproj.filters /test/NightlyMemoryCheck.vcxproj @@ -39,46 +35,28 @@ /test/Nightly.vcxproj /test/Experimental.vcxproj.filters /test/Experimental.vcxproj -/test/DartConfiguration.tcl -/test/CTestTestfile.cmake /test/Continuous.vcxproj.filters /test/Continuous.vcxproj -/test/cmake_install.cmake -/test/CMakeFiles/generate.stamp.depend -/test/CMakeFiles/generate.stamp -/test/CMakeFiles -/test/Ark-Cpp-Client-tests.vcxproj.filters -/test/Ark-Cpp-Client-tests.vcxproj -/test/Ark-Cpp-Client-tests.sln +/test/ark_cpp_client_tests.vcxproj.filters +/test/ark_cpp_client_tests.vcxproj +/test/Aark_cpp_client_tests.sln /test/ALL_BUILD.vcxproj.filters /test/ALL_BUILD.vcxproj /_3rdParty /ZERO_CHECK.vcxproj.filters /ZERO_CHECK.vcxproj -/cmake_install.cmake -/CMakeCache.txt -/Ark-Cpp-Client.sln +/ark_cpp_client.sln /ALL_BUILD.vcxproj.filters /ALL_BUILD.vcxproj /src/Win32 -/test/Debug -/src/Debug -/test/Release -/src/Release -/examples/cmake_example/CMakeFiles -/examples/cmake_example/CMakeCache.txt -/examples/cmake_example/Win32/ /examples/cmake_example/_3rdParty -/examples/cmake_example/lib/Debug /examples/cmake_example/bin -/examples/cmake_example/Cpp-Client-Example.dir /examples/cmake_example/ZERO_CHECK.vcxproj.filters /examples/cmake_example/ZERO_CHECK.vcxproj -/examples/cmake_example/Cpp-Client-Example.vcxproj.filters -/examples/cmake_example/Cpp-Client-Example.vcxproj -/examples/cmake_example/Cpp-Client-Example.sln -/examples/cmake_example/cmake_install.cmake +/examples/cmake_example/ark_cpp_client_example.vcxproj.filters +/examples/cmake_example/ark_cpp_client_example.vcxproj +/examples/cmake_example/ark_cpp_client_example.sln /examples/cmake_example/ALL_BUILD.vcxproj.filters /examples/cmake_example/ALL_BUILD.vcxproj /examples/cmake_example/Win32 -/examples/cmake_example/Debug +compile_commands.json diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 2686e380..00000000 --- a/.gitmodules +++ /dev/null @@ -1,9 +0,0 @@ -[submodule "test/lib/googletest"] - path = test/lib/googletest - url = https://github.com/google/googletest.git -[submodule "test/lib/ArduinoJson"] - path = test/lib/ArduinoJson - url = https://github.com/bblanchon/ArduinoJson -[submodule "src/lib/curl"] - path = src/lib/curl - url = https://github.com/curl/curl diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..88f87e33 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,28 @@ +{ + "editor.tokenColorCustomizations": { + "textMateRules": [ + { + "scope": "googletest.failed", + "settings": { + "foreground": "#f00" + } + }, + { + "scope": "googletest.passed", + "settings": { + "foreground": "#0f0" + } + }, + { + "scope": "googletest.run", + "settings": { + "foreground": "#0f0" + } + } + ] + }, + "gtest-adapter.debugConfig": [ + "Debug Tests" + ], + "gtest-adapter.supportLocation": true +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 00000000..405ed354 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,19 @@ +{ + "tasks": [ + { + "type": "shell", + "label": "build_tests", + "command": "cmake -DCMAKE_BUILD_TYPE=Debug . && cmake --build .", + "args": [], + "options": { + "cwd": "${workspaceFolder}" + }, + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": true + } + } + ], + "version": "2.0.0" +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 818731fc..68a139f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,59 +5,73 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). -## Unreleased +## [1.3.0] - 2019-10-09 -### Changed +## [1.3.0-arduino] - 2019-10-09 -- improved class members and test coverage ([#93]) -- improved formatting and maintainability ([#92]) -- dropped Hunter Package Manager in favor of git submodules in OS builds. ([#90]) -- updated ArduinoJson 5.13.2 >> 6.10.1, usage patterns, and documentation/examples. ([#87]) +### Added +- added Blockchain API endpoint ([#104]) -### Fixed +### Changed +- improved API query usage to accept strings ([#114]) +- improved class members and test coverage ([#93]) +- improved formatting and maintainability ([#92]) +- dropped Hunter Package Manager in favor of git submodules in OS builds ([#90]) +- updated ArduinoJson 5.13.2 >> 6.10.1, usage patterns, and documentation/examples ([#87]) +- moved external libraries out of source tree ([#140]) -- fixed typos in Arduino examples ([#86]) -- changed to "statusCode" '422' to test API Post response for empty Transactions objects. ([#85]) +### Fixed +- fixed typos in Arduino examples ([#86]) +- changed to "statusCode" '422' to test API Post response for empty Transactions objects ([#85]) ## [1.2.0] - 2019-02-16 ## [1.2.0-arduino] - 2019-02-16 - ### Added - -- Arduino CircleCI config ([#73]) +- arduino CircleCI config ([#73]) ### Changed - -- updated `keywords.txt`. ([#77]) -- updated `./library.json` package export settings. ([#70]) -- removed unnecessary files: ([#75]) - - `./appveyor.yml`. - - `./CMakeSettings.json`. - - submodule from `cmake_example`. -- removed `./src/stl` library. ([#78]) -- moved `./docs` to `./extras` in arduino builds. ([#75]) -- automated `ARDUINO_IDE.sh` script. ([#72]) -- updated `ARDUINO_IDE.sh` script to reflect `lib/` changes. ([#76]) +- updated `keywords.txt`. ([#77]) +- updated `./library.json` package export settings ([#70]) +- reorganized files and documentation ([#75]) +- removed `./src/stl` library ([#78]) +- automated `ARDUINO_IDE.sh` script ([#72]) +- updated `ARDUINO_IDE.sh` script to reflect `lib/` changes ([#76]) ## [1.1.0] - 2019-02-07 - ### Added - -- Added an API `send()` method for the `Transactions` class ([#64]) -- Added Arduino Sketch Paths to `library.json` ([#67]) +- added an API `send()` method for the `Transactions` class ([#64]) +- added Arduino Sketch Paths to `library.json` ([#67]) ### Fixed +- fixed unterminated comment which resulted in skipped `Node` tests ([#63]) +- renamed `Helpers` class to avoid naming collision with Cpp-Crypto `Helpers` ([#65]) -- Fixed unterminated comment which resulted in skipped `Node` tests ([#63]) -- Renamed `Helpers` class to avoid naming collision with Cpp-Crypto `Helpers` ([#65]) - -## 1.0.0 - 2019-01-19 - -- Initial Release +## [1.0.0] - 2019-01-19 +- Initial Release -[unreleased]: https://github.com/ArkEcosystem/cpp-client/compare/1.1.0...develop -[1.1.0]: https://github.com/ArkEcosystem/cpp-client/compare/1.0.0...1.1.0 -[#64]: https://github.com/ArkEcosystem/cpp-client/pull/64 -[#67]: https://github.com/ArkEcosystem/cpp-client/pull/67 +[1.0.0]: https://github.com/ArkEcosystem/cpp-client/compare/1.0.0...master [#63]: https://github.com/ArkEcosystem/cpp-client/pull/63 +[#64]: https://github.com/ArkEcosystem/cpp-client/pull/64 [#65]: https://github.com/ArkEcosystem/cpp-client/pull/65 +[#67]: https://github.com/ArkEcosystem/cpp-client/pull/67 +[1.1.0]: https://github.com/ArkEcosystem/cpp-client/compare/1.0.0...1.1.0 +[#70]: https://github.com/ArkEcosystem/cpp-client/pull/70 +[#72]: https://github.com/ArkEcosystem/cpp-client/pull/72 +[#73]: https://github.com/ArkEcosystem/cpp-client/pull/73 +[#75]: https://github.com/ArkEcosystem/cpp-client/pull/75 +[#76]: https://github.com/ArkEcosystem/cpp-client/pull/76 +[#77]: https://github.com/ArkEcosystem/cpp-client/pull/77 +[#78]: https://github.com/ArkEcosystem/cpp-client/pull/78 +[1.2.0]: https://github.com/ArkEcosystem/cpp-client/compare/1.1.0...1.2.0 +[1.2.0-arduino]: https://github.com/ArkEcosystem/cpp-client/compare/1.1.0-arduino...1.2.0-arduino +[#85]: https://github.com/ArkEcosystem/cpp-client/pull/85 +[#86]: https://github.com/ArkEcosystem/cpp-client/pull/86 +[#87]: https://github.com/ArkEcosystem/cpp-client/pull/87 +[#90]: https://github.com/ArkEcosystem/cpp-client/pull/90 +[#92]: https://github.com/ArkEcosystem/cpp-client/pull/92 +[#93]: https://github.com/ArkEcosystem/cpp-client/pull/93 +[#104]: https://github.com/ArkEcosystem/cpp-client/pull/104 +[#114]: https://github.com/ArkEcosystem/cpp-client/pull/114 +[#140]: https://github.com/ArkEcosystem/cpp-client/pull/140 +[1.3.0-arduino]: https://github.com/ArkEcosystem/cpp-client/compare/1.2.0-arduino...1.3.0-arduino +[1.3.0]: https://github.com/ArkEcosystem/cpp-client/compare/1.2.0...1.3.0 diff --git a/CMakeLists.txt b/CMakeLists.txt index ce7c04f0..dc18b910 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,62 +1,82 @@ -cmake_minimum_required(VERSION 3.2.2) -set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/toolchain.cmake") +cmake_minimum_required(VERSION 3.2) -project(Ark-Cpp-Client) +project(ark_cpp_client) + +# ------------------------------------------------------------------------------ +# Set the Environment Variables +# ------------------------------------------------------------------------------ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_CXX_STANDARD 11) set(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR}) +set(EXTERNAL_LIBRARY_DIR ${PROJECT_SOURCE_DIR}/extern) + +set(BUILD_SHARED_LIBS OFF) if (MSVC) - add_definitions( - -D_CRT_SECURE_NO_WARNINGS - -D_SCL_SECURE_NO_WARNINGS - -DNOMINMAX - ) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8") + add_definitions(-D_CRT_SECURE_NO_WARNINGS + -D_SCL_SECURE_NO_WARNINGS + -DNOMINMAX) + + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") +else() + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -g") endif() -# clone submodules -execute_process( - COMMAND git submodule update --init --recursive - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} -) +# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ # Clang Tidy # ------------------------------------------------------------------------------ if(ENABLE_CLANG_TIDY) - find_program(CLANG_TIDY_BIN clang-tidy-5.0) find_program(RUN_CLANG_TIDY_BIN run-clang-tidy-5.0.py) - if(CLANG_TIDY_BIN STREQUAL "CLANG_TIDY_BIN-NOTFOUND") - message(FATAL_ERROR "unable to locate clang-tidy-5.0") - endif() - - if(RUN_CLANG_TIDY_BIN STREQUAL "RUN_CLANG_TIDY_BIN-NOTFOUND") - message(FATAL_ERROR "unable to locate run-clang-tidy-5.0.py") - endif() + if(CLANG_TIDY_BIN STREQUAL "CLANG_TIDY_BIN-NOTFOUND") + message(FATAL_ERROR "unable to locate clang-tidy-5.0") + endif() - list(APPEND RUN_CLANG_TIDY_BIN_ARGS - -clang-tidy-binary ${CLANG_TIDY_BIN} - "\"-header-filter=.*\\b(src|test|examples)\\b\\/(?!lib).*\"" #Only run clang tidy on src, test, examples and skip 3rd party libraries - -checks=clan*,cert*,misc*,perf*,cppc*,read*,mode*,-cert-err58-cpp,-misc-noexcept-move-constructor,-cppcoreguidelines-* - ) + if(RUN_CLANG_TIDY_BIN STREQUAL "RUN_CLANG_TIDY_BIN-NOTFOUND") + message(FATAL_ERROR "unable to locate run-clang-tidy-5.0.py") + endif() - add_custom_target( - tidy - COMMAND ${RUN_CLANG_TIDY_BIN} ${RUN_CLANG_TIDY_BIN_ARGS} - COMMENT "running clang tidy" - ) + list(APPEND RUN_CLANG_TIDY_BIN_ARGS + -clang-tidy-binary ${CLANG_TIDY_BIN} + -header-filter="\".*\\b(cpp-client/src)\"" + -checks=clan*,cert*,misc*,perf*,cppc*,read*,mode*,-cert-err58-cpp,-misc-noexcept-move-constructor,-cppcoreguidelines-*) + add_custom_target(tidy + COMMAND ${RUN_CLANG_TIDY_BIN} ${RUN_CLANG_TIDY_BIN_ARGS} + COMMENT "running clang tidy") endif() # ------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ +# Add the ARK C++ Client Library Subdirectory +# ------------------------------------------------------------------------------ + add_subdirectory(src) -add_subdirectory(test) +# ------------------------------------------------------------------------------ + +# ------------------------------------------------------------------------------ +# Add the ARK C++ Client Test Subdirectory +# +# Disabled by default. +# +# Use `cmake -DUNIT_TEST=ON ..` to enable Test building. +# ------------------------------------------------------------------------------ + +option(UNIT_TEST "Tests disabled by default" OFF) + +if(UNIT_TEST) + add_subdirectory(test) +endif() + +# ------------------------------------------------------------------------------ diff --git a/CMakeSettings.json b/CMakeSettings.json new file mode 100644 index 00000000..ae32ec0f --- /dev/null +++ b/CMakeSettings.json @@ -0,0 +1,100 @@ +{ + "configurations": [ + { + "name": "x86-Debug", + "generator": "Visual Studio 16 2019", + "configurationType": "Debug", + "inheritEnvironments": [ "msvc_x86" ], + "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", + "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "variables": [] + }, + { + "name": "x86-Release", + "generator": "Visual Studio 16 2019", + "configurationType": "Release", + "inheritEnvironments": [ "msvc_x86" ], + "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", + "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "variables": [] + }, + { + "name": "x64-Debug", + "generator": "Visual Studio 16 2019 Win64", + "configurationType": "Debug", + "inheritEnvironments": [ "msvc_x64_x64" ], + "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", + "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "variables": [] + }, + { + "name": "x64-Release", + "generator": "Visual Studio 16 2019 Win64", + "configurationType": "Release", + "inheritEnvironments": [ "msvc_x64_x64" ], + "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", + "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "variables": [] + }, + { + "name": "x86-Debug - 2017", + "generator": "Visual Studio 15 2017", + "configurationType": "Debug", + "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", + "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "inheritEnvironments": [ "msvc_x86" ], + "variables": [] + }, + { + "name": "x86-Release - 2017", + "generator": "Visual Studio 15 2017", + "configurationType": "Release", + "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", + "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "inheritEnvironments": [ "msvc_x86" ], + "variables": [] + }, + { + "name": "x64-Debug - 2017", + "generator": "Visual Studio 15 2017 Win64", + "configurationType": "Debug", + "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", + "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "inheritEnvironments": [ "msvc_x64_x64" ], + "variables": [] + }, + { + "name": "x64-Release - 2017", + "generator": "Visual Studio 15 2017 Win64", + "configurationType": "Release", + "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", + "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "inheritEnvironments": [ "msvc_x64_x64" ], + "variables": [] + } + ] +} \ No newline at end of file diff --git a/build.cmd b/build.cmd new file mode 100644 index 00000000..d71edd00 --- /dev/null +++ b/build.cmd @@ -0,0 +1,9 @@ + +rmdir /S /Q build +mkdir build +cd build + +cmake .. +cmake --build . + +cd .. diff --git a/build.sh b/build.sh new file mode 100755 index 00000000..69c55a93 --- /dev/null +++ b/build.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +rm -dfr build +mkdir build +cd build + +cmake .. +cmake --build . diff --git a/cmake/External.cmake b/cmake/External.cmake new file mode 100644 index 00000000..d513efc2 --- /dev/null +++ b/cmake/External.cmake @@ -0,0 +1,48 @@ + +# ------------------------------------------------------------------------------ +# CURL +# ------------------------------------------------------------------------------ + +set(BUILD_TESTING OFF) +set(HTTP_ONLY ON) +set(CURL_STATICLIB YES) +set(CURL_STATIC_CRT ON) +option(CMAKE_USE_LIBSSH2 OFF) +option(BUILD_CURL_EXE OFF) + +if (APPLE) + set(OPENSSL_ROOT_DIR "/usr/local/opt/openssl/lib") + set(OPENSSL_INCLUDE_DIR "/usr/local/opt/openssl/include") +endif() + +# Set the configuration +configure_file(${CMAKE_SOURCE_DIR}/cmake/extern/CURL.txt.in + ${EXTERNAL_LIBRARY_DIR}/curl/CMakeLists.txt) + +# Execute Git Clone and run Cmake +execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . + RESULT_VARIABLE result + WORKING_DIRECTORY ${EXTERNAL_LIBRARY_DIR}/curl) + +if(result) + message(FATAL_ERROR "cURL: CMake Failed: ${result}") +endif() + +# Build the Cloned Repo +execute_process(COMMAND ${CMAKE_COMMAND} --build . + RESULT_VARIABLE result + WORKING_DIRECTORY ${EXTERNAL_LIBRARY_DIR}/curl) + +if(result) + message(FATAL_ERROR "cURL: Build Failed: ${result}") +endif() + +add_subdirectory("${EXTERNAL_LIBRARY_DIR}/curl/src" + "${EXTERNAL_LIBRARY_DIR}/curl/build" + EXCLUDE_FROM_ALL) + +set(CURL_INCLUDE_DIR + ${EXTERNAL_LIBRARY_DIR}/curl/src/include + CACHE INTERNAL "cURL: Include Folder Path") + +# ------------------------------------------------------------------------------ diff --git a/cmake/GTest.cmake b/cmake/GTest.cmake new file mode 100644 index 00000000..b30c64e4 --- /dev/null +++ b/cmake/GTest.cmake @@ -0,0 +1,33 @@ + +# ------------------------------------------------------------------------------ +# Google Test +# ------------------------------------------------------------------------------ + +configure_file(${CMAKE_SOURCE_DIR}/cmake/extern/GTest.txt.in + ${EXTERNAL_LIBRARY_DIR}/googletest/CMakeLists.txt) + +execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . + RESULT_VARIABLE result + WORKING_DIRECTORY ${EXTERNAL_LIBRARY_DIR}/googletest) + +if(result) + message(FATAL_ERROR "CMake step for GTest failed: ${result}") +endif() + +execute_process(COMMAND ${CMAKE_COMMAND} --build . + RESULT_VARIABLE result + WORKING_DIRECTORY ${EXTERNAL_LIBRARY_DIR}/googletest) + +if(result) + message(FATAL_ERROR "Build step for GTest failed: ${result}") +endif() + +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + +add_subdirectory("${EXTERNAL_LIBRARY_DIR}/googletest/src" + "${EXTERNAL_LIBRARY_DIR}/googletest/build" + EXCLUDE_FROM_ALL) + +include_directories(${EXTERNAL_LIBRARY_DIR}/googletest/src/googlemock/include) + +# ------------------------------------------------------------------------------ diff --git a/cmake/extern/CURL.txt.in b/cmake/extern/CURL.txt.in new file mode 100644 index 00000000..b03d6f9a --- /dev/null +++ b/cmake/extern/CURL.txt.in @@ -0,0 +1,21 @@ + +cmake_minimum_required(VERSION 3.2) + +include(ExternalProject) + +# ------------------------------------------------------------------------------ +# CURL +# ------------------------------------------------------------------------------ + +ExternalProject_Add(CURL + GIT_REPOSITORY https://github.com/curl/curl + GIT_TAG curl-7_66_0 + SOURCE_DIR "${EXTERNAL_LIBRARY_DIR}/curl/src" + BINARY_DIR "${EXTERNAL_LIBRARY_DIR}/curl/build" + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + TEST_COMMAND "" +) + +# ------------------------------------------------------------------------------ diff --git a/cmake/extern/GTest.txt.in b/cmake/extern/GTest.txt.in new file mode 100644 index 00000000..4d4372eb --- /dev/null +++ b/cmake/extern/GTest.txt.in @@ -0,0 +1,21 @@ + +cmake_minimum_required(VERSION 3.2) + +include(ExternalProject) + +# ------------------------------------------------------------------------------ +# Google Test +# ------------------------------------------------------------------------------ + +ExternalProject_Add(GoogleTest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG v1.10.x + SOURCE_DIR "${EXTERNAL_LIBRARY_DIR}/googletest/src" + BINARY_DIR "${EXTERNAL_LIBRARY_DIR}/googletest/build" + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + TEST_COMMAND "" +) + +# ------------------------------------------------------------------------------ diff --git a/docs/INSTALL_ARDUINO.md b/docs/INSTALL_ARDUINO.md index 9a9d7172..f19e0b22 100644 --- a/docs/INSTALL_ARDUINO.md +++ b/docs/INSTALL_ARDUINO.md @@ -11,15 +11,6 @@ Download and install the Arduino IDE (>=1.8.5) from the following link: # -### dependencies: - -Using the Arduino IDE's built in Library Manager, -install the following Libraries -- ArduinoJson v6.10.1 -- AUnit - -# - ### Using with the Arduino IDE > include the following header in your Arduino Sketch: ```cpp @@ -28,42 +19,48 @@ install the following Libraries # -### Arduino Example using the Adafruit Feather ESP8266 +### Minimal Arduino Example using the Adafruit Feather ESP8266 ```cpp -#include #include +#include const char* ssid = "your_network"; const char* password = "your_password"; void setup() { - Serial.begin(115200); - - WiFi.mode(WIFI_STA); - WiFi.begin(ssid, password); - while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } - Serial.print("\nConnected, IP address: "); - Serial.println(WiFi.localIP()); - - Ark::Client::Connection connection(CustomNetwork); - - Serial.println(arkClient.blocks.all().c_str()); - Serial.println(); - - Serial.println(arkClient.delegates.all().c_str()); - Serial.println(); - - Serial.println(arkClient.delegates.count().c_str()); - Serial.println(); - - Serial.println(arkClient.peers.all().c_str()); - Serial.println(); - - Serial.println(arkClient.transactions.all().c_str()); - Serial.println(); + Serial.begin(115200); + + WiFi.mode(WIFI_STA); + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } + Serial.print("\nConnected, IP address: "); + Serial.println(WiFi.localIP()); + + Ark::Client::Connection connection("167.114.29.54", 4003); + Serial.println(arkClient.blockchain.get().c_str()); + Serial.println(); + + Serial.println(arkClient.blocks.all().c_str()); + Serial.println(); + + Serial.println(arkClient.delegates.all().c_str()); + Serial.println(); + + Serial.println(arkClient.delegates.count().c_str()); + Serial.println(); + + auto delegatesCount = arkClient.delegates.count(); + Serial.println(delegatesCount.c_str()); + + auto allPeers = arkClient.peers.all(); + Serial.println(allPeers.c_str()); + + auto allTransactions = arkClient.transactions.all(); + Serial.println(allTransactions.c_str()); } void loop() {} + ``` diff --git a/docs/INSTALL_OS.md b/docs/INSTALL_OS.md index 73ba248c..56f2a2bd 100644 --- a/docs/INSTALL_OS.md +++ b/docs/INSTALL_OS.md @@ -17,9 +17,15 @@ or using # ### make and build -**`cd` into `.../cpp-client/`** -then run the following command combo: -`cmake . && cmake --build .` +**For Linux/Mac** +> `./build.sh` + +**For Windows** +> `./build.cmd` ### run tests -`./bin/Ark-Cpp-Client-tests` +**For Linux/Mac** +> `./run_tests.sh` + +**For Windows** +> `./run_tests.cmd` diff --git a/docs/INSTALL_PLATFORMIO.md b/docs/INSTALL_PLATFORMIO.md index 5adc364a..0231f558 100644 --- a/docs/INSTALL_PLATFORMIO.md +++ b/docs/INSTALL_PLATFORMIO.md @@ -18,8 +18,8 @@ or also install platformio dependencies: -> install ArduinoJson@6.10.1 AUnit (2778) -```platformio lib -g install 64@6.10.1 2778``` +> install AUnit (2778) +```platformio lib -g install 2778``` # diff --git a/docs/cpp.md b/docs/cpp.md index 6043451d..c94b4a18 100644 --- a/docs/cpp.md +++ b/docs/cpp.md @@ -40,19 +40,21 @@ The below example shows how you can perform a request. ```cpp // Perform an API call using the connection to access endpoint +const auto blockchainResponse = connection.api.blockchain.get(); + const auto blockResponse = connection.api.blocks.get("13114381566690093367") -const auto delegateResponse = connection.api.delegates.get("boldninja"); +const auto delegateResponse = connection.api.delegates.get("genesis_1"); const auto nodeConfiguration = connection.api.node.configuration(); const auto peer = connection.api.peers.get("167.114.29.49"); -const auto transaction = connection.api.transactions.get("b324cea5c5a6c15e6ced3ec9c3135a8022eeadb8169f7ba66c80ebc82b0ac850"); +const auto transaction = connection.api.transactions.get("ed46b70a5fad2957c09aa0e0d02b7a2e3e4ab93f0581d1a871e0c44907a4f3e4"); -const auto vote = connection.api.votes.get("d202acbfa947acac53ada2ac8a0eb662c9f75421ede3b10a42759352968b4ed2"); +const auto vote = connection.api.votes.get("a3b890d25824eba36dfc2a5956590c68101378211dab216ae92c123ab1ba4b67"); -const auto walletsSearch = connection.api.wallets.search({"username", "baldninja"}); +const auto walletsSearch = connection.api.wallets.search({"username", "genesis_1"}); ``` > \*note: All API response are of the type `std::string` @@ -68,34 +70,35 @@ Below are examples of how to access the Path interface: ```cpp Ark::Client::Host dummyHost("0.0.0.0:4003"); -std::string blocksAllPath = Ark::Client::API::Paths::Blocks::all(dummyHost, 5 /* limit */, 1 /* page */); -// blocksAllPath will be the string "0.0.0.0:4003/api/v2/blocks?limit=5&page=1" +std::string blockchainGetPath = Ark::Client::api::paths::Blockschain::get(dummyHost); +// blockchainGetPath will be the string "0.0.0.0:4003/api/blockchain" + +std::string blocksAllPath = Ark::Client::API::Paths::Blocks::all(dummyHost, "?page=1&limit=5"); +// blocksAllPath will be the string "0.0.0.0:4003/api/blocks?page=1&limit=5" -std::string delegatesGetPath = Ark::Client::API::Paths::Delegates::get(dummyHost, "boldninja"); -// delegatesGetPath will be the string "0.0.0.0:4003/api/v2/delegates/boldninja" +std::string delegatesGetPath = Ark::Client::api::paths::Delegates::get(dummyHost, "genesis_1"); +// delegatesGetPath will be the string "0.0.0.0:4003/api/delegates/genesis_1" -std::string nodeConfigurationPath = Ark::Client::API::Paths::Node::configuration(dummyHost); -// nodeConfigurationPath will be the string "0.0.0.0:4003/api/v2/node/configuration" +std::string nodeConfigurationPath = Ark::Client::api::paths::Node::configuration(dummyHost); +// nodeConfigurationPath will be the string "0.0.0.0:4003/api/node/configuration" -std::string peersAllPath = Ark::Client::API::Paths::Peers::all(dummyHost, 5 /* limit */, 1 /* page */); -// peersAllPath will be the string "0.0.0.0:4003/api/v2/peers?limit=5&page=1" +std::string peersAllPath = Ark::Client::API::Paths::Peers::all(dummyHost, "?page=1&limit=5"); +// peersAllPath will be the string "0.0.0.0:4003/api/peers?page=1&limit=5" -std::string transactionsTypesPath = Ark::Client::API::Paths::Transactions::types(dummyHost); -// transactionsTypesPath will be the string "0.0.0.0:4003/api/v2/transactions/types" +std::string transactionsTypesPath = Ark::Client::api::paths::Transactions::types(dummyHost); +// transactionsTypesPath will be the string "0.0.0.0:4003/api/transactions/types" -std::string votesGetPath = Ark::Client::API::Paths::Votes::get(dummyHost, "d202acbfa947acac53ada2ac8a0eb662c9f75421ede3b10a42759352968b4ed2"); -// votesGetPath will be the string "0.0.0.0:4003/api/v2/votes/d202acbfa947acac53ada2ac8a0eb662c9f75421ede3b10a42759352968b4ed2" +std::string votesGetPath = Ark::Client::api::paths::Votes::get(dummyHost, "a3b890d25824eba36dfc2a5956590c68101378211dab216ae92c123ab1ba4b67"); +// votesGetPath will be the string "0.0.0.0:4003/api/votes/a3b890d25824eba36dfc2a5956590c68101378211dab216ae92c123ab1ba4b67" // the following is an example of formatting a path and body parameters for an http post const std::map searchBody = { - {"username", "baldninja"}, - {"address", "DFJ5Z51F1euNNdRUQJKQVdG4h495LZkc6T"}, - {"publicKey", "03d3c6889608074b44155ad2e6577c3368e27e6e129c457418eb3e5ed029544e8d"} + {"username", "genesis_1"} }; -std::pair walletsSearchPath = Ark::Client::API::Paths::Wallets::search(testHost, searchBody, 5, 1); -// walletsSearchPath.first will be the string "0.0.0.0:4003/api/v2/wallets/search?limit=5&page=1" -// walletsSearchPath.second will be the string "address=DFJ5Z51F1euNNdRUQJKQVdG4h495LZkc6T&publicKey=03d3c6889608074b44155ad2e6577c3368e27e6e129c457418eb3e5ed029544e8d&username=baldninja" +std::pair walletsSearchPath = Ark::Client::API::Paths::Wallets::search(testHost, searchBody, "?page=1&limit=5"); +// walletsSearchPath.first will be the string "0.0.0.0:4003/api/wallets/search?page=1&limit=5" +// walletsSearchPath.second will be the string "username=genesis_1" ``` # Arduino @@ -104,16 +107,11 @@ std::pair walletsSearchPath = Ark::Client::API::Paths: Download and install the Arduino IDE (>=1.8.5) from the following link: `https://www.arduino.cc/en/Main/Software` -Using the Arduino IDE's built in Library Manager, -install the following Libraries: -`ArduinoJson v6.10.1` -`AUnit` - -#### Arduino Example using the Adafruit Feather ESP8266 +#### Minimal Arduino Example using the Adafruit Feather ESP8266 ```Arduino -#include #include +#include const char* ssid = "your_network"; const char* password = "your_password"; @@ -129,6 +127,8 @@ void setup() { Ark::Client::Connection connection("167.114.29.54", 4003); + Serial.println(arkClient.blockchain.get().c_str()); + auto allBlocks = arkClient.blocks.all(); Serial.println(allBlocks.c_str()); @@ -146,6 +146,7 @@ void setup() { } void loop() {} + ``` **PlatformIO IDE:** @@ -163,9 +164,9 @@ or python -c "$(curl -fsSL https://raw.githubusercontent.com/platformio/platformio/develop/scripts/get-platformio.py)" -Install ArduinoJson@6.10.1 AUnit (2778) +Install AUnit (2778) - platformio lib -g install 64@6.10.1 2778 + platformio lib -g install 2778 #### Provide your WiFi info for your board to access the internet @@ -212,9 +213,10 @@ using ### make and build - cd cpp-client/ - cmake . && cmake --build . + mkdir build && cd build + cmake -DUNIT_TEST .. + cmake --build . ### run tests - ./bin/Ark-Cpp-Client-tests + ./test/ark_cpp_client_tests diff --git a/examples/arduino/ESP32/ESP32.ino b/examples/arduino/ESP32/ESP32.ino index 795979ed..76bd4b65 100644 --- a/examples/arduino/ESP32/ESP32.ino +++ b/examples/arduino/ESP32/ESP32.ino @@ -1,7 +1,7 @@ /** - * This file is part of Ark Cpp Client. + * This file is part of ARK Cpp Client. * - * (c) Ark Ecosystem + * (c) ARK Ecosystem * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -11,7 +11,7 @@ * ESP32 Cpp-Client Usage Example Sketch * * This sketch covers how to use the Cpp-Client API. - * It allows your ESP32 to send requests to an Ark Node + * It allows your ESP32 to send requests to an ARK Node */ /** @@ -23,7 +23,7 @@ /** * This is where you include the 'arkClient.h' header. - * This allows your project to use Ark Cpp-Client. + * This allows your project to use ARK Cpp-Client. */ #include /**/ @@ -46,12 +46,12 @@ const char* password = "yourWiFiPassword"; /****************************************/ -/** - * This is the IP address of an Ark Node - * Specifically, this is a Devnet V2 Node IP +/** + * This is the IP address of an ARK Node + * Specifically, this is a Devnet Node IP * You can find more peers here: https://github.com/ArkEcosystem/peers - * - * The Public API port for the V2 Ark network is '4003' + * + * The Public API port for the ARK network is '4003' */ const char* peer = "167.114.29.55"; int port = 4003; @@ -69,389 +69,303 @@ Ark::Client::Connection connection(peer, port); /****************************************/ void checkAPI() { + // With this API endpoint, you can find ARK Blockchain info. + // This is equivalent to calling 'https://dexplorer.ark.io/api//blockchain' + // + // { + // "data": { + // "block": { + // "height": 2922163, + // "id": "84125ec94ba3f3a2d6fd6643d50c98ed2f3c8fa62d8c939355974f404e9b3906" + // }, + // "supply": "13082272800000000" + // } + // } + const auto blockchainResponse = connection.api.blockchain.get(); + Serial.print("\nBlockchain Response: "); + Serial.println(blockchainResponse.c_str()); + /********************/ - /** - * Here you can call a list of 'All' 'Blocks' on the network. - * The '2' and '1' refer to the pagination (e.g. response limit and how many pages) - * - * This is equivalent to calling '167.114.29.49:4003/api/v2/blocks?limit=2&page=1' - * - * The response should be a json-formatted object - * The "pretty print" version would look something like this - * - * { - * "meta": { - * "count": 2, - * "pageCount": 597291, - * "totalCount": 1194581, - * "next": "\/api\/v2\/blocks?limit=2&page=2", - * "previous": null, - * "self": "\/api\/v2\/blocks?limit=2&page=1", - * "first": "\/api\/v2\/blocks?limit=2&page=1", - * "last": "\/api\/v2\/blocks?limit=2&page=597291" - * }, - * "data": [ - * { - * "id": "9809002764916365223", - * "version": 0, - * "height": 1178071, - * "previous": "10476150126412446830", - * "forged": { - * "reward": 200000000, - * "fee": 0, - * "total": 200000000, - * "amount": 0 - * }, - * "payload": { - * "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - * "length": 0 - * }, - * "generator": { - * "username": "darkcrow", - * "address": "DFSUsSmcVUhVZYQ1nowciWmmtnj1kvZK5Z", - * "publicKey": "03a8ff0a3cbdcb3bfbdb84dbf83226f338ba1452047ac5b8228a1513f7f1de80de" - * }, - * "signature": "304402207fd861e98aa5e4ea0c4a828ad9104bb636b429bc73dc0d5bfe3515347e8b1a79022051f8fb3b3752f1204e8c425d0528203942756811d669c7dd1ccb15ff7bc14e09", - * "transactions": 0, - * "timestamp": { - * "epoch": 57144626, - * "unix": 1547245826, - * "human": "2019-01-11T22:30:26.000Z" - * } - * }, - * { - * "id": "10476150126412446830", - * "version": 0, - * "height": 1178070, - * "previous": "1656548224477584335", - * "forged": { - * "reward": 200000000, - * "fee": 0, - * "total": 200000000, - * "amount": 0 - * }, - * "payload": { - * "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - * "length": 0 - * }, - * "generator": { - * "username": "genesis_16", - * "address": "DHg1jYVS23D6GP7RuhckuJsYAr6crH6c3Z", - * "publicKey": "03c57b6a3eb7d01ade51f95c8ae4e8ebeb7ca7b8422ab0fb2a236de5d1a5bc6a1b" - * }, - * "signature": "304402201e548ee45d835a7edda9cddbe26530563c1aceebbb25ebf89966eed8fec5d0e40220140aee033d42562b22c73f097249e9a59cef24a2a7e1c887c7a16691445c2987", - * "transactions": 0, - * "timestamp": { - * "epoch": 57144618, - * "unix": 1547245818, - * "human": "2019-01-11T22:30:18.000Z" - * } - * } - * ] - * } - * - */ - const auto blocksResponse = connection.api.blocks.all(2, 1); - Serial.print("\nBlocks Response: "); - Serial.println(blocksResponse.c_str()); // The response is a 'std::string', to Print on Arduino, we need the c_string type. - /**/ + // Here you can call a list of 'All' 'Blocks' on the network. + // The '1' and '1' refer to the pagination (e.g. response limit and what page) + // + // This is equivalent to calling 'https://dexplorer.ark.io/api/blocks?limit=1&page=1' + // + // The response should be a json-formatted object + // The "pretty print" version would look something like this: + // + // { + // "meta": { + // "totalCountIsEstimate": false, + // "count": 1, + // "pageCount": 2918749, + // "totalCount": 2918749, + // "next": "/api/blocks?limit=1&page=2&transform=true", + // "previous": null, + // "self": "/api/blocks?limit=1&page=1&transform=true", + // "first": "/api/blocks?limit=1&page=1&transform=true", + // "last": "/api/blocks?limit=1&page=2918749&transform=true" + // }, + // "data": [ + // { + // "id": "804da254073cad1c2386acbd3c3365c7532cd44ed43f9a4ad6b47541e4a62a2e", + // "version": 0, + // "height": 2918749, + // "previous": "38b9b9fbf9cf8891e1b4f94c73c122199c8871c447bb59ab7c07fe0cedc75ea6", + // "forged": { + // "reward": "200000000", + // "fee": "0", + // "total": "200000000", + // "amount": "0" + // }, + // "payload": { + // "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + // "length": 0 + // }, + // "generator": { + // "username": "zillion", + // "address": "DFWTC6qyGgWPFp3NvWtmtvZV1mKF9ASVMk", + // "publicKey": "0366da7ed85cc1e73a13fafb8007d2609d92239355847343cc7b12d85a65d25502" + // }, + // "signature": "3045022100c7965c32f881fd6f4f691e9e479c8768a7ba13679cf449ae78174906431154ce02202ad413d16ce61ca19ef795dad431670ac2392b8980bfe5fc6e802a34e741c940", + // "confirmations": 0, + // "transactions": 0, + // "timestamp": { + // "epoch": 72725376, + // "unix": 1562826576, + // "human": "2019-07-11T06:29:36.000Z" + // } + // } + // ] + // } + const auto blocksResponse = connection.api.blocks.all("?limit=1&page=1"); + Serial.print("\nBlocks Response: "); + // The response is a 'std::string'; to 'Print' on Arduino, we need the c_string type. + Serial.println(blocksResponse.c_str()); /********************/ - /** - * The following method can be used to search for a speficit Delegate. - * In this case, 'boldninja'. - * - * This is equivalent to calling '167.114.29.49:4003/api/v2/delegates/boldninja' - * - * The response should be a json-formatted object - * The "pretty print" version would look something like this: - * - * { - * "data": { - * "username": "boldninja", - * "address": "DKrACQw7ytoU2gjppy3qKeE2dQhZjfXYqu", - * "publicKey": "023ee98f453661a1cb765fd60df95b4efb1e110660ffb88ae31c2368a70f1f7359", - * "votes": 4970515580299, - * "rank": 27, - * "blocks": { - * "produced": 23867, - * "missed": 439, - * "last": { - * "id": "13492733628654518284", - * "height": 1178126, - * "timestamp": { - * "epoch": 57145090, - * "unix": 1547246290, - * "human": "2019-01-11T22:38:10.000Z" - * } - * } - * }, - * "production": { - * "approval": 0.04, - * "productivity": 98.19 - * }, - * "forged": { - * "fees": 103507430299, - * "rewards": 4731200000000, - * "total": 4834707430299 - * } - * } - * } - */ - const auto delegateResponse = connection.api.delegates.get("boldninja"); + // The following method can be used to search for a speficit Delegate. + // + // This is equivalent to calling 'https://dexplorer.ark.io/api/delegates/boldninja' + // + // { + // "data": { + // "username": "munich", + // "address": "DKfEF2sykKCZzom3vFg1dp9D2kisB8hM2Q", + // "publicKey": "036a520acf24036ff691a4f8ba19514828e9b5aa36ca4ba0452e9012023caccfef", + // "votes": "30756514325531", + // "rank": 8, + // "blocks": { + // "produced": 39154, + // "last": { + // "id": "9ece2a535ad471766c4bd5b6d0e8f342301b7f744a1ec200ddbc150da0d8c669", + // "height": 2919031, + // "timestamp": { + // "epoch": 72727632, + // "unix": 1562828832, + // "human": "2019-07-11T07:07:12.000Z" + // } + // } + // }, + // "production": { + // "approval": 0.25 + // }, + // "forged": { + // "fees": "5933484566", + // "rewards": "7830800000000", + // "total": "7836733484566" + // } + // } + // } + const auto delegateResponse = connection.api.delegates.get("munich"); Serial.print("\nDelegate Response: "); - Serial.println(delegateResponse.c_str()); // The response is a 'std::string', to Print on Arduino, we need the c_string type. - /**/ + Serial.println(delegateResponse.c_str()); /********************/ - /** - * The following method can be used to get the Status of a Node. - * - * This is equivalent to calling '167.114.29.49:4003/api/v2/node/status' - * - * The response should be a json-formatted object - * The "pretty print" version would look something like this: - * - * { - * "data": { - * "synced": true, - * "now": 1178395, - * "blocksCount": 0 - * } - * } - */ + // The following method can be used to get the Status of a Node. + // + // This is equivalent to calling 'https://dexplorer.ark.io/api/node/status' + // + // The response should be a json-formatted object + // The "pretty print" version would look something like this: + // + // { + // "data": { + // "synced": true, + // "now": 2919069, + // "blocksCount": -1, + // "timestamp": 72727946 + // } + // } const auto nodeStatus = connection.api.node.status(); - Serial.print("\nNode Status: "); - Serial.println(nodeStatus.c_str()); // The response is a 'std::string', to Print on Arduino, we need the c_string type. + Serial.print("\nNode Status: "); + Serial.println(nodeStatus.c_str()); /**/ /********************/ - /** - * The following method can be used to get a list of 'All' 'Peers' on the network. - * - * The '2' and '1' refer to the pagination (e.g. response limit and how many pages) - * - * This is equivalent to calling 'http://167.114.29.49:4003/api/v2/peers?limit=2&page=1' - * - * The response should be a json-formatted object - * The "pretty print" version would look something like this: - * - * { - * "meta": { - * "count": 2, - * "pageCount": 46, - * "totalCount": 91, - * "next": "\/api\/v2\/peers?limit=2&page=2", - * "previous": null, - * "self": "\/api\/v2\/peers?limit=2&page=1", - * "first": "\/api\/v2\/peers?limit=2&page=1", - * "last": "\/api\/v2\/peers?limit=2&page=46" - * }, - * "data": [ - * { - * "ip": "213.32.9.98", - * "port": 4002, - * "version": "2.1.0", - * "height": 1178420, - * "status": 200, - * "os": "linux", - * "latency": 15, - * "hashid": "1c254aa0" - * }, - * { - * "ip": "137.74.237.196", - * "port": 4002, - * "version": "2.1.0", - * "height": 1178420, - * "status": 200, - * "os": "linux", - * "latency": 20, - * "hashid": "64e290cc" - * } - * ] - * } - */ - const auto allPeers = connection.api.peers.all(2, 1); - Serial.print("\nAll Peers: "); - Serial.println(allPeers.c_str()); // The response is a 'std::string', to Print on Arduino, we need the c_string type. - /**/ + // The following method can be used to get a list of 'All' 'Peers' on the network. + // + // This is equivalent to calling 'https://dexplorer.ark.io/api/peers?limit=1&page=1' + // + // { + // "meta": { + // "count": 1, + // "pageCount": 219, + // "totalCount": 219, + // "next": "/api/peers?limit=1&page=2", + // "previous": null, + // "self": "/api/peers?limit=1&page=1", + // "first": "/api/peers?limit=1&page=1", + // "last": "/api/peers?limit=1&page=219" + // }, + // "data": [ + // { + // "ip": "213.32.9.98", + // "port": 4002, + // "ports": {}, + // "version": "2.5.0-next.9", + // "height": 2919099, + // "latency": 9 + // } + // ] + // } + const auto allPeers = connection.api.peers.all("?limit=1&page=1"); + Serial.print("\nAll Peers: "); + Serial.println(allPeers.c_str()); /********************/ - /** - * The following method can be used to get a list of 'Transaction' 'Types'. - * - * This is equivalent to calling 'http://167.114.29.49:4003/api/v2/transactions/types' - * - * The response should be a json-formatted object - * The "pretty print" version would look something like this: - * - * { - * "data": { - * "Transfer": 0, - * "SecondSignature": 1, - * "DelegateRegistration": 2, - * "Vote": 3, - * "MultiSignature": 4, - * "Ipfs": 5, - * "TimelockTransfer": 6, - * "MultiPayment": 7, - * "DelegateResignation": 8 - * } - * } - */ + // The following method can be used to get a list of 'Transaction' 'Types'. + // + // This is equivalent to calling https://dexplorer.ark.io/api/transactions/types' + // + // { + // "data": { + // "Transfer": 0, + // "SecondSignature": 1, + // "DelegateRegistration": 2, + // "Vote": 3, + // "MultiSignature": 4, + // "Ipfs": 5, + // "TimelockTransfer": 6, + // "MultiPayment": 7, + // "DelegateResignation": 8 + // } + // } const auto transactionTypes = connection.api.transactions.types(); - Serial.print("\nTransaction Types: "); - Serial.println(transactionTypes.c_str()); // The response is a 'std::string', to Print on Arduino, we need the c_string type. - /**/ + Serial.print("\nTransaction Types: "); + Serial.println(transactionTypes.c_str()); /********************/ - /** - * This method can be used to get a list of 'Vote' Transactions. - * The '2' and '1' refer to the pagination (e.g. response limit and how many pages) - * - * This is equivalent to calling 'http://167.114.29.49:4003/api/v2/votes?limit=2&page=1' - * - * The response should be a json-formatted object - * The "pretty print" version would look something like this: - * - * { - * "meta": { - * "count": 2, - * "pageCount": 6962, - * "totalCount": 13924, - * "next": "\/api\/v2\/votes?limit=2&page=2", - * "previous": null, - * "self": "\/api\/v2\/votes?limit=2&page=1", - * "first": "\/api\/v2\/votes?limit=2&page=1", - * "last": "\/api\/v2\/votes?limit=2&page=6962" - * }, - * "data": [ - * { - * "id": "315481aa6f8023beb5e0e89ab2b35f11e2fda3f3f34003e6ff563517fe497e0b", - * "blockId": "8426118737032066166", - * "version": 1, - * "type": 3, - * "amount": 0, - * "fee": 80494853, - * "sender": "DQjc6E6WAH7PNtPUNALjZmkyk5yU34RTkU", - * "recipient": "DQjc6E6WAH7PNtPUNALjZmkyk5yU34RTkU", - * "signature": "30450221009095883cb1e4ddab2724a9c7473ca12fd40f390765776e1258375859beb05f12022023d845fd9ce1e424a54adf056e3915ca2a2e9c55a6ea6713639e3da781263df5", - * "asset": { - * "votes": [ - * "+033cce8deb934704f07c994f2f5cfe54d59e061aad8e2f7fc982e4fe978d312a43" - * ] - * }, - * "confirmations": 11466, - * "timestamp": { - * "epoch": 57049890, - * "unix": 1547151090, - * "human": "2019-01-10T20:11:30.000Z" - * } - * }, - * { - * "id": "8484b6de30fe2cc51e7c1844dfae436ba56de3280182e87ff37f1aab7a2d3aa3", - * "blockId": "4417493337461919261", - * "version": 1, - * "type": 3, - * "amount": 0, - * "fee": 80494853, - * "sender": "DQjc6E6WAH7PNtPUNALjZmkyk5yU34RTkU", - * "recipient": "DQjc6E6WAH7PNtPUNALjZmkyk5yU34RTkU", - * "signature": "30440220486bfed2fafdc4b56cd271cceff7849e952776ec10dcfa66ac172f21b9146f8302200751d94d938b0db033019c02ecf9a831fb228e025c5ecbd7a5b5ee8f8634fb1f", - * "asset": { - * "votes": [ - * "-03f294777f7376e970b2bd4805b4a90c8449b5935d530bdb566d02800ac44a4c00" - * ] - * }, - * "confirmations": 11480, - * "timestamp": { - * "epoch": 57049770, - * "unix": 1547150970, - * "human": "2019-01-10T20:09:30.000Z" - * } - * } - * ] - * } - */ - const auto allVotes = connection.api.votes.all(2, 1); - Serial.print("\nAll Votes: "); - Serial.println(allVotes.c_str()); // The response is a 'std::string', to Print on Arduino, we need the c_string type. - /**/ + // This method can be used to get a list of 'Vote' Transactions. + // + // This is equivalent to calling 'https://dexplorer.ark.io/api/votes?limit=1&page=1' + // + // { + // "meta": { + // "totalCountIsEstimate": false, + // "count": 1, + // "pageCount": 15137, + // "totalCount": 15137, + // "next": "/api/votes?limit=1&page=2&transform=true", + // "previous": null, + // "self": "/api/votes?limit=1&page=1&transform=true", + // "first": "/api/votes?limit=1&page=1&transform=true", + // "last": "/api/votes?limit=1&page=15137&transform=true" + // }, + // "data": [ + // { + // "id": "a3b890d25824eba36dfc2a5956590c68101378211dab216ae92c123ab1ba4b67", + // "blockId": "9df8800ab375cfda3782b90bb8e14326e029cecfb22742c6a7c3100c7209a30b", + // "version": 1, + // "type": 3, + // "amount": "0", + // "fee": "97013913", + // "sender": "DTRdbaUW3RQQSL5By4G43JVaeHiqfVp9oh", + // "senderPublicKey": "034da006f958beba78ec54443df4a3f52237253f7ae8cbdb17dccf3feaa57f3126", + // "recipient": "DTRdbaUW3RQQSL5By4G43JVaeHiqfVp9oh", + // "signature": "3045022100b92598f344d3d3d6b0224cfd2058fb35318aac127b8bde529e01fe3868018b610220041cb63436f84bbf93b11c040f9389ebaf8293d63cc685255cea13f48a3f48f6", + // "asset": { + // "votes": [ + // "+02aea83a44f1d6b073e5bcffb4176bbe3c51dcd0e96a793a88f3a6135600224adf" + // ] + // }, + // "confirmations": 229, + // "timestamp": { + // "epoch": 72739207, + // "unix": 1562840407, + // "human": "2019-07-11T10:20:07.000Z" + // } + // } + // ] + // } + const auto allVotes = connection.api.votes.all("?limit=1&page=1"); + Serial.print("\nAll Votes: "); + Serial.println(allVotes.c_str()); /********************/ - /** - * This method can be used to get a list of 'Top' 'Wallets' (Wallets with the most ARK). - * The '2' and '1' refer to the pagination (e.g. response limit and how many pages) - * - * This is equivalent to calling '167.114.29.49:4003/api/v2/wallets/top?limit=2&page=1' - * - * The response should be a json-formatted object - * The "pretty print" version would look something like this: - * - * { - * "meta": { - * "count": 2, - * "pageCount": 97775, - * "totalCount": 195549, - * "next": "\/api\/v2\/wallets\/top?limit=2&page=2", - * "previous": null, - * "self": "\/api\/v2\/wallets\/top?limit=2&page=1", - * "first": "\/api\/v2\/wallets\/top?limit=2&page=1", - * "last": "\/api\/v2\/wallets\/top?limit=2&page=97775" - * }, - * "data": [ - * { - * "address": "D6Z26L69gdk9qYmTv5uzk3uGepigtHY4ax", - * "publicKey": "03d3fdad9c5b25bf8880e6b519eb3611a5c0b31adebc8455f0e096175b28321aff", - * "username": null, - * "secondPublicKey": null, - * "balance": 10181224932845318, - * "isDelegate": false - * }, - * { - * "address": "DEyaFhDuaoQyKbFH4gJtYZvKkB6umyrEUj", - * "publicKey": "033c59dcdc36944cc28f68c1e4b47ac370fe326e53f9adf5f07764d3e8b74b1838", - * "username": "whalessio", - * "secondPublicKey": "03820f214bd49a09c636fa366b4b3c1a0dbd2953d14aac7e68a596e0636e662dfb", - * "balance": 2000035979999643, - * "isDelegate": true - * } - * ] - * } - */ - const auto topWallets = connection.api.wallets.top(2, 1); - Serial.print("\nTop Wallets: "); - Serial.println(topWallets.c_str()); // The response is a 'std::string', to Print on Arduino, we need the c_string type. - /**/ + // This method can be used to get a list of 'Top' 'Wallets' (Wallets with the most ARK). + // + // This is equivalent to calling 'https://dexplorer.ark.io/api/wallets/top?limit=1&page=1' + // + // The response should be a json-formatted object + // The "pretty print" version would look something like this: + // + // { + // "meta": { + // "count": 1, + // "pageCount": 196457, + // "totalCount": 196457, + // "next": "/api/wallets?limit=1&page=2", + // "previous": null, + // "self": "/api/wallets?limit=1&page=1", + // "first": "/api/wallets?limit=1&page=1", + // "last": "/api/wallets?limit=1&page=196457" + // }, + // "data": [ + // { + // "address": "D6Z26L69gdk9qYmTv5uzk3uGepigtHY4ax", + // "publicKey": "03d3fdad9c5b25bf8880e6b519eb3611a5c0b31adebc8455f0e096175b28321aff", + // "balance": "9898440219335676", + // "isDelegate": false + // } + // ] + // } + const auto topWallets = connection.api.wallets.top("limit=1&page=1"); + Serial.print("\nTop Wallets: "); + Serial.println(topWallets.c_str()); }; /****************************************/ -void setup() -{ - Serial.begin(115200); // Begin your Serial Connection. This allows you to monitor your boards output. +void setup() { + // Begin your Serial Connection. + // This allows you to monitor your boards output. + Serial.begin(115200); + + // This starts your boards connection to WiFi. + WiFi.begin(ssid, password); - WiFi.begin(ssid, password); // This starts your boards connection to WiFi. - while (WiFi.status() != WL_CONNECTED) // This will delay your board from continuing until a WiFi connection is established. - { + // This will delay until we're connected to WiFi. + while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); - } - Serial.println(); + }; - Serial.print("Connected, IP address: "); + Serial.print("\nConnected, IP address: "); Serial.println(WiFi.localIP()); - checkAPI(); // Begin API Requests + // Begin API Demo + checkAPI(); }; /****************************************/ -void loop() {}; // We can leave this empty, as we don't want to repeat anything in this example. +// We can leave this empty, we don't want to repeat anything in this example. +void loop() {}; diff --git a/examples/arduino/ESP8266/ESP8266.ino b/examples/arduino/ESP8266/ESP8266.ino index 4965a540..5b3c9619 100644 --- a/examples/arduino/ESP8266/ESP8266.ino +++ b/examples/arduino/ESP8266/ESP8266.ino @@ -1,7 +1,7 @@ /** - * This file is part of Ark Cpp Client. + * This file is part of ARK Cpp Client. * - * (c) Ark Ecosystem + * (c) ARK Ecosystem * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -11,7 +11,7 @@ * ESP8266 Cpp-Client Usage Example Sketch * * This sketch covers how to use the Cpp-Client API. - * It allows your ESP8266 to send requests to an Ark Node + * It allows your ESP8266 to send requests to an ARK Node */ /** @@ -23,7 +23,7 @@ /** * This is where you include the 'arkClient.h' header. - * This allows your project to use Ark Cpp-Client. + * This allows your project to use ARK Cpp-Client. */ #include /**/ @@ -46,12 +46,12 @@ const char* password = "yourWiFiPassword"; /****************************************/ -/** - * This is the IP address of an Ark Node - * Specifically, this is a Devnet V2 Node IP +/** + * This is the IP address of an ARK Node + * Specifically, this is a Devnet Node IP * You can find more peers here: https://github.com/ArkEcosystem/peers - * - * The Public API port for the V2 Ark network is '4003' + * + * The Public API port for the ARK network is '4003' */ const char* peer = "167.114.29.55"; int port = 4003; @@ -69,390 +69,307 @@ Ark::Client::Connection connection(peer, port); /****************************************/ void checkAPI() { + // With this API endpoint, you can find ARK Blockchain info. + // This is equivalent to calling 'https://dexplorer.ark.io/api//blockchain' + // + // { + // "data": { + // "block": { + // "height": 2922163, + // "id": "84125ec94ba3f3a2d6fd6643d50c98ed2f3c8fa62d8c939355974f404e9b3906" + // }, + // "supply": "13082272800000000" + // } + // } + const auto blockchainResponse = connection.api.blockchain.get(); + Serial.print("\nBlockchain Response: "); + Serial.println(blockchainResponse.c_str()); + /********************/ - /** - * Here you can call a list of 'All' 'Blocks' on the network. - * The '2' and '1' refer to the pagination (e.g. response limit and how many pages) - * - * This is equivalent to calling '167.114.29.49:4003/api/v2/blocks?limit=2&page=1' - * - * The response should be a json-formatted object - * The "pretty print" version would look something like this - * - * { - * "meta": { - * "count": 2, - * "pageCount": 597291, - * "totalCount": 1194581, - * "next": "\/api\/v2\/blocks?limit=2&page=2", - * "previous": null, - * "self": "\/api\/v2\/blocks?limit=2&page=1", - * "first": "\/api\/v2\/blocks?limit=2&page=1", - * "last": "\/api\/v2\/blocks?limit=2&page=597291" - * }, - * "data": [ - * { - * "id": "9809002764916365223", - * "version": 0, - * "height": 1178071, - * "previous": "10476150126412446830", - * "forged": { - * "reward": 200000000, - * "fee": 0, - * "total": 200000000, - * "amount": 0 - * }, - * "payload": { - * "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - * "length": 0 - * }, - * "generator": { - * "username": "darkcrow", - * "address": "DFSUsSmcVUhVZYQ1nowciWmmtnj1kvZK5Z", - * "publicKey": "03a8ff0a3cbdcb3bfbdb84dbf83226f338ba1452047ac5b8228a1513f7f1de80de" - * }, - * "signature": "304402207fd861e98aa5e4ea0c4a828ad9104bb636b429bc73dc0d5bfe3515347e8b1a79022051f8fb3b3752f1204e8c425d0528203942756811d669c7dd1ccb15ff7bc14e09", - * "transactions": 0, - * "timestamp": { - * "epoch": 57144626, - * "unix": 1547245826, - * "human": "2019-01-11T22:30:26.000Z" - * } - * }, - * { - * "id": "10476150126412446830", - * "version": 0, - * "height": 1178070, - * "previous": "1656548224477584335", - * "forged": { - * "reward": 200000000, - * "fee": 0, - * "total": 200000000, - * "amount": 0 - * }, - * "payload": { - * "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - * "length": 0 - * }, - * "generator": { - * "username": "genesis_16", - * "address": "DHg1jYVS23D6GP7RuhckuJsYAr6crH6c3Z", - * "publicKey": "03c57b6a3eb7d01ade51f95c8ae4e8ebeb7ca7b8422ab0fb2a236de5d1a5bc6a1b" - * }, - * "signature": "304402201e548ee45d835a7edda9cddbe26530563c1aceebbb25ebf89966eed8fec5d0e40220140aee033d42562b22c73f097249e9a59cef24a2a7e1c887c7a16691445c2987", - * "transactions": 0, - * "timestamp": { - * "epoch": 57144618, - * "unix": 1547245818, - * "human": "2019-01-11T22:30:18.000Z" - * } - * } - * ] - * } - * - */ - const auto blocksResponse = connection.api.blocks.all(2, 1); - Serial.print("\nBlocks Response: "); - Serial.println(blocksResponse.c_str()); // The response is a 'std::string', to Print on Arduino, we need the c_string type. - /**/ + // Here you can call a list of 'All' 'Blocks' on the network. + // The '1' and '1' refer to the pagination (e.g. response limit and what page) + // + // This is equivalent to calling 'https://dexplorer.ark.io/api/blocks?limit=1&page=1' + // + // The response should be a json-formatted object + // The "pretty print" version would look something like this: + // + // { + // "meta": { + // "totalCountIsEstimate": false, + // "count": 1, + // "pageCount": 2918749, + // "totalCount": 2918749, + // "next": "/api/blocks?limit=1&page=2&transform=true", + // "previous": null, + // "self": "/api/blocks?limit=1&page=1&transform=true", + // "first": "/api/blocks?limit=1&page=1&transform=true", + // "last": "/api/blocks?limit=1&page=2918749&transform=true" + // }, + // "data": [ + // { + // "id": "804da254073cad1c2386acbd3c3365c7532cd44ed43f9a4ad6b47541e4a62a2e", + // "version": 0, + // "height": 2918749, + // "previous": "38b9b9fbf9cf8891e1b4f94c73c122199c8871c447bb59ab7c07fe0cedc75ea6", + // "forged": { + // "reward": "200000000", + // "fee": "0", + // "total": "200000000", + // "amount": "0" + // }, + // "payload": { + // "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + // "length": 0 + // }, + // "generator": { + // "username": "zillion", + // "address": "DFWTC6qyGgWPFp3NvWtmtvZV1mKF9ASVMk", + // "publicKey": "0366da7ed85cc1e73a13fafb8007d2609d92239355847343cc7b12d85a65d25502" + // }, + // "signature": "3045022100c7965c32f881fd6f4f691e9e479c8768a7ba13679cf449ae78174906431154ce02202ad413d16ce61ca19ef795dad431670ac2392b8980bfe5fc6e802a34e741c940", + // "confirmations": 0, + // "transactions": 0, + // "timestamp": { + // "epoch": 72725376, + // "unix": 1562826576, + // "human": "2019-07-11T06:29:36.000Z" + // } + // } + // ] + // } + const auto blocksResponse = connection.api.blocks.all("?limit=1&page=1"); + Serial.print("\nBlocks Response: "); + // The response is a 'std::string'; to 'Print' on Arduino, we need the c_string type. + Serial.println(blocksResponse.c_str()); /********************/ - /** - * The following method can be used to search for a speficit Delegate. - * In this case, 'boldninja'. - * - * This is equivalent to calling '167.114.29.49:4003/api/v2/delegates/boldninja' - * - * The response should be a json-formatted object - * The "pretty print" version would look something like this: - * - * { - * "data": { - * "username": "boldninja", - * "address": "DKrACQw7ytoU2gjppy3qKeE2dQhZjfXYqu", - * "publicKey": "023ee98f453661a1cb765fd60df95b4efb1e110660ffb88ae31c2368a70f1f7359", - * "votes": 4970515580299, - * "rank": 27, - * "blocks": { - * "produced": 23867, - * "missed": 439, - * "last": { - * "id": "13492733628654518284", - * "height": 1178126, - * "timestamp": { - * "epoch": 57145090, - * "unix": 1547246290, - * "human": "2019-01-11T22:38:10.000Z" - * } - * } - * }, - * "production": { - * "approval": 0.04, - * "productivity": 98.19 - * }, - * "forged": { - * "fees": 103507430299, - * "rewards": 4731200000000, - * "total": 4834707430299 - * } - * } - * } - */ - const auto delegateResponse = connection.api.delegates.get("boldninja"); - Serial.print("\nDelegate Response: "); - Serial.println(delegateResponse.c_str()); // The response is a 'std::string', to Print on Arduino, we need the c_string type. - /**/ + // The following method can be used to search for a speficit Delegate. + // + // This is equivalent to calling 'https://dexplorer.ark.io/api/delegates/boldninja' + // + // { + // "data": { + // "username": "munich", + // "address": "DKfEF2sykKCZzom3vFg1dp9D2kisB8hM2Q", + // "publicKey": "036a520acf24036ff691a4f8ba19514828e9b5aa36ca4ba0452e9012023caccfef", + // "votes": "30756514325531", + // "rank": 8, + // "blocks": { + // "produced": 39154, + // "last": { + // "id": "9ece2a535ad471766c4bd5b6d0e8f342301b7f744a1ec200ddbc150da0d8c669", + // "height": 2919031, + // "timestamp": { + // "epoch": 72727632, + // "unix": 1562828832, + // "human": "2019-07-11T07:07:12.000Z" + // } + // } + // }, + // "production": { + // "approval": 0.25 + // }, + // "forged": { + // "fees": "5933484566", + // "rewards": "7830800000000", + // "total": "7836733484566" + // } + // } + // } + const auto delegateResponse = connection.api.delegates.get("munich"); + Serial.print("\nDelegate Response: "); + Serial.println(delegateResponse.c_str()); /********************/ - /** - * The following method can be used to get the Status of a Node. - * - * This is equivalent to calling '167.114.29.49:4003/api/v2/node/status' - * - * The response should be a json-formatted object - * The "pretty print" version would look something like this: - * - * { - * "data": { - * "synced": true, - * "now": 1178395, - * "blocksCount": 0 - * } - * } - */ + // The following method can be used to get the Status of a Node. + // + // This is equivalent to calling 'https://dexplorer.ark.io/api/node/status' + // + // The response should be a json-formatted object + // The "pretty print" version would look something like this: + // + // { + // "data": { + // "synced": true, + // "now": 2919069, + // "blocksCount": -1, + // "timestamp": 72727946 + // } + // } const auto nodeStatus = connection.api.node.status(); - Serial.print("\nNode Status: "); - Serial.println(nodeStatus.c_str()); // The response is a 'std::string', to Print on Arduino, we need the c_string type. + Serial.print("\nNode Status: "); + Serial.println(nodeStatus.c_str()); /**/ /********************/ - /** - * The following method can be used to get a list of 'All' 'Peers' on the network. - * - * The '2' and '1' refer to the pagination (e.g. response limit and how many pages) - * - * This is equivalent to calling 'http://167.114.29.49:4003/api/v2/peers?limit=2&page=1' - * - * The response should be a json-formatted object - * The "pretty print" version would look something like this: - * - * { - * "meta": { - * "count": 2, - * "pageCount": 46, - * "totalCount": 91, - * "next": "\/api\/v2\/peers?limit=2&page=2", - * "previous": null, - * "self": "\/api\/v2\/peers?limit=2&page=1", - * "first": "\/api\/v2\/peers?limit=2&page=1", - * "last": "\/api\/v2\/peers?limit=2&page=46" - * }, - * "data": [ - * { - * "ip": "213.32.9.98", - * "port": 4002, - * "version": "2.1.0", - * "height": 1178420, - * "status": 200, - * "os": "linux", - * "latency": 15, - * "hashid": "1c254aa0" - * }, - * { - * "ip": "137.74.237.196", - * "port": 4002, - * "version": "2.1.0", - * "height": 1178420, - * "status": 200, - * "os": "linux", - * "latency": 20, - * "hashid": "64e290cc" - * } - * ] - * } - */ - const auto allPeers = connection.api.peers.all(2, 1); - Serial.print("\nAll Peers: "); - Serial.println(allPeers.c_str()); // The response is a 'std::string', to Print on Arduino, we need the c_string type. - /**/ + // The following method can be used to get a list of 'All' 'Peers' on the network. + // + // This is equivalent to calling 'https://dexplorer.ark.io/api/peers?limit=1&page=1' + // + // { + // "meta": { + // "count": 1, + // "pageCount": 219, + // "totalCount": 219, + // "next": "/api/peers?limit=1&page=2", + // "previous": null, + // "self": "/api/peers?limit=1&page=1", + // "first": "/api/peers?limit=1&page=1", + // "last": "/api/peers?limit=1&page=219" + // }, + // "data": [ + // { + // "ip": "213.32.9.98", + // "port": 4002, + // "ports": {}, + // "version": "2.5.0-next.9", + // "height": 2919099, + // "latency": 9 + // } + // ] + // } + const auto allPeers = connection.api.peers.all("?limit=1&page=1"); + Serial.print("\nAll Peers: "); + Serial.println(allPeers.c_str()); /********************/ - /** - * The following method can be used to get a list of 'Transaction' 'Types'. - * - * This is equivalent to calling 'http://167.114.29.49:4003/api/v2/transactions/types' - * - * The response should be a json-formatted object - * The "pretty print" version would look something like this: - * - * { - * "data": { - * "Transfer": 0, - * "SecondSignature": 1, - * "DelegateRegistration": 2, - * "Vote": 3, - * "MultiSignature": 4, - * "Ipfs": 5, - * "TimelockTransfer": 6, - * "MultiPayment": 7, - * "DelegateResignation": 8 - * } - * } - */ + // The following method can be used to get a list of 'Transaction' 'Types'. + // + // This is equivalent to calling https://dexplorer.ark.io/api/transactions/types' + // + // { + // "data": { + // "Transfer": 0, + // "SecondSignature": 1, + // "DelegateRegistration": 2, + // "Vote": 3, + // "MultiSignature": 4, + // "Ipfs": 5, + // "TimelockTransfer": 6, + // "MultiPayment": 7, + // "DelegateResignation": 8 + // } + // } const auto transactionTypes = connection.api.transactions.types(); - Serial.print("\nTransaction Types: "); - Serial.println(transactionTypes.c_str()); // The response is a 'std::string', to Print on Arduino, we need the c_string type. - /**/ + Serial.print("\nTransaction Types: "); + Serial.println(transactionTypes.c_str()); /********************/ - /** - * This method can be used to get a list of 'Vote' Transactions. - * The '2' and '1' refer to the pagination (e.g. response limit and how many pages) - * - * This is equivalent to calling 'http://167.114.29.49:4003/api/v2/votes?limit=2&page=1' - * - * The response should be a json-formatted object - * The "pretty print" version would look something like this: - * - * { - * "meta": { - * "count": 2, - * "pageCount": 6962, - * "totalCount": 13924, - * "next": "\/api\/v2\/votes?limit=2&page=2", - * "previous": null, - * "self": "\/api\/v2\/votes?limit=2&page=1", - * "first": "\/api\/v2\/votes?limit=2&page=1", - * "last": "\/api\/v2\/votes?limit=2&page=6962" - * }, - * "data": [ - * { - * "id": "315481aa6f8023beb5e0e89ab2b35f11e2fda3f3f34003e6ff563517fe497e0b", - * "blockId": "8426118737032066166", - * "version": 1, - * "type": 3, - * "amount": 0, - * "fee": 80494853, - * "sender": "DQjc6E6WAH7PNtPUNALjZmkyk5yU34RTkU", - * "recipient": "DQjc6E6WAH7PNtPUNALjZmkyk5yU34RTkU", - * "signature": "30450221009095883cb1e4ddab2724a9c7473ca12fd40f390765776e1258375859beb05f12022023d845fd9ce1e424a54adf056e3915ca2a2e9c55a6ea6713639e3da781263df5", - * "asset": { - * "votes": [ - * "+033cce8deb934704f07c994f2f5cfe54d59e061aad8e2f7fc982e4fe978d312a43" - * ] - * }, - * "confirmations": 11466, - * "timestamp": { - * "epoch": 57049890, - * "unix": 1547151090, - * "human": "2019-01-10T20:11:30.000Z" - * } - * }, - * { - * "id": "8484b6de30fe2cc51e7c1844dfae436ba56de3280182e87ff37f1aab7a2d3aa3", - * "blockId": "4417493337461919261", - * "version": 1, - * "type": 3, - * "amount": 0, - * "fee": 80494853, - * "sender": "DQjc6E6WAH7PNtPUNALjZmkyk5yU34RTkU", - * "recipient": "DQjc6E6WAH7PNtPUNALjZmkyk5yU34RTkU", - * "signature": "30440220486bfed2fafdc4b56cd271cceff7849e952776ec10dcfa66ac172f21b9146f8302200751d94d938b0db033019c02ecf9a831fb228e025c5ecbd7a5b5ee8f8634fb1f", - * "asset": { - * "votes": [ - * "-03f294777f7376e970b2bd4805b4a90c8449b5935d530bdb566d02800ac44a4c00" - * ] - * }, - * "confirmations": 11480, - * "timestamp": { - * "epoch": 57049770, - * "unix": 1547150970, - * "human": "2019-01-10T20:09:30.000Z" - * } - * } - * ] - * } - */ - const auto allVotes = connection.api.votes.all(2, 1); - Serial.print("\nAll Votes: "); - Serial.println(allVotes.c_str()); // The response is a 'std::string', to Print on Arduino, we need the c_string type. - /**/ + // This method can be used to get a list of 'Vote' Transactions. + // + // This is equivalent to calling 'https://dexplorer.ark.io/api/votes?limit=1&page=1' + // + // { + // "meta": { + // "totalCountIsEstimate": false, + // "count": 1, + // "pageCount": 15137, + // "totalCount": 15137, + // "next": "/api/votes?limit=1&page=2&transform=true", + // "previous": null, + // "self": "/api/votes?limit=1&page=1&transform=true", + // "first": "/api/votes?limit=1&page=1&transform=true", + // "last": "/api/votes?limit=1&page=15137&transform=true" + // }, + // "data": [ + // { + // "id": "a3b890d25824eba36dfc2a5956590c68101378211dab216ae92c123ab1ba4b67", + // "blockId": "9df8800ab375cfda3782b90bb8e14326e029cecfb22742c6a7c3100c7209a30b", + // "version": 1, + // "type": 3, + // "amount": "0", + // "fee": "97013913", + // "sender": "DTRdbaUW3RQQSL5By4G43JVaeHiqfVp9oh", + // "senderPublicKey": "034da006f958beba78ec54443df4a3f52237253f7ae8cbdb17dccf3feaa57f3126", + // "recipient": "DTRdbaUW3RQQSL5By4G43JVaeHiqfVp9oh", + // "signature": "3045022100b92598f344d3d3d6b0224cfd2058fb35318aac127b8bde529e01fe3868018b610220041cb63436f84bbf93b11c040f9389ebaf8293d63cc685255cea13f48a3f48f6", + // "asset": { + // "votes": [ + // "+02aea83a44f1d6b073e5bcffb4176bbe3c51dcd0e96a793a88f3a6135600224adf" + // ] + // }, + // "confirmations": 229, + // "timestamp": { + // "epoch": 72739207, + // "unix": 1562840407, + // "human": "2019-07-11T10:20:07.000Z" + // } + // } + // ] + // } + const auto allVotes = connection.api.votes.all("?limit=1&page=1"); + Serial.print("\nAll Votes: "); + Serial.println(allVotes.c_str()); /********************/ - /** - * This method can be used to get a list of 'Top' 'Wallets' (Wallets with the most ARK). - * The '2' and '1' refer to the pagination (e.g. response limit and how many pages) - * - * This is equivalent to calling '167.114.29.49:4003/api/v2/wallets/top?limit=2&page=1' - * - * The response should be a json-formatted object - * The "pretty print" version would look something like this: - * - * { - * "meta": { - * "count": 2, - * "pageCount": 97775, - * "totalCount": 195549, - * "next": "\/api\/v2\/wallets\/top?limit=2&page=2", - * "previous": null, - * "self": "\/api\/v2\/wallets\/top?limit=2&page=1", - * "first": "\/api\/v2\/wallets\/top?limit=2&page=1", - * "last": "\/api\/v2\/wallets\/top?limit=2&page=97775" - * }, - * "data": [ - * { - * "address": "D6Z26L69gdk9qYmTv5uzk3uGepigtHY4ax", - * "publicKey": "03d3fdad9c5b25bf8880e6b519eb3611a5c0b31adebc8455f0e096175b28321aff", - * "username": null, - * "secondPublicKey": null, - * "balance": 10181224932845318, - * "isDelegate": false - * }, - * { - * "address": "DEyaFhDuaoQyKbFH4gJtYZvKkB6umyrEUj", - * "publicKey": "033c59dcdc36944cc28f68c1e4b47ac370fe326e53f9adf5f07764d3e8b74b1838", - * "username": "whalessio", - * "secondPublicKey": "03820f214bd49a09c636fa366b4b3c1a0dbd2953d14aac7e68a596e0636e662dfb", - * "balance": 2000035979999643, - * "isDelegate": true - * } - * ] - * } - */ - const auto topWallets = connection.api.wallets.top(2, 1); - Serial.print("\nTop Wallets: "); - Serial.println(topWallets.c_str()); // The response is a 'std::string', to Print on Arduino, we need the c_string type. - /**/ + // This method can be used to get a list of 'Top' 'Wallets' (Wallets with the most ARK). + // + // This is equivalent to calling 'https://dexplorer.ark.io/api/wallets/top?limit=1&page=1' + // + // The response should be a json-formatted object + // The "pretty print" version would look something like this: + // + // { + // "meta": { + // "count": 1, + // "pageCount": 196457, + // "totalCount": 196457, + // "next": "/api/wallets?limit=1&page=2", + // "previous": null, + // "self": "/api/wallets?limit=1&page=1", + // "first": "/api/wallets?limit=1&page=1", + // "last": "/api/wallets?limit=1&page=196457" + // }, + // "data": [ + // { + // "address": "D6Z26L69gdk9qYmTv5uzk3uGepigtHY4ax", + // "publicKey": "03d3fdad9c5b25bf8880e6b519eb3611a5c0b31adebc8455f0e096175b28321aff", + // "balance": "9898440219335676", + // "isDelegate": false + // } + // ] + // } + const auto topWallets = connection.api.wallets.top("?limit=1&page=1"); + Serial.print("\nTop Wallets: "); + Serial.println(topWallets.c_str()); }; /****************************************/ -void setup() -{ - Serial.begin(115200); // Begin your Serial Connection. This allows you to monitor your boards output. +void setup() { + // Begin your Serial Connection. + // This allows you to monitor your boards output. + Serial.begin(115200); + + // WiFi Station Mode. + // Meaning it will only connect to WiFi (vs. acting as an access point). + WiFi.mode(WIFI_STA); + + // This starts your boards connection to WiFi. + WiFi.begin(ssid, password); - WiFi.mode(WIFI_STA); // WiFi Station Mode. Meaning it will only connect to WiFi (vs. acting as an access point). - WiFi.begin(ssid, password); // This starts your boards connection to WiFi. - while (WiFi.status() != WL_CONNECTED) // This will delay your board from continuing until a WiFi connection is established. - { + // This will delay until we're connected to WiFi. + while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); - } - Serial.println(); + }; - Serial.print("Connected, IP address: "); + Serial.print("\nConnected, IP address: "); Serial.println(WiFi.localIP()); - checkAPI(); // Begin API Requests + // Begin API Demo + checkAPI(); }; /****************************************/ -void loop() {}; // We can leave this empty, as we don't want to repeat anything in this example. +// We can leave this empty, we don't want to repeat anything in this example. +void loop() {}; diff --git a/examples/cmake_example/.gitmodules b/examples/cmake_example/.gitmodules deleted file mode 100644 index 458f10ec..00000000 --- a/examples/cmake_example/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "lib/cpp-client"] - path = lib/cpp-client - url = https://github.com/ArkEcosystem/cpp-client.git diff --git a/examples/cmake_example/CMakeLists.txt b/examples/cmake_example/CMakeLists.txt index b549ccc2..a7a8c529 100644 --- a/examples/cmake_example/CMakeLists.txt +++ b/examples/cmake_example/CMakeLists.txt @@ -1,14 +1,7 @@ -cmake_minimum_required(VERSION 3.2) - -# clone submodules -execute_process( - COMMAND git submodule update --init --recursive - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} -) -add_subdirectory(lib/cpp-client) +cmake_minimum_required(VERSION 3.2) -project(Cpp-Client-Example) +project(ark_cpp_client_example) set(CMAKE_CXX_STANDARD 11) @@ -25,8 +18,9 @@ if (MSVC) #set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") endif() +add_subdirectory(lib/cpp-client/src) + set(SOURCE_FILES main.cpp) add_executable(${PROJECT_NAME} ${SOURCE_FILES}) -target_link_libraries(${PROJECT_NAME} Ark-Cpp-Client-lib) - +target_link_libraries(${PROJECT_NAME} ark_cpp_client) diff --git a/examples/cmake_example/build.cmd b/examples/cmake_example/build.cmd new file mode 100644 index 00000000..1224556a --- /dev/null +++ b/examples/cmake_example/build.cmd @@ -0,0 +1,12 @@ +rmdir /S /Q build +mkdir build +cd build + +REM Mimic submodule process by copying cpp-client src into the expected directory +REM git doesn't like nested .gitmodule files +rmdir /S /Q ..\lib\cpp-client\ +mkdir ..\lib\cpp-client\ +xcopy /E /Y /H /R ..\..\..\src ..\lib\cpp-client\ + +cmake .. +cmake --build . diff --git a/examples/cmake_example/build.sh b/examples/cmake_example/build.sh new file mode 100755 index 00000000..5af1675c --- /dev/null +++ b/examples/cmake_example/build.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +rm -dfr build +mkdir build +cd build + +# Mimic submodule process by copying cpp-client src into the expected directory +# git doesn't like nested .gitmodule files +rm -dfr ../lib/cpp-client/ +mkdir ../lib/cpp-client/ +cp -R ../../../src ../lib/cpp-client/ + +cmake .. +cmake --build . diff --git a/examples/cmake_example/lib/put-cpp-client-folder-here b/examples/cmake_example/lib/submodule-cpp-client-folder-here similarity index 100% rename from examples/cmake_example/lib/put-cpp-client-folder-here rename to examples/cmake_example/lib/submodule-cpp-client-folder-here diff --git a/examples/cmake_example/main.cpp b/examples/cmake_example/main.cpp index 1acb5dd8..0470200f 100644 --- a/examples/cmake_example/main.cpp +++ b/examples/cmake_example/main.cpp @@ -1,18 +1,22 @@ -#include "arkClient.h" +#include #include -int main(int argc, char* argv[]) { +int main(int argc, char* argv[]) { // NOLINT // Create a connection Ark::Client::Connection connection("167.114.29.54", 4003); // Perform an API call using the connection to access endpoint + const auto blockchainResponse = connection.api.blockchain.get(); + std::cout << "Response for blockchain:\n"; + std::cout << blockchainResponse << "\n\n"; + const auto blockResponse = connection.api.blocks.get("13114381566690093367"); std::cout << "Response for block '13114381566690093367':\n"; std::cout << blockResponse << "\n\n"; - const auto delegateResponse = connection.api.delegates.get("boldninja"); - std::cout << "Response for delegate 'boldninja':\n"; + const auto delegateResponse = connection.api.delegates.get("genesis_1"); + std::cout << "Response for delegate 'genesis_1':\n"; std::cout << delegateResponse << "\n\n"; const auto nodeConfiguration = connection.api.node.configuration(); @@ -23,17 +27,21 @@ int main(int argc, char* argv[]) { std::cout << "Response for peer '167.114.29.49':\n"; std::cout << peer << "\n\n"; - const auto transaction = - connection.api.transactions.get("b324cea5c5a6c15e6ced3ec9c3135a8022eeadb8169f7ba66c80ebc82b0ac850"); - std::cout << "Response for transaction 'b324cea5c5a6c15e6ced3ec9c3135a8022eeadb8169f7ba66c80ebc82b0ac850':\n"; + const auto transaction =connection.api.transactions.get( + "ed46b70a5fad2957c09aa0e0d02b7a2e3e4ab93f0581d1a871e0c44907a4f3e4"); + std::cout << "Response for transaction 'ed46b70a5fad2957c09aa0e0d02b7a2e3e4ab93f0581d1a871e0c44907a4f3e4':\n"; std::cout << transaction << "\n\n"; - const auto vote = connection.api.votes.get("d202acbfa947acac53ada2ac8a0eb662c9f75421ede3b10a42759352968b4ed2"); - std::cout << "Response for votes 'd202acbfa947acac53ada2ac8a0eb662c9f75421ede3b10a42759352968b4ed2':\n"; + const auto vote = connection.api.votes.get( + "a3b890d25824eba36dfc2a5956590c68101378211dab216ae92c123ab1ba4b67"); + std::cout << "Response for votes 'a3b890d25824eba36dfc2a5956590c68101378211dab216ae92c123ab1ba4b67':\n"; std::cout << vote << "\n\n"; - const auto walletsSearch = connection.api.wallets.search({"username", "baldninja"}); - std::cout << "Response for wallet search 'username=baldninja':\n"; + const std::map body_parameters = { + {"username", "genesis_1"} + }; + const auto walletsSearch = connection.api.wallets.search(body_parameters); + std::cout << "Response for wallet search 'username=genesis_1':\n"; std::cout << walletsSearch << std::endl; return 0; diff --git a/examples/platformio_example/src/main.ino b/examples/platformio_example/src/main.ino index 8c099021..d56ba1f3 100644 --- a/examples/platformio_example/src/main.ino +++ b/examples/platformio_example/src/main.ino @@ -1,3 +1,4 @@ + #include "arkClient.h" #include @@ -14,38 +15,38 @@ void loop() { Ark::Client::Connection connection("167.114.29.54", 4003); // Perform an API call using the connection to access endpoint + const auto blockchainResponse = connection.api.blockchain.get(); + Serial.print("\nResponse for blockchain:"); + Serial.println(blockchainResponse.c_str()); + const auto blockResponse = connection.api.blocks.get("13114381566690093367"); Serial.println("Response for block '13114381566690093367':"); Serial.println(blockResponse.c_str()); - Serial.println(); - const auto delegateResponse = connection.api.delegates.get("boldninja"); - Serial.println("Response for delegate 'boldninja':"); + const auto delegateResponse = connection.api.delegates.get("genesis_1"); + Serial.println("\nResponse for delegate 'genesis_1':"); Serial.println(delegateResponse.c_str()); - Serial.println(); const auto nodeConfiguration = connection.api.node.configuration(); - Serial.println("Response for configuration of node '167.114.29.54:4003':"); + Serial.println("\nResponse for configuration of node '167.114.29.54:4003':"); Serial.println(nodeConfiguration.c_str()); - Serial.println(); const auto peer = connection.api.peers.get("167.114.29.49"); - Serial.println("Response for peer '167.114.29.49':"); + Serial.println("\nResponse for peer '167.114.29.49':"); Serial.println(peer.c_str()); - Serial.println(); - const auto transaction = connection.api.transactions.get("b324cea5c5a6c15e6ced3ec9c3135a8022eeadb8169f7ba66c80ebc82b0ac850"); - Serial.println("Response for transaction 'b324cea5c5a6c15e6ced3ec9c3135a8022eeadb8169f7ba66c80ebc82b0ac850':"); + const auto transaction = connection.api.transactions.get( + "ed46b70a5fad2957c09aa0e0d02b7a2e3e4ab93f0581d1a871e0c44907a4f3e4"); + Serial.println("\nResponse for transaction 'ed46b70a5fad2957c09aa0e0d02b7a2e3e4ab93f0581d1a871e0c44907a4f3e4':"); Serial.println(transaction.c_str()); - Serial.println(); - const auto vote = connection.api.votes.get("d202acbfa947acac53ada2ac8a0eb662c9f75421ede3b10a42759352968b4ed2"); - Serial.println("Response for votes 'd202acbfa947acac53ada2ac8a0eb662c9f75421ede3b10a42759352968b4ed2':"); + const auto vote = connection.api.votes.get( + "a3b890d25824eba36dfc2a5956590c68101378211dab216ae92c123ab1ba4b67"); + Serial.println("\nResponse for votes 'a3b890d25824eba36dfc2a5956590c68101378211dab216ae92c123ab1ba4b67':"); Serial.println(vote.c_str()); - Serial.println(); - const auto walletsSearch = connection.api.wallets.search({ "username", "baldninja" }); - Serial.println("Response for wallet search 'username=baldninja':"); + const auto walletsSearch = connection.api.wallets.search({ "username", "genesis_1" }); + Serial.println("\nResponse for wallet search 'username=genesis_1':"); Serial.println(walletsSearch.c_str()); } diff --git a/extras/ARDUINO_IDE.sh b/extras/ARDUINO_IDE.sh index e051b9b4..0b4cadfe 100644 --- a/extras/ARDUINO_IDE.sh +++ b/extras/ARDUINO_IDE.sh @@ -35,18 +35,22 @@ SRC_DIR=${EXTRAS_DIR}/../src INCLUDE_API_DIR=${INCLUDE_DIR}/api SRC_API_DIR=${SRC_DIR}/api +INCLUDE_BLOCKCHAIN_DIR=${INCLUDE_DIR}/api/blockchain INCLUDE_BLOCKS_DIR=${INCLUDE_DIR}/api/blocks INCLUDE_DELEGATES_DIR=${INCLUDE_DIR}/api/delegates INCLUDE_NODE_DIR=${INCLUDE_DIR}/api/node INCLUDE_PEERS_DIR=${INCLUDE_DIR}/api/peers +INCLUDE_ROUNDS_DIR=${INCLUDE_DIR}/api/rounds INCLUDE_TRANSACTIONS_DIR=${INCLUDE_DIR}/api/transactions INCLUDE_VOTES_DIR=${INCLUDE_DIR}/api/votes INCLUDE_WALLETS_DIR=${INCLUDE_DIR}/api/wallets +SRC_BLOCKCHAIN_DIR=${SRC_DIR}/api/blockchain SRC_BLOCKS_DIR=${SRC_DIR}/api/blocks SRC_DELEGATES_DIR=${SRC_DIR}/api/delegates SRC_NODE_DIR=${SRC_DIR}/api/node SRC_PEERS_DIR=${SRC_DIR}/api/peers +SRC_ROUNDS_DIR=${SRC_DIR}/api/rounds SRC_TRANSACTIONS_DIR=${SRC_DIR}/api/transactions SRC_VOTES_DIR=${SRC_DIR}/api/votes SRC_WALLETS_DIR=${SRC_DIR}/api/wallets @@ -105,10 +109,12 @@ if [[ -d ${INCLUDE_DIR} ]]; then mv ${INCLUDE_API_DIR}/base.h ${SRC_API_DIR} mv ${INCLUDE_API_DIR}/paths.h ${SRC_API_DIR} + mv ${INCLUDE_BLOCKCHAIN_DIR}/blockchain.hpp ${SRC_BLOCKCHAIN_DIR} mv ${INCLUDE_BLOCKS_DIR}/blocks.h ${SRC_BLOCKS_DIR} mv ${INCLUDE_DELEGATES_DIR}/delegates.h ${SRC_DELEGATES_DIR} mv ${INCLUDE_NODE_DIR}/node.h ${SRC_NODE_DIR} mv ${INCLUDE_PEERS_DIR}/peers.h ${SRC_PEERS_DIR} + mv ${INCLUDE_ROUNDS_DIR}/rounds.h ${SRC_ROUNDS_DIR} mv ${INCLUDE_TRANSACTIONS_DIR}/transactions.h ${SRC_TRANSACTIONS_DIR} mv ${INCLUDE_VOTES_DIR}/votes.h ${SRC_VOTES_DIR} mv ${INCLUDE_WALLETS_DIR}/wallets.h ${SRC_WALLETS_DIR} @@ -147,10 +153,12 @@ else echo -e "Recreating API directories 🗂\n" mkdir ${INCLUDE_API_DIR} + mkdir ${INCLUDE_BLOCKCHAIN_DIR} mkdir ${INCLUDE_BLOCKS_DIR} mkdir ${INCLUDE_DELEGATES_DIR} mkdir ${INCLUDE_NODE_DIR} mkdir ${INCLUDE_PEERS_DIR} + mkdir ${INCLUDE_ROUNDS_DIR} mkdir ${INCLUDE_TRANSACTIONS_DIR} mkdir ${INCLUDE_VOTES_DIR} mkdir ${INCLUDE_WALLETS_DIR} @@ -161,10 +169,12 @@ else mv ${SRC_API_DIR}/base.h ${INCLUDE_API_DIR} mv ${SRC_API_DIR}/paths.h ${INCLUDE_API_DIR} + mv ${SRC_BLOCKCHAIN_DIR}/blockchain.hpp ${INCLUDE_BLOCKCHAIN_DIR} mv ${SRC_BLOCKS_DIR}/blocks.h ${INCLUDE_BLOCKS_DIR} mv ${SRC_DELEGATES_DIR}/delegates.h ${INCLUDE_DELEGATES_DIR} mv ${SRC_NODE_DIR}/node.h ${INCLUDE_NODE_DIR} mv ${SRC_PEERS_DIR}/peers.h ${INCLUDE_PEERS_DIR} + mv ${SRC_ROUNDS_DIR}/rounds.h ${INCLUDE_ROUNDS_DIR} mv ${SRC_TRANSACTIONS_DIR}/transactions.h ${INCLUDE_TRANSACTIONS_DIR} mv ${SRC_VOTES_DIR}/votes.h ${INCLUDE_VOTES_DIR} mv ${SRC_WALLETS_DIR}/wallets.h ${INCLUDE_WALLETS_DIR} diff --git a/keywords.txt b/keywords.txt index 7bdcddae..ed2a0fc1 100644 --- a/keywords.txt +++ b/keywords.txt @@ -6,25 +6,25 @@ # Datatypes (KEYWORD1) ####################################### -Ark KEYWORD1 -Client KEYWORD1 -API KEYWORD1 +Ark KEYWORD1 +Client KEYWORD1 +api KEYWORD1 -Api KEYWORD1 +Api KEYWORD1 -Blocks KEYWORD1 -Delegates KEYWORD1 -Node KEYWORD1 -Peers KEYWORD1 -Transactions KEYWORD1 -Votes KEYWORD1 -Wallets KEYWORD1 +Blocks KEYWORD1 +Delegates KEYWORD1 +Node KEYWORD1 +Peers KEYWORD1 +Transactions KEYWORD1 +Votes KEYWORD1 +Wallets KEYWORD1 -Paths KEYWORD1 +paths KEYWORD1 -Connection KEYWORD1 +Connection KEYWORD1 -Host KEYWORD1 +Host KEYWORD1 ####################################### # Methods and Functions (KEYWORD2) diff --git a/library.json b/library.json index 27f9fddc..6c83f652 100644 --- a/library.json +++ b/library.json @@ -7,7 +7,7 @@ "type": "git", "url": "https://github.com/ArkEcosystem/Cpp-Client.git" }, - "version": "1.2.0", + "version": "1.3.0", "authors": [ { "name": "Ark Ecosystem", @@ -16,7 +16,10 @@ } ], "frameworks": "arduino", - "platforms": "*", + "platforms": [ + "espressif8266", + "espressif32" + ], "export": { "include": [ "src/*", diff --git a/library.properties b/library.properties index 1c342a6c..b76ba85d 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Ark-Cpp-Client -version=1.2.0 +version=1.3.0 author=Ark Ecosystem maintainer=Ark Ecosystem sentence=A simple API client implementation in C++ for the ARK Blockchain. diff --git a/platformio.ini b/platformio.ini index 6a02319b..7eeed0d9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -10,10 +10,13 @@ [platformio] description = "A simple API client implementation in C++ for the ARK Blockchain." +src_dir = ./src +build_dir = build/.pioenvs +libdeps_dir = extern/.piolibdeps [common] build_flags = -I./src/ -I./src/include/cpp-client -src_filter = +<*> -<.git/> - - -<_3rdParty> - +src_filter = +<*> - upload_speed = 921600 [env:esp8266] diff --git a/run_tests.cmd b/run_tests.cmd new file mode 100644 index 00000000..9e77eeb7 --- /dev/null +++ b/run_tests.cmd @@ -0,0 +1,11 @@ + +rmdir /S /Q build +mkdir build +cd build + +cmake -DUNIT_TEST=ON .. +cmake --build . + +cd .. + +.\build\test\Debug\ark_cpp_client_tests diff --git a/run_tests.sh b/run_tests.sh new file mode 100755 index 00000000..f428bf51 --- /dev/null +++ b/run_tests.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +rm -dfr build +mkdir build +cd build + +cmake -DUNIT_TEST=ON .. +cmake --build . + +chmod +x ./build/test/ark_cpp_client_tests +./build/test/ark_cpp_client_tests diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index aca3b95e..791de74f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,67 +1,92 @@ -cmake_minimum_required(VERSION 3.2.2) -project(Ark-Cpp-Client-lib) +cmake_minimum_required(VERSION 3.2) -set(PLATFORM_SRC - http/os/http.cpp -) +project(ark_cpp_client C CXX) -set(HOST_SRC - host/host.cpp -) +# ------------------------------------------------------------------------------ +# External Libraries +# ------------------------------------------------------------------------------ + +include(${CMAKE_SOURCE_DIR}/cmake/External.cmake) + +# ------------------------------------------------------------------------------ + +# ------------------------------------------------------------------------------ +# ARK C++ Cliient Source +# ------------------------------------------------------------------------------ + +# ------------------------------------------------------------------------------ +# Platform + +set(PLATFORM_SRC http/os/http.cpp) + +# ------------------------------------------------------------------------------ +# Host + +set(HOST_SRC host/host.cpp) + +# ------------------------------------------------------------------------------ +# Paths + +set(PATHS_SRC api/paths.cpp) -set(API_PATHS_SRC - api/paths.cpp -) +# ------------------------------------------------------------------------------ +# API set(API_SRC - api/blocks/blocks.cpp - api/delegates/delegates.cpp - api/node/node.cpp - api/peers/peers.cpp - api/transactions/transactions.cpp - api/votes/votes.cpp - api/wallets/wallets.cpp -) + api/blockchain/blockchain.cpp + api/blocks/blocks.cpp + api/delegates/delegates.cpp + api/node/node.cpp + api/peers/peers.cpp + api/rounds/rounds.cpp + api/transactions/transactions.cpp + api/votes/votes.cpp + api/wallets/wallets.cpp) -add_library(Ark-Cpp-Client-lib STATIC - ${PLATFORM_SRC} - ${HOST_SRC} - ${API_PATHS_SRC} - ${API_SRC} -) +# ------------------------------------------------------------------------------ +# ARK C++ Client Library Source -set(cpp_client_build_include_dirs - ${PROJECT_SOURCE_DIR} - ${PROJECT_SOURCE_DIR}/include/cpp-client -) +set(ARK_SOURCE + ${PLATFORM_SRC} + ${HOST_SRC} + ${PATHS_SRC} + ${API_SRC}) -include_directories(${cpp_client_build_include_dirs}) -include_directories(${PROJECT_SOURCE_DIR}) +# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ -# curl +# Add the Source Files to the Library # ------------------------------------------------------------------------------ -set(BUILD_TESTING OFF) -set(HTTP_ONLY ON) -set(CMAKE_USE_LIBSSH2 OFF) +add_library(${PROJECT_NAME} STATIC ${ARK_SOURCE}) -include_directories(${PROJECT_SOURCE_DIR}/lib/curl/include) +# ------------------------------------------------------------------------------ -if (UNIX AND NOT APPLE) - add_subdirectory(${PROJECT_SOURCE_DIR}/lib/curl) - target_link_libraries(${PROJECT_NAME} PUBLIC libcurl) -else() - target_link_libraries(${PROJECT_NAME} PUBLIC CURL) -endif() +set(ARK_CPP_CLIENT_INCLUDE_DIRS + ${PROJECT_SOURCE_DIR} + ${PROJECT_SOURCE_DIR}/include/cpp-client) + +include_directories(${ARK_CPP_CLIENT_INCLUDE_DIRS}) + +target_include_directories(${PROJECT_NAME} PUBLIC ${ARK_CPP_CLIENT_INCLUDE_DIRS}) # ------------------------------------------------------------------------------ -target_include_directories(${PROJECT_NAME} PUBLIC - ${cpp_client_build_include_dirs} -) +# ------------------------------------------------------------------------------ +# Link against CURL +# ------------------------------------------------------------------------------ + +target_link_libraries(${PROJECT_NAME} PUBLIC libcurl) + +# ------------------------------------------------------------------------------ + +# ------------------------------------------------------------------------------ +# Windows: Link to `crypt32` +# ------------------------------------------------------------------------------ if (MSVC) - target_link_libraries(${PROJECT_NAME} PUBLIC crypt32) + target_link_libraries(${PROJECT_NAME} PUBLIC crypt32) endif() + +# ------------------------------------------------------------------------------ diff --git a/src/api/blockchain/blockchain.cpp b/src/api/blockchain/blockchain.cpp new file mode 100644 index 00000000..b7a58861 --- /dev/null +++ b/src/api/blockchain/blockchain.cpp @@ -0,0 +1,22 @@ +/** + * This file is part of Ark Cpp Client. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#include "api/blockchain/blockchain.hpp" + +namespace Ark { +namespace Client { +namespace api { + +std::string Blockchain::get() { + return http_->get(paths::Blockchain::get(this->host_).c_str()); +} + +} // namespace api +} // namespace Client +} // namespace Ark diff --git a/src/api/blocks/blocks.cpp b/src/api/blocks/blocks.cpp index d0a932d6..8610b498 100644 --- a/src/api/blocks/blocks.cpp +++ b/src/api/blocks/blocks.cpp @@ -1,41 +1,46 @@ +/** + * This file is part of Ark Cpp Client. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ #include "api/blocks/blocks.h" -std::string Ark::Client::API::Blocks::get( - const char *const blockId) { - return http_->get(Ark::Client::API::Paths::Blocks::get( - this->host_, - blockId).c_str()); +namespace Ark { +namespace Client { +namespace api { + +std::string Blocks::get(const char* blockId) { + return http_->get(paths::Blocks::get(this->host_, blockId).c_str()); } /**/ -std::string Ark::Client::API::Blocks::all( - int limit /* = 5 */, - int page /* = 1 */) { - return http_->get(Ark::Client::API::Paths::Blocks::all( - this->host_, - limit, page).c_str()); +std::string Blocks::all(const char* const query) { + return http_->get(paths::Blocks::all(this->host_, query).c_str()); } /**/ -std::string Ark::Client::API::Blocks::transactions( - const char *const blockId) { - return http_->get(Ark::Client::API::Paths::Blocks::transactions( - this->host_, - blockId).c_str()); +std::string Blocks::transactions(const char* blockId) { + return http_->get(paths::Blocks::transactions(this->host_, blockId).c_str()); } /**/ -std::string Ark::Client::API::Blocks::search( +std::string Blocks::search( const std::map &bodyParameters, - int limit /* = 5 */, - int page /* = 1 */) { - const auto searchPathPair = Ark::Client::API::Paths::Blocks::search( - this->host_, - bodyParameters, - limit, page); - return http_->post(searchPathPair.first.c_str(), searchPathPair.second.c_str()); + const char* const query) { + const auto searchPathPair = paths::Blocks::search(this->host_, + bodyParameters, + query); + return http_->post(searchPathPair.first.c_str(), + searchPathPair.second.c_str()); } + +} // namespace api +} // namespace Client +} // namespace Ark diff --git a/src/api/delegates/delegates.cpp b/src/api/delegates/delegates.cpp index 154de169..4d0d9da9 100644 --- a/src/api/delegates/delegates.cpp +++ b/src/api/delegates/delegates.cpp @@ -1,43 +1,46 @@ +/** + * This file is part of Ark Cpp Client. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ #include "api/delegates/delegates.h" -std::string Ark::Client::API::Delegates::get( - const char *const identifier) { - return http_->get(Ark::Client::API::Paths::Delegates::get( - this->host_, - identifier).c_str()); +namespace Ark { +namespace Client { +namespace api { + +std::string Delegates::get(const char* identifier) { + return http_->get(paths::Delegates::get(this->host_, identifier).c_str()); } /**/ -std::string Ark::Client::API::Delegates::all( - int limit /* = 5 */, - int page /* = 1 */) { - return http_->get(Ark::Client::API::Paths::Delegates::all( - this->host_, - limit, page).c_str()); +std::string Delegates::all(const char* const query) { + return http_->get(paths::Delegates::all(this->host_, query).c_str()); } /**/ -std::string Ark::Client::API::Delegates::blocks( - const char *const identifier, - int limit /* = 5 */, - int page /* = 1 */) { - return http_->get(Ark::Client::API::Paths::Delegates::blocks( - this->host_, - identifier, - limit, page).c_str()); +std::string Delegates::blocks(const char *const identifier, + const char* const query) { + return http_->get(paths::Delegates::blocks(this->host_, + identifier, + query).c_str()); } /**/ -std::string Ark::Client::API::Delegates::voters( - const char *const identifier, - int limit /* = 5 */, - int page /* = 1 */) { - return http_->get(Ark::Client::API::Paths::Delegates::voters( - this->host_, - identifier, - limit, page).c_str()); +std::string Delegates::voters(const char *const identifier, + const char* const query) { + return http_->get(paths::Delegates::voters(this->host_, + identifier, + query).c_str()); } + +} // namespace api +} // namespace Client +} // namespace Ark diff --git a/src/api/node/node.cpp b/src/api/node/node.cpp index 2e061487..b9dcb3df 100644 --- a/src/api/node/node.cpp +++ b/src/api/node/node.cpp @@ -1,21 +1,46 @@ +/** + * This file is part of Ark Cpp Client. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ #include "api/node/node.h" -std::string Ark::Client::API::Node::configuration() { - return http_->get(Ark::Client::API::Paths::Node::configuration( - this->host_).c_str()); +namespace Ark { +namespace Client { +namespace api { + +std::string Node::configuration() { + return http_->get(paths::Node::configuration(this->host_).c_str()); +} + +/**/ + +std::string Node::crypto() { + return http_->get(paths::Node::crypto(this->host_).c_str()); } /**/ -std::string Ark::Client::API::Node::status() { - return http_->get(Ark::Client::API::Paths::Node::status( - this->host_).c_str()); +std::string Node::fees(const char* const query) { + return http_->get(paths::Node::fees(this->host_, query).c_str()); } /**/ -std::string Ark::Client::API::Node::syncing() { - return http_->get(Ark::Client::API::Paths::Node::syncing( - this->host_).c_str()); +std::string Node::status() { + return http_->get(paths::Node::status(this->host_).c_str()); } + +/**/ + +std::string Node::syncing() { + return http_->get(paths::Node::syncing(this->host_).c_str()); +} + +} // namespace api +} // namespace Client +} // namespace Ark diff --git a/src/api/paths.cpp b/src/api/paths.cpp index 85d7ed1b..2303c356 100644 --- a/src/api/paths.cpp +++ b/src/api/paths.cpp @@ -1,72 +1,97 @@ +/** + * This file is part of Ark Cpp Client. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ #include "api/paths.h" +#include + + +#include + +namespace Ark { +namespace Client { +namespace api { +namespace paths { + +namespace { +constexpr const uint8_t URL_MAX_LEN = 128U; +} //namespace + /** - * Blocks + * Blockchain **/ -const char* Ark::Client::API::Paths::Blocks::base() { - return "/api/v2/blocks"; +const char* Blockchain::base() { return "/api/blockchain"; } + +/**/ +std::string Blockchain::get(Host& newHost) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Blockchain::base(); + return url; } +/****/ + +/** + * Blocks + **/ +const char* Blocks::base() { return "/api/blocks"; } + /**/ -std::string Ark::Client::API::Paths::Blocks::get( - Host& newHost, - const char* const blockId) { - char url[128] = {}; - snprintf( - url, sizeof(url), - "%s%s/%s", - newHost.toString().c_str(), - Ark::Client::API::Paths::Blocks::base(), - blockId); +std::string Blocks::get(Host& newHost, const char* blockId) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Blocks::base(); + url += "/"; + url += blockId; return url; } /**/ -std::string Ark::Client::API::Paths::Blocks::all( - Host& newHost, - int limit /* = 5 */, - int page /* = 1 */) { - char url[128] = {}; - snprintf( - url, sizeof(url), - "%s%s?limit=%d&page=%d", - newHost.toString().c_str(), - Ark::Client::API::Paths::Blocks::base(), - limit, page); +std::string Blocks::all(Host& newHost, const char* const query) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Blocks::base(); + url += query; return url; } /**/ -std::string Ark::Client::API::Paths::Blocks::transactions( - Host& newHost, - const char* const blockId) { - char url[128] = {}; - snprintf( - url, sizeof(url), - "%s%s/%s/transactions", - newHost.toString().c_str(), - Ark::Client::API::Paths::Blocks::base(), - blockId); +std::string Blocks::transactions(Host& newHost, const char* blockId) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Blocks::base(); + url += "/"; + url += blockId; + url += "/transactions"; return url; } /**/ -std::pair Ark::Client::API::Paths::Blocks::search( +std::pair Blocks::search( Host& newHost, const std::map& bodyParameters, - int limit /* = 5 */, - int page /* = 1 */) { - char uri[96] = {}; - snprintf( - uri, sizeof(uri), - "%s%s/search?limit=%d&page=%d", - newHost.toString().c_str(), - Ark::Client::API::Paths::Blocks::base(), - limit, page); + const char* const query) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Blocks::base(); + url += "/search"; + url += query; + std::string parameterBuffer; auto count = 0UL; for (const auto& p : bodyParameters) { @@ -76,7 +101,7 @@ std::pair Ark::Client::API::Paths::Blocks::search( parameterBuffer += '&'; }; }; - return {uri, parameterBuffer.c_str()}; + return { url, parameterBuffer }; } /****/ @@ -84,74 +109,60 @@ std::pair Ark::Client::API::Paths::Blocks::search( /** * Delegates **/ -const char* Ark::Client::API::Paths::Delegates::base() { - return "/api/v2/delegates"; -} +const char* Delegates::base() { return "/api/delegates"; } /**/ -std::string Ark::Client::API::Paths::Delegates::get( - Host& newHost, - const char* const identifier) { - char url[128] = {}; - snprintf( - url, sizeof(url), - "%s%s/%s", - newHost.toString().c_str(), - Ark::Client::API::Paths::Delegates::base(), - identifier); +std::string Delegates::get(Host& newHost, const char* identifier) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Delegates::base(); + url += "/"; + url += identifier; return url; } /**/ -std::string Ark::Client::API::Paths::Delegates::all( - Host& newHost, - int limit /* = 5 */, - int page /* = 1 */) { - char uri[128] = {}; - snprintf( - uri, sizeof(uri), - "%s%s?limit=%d&page=%d", - newHost.toString().c_str(), - Ark::Client::API::Paths::Delegates::base(), - limit, page); - return uri; +std::string Delegates::all( Host& newHost, const char* const query) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Delegates::base(); + url += query; + return url; } /**/ -std::string Ark::Client::API::Paths::Delegates::blocks( - Host& newHost, - const char* const identifier, - int limit /* = 5 */, - int page /* = 1 */) { - char url[128] = {}; - snprintf( - url, sizeof(url), - "%s%s/%s/blocks?limit=%d&page=%d", - newHost.toString().c_str(), - Ark::Client::API::Paths::Delegates::base(), - identifier, - limit, page); +std::string Delegates::blocks(Host& newHost, + const char* const identifier, + const char* const query) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Delegates::base(); + url += "/"; + url += identifier; + url += "/blocks"; + url += query; return url; } /**/ -std::string Ark::Client::API::Paths::Delegates::voters( - Host& newHost, - const char* const identifier, - int limit /* = 5 */, - int page /* = 1 */) { - char url[128] = {}; - snprintf( - url, sizeof(url), - "%s%s/%s/voters?limit=%d&page=%d", - newHost.toString().c_str(), - Ark::Client::API::Paths::Delegates::base(), - identifier, - limit, page); +std::string Delegates::voters(Host& newHost, + const char* const identifier, + const char* const query) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Delegates::base(); + url += "/"; + url += identifier; + url += "/voters"; + url += query; return url; } @@ -160,43 +171,61 @@ std::string Ark::Client::API::Paths::Delegates::voters( /** * Node **/ -const char* Ark::Client::API::Paths::Node::base() { - return "/api/v2/node"; +const char* Node::base() { return "/api/node"; } + +/**/ + +std::string Node::configuration(Host& newHost) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Node::base(); + url += "/configuration"; + return url; +} + +/**/ + +std::string Node::crypto(Host& newHost) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Node::base(); + url += "/configuration/crypto"; + return url; } /**/ -std::string Ark::Client::API::Paths::Node::configuration(Host& newHost) { - char url[128] = {}; - snprintf( - url, sizeof(url), - "%s%s/configuration", - newHost.toString().c_str(), - Ark::Client::API::Paths::Node::base()); +std::string Node::fees(Host& newHost, const char* const query) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Node::base(); + url += "/fees"; + url += query; return url; } /**/ -std::string Ark::Client::API::Paths::Node::status(Host& newHost) { - char url[128] = {}; - snprintf( - url, sizeof(url), - "%s%s/status", - newHost.toString().c_str(), - Ark::Client::API::Paths::Node::base()); +std::string Node::status(Host& newHost) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Node::base(); + url += "/status"; return url; } /**/ -std::string Ark::Client::API::Paths::Node::syncing(Host& newHost) { - char url[128] = {}; - snprintf( - url, sizeof(url), - "%s%s/syncing", - newHost.toString().c_str(), - Ark::Client::API::Paths::Node::base()); +std::string Node::syncing(Host& newHost) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Node::base(); + url += "/syncing"; return url; } @@ -205,38 +234,48 @@ std::string Ark::Client::API::Paths::Node::syncing(Host& newHost) { /** * Peers **/ -const char* Ark::Client::API::Paths::Peers::base() { - return "/api/v2/peers"; +const char* Peers::base() { return "/api/peers"; } + +/**/ + +std::string Peers::get(Host& newHost, const char* ip) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Peers::base(); + url += "/"; + url += ip; + return url; } /**/ -std::string Ark::Client::API::Paths::Peers::get( - Host& newHost, - const char* const ip) { - char url[128] = {}; - snprintf( - url, sizeof(url), - "%s%s/%s", - newHost.toString().c_str(), - Ark::Client::API::Paths::Peers::base(), - ip); +std::string Peers::all(Host& newHost, const char* const query) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Peers::base(); + url += query; return url; } +/****/ + +/** + * Rounds + **/ +const char* Rounds::base() { return "/api/rounds"; } + /**/ -std::string Ark::Client::API::Paths::Peers::all( - Host& newHost, - int limit /* = 5 */, - int page /* = 1 */) { - char url[128] = {}; - snprintf( - url, sizeof(url), - "%s%s?limit=%d&page=%d", - newHost.toString().c_str(), - Ark::Client::API::Paths::Peers::base(), - limit, page); +std::string Rounds::delegates(Host& newHost, const char* roundId) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Rounds::base(); + url += "/"; + url += roundId; + url += "/delegates"; return url; } @@ -245,98 +284,92 @@ std::string Ark::Client::API::Paths::Peers::all( /** * Transactions **/ -const char* Ark::Client::API::Paths::Transactions::base() { - return "/api/v2/transactions"; +const char* Transactions::base() { return "/api/transactions"; } + +/**/ + +std::string Transactions::getUnconfirmed(Host& newHost, + const char* identifier) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Transactions::base(); + url += "/unconfirmed/"; + url += identifier; + return url; } /**/ -std::string Ark::Client::API::Paths::Transactions::getUnconfirmed( - Host& newHost, - const char* const identifier) { - char url[128] = {}; - snprintf( - url, sizeof(url), - "%s%s/unconfirmed/%s", - newHost.toString().c_str(), - Ark::Client::API::Paths::Transactions::base(), - identifier); +std::string Transactions::all(Host& newHost, const char* const query) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Transactions::base(); + url += query; return url; } /**/ -std::string Ark::Client::API::Paths::Transactions::all( - Host& newHost, - int limit /* = 5 */, - int page /* = 1 */) { - char url[128] = {}; - snprintf( - url, sizeof(url), - "%s%s?limit=%d&page=%d", - newHost.toString().c_str(), - Ark::Client::API::Paths::Transactions::base(), - limit, page); +std::string Transactions::get(Host& newHost, const char* identifier) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Transactions::base(); + url += "/"; + url += identifier; return url; } /**/ -std::string Ark::Client::API::Paths::Transactions::get( - Host& newHost, - const char* const identifier) { - char url[128] = {}; - snprintf( - url, sizeof(url), - "%s%s/%s", - newHost.toString().c_str(), - Ark::Client::API::Paths::Transactions::base(), - identifier); +std::string Transactions::allUnconfirmed(Host& newHost, + const char* const query) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Transactions::base(); + url += "/unconfirmed"; + url += query; return url; } /**/ -std::string Ark::Client::API::Paths::Transactions::allUnconfirmed( - Host& newHost, - int limit /* = 5 */, - int page /* = 1 */) { - char url[128] = {}; - snprintf( - url, sizeof(url), - "%s%s/unconfirmed?limit=%d&page=%d", - newHost.toString().c_str(), - Ark::Client::API::Paths::Transactions::base(), - limit, page); +std::string Transactions::types(Host& newHost) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Transactions::base(); + url += "/types"; return url; } /**/ -std::string Ark::Client::API::Paths::Transactions::types(Host& newHost) { - char url[128] = {}; - snprintf( - url, sizeof(url), - "%s%s/types", - newHost.toString().c_str(), - Ark::Client::API::Paths::Transactions::base()); +std::string Transactions::fees(Host& newHost) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Transactions::base(); + url += "/fees"; return url; } /**/ -std::pair Ark::Client::API::Paths::Transactions::search( +std::pair Transactions::search( Host& newHost, const std::map& bodyParameters, - int limit /* = 5 */, - int page /* = 1 */) { - char uri[96] = {}; - snprintf( - uri, sizeof(uri), - "%s%s/search?limit=%d&page=%d", - newHost.toString().c_str(), - Ark::Client::API::Paths::Transactions::base(), - limit, page); + const char* const query) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Transactions::base(); + url += "/search"; + url += query; + std::string parameterBuffer; auto count = 0UL; for (const auto& p : bodyParameters) { @@ -346,21 +379,20 @@ std::pair Ark::Client::API::Paths::Transactions::searc parameterBuffer += '&'; }; }; - return {uri, parameterBuffer.c_str()}; + return { url, parameterBuffer.c_str() }; } /**/ -std::pair Ark::Client::API::Paths::Transactions::send( +std::pair Transactions::send( Host& newHost, std::string& jsonTransaction) { - char uri[96] = {}; - snprintf( - uri, sizeof(uri), - "%s%s", - newHost.toString().c_str(), - Ark::Client::API::Paths::Transactions::base()); - return {uri, jsonTransaction.c_str()}; + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Transactions::base(); + + return { url.c_str(), jsonTransaction.c_str() }; } /****/ @@ -368,38 +400,28 @@ std::pair Ark::Client::API::Paths::Transactions::send( /** * Votes **/ -const char* Ark::Client::API::Paths::Votes::base() { - return "/api/v2/votes"; -} +const char* Votes::base() { return "/api/votes"; } /**/ -std::string Ark::Client::API::Paths::Votes::get( - Host& newHost, - const char* const identifier) { - char url[128] = {}; - snprintf( - url, sizeof(url), - "%s%s/%s", - newHost.toString().c_str(), - Ark::Client::API::Paths::Votes::base(), - identifier); +std::string Votes::get(Host& newHost, const char* identifier) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Votes::base(); + url += "/"; + url += identifier; return url; } /**/ -std::string Ark::Client::API::Paths::Votes::all( - Host& newHost, - int limit /* = 5 */, - int page /* = 1 */) { - char url[128] = {}; - snprintf( - url, sizeof(url), - "%s%s?limit=%d&page=%d", - newHost.toString().c_str(), - Ark::Client::API::Paths::Votes::base(), - limit, page); +std::string Votes::all(Host& newHost, const char* const query) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Votes::base(); + url += query; return url; } @@ -408,143 +430,120 @@ std::string Ark::Client::API::Paths::Votes::all( /** * Wallets **/ -const char* Ark::Client::API::Paths::Wallets::base() { - return "/api/v2/wallets"; -} +const char* Wallets::base() { return "/api/wallets"; } /**/ -std::string Ark::Client::API::Paths::Wallets::get( - Host& newHost, - const char* const identifier) { - char url[128] = {}; - snprintf( - url, sizeof(url), - "%s%s/%s", - newHost.toString().c_str(), - Ark::Client::API::Paths::Wallets::base(), - identifier); +std::string Wallets::get(Host& newHost, const char* identifier) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Wallets::base(); + url += "/"; + url += identifier; return url; } /**/ -std::string Ark::Client::API::Paths::Wallets::all( - Host& newHost, - int limit /* = 5 */, - int page /* = 1 */) { - char url[128] = {}; - snprintf( - url, sizeof(url), - "%s%s?limit=%d&page=%d", - newHost.toString().c_str(), - Ark::Client::API::Paths::Wallets::base(), - limit, page); +std::string Wallets::all(Host& newHost, const char* const query) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Wallets::base(); + url += query; return url; } /**/ -std::string Ark::Client::API::Paths::Wallets::top( - Host& newHost, - int limit /* = 5 */, - int page /* = 1 */) { - char url[128] = {}; - snprintf( - url, sizeof(url), - "%s%s/top?limit=%d&page=%d", - newHost.toString().c_str(), - Ark::Client::API::Paths::Wallets::base(), - limit, page); +std::string Wallets::top(Host& newHost, const char* const query) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Wallets::base(); + url += "/top"; + url += query; return url; } /**/ -std::string Ark::Client::API::Paths::Wallets::transactions( - Host& newHost, - const char* const identifier, - int limit /* = 5 */, - int page /* = 1 */) { - char url[128] = {}; - snprintf( - url, sizeof(url), - "%s%s/%s/transactions?limit=%d&page=%d", - newHost.toString().c_str(), - Ark::Client::API::Paths::Wallets::base(), - identifier, - limit, page); +std::string Wallets::transactions(Host& newHost, + const char* const identifier, + const char* const query) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Wallets::base(); + url += "/"; + url += identifier; + url += "/transactions"; + url += query; return url; } /**/ -std::string Ark::Client::API::Paths::Wallets::transactionsSent( - Host& newHost, - const char* const identifier, - int limit /* = 5 */, - int page /* = 1 */) { - char url[128] = {}; - snprintf( - url, sizeof(url), - "%s%s/%s/transactions/sent?limit=%d&page=%d", - newHost.toString().c_str(), - Ark::Client::API::Paths::Wallets::base(), - identifier, - limit, page); +std::string Wallets::transactionsSent(Host& newHost, + const char* const identifier, + const char* const query) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Wallets::base(); + url += "/"; + url += identifier; + url += "/transactions/sent"; + url += query; return url; } /**/ -std::string Ark::Client::API::Paths::Wallets::transactionsReceived( - Host& newHost, - const char* const identifier, - int limit /* = 5 */, - int page /* = 1 */) { - char url[128] = {}; - snprintf( - url, sizeof(url), - "%s%s/%s/transactions/received?limit=%d&page=%d", - newHost.toString().c_str(), - Ark::Client::API::Paths::Wallets::base(), - identifier, - limit, page); +std::string Wallets::transactionsReceived(Host& newHost, + const char* const identifier, + const char* const query) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Wallets::base(); + url += "/"; + url += identifier; + url += "/transactions/received"; + url += query; return url; } /**/ -std::string Ark::Client::API::Paths::Wallets::votes( - Host& newHost, - const char* const identifier, - int limit /* = 5 */, - int page /* = 1 */) { - char url[128] = {}; - snprintf( - url, sizeof(url), - "%s%s/%s/votes?limit=%d&page=%d", - newHost.toString().c_str(), - Ark::Client::API::Paths::Wallets::base(), - identifier, - limit, page); +std::string Wallets::votes(Host& newHost, + const char* const identifier, + const char* const query) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Wallets::base(); + url += "/"; + url += identifier; + url += "/votes"; + url += query; return url; } /**/ -std::pair Ark::Client::API::Paths::Wallets::search( +std::pair Wallets::search( Host& newHost, const std::map& bodyParameters, - int limit /* = 5 */, - int page /* = 1 */) { - char uri[96] = {}; - snprintf( - uri, sizeof(uri), - "%s%s/search?limit=%d&page=%d", - newHost.toString().c_str(), - Ark::Client::API::Paths::Wallets::base(), - limit, page); + const char* const query) { + std::string url; + url.reserve(URL_MAX_LEN); + url += newHost.toString().c_str(); + url += Wallets::base(); + url += "/search"; + url += query; + std::string parameterBuffer; auto count = 0UL; for (const auto& p : bodyParameters) { @@ -554,5 +553,10 @@ std::pair Ark::Client::API::Paths::Wallets::search( parameterBuffer += '&'; }; }; - return {uri, parameterBuffer.c_str()}; + return { url.c_str(), parameterBuffer.c_str() }; } + +} // namespace paths +} // namespace api +} // namespace Client +} // namespace Ark diff --git a/src/api/peers/peers.cpp b/src/api/peers/peers.cpp index 29a277eb..ed2d93d4 100644 --- a/src/api/peers/peers.cpp +++ b/src/api/peers/peers.cpp @@ -1,19 +1,28 @@ +/** + * This file is part of Ark Cpp Client. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ #include "api/peers/peers.h" -std::string Ark::Client::API::Peers::get( - const char *const ip) { - return http_->get(Ark::Client::API::Paths::Peers::get( - this->host_, ip).c_str()); +namespace Ark { +namespace Client { +namespace api { + +std::string Peers::get(const char* ip) { + return http_->get(paths::Peers::get(this->host_, ip).c_str()); } /**/ -std::string Ark::Client::API::Peers::all( - int limit /* = 5 */, - int page /* = 1 */ -) { - return http_->get(Ark::Client::API::Paths::Peers::all( - this->host_, - limit, page).c_str()); +std::string Peers::all(const char* const query) { + return http_->get(paths::Peers::all(this->host_, query).c_str()); } + +} // namespace api +} // namespace Client +} // namespace Ark diff --git a/src/api/rounds/rounds.cpp b/src/api/rounds/rounds.cpp new file mode 100644 index 00000000..255bca67 --- /dev/null +++ b/src/api/rounds/rounds.cpp @@ -0,0 +1,22 @@ +/** + * This file is part of Ark Cpp Client. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#include "api/rounds/rounds.h" + +namespace Ark { +namespace Client { +namespace api { + +std::string Rounds::delegates(const char* roundId) { + return http_->get(paths::Rounds::delegates(this->host_, roundId).c_str()); +} + +} // namespace api +} // namespace Client +} // namespace Ark diff --git a/src/api/transactions/transactions.cpp b/src/api/transactions/transactions.cpp index 4c2d40f8..315db222 100644 --- a/src/api/transactions/transactions.cpp +++ b/src/api/transactions/transactions.cpp @@ -1,69 +1,74 @@ +/** + * This file is part of Ark Cpp Client. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ #include "api/transactions/transactions.h" -std::string Ark::Client::API::Transactions::getUnconfirmed( - const char *const identifier) { - return http_->get(Ark::Client::API::Paths::Transactions::getUnconfirmed( - this->host_, - identifier).c_str()); +namespace Ark { +namespace Client { +namespace api { + +std::string Transactions::getUnconfirmed(const char* identifier) { + return http_->get(paths::Transactions::getUnconfirmed(this->host_, + identifier).c_str()); } /**/ -std::string Ark::Client::API::Transactions::all( - int limit /* = 5 */, - int page /* = 1 */) { - return http_->get(Ark::Client::API::Paths::Transactions::all( - this->host_, - limit, page).c_str()); +std::string Transactions::all(const char* const query) { + return http_->get(paths::Transactions::all(this->host_, query).c_str()); } /**/ -std::string Ark::Client::API::Transactions::get( - const char *const identifier) { - return http_->get(Ark::Client::API::Paths::Transactions::get( - this->host_, - identifier).c_str()); +std::string Transactions::get(const char* identifier) { + return http_->get(paths::Transactions::get(this->host_, identifier).c_str()); } /**/ -std::string Ark::Client::API::Transactions::allUnconfirmed( - int limit /* = 5 */, - int page /* =1 */) { - return http_->get(Ark::Client::API::Paths::Transactions::allUnconfirmed( - this->host_, - limit, page).c_str()); +std::string Transactions::allUnconfirmed(const char* const query) { + return http_->get(paths::Transactions::allUnconfirmed(this->host_, + query).c_str()); } /**/ -std::string Ark::Client::API::Transactions::types() { - return http_->get(Ark::Client::API::Paths::Transactions::types( - this->host_).c_str()); +std::string Transactions::types() { + return http_->get(paths::Transactions::types(this->host_).c_str()); } + /**/ -std::string Ark::Client::API::Transactions::search( +std::string Transactions::fees() { + return http_->get(paths::Transactions::fees(this->host_).c_str()); +} + +/**/ + +std::string Transactions::search( const std::map &bodyParameters, - int limit /* = 5 */, - int page /* = 1 */) { - const auto searchPathPair = Ark::Client::API::Paths::Transactions::search( - this->host_, - bodyParameters, - limit, page); - return http_->post(searchPathPair.first.c_str(), searchPathPair.second.c_str()); + const char* const query) { + const auto searchPathPair = paths::Transactions::search(this->host_, + bodyParameters, + query); + return http_->post(searchPathPair.first.c_str(), + searchPathPair.second.c_str()); } /**/ -std::string Ark::Client::API::Transactions::send( - std::string& jsonTransaction) { - const auto pathPair = Ark::Client::API::Paths::Transactions::send( - this->host_, - jsonTransaction); +std::string Transactions::send(std::string& jsonTransaction) { + const auto pathPair = paths::Transactions::send(this->host_, jsonTransaction); return http_->post(pathPair.first.c_str(), pathPair.second.c_str()); -}; +} +} // namespace api +} // namespace Client +} // namespace Ark diff --git a/src/api/votes/votes.cpp b/src/api/votes/votes.cpp index 74478336..75f88195 100644 --- a/src/api/votes/votes.cpp +++ b/src/api/votes/votes.cpp @@ -1,19 +1,28 @@ +/** + * This file is part of Ark Cpp Client. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ #include "api/votes/votes.h" -std::string Ark::Client::API::Votes::get( - const char *const identifier) { - return http_->get(Ark::Client::API::Paths::Votes::get( - this->host_, - identifier).c_str()); +namespace Ark { +namespace Client { +namespace api { + +std::string Votes::get(const char* identifier) { + return http_->get(paths::Votes::get(this->host_, identifier).c_str()); } /**/ -std::string Ark::Client::API::Votes::all( - int limit /* = 5 */, - int page /* = 1 */) { - return http_->get(Ark::Client::API::Paths::Votes::all( - this->host_, - limit, page).c_str()); +std::string Votes::all(const char* const query) { + return http_->get(paths::Votes::all(this->host_, query).c_str()); } + +} // namespace api +} // namespace Client +} // namespace Ark diff --git a/src/api/wallets/wallets.cpp b/src/api/wallets/wallets.cpp index e7cdebbd..c2f8e2e5 100644 --- a/src/api/wallets/wallets.cpp +++ b/src/api/wallets/wallets.cpp @@ -1,89 +1,82 @@ +/** + * This file is part of Ark Cpp Client. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ #include "api/wallets/wallets.h" -std::string Ark::Client::API::Wallets::get( - const char *const identifier) { - return http_->get(Ark::Client::API::Paths::Wallets::get( - this->host_, - identifier).c_str()); +namespace Ark { +namespace Client { +namespace api { + +std::string Wallets::get(const char* identifier) { + return http_->get(paths::Wallets::get(this->host_, identifier).c_str()); } /**/ -std::string Ark::Client::API::Wallets::all( - int limit /* = 5 */, - int page /* = 1 */) { - return http_->get(Ark::Client::API::Paths::Wallets::all( - this->host_, - limit, page).c_str()); +std::string Wallets::all(const char* const query) { + return http_->get(paths::Wallets::all(this->host_, query).c_str()); } /**/ -std::string Ark::Client::API::Wallets::top( - int limit /* = 5 */, - int page /* = 1 */) { - return http_->get(Ark::Client::API::Paths::Wallets::top( - this->host_, - limit, page).c_str()); +std::string Wallets::top(const char* const query) { + return http_->get(paths::Wallets::top(this->host_, query).c_str()); } /**/ -std::string Ark::Client::API::Wallets::transactions( - const char *const identifier, - int limit /* = 5 */, - int page /* = 1 */) { - return http_->get(Ark::Client::API::Paths::Wallets::transactions( - this->host_, - identifier, - limit, page).c_str()); +std::string Wallets::transactions(const char *const identifier, + const char* const query) { + return http_->get(paths::Wallets::transactions(this->host_, + identifier, + query).c_str()); } /**/ -std::string Ark::Client::API::Wallets::transactionsSent( - const char *const identifier, - int limit /* = 5 */, - int page /* = 1 */) { - return http_->get(Ark::Client::API::Paths::Wallets::transactionsSent( - this->host_, - identifier, - limit, page).c_str()); +std::string Wallets::transactionsSent(const char *const identifier, + const char* const query) { + return http_->get(paths::Wallets::transactionsSent(this->host_, + identifier, + query).c_str()); } /**/ -std::string Ark::Client::API::Wallets::transactionsReceived( - const char *const identifier, - int limit /* = 5 */, - int page /* = 1 */) { - return http_->get(Ark::Client::API::Paths::Wallets::transactionsReceived( - this->host_, - identifier, - limit, page).c_str()); +std::string Wallets::transactionsReceived(const char *const identifier, + const char* const query) { + return http_->get(paths::Wallets::transactionsReceived(this->host_, + identifier, + query).c_str()); } /**/ -std::string Ark::Client::API::Wallets::votes( - const char *const identifier, - int limit /* = 5 */, - int page /* = 1 */) { - return http_->get(Ark::Client::API::Paths::Wallets::votes( - this->host_, - identifier, limit, page).c_str()); +std::string Wallets::votes(const char *const identifier, + const char* const query) { + return http_->get(paths::Wallets::votes(this->host_, + identifier, + query).c_str()); } /**/ -std::string Ark::Client::API::Wallets::search( +std::string Wallets::search( const std::map &bodyParameters, - int limit /* = 5 */, - int page /* = 1 */) { - const auto searchPathPair = Ark::Client::API::Paths::Wallets::search( - this->host_, - bodyParameters, - limit, page); - return http_->post(searchPathPair.first.c_str(), searchPathPair.second.c_str()); + const char* const query) { + const auto searchPathPair = paths::Wallets::search(this->host_, + bodyParameters, + query); + return http_->post(searchPathPair.first.c_str(), + searchPathPair.second.c_str()); } + +} // namespace api +} // namespace Client +} // namespace Ark diff --git a/src/host/host.cpp b/src/host/host.cpp index 583613d2..4acd3efe 100644 --- a/src/host/host.cpp +++ b/src/host/host.cpp @@ -1,50 +1,49 @@ +/** + * This file is part of Ark Cpp Client. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + #include "host/host.h" -#include +#include #include -Ark::Client::Host::Host() : ip_(), port_(-1) {} +namespace Ark { +namespace Client { -/**/ - -Ark::Client::Host::Host( - const char* const newIP, - int newPort) : port_(newPort) { - strncpy(this->ip_, newIP, sizeof(this->ip_)); -} +Host::Host(const char* ip, int port) : ip_(ip), port_(port) {} /**/ -bool Ark::Client::Host::set( - const char* const newIP, - int newPort) { - strncpy(this->ip_, newIP, sizeof(this->ip_)); - this->port_ = newPort; - return - ((this->port_ == newPort) - && (strcmp(this->ip_, newIP) != 0)); +bool Host::set(const char* ip, int port) { + this->ip_.reserve(IP_MAX_STRING_LEN); + this->ip_ += ip; + this->port_ = port; + return this->port_ == port && this->ip_ == ip; } /**/ -std::string Ark::Client::Host::ip() const noexcept { - return this->ip_; -}; +std::string Host::ip() const noexcept { return this->ip_; }; /**/ -int Ark::Client::Host::port() const noexcept { - return this->port_; -}; +int Host::port() const noexcept { return this->port_; }; /**/ -std::string Ark::Client::Host::toString() { - char temp[36] = {}; - snprintf( - temp, - sizeof(this->ip_) + sizeof(this->port_), - "%s:%d", - this->ip_, this->port_); - return temp; +std::string Host::toString() { + std::string out; + out.reserve(IP_MAX_STRING_LEN + PORT_MAX_STRING_LEN); + out += (this->ip_); + out += ":"; + snprintf(&out[out.length()], PORT_MAX_STRING_LEN, "%d", this->port_); + return out; } + +} // namespace Client +} // namespace Ark diff --git a/src/http/iot/http.cpp b/src/http/iot/http.cpp index 99c9c4e2..8b26c490 100644 --- a/src/http/iot/http.cpp +++ b/src/http/iot/http.cpp @@ -1,3 +1,12 @@ +/** + * This file is part of Ark Cpp Client. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + #include "http/http.h" #include #include @@ -12,85 +21,70 @@ namespace Ark { namespace Client { namespace { -/** - * - **/ + class PlatformHTTP : public AbstractHTTP { public: PlatformHTTP() = default; - /**/ - - int tryConnection( - HTTPClient &httpClient, - const char *const request - ) { - if (!httpClient.begin(request)) - { /* Bad HTTP begin */ - return -1; - } - int code = httpClient.GET(); - int count = 0; - while (code != HTTP_CODE_OK) - { //error - httpClient.end(); - if (count >=2) - { /* Bad connection. Try another peer */ - return code; - }; - /* Bad HTTP GET.\nRetrying connection.. */ - delay(1000); - httpClient.addHeader("Content-Type", "application/json"); - httpClient.begin(request); - code = httpClient.GET(); - count++; - } - return code; + int tryConnection(HTTPClient &httpClient, const char* request ) { + if (!httpClient.begin(request)) { + return -1; + }; + int code = httpClient.GET(); + int count = 0; + while (code != HTTP_CODE_OK) { + httpClient.end(); + if (count >=2) { + return code; + }; + delay(1000); + httpClient.addHeader("Content-Type", "application/json"); + httpClient.begin(request); + code = httpClient.GET(); + count++; } + return code; + } /**/ - // Arduino's HTTPClient requires that a single-line HTTP request string begins with 'http://'. - // This is only a consideration on IoT platforms. - inline std::string toHttpStr(const char *const request) { - // char[7 (size of char string "http://") + 'request' string-length + 1 (for the null terminator '\0')] - char httpRequest[7 + std::strlen(request) + 1]; - snprintf(httpRequest, sizeof(httpRequest), "http://%s%c", request, '\0'); - return httpRequest; - } + // Arduino's HTTPClient requires that a single-line HTTP request string begins with 'http://'. + // This is only a consideration on IoT platforms. + inline std::string toHttpStr(const char* request) { + // char[7 (size of char string "http://") + 'request' string-length + 1 (for the null terminator '\0')] + size_t length = 0; + while (request[length] != 0) { length++; }; + char httpRequest[7 + length + 1]; + snprintf(httpRequest, length, "http://%s%c", request, '\0'); + return httpRequest; + } - /**/ + /**/ - std::string get( - const char *const request - ) override { - HTTPClient httpClient; - httpClient.setReuse(false); - httpClient.setTimeout(3000); - if (int code = tryConnection(httpClient, toHttpStr(request).c_str()) != 200) - { /* error */ - return httpClient.errorToString(-code).c_str(); // <- note `-` symbol. - } - return httpClient.getString().c_str(); + std::string get(const char* request) override { + HTTPClient httpClient; + httpClient.setReuse(false); + httpClient.setTimeout(3000); + if (int code = tryConnection(httpClient, + toHttpStr(request).c_str()) != 200) { + return httpClient.errorToString(-code).c_str(); // <- note `-` symbol. } + return httpClient.getString().c_str(); + } /**/ - std::string post( - const char *const request, - const char *body - ) override { - HTTPClient httpClient; - httpClient.setReuse(true); - httpClient.setTimeout(3000); - httpClient.begin(toHttpStr(request).c_str()); - httpClient.addHeader("Content-Type", "application/json"); - httpClient.POST(body); - return httpClient.getString().c_str(); - } - /**/ + std::string post(const char* request, const char *body) override { + HTTPClient httpClient; + httpClient.setReuse(true); + httpClient.setTimeout(3000); + httpClient.begin(toHttpStr(request).c_str()); + httpClient.addHeader("Content-Type", "application/json"); + httpClient.POST(body); + return httpClient.getString().c_str(); + } }; -/**/ + } // namespace /** @@ -99,6 +93,6 @@ class PlatformHTTP : public AbstractHTTP { std::unique_ptr makeHTTP() { return std::unique_ptr(new PlatformHTTP()); } -/**/ + } // namespace Client } // namespace Ark diff --git a/src/http/iot/main.cpp b/src/http/iot/main.cpp index dcae0526..5e2daae8 100644 --- a/src/http/iot/main.cpp +++ b/src/http/iot/main.cpp @@ -1,3 +1,12 @@ +/** + * This file is part of Ark Cpp Client. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + #include "helpers/client_helpers.h" #if (defined PLATFORMIO && !defined UNIT_TEST) diff --git a/src/http/os/http.cpp b/src/http/os/http.cpp index 00838433..7529320c 100644 --- a/src/http/os/http.cpp +++ b/src/http/os/http.cpp @@ -1,3 +1,12 @@ +/** + * This file is part of Ark Cpp Client. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + #include "http/http.h" #include "helpers/client_helpers.h" @@ -10,16 +19,13 @@ namespace Ark { namespace Client { -namespace { +namespace { // NOLINT class PlatformHTTP : public AbstractHTTP { public: PlatformHTTP() = default; - /**/ - - static size_t WriteCallback(void *contents, size_t size, size_t nmemb, - void *userp) { + static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) { // https://curl.haxx.se/libcurl/c/CURLOPT_WRITEFUNCTION.html ((std::string *)userp)->append((char *)contents, size * nmemb); return size * nmemb; @@ -27,36 +33,35 @@ class PlatformHTTP : public AbstractHTTP { /**/ - std::string get( - const char *const request - ) override { - CURL *curl; - CURLcode res; - std::string readBuffer; - - curl = curl_easy_init(); - if (curl != nullptr) { - curl_easy_setopt(curl, CURLOPT_URL, request); - - curl_slist *header_list = nullptr; - header_list = curl_slist_append(header_list, "Content-Type: application/json"); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list); - - /* skip https verification */ - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); - - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); - res = curl_easy_perform(curl); - curl_slist_free_all(header_list); - curl_easy_cleanup(curl); - } - return readBuffer; + std::string get(const char* request) override { + CURL *curl; + CURLcode res; + std::string readBuffer; + + curl = curl_easy_init(); + if (curl != nullptr) { + curl_easy_setopt(curl, CURLOPT_URL, request); + + curl_slist *header_list = nullptr; + header_list = curl_slist_append(header_list, "Content-Type: application/json"); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list); + + /* skip https verification */ + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); + curl_easy_perform(curl); + curl_slist_free_all(header_list); + curl_easy_cleanup(curl); } + return readBuffer; + } + /**/ - std::string post(const char *const request, const char *body) override { + std::string post(const char* request, const char *body) override { // https://curl.haxx.se/libcurl/c/http-post.html CURL *curl; CURLcode res; @@ -65,8 +70,8 @@ class PlatformHTTP : public AbstractHTTP { curl_global_init(CURL_GLOBAL_ALL); curl = curl_easy_init(); if (curl != nullptr) { - curl_easy_setopt(curl, CURLOPT_URL, request); // Set the URL that is about to receive our POST - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body); // Now specify the POST json data ex: "username=baldninja" + curl_easy_setopt(curl, CURLOPT_URL, request); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body); /* set the header content-type */ curl_slist *header_list = nullptr; @@ -79,17 +84,18 @@ class PlatformHTTP : public AbstractHTTP { curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); - res = curl_easy_perform(curl); // Perform the request, res will get the return code - if (res != CURLE_OK) { // Check for errors + res = curl_easy_perform(curl); + if (res != CURLE_OK) { fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); - } - curl_easy_cleanup(curl); /* always cleanup */ - } + }; + /* always cleanup */ + curl_easy_cleanup(curl); + }; curl_global_cleanup(); return readBuffer; }; }; -/**/ + } // namespace /** @@ -98,7 +104,7 @@ class PlatformHTTP : public AbstractHTTP { std::unique_ptr makeHTTP() { return std::unique_ptr(new PlatformHTTP()); } -/**/ + } // namespace Client } // namespace Ark diff --git a/src/include/cpp-client/api/abstract.h b/src/include/cpp-client/api/abstract.h index d415cd42..dbb4adc4 100644 --- a/src/include/cpp-client/api/abstract.h +++ b/src/include/cpp-client/api/abstract.h @@ -15,24 +15,24 @@ namespace Ark { namespace Client { -namespace API { -/** - * Ark::Client::API::Abstract - **/ +namespace api { + class Abstract { -protected: + public: + void setHost(const char* newHost, int newPort) { + this->host_.set(newHost, newPort); + }; + + protected: Host host_; std::unique_ptr http_; Abstract() : http_(makeHTTP()) {} explicit Abstract(IHTTP* http) : http_(http) {} - -public: - void setHost(const char* const newHost, int newPort) { this->host_.set(newHost, newPort); }; }; -/**/ -}; // namespace API -}; // namespace Client -}; // namespace Ark + +} // namespace api +} // namespace Client +} // namespace Ark #endif diff --git a/src/include/cpp-client/api/api.h b/src/include/cpp-client/api/api.h index f7058a14..6acddcf0 100644 --- a/src/include/cpp-client/api/api.h +++ b/src/include/cpp-client/api/api.h @@ -12,39 +12,44 @@ #include "api/abstract.h" #include "api/api.h" +#include "api/blockchain/blockchain.hpp" #include "api/blocks/blocks.h" #include "api/delegates/delegates.h" #include "api/node/node.h" #include "api/peers/peers.h" +#include "api/rounds/rounds.h" #include "api/transactions/transactions.h" #include "api/votes/votes.h" #include "api/wallets/wallets.h" namespace Ark { namespace Client { -/**/ -class Api : public API::Abstract { -public: - API::Blocks blocks; - API::Delegates delegates; - API::Node node; - API::Peers peers; - API::Transactions transactions; - API::Votes votes; - API::Wallets wallets; - Api() - : API::Abstract(), - blocks(host_, *http_), - delegates(host_, *http_), - node(host_, *http_), - peers(host_, *http_), - transactions(host_, *http_), - votes(host_, *http_), - wallets(host_, *http_) {} +class Api : public api::Abstract { + public: + api::Blockchain blockchain; + api::Blocks blocks; + api::Delegates delegates; + api::Node node; + api::Peers peers; + api::Rounds rounds; + api::Transactions transactions; + api::Votes votes; + api::Wallets wallets; + + Api() : Abstract(), + blockchain(host_, *http_), + blocks(host_, *http_), + delegates(host_, *http_), + node(host_, *http_), + peers(host_, *http_), + rounds(host_, *http_), + transactions(host_, *http_), + votes(host_, *http_), + wallets(host_, *http_) {} }; -/**/ -}; // namespace Client -}; // namespace Ark + +} // namespace Client +} // namespace Ark #endif diff --git a/src/include/cpp-client/api/base.h b/src/include/cpp-client/api/base.h index 1f3c2df7..c1cec957 100644 --- a/src/include/cpp-client/api/base.h +++ b/src/include/cpp-client/api/base.h @@ -15,21 +15,20 @@ namespace Ark { namespace Client { -namespace API { -/** - * Ark::Client::API::Base - **/ +namespace api { + class Base { -protected: + protected: Host& host_; IHTTP* http_; template - explicit Base(Host& host, HTTPType& http) : host_(host), http_(static_cast(&http)) {} + explicit Base(Host& host, HTTPType& http) + : host_(host), http_(static_cast(&http)) {} }; -/**/ -}; // namespace API -}; // namespace Client -}; // namespace Ark + +} // namespace api +} // namespace Client +} // namespace Ark #endif diff --git a/src/include/cpp-client/api/blockchain/blockchain.hpp b/src/include/cpp-client/api/blockchain/blockchain.hpp new file mode 100644 index 00000000..3511b728 --- /dev/null +++ b/src/include/cpp-client/api/blockchain/blockchain.hpp @@ -0,0 +1,45 @@ +/** + * This file is part of Ark Cpp Client. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#ifndef BLOCKCHAIN_HPP +#define BLOCKCHAIN_HPP + +#include "api/base.h" +#include "api/paths.h" + +#include + +namespace Ark { +namespace Client { +namespace api { + +class IBlockchain : public api::Base { + public: + virtual ~IBlockchain() {} + + virtual std::string get() = 0; + +protected: + IBlockchain(Host& host, IHTTP& http) : api::Base(host, http) {} +}; + +/**/ + +class Blockchain : public IBlockchain { + public: + Blockchain(Host& host, IHTTP& http) : IBlockchain(host, http) {} + + std::string get() override; +}; + +} // namespace api +} // namespace Client +} // namespace Ark + +#endif diff --git a/src/include/cpp-client/api/blocks/blocks.h b/src/include/cpp-client/api/blocks/blocks.h index f684b9ce..9b1f11a5 100644 --- a/src/include/cpp-client/api/blocks/blocks.h +++ b/src/include/cpp-client/api/blocks/blocks.h @@ -10,46 +10,42 @@ #ifndef BLOCKS_H #define BLOCKS_H -#include "api/base.h" -#include "api/paths.h" - #include #include +#include "api/base.h" +#include "api/paths.h" + namespace Ark { namespace Client { -namespace API { -/**/ -class IBlocks : public API::Base { -protected: - IBlocks(Host& host, IHTTP& http) : API::Base(host, http) {} +namespace api { // NOLINT -public: +class IBlocks : public Base { + public: virtual ~IBlocks() {} virtual std::string get(const char* const blockId) = 0; - virtual std::string all(int limit = 5, int page = 1) = 0; + virtual std::string all(const char* const query) = 0; virtual std::string transactions(const char* const blockId) = 0; - virtual std::string search( - const std::map& bodyParameters, - int limit = 5, - int page = 1) = 0; + virtual std::string search(const std::map& bodyParameters, const char* const query) = 0; + + protected: + IBlocks(Host& host, IHTTP& http) : Base(host, http) {} }; + /**/ -class Blocks : public IBlocks { -public: + +class Blocks : public IBlocks { + public: Blocks(Host& host, IHTTP& http) : IBlocks(host, http) {} std::string get(const char* const blockId) override; - std::string all(int limit = 5, int page = 1) override; + std::string all(const char* const query) override; std::string transactions(const char* const blockId) override; - std::string search( - const std::map& bodyParameters, - int limit = 5, - int page = 1) override; + std::string search(const std::map& bodyParameters, const char* const query) override; }; -/**/ -}; // namespace API -}; // namespace Client -}; // namespace Ark + +} // namespace api +} // namespace Client +} // namespace Ark #endif diff --git a/src/include/cpp-client/api/delegates/delegates.h b/src/include/cpp-client/api/delegates/delegates.h index 5eeb80d0..00071192 100644 --- a/src/include/cpp-client/api/delegates/delegates.h +++ b/src/include/cpp-client/api/delegates/delegates.h @@ -15,33 +15,35 @@ namespace Ark { namespace Client { -namespace API { -/**/ -class IDelegates : public API::Base { -protected: - IDelegates(Host &host, IHTTP &http) : API::Base(host, http) {} +namespace api { // NOLINT -public: +class IDelegates : public Base { + public: virtual ~IDelegates() {} virtual std::string get(const char *const identifier) = 0; - virtual std::string all(int limit = 5, int page = 1) = 0; - virtual std::string blocks(const char *const identifier, int limit = 5, int page = 1) = 0; - virtual std::string voters(const char *const identifier, int limit = 5, int page = 1) = 0; + virtual std::string all(const char* const query) = 0; + virtual std::string blocks(const char *const identifier, const char* const query) = 0; + virtual std::string voters(const char *const identifier, const char* const query) = 0; + + protected: + IDelegates(Host &host, IHTTP &http) : Base(host, http) {} }; + /**/ + class Delegates : public IDelegates { -public: + public: Delegates(Host &host, IHTTP &http) : IDelegates(host, http) {} std::string get(const char *const identifier) override; - std::string all(int limit = 5, int page = 1) override; - std::string blocks(const char *const identifier, int limit = 5, int page = 1) override; - std::string voters(const char *const identifier, int limit = 5, int page = 1) override; + std::string all(const char* const query) override; + std::string blocks(const char *const identifier, const char* const query) override; + std::string voters(const char *const identifier, const char* const query) override; }; -/**/ -}; // namespace API -}; // namespace Client -}; // namespace Ark + +} // namespace api +} // namespace Client +} // namespace Ark #endif diff --git a/src/include/cpp-client/api/node/node.h b/src/include/cpp-client/api/node/node.h index 0a877bdd..bc2ab2d2 100644 --- a/src/include/cpp-client/api/node/node.h +++ b/src/include/cpp-client/api/node/node.h @@ -15,31 +15,37 @@ namespace Ark { namespace Client { -namespace API { -/**/ -class INode : public API::Base { -protected: - INode(Host& host, IHTTP& http) : API::Base(host, http) {} +namespace api { -public: +class INode : public Base { + public: virtual ~INode() {} virtual std::string configuration() = 0; + virtual std::string crypto() = 0; + virtual std::string fees(const char* const query) = 0; virtual std::string status() = 0; virtual std::string syncing() = 0; + + protected: + INode(Host& host, IHTTP& http) : Base(host, http) {} }; + /**/ + class Node : public INode { -public: + public: Node(Host& host, IHTTP& http) : INode(host, http) {} std::string configuration() override; + std::string crypto() override; + std::string fees(const char* const query) override; std::string status() override; std::string syncing() override; }; -/**/ -}; // namespace API -}; // namespace Client -}; // namespace Ark + +} // namespace api +} // namespace Client +} // namespace Ark #endif diff --git a/src/include/cpp-client/api/paths.h b/src/include/cpp-client/api/paths.h index fe9ecabe..97bc407e 100644 --- a/src/include/cpp-client/api/paths.h +++ b/src/include/cpp-client/api/paths.h @@ -10,139 +10,116 @@ #ifndef PATHS_H #define PATHS_H -#include "host/host.h" - #include #include #include +#include "host/host.h" + namespace Ark { namespace Client { -namespace API { -namespace Paths { +namespace api { +namespace paths { // NOLINT -namespace Blocks { -extern const char* base(); -/***/ -extern std::string get(Host& newHost, const char* const blockId); -/***/ -extern std::string all(Host& newHost, int limit = 5, int page = 1); -/***/ -extern std::string transactions(Host& newHost, const char* const blockId); -/***/ -extern std::pair search( - Host& newHost, - const std::map& bodyParameters, - int limit = 5, - int page = 1); -/***/ -}; // namespace Blocks +static const char* DEFAULT_QUERY = "?page=1&limit=5"; +static const char* DEFAULT_DAYS_QUERY = "?days=7"; -/***/ +struct Blockchain { + static const char* base(); + static std::string get(Host& newHost); +}; -namespace Delegates { -extern const char* base(); -/***/ -extern std::string get(Host& newHost, const char* const identifier); /***/ -extern std::string all(Host& newHost, int limit = 5, int page = 1); -/***/ -extern std::string blocks(Host& newHost, const char* const identifier, int limit = 5, int page = 1); -/***/ -extern std::string voters(Host& newHost, const char* const identifier, int limit = 5, int page = 1); -/***/ -}; // namespace Delegates -/***/ +struct Blocks { + static const char* base(); + static std::string get(Host& newHost, const char* const blockId); + static std::string all(Host& newHost, const char* const query = DEFAULT_QUERY); + static std::string transactions(Host& newHost, const char* const blockId); + static std::pair search(Host& newHost, + const std::map& bodyParameters, + const char* const query = DEFAULT_QUERY); +}; -namespace Node { -extern const char* base(); -/***/ -extern std::string configuration(Host& newHost); -/***/ -extern std::string status(Host& newHost); /***/ -extern std::string syncing(Host& newHost); -/***/ -}; // namespace Node -/***/ +struct Delegates { + static const char* base(); + static std::string get(Host& newHost, const char* const identifier); + static std::string all(Host& newHost, const char* const query = DEFAULT_QUERY); + static std::string blocks(Host& newHost, const char* const identifier, const char* const query = DEFAULT_QUERY); + static std::string voters(Host& newHost, const char* const identifier, const char* const query = DEFAULT_QUERY); +}; -namespace Peers { -extern const char* base(); -/***/ -extern std::string get(Host& newHost, const char* const ip); /***/ -extern std::string all(Host& newHost, int limit = 5, int page = 1); -/***/ -}; // namespace Peers -/***/ +struct Node { + static const char* base(); + static std::string configuration(Host& newHost); + static std::string crypto(Host& newHost); + static std::string fees(Host& newHost, const char* const query = DEFAULT_DAYS_QUERY); + static std::string status(Host& newHost); + static std::string syncing(Host& newHost); +}; -namespace Transactions { -extern const char* base(); /***/ -extern std::string getUnconfirmed(Host& newHost, const char* const identifier); -/***/ -extern std::string all(Host& newHost, int limit = 5, int page = 1); -/***/ -extern std::string get(Host& newHost, const char* const identifier); -/***/ -extern std::string allUnconfirmed(Host& newHost, int limit = 5, int page = 1); -/***/ -extern std::string types(Host& newHost); -/***/ -extern std::pair search( - Host& newHost, - const std::map& bodyParameters, - int limit = 5, - int page = 1); -/***/ -extern std::pair send(Host& newHost, std::string& jsonTransaction); -/***/ -}; // namespace Transactions -/***/ +struct Peers { + static const char* base(); + static std::string get(Host& newHost, const char* const ip); + static std::string all(Host& newHost, const char* const query = DEFAULT_QUERY); +}; -namespace Votes { -extern const char* base(); -/***/ -extern std::string get(Host& newHost, const char* const identifier); /***/ -extern std::string all(Host& newHost, int limit = 5, int page = 1); -/***/ -}; // namespace Votes -/***/ +struct Rounds { + static const char* base(); + static std::string delegates(Host& newHost, const char* const roundId); +}; -namespace Wallets { -extern const char* base(); /***/ -extern std::string get(Host& newHost, const char* const identifier); -/***/ -extern std::string all(Host& newHost, int limit = 5, int page = 1); -/***/ -extern std::string top(Host& newHost, int limit = 5, int page = 1); -/***/ -extern std::string transactions(Host& newHost, const char* const identifier, int limit = 5, int page = 1); -/***/ -extern std::string transactionsSent(Host& newHost, const char* const identifier, int limit = 5, int page = 1); -/***/ -extern std::string transactionsReceived(Host& newHost, const char* const identifier, int limit = 5, int page = 1); -/***/ -extern std::string votes(Host& newHost, const char* const identifier, int limit = 5, int page = 1); + +struct Transactions { + static const char* base(); + static std::string getUnconfirmed(Host& newHost, const char* const identifier); + static std::string all(Host& newHost, const char* const query = DEFAULT_QUERY); + static std::string get(Host& newHost, const char* const identifier); + static std::string allUnconfirmed(Host& newHost, const char* const query = DEFAULT_QUERY); + static std::string types(Host& newHost); + static std::string fees(Host& newHost); + static std::pair search(Host& newHost, + const std::map& bodyParameters, + const char* const query = DEFAULT_QUERY); + static std::pair send(Host& newHost, std::string& jsonTransaction); +}; + /***/ -extern std::pair search( - Host& newHost, - const std::map& bodyParameters, - int limit = 5, - int page = 1); + +struct Votes { + static const char* base(); + static std::string get(Host& newHost, const char* const identifier); + static std::string all(Host& newHost, const char* const query = DEFAULT_QUERY); +}; + /***/ -}; // namespace Wallets -}; // namespace Paths -}; // namespace API -}; // namespace Client -}; // namespace Ark +struct Wallets { + static const char* base(); + static std::string get(Host& newHost, const char* const identifier); + static std::string all(Host& newHost, const char* const query = DEFAULT_QUERY); + static std::string top(Host& newHost, const char* const query = DEFAULT_QUERY); + static std::string transactions(Host& newHost, const char* const identifier, const char* const query = DEFAULT_QUERY); + static std::string transactionsSent(Host& newHost, const char* const identifier, const char* const query = DEFAULT_QUERY); + static std::string transactionsReceived(Host& newHost, const char* const identifier, const char* const query = DEFAULT_QUERY); + static std::string votes(Host& newHost, const char* const identifier, const char* const query = DEFAULT_QUERY); + static std::pair search(Host& newHost, + const std::map& bodyParameters, + const char* const query = DEFAULT_QUERY); +}; + +} // namespace paths +} // namespace api +} // namespace Client +} // namespace Ark #endif diff --git a/src/include/cpp-client/api/peers/peers.h b/src/include/cpp-client/api/peers/peers.h index 8befe345..007d543a 100644 --- a/src/include/cpp-client/api/peers/peers.h +++ b/src/include/cpp-client/api/peers/peers.h @@ -15,29 +15,31 @@ namespace Ark { namespace Client { -namespace API { -/**/ -class IPeers : public API::Base { -protected: - IPeers(Host& host, IHTTP& http) : API::Base(host, http) {} +namespace api { -public: +class IPeers : public Base { + public: virtual ~IPeers() {} virtual std::string get(const char* const ip) = 0; - virtual std::string all(int limit = 5, int page = 1) = 0; + virtual std::string all(const char* const query) = 0; + + protected: + IPeers(Host& host, IHTTP& http) : Base(host, http) {} }; + /**/ + class Peers : public IPeers { -public: + public: Peers(Host& host, IHTTP& http) : IPeers(host, http) {} std::string get(const char* const ip) override; - std::string all(int limit = 5, int page = 1) override; + std::string all(const char* const query) override; }; -/**/ -}; // namespace API -}; // namespace Client -}; // namespace Ark + +} // namespace api +} // namespace Client +} // namespace Ark #endif diff --git a/src/include/cpp-client/api/rounds/rounds.h b/src/include/cpp-client/api/rounds/rounds.h new file mode 100644 index 00000000..51e073dd --- /dev/null +++ b/src/include/cpp-client/api/rounds/rounds.h @@ -0,0 +1,45 @@ +/** + * This file is part of Ark Cpp Client. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#ifndef ROUNDS_H +#define ROUNDS_H + +#include +#include + +#include "api/base.h" +#include "api/paths.h" + +namespace Ark { +namespace Client { +namespace api { // NOLINT + +class IRounds : public Base { + public: + virtual ~IRounds() {} + virtual std::string delegates(const char* const roundId) = 0; + + protected: + IRounds(Host& host, IHTTP& http) : Base(host, http) {} +}; + +/**/ + +class Rounds : public IRounds { + public: + Rounds(Host& host, IHTTP& http) : IRounds(host, http) {} + + std::string delegates(const char* const roundId) override; +}; + +} // namespace api +} // namespace Client +} // namespace Ark + +#endif diff --git a/src/include/cpp-client/api/transactions/transactions.h b/src/include/cpp-client/api/transactions/transactions.h index de11d26f..1859448e 100644 --- a/src/include/cpp-client/api/transactions/transactions.h +++ b/src/include/cpp-client/api/transactions/transactions.h @@ -18,39 +18,43 @@ namespace Ark { namespace Client { -namespace API { -/**/ -class ITransactions : public API::Base { -protected: - ITransactions(Host& host, IHTTP& http) : API::Base(host, http) {} +namespace api { // NOLINT -public: +class ITransactions : public Base { + public: virtual ~ITransactions() {} virtual std::string getUnconfirmed(const char* const identifier) = 0; virtual std::string get(const char* const identifier) = 0; - virtual std::string all(int limit = 5, int page = 1) = 0; - virtual std::string allUnconfirmed(int limit = 2, int page = 1) = 0; + virtual std::string all(const char* const query) = 0; + virtual std::string allUnconfirmed(const char* const query) = 0; virtual std::string types() = 0; - virtual std::string search(const std::map& bodyParameters, int limit = 5, int page = 1) = 0; + virtual std::string fees() = 0; + virtual std::string search(const std::map& bodyParameters, const char* const query) = 0; virtual std::string send(std::string& jsonTransaction) = 0; + + protected: + ITransactions(Host& host, IHTTP& http) : Base(host, http) {} }; + /**/ + class Transactions : public ITransactions { -public: + public: Transactions(Host& host, IHTTP& http) : ITransactions(host, http) {} std::string getUnconfirmed(const char* const identifier) override; std::string get(const char* const identifier) override; - std::string all(int limit = 5, int page = 1) override; - std::string allUnconfirmed(int limit = 2, int page = 1) override; + std::string all(const char* const query) override; + std::string allUnconfirmed(const char* const query) override; std::string types() override; - std::string search(const std::map& bodyParameters, int limit = 5, int page = 1) override; + std::string fees() override; + std::string search(const std::map& bodyParameters, const char* const query) override; std::string send(std::string& jsonTransaction) override; }; -/**/ -}; // namespace API -}; // namespace Client -}; // namespace Ark + +} // namespace api +} // namespace Client +} // namespace Ark #endif diff --git a/src/include/cpp-client/api/votes/votes.h b/src/include/cpp-client/api/votes/votes.h index 986c34c9..1e3892f6 100644 --- a/src/include/cpp-client/api/votes/votes.h +++ b/src/include/cpp-client/api/votes/votes.h @@ -15,29 +15,31 @@ namespace Ark { namespace Client { -namespace API { +namespace api { /**/ -class IVotes : public API::Base { -protected: - IVotes(Host& host, IHTTP& http) : API::Base(host, http) {} - -public: +class IVotes : public Base { + public: virtual ~IVotes() {} virtual std::string get(const char* const identifier) = 0; - virtual std::string all(int limit = 5, int page = 1) = 0; + virtual std::string all(const char* const query) = 0; + + protected: + IVotes(Host& host, IHTTP& http) : Base(host, http) {} }; + /**/ + class Votes : public IVotes { -public: + public: Votes(Host& host, IHTTP& http) : IVotes(host, http) {} std::string get(const char* const identifier) override; - std::string all(int limit = 5, int page = 1) override; + std::string all(const char* const query) override; }; -/**/ -}; // namespace API -}; // namespace Client -}; // namespace Ark + +} // namespace api +} // namespace Client +} // namespace Ark #endif diff --git a/src/include/cpp-client/api/wallets/wallets.h b/src/include/cpp-client/api/wallets/wallets.h index 17a76260..34843de7 100644 --- a/src/include/cpp-client/api/wallets/wallets.h +++ b/src/include/cpp-client/api/wallets/wallets.h @@ -18,39 +18,43 @@ namespace Ark { namespace Client { -namespace API { -/**/ -class IWallets : public API::Base { -protected: - IWallets(Host &host, IHTTP &http) : API::Base(host, http) {} +namespace api { // NOLINT + +class IWallets : public Base { + public: + virtual ~IWallets() {} -public: virtual std::string get(const char *const identifier) = 0; - virtual std::string all(int limit = 5, int page = 1) = 0; - virtual std::string top(int limit = 5, int page = 1) = 0; - virtual std::string transactions(const char *const identifier, int limit = 5, int page = 1) = 0; - virtual std::string transactionsReceived(const char *const identifier, int limit = 5, int page = 1) = 0; - virtual std::string transactionsSent(const char *const identifier, int limit = 5, int page = 1) = 0; - virtual std::string votes(const char *const identifier, int limit = 5, int page = 1) = 0; - virtual std::string search(const std::map &bodyParameters, int limit = 5, int page = 1) = 0; + virtual std::string all(const char* const query) = 0; + virtual std::string top(const char* const query) = 0; + virtual std::string transactions(const char *const identifier, const char* const query) = 0; + virtual std::string transactionsReceived(const char *const identifier, const char* const query) = 0; + virtual std::string transactionsSent(const char *const identifier, const char* const query) = 0; + virtual std::string votes(const char *const identifier, const char* const query) = 0; + virtual std::string search(const std::map &bodyParameters, const char* const query) = 0; + + protected: + IWallets(Host &host, IHTTP &http) : Base(host, http) {} }; + /**/ + class Wallets : public IWallets { -public: + public: Wallets(Host &host, IHTTP &http) : IWallets(host, http) {} std::string get(const char *const identifier) override; - std::string all(int limit = 5, int page = 1) override; - std::string top(int limit = 5, int page = 1) override; - std::string transactions(const char *const identifier, int limit = 5, int page = 1) override; - std::string transactionsReceived(const char *const identifier, int limit = 5, int page = 1) override; - std::string transactionsSent(const char *const identifier, int limit = 5, int page = 1) override; - std::string votes(const char *const identifier, int limit = 5, int page = 1) override; - std::string search(const std::map &bodyParameters, int limit = 5, int page = 1) override; + std::string all(const char* const query) override; + std::string top(const char* const query) override; + std::string transactions(const char *const identifier, const char* const query) override; + std::string transactionsReceived(const char *const identifier, const char* const query) override; + std::string transactionsSent(const char *const identifier, const char* const query) override; + std::string votes(const char *const identifier, const char* const query) override; + std::string search(const std::map &bodyParameters, const char* const query) override; }; -/**/ -}; // namespace API -}; // namespace Client -}; // namespace Ark + +} // namespace api +} // namespace Client +} // namespace Ark #endif diff --git a/src/include/cpp-client/arkClient.h b/src/include/cpp-client/arkClient.h index 3ff8c633..951ba87c 100644 --- a/src/include/cpp-client/arkClient.h +++ b/src/include/cpp-client/arkClient.h @@ -13,4 +13,6 @@ #include "helpers/client_helpers.h" #include "connection/connection.h" +using namespace Ark::Client; + #endif diff --git a/src/include/cpp-client/connection/connection.h b/src/include/cpp-client/connection/connection.h index 7a8446f5..c42911c6 100644 --- a/src/include/cpp-client/connection/connection.h +++ b/src/include/cpp-client/connection/connection.h @@ -17,25 +17,23 @@ namespace Ark { namespace Client { -/** - * Ark::Client::Connection - **/ + template class Connection { -public: + public: TAPI api; Host host; Connection() = default; - Connection(const TAPI& other) : api(other) {} + explicit Connection(const TAPI& other) : api(other) {} - Connection(const char* const newIP, int newPort) { + Connection(const char* newIP, int newPort) { this->host.set(newIP, newPort); this->api.setHost(newIP, newPort); }; }; -/**/ -}; // namespace Client -}; // namespace Ark + +} // namespace Client +} // namespace Ark #endif diff --git a/src/include/cpp-client/host/host.h b/src/include/cpp-client/host/host.h index 9b48088d..5cfb7e23 100644 --- a/src/include/cpp-client/host/host.h +++ b/src/include/cpp-client/host/host.h @@ -10,33 +10,34 @@ #ifndef HOST_H #define HOST_H -#include -#include #include namespace Ark { namespace Client { -/*** - * Ark::Client::Host - **/ -class Host { -protected: - char ip_[17]; - int port_; +namespace { +constexpr const size_t IP_MAX_STRING_LEN = 17U; +constexpr const size_t PORT_MAX_STRING_LEN = 5U; +} // namespace + +class Host { public: - Host(); - Host(const char* const newIP, int newPort); + Host() = default; + Host(const char* ip, int port); - bool set(const char* const newIP, int newPort); + bool set(const char* ip, int port); std::string ip() const noexcept; int port() const noexcept; std::string toString(); + + protected: + std::string ip_; + int port_ = -1; }; -/**/ -}; // namespace Client -}; // namespace Ark + +} // namespace Client +} // namespace Ark #endif diff --git a/src/include/cpp-client/http/http.h b/src/include/cpp-client/http/http.h index 8a2a4aad..99eb1b28 100644 --- a/src/include/cpp-client/http/http.h +++ b/src/include/cpp-client/http/http.h @@ -10,7 +10,6 @@ #ifndef HTTP_H #define HTTP_H -#include #include #include @@ -18,45 +17,34 @@ namespace Ark { namespace Client { class IHTTP { -protected: + protected: IHTTP() = default; -public: + public: virtual ~IHTTP() {} - virtual std::string get(const char* const request) = 0; - virtual std::string post(const char* const request, const char* body) = 0; + virtual std::string get(const char* request) = 0; + virtual std::string post(const char* request, const char* body) = 0; }; -/*** - * Ark::Client::AbstractHTTP - * - * The purpose of this class is to serve as an - * entry point for integrating the HTTPClient - * library for different boards/chipsets - **/ +/**/ + class AbstractHTTP : public IHTTP { -protected: + protected: AbstractHTTP() = default; AbstractHTTP(AbstractHTTP&&) = delete; AbstractHTTP& operator=(AbstractHTTP&&) = delete; AbstractHTTP& operator=(const AbstractHTTP& other) = default; -public: + public: virtual ~AbstractHTTP(){}; }; -/**/ -/***/ +/**/ -/*** - * HTTP object factory - **/ std::unique_ptr makeHTTP(); -/**/ -}; // namespace Client -}; // namespace Ark -/**/ +} // namespace Client +} // namespace Ark #endif diff --git a/src/lib/curl b/src/lib/curl deleted file mode 160000 index fe20826b..00000000 --- a/src/lib/curl +++ /dev/null @@ -1 +0,0 @@ -Subproject commit fe20826b580aa221f8f796cba236d08dc0fd80fd diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 73671d44..dcc7c935 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,66 +1,104 @@ -cmake_minimum_required(VERSION 3.2.2) -project(Ark-Cpp-Client-tests) +cmake_minimum_required(VERSION 3.2) -add_subdirectory(lib/googletest) - -include(CTest) -enable_testing() +project(${PROJECT_NAME}_tests C CXX) set(PROJECT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../lib") +# ------------------------------------------------------------------------------ +# External Libraries +# ------------------------------------------------------------------------------ + +include(${CMAKE_SOURCE_DIR}/cmake/GTest.cmake) + +# ------------------------------------------------------------------------------ + +# ------------------------------------------------------------------------------ +# Link the directories to be included +# ------------------------------------------------------------------------------ + +include_directories(${PROJECT_SOURCE_DIR}) include_directories(${PROJECT_SOURCE_DIR}/../src) -include_directories(${PROJECT_SOURCE_DIR}/../test) -include_directories(${PROJECT_SOURCE_DIR}/lib/ArduinoJson) include_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) -set(TEST_CONNECTION_SRC - ${PROJECT_SOURCE_DIR}/connection/connection.cpp -) +# ------------------------------------------------------------------------------ + +# ------------------------------------------------------------------------------ +# ARK Test Source +# ------------------------------------------------------------------------------ + +# ------------------------------------------------------------------------------ +# Connection + +set(CONNECTION_TEST_SOURCE ${PROJECT_SOURCE_DIR}/connection/connection.cpp) + +# ------------------------------------------------------------------------------ +# Host + +set(HOST_TEST_SOURCE ${PROJECT_SOURCE_DIR}/host/host.cpp) + +# ------------------------------------------------------------------------------ +# HTTP + +set(HTTP_TEST_SOURCE ${PROJECT_SOURCE_DIR}/http/http.cpp) + +# ------------------------------------------------------------------------------ +# Paths + +set(PATH_TEST_SOURCE ${PROJECT_SOURCE_DIR}/api/paths.cpp) + +# ------------------------------------------------------------------------------ +# API + +set(API_TEST_SOURCE + ${PROJECT_SOURCE_DIR}/api/blockchain.cpp + ${PROJECT_SOURCE_DIR}/api/blocks.cpp + ${PROJECT_SOURCE_DIR}/api/delegates.cpp + ${PROJECT_SOURCE_DIR}/api/node.cpp + ${PROJECT_SOURCE_DIR}/api/peers.cpp + ${PROJECT_SOURCE_DIR}/api/rounds.cpp + ${PROJECT_SOURCE_DIR}/api/transactions.cpp + ${PROJECT_SOURCE_DIR}/api/votes.cpp + ${PROJECT_SOURCE_DIR}/api/wallets.cpp) + +# ------------------------------------------------------------------------------ +# ARK C++ Client Library Source + +set(ARK_TEST_SOURCE + ${CONNECTION_TEST_SOURCE} + ${HOST_TEST_SOURCE} + ${HTTP_TEST_SOURCE} + ${PATH_TEST_SOURCE} + ${API_TEST_SOURCE}) -set(TEST_HOST_SRC - ${PROJECT_SOURCE_DIR}/host/host.cpp -) +# ------------------------------------------------------------------------------ -set(TEST_HTTP_SRC - ${PROJECT_SOURCE_DIR}/http/http.cpp -) +# ------------------------------------------------------------------------------ +# Link ARK C++ Client to the Test Libraries +# ------------------------------------------------------------------------------ -set(TEST_API_PATHS_SRC - ${PROJECT_SOURCE_DIR}/api/paths.cpp -) +find_library(${PROJECT_NAME} PUBLIC) -set(TEST_API_SRC - ${PROJECT_SOURCE_DIR}/api/blocks.cpp - ${PROJECT_SOURCE_DIR}/api/delegates.cpp - ${PROJECT_SOURCE_DIR}/api/node.cpp - ${PROJECT_SOURCE_DIR}/api/peers.cpp - ${PROJECT_SOURCE_DIR}/api/transactions.cpp - ${PROJECT_SOURCE_DIR}/api/votes.cpp - ${PROJECT_SOURCE_DIR}/api/wallets.cpp -) +add_executable(${PROJECT_NAME} ${ARK_TEST_SOURCE}) -find_library(Ark-Cpp-Client-tests PUBLIC) +target_link_libraries(${PROJECT_NAME} ark_cpp_client gtest gmock gmock_main) -add_executable(Ark-Cpp-Client-tests - ${TEST_CONNECTION_SRC} - ${TEST_HOST_SRC} - ${TEST_HTTP_SRC} - ${TEST_API_PATHS_SRC} - ${TEST_API_SRC} -) +add_test(NAME test COMMAND ${PROJECT_NAME}) -target_link_libraries(Ark-Cpp-Client-tests Ark-Cpp-Client-lib gtest gmock gmock_main) +# ------------------------------------------------------------------------------ -add_test(NAME test COMMAND Ark-Cpp-Client-tests) +# ------------------------------------------------------------------------------ +# Coverage +# ------------------------------------------------------------------------------ if (CMAKE_BUILD_TYPE STREQUAL "Coverage") - include("${CMAKE_SOURCE_DIR}/cmake/CodeCoverage.cmake") + include("${CMAKE_SOURCE_DIR}/cmake/CodeCoverage.cmake") - setup_target_for_coverage(${PROJECT_NAME}_coverage Ark-Cpp-Client-tests coverage) + setup_target_for_coverage(${PROJECT_NAME}_coverage ${PROJECT_NAME} coverage) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") endif() #CMAKE_BUILD_TYPE STREQUAL "Coverage" +# ------------------------------------------------------------------------------ diff --git a/test/api/blockchain.cpp b/test/api/blockchain.cpp new file mode 100644 index 00000000..99ddde73 --- /dev/null +++ b/test/api/blockchain.cpp @@ -0,0 +1,40 @@ + +#include "gtest/gtest.h" +#include "gmock/gmock.h" + +#include + +#include "mocks/mock_api.h" + +using testing::Return; + +namespace { +using namespace Ark::Client; +using namespace Ark::Client::api; +constexpr const char* tIp = "167.114.29.55"; +constexpr const int tPort = 4003; +} // namespace + +TEST(api, test_blockchain) { // NOLINT + Ark::Client::Connection connection(tIp, tPort); + + const std::string expected_response = R"({ + "data": { + "block": { + "height": 2922163, + "id": "84125ec94ba3f3a2d6fd6643d50c98ed2f3c8fa62d8c939355974f404e9b3906" + }, + "supply": "13082272800000000" + } + })"; + + EXPECT_CALL(connection.api.blockchain, get()) + .Times(1) + .WillOnce(Return(expected_response)); + + const auto blockchain = connection.api.blockchain.get(); + + auto responseMatches = strcmp(expected_response.c_str(), + blockchain.c_str()) == 0; + ASSERT_TRUE(responseMatches); +} diff --git a/test/api/blocks.cpp b/test/api/blocks.cpp index 4968e4fd..cdd4504c 100644 --- a/test/api/blocks.cpp +++ b/test/api/blocks.cpp @@ -1,393 +1,237 @@ -#include "arkClient.h" -#include "gmock/gmock.h" #include "gtest/gtest.h" +#include "gmock/gmock.h" + +#include + #include "mocks/mock_api.h" -#include "utils/json.h" using testing::_; using testing::Return; +namespace { +using namespace Ark::Client; +using namespace Ark::Client::api; +constexpr const char* tIp = "167.114.29.55"; +constexpr const int tPort = 4003; +} // namespace + +/**/ + TEST(api, test_block) { // NOLINT - Ark::Client::Connection connection("167.114.29.55", 4003); + Ark::Client::Connection connection(tIp, tPort); const std::string expected_response = R"({ "data": { - "id": "58328125061111756", + "id": "52bf612923a1cc314de553f64f40597f89284e6d06d6b652a0eb00f6890f5d69", "version": 0, - "height": 3035362, - "previous": "3741191868092856237", + "height": 2918583, + "previous": "56aea32861cdc55b9826601341c41a2d5c44447bc55654a55c51fa41ee4906f7", "forged": { - "reward": 200000000, - "fee": 0, - "total": 200000000 + "reward": "200000000", + "fee": "0", + "total": "200000000", + "amount": "0" }, "payload": { "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "length": 0 }, "generator": { - "username": "genesis_6", - "address": "D5e2FzTPqdEHridjzpFZCCVyepAu6Vpmk4", - "publicKey": "023e577a7b3362e0aba70e6911d230e86d729b4cb640f0e0b25637b812a3e38b53" + "username": "lemii", + "address": "DAWNRvnMNPWodLjQwhphJwUpTW2KJXBzVR", + "publicKey": "03dcb84917cf6d7b742f58c04693c5e00c56a4ae83feec129b3e3cc27111796232" }, - "signature": "3044022047aeb0c9cfbb5709aba4c177009bfdc7804ef597073fb9ca6cb614d7e3d1af2d02207234119d02ca26600ece045c59266945081b4c8237370576aaad7c61a09fe0ad", + "signature": "3045022100e5e97a5b00375892ba5359a65943aebb9a2be29df5b6e030c275d61474447e7f02206ce93dbfbdb46535eb7ac53b78689b18f62665928b1f26b9422a5eb15e2f4cbc", + "confirmations": 8, "transactions": 0, "timestamp": { - "epoch": 32816544, - "unix": 1522917744, - "human": "2018-04-05T08:42:24Z" + "epoch": 72724048, + "unix": 1562825248, + "human": "2019-07-11T06:07:28.000Z" } } })"; - EXPECT_CALL(connection.api.blocks, get(_)).Times(1).WillOnce(Return(expected_response)); - - const auto blockResponse = connection.api.blocks.get("58328125061111756"); - - DynamicJsonDocument doc(1244); - DeserializationError error = deserializeJson(doc, blockResponse); - if (error) { exit(0); } - - JsonObject data = doc["data"]; - - const auto id = data["id"]; - ASSERT_STREQ("58328125061111756", id); - - int version = data["version"]; - ASSERT_EQ(0, version); - - int height = data["height"]; - ASSERT_EQ(3035362, height); - - JsonObject forged = data["forged"]; - - uint64_t reward = forged["reward"]; - ASSERT_TRUE(reward == 200000000); - - uint64_t fee = forged["fee"]; - ASSERT_TRUE(fee == 0); - - uint64_t total = forged["total"]; - ASSERT_TRUE(total == 200000000); - - JsonObject payload = data["payload"]; - - const auto hash = payload["hash"]; - ASSERT_STREQ( - "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - hash); - - int length = payload["length"]; - ASSERT_EQ(0, length); - - JsonObject generator = data["generator"]; - - const auto username = generator["username"]; - ASSERT_STREQ("genesis_6", username); - - const auto address = generator["address"]; - ASSERT_STREQ("D5e2FzTPqdEHridjzpFZCCVyepAu6Vpmk4", address); - - const auto publicKey = generator["publicKey"]; - ASSERT_STREQ( - "023e577a7b3362e0aba70e6911d230e86d729b4cb640f0e0b25637b812a3e38b53", - publicKey); - - const auto signature = data["signature"]; - ASSERT_STREQ( - "3044022047aeb0c9cfbb5709aba4c177009bfdc7804ef597073fb9ca6cb614d7e3d1af2d02207234119d02ca26600ece045c59266945081b4c8237370576aaad7c61a09fe0ad", - signature); + EXPECT_CALL(connection.api.blocks, get(_)) + .Times(1) + .WillOnce(Return(expected_response)); - int transactions = data["transactions"]; - ASSERT_EQ(0, transactions); + const auto block = connection.api.blocks.get("2918583"); - JsonObject timestamp = data["timestamp"]; - - int epoch = timestamp["epoch"]; - ASSERT_EQ(32816544, epoch); - - int timestampUnix = timestamp["unix"]; - ASSERT_EQ(1522917744, timestampUnix); - - const auto human = timestamp["human"]; - ASSERT_STREQ("2018-04-05T08:42:24Z", human); + auto responseMatches = strcmp(expected_response.c_str(), + block.c_str()) == 0; + ASSERT_TRUE(responseMatches); } /**/ TEST(api, test_block_transactions) { // NOLINT - Ark::Client::Connection connection("167.114.29.55", 4003); + Ark::Client::Connection connection(tIp, tPort); const std::string expected_response = R"({ - "meta": { - "count": 1, - "pageCount": 1, - "totalCount": 1, - "next": null, - "previous": null, - "self": "/v2/blocks/14126007750611341900/transactions?page=1", - "first": "/v2/blocks/14126007750611341900/transactions?page=1", - "last": "/v2/blocks/14126007750611341900/transactions?page=1" - }, - "data": [ - { - "id": "57415c61e6e7f10a6f9820d5124b3916f3c3a036b360f4802f0eb484f86f3369", - "blockId": "14126007750611341900", - "type": 0, - "amount": 1000000000000000, - "fee": 10000000, - "sender": "DGihocTkwDygiFvmg6aG8jThYTic47GzU9", - "recipient": "DRac35wghMcmUSe5jDMLBDLWkVVjyKZFxK", - "signature": "3045022100878335a71ab6769f3c1e2895041ad24d6c58cdcfe1151c639e65289e5287b0a8022010800bcfdc3223a9c59a6b014e8adf72f1c34df8a46afe655b021930b03e214e", - "vendorField": "yo", - "confirmations": 3034848, - "timestamp": { - "epoch": 3909196, - "unix": 1494010396, - "human": "2017-05-05T18:53:16Z" - } + "data": { + "id": "099d852e9c346370838c68915226a553ff89babbf3065645d98fcab47b9db8c0", + "version": 0, + "height": 2890293, + "previous": "2d21a61a5adad84fc64268b92f98d8b48238fbe05fc4585433fce42385eee743", + "forged": { + "reward": "200000000", + "fee": "1275666", + "total": "201275666", + "amount": "500000000" + }, + "payload": { + "hash": "abbd2293d21682fb6678a500e436cd6381f697f7b8769fe3c42d13df0dd2cbe5", + "length": 32 + }, + "generator": { + "username": "darkdrakeler", + "address": "DDZaj5qRyrsVT9fqhuRq1D2Z5JvbAGdrdN", + "publicKey": "0286b465fa963d758118cff91b4afe7c89cb777621bf5eae8876166ae65ed658a0" + }, + "signature": "304402200324a6b25b6ed83d11930647a9b0ef207d589a9bdf88f0bf416f6792b5d5204702204eebb4c586bdd65f56aa8584e6142c28e0ad7a5b560fb8bcc253587a8b07a790", + "confirmations": 28450, + "transactions": 1, + "timestamp": { + "epoch": 72496608, + "unix": 1562597808, + "human": "2019-07-08T14:56:48.000Z" } - ] + } })"; EXPECT_CALL(connection.api.blocks, transactions(_)).Times(1).WillOnce(Return(expected_response)); - const auto blockTransactionsResponse = connection.api.blocks.transactions("14126007750611341900"); - - DynamicJsonDocument doc(1452); - DeserializationError error = deserializeJson(doc, blockTransactionsResponse); - if (error) { exit(0); } - - JsonObject meta = doc["meta"]; - - int count = meta["count"]; - ASSERT_EQ(1, count); + const auto transactions = connection.api.blocks.transactions( + "099d852e9c346370838c68915226a553ff89babbf3065645d98fcab47b9db8c0"); - int pageCount = meta["pageCount"]; - ASSERT_EQ(1, pageCount); - - int totalCount = meta["totalCount"]; - ASSERT_EQ(1, totalCount); - - JsonObject dataZero = doc["data"][0]; - - const auto id = dataZero["id"]; - ASSERT_STREQ( - "57415c61e6e7f10a6f9820d5124b3916f3c3a036b360f4802f0eb484f86f3369", - id); - - const auto blockId = dataZero["blockId"]; - ASSERT_STREQ("14126007750611341900", blockId); - - int type = dataZero["type"]; - ASSERT_EQ(0, type); - - uint64_t amount = dataZero["amount"]; - ASSERT_TRUE(amount = 1000000000000000); - - uint64_t fee = dataZero["fee"]; - ASSERT_TRUE(fee == 10000000); - - const auto sender = dataZero["sender"]; - ASSERT_STREQ("DGihocTkwDygiFvmg6aG8jThYTic47GzU9", sender); - - const auto signature = dataZero["signature"]; - ASSERT_STREQ( - "3045022100878335a71ab6769f3c1e2895041ad24d6c58cdcfe1151c639e65289e5287b0a8022010800bcfdc3223a9c59a6b014e8adf72f1c34df8a46afe655b021930b03e214e", - signature); - - int confirmations = dataZero["confirmations"]; - ASSERT_EQ(3034848, confirmations); - - JsonObject timestamp = dataZero["timestamp"]; - - int epoch = timestamp["epoch"]; - ASSERT_EQ(3909196, epoch); - - int timestampUnix = timestamp["unix"]; - ASSERT_EQ(1494010396, timestampUnix); - - const auto human = timestamp["human"]; - ASSERT_STREQ("2017-05-05T18:53:16Z", human); + auto responseMatches = strcmp(expected_response.c_str(), + transactions.c_str()) == 0; + ASSERT_TRUE(responseMatches); } /**/ TEST(api, test_blocks) { // NOLINT - Ark::Client::Connection connection("167.114.29.55", 4003); + Ark::Client::Connection connection(tIp, tPort); const std::string expected_response = R"({ "meta": { - "count": 2, - "pageCount": 1517682, - "totalCount": 3035363, - "next": "/v2/blocks?limit=2&page=2", - "previous": null, - "self": "/v2/blocks?limit=2&page=1", - "first": "/v2/blocks?limit=2&page=1", - "last": "/v2/blocks?limit=2&page=1517682" + "totalCountIsEstimate": false, + "count": 1, + "pageCount": 2918749, + "totalCount": 2918749, + "next": "/api/blocks?limit=1&page=2&transform=true", + "previous": null, + "self": "/api/blocks?limit=1&page=1&transform=true", + "first": "/api/blocks?limit=1&page=1&transform=true", + "last": "/api/blocks?limit=1&page=2918749&transform=true" }, "data": [ { - "id": "6402736103893238690", + "id": "804da254073cad1c2386acbd3c3365c7532cd44ed43f9a4ad6b47541e4a62a2e", "version": 0, - "height": 3035363, - "previous": "58328125061111756", + "height": 2918749, + "previous": "38b9b9fbf9cf8891e1b4f94c73c122199c8871c447bb59ab7c07fe0cedc75ea6", "forged": { - "reward": 200000000, - "fee": 0, - "total": 200000000 + "reward": "200000000", + "fee": "0", + "total": "200000000", + "amount": "0" }, "payload": { "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "length": 0 }, "generator": { - "username": "shawmishrak", - "address": "D7P41dV7s259L3P7BVPNyqExqNDC7vdfx9", - "publicKey": "030fa94238eb63db0247a9bd6a3fd810f690b449ee9ce4eb654b94b22875a9a612" + "username": "zillion", + "address": "DFWTC6qyGgWPFp3NvWtmtvZV1mKF9ASVMk", + "publicKey": "0366da7ed85cc1e73a13fafb8007d2609d92239355847343cc7b12d85a65d25502" }, - "signature": "304402204d0dbeb4e71a99a0f128a3480350014f0a9f250818dae908edd15bce99f49be00220257bf240c5d8578e9ffe144e7dbf0c2259d34e6571e6a83402edc01daec6228e", + "signature": "3045022100c7965c32f881fd6f4f691e9e479c8768a7ba13679cf449ae78174906431154ce02202ad413d16ce61ca19ef795dad431670ac2392b8980bfe5fc6e802a34e741c940", + "confirmations": 0, "transactions": 0, "timestamp": { - "epoch": 32816552, - "unix": 1522917752, - "human": "2018-04-05T08:42:32Z" + "epoch": 72725376, + "unix": 1562826576, + "human": "2019-07-11T06:29:36.000Z" } } ] })"; - EXPECT_CALL(connection.api.blocks, all(5, 1)).Times(1).WillOnce(Return(expected_response)); - - const auto blocksResponse = connection.api.blocks.all(5, 1); - - DynamicJsonDocument doc(1740); - DeserializationError error = deserializeJson(doc, blocksResponse); - if (error) { exit(0); } - - JsonObject meta = doc["meta"]; - - int count = meta["count"]; - ASSERT_NE(0, count); + EXPECT_CALL(connection.api.blocks, all("?limit=1&page=1")) + .Times(1) + .WillOnce(Return(expected_response)); - int pageCount = meta["pageCount"]; - ASSERT_NE(0, pageCount); + const auto blocks = connection.api.blocks.all("?limit=1&page=1"); - int totalCount = meta["totalCount"]; - ASSERT_NE(0, totalCount); - - JsonObject dataZero = doc["data"][0]; - - int version = dataZero["version"]; - ASSERT_EQ(0, version); + auto responseMatches = strcmp(expected_response.c_str(), + blocks.c_str()) == 0; + ASSERT_TRUE(responseMatches); } /**/ TEST(api, test_blocks_search) { // NOLINT - Ark::Client::Connection connection("167.114.29.55", 4003); + Ark::Client::Connection connection(tIp, tPort); const std::string expected_response = R"({ "meta": { + "totalCountIsEstimate": false, "count": 1, - "pageCount": 1, - "totalCount": 1, - "next": null, + "pageCount": 2918791, + "totalCount": 2918791, + "next": "/api/blocks/search?limit=1&page=2&transform=true", "previous": null, - "self": "/v2/blocks/14126007750611341900/transactions/search?page=1", - "first": "/v2/blocks/14126007750611341900/transactions/search?page=1", - "last": "/v2/blocks/14126007750611341900/transactions/search?page=1" + "self": "/api/blocks/search?limit=1&page=1&transform=true", + "first": "/api/blocks/search?limit=1&page=1&transform=true", + "last": "/api/blocks/search?limit=1&page=2918791&transform=true" }, "data": [ { - "id": "57415c61e6e7f10a6f9820d5124b3916f3c3a036b360f4802f0eb484f86f3369", - "blockId": "14126007750611341900", - "type": 0, - "amount": 1000000000000000, - "fee": 10000000, - "sender": "DGihocTkwDygiFvmg6aG8jThYTic47GzU9", - "recipient": "DRac35wghMcmUSe5jDMLBDLWkVVjyKZFxK", - "signature": "3045022100878335a71ab6769f3c1e2895041ad24d6c58cdcfe1151c639e65289e5287b0a8022010800bcfdc3223a9c59a6b014e8adf72f1c34df8a46afe655b021930b03e214e", - "vendorField": "yo", - "confirmations": 3034848, + "id": "2cf82927bba7a8ef808e157b56821140976f6266e5f042b4433da7d492d3528a", + "version": 0, + "height": 2918791, + "previous": "1c7b06d1cb0f469fadcbb32c62099d6f6bb7721e3215f9d982a90fc6253a45d1", + "forged": { + "reward": "200000000", + "fee": "0", + "total": "200000000", + "amount": "0" + }, + "payload": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "length": 0 + }, + "generator": { + "username": "itsanametoo", + "address": "DBk4cPYpqp7EBcvkstVDpyX7RQJNHxpMg8", + "publicKey": "0236d5232cdbd1e7ab87fad10ebe689c4557bc9d0c408b6773be964c837231d5f0" + }, + "signature": "304402204e6cdc1eca2ad1b9dcd31dd9c6a8c36c4a126272811e83196be538b4906d181202204d8b4680cc2e124ede985efb18aae9a46b40942febd65a0d5238337acc72684c", + "confirmations": 0, + "transactions": 0, "timestamp": { - "epoch": 3909196, - "unix": 1494010396, - "human": "2017-05-05T18:53:16Z" + "epoch": 72725712, + "unix": 1562826912, + "human": "2019-07-11T06:35:12.000Z" } } ] })"; - EXPECT_CALL(connection.api.blocks, search(_, _, _)).Times(1).WillOnce(Return(expected_response)); + EXPECT_CALL(connection.api.blocks, search(_, _)) + .Times(1) + .WillOnce(Return(expected_response)); const std::map body = { - { "id", "8337447655053578871" }, - { "previousBlock", "6440284271011893973" }, - { "version", "0" }}; - const auto walletsSearch = connection.api.blocks.search(body, 5, 1); - - DynamicJsonDocument doc(1476); - DeserializationError error = deserializeJson(doc, walletsSearch); - if (error) { exit(0); } - - JsonObject meta = doc["meta"]; - - int count = meta["count"]; - ASSERT_NE(0, count); - - int pageCount = meta["pageCount"]; - ASSERT_NE(0, pageCount); - - int totalCount = meta["totalCount"]; - ASSERT_NE(0, totalCount); - - JsonObject dataZero = doc["data"][0]; - - const auto id = dataZero["id"]; - ASSERT_STREQ( - "57415c61e6e7f10a6f9820d5124b3916f3c3a036b360f4802f0eb484f86f3369", - id); - - const auto blockId = dataZero["blockId"]; - ASSERT_STREQ("14126007750611341900", blockId); - - int type = dataZero["type"]; - ASSERT_EQ(0, type); - - uint64_t amount = dataZero["amount"]; - ASSERT_TRUE(1000000000000000ULL == amount); - - uint64_t fee = dataZero["fee"]; - ASSERT_TRUE(10000000ULL == fee); - - const auto sender = dataZero["sender"]; - ASSERT_STREQ("DGihocTkwDygiFvmg6aG8jThYTic47GzU9", sender); - - const auto recipient = dataZero["recipient"]; - ASSERT_STREQ("DRac35wghMcmUSe5jDMLBDLWkVVjyKZFxK", recipient); - - const auto signature = dataZero["signature"]; - ASSERT_STREQ( - "3045022100878335a71ab6769f3c1e2895041ad24d6c58cdcfe1151c639e65289e5287b0a8022010800bcfdc3223a9c59a6b014e8adf72f1c34df8a46afe655b021930b03e214e", - signature); - - const auto vendorField = dataZero["vendorField"]; - ASSERT_STREQ("yo", vendorField); - - int confirmations = dataZero["confirmations"]; - ASSERT_EQ(3034848, confirmations); - - JsonObject timestamp = dataZero["timestamp"]; - - uint64_t epoch = timestamp["epoch"]; - ASSERT_TRUE(3909196ULL == epoch); - - uint64_t unix_timestamp = timestamp["unix"]; - ASSERT_TRUE(1494010396ULL == unix_timestamp); + { "version", "0" } + }; + const auto blocks = connection.api.blocks.search(body, "?limit=1&page=1"); - const auto human = timestamp["human"]; - ASSERT_STREQ("2017-05-05T18:53:16Z", human); + auto responseMatches = strcmp(expected_response.c_str(), + blocks.c_str()) == 0; + ASSERT_TRUE(responseMatches); } diff --git a/test/api/delegates.cpp b/test/api/delegates.cpp index b05b2e8a..233e9dbd 100644 --- a/test/api/delegates.cpp +++ b/test/api/delegates.cpp @@ -1,330 +1,221 @@ -#include "arkClient.h" -#include "gmock/gmock.h" #include "gtest/gtest.h" +#include "gmock/gmock.h" + +#include + #include "mocks/mock_api.h" -#include "utils/json.h" using testing::_; using testing::Return; +namespace { +using namespace Ark::Client; +using namespace Ark::Client::api; +constexpr const char* tIp = "167.114.29.55"; +constexpr const int tPort = 4003; +} // namespace + +/**/ + TEST(api, test_delegate) { // NOLINT - Ark::Client::Connection connection("167.114.29.55", 4003); + Ark::Client::Connection connection(tIp, tPort); const std::string expected_response = R"({ "data": { - "username": "boldninja", - "address": "DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN", - "publicKey": "022cca9529ec97a772156c152a00aad155ee6708243e65c9d211a589cb5d43234d", - "votes": 0, - "rank": 29, + "username": "munich", + "address": "DKfEF2sykKCZzom3vFg1dp9D2kisB8hM2Q", + "publicKey": "036a520acf24036ff691a4f8ba19514828e9b5aa36ca4ba0452e9012023caccfef", + "votes": "30756514325531", + "rank": 8, "blocks": { - "produced": 0, - "missed": 0, + "produced": 39154, "last": { - "id": "10652480998435361357", + "id": "9ece2a535ad471766c4bd5b6d0e8f342301b7f744a1ec200ddbc150da0d8c669", + "height": 2919031, "timestamp": { - "epoch": 32816112, - "unix": 1522917312, - "human": "2018-04-05T08:35:12Z" + "epoch": 72727632, + "unix": 1562828832, + "human": "2019-07-11T07:07:12.000Z" } } }, "production": { - "approval": "0.10", - "productivity": "0.00" + "approval": 0.25 + }, + "forged": { + "fees": "5933484566", + "rewards": "7830800000000", + "total": "7836733484566" } } })"; - EXPECT_CALL(connection.api.delegates, get(_)).Times(1).WillOnce(Return(expected_response)); - - const auto delegateResponse = connection.api.delegates.get("boldninja"); - - DynamicJsonDocument doc(876); - DeserializationError error = deserializeJson(doc, delegateResponse); - if (error) { exit(0); } - - JsonObject data = doc["data"]; - - const auto username = data["username"]; - ASSERT_STREQ("boldninja", username); - - const auto address = data["address"]; - ASSERT_STREQ("DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN", address); - - const auto publicKey = data["publicKey"]; - ASSERT_STREQ( - "022cca9529ec97a772156c152a00aad155ee6708243e65c9d211a589cb5d43234d", - publicKey); - - uint64_t votes = data["votes"]; - ASSERT_EQ(0, votes); + EXPECT_CALL(connection.api.delegates, get(_)) + .Times(1) + .WillOnce(Return(expected_response)); - int rank = data["rank"]; - ASSERT_EQ(29, rank); + const auto delegate = connection.api.delegates.get("munich"); - JsonObject blocks = data["blocks"]; - - int produced = blocks["produced"]; - ASSERT_EQ(0, produced); - - int missed = blocks["missed"]; - ASSERT_EQ(0, missed); - - JsonObject last = blocks["last"]; - - const auto last_id = last["id"]; - ASSERT_STREQ("10652480998435361357", last_id); - - JsonObject timestamp = last["timestamp"]; - - uint64_t epoch = timestamp["epoch"]; - ASSERT_TRUE(32816112ULL == epoch); - - uint64_t unix_timestamp = timestamp["unix"]; - ASSERT_TRUE(1522917312ULL == unix_timestamp); - - const auto human = timestamp["human"]; - ASSERT_STREQ("2018-04-05T08:35:12Z", human); - - JsonObject production = data["production"]; - - double approval = production["approval"]; - ASSERT_EQ(0.10, approval); - - double productivity = production["productivity"]; - ASSERT_EQ(0.0, productivity); + auto responseMatches = strcmp(expected_response.c_str(), + delegate.c_str()) == 0; + ASSERT_TRUE(responseMatches); } /**/ TEST(api, test_delegate_blocks) { // NOLINT - Ark::Client::Connection connection("167.114.29.55", 4003); + Ark::Client::Connection connection(tIp, tPort); const std::string expected_response = R"({ "meta": { - "count": 2, - "pageCount": 29919, - "totalCount": 59838, - "next": "/v2/delegates/boldninja/blocks?page=2", - "previous": null, - "self": "/v2/delegates/boldninja/blocks?page=1", - "first": "/v2/delegates/boldninja/blocks?page=1", - "last": "/v2/delegates/boldninja/blocks?page=29919" + "totalCountIsEstimate": false, + "count": 1, + "pageCount": 39154, + "totalCount": 39154, + "next": "/api/delegates/munich/blocks?limit=1&page=2&transform=true", + "previous": null, + "self": "/api/delegates/munich/blocks?limit=1&page=1&transform=true", + "first": "/api/delegates/munich/blocks?limit=1&page=1&transform=true", + "last": "/api/delegates/munich/blocks?limit=1&page=39154&transform=true" }, "data": [ { - "id": "10652480998435361357", + "id": "9ece2a535ad471766c4bd5b6d0e8f342301b7f744a1ec200ddbc150da0d8c669", "version": 0, - "height": 3035318, - "previous": "12548322724277171379", + "height": 2919031, + "previous": "90a3928a6daf34109107545fe0d27775b47a3821e0e1e9cb3f9567ceb9b26237", "forged": { - "reward": 200000000, - "fee": 0, - "total": 200000000 + "reward": "200000000", + "fee": "0", + "total": "200000000", + "amount": "0" }, "payload": { "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "length": 0 }, "generator": { - "username": "boldninja", - "address": "DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN", - "publicKey": "022cca9529ec97a772156c152a00aad155ee6708243e65c9d211a589cb5d43234d" + "username": "munich", + "address": "DKfEF2sykKCZzom3vFg1dp9D2kisB8hM2Q", + "publicKey": "036a520acf24036ff691a4f8ba19514828e9b5aa36ca4ba0452e9012023caccfef" }, - "signature": "3044022034e754a3ff70adba6323517e1297c6a9f30176df2ac589661e9206fe60a203120220182c38da201fee20e803bb7725fe9618d6707547e6d7b757d4108f546934fe1c", + "signature": "3045022100f0f2c0856eb8d86dbd86e4b5db47217d9558aa2df6cf6a33a3217a8b30ef631c022045808b473d00732c75a6af98d600cc57839bbdeab8dd22f70ab41afcde39e180", + "confirmations": 16, "transactions": 0, "timestamp": { - "epoch": 32816112, - "unix": 1522917312, - "human": "2018-04-05T08:35:12Z" + "epoch": 72727632, + "unix": 1562828832, + "human": "2019-07-11T07:07:12.000Z" } } ] })"; - EXPECT_CALL(connection.api.delegates, blocks(_, _, _)).Times(1).WillOnce(Return(expected_response)); - - const auto delegateBlocksResponse = connection.api.delegates.blocks("boldninja", 2, 1); - - DynamicJsonDocument doc(1788); - DeserializationError error = deserializeJson(doc, delegateBlocksResponse); - if (error) { exit(0); } - - JsonObject meta = doc["meta"]; - - int count = meta["count"]; - ASSERT_EQ(2, count); + EXPECT_CALL(connection.api.delegates, blocks(_, _)) + .Times(1) + .WillOnce(Return(expected_response)); - int pageCount = meta["pageCount"]; - ASSERT_EQ(29919, pageCount); + const auto blocks = connection.api.delegates.blocks("munich", "?limit=1&page=1"); - int totalCount = meta["totalCount"]; - ASSERT_EQ(59838, totalCount); - - JsonObject dataZero = doc["data"][0]; - - const auto id = dataZero["id"]; - ASSERT_STREQ("10652480998435361357", id); - - int version = dataZero["version"]; - ASSERT_EQ(0, version); - - uint64_t height = dataZero["height"]; - ASSERT_TRUE(3035318ULL == height); - - const auto previous = dataZero["previous"]; - ASSERT_STREQ("12548322724277171379", previous); - - JsonObject generatorZero = dataZero["generator"]; - - const auto username = generatorZero["username"]; - ASSERT_STREQ("boldninja", username); - - const auto address = generatorZero["address"]; - ASSERT_STREQ("DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN", address); - - const auto publicKey = generatorZero["publicKey"]; - ASSERT_STREQ( - "022cca9529ec97a772156c152a00aad155ee6708243e65c9d211a589cb5d43234d", - publicKey); + auto responseMatches = strcmp(expected_response.c_str(), + blocks.c_str()) == 0; + ASSERT_TRUE(responseMatches); } /**/ TEST(api, test_delegate_voters) { // NOLINT - Ark::Client::Connection connection("167.114.29.55", 4003); + Ark::Client::Connection connection(tIp, tPort); const std::string expected_response = R"({ "meta": { - "count": 2, - "pageCount": 10, - "totalCount": 19, - "next": "/v2/delegates/boldninja/voters?page=2", + "count": 1, + "pageCount": 1, + "totalCount": 1, + "next": null, "previous": null, - "self": "/v2/delegates/boldninja/voters?page=1", - "first": "/v2/delegates/boldninja/voters?page=1", - "last": "/v2/delegates/boldninja/voters?page=10" + "self": "/api/delegates/munich/voters?limit=1&page=1&transform=true", + "first": "/api/delegates/munich/voters?limit=1&page=1&transform=true", + "last": "/api/delegates/munich/voters?limit=1&page=1&transform=true" }, "data": [ { - "address": "D5mbS6mpP5UheuciNscpDLgC127kYjRtkK", - "publicKey": "03f7e0b1ab14985990416f72ed0b206c20b9efa35156e4528c8ff749fa0eea5d5a", - "balance": 400000000, - "isDelegate": false + "address": "DKfEF2sykKCZzom3vFg1dp9D2kisB8hM2Q", + "publicKey": "036a520acf24036ff691a4f8ba19514828e9b5aa36ca4ba0452e9012023caccfef", + "username": "munich", + "balance": "30756514325531", + "isDelegate": true, + "vote": "036a520acf24036ff691a4f8ba19514828e9b5aa36ca4ba0452e9012023caccfef" } ] })"; - EXPECT_CALL(connection.api.delegates, voters(_, _, _)).Times(1).WillOnce(Return(expected_response)); - - const auto delegateVotersResponse = connection.api.delegates.voters("boldninja", 5, 1); - - DynamicJsonDocument doc(836); - DeserializationError error = deserializeJson(doc, delegateVotersResponse); - if (error) { exit(0); } - - JsonObject meta = doc["meta"]; - - int count = meta["count"]; - ASSERT_NE(0, count); - - int pageCount = meta["pageCount"]; - ASSERT_NE(0, pageCount); - - int totalCount = meta["totalCount"]; - ASSERT_NE(0, totalCount); + EXPECT_CALL(connection.api.delegates, voters(_, _)) + .Times(1) + .WillOnce(Return(expected_response)); - JsonObject dataZero = doc["data"][0]; + const auto voters = connection.api.delegates.voters("munich", "?limit=1&page=1"); - const auto address = dataZero["address"]; - ASSERT_STREQ("D5mbS6mpP5UheuciNscpDLgC127kYjRtkK", address); - - const auto publicKey = dataZero["publicKey"]; - ASSERT_STREQ( - "03f7e0b1ab14985990416f72ed0b206c20b9efa35156e4528c8ff749fa0eea5d5a", - publicKey); - - bool isDelegate = dataZero["isDelegate"]; - ASSERT_FALSE(isDelegate); + auto responseMatches = strcmp(expected_response.c_str(), + voters.c_str()) == 0; + ASSERT_TRUE(responseMatches); } /**/ TEST(api, test_delegates) { // NOLINT - Ark::Client::Connection connection("167.114.29.55", 4003); + Ark::Client::Connection connection(tIp, tPort); const std::string expected_response = R"({ "meta": { - "count": 2, - "pageCount": 99, - "totalCount": 197, - "next": "/v2/delegates?page=2", - "previous": null, - "self": "/v2/delegates?page=1", - "first": "/v2/delegates?page=1", - "last": "/v2/delegates?page=99" + "count": 1, + "pageCount": 392, + "totalCount": 392, + "next": "/api/delegates?limit=1&page=2", + "previous": null, + "self": "/api/delegates?limit=1&page=1", + "first": "/api/delegates?limit=1&page=1", + "last": "/api/delegates?limit=1&page=392" }, "data": [ { - "username": "dark_jmc", - "address": "D5PXQVeJmchVrZFHL7cALZK8mWWzjCaVfz", - "publicKey": "02a9a0ac34a94f9d27fd9b4b56eb3c565a9a3f61e660f269775fb456f7f3301586", - "votes": 0, + "username": "alessio", + "address": "DSyG9hK9CE8eyfddUoEvsga4kNVQLdw2ve", + "publicKey": "033a5474f68f92f254691e93c06a2f22efaf7d66b543a53efcece021819653a200", + "votes": "2000712345332209", "rank": 1, "blocks": { - "produced": 0, - "missed": 0, + "produced": 46928, "last": { - "id": "12383884455448354193", + "id": "97a2b8aa2a5c6542e10289705a028bc74b0088fb0f11773f9b38b2bb3a5751c1", + "height": 2919050, "timestamp": { - "epoch": 31784600, - "unix": 1521885800, - "human": "2018-03-24T10:03:20Z" + "epoch": 72727784, + "unix": 1562828984, + "human": "2019-07-11T07:09:44.000Z" } } }, "production": { - "approval": "0.08", - "productivity": "0.00" + "approval": 15.99 + }, + "forged": { + "fees": "468407250508", + "rewards": "9346000000000", + "total": "9814407250508" } } ] })"; - EXPECT_CALL(connection.api.delegates, all(5, 1)).Times(1).WillOnce(Return(expected_response)); - - const auto delegates = connection.api.delegates.all(5, 1); - - DynamicJsonDocument doc(1340); - DeserializationError error = deserializeJson(doc, delegates); - if (error) { exit(0); } - - JsonObject meta = doc["meta"]; - - int count = meta["count"]; - ASSERT_NE(0, count); - - int pageCount = meta["pageCount"]; - ASSERT_NE(0, pageCount); - - int totalCount = meta["totalCount"]; - ASSERT_NE(0, totalCount); - - JsonObject dataZero = doc["data"][0]; - - const auto username = dataZero["username"]; - ASSERT_STREQ("dark_jmc", username); - - const auto address = dataZero["address"]; - ASSERT_STREQ("D5PXQVeJmchVrZFHL7cALZK8mWWzjCaVfz", address); + EXPECT_CALL(connection.api.delegates, all(_)) + .Times(1) + .WillOnce(Return(expected_response)); - const auto publicKey = dataZero["publicKey"]; - ASSERT_STREQ( - "02a9a0ac34a94f9d27fd9b4b56eb3c565a9a3f61e660f269775fb456f7f3301586", - publicKey); + const auto delegates = connection.api.delegates.all("?limit=1&page=1"); - uint64_t votes = dataZero["votes"]; - ASSERT_TRUE(0ULL == votes); + auto responseMatches = strcmp(expected_response.c_str(), + delegates.c_str()) == 0; + ASSERT_TRUE(responseMatches); } diff --git a/test/api/node.cpp b/test/api/node.cpp index 810a3586..17cf1feb 100644 --- a/test/api/node.cpp +++ b/test/api/node.cpp @@ -1,166 +1,305 @@ -#include "gmock/gmock.h" #include "gtest/gtest.h" +#include "gmock/gmock.h" -#include "mocks/mock_api.h" +#include -#include "arkClient.h" -#include "utils/json.h" +#include "mocks/mock_api.h" +using testing::_; using testing::Return; +namespace { +using namespace Ark::Client; +using namespace Ark::Client::api; +constexpr const char* tIp = "167.114.29.55"; +constexpr const int tPort = 4003; +} // namespace + /**/ TEST(api, test_node_configuration) { // NOLINT - Ark::Client::Connection connection("167.114.29.54", 4003); + Ark::Client::Connection connection(tIp, tPort); - const std::string response = R"({ + const std::string expected_response = R"({ "data": { - "nethash": "578e820911f24e039733b45e4882b73e301f813a0d2c31330dafda84534ffa23", - "token" : "DARK", - "symbol" : "DѦ", - "explorer" : "https://dexplorer.ark.io", - "version" : 30, - "ports" : { - "@arkecosystem/core-p2p": 4000, - "@arkecosystem/core-api" : 4003, - "@arkecosystem/core-graphql" : 4005, - "@arkecosystem/core-json-rpc" : 8080 + "nethash": "2a44f340d76ffc3df204c5f38cd355b7496c9065a1ade2ef92071436bd72e867", + "slip44": 1, + "wif": 170, + "token": "DARK", + "symbol": "DѦ", + "explorer": "https://dexplorer.ark.io", + "version": 30, + "ports": { + "@arkecosystem/core-p2p": null, + "@arkecosystem/core-api": 4003 }, - "feeStatistics": [ - { - "type": 0, - "fees" : { - "minFee": 268421, - "maxFee" : 597781, - "avgFee" : 404591 - } - } - ], "constants": { - "height": 75600, - "reward" : 200000000, - "activeDelegates" : 51, - "blocktime" : 8, - "block" : { + "height": 2850000, + "reward": 200000000, + "activeDelegates": 51, + "blocktime": 8, + "block": { "version": 0, - "maxTransactions" : 50, - "maxPayload" : 2097152 + "maxTransactions": 500, + "maxPayload": 21000000, + "acceptExpiredTransactionTimestamps": false, + "idFullSha256": true }, - "epoch" : "2017-03-21T13:00:00.000Z", - "fees" : { - "send": 10000000, - "vote" : 100000000, - "secondsignature" : 500000000, - "delegate" : 2500000000, - "multisignature" : 500000000 + "epoch": "2017-03-21T13:00:00.000Z", + "fees": { + "staticFees": { + "transfer": 10000000, + "secondSignature": 500000000, + "delegateRegistration": 2500000000, + "vote": 100000000, + "multiSignature": 500000000, + "ipfs": 0, + "timelockTransfer": 0, + "multiPayment": 0, + "delegateResignation": 2500000000 + } + }, + "ignoreInvalidSecondSignatureField": false, + "ignoreExpiredTransactions": false, + "vendorFieldLength": 255 + }, + "transactionPool": { + "dynamicFees": { + "enabled": true, + "minFeePool": 1000, + "minFeeBroadcast": 1000, + "addonBytes": { + "transfer": 100, + "secondSignature": 250, + "delegateRegistration": 400000, + "vote": 100, + "multiSignature": 500, + "ipfs": 250, + "timelockTransfer": 500, + "multiPayment": 500, + "delegateResignation": 100 + } } } } })"; - EXPECT_CALL(connection.api.node, configuration()).Times(1).WillOnce(Return(response)); - - const auto nodeConfiguration = connection.api.node.configuration(); - - DynamicJsonDocument doc(1556); - DeserializationError error = deserializeJson(doc, nodeConfiguration); - if (error) { exit(0); } - - JsonObject data = doc["data"]; - - const auto nethash = data["nethash"]; - ASSERT_STREQ( - "578e820911f24e039733b45e4882b73e301f813a0d2c31330dafda84534ffa23", - nethash); - - const auto token = data["token"]; - ASSERT_STREQ("DARK", token); + EXPECT_CALL(connection.api.node, configuration()) + .Times(1) + .WillOnce(Return(expected_response)); - const auto symbol = data["symbol"]; - ASSERT_STREQ(u8"DѦ", symbol); + const auto configuration = connection.api.node.configuration(); - const auto explorer = data["explorer"]; - ASSERT_STREQ("https://dexplorer.ark.io", explorer); - - int version = data["version"]; - ASSERT_EQ(30, version); - - JsonObject ports = data["ports"]; - - int core_p2p = ports["@arkecosystem/core-p2p"]; - ASSERT_EQ(4000, core_p2p); - - int core_api = ports["@arkecosystem/core-api"]; - ASSERT_EQ(4003, core_api); + auto responseMatches = strcmp(expected_response.c_str(), + configuration.c_str()) == 0; + ASSERT_TRUE(responseMatches); } /**/ -TEST(api, test_node_status) { // NOLINT - Ark::Client::Connection connection("167.114.29.54", 4003); +TEST(api, test_node_crypto) { // NOLINT + Ark::Client::Connection connection(tIp, tPort); - const std::string response = R"({ + const std::string expected_response = R"({ "data": { - "synced": false, - "now": 3034451, - "blocksCount": 36 + "exceptions": { + "blocks": [ + "6671890826474701031" + ], + "transactions": [ + "df8223e5443ed0decb7f8f3bcf7e822b7bbd3bea31f615d99c26909ac6d066f8" + ] + }, + "genesisBlock": { + "version": 0, + "totalAmount": "12500000000000000", + "totalFee": "0", + "reward": "0", + "payloadHash": "2a44f340d76ffc3df204c5f38cd355b7496c9065a1ade2ef92071436bd72e867", + "timestamp": 0, + "numberOfTransactions": 52, + "payloadLength": 11395, + "previousBlock": null, + "generatorPublicKey": "03d3fdad9c5b25bf8880e6b519eb3611a5c0b31adebc8455f0e096175b28321aff", + "transactions": [ + { + "type": 0, + "amount": "12500000000000000", + "fee": "0", + "recipientId": "D6Z26L69gdk9qYmTv5uzk3uGepigtHY4ax", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0208e6835a8f020cfad439c059b89addc1ce21f8cab0af6e6957e22d3720bff8a4", + "signature": "304402203a3f0f80aad4e0561ae975f241f72a074245f1205d676d290d6e5630ed4c027502207b31fee68e64007c380a4b6baccd4db9b496daef5f7894676586e1347ac30a3b", + "id": "3e3817fd0c35bc36674f3874c2953fa3e35877cbcdb44a08bdc6083dbd39d572" + } + ], + "height": 1, + "id": "13114381566690093367", + "blockSignature": "3044022035694a9b99a9236655c658eb07fc3b02ce5edcc24b76424a7287c54ed3822b0602203621e92defb360490610f763d85e94c2db2807a4bd7756cc8a6a585463ef7bae" + }, + "milestones": [ + { + "height": 1, + "reward": 0, + "activeDelegates": 51, + "blocktime": 8, + "block": { + "version": 0, + "maxTransactions": 50, + "maxPayload": 2097152, + "acceptExpiredTransactionTimestamps": true + }, + "epoch": "2017-03-21T13:00:00.000Z", + "fees": { + "staticFees": { + "transfer": 10000000, + "secondSignature": 500000000, + "delegateRegistration": 2500000000, + "vote": 100000000, + "multiSignature": 500000000, + "ipfs": 0, + "timelockTransfer": 0, + "multiPayment": 0, + "delegateResignation": 2500000000 + } + }, + "ignoreInvalidSecondSignatureField": true, + "ignoreExpiredTransactions": true, + "vendorFieldLength": 64 + } + ], + "network": { + "name": "devnet", + "messagePrefix": "DARK message:\n", + "bip32": { + "public": 46090600, + "private": 46089520 + }, + "pubKeyHash": 30, + "nethash": "2a44f340d76ffc3df204c5f38cd355b7496c9065a1ade2ef92071436bd72e867", + "wif": 170, + "slip44": 1, + "aip20": 1, + "client": { + "token": "DARK", + "symbol": "DѦ", + "explorer": "https://dexplorer.ark.io" + } + } } })"; - EXPECT_CALL(connection.api.node, status()).Times(1).WillOnce(Return(response)); + EXPECT_CALL(connection.api.node, crypto()) + .Times(1) + .WillOnce(Return(expected_response)); - const auto nodeStatus = connection.api.node.status(); + const auto crypto = connection.api.node.crypto(); - DynamicJsonDocument doc(156); - DeserializationError error = deserializeJson(doc, nodeStatus); - if (error) { exit(0); } + auto responseMatches = strcmp(expected_response.c_str(), + crypto.c_str()) == 0; + ASSERT_TRUE(responseMatches); +} + +/**/ - JsonObject data = doc["data"]; +TEST(api, test_node_fees) { + Ark::Client::Connection connection(tIp, tPort); + + const std::string expected_response = R"({ + "meta": { + "days": 7 + }, + "data": [ + { + "type": 0, + "avg": "2159269", + "min": "30000", + "max": "17493405", + "sum": "70675045972" + }, + { + "type": 1, + "avg": "275000000", + "min": "50000000", + "max": "500000000", + "sum": "550000000" + }, + { + "type": 2, + "avg": "1200000000", + "min": "1200000000", + "max": "1200000000", + "sum": "2400000000" + }, + { + "type": 3, + "avg": "26815214", + "min": "700000", + "max": "186790786", + "sum": "7427814405" + } + ] + })"; - bool synced = data["synced"]; - ASSERT_FALSE(synced); + EXPECT_CALL(connection.api.node, fees(_)) + .Times(1) + .WillOnce(Return(expected_response)); - int now = data["now"]; - ASSERT_EQ(3034451, now); + const auto fees = connection.api.node.fees("?days=7"); - int blocksCount = data["blocksCount"]; - ASSERT_EQ(36, blocksCount); + auto responseMatches = strcmp(expected_response.c_str(), + fees.c_str()) == 0; + ASSERT_TRUE(responseMatches); } /**/ -TEST(api, test_node_syncing) { // NOLINT - Ark::Client::Connection connection("167.114.29.54", 4003); +TEST(api, test_node_status) { + Ark::Client::Connection connection(tIp, tPort); - const std::string response = R"({ + const std::string expected_response = R"({ "data": { - "syncing": true, - "blocks": 36, - "height": 3034451, - "id": "5444078994968869529" + "synced": true, + "now": 2919069, + "blocksCount": -1, + "timestamp": 72727946 } })"; - EXPECT_CALL(connection.api.node, syncing()).Times(1).WillOnce(Return(response)); + EXPECT_CALL(connection.api.node, status()) + .Times(1) + .WillOnce(Return(expected_response)); - const auto nodeSyncing = connection.api.node.syncing(); + const auto status = connection.api.node.status(); - DynamicJsonDocument doc(212); - DeserializationError error = deserializeJson(doc, nodeSyncing); - if (error) { exit(0); } + auto responseMatches = strcmp(expected_response.c_str(), + status.c_str()) == 0; + ASSERT_TRUE(responseMatches); +} - JsonObject data = doc["data"]; +/**/ + +TEST(api, test_node_syncing) { + Ark::Client::Connection connection(tIp, tPort); - bool syncing = data["syncing"]; - ASSERT_TRUE(syncing); + const std::string expected_response = R"({ + "data": { + "syncing": false, + "blocks": -1, + "height": 2919074, + "id": "54167104076192c87659c6a9733555328dba615b4bb1093329185e5d1d1f8666" + } + })"; - int blocks = data["blocks"]; - ASSERT_EQ(36, blocks); + EXPECT_CALL(connection.api.node, syncing()) + .Times(1) + .WillOnce(Return(expected_response)); - uint64_t height = data["height"]; - ASSERT_TRUE(3034451ULL == height); + const auto syncing = connection.api.node.syncing(); - const auto id = data["id"]; - ASSERT_STREQ("5444078994968869529", id); + auto responseMatches = strcmp(expected_response.c_str(), + syncing.c_str()) == 0; + ASSERT_TRUE(responseMatches); } diff --git a/test/api/paths.cpp b/test/api/paths.cpp index be60af3b..ef0f5cc1 100644 --- a/test/api/paths.cpp +++ b/test/api/paths.cpp @@ -5,117 +5,159 @@ #include "arkClient.h" namespace { - Ark::Client::Host testHost("0.0.0.0", 4003); +using namespace Ark::Client; +using namespace Ark::Client::api; +constexpr const char* tIp = "0.0.0.0"; +constexpr const int tPort = 4003; +constexpr const int tLimit = 5; +constexpr const int tPage = 1; +Host testHost(tIp, tPort); +} // namespace + +/**/ + +TEST(paths, test_blockchain) { + const auto base = paths::Blockchain::base(); + ASSERT_STREQ("/api/blockchain", base); + + const auto get = paths::Blockchain::get(testHost); + ASSERT_STREQ("0.0.0.0:4003/api/blockchain", get.c_str()); } /**/ -TEST(paths, test_blocks) { // NOLINT - const auto base = Ark::Client::API::Paths::Blocks::base(); - ASSERT_STREQ("/api/v2/blocks", base); +TEST(paths, test_blocks) { + const auto base = paths::Blocks::base(); + ASSERT_STREQ("/api/blocks", base); - const auto get = Ark::Client::API::Paths::Blocks::get(testHost, "58328125061111756"); - ASSERT_STREQ("0.0.0.0:4003/api/v2/blocks/58328125061111756", get.c_str()); + const auto get = paths::Blocks::get(testHost, "58328125061111756"); + ASSERT_STREQ("0.0.0.0:4003/api/blocks/58328125061111756", get.c_str()); - const auto all = Ark::Client::API::Paths::Blocks::all(testHost, 5, 1); - ASSERT_STREQ("0.0.0.0:4003/api/v2/blocks?limit=5&page=1", all.c_str()); + const auto all = paths::Blocks::all(testHost, "?limit=1&page=5"); + ASSERT_STREQ("0.0.0.0:4003/api/blocks?limit=1&page=5", all.c_str()); - const auto transactions = Ark::Client::API::Paths::Blocks::transactions(testHost, "58328125061111756"); - ASSERT_STREQ("0.0.0.0:4003/api/v2/blocks/58328125061111756/transactions", transactions.c_str()); + const auto transactions = paths::Blocks::transactions(testHost, + "58328125061111756"); + ASSERT_STREQ("0.0.0.0:4003/api/blocks/58328125061111756/transactions", + transactions.c_str()); const std::map searchBody = { { "id", "8337447655053578871" }, { "previousBlock", "6440284271011893973" }, { "version", "0" } }; - const auto search = Ark::Client::API::Paths::Blocks::search(testHost, searchBody, 5, 1); - ASSERT_STREQ("0.0.0.0:4003/api/v2/blocks/search?limit=5&page=1", search.first.c_str()); - ASSERT_STREQ("id=8337447655053578871&previousBlock=6440284271011893973&version=0", search.second.c_str()); + const auto search = paths::Blocks::search(testHost, searchBody, "?limit=1&page=5"); + ASSERT_STREQ("0.0.0.0:4003/api/blocks/search?limit=1&page=5", + search.first.c_str()); + ASSERT_STREQ( + "id=8337447655053578871&previousBlock=6440284271011893973&version=0", + search.second.c_str()); } /**/ -TEST(paths, test_delegates) { // NOLINT - const auto base = Ark::Client::API::Paths::Delegates::base(); - ASSERT_STREQ("/api/v2/delegates", base); +TEST(paths, test_delegates) { + const auto base = paths::Delegates::base(); + ASSERT_STREQ("/api/delegates", base); - const auto get = Ark::Client::API::Paths::Delegates::get(testHost, "boldninja"); - ASSERT_STREQ("0.0.0.0:4003/api/v2/delegates/boldninja", get.c_str()); + const auto get = paths::Delegates::get(testHost, "boldninja"); + ASSERT_STREQ("0.0.0.0:4003/api/delegates/boldninja", get.c_str()); - const auto all = Ark::Client::API::Paths::Delegates::all(testHost, 5, 1); - ASSERT_STREQ("0.0.0.0:4003/api/v2/delegates?limit=5&page=1", all.c_str()); + const auto all = paths::Delegates::all(testHost, "?limit=1&page=5"); + ASSERT_STREQ("0.0.0.0:4003/api/delegates?limit=1&page=5", all.c_str()); - const auto blocks = Ark::Client::API::Paths::Delegates::blocks(testHost, "boldninja", 5, 1); - ASSERT_STREQ("0.0.0.0:4003/api/v2/delegates/boldninja/blocks?limit=5&page=1", blocks.c_str()); + const auto blocks = paths::Delegates::blocks(testHost, "boldninja", "?limit=1&page=5"); + ASSERT_STREQ("0.0.0.0:4003/api/delegates/boldninja/blocks?limit=1&page=5", + blocks.c_str()); - const auto voters = Ark::Client::API::Paths::Delegates::voters(testHost, "boldninja", 5, 1); - ASSERT_STREQ("0.0.0.0:4003/api/v2/delegates/boldninja/voters?limit=5&page=1", voters.c_str()); + const auto voters = paths::Delegates::voters(testHost, "boldninja", "?limit=1&page=5"); + ASSERT_STREQ("0.0.0.0:4003/api/delegates/boldninja/voters?limit=1&page=5", + voters.c_str()); } /**/ -TEST(paths, test_node) { // NOLINT - const auto base = Ark::Client::API::Paths::Node::base(); - ASSERT_STREQ("/api/v2/node", base); +TEST(paths, test_node) { + const auto base = paths::Node::base(); + ASSERT_STREQ("/api/node", base); - const auto configuration = Ark::Client::API::Paths::Node::configuration(testHost); - ASSERT_STREQ("0.0.0.0:4003/api/v2/node/configuration", configuration.c_str()); + const auto configuration = paths::Node::configuration(testHost); + ASSERT_STREQ("0.0.0.0:4003/api/node/configuration", configuration.c_str()); - const auto status = Ark::Client::API::Paths::Node::status(testHost); - ASSERT_STREQ("0.0.0.0:4003/api/v2/node/status", status.c_str()); + const auto crypto = paths::Node::crypto(testHost); + ASSERT_STREQ("0.0.0.0:4003/api/node/configuration/crypto", crypto.c_str()); - const auto syncing = Ark::Client::API::Paths::Node::syncing(testHost); - ASSERT_STREQ("0.0.0.0:4003/api/v2/node/syncing", syncing.c_str()); + const auto status = paths::Node::status(testHost); + ASSERT_STREQ("0.0.0.0:4003/api/node/status", status.c_str()); + + const auto syncing = paths::Node::syncing(testHost); + ASSERT_STREQ("0.0.0.0:4003/api/node/syncing", syncing.c_str()); } /**/ -TEST(paths, test_peers) { // NOLINT - const auto base = Ark::Client::API::Paths::Peers::base(); - ASSERT_STREQ("/api/v2/peers", base); +TEST(paths, test_peers) { + const auto base = paths::Peers::base(); + ASSERT_STREQ("/api/peers", base); + + const auto get = paths::Peers::get(testHost, "0.0.0.0"); + ASSERT_STREQ("0.0.0.0:4003/api/peers/0.0.0.0", get.c_str()); - const auto get = Ark::Client::API::Paths::Peers::get(testHost, "0.0.0.0"); - ASSERT_STREQ("0.0.0.0:4003/api/v2/peers/0.0.0.0", get.c_str()); + const auto all = paths::Peers::all(testHost, "?limit=1&page=5"); + ASSERT_STREQ("0.0.0.0:4003/api/peers?limit=1&page=5", all.c_str()); +} + +/**/ + +TEST(paths, test_rounds) { + const auto base = paths::Rounds::base(); + ASSERT_STREQ("/api/rounds", base); - const auto all = Ark::Client::API::Paths::Peers::all(testHost, 5, 1); - ASSERT_STREQ("0.0.0.0:4003/api/v2/peers?limit=5&page=1", all.c_str()); + const auto delegates = paths::Rounds::delegates(testHost, "12345"); + ASSERT_STREQ("0.0.0.0:4003/api/rounds/12345/delegates", delegates.c_str()); } /**/ TEST(paths, test_transactions) { // NOLINT - const auto base = Ark::Client::API::Paths::Transactions::base(); - ASSERT_STREQ("/api/v2/transactions", base); + const auto base = paths::Transactions::base(); + ASSERT_STREQ("/api/transactions", base); - const auto getUnconfirmed = Ark::Client::API::Paths::Transactions::getUnconfirmed( + const auto getUnconfirmed = paths::Transactions::getUnconfirmed( testHost, "4bbc5433e5a4e439369f1f57825e92d07cf9cb8e07aada69c122a2125e4b9d48"); ASSERT_STREQ( - "0.0.0.0:4003/api/v2/transactions/unconfirmed/4bbc5433e5a4e439369f1f57825e92d07cf9cb8e07aada69c122a2125e4b9d48", + "0.0.0.0:4003/api/transactions/unconfirmed/4bbc5433e5a4e439369f1f57825e92d07cf9cb8e07aada69c122a2125e4b9d48", getUnconfirmed.c_str()); - const auto all = Ark::Client::API::Paths::Transactions::all(testHost, 5, 1); - ASSERT_STREQ("0.0.0.0:4003/api/v2/transactions?limit=5&page=1", all.c_str()); + const auto all = paths::Transactions::all(testHost, "?limit=1&page=5"); + ASSERT_STREQ("0.0.0.0:4003/api/transactions?limit=1&page=5", all.c_str()); - const auto get = Ark::Client::API::Paths::Transactions::get( + const auto get = paths::Transactions::get( testHost, "4bbc5433e5a4e439369f1f57825e92d07cf9cb8e07aada69c122a2125e4b9d48"); ASSERT_STREQ( - "0.0.0.0:4003/api/v2/transactions/4bbc5433e5a4e439369f1f57825e92d07cf9cb8e07aada69c122a2125e4b9d48", + "0.0.0.0:4003/api/transactions/4bbc5433e5a4e439369f1f57825e92d07cf9cb8e07aada69c122a2125e4b9d48", get.c_str()); - const auto allUnconfirmed = Ark::Client::API::Paths::Transactions::allUnconfirmed(testHost, 5, 1); - ASSERT_STREQ("0.0.0.0:4003/api/v2/transactions/unconfirmed?limit=5&page=1", allUnconfirmed.c_str()); + const auto allUnconfirmed = paths::Transactions::allUnconfirmed( + testHost, "?limit=1&page=5"); + ASSERT_STREQ("0.0.0.0:4003/api/transactions/unconfirmed?limit=1&page=5", + allUnconfirmed.c_str()); - const auto types = Ark::Client::API::Paths::Transactions::types(testHost); - ASSERT_STREQ("0.0.0.0:4003/api/v2/transactions/types", types.c_str()); + const auto types = paths::Transactions::types(testHost); + ASSERT_STREQ("0.0.0.0:4003/api/transactions/types", types.c_str()); + + const auto fees = paths::Transactions::fees(testHost); + ASSERT_STREQ("0.0.0.0:4003/api/transactions/fees", fees.c_str()); const std::map searchBody = { { "id", "dummy" }, { "key", "value" } }; - const auto search = Ark::Client::API::Paths::Transactions::search(testHost, searchBody, 5, 1); - ASSERT_STREQ("0.0.0.0:4003/api/v2/transactions/search?limit=5&page=1", search.first.c_str()); + const auto search = paths::Transactions::search(testHost, searchBody, "?limit=1&page=5"); + ASSERT_STREQ("0.0.0.0:4003/api/transactions/search?limit=1&page=5", + search.first.c_str()); ASSERT_STREQ("id=dummy&key=value", search.second.c_str()); std::string jsonTransaction = "{" @@ -129,75 +171,77 @@ TEST(paths, test_transactions) { // NOLINT "\"recipientId\":\"DHQ4Fjsyiop3qBR4otAjAu6cBHkgRELqGA\"," "\"vendorField\":\"7ad0eeb302ee7d9b4e58cf52daa9ece7922ad92d14f0407e3881597bf3c9c1c6\"" "}"; - const auto send = Ark::Client::API::Paths::Transactions::send(testHost, jsonTransaction); - ASSERT_STREQ("0.0.0.0:4003/api/v2/transactions", send.first.c_str()); + const auto send = paths::Transactions::send(testHost, jsonTransaction); + ASSERT_STREQ("0.0.0.0:4003/api/transactions", send.first.c_str()); ASSERT_STREQ(jsonTransaction.c_str(), send.second.c_str()); } /**/ TEST(paths, test_votes) { // NOLINT - const auto base = Ark::Client::API::Paths::Votes::base(); - ASSERT_STREQ("/api/v2/votes", base); + const auto base = paths::Votes::base(); + ASSERT_STREQ("/api/votes", base); - const auto get = Ark::Client::API::Paths::Votes::get( + const auto get = paths::Votes::get( testHost, "d202acbfa947acac53ada2ac8a0eb662c9f75421ede3b10a42759352968b4ed2"); ASSERT_STREQ( - "0.0.0.0:4003/api/v2/votes/d202acbfa947acac53ada2ac8a0eb662c9f75421ede3b10a42759352968b4ed2", + "0.0.0.0:4003/api/votes/d202acbfa947acac53ada2ac8a0eb662c9f75421ede3b10a42759352968b4ed2", get.c_str()); - const auto all = Ark::Client::API::Paths::Votes::all(testHost, 5, 1); - ASSERT_STREQ("0.0.0.0:4003/api/v2/votes?limit=5&page=1", all.c_str()); + const auto all = paths::Votes::all(testHost, "?limit=1&page=5"); + ASSERT_STREQ("0.0.0.0:4003/api/votes?limit=1&page=5", all.c_str()); } /**/ TEST(paths, test_wallets) { // NOLINT - const auto base = Ark::Client::API::Paths::Wallets::base(); - ASSERT_STREQ("/api/v2/wallets", base); + const auto base = paths::Wallets::base(); + ASSERT_STREQ("/api/wallets", base); - const auto get = Ark::Client::API::Paths::Wallets::get(testHost, "DKrACQw7ytoU2gjppy3qKeE2dQhZjfXYqu"); - ASSERT_STREQ("0.0.0.0:4003/api/v2/wallets/DKrACQw7ytoU2gjppy3qKeE2dQhZjfXYqu", get.c_str()); + const auto get = paths::Wallets::get(testHost, + "DKrACQw7ytoU2gjppy3qKeE2dQhZjfXYqu"); + ASSERT_STREQ("0.0.0.0:4003/api/wallets/DKrACQw7ytoU2gjppy3qKeE2dQhZjfXYqu", + get.c_str()); - const auto all = Ark::Client::API::Paths::Wallets::all(testHost, 5, 1); - ASSERT_STREQ("0.0.0.0:4003/api/v2/wallets?limit=5&page=1", all.c_str()); + const auto all = paths::Wallets::all(testHost, "?limit=1&page=5"); + ASSERT_STREQ("0.0.0.0:4003/api/wallets?limit=1&page=5", all.c_str()); - const auto top = Ark::Client::API::Paths::Wallets::top(testHost, 5, 1); - ASSERT_STREQ("0.0.0.0:4003/api/v2/wallets/top?limit=5&page=1", top.c_str()); + const auto top = paths::Wallets::top(testHost, "?limit=1&page=5"); + ASSERT_STREQ("0.0.0.0:4003/api/wallets/top?limit=1&page=5", top.c_str()); - const auto transactions = - Ark::Client::API::Paths::Wallets::transactions(testHost, "DNv1iScT2DJBWzpJd1AFYkTx1xkAZ9XVJk", 5, 1); + const auto transactions = paths::Wallets::transactions( + testHost, "DNv1iScT2DJBWzpJd1AFYkTx1xkAZ9XVJk", "?limit=1&page=5"); ASSERT_STREQ( - "0.0.0.0:4003/api/v2/wallets/DNv1iScT2DJBWzpJd1AFYkTx1xkAZ9XVJk/transactions?limit=5&page=1", + "0.0.0.0:4003/api/wallets/DNv1iScT2DJBWzpJd1AFYkTx1xkAZ9XVJk/transactions?limit=1&page=5", transactions.c_str()); - const auto sent = Ark::Client::API::Paths::Wallets::transactionsSent( - testHost, - "DNv1iScT2DJBWzpJd1AFYkTx1xkAZ9XVJk", - 5, 1); + const auto sent = paths::Wallets::transactionsSent( + testHost, "DNv1iScT2DJBWzpJd1AFYkTx1xkAZ9XVJk", "?limit=1&page=5"); ASSERT_STREQ( - "0.0.0.0:4003/api/v2/wallets/DNv1iScT2DJBWzpJd1AFYkTx1xkAZ9XVJk/transactions/sent?limit=5&page=1", + "0.0.0.0:4003/api/wallets/DNv1iScT2DJBWzpJd1AFYkTx1xkAZ9XVJk/transactions/sent?limit=1&page=5", sent.c_str()); - const auto received = Ark::Client::API::Paths::Wallets::transactionsReceived( - testHost, - "DNv1iScT2DJBWzpJd1AFYkTx1xkAZ9XVJk", - 5, 1); + const auto received = paths::Wallets::transactionsReceived( + testHost, "DNv1iScT2DJBWzpJd1AFYkTx1xkAZ9XVJk", "?limit=1&page=5"); ASSERT_STREQ( - "0.0.0.0:4003/api/v2/wallets/DNv1iScT2DJBWzpJd1AFYkTx1xkAZ9XVJk/transactions/received?limit=5&page=1", + "0.0.0.0:4003/api/wallets/DNv1iScT2DJBWzpJd1AFYkTx1xkAZ9XVJk/transactions/received?limit=1&page=5", received.c_str()); - const auto votes = Ark::Client::API::Paths::Wallets::votes(testHost, "DNv1iScT2DJBWzpJd1AFYkTx1xkAZ9XVJk", 5, 1); - ASSERT_STREQ("0.0.0.0:4003/api/v2/wallets/DNv1iScT2DJBWzpJd1AFYkTx1xkAZ9XVJk/votes?limit=5&page=1", votes.c_str()); + const auto votes = paths::Wallets::votes( + testHost, "DNv1iScT2DJBWzpJd1AFYkTx1xkAZ9XVJk", "?limit=1&page=5"); + ASSERT_STREQ( + "0.0.0.0:4003/api/wallets/DNv1iScT2DJBWzpJd1AFYkTx1xkAZ9XVJk/votes?limit=1&page=5", + votes.c_str()); const std::map searchBody = { { "username", "baldninja" }, { "address", "DFJ5Z51F1euNNdRUQJKQVdG4h495LZkc6T" }, { "publicKey", "03d3c6889608074b44155ad2e6577c3368e27e6e129c457418eb3e5ed029544e8d" } }; - const auto search = Ark::Client::API::Paths::Wallets::search(testHost, searchBody, 5, 1); - ASSERT_STREQ("0.0.0.0:4003/api/v2/wallets/search?limit=5&page=1", search.first.c_str()); + const auto search = paths::Wallets::search(testHost, searchBody, "?limit=1&page=5"); + ASSERT_STREQ("0.0.0.0:4003/api/wallets/search?limit=1&page=5", + search.first.c_str()); ASSERT_STREQ( "address=DFJ5Z51F1euNNdRUQJKQVdG4h495LZkc6T&publicKey=03d3c6889608074b44155ad2e6577c3368e27e6e129c457418eb3e5ed029544e8d&username=baldninja", search.second.c_str()); diff --git a/test/api/peers.cpp b/test/api/peers.cpp index da88ab1f..ccd25049 100644 --- a/test/api/peers.cpp +++ b/test/api/peers.cpp @@ -1,122 +1,88 @@ -#include "gmock/gmock.h" #include "gtest/gtest.h" +#include "gmock/gmock.h" -#include "mocks/mock_api.h" +#include -#include "arkClient.h" -#include "utils/json.h" +#include "mocks/mock_api.h" using testing::_; using testing::Return; -TEST(api, test_peer) { // NOLINT - Ark::Client::Connection connection("167.114.29.54", 4003); +namespace { +using namespace Ark::Client; +using namespace Ark::Client::api; +constexpr const char* tIp = "167.114.29.55"; +constexpr const int tPort = 4003; +} // namespace + +/**/ + +TEST(api, test_peer) { + Ark::Client::Connection connection(tIp, tPort); - const std::string response = R"({ + const std::string expected_response = R"({ "data": { - "ip": "167.114.29.55", + "ip": "167.114.29.49", "port": 4002, - "version": "1.1.1", - "status": 200, - "os": "linux", - "latency": 355 + "ports": { + "@arkecosystem/core-exchange-json-rpc": -1, + "@arkecosystem/core-webhooks": -1, + "@arkecosystem/core-wallet-api": 4040, + "@arkecosystem/core-api": 4003 + }, + "version": "2.5.0-next.9", + "height": 2919091, + "latency": 237 } })"; - EXPECT_CALL(connection.api.peers, get(_)).Times(1).WillOnce(Return(response)); + EXPECT_CALL(connection.api.peers, get(_)) + .Times(1) + .WillOnce(Return(expected_response)); const auto peer = connection.api.peers.get("167.114.29.49"); - DynamicJsonDocument doc(292); - DeserializationError error = deserializeJson(doc, peer); - if (error) { exit(0); } - - JsonObject data = doc["data"]; - - const auto ip = data["ip"]; - ASSERT_STREQ("167.114.29.55", ip); - - int port = data["port"]; - ASSERT_EQ(4002, port); - - const auto version = data["version"]; - ASSERT_STREQ("1.1.1", version); - - int status = data["status"]; - ASSERT_EQ(200, status); - - const auto os = data["os"]; - ASSERT_STREQ("linux", os); - - int latency = data["latency"]; - ASSERT_EQ(355, latency); + auto responseMatches = strcmp(expected_response.c_str(), + peer.c_str()) == 0; + ASSERT_TRUE(responseMatches); } /**/ -TEST(api, test_peers) { // NOLINT - Ark::Client::Connection connection("167.114.29.55", 4003); +TEST(api, test_peers) { + Ark::Client::Connection connection(tIp, tPort); - const std::string response = R"({ + const std::string expected_response = R"({ "meta": { - "count": 2, - "pageCount": 1, - "totalCount": 2, - "next": null, + "count": 1, + "pageCount": 219, + "totalCount": 219, + "next": "/api/peers?limit=1&page=2", "previous": null, - "self": "/v2/peers?page=1", - "first": "/v2/peers?page=1", - "last": "/v2/peers?page=1" + "self": "/api/peers?limit=1&page=1", + "first": "/api/peers?limit=1&page=1", + "last": "/api/peers?limit=1&page=219" }, "data": [ { - "ip": "167.114.29.53", + "ip": "213.32.9.98", "port": 4002, - "version": "1.1.1", - "status": 200, - "os": "linux", - "latency": 1390 + "ports": {}, + "version": "2.5.0-next.9", + "height": 2919099, + "latency": 9 } ] })"; - EXPECT_CALL(connection.api.peers, all(_, _)).Times(1).WillOnce(Return(response)); - - const auto peers = connection.api.peers.all(5, 1); - - DynamicJsonDocument doc(724); - DeserializationError error = deserializeJson(doc, peers); - if (error) { exit(0); } - - JsonObject meta = doc["meta"]; - - int count = meta["count"]; - ASSERT_NE(0, count); - - int pageCount = meta["pageCount"]; - ASSERT_NE(0, pageCount); - - int totalCount = meta["totalCount"]; - ASSERT_NE(0, totalCount); - - JsonObject dataZero = doc["data"][0]; - - const auto ip = dataZero["ip"]; - ASSERT_STREQ("167.114.29.53", ip); - - int port = dataZero["port"]; - ASSERT_EQ(4002, port); - - const auto version = dataZero["version"]; - ASSERT_STREQ("1.1.1", version); - - int status = dataZero["status"]; - ASSERT_EQ(200, status); + EXPECT_CALL(connection.api.peers, all(_)) + .Times(1) + .WillOnce(Return(expected_response)); - const auto os = dataZero["os"]; - ASSERT_STREQ("linux", os); + const auto peers = connection.api.peers.all("?limit=1&page=1"); - int latency = dataZero["latency"]; - ASSERT_EQ(1390, latency); + auto responseMatches = strcmp(expected_response.c_str(), + peers.c_str()) == 0; + ASSERT_TRUE(responseMatches); } diff --git a/test/api/rounds.cpp b/test/api/rounds.cpp new file mode 100644 index 00000000..522d3344 --- /dev/null +++ b/test/api/rounds.cpp @@ -0,0 +1,42 @@ + +#include "gtest/gtest.h" +#include "gmock/gmock.h" + +#include + +#include "mocks/mock_api.h" + +using testing::_; +using testing::Return; + +namespace { +using namespace Ark::Client; +using namespace Ark::Client::api; +constexpr const char* tIp = "167.114.29.55"; +constexpr const int tPort = 4003; +} // namespace + +/**/ + +TEST(api, test_round_delegates) { // NOLINT + Ark::Client::Connection connection(tIp, tPort); + + const std::string expected_response = R"({ + "data": [ + { + "publicKey": "03ffc17c5528d490b045a9b710c754e00a536d05d9b0b78a9baa0533a246dcd98c", + "votes": "156947252547993" + } + ] + })"; + + EXPECT_CALL(connection.api.rounds, delegates(_)) + .Times(1) + .WillOnce(Return(expected_response)); + + const auto delegates = connection.api.rounds.delegates("12345"); + + auto responseMatches = strcmp(expected_response.c_str(), + delegates.c_str()) == 0; + ASSERT_TRUE(responseMatches); +} diff --git a/test/api/transactions.cpp b/test/api/transactions.cpp index 38c47c44..8a6847ec 100644 --- a/test/api/transactions.cpp +++ b/test/api/transactions.cpp @@ -1,94 +1,67 @@ -#include "gmock/gmock.h" + #include "gtest/gtest.h" +#include "gmock/gmock.h" -#include "mocks/mock_api.h" +#include -#include "arkClient.h" -#include "utils/json.h" +#include "mocks/mock_api.h" using testing::_; using testing::Return; +namespace { +using namespace Ark::Client; +using namespace Ark::Client::api; +constexpr const char* tIp = "167.114.29.55"; +constexpr const int tPort = 4003; +} // namespace + +/**/ + TEST(api, test_transaction) { // NOLINT - Ark::Client::Connection connection("167.114.29.55", 4003); + Ark::Client::Connection connection(tIp, tPort); - const std::string response = R"({ + const std::string expected_response = R"({ "data": { - "id": "5c6ce775447a5acd22050d72e2615392494953bb1fb6287e9ffb3c33eaeb79aa", - "blockId": "4271682877946294396", + "id": "8d41094befe91164c49f429aa7131cb9d3c5ef741495670d6cfee6d224c86974", + "blockId": "849e579749dba0a9d5d8667b128a746c1c129c29c8718a4df18cb89802706a5a", + "version": 1, "type": 0, - "amount": 32106400000, - "fee": 10000000, - "sender": "DDiTHZ4RETZhGxcyAi1VruCXZKxBFqXMeh", - "recipient": "DQnQNoJuNCvpjYhxL7fsnGepHBqrumgsyP", - "signature": "3044022047c39f6f45a46a87f91ca867f9551dbebf0035adcfcbdc1370222c7a1517fc0002206fb5ecc10460e0352a8b626a508e2fcc76e39e490b0a2581dd772ebc8079696e", - "confirmations": 1928, + "amount": "482750000", + "fee": "450000", + "sender": "DJpFwW39QnQvQRQJF2MCfAoKvsX4DJ28jq", + "senderPublicKey": "027716e659220085e41389efc7cf6a05f7f7c659cf3db9126caabce6cda9156582", + "recipient": "DEFfff5D258XAc7aSjfn9acs4BbXwSXjrr", + "signature": "3045022100f0e545e9dc9a5f36017cc64f6b5ca9e4b8cead1e11c05b3736ac271208e64d2d02204c28eee85033a67e56c028628aa3e3e90a94268493b54b09915e186cd13ba4c4", + "signSignature": "304402204484acf8bca39a58af944be54e370dd24eed5b1665012a952d46828a40da0d40022047c0ea4b8c5120316269dd6daf6262de689fbe3df525efcd44c3e9410a395a4c", + "vendorField": "reserve", + "confirmations": 3222, "timestamp": { - "epoch": 32794053, - "unix": 1522895253, - "human": "2018-04-05T02:27:33Z" + "epoch": 72702109, + "unix": 1562803309, + "human": "2019-07-11T00:01:49.000Z" } } })"; - EXPECT_CALL(connection.api.transactions, get(_)).Times(1).WillOnce(Return(response)); + EXPECT_CALL(connection.api.transactions, get(_)) + .Times(1) + .WillOnce(Return(expected_response)); const auto transaction = connection.api.transactions.get( - "5c6ce775447a5acd22050d72e2615392494953bb1fb6287e9ffb3c33eaeb79aa"); - - DynamicJsonDocument doc(868); - DeserializationError error = deserializeJson(doc, transaction); - if (error) { exit(0); } - - JsonObject data = doc["data"]; - - const auto id = data["id"]; - ASSERT_STREQ("5c6ce775447a5acd22050d72e2615392494953bb1fb6287e9ffb3c33eaeb79aa", id); - - const auto blockId = data["blockId"]; - ASSERT_STREQ("4271682877946294396", blockId); - - int type = data["type"]; - ASSERT_EQ(0, type); - - uint64_t amount = data["amount"]; - ASSERT_TRUE(amount == 32106400000); - - uint64_t fee = data["fee"]; - ASSERT_TRUE(fee == 10000000); - - const auto sender = data["sender"]; - ASSERT_STREQ("DDiTHZ4RETZhGxcyAi1VruCXZKxBFqXMeh", sender); - - const auto recipient = data["recipient"]; - ASSERT_STREQ("DQnQNoJuNCvpjYhxL7fsnGepHBqrumgsyP", recipient); - - const auto signature = data["signature"]; - ASSERT_STREQ( - "3044022047c39f6f45a46a87f91ca867f9551dbebf0035adcfcbdc1370222c7a1517fc0002206fb5ecc10460e0352a8b626a508e2fcc76e39e490b0a2581dd772ebc8079696e", - signature); - - int confirmations = data["confirmations"]; - ASSERT_EQ(confirmations, 1928); - - JsonObject timestamp = data["timestamp"]; - - int epoch = timestamp["epoch"]; - ASSERT_EQ(32794053, epoch); + "8d41094befe91164c49f429aa7131cb9d3c5ef741495670d6cfee6d224c86974"); - int timestampUnix = timestamp["unix"]; - ASSERT_EQ(1522895253, timestampUnix); - - const auto human = timestamp["human"]; - ASSERT_STREQ("2018-04-05T02:27:33Z", human); + auto responseMatches = strcmp(expected_response.c_str(), + transaction.c_str()) == 0; + ASSERT_TRUE(responseMatches); } /**/ TEST(api, test_transaction_types) { // NOLINT - Ark::Client::Connection connection("167.114.29.55", 4003); + Ark::Client::Connection connection(tIp, tPort); - const std::string response = R"({ + const std::string expected_response = R"({ "data": { "Transfer": 0, "SecondSignature": 1, @@ -102,379 +75,281 @@ TEST(api, test_transaction_types) { // NOLINT } })"; - EXPECT_CALL(connection.api.transactions, types()).Times(1).WillOnce(Return(response)); + EXPECT_CALL(connection.api.transactions, types()) + .Times(1) + .WillOnce(Return(expected_response)); const auto types = connection.api.transactions.types(); - DynamicJsonDocument doc(444); - DeserializationError error = deserializeJson(doc, types); - if (error) { exit(0); } - - JsonObject data = doc["data"]; - - int Transfer = data["Transfer"]; - ASSERT_EQ(0, Transfer); - - int SecondSignature = data["SecondSignature"]; - ASSERT_EQ(1, SecondSignature); - - int DelegateRegistration = data["DelegateRegistration"]; - ASSERT_EQ(2, DelegateRegistration); + auto responseMatches = strcmp(expected_response.c_str(), + types.c_str()) == 0; + ASSERT_TRUE(responseMatches); +} - int Vote = data["Vote"]; - ASSERT_EQ(3, Vote); +/**/ - int MultiSignature = data["MultiSignature"]; - ASSERT_EQ(4, MultiSignature); +TEST(api, test_transaction_fees) { // NOLINT + Ark::Client::Connection connection(tIp, tPort); - int Ipfs = data["Ipfs"]; - ASSERT_EQ(5, Ipfs); + const std::string expected_response = R"({ + "data": { + "transfer": 10000000, + "secondSignature": 500000000, + "delegateRegistration": 2500000000, + "vote": 100000000, + "multiSignature": 500000000, + "ipfs": 0, + "timelockTransfer": 0, + "multiPayment": 0, + "delegateResignation": 2500000000 + } + })"; - int TimelockTransfer = data["TimelockTransfer"]; - ASSERT_EQ(6, TimelockTransfer); + EXPECT_CALL(connection.api.transactions, fees()) + .Times(1) + .WillOnce(Return(expected_response)); - int MultiPayment = data["MultiPayment"]; - ASSERT_EQ(7, MultiPayment); + const auto fees = connection.api.transactions.fees(); - int DelegateResignation = data["DelegateResignation"]; - ASSERT_EQ(8, DelegateResignation); + auto responseMatches = strcmp(expected_response.c_str(), + fees.c_str()) == 0; + ASSERT_TRUE(responseMatches); } /**/ TEST(api, test_transaction_unconfirmed) { // NOLINT - Ark::Client::Connection connection("167.114.29.55", 4003); + Ark::Client::Connection connection(tIp, tPort); - const std::string response = R"({ + const std::string expected_response = R"({ "data": { - "id": "dummy", - "blockId": "dummy", + "id": "5685946299c426f68c6a6f007059e8f5f015538575b5ef05584963b5837b4c5d", + "version": 1, "type": 0, - "amount": 10000000, - "fee": 10000000, - "sender": "dummy", - "recipient": "dummy", - "signature": "dummy", - "vendorField": "dummy", - "confirmations": 10, + "amount": 100000000, + "fee": 673078, + "sender": "DTQgqpnRkkJ2jKNB8DTNjAhhcwZx1JZrgx", + "senderPublicKey": "033e6e27afd6336946b21a3f4fc1a03205a9a561fbd982ce38e6dfd771c983e70c", + "recipient": "DFSByMjuFNQy1MkRyyBPxEr6fqsu2w5ava", + "signature": "3045022100e47f4f1b33cc9376138d87529c24e37afd37a36c87f0b53a1700d1d24c6d629e022009bf60d8a99e9048b07bc9bedaef7c41b28154a0dff147ae10891b5f45bb4954", + "vendorField": "🐭", + "confirmations": 0, "timestamp": { - "epoch": 40505460, - "unix": 1530606660, - "human": "2018-07-03T08:31:00Z" + "epoch": 70597829, + "unix": 1560699029, + "human": "2019-06-16T15:30:29.000Z" } } })"; - EXPECT_CALL(connection.api.transactions, getUnconfirmed(_)).Times(1).WillOnce(Return(response)); - - const auto transactionUnconfirmed = connection.api.transactions.getUnconfirmed("dummy"); - - DynamicJsonDocument doc(652); - DeserializationError error = deserializeJson(doc, transactionUnconfirmed); - if (error) { exit(0); } - - JsonObject data = doc["data"]; - - const auto id = data["id"]; - ASSERT_STREQ("dummy", id); - - const auto blockId = data["blockId"]; - ASSERT_STREQ("dummy", blockId); - - int type = data["type"]; - ASSERT_EQ(0, type); - - uint64_t amount = data["amount"]; - ASSERT_TRUE(10000000ULL == amount); - - uint64_t fee = data["fee"]; - ASSERT_TRUE(10000000ULL == fee); - - const auto sender = data["sender"]; - ASSERT_STREQ("dummy", sender); - - const auto recipient = data["recipient"]; - ASSERT_STREQ("dummy", recipient); - - const auto signature = data["signature"]; - ASSERT_STREQ("dummy", signature); + EXPECT_CALL(connection.api.transactions, getUnconfirmed(_)) + .Times(1) + .WillOnce(Return(expected_response)); - const auto vendorField = data["vendorField"]; - ASSERT_STREQ("dummy", vendorField); + const auto unconfirmed = connection.api.transactions.getUnconfirmed("dummy"); - int confirmations = data["confirmations"]; - ASSERT_EQ(10, confirmations); - - JsonObject timestamp = data["timestamp"]; - - uint64_t epoch = timestamp["epoch"]; - ASSERT_TRUE(40505460ULL == epoch); - - uint64_t unix_timestamp = timestamp["unix"]; - ASSERT_TRUE(1530606660ULL == unix_timestamp); - - const auto human = timestamp["human"]; - ASSERT_STREQ("2018-07-03T08:31:00Z", human); + auto responseMatches = strcmp(expected_response.c_str(), + unconfirmed.c_str()) == 0; + ASSERT_TRUE(responseMatches); } /**/ TEST(api, test_transactions) { // NOLINT - Ark::Client::Connection connection("167.114.29.55", 4003); + Ark::Client::Connection connection(tIp, tPort); - const std::string response = R"({ + const std::string expected_response = R"({ "meta": { - "count": 2, - "pageCount": 127430, - "totalCount": 254860, - "next": "/v2/transactions?page=2", + "totalCountIsEstimate": false, + "count": 1, + "pageCount": 778588, + "totalCount": 778588, + "next": "/api/transactions?limit=1&page=2&transform=true", "previous": null, - "self": "/v2/transactions?page=1", - "first": "/v2/transactions?page=1", - "last": "/v2/transactions?page=127430" + "self": "/api/transactions?limit=1&page=1&transform=true", + "first": "/api/transactions?limit=1&page=1&transform=true", + "last": "/api/transactions?limit=1&page=778588&transform=true" }, "data": [ { - "id": "5c6ce775447a5acd22050d72e2615392494953bb1fb6287e9ffb3c33eaeb79aa", - "blockId": "4271682877946294396", + "id": "ba022647988fd878c9962267c994f6f314f8483eb793da498c3732bec8486fcc", + "blockId": "71f15e65f23554e5a57067cb18333d082641074c2a1a190df44a273eb04693d3", + "version": 1, "type": 0, - "amount": 32106400000, - "fee": 10000000, - "sender": "DDiTHZ4RETZhGxcyAi1VruCXZKxBFqXMeh", - "recipient": "DQnQNoJuNCvpjYhxL7fsnGepHBqrumgsyP", - "signature": "3044022047c39f6f45a46a87f91ca867f9551dbebf0035adcfcbdc1370222c7a1517fc0002206fb5ecc10460e0352a8b626a508e2fcc76e39e490b0a2581dd772ebc8079696e", - "confirmations": 1924, + "amount": "1980000", + "fee": "500000", + "sender": "DUTnUVuUFrW3SuWQMbR5ibYkcJ16KhfNKM", + "senderPublicKey": "02747353898e59c4f784542f357d5dd938a2872adb53abb94924091fddfdd83dc3", + "recipient": "DQdpw8RPwZKri4HsHxgMVyuLi5memjxo97", + "signature": "304402206c053265fa0d99418bc5ecbdba3d097e7828a790a1ab3ff53d26b977b48fb98a022015ba5c9b6c5b73e583f50603b6cf5b645e4169633368fa4ee63a6917e047a5da", + "vendorField": "generaliroh - this is just leafy water", + "confirmations": 82, "timestamp": { - "epoch": 32794053, - "unix": 1522895253, - "human": "2018-04-05T02:27:33Z" + "epoch": 72727769, + "unix": 1562828969, + "human": "2019-07-11T07:09:29.000Z" } } ] })"; - EXPECT_CALL(connection.api.transactions, all(_, _)).Times(1).WillOnce(Return(response)); - - const auto transactions = connection.api.transactions.all(2, 1); - - DynamicJsonDocument doc(1348); - DeserializationError error = deserializeJson(doc, transactions); - if (error) { exit(0); } - - JsonObject meta = doc["meta"]; - - int count = meta["count"]; - ASSERT_NE(0, count); - - int pageCount = meta["pageCount"]; - ASSERT_NE(0, pageCount); - - int totalCount = meta["totalCount"]; - ASSERT_NE(0, totalCount); + EXPECT_CALL(connection.api.transactions, all(_)) + .Times(1) + .WillOnce(Return(expected_response)); - JsonObject dataZero = doc["data"][0]; + const auto transactions = connection.api.transactions.all("?limit=1&page=1"); - int type = dataZero["type"]; - ASSERT_EQ(0, type); - - uint64_t fee = dataZero["fee"]; - ASSERT_TRUE(fee >= 0); + auto responseMatches = strcmp(expected_response.c_str(), + transactions.c_str()) == 0; + ASSERT_TRUE(responseMatches); } /**/ TEST(api, test_transactions_unconfirmed) { // NOLINT - Ark::Client::Connection connection("167.114.29.55", 4003); + Ark::Client::Connection connection(tIp, tPort); - const std::string response = R"({ + const std::string expected_response = R"({ "meta": { "count": 1, "pageCount": 1, "totalCount": 1, "next": null, "previous": null, - "self": "/api/transactions/unconfirmed?page=1&limit=1", - "first": "/api/transactions/unconfirmed?page=1&limit=1", - "last": "/api/transactions/unconfirmed?page=1&limit=1" + "self": "/api/transactions/unconfirmed?transform=true&page=1&limit=100", + "first": "/api/transactions/unconfirmed?transform=true&page=1&limit=100", + "last": "/api/transactions/unconfirmed?transform=true&page=1&limit=100" }, "data": [ { - "id": "dummy", - "blockId": "dummy", + "id": "5685946299c426f68c6a6f007059e8f5f015538575b5ef05584963b5837b4c5d", + "version": 1, "type": 0, - "amount": 10000000, - "fee": 10000000, - "sender": "dummy", - "recipient": "dummy", - "signature": "dummy", - "vendorField": "dummy", - "confirmations": 10, + "amount": 100000000, + "fee": 673078, + "sender": "DTQgqpnRkkJ2jKNB8DTNjAhhcwZx1JZrgx", + "senderPublicKey": "033e6e27afd6336946b21a3f4fc1a03205a9a561fbd982ce38e6dfd771c983e70c", + "recipient": "DFSByMjuFNQy1MkRyyBPxEr6fqsu2w5ava", + "signature": "3045022100e47f4f1b33cc9376138d87529c24e37afd37a36c87f0b53a1700d1d24c6d629e022009bf60d8a99e9048b07bc9bedaef7c41b28154a0dff147ae10891b5f45bb4954", + "vendorField": "🐭", + "confirmations": 0, "timestamp": { - "epoch": 40505460, - "unix": 1530606660, - "human": "2018-07-03T08:31:00Z" + "epoch": 70597829, + "unix": 1560699029, + "human": "2019-06-16T15:30:29.000Z" } } ] })"; - EXPECT_CALL(connection.api.transactions, allUnconfirmed(_, _)).Times(1).WillOnce(Return(response)); - - const auto transactionsUnconfirmed = connection.api.transactions.allUnconfirmed(5, 1); - - DynamicJsonDocument doc(1164); - DeserializationError error = deserializeJson(doc, transactionsUnconfirmed); - if (error) { exit(0); } - - JsonObject meta = doc["meta"]; + EXPECT_CALL(connection.api.transactions, allUnconfirmed(_)) + .Times(1) + .WillOnce(Return(expected_response)); - int count = meta["count"]; - ASSERT_TRUE(count >= 0); + const auto unconfirmed = connection.api.transactions.allUnconfirmed("?limit=1&page=1"); - int pageCount = meta["pageCount"]; - ASSERT_TRUE(pageCount >= 0); - - int totalCount = meta["totalCount"]; - ASSERT_TRUE(totalCount >= 0); + auto responseMatches = strcmp(expected_response.c_str(), + unconfirmed.c_str()) == 0; + ASSERT_TRUE(responseMatches); } /**/ TEST(api, test_transactions_search) { // NOLINT - Ark::Client::Connection connection("167.114.29.55", 4003); + Ark::Client::Connection connection(tIp, tPort); - const std::string response = R"({ + const std::string expected_response = R"({ "meta": { + "totalCountIsEstimate": false, "count": 1, - "pageCount": 1, - "totalCount": 1, - "next": null, + "pageCount": 762344, + "totalCount": 762344, + "next": "/api/transactions/search?limit=1&page=2&transform=true", "previous": null, - "self": "/api/transactions/search?page=1&limit=1", - "first": "/api/transactions/search?page=1&limit=1", - "last": "/api/transactions/search?page=1&limit=1" + "self": "/api/transactions/search?limit=1&page=1&transform=true", + "first": "/api/transactions/search?limit=1&page=1&transform=true", + "last": "/api/transactions/search?limit=1&page=762344&transform=true" }, "data": [ { - "id": "dummy", - "blockId": "dummy", + "id": "ed46b70a5fad2957c09aa0e0d02b7a2e3e4ab93f0581d1a871e0c44907a4f3e4", + "blockId": "37c2f608910d0624ba114ba9855b3762b2095cd9c2866e1a6ead6c887ff5b07c", + "version": 1, "type": 0, - "amount": 10000000, - "fee": 10000000, - "sender": "dummy", - "recipient": "dummy", - "signature": "dummy", - "vendorField": "dummy", + "amount": "1980000", + "fee": "500000", + "sender": "DUTnUVuUFrW3SuWQMbR5ibYkcJ16KhfNKM", + "senderPublicKey": "02747353898e59c4f784542f357d5dd938a2872adb53abb94924091fddfdd83dc3", + "recipient": "DFrnspWhQsJVQswy6qkWWgpyGm4Kj1FA8s", + "signature": "30440220015f53fff9d86e0ca38f18066ec64b078b6391d420f27d452f2e530ca50571320220162e95d725c154bee54767ab5e9e10824ad9e77a97b47901381b820b33635b25", + "vendorField": "generaliroh - uncle", "confirmations": 10, "timestamp": { - "epoch": 40505460, - "unix": 1530606660, - "human": "2018-07-03T08:31:00Z" + "epoch": 72728617, + "unix": 1562829817, + "human": "2019-07-11T07:23:37.000Z" } } ] })"; - EXPECT_CALL(connection.api.transactions, search(_, _, _)).Times(1).WillOnce(Return(response)); - - const std::map body = { - { "id", "dummy" } - }; - const auto transactions = connection.api.transactions.search(body, 5, 1); + EXPECT_CALL(connection.api.transactions, search(_, _)) + .Times(1) + .WillOnce(Return(expected_response)); - DynamicJsonDocument doc(1148); - DeserializationError error = deserializeJson(doc, transactions); - if (error) { exit(0); } +std::map body{{ + "id", "ed46b70a5fad2957c09aa0e0d02b7a2e3e4ab93f0581d1a871e0c44907a4f3e4" +}}; - JsonObject meta = doc["meta"]; + const auto transactions = connection.api.transactions.search(body,"?limit=1&page=1"); - int count = meta["count"]; - ASSERT_TRUE(count >= 0); - - int pageCount = meta["pageCount"]; - ASSERT_TRUE(pageCount >= 0); - - int totalCount = meta["totalCount"]; - ASSERT_TRUE(totalCount >= 0); - - JsonObject data = doc["data"][0]; - - const auto id = data["id"]; - ASSERT_STREQ("dummy", id); - - const auto blockId = data["blockId"]; - ASSERT_STREQ("dummy", blockId); - - int type = data["type"]; - ASSERT_EQ(0, type); - - const auto sender = data["sender"]; - ASSERT_STREQ("dummy", sender); - - const auto recipient = data["recipient"]; - ASSERT_STREQ("dummy", recipient); - - const auto signature = data["signature"]; - ASSERT_STREQ("dummy", signature); + auto responseMatches = strcmp(expected_response.c_str(), + transactions.c_str()) == 0; + ASSERT_TRUE(responseMatches); } /**/ TEST(api, test_transactions_send) { // NOLINT - Ark::Client::Connection connection("167.114.29.55", 4003); - - const std::string response = R"({ - "data": { - "accept": [ - "dummy" - ], - "broadcast": [ - "dummy" - ], - "excess": [], - "invalid": [] - }, - "errors": null - })"; - - EXPECT_CALL(connection.api.transactions, send(_)).Times(1).WillOnce(Return(response)); - - std::string jsonTransaction = "{" - "\"transactions\":[" - "{" - "\"type\":0," - "\"amount\":1," - "\"fee\":10000000," - "\"id\":\"bc5bb5cd23521c041fca17b5f78d6f3621fc07ab8f6581aff1b6eb86fa4bafe2\"," - "\"recipientId\":\"DNSrsDUq5injGBdNXPV7v7u1Qy9LZfWEdM\"," - "\"senderPublicKey\":\"0216fa03d378b6ad01325e186ad2cbb9d18976d5b27d0ca74b4f92bb6bf9a6d4d9\"," - "\"signature\":\"3044022014204515b82cdd47513377d3e80e6b5f4fd1ab0fb6b4c181e09a7a30428d542502205ba076a332997053e1d31b506777a99f93bcb11294cd678ebe2da313eb02cae2\"," - "\"timestamp\":58351951," - "\"vendorField\":\"7ad0eeb302ee7d9b4e58cf52daa9ece7922ad92d14f0407e3881597bf3c9c1c6\"" - "}" - "]" - "}"; - - const auto transaction = connection.api.transactions.send(jsonTransaction); + Ark::Client::Connection connection(tIp, tPort); - DynamicJsonDocument doc(324); - DeserializationError error = deserializeJson(doc, transaction); - if (error) { exit(0); } - - JsonObject data = doc["data"]; - - std::string accept = data["accept"]; - ASSERT_NE(accept.length(), 0); + const std::string expected_response = R"({ + "data": { + "accept": [ + "dummy" + ], + "broadcast": [ + "dummy" + ], + "excess": [], + "invalid": [] + }, + "errors": null + })"; - std::string broadcast = data["broadcast"]; - ASSERT_NE(broadcast.length(), 0); + std::string jsonTransaction = R"({ + "transactions":[ + { + "type":0, + "amount":"1", + "fee":"10000000", + "id":"bc5bb5cd23521c041fca17b5f78d6f3621fc07ab8f6581aff1b6eb86fa4bafe2", + "recipientId":"DNSrsDUq5injGBdNXPV7v7u1Qy9LZfWEdM", + "senderPublicKey":"0216fa03d378b6ad01325e186ad2cbb9d18976d5b27d0ca74b4f92bb6bf9a6d4d9", + "signature":"3044022014204515b82cdd47513377d3e80e6b5f4fd1ab0fb6b4c181e09a7a30428d542502205ba076a332997053e1d31b506777a99f93bcb11294cd678ebe2da313eb02cae2", + "timestamp":58351951, + "vendorField":"7ad0eeb302ee7d9b4e58cf52daa9ece7922ad92d14f0407e3881597bf3c9c1c6" + } + ] + })"; - std::string excess = data["excess"]; - ASSERT_EQ(excess.length(), 2); + EXPECT_CALL(connection.api.transactions, send(_)) + .Times(1) + .WillOnce(Return(expected_response)); - std::string invalid = data["invalid"]; - ASSERT_EQ(invalid.length(), 2); + const auto transaction = connection.api.transactions.send(jsonTransaction); - std::string errors = data["errors"]; - ASSERT_EQ(errors.length(), 4); + auto responseMatches = strcmp(expected_response.c_str(), + transaction.c_str()) == 0; + ASSERT_TRUE(responseMatches); } diff --git a/test/api/votes.cpp b/test/api/votes.cpp index b3ab8477..7f8dc78d 100644 --- a/test/api/votes.cpp +++ b/test/api/votes.cpp @@ -1,160 +1,115 @@ -#include "gmock/gmock.h" + #include "gtest/gtest.h" +#include "gmock/gmock.h" -#include "mocks/mock_api.h" +#include -#include "arkClient.h" -#include "utils/json.h" +#include "mocks/mock_api.h" using testing::_; using testing::Return; +namespace { +using namespace Ark::Client; +using namespace Ark::Client::api; +constexpr const char* tIp = "167.114.29.55"; +constexpr const int tPort = 4003; +} // namespace + +/**/ + TEST(api, test_vote) { // NOLINT - Ark::Client::Connection connection("167.114.29.55", 4003); + Ark::Client::Connection connection(tIp, tPort); - const std::string response = R"({ + const std::string expected_response = R"({ "data": { - "id": "beb8dd43c640f562704090159154b2742afba7eacada9e8edee447e34e7675c6", - "blockId": "13661015019049808045", + "id": "a3b890d25824eba36dfc2a5956590c68101378211dab216ae92c123ab1ba4b67", + "blockId": "9df8800ab375cfda3782b90bb8e14326e029cecfb22742c6a7c3100c7209a30b", + "version": 1, "type": 3, - "amount": 0, - "fee": 100000000, - "sender": "DAp7JjULVgqzd4jLofkUyLRovHRPUTQwiZ", - "recipient": "DAp7JjULVgqzd4jLofkUyLRovHRPUTQwiZ", - "signature": "3045022100e9a743c5aa0df427f49af61d35fe617182479f7e8d368ce23b7ec43ab6d269c80220193aafd4ccb3eedbd76ded7ea99f31629013dc3af60540029fe98b274d42d284", + "amount": "0", + "fee": "97013913", + "sender": "DTRdbaUW3RQQSL5By4G43JVaeHiqfVp9oh", + "senderPublicKey": "034da006f958beba78ec54443df4a3f52237253f7ae8cbdb17dccf3feaa57f3126", + "recipient": "DTRdbaUW3RQQSL5By4G43JVaeHiqfVp9oh", + "signature": "3045022100b92598f344d3d3d6b0224cfd2058fb35318aac127b8bde529e01fe3868018b610220041cb63436f84bbf93b11c040f9389ebaf8293d63cc685255cea13f48a3f48f6", "asset": { "votes": [ - "+032fe001dff675a6edfe3d0e51201b2900d3b5050a46d770306aefaa574c022672" + "+02aea83a44f1d6b073e5bcffb4176bbe3c51dcd0e96a793a88f3a6135600224adf" ] }, - "confirmations": 48189, + "confirmations": 223, "timestamp": { - "epoch": 32338609, - "unix": 1522439809, - "human": "2018-03-30T19:56:49Z" + "epoch": 72739207, + "unix": 1562840407, + "human": "2019-07-11T10:20:07.000Z" } } })"; - EXPECT_CALL(connection.api.votes, get(_)).Times(1).WillOnce(Return(response)); - - const auto vote = connection.api.votes.get("beb8dd43c640f562704090159154b2742afba7eacada9e8edee447e34e7675c6"); - - DynamicJsonDocument doc(1044); - DeserializationError error = deserializeJson(doc, vote); - if (error) { exit(0); } - - JsonObject data = doc["data"]; - - const auto id = data["id"]; - ASSERT_STREQ("beb8dd43c640f562704090159154b2742afba7eacada9e8edee447e34e7675c6", id); - - const auto blockId = data["blockId"]; - ASSERT_STREQ("13661015019049808045", blockId); - - int type = data["type"]; - ASSERT_EQ(3, type); - - uint64_t amount = data["amount"]; - ASSERT_TRUE(amount == 0); + EXPECT_CALL(connection.api.votes, get(_)) + .Times(1) + .WillOnce(Return(expected_response)); - uint64_t fee = data["fee"]; - ASSERT_TRUE(fee == 100000000); + const auto vote = connection.api.votes.get( + "a3b890d25824eba36dfc2a5956590c68101378211dab216ae92c123ab1ba4b67"); - const auto sender = data["sender"]; - ASSERT_STREQ("DAp7JjULVgqzd4jLofkUyLRovHRPUTQwiZ", sender); - - const auto recipient = data["recipient"]; - ASSERT_STREQ("DAp7JjULVgqzd4jLofkUyLRovHRPUTQwiZ", recipient); - - const auto signature = data["signature"]; - ASSERT_STREQ( - "3045022100e9a743c5aa0df427f49af61d35fe617182479f7e8d368ce23b7ec43ab6d269c80220193aafd4ccb3eedbd76ded7ea99f31629013dc3af60540029fe98b274d42d284", - signature); - - int confirmations = data["confirmations"]; - ASSERT_EQ(48189, confirmations); - - JsonObject timestamp = data["timestamp"]; - - int epoch = timestamp["epoch"]; - ASSERT_EQ(32338609, epoch); - - int timestampUnix = timestamp["unix"]; - ASSERT_EQ(1522439809, timestampUnix); - - const auto human = timestamp["human"]; - ASSERT_STREQ("2018-03-30T19:56:49Z", human); + auto responseMatches = strcmp(expected_response.c_str(), + vote.c_str()) == 0; + ASSERT_TRUE(responseMatches); } /**/ TEST(api, test_votes) { // NOLINT - Ark::Client::Connection connection("167.114.29.55", 4003); + Ark::Client::Connection connection(tIp, tPort); - const std::string response = R"({ + const std::string expected_response = R"({ "meta": { - "count": 2, - "pageCount": 658, - "totalCount": 1315, - "next": "/v2/votes?page=2", + "totalCountIsEstimate": false, + "count": 1, + "pageCount": 15137, + "totalCount": 15137, + "next": "/api/votes?limit=1&page=2&transform=true", "previous": null, - "self": "/v2/votes?page=1", - "first": "/v2/votes?page=1", - "last": "/v2/votes?page=658" + "self": "/api/votes?limit=1&page=1&transform=true", + "first": "/api/votes?limit=1&page=1&transform=true", + "last": "/api/votes?limit=1&page=15137&transform=true" }, "data": [ { - "id": "560959e435cbf8eec60691890f3dd55d141e76077e1fe803f65d137c91099240", - "blockId": "12872155462883631430", + "id": "a3b890d25824eba36dfc2a5956590c68101378211dab216ae92c123ab1ba4b67", + "blockId": "9df8800ab375cfda3782b90bb8e14326e029cecfb22742c6a7c3100c7209a30b", + "version": 1, "type": 3, - "amount": 0, - "fee": 100000000, - "sender": "DAp7JjULVgqzd4jLofkUyLRovHRPUTQwiZ", - "recipient": "DAp7JjULVgqzd4jLofkUyLRovHRPUTQwiZ", - "signature": "30440220522eadff84b5b4b2fc6a3ef611bf093dbd0a06963c32c767ee28729898d0a1d302203f851594e5b2271a987e98daa4fc8b5f384fac65c41eb1c43739af2d4b5dc902", + "amount": "0", + "fee": "97013913", + "sender": "DTRdbaUW3RQQSL5By4G43JVaeHiqfVp9oh", + "senderPublicKey": "034da006f958beba78ec54443df4a3f52237253f7ae8cbdb17dccf3feaa57f3126", + "recipient": "DTRdbaUW3RQQSL5By4G43JVaeHiqfVp9oh", + "signature": "3045022100b92598f344d3d3d6b0224cfd2058fb35318aac127b8bde529e01fe3868018b610220041cb63436f84bbf93b11c040f9389ebaf8293d63cc685255cea13f48a3f48f6", "asset": { "votes": [ - "-032fe001dff675a6edfe3d0e51201b2900d3b5050a46d770306aefaa574c022672" + "+02aea83a44f1d6b073e5bcffb4176bbe3c51dcd0e96a793a88f3a6135600224adf" ] }, - "confirmations": 39989, + "confirmations": 229, "timestamp": { - "epoch": 32414926, - "unix": 1522516126, - "human": "2018-03-31T17:08:46Z" + "epoch": 72739207, + "unix": 1562840407, + "human": "2019-07-11T10:20:07.000Z" } } ] })"; - EXPECT_CALL(connection.api.votes, all(_, _)).Times(1).WillOnce(Return(response)); - - const auto votes = connection.api.votes.all(5, 1); - - DynamicJsonDocument doc(1492); - DeserializationError error = deserializeJson(doc, votes); - if (error) { exit(0); } - - JsonObject meta = doc["meta"]; - - int count = meta["count"]; - ASSERT_NE(0, count); - - int pageCount = meta["pageCount"]; - ASSERT_NE(0, pageCount); - - int totalCount = meta["totalCount"]; - ASSERT_NE(0, totalCount); - - JsonObject dataZero = doc["data"][0]; - - int type = dataZero["type"]; - ASSERT_EQ(3, type); + EXPECT_CALL(connection.api.votes, all(_)) + .Times(1) + .WillOnce(Return(expected_response)); - uint64_t fee = dataZero["fee"]; - ASSERT_GT(fee, 0); + const auto votes = connection.api.votes.all("?limit=1&page=1"); - int confirmations = dataZero["confirmations"]; - ASSERT_NE(0, confirmations); + auto responseMatches = strcmp(expected_response.c_str(), + votes.c_str()) == 0; + ASSERT_TRUE(responseMatches); } diff --git a/test/api/wallets.cpp b/test/api/wallets.cpp index 1c15a5f4..cc0df48f 100644 --- a/test/api/wallets.cpp +++ b/test/api/wallets.cpp @@ -1,579 +1,380 @@ -#include "gmock/gmock.h" + #include "gtest/gtest.h" +#include "gmock/gmock.h" -#include "mocks/mock_api.h" +#include -#include "arkClient.h" -#include "utils/json.h" +#include "mocks/mock_api.h" using testing::_; using testing::Return; +namespace { +using namespace Ark::Client; +using namespace Ark::Client::api; +constexpr const char* tIp = "167.114.29.55"; +constexpr const int tPort = 4003; +} // namespace + +/**/ + TEST(api, test_wallet) { // NOLINT - Ark::Client::Connection connection("167.114.29.55", 4003); + Ark::Client::Connection connection(tIp, tPort); - const std::string response = R"({ + const std::string expected_response = R"({ "data": { - "address": "DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN", - "publicKey": "022cca9529ec97a772156c152a00aad155ee6708243e65c9d211a589cb5d43234d", - "balance": 12534670000000, - "isDelegate": true + "address": "DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK", + "publicKey": "02511f16ffb7b7e9afc12f04f317a11d9644e4be9eb5a5f64673946ad0f6336f34", + "username": "genesis_1", + "balance": "10035728150000", + "isDelegate": true, + "vote": "035c14e8c5f0ee049268c3e75f02f05b4246e746dc42f99271ff164b7be20cf5b8" } })"; - EXPECT_CALL(connection.api.wallets, get(_)).Times(1).WillOnce(Return(response)); - - const auto wallet = connection.api.wallets.get("DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN"); - - DynamicJsonDocument doc(300); - DeserializationError error = deserializeJson(doc, wallet); - if (error) { exit(0); } - - JsonObject data = doc["data"]; - - const auto address = data["address"]; - ASSERT_STREQ("DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN", address); - - const auto publicKey = data["publicKey"]; - ASSERT_STREQ( - "022cca9529ec97a772156c152a00aad155ee6708243e65c9d211a589cb5d43234d", - publicKey); + EXPECT_CALL(connection.api.wallets, get(_)) + .Times(1) + .WillOnce(Return(expected_response)); - uint64_t balance = data["balance"]; - ASSERT_TRUE(balance == 12534670000000); + const auto wallet = connection.api.wallets.get( + "DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK"); - bool isDelegate = data["isDelegate"]; - ASSERT_TRUE(isDelegate); + auto responseMatches = strcmp(expected_response.c_str(), + wallet.c_str()) == 0; + ASSERT_TRUE(responseMatches); } /**/ TEST(api, test_wallets) { // NOLINT - Ark::Client::Connection connection("167.114.29.55", 4003); - - const std::string response = R"({ + Ark::Client::Connection connection(tIp, tPort); + const std::string expected_response = R"({ "meta": { - "count": 2, - "pageCount": 421, - "totalCount": 841, - "next": "/v2/wallets?page=2", + "count": 1, + "pageCount": 196457, + "totalCount": 196457, + "next": "/api/wallets?limit=1&page=2", "previous": null, - "self": "/v2/wallets?page=1", - "first": "/v2/wallets?page=1", - "last": "/v2/wallets?page=421" + "self": "/api/wallets?limit=1&page=1", + "first": "/api/wallets?limit=1&page=1", + "last": "/api/wallets?limit=1&page=196457" }, "data": [ { - "address": "D59NTfV92ca9QevUydvMiFMFdubbCaAVCV", - "publicKey": "037d035f08b3bad0d5bb605232c7aa41555693c480044dbeb797270a44c339da5a", - "balance": 1023145260990, + "address": "D6Z26L69gdk9qYmTv5uzk3uGepigtHY4ax", + "publicKey": "03d3fdad9c5b25bf8880e6b519eb3611a5c0b31adebc8455f0e096175b28321aff", + "balance": "9898440219335676", "isDelegate": false } ] })"; - EXPECT_CALL(connection.api.wallets, all(_, _)).Times(1).WillOnce(Return(response)); - - const auto wallets = connection.api.wallets.all(5, 1); - - DynamicJsonDocument doc(764); - DeserializationError error = deserializeJson(doc, wallets); - if (error) { exit(0); } - - JsonObject meta = doc["meta"]; - - int count = meta["count"]; - ASSERT_NE(0, count); - - int pageCount = meta["pageCount"]; - ASSERT_NE(0, pageCount); - - int totalCount = meta["totalCount"]; - ASSERT_NE(0, totalCount); + EXPECT_CALL(connection.api.wallets, all(_)) + .Times(1) + .WillOnce(Return(expected_response)); - JsonObject dataZero = doc["data"][0]; + const auto wallets = connection.api.wallets.all("?limit=1&page=1"); - const auto address = dataZero["address"]; - ASSERT_STREQ("D59NTfV92ca9QevUydvMiFMFdubbCaAVCV", address); - - const auto publicKey = dataZero["publicKey"]; - ASSERT_STREQ( - "037d035f08b3bad0d5bb605232c7aa41555693c480044dbeb797270a44c339da5a", - publicKey); - - uint64_t balance = dataZero["balance"]; - ASSERT_TRUE(balance >= 0); - - bool isDelegate = dataZero["isDelegate"]; - ASSERT_FALSE(isDelegate); + auto responseMatches = strcmp(expected_response.c_str(), + wallets.c_str()) == 0; + ASSERT_TRUE(responseMatches); } /**/ TEST(api, test_wallets_search) { // NOLINT - Ark::Client::Connection connection("167.114.29.55", 4003); + Ark::Client::Connection connection(tIp, tPort); - const std::string response = R"({ + const std::string expected_response = R"({ "meta": { - "count": 2, - "pageCount": 2, - "totalCount": 3, - "next": "/v2/wallets/search?page=2", + "count": 1, + "pageCount": 1, + "totalCount": 1, + "next": null, "previous": null, - "self": "/v2/wallets/search?page=1", - "first": "/v2/wallets/search?page=1", - "last": "/v2/wallets/search?page=2" + "self": "/api/wallets/search?limit=1&page=1", + "first": "/api/wallets/search?limit=1&page=1", + "last": "/api/wallets/search?limit=1&page=1" }, "data": [ { - "id": "08c6b23f9edd97b613f17153fb97a316a4fb83136e9842655dafc8262f363e0e", - "blockId": "14847399772737279404", - "type": 3, - "amount": 0, - "fee": 100000000, - "sender": "DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN", - "recipient": "DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN", - "signature": "304402207ba0e8aaee93695360081b7ce713f13d62b544038ac440bd46357398af86cae6022059ac74586738be1ef622e0baba992d0e417d9aed7ab980f374eb0c9d53e25f8e", - "asset": { - "votes": [ - "+0257b7724e97cd832e0c28533a86da5220656f9b5122141daab20e8526decce01f" - ] - }, - "confirmations": 1636029, - "timestamp": { - "epoch": 17094358, - "unix": 1507195558, - "human": "2017-10-05T09:25:58Z" - } + "address": "DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK", + "publicKey": "02511f16ffb7b7e9afc12f04f317a11d9644e4be9eb5a5f64673946ad0f6336f34", + "username": "genesis_1", + "balance": "10035728150000", + "isDelegate": true, + "vote": "035c14e8c5f0ee049268c3e75f02f05b4246e746dc42f99271ff164b7be20cf5b8" } ] })"; - EXPECT_CALL(connection.api.wallets, search(_, _, _)).Times(1).WillOnce(Return(response)); - - const std::map body_parameters = { - { "username", "baldninja" }, - { "address", "DFJ5Z51F1euNNdRUQJKQVdG4h495LZkc6T" }, - { "publicKey", "03d3c6889608074b44155ad2e6577c3368e27e6e129c457418eb3e5ed029544e8d" }}; - const auto walletsSearch = connection.api.wallets.search(body_parameters, 5, 1); - - DynamicJsonDocument doc(1524); - DeserializationError error = deserializeJson(doc, walletsSearch); - if (error) { exit(0); } - - JsonObject meta = doc["meta"]; - - int count = meta["count"]; - ASSERT_NE(0, count); - - int pageCount = meta["pageCount"]; - ASSERT_NE(0, pageCount); - - int totalCount = meta["totalCount"]; - ASSERT_NE(0, totalCount); - - JsonObject dataZero = doc["data"][0]; - - const auto id = dataZero["id"]; - ASSERT_STREQ( - "08c6b23f9edd97b613f17153fb97a316a4fb83136e9842655dafc8262f363e0e", - id); + EXPECT_CALL(connection.api.wallets, search(_, _)) + .Times(1) + .WillOnce(Return(expected_response)); - const auto blockId = dataZero["blockId"]; - ASSERT_STREQ("14847399772737279404", blockId); + const std::map body = { + { "username", "genesis_1" } + }; - int type = dataZero["type"]; - ASSERT_EQ(3, type); + const auto wallets = connection.api.wallets.search(body, "?limit=1&page=1"); - uint64_t amount = dataZero["amount"]; - ASSERT_TRUE(0ULL == amount); - - uint64_t fee = dataZero["fee"]; - ASSERT_TRUE(100000000ULL == fee); - - const auto sender = dataZero["sender"]; - ASSERT_STREQ("DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN", sender); - - const auto recipient = dataZero["recipient"]; - ASSERT_STREQ("DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN", recipient); - - const auto signature = dataZero["signature"]; - ASSERT_STREQ( - "304402207ba0e8aaee93695360081b7ce713f13d62b544038ac440bd46357398af86cae6022059ac74586738be1ef622e0baba992d0e417d9aed7ab980f374eb0c9d53e25f8e", - signature); - - int confirmations = dataZero["confirmations"]; - ASSERT_EQ(1636029, confirmations); - - JsonObject timestamp = dataZero["timestamp"]; - - int epoch = timestamp["epoch"]; - ASSERT_EQ(17094358, epoch); - - int timestampUnix = timestamp["unix"]; - ASSERT_EQ(1507195558, timestampUnix); - - const auto human = timestamp["human"]; - ASSERT_STREQ("2017-10-05T09:25:58Z", human); + auto responseMatches = strcmp(expected_response.c_str(), + wallets.c_str()) == 0; + ASSERT_TRUE(responseMatches); } /**/ TEST(api, test_wallets_top) { // NOLINT - Ark::Client::Connection connection("167.114.29.55", 4003); - - const std::string response = R"({ - "meta": { - "count": 2, - "pageCount": 97849, - "totalCount": 195698, - "next": "\/api\/v2\/wallets\/top?limit=2&page=2", - "previous": null, - "self": "\/api\/v2\/wallets\/top?limit=2&page=1", - "first": "\/api\/v2\/wallets\/top?limit=2&page=1", - "last": "\/api\/v2\/wallets\/top?limit=2&page=97849" - }, - "data": [ - { - "address": "D6Z26L69gdk9qYmTv5uzk3uGepigtHY4ax", - "publicKey": "03d3fdad9c5b25bf8880e6b519eb3611a5c0b31adebc8455f0e096175b28321aff", - "balance": 10105417471949050, - "isDelegate": false - }, - { - "address": "DEyaFhDuaoQyKbFH4gJtYZvKkB6umyrEUj", - "publicKey": "033c59dcdc36944cc28f68c1e4b47ac370fe326e53f9adf5f07764d3e8b74b1838", - "username": "whalessio", - "secondPublicKey": "03820f214bd49a09c636fa366b4b3c1a0dbd2953d14aac7e68a596e0636e662dfb", - "balance": 2000035929999638, - "isDelegate": true - } - ] -})"; - - EXPECT_CALL( - connection.api.wallets, - top(_, _)) - .Times(1) - .WillOnce(Return(response)); - - const auto walletsTop = connection.api.wallets.top(2, 1); + Ark::Client::Connection connection(tIp, tPort); - DynamicJsonDocument doc(1292); - DeserializationError error = deserializeJson(doc, walletsTop); - if (error) { exit(0); } - - JsonObject meta = doc["meta"]; - - int count = meta["count"]; - ASSERT_NE(0, count); - - int pageCount = meta["pageCount"]; - ASSERT_NE(0, pageCount); - - int totalCount = meta["totalCount"]; - ASSERT_NE(0, totalCount); - - JsonObject dataZero = doc["data"][0]; - - const auto address = dataZero["address"]; - ASSERT_STREQ("D6Z26L69gdk9qYmTv5uzk3uGepigtHY4ax", address); - - const auto publicKey = dataZero["publicKey"]; - ASSERT_STREQ( - "03d3fdad9c5b25bf8880e6b519eb3611a5c0b31adebc8455f0e096175b28321aff", - publicKey); - - unsigned long long balance = dataZero["balance"]; - ASSERT_EQ(balance, 10105417471949050ULL); - - bool isDelegate = dataZero["isDelegate"]; - ASSERT_FALSE(isDelegate); - - JsonObject dataOne = doc["data"][1]; - - const auto addressOne = dataOne["address"]; - ASSERT_STREQ("DEyaFhDuaoQyKbFH4gJtYZvKkB6umyrEUj", addressOne); + const std::string expected_response = R"({ + "meta": { + "count": 1, + "pageCount": 196457, + "totalCount": 196457, + "next": "/api/wallets/top?page=2&limit=1", + "previous": null, + "self": "/api/wallets/top?page=1&limit=1", + "first": "/api/wallets/top?page=1&limit=1", + "last": "/api/wallets/top?page=196457&limit=1" + }, + "data": [ + { + "address": "D6Z26L69gdk9qYmTv5uzk3uGepigtHY4ax", + "publicKey": "03d3fdad9c5b25bf8880e6b519eb3611a5c0b31adebc8455f0e096175b28321aff", + "balance": "9898440219335676", + "isDelegate": false + } + ] + })"; - const auto publicKeyOne = dataOne["publicKey"]; - ASSERT_STREQ( - "033c59dcdc36944cc28f68c1e4b47ac370fe326e53f9adf5f07764d3e8b74b1838", - publicKeyOne); + EXPECT_CALL(connection.api.wallets, top(_)) + .Times(1) + .WillOnce(Return(expected_response)); - unsigned long long balanceOne = dataOne["balance"]; - ASSERT_EQ(balanceOne, 2000035929999638ULL); + const auto wallets = connection.api.wallets.top("?limit=1&page=1"); - const bool isDelegateOne = dataOne["isDelegate"]; - ASSERT_TRUE(isDelegateOne); + auto responseMatches = strcmp(expected_response.c_str(), + wallets.c_str()) == 0; + ASSERT_TRUE(responseMatches); } /**/ TEST(api, test_wallets_transactions) { // NOLINT - Ark::Client::Connection connection("167.114.29.55", 4003); + Ark::Client::Connection connection(tIp, tPort); - const std::string response = R"({ + const std::string expected_response = R"({ "meta": { - "count": 2, - "pageCount": 127430, - "totalCount": 254860, - "next": "/v2/wallets/boldninja/transactions?page=2", + "totalCountIsEstimate": false, + "count": 1, + "pageCount": 7, + "totalCount": 7, + "next": "/api/wallets/DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK/transactions?limit=1&page=2&transform=true", "previous": null, - "self": "/v2/wallets/boldninja/transactions?page=1", - "first": "/v2/wallets/boldninja/transactions?page=1", - "last": "/v2/wallets/boldninja/transactions?page=127430" + "self": "/api/wallets/DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK/transactions?limit=1&page=1&transform=true", + "first": "/api/wallets/DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK/transactions?limit=1&page=1&transform=true", + "last": "/api/wallets/DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK/transactions?limit=1&page=7&transform=true" }, "data": [ { - "id": "5c6ce775447a5acd22050d72e2615392494953bb1fb6287e9ffb3c33eaeb79aa", - "blockId": "4271682877946294396", + "id": "a8c0b8b9acabcb742e1760ce16aef5e92f0863bd035fd9bcb341b30d546abdad", + "blockId": "17044958519703434496", + "version": 1, "type": 0, - "amount": 32106400000, - "fee": 10000000, - "sender": "DDiTHZ4RETZhGxcyAi1VruCXZKxBFqXMeh", - "recipient": "DQnQNoJuNCvpjYhxL7fsnGepHBqrumgsyP", - "signature": "3044022047c39f6f45a46a87f91ca867f9551dbebf0035adcfcbdc1370222c7a1517fc0002206fb5ecc10460e0352a8b626a508e2fcc76e39e490b0a2581dd772ebc8079696e", - "confirmations": 1683, + "amount": "100000000", + "fee": "10000000", + "sender": "D6Z26L69gdk9qYmTv5uzk3uGepigtHY4ax", + "senderPublicKey": "03d3fdad9c5b25bf8880e6b519eb3611a5c0b31adebc8455f0e096175b28321aff", + "recipient": "DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK", + "signature": "3045022100cde3452fa74e8d9c2ed8187467edd631e55eb9bde5de4a62b7f52ec3d57399a602201827ead48ae19255770d10608fad103dc497f47458737edfae6abebbdd82245e", + "confirmations": 2920745, "timestamp": { - "epoch": 32794053, - "unix": 1522895253, - "human": "2018-04-05T02:27:33Z" + "epoch": 45021207, + "unix": 1535122407, + "human": "2018-08-24T14:53:27.000Z" } } ] })"; - EXPECT_CALL(connection.api.wallets, transactions(_, _, _)).Times(1).WillOnce(Return(response)); + EXPECT_CALL(connection.api.wallets, transactions(_, _)) + .Times(1) + .WillOnce(Return(expected_response)); - const auto walletsTransactions = connection.api.wallets.transactions( - "DDiTHZ4RETZhGxcyAi1VruCXZKxBFqXMeh", - 2, 1); + const auto transactions = connection.api.wallets.transactions( + "DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK", "?limit=1&page=1"); - DynamicJsonDocument doc(1420); - DeserializationError error = deserializeJson(doc, walletsTransactions); - if (error) { exit(0); } - - JsonObject meta = doc["meta"]; - - int count = meta["count"]; - ASSERT_EQ(2, count); + auto responseMatches = strcmp(expected_response.c_str(), + transactions.c_str()) == 0; + ASSERT_TRUE(responseMatches); } /**/ TEST(api, test_wallets_transactions_received) { // NOLINT - Ark::Client::Connection connection("167.114.29.55", 4003); + Ark::Client::Connection connection(tIp, tPort); - const std::string response = R"({ + const std::string expected_response = R"({ "meta": { - "count": 2, - "pageCount": 4, - "totalCount": 8, - "next": "/v2/wallets/boldninja/transactions/received?page=2", + "totalCountIsEstimate": false, + "count": 1, + "pageCount": 7, + "totalCount": 7, + "next": "/api/wallets/DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK/transactions/received?limit=1&page=2&transform=true", "previous": null, - "self": "/v2/wallets/boldninja/transactions/received?page=1", - "first": "/v2/wallets/boldninja/transactions/received?page=1", - "last": "/v2/wallets/boldninja/transactions/received?page=4" + "self": "/api/wallets/DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK/transactions/received?limit=1&page=1&transform=true", + "first": "/api/wallets/DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK/transactions/received?limit=1&page=1&transform=true", + "last": "/api/wallets/DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK/transactions/received?limit=1&page=7&transform=true" }, "data": [ { - "id": "c46a6a83f7a358f269691c16f050beeab669767643634086bc12ad1182d54413", - "blockId": "17271524574301696572", - "type": 0, - "amount": 5000000000, - "fee": 10000000, - "sender": "DK6Q1Lufhb939H9EshLViYbaaKUkswMiUz", - "recipient": "DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN", - "signature": "304402204b81411e507273f2a27e6135510abda5bff00a0d3121977df09363227c8fd2360220503cab4484a7db785d91a7adcfad681811e3d73f2d00b4dab7e4190ecd41cb34", - "vendorField": "More monopoly money for EVERYONE!!", - "confirmations": 1482069, + "id": "6b3d348a4341de3ea281d0af584d04ba78f14154955ac14af044a11bd43388cd", + "blockId": "35da9ef1a5ffb396a180a1ccb7b40ee32ddfced5b6c24cb7133c926e8e66796a", + "version": 1, + "type": 3, + "amount": "0", + "fee": "10000000", + "sender": "DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK", + "senderPublicKey": "02511f16ffb7b7e9afc12f04f317a11d9644e4be9eb5a5f64673946ad0f6336f34", + "recipient": "DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK", + "signature": "3044022052b1d1f49c2efcbd306906449f6f46824db31110e3afbc0ed6fdca2ca5b3d59c0220039dfc70a8b48d49c5df12a7cbbb0cadc969078786d4824d25e8ff251360e763", + "asset": { + "votes": [ + "+035c14e8c5f0ee049268c3e75f02f05b4246e746dc42f99271ff164b7be20cf5b8" + ] + }, + "confirmations": 218052, "timestamp": { - "epoch": 18382414, - "unix": 1508483614, - "human": "2017-10-20T07:13:34Z" + "epoch": 70926445, + "unix": 1561027645, + "human": "2019-06-20T10:47:25.000Z" } } ] })"; - EXPECT_CALL(connection.api.wallets, transactionsReceived(_, _, _)).Times(1).WillOnce(Return(response)); - - const auto walletsTransactionsReceived = connection.api.wallets.transactionsReceived( - "DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN", - 2, 1); - - DynamicJsonDocument doc(1532); - DeserializationError error = deserializeJson(doc, walletsTransactionsReceived); - if (error) { exit(0); } - - JsonObject meta = doc["meta"]; - - int count = meta["count"]; - ASSERT_NE(0, count); + EXPECT_CALL(connection.api.wallets, transactionsReceived(_, _)) + .Times(1) + .WillOnce(Return(expected_response)); - int pageCount = meta["pageCount"]; - ASSERT_NE(0, pageCount); + const auto received = connection.api.wallets.transactionsReceived( + "DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK", "?limit=1&page=1"); - int totalCount = meta["totalCount"]; - ASSERT_NE(0, totalCount); + auto responseMatches = strcmp(expected_response.c_str(), + received.c_str()) == 0; + ASSERT_TRUE(responseMatches); } /**/ TEST(api, test_wallets_transactions_sent) { // NOLINT - Ark::Client::Connection connection("167.114.29.55", 4003); + Ark::Client::Connection connection(tIp, tPort); - const std::string response = R"({ + const std::string expected_response = R"({ "meta": { - "count": 2, - "pageCount": 2, + "totalCountIsEstimate": false, + "count": 1, + "pageCount": 4, "totalCount": 4, - "next": "/v2/wallets/boldninja/transactions/sent?page=2", + "next": "/api/wallets/DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK/transactions/sent?limit=1&page=2&transform=true", "previous": null, - "self": "/v2/wallets/boldninja/transactions/sent?page=1", - "first": "/v2/wallets/boldninja/transactions/sent?page=1", - "last": "/v2/wallets/boldninja/transactions/sent?page=2" + "self": "/api/wallets/DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK/transactions/sent?limit=1&page=1&transform=true", + "first": "/api/wallets/DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK/transactions/sent?limit=1&page=1&transform=true", + "last": "/api/wallets/DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK/transactions/sent?limit=1&page=4&transform=true" }, "data": [ { - "id": "08c6b23f9edd97b613f17153fb97a316a4fb83136e9842655dafc8262f363e0e", - "blockId": "14847399772737279404", + "id": "6b3d348a4341de3ea281d0af584d04ba78f14154955ac14af044a11bd43388cd", + "blockId": "35da9ef1a5ffb396a180a1ccb7b40ee32ddfced5b6c24cb7133c926e8e66796a", + "version": 1, "type": 3, - "amount": 0, - "fee": 100000000, - "sender": "DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN", - "recipient": "DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN", - "signature": "304402207ba0e8aaee93695360081b7ce713f13d62b544038ac440bd46357398af86cae6022059ac74586738be1ef622e0baba992d0e417d9aed7ab980f374eb0c9d53e25f8e", + "amount": "0", + "fee": "10000000", + "sender": "DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK", + "senderPublicKey": "02511f16ffb7b7e9afc12f04f317a11d9644e4be9eb5a5f64673946ad0f6336f34", + "recipient": "DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK", + "signature": "3044022052b1d1f49c2efcbd306906449f6f46824db31110e3afbc0ed6fdca2ca5b3d59c0220039dfc70a8b48d49c5df12a7cbbb0cadc969078786d4824d25e8ff251360e763", "asset": { "votes": [ - "+0257b7724e97cd832e0c28533a86da5220656f9b5122141daab20e8526decce01f" + "+035c14e8c5f0ee049268c3e75f02f05b4246e746dc42f99271ff164b7be20cf5b8" ] }, - "confirmations": 1636232, + "confirmations": 218061, "timestamp": { - "epoch": 17094358, - "unix": 1507195558, - "human": "2017-10-05T09:25:58Z" + "epoch": 70926445, + "unix": 1561027645, + "human": "2019-06-20T10:47:25.000Z" } } ] })"; - EXPECT_CALL(connection.api.wallets, transactionsSent(_, _, _)).Times(1).WillOnce(Return(response)); - - const auto walletsTransactionsSent = connection.api.wallets.transactionsSent( - "DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN", - 2, 1); - - DynamicJsonDocument doc(1612); - DeserializationError error = deserializeJson(doc, walletsTransactionsSent); - if (error) { exit(0); } - - JsonObject meta = doc["meta"]; - - int count = meta["count"]; - ASSERT_NE(0, count); - - int pageCount = meta["pageCount"]; - ASSERT_NE(0, pageCount); + EXPECT_CALL(connection.api.wallets, transactionsSent(_, _)) + .Times(1) + .WillOnce(Return(expected_response)); - int totalCount = meta["totalCount"]; - ASSERT_NE(0, totalCount); + const auto sent = connection.api.wallets.transactionsSent( + "DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK", "?limit=1&page=1"); - JsonObject dataZero = doc["data"][0]; - - const auto id = dataZero["id"]; - ASSERT_STREQ( - "08c6b23f9edd97b613f17153fb97a316a4fb83136e9842655dafc8262f363e0e", - id); - - const auto blockId = dataZero["blockId"]; - ASSERT_STREQ("14847399772737279404", blockId); - - const auto sender = dataZero["sender"]; - ASSERT_STREQ("DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN", sender); - - const auto recipient = dataZero["recipient"]; - ASSERT_STREQ("DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN", recipient); - - const auto signature = dataZero["signature"]; - ASSERT_STREQ( - "304402207ba0e8aaee93695360081b7ce713f13d62b544038ac440bd46357398af86cae6022059ac74586738be1ef622e0baba992d0e417d9aed7ab980f374eb0c9d53e25f8e", - signature); + auto responseMatches = strcmp(expected_response.c_str(), + sent.c_str()) == 0; + ASSERT_TRUE(responseMatches); } /**/ TEST(api, test_wallets_votes) { // NOLINT - Ark::Client::Connection connection("167.114.29.55", 4003); + Ark::Client::Connection connection(tIp, tPort); - const std::string response = R"({ + const std::string expected_response = R"({ "meta": { - "count": 2, - "pageCount": 2, + "totalCountIsEstimate": false, + "count": 1, + "pageCount": 3, "totalCount": 3, - "next": "/v2/wallets/boldninja/votes?page=2", + "next": "/api/wallets/DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK/votes?limit=1&page=2&transform=true", "previous": null, - "self": "/v2/wallets/boldninja/votes?page=1", - "first": "/v2/wallets/boldninja/votes?page=1", - "last": "/v2/wallets/boldninja/votes?page=2" + "self": "/api/wallets/DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK/votes?limit=1&page=1&transform=true", + "first": "/api/wallets/DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK/votes?limit=1&page=1&transform=true", + "last": "/api/wallets/DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK/votes?limit=1&page=3&transform=true" }, "data": [ { - "id": "08c6b23f9edd97b613f17153fb97a316a4fb83136e9842655dafc8262f363e0e", - "blockId": "14847399772737279404", + "id": "6b3d348a4341de3ea281d0af584d04ba78f14154955ac14af044a11bd43388cd", + "blockId": "35da9ef1a5ffb396a180a1ccb7b40ee32ddfced5b6c24cb7133c926e8e66796a", + "version": 1, "type": 3, - "amount": 0, - "fee": 100000000, - "sender": "DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN", - "recipient": "DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN", - "signature": "304402207ba0e8aaee93695360081b7ce713f13d62b544038ac440bd46357398af86cae6022059ac74586738be1ef622e0baba992d0e417d9aed7ab980f374eb0c9d53e25f8e", + "amount": "0", + "fee": "10000000", + "sender": "DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK", + "senderPublicKey": "02511f16ffb7b7e9afc12f04f317a11d9644e4be9eb5a5f64673946ad0f6336f34", + "recipient": "DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK", + "signature": "3044022052b1d1f49c2efcbd306906449f6f46824db31110e3afbc0ed6fdca2ca5b3d59c0220039dfc70a8b48d49c5df12a7cbbb0cadc969078786d4824d25e8ff251360e763", "asset": { "votes": [ - "+0257b7724e97cd832e0c28533a86da5220656f9b5122141daab20e8526decce01f" + "+035c14e8c5f0ee049268c3e75f02f05b4246e746dc42f99271ff164b7be20cf5b8" ] }, - "confirmations": 1636029, + "confirmations": 218065, "timestamp": { - "epoch": 17094358, - "unix": 1507195558, - "human": "2017-10-05T09:25:58Z" + "epoch": 70926445, + "unix": 1561027645, + "human": "2019-06-20T10:47:25.000Z" } } ] })"; - EXPECT_CALL(connection.api.wallets, votes(_, _, _)).Times(1).WillOnce(Return(response)); - - const auto walletsVotes = connection.api.wallets.votes("DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN", 1, 1); - - DynamicJsonDocument doc(1612); - DeserializationError error = deserializeJson(doc, walletsVotes); - if (error) { exit(0); } - - JsonObject meta = doc["meta"]; - - int count = meta["count"]; - ASSERT_GT(count, 0); - - JsonObject dataZero = doc["data"][0]; - - const auto id = dataZero["id"]; - ASSERT_STREQ( - "08c6b23f9edd97b613f17153fb97a316a4fb83136e9842655dafc8262f363e0e", - id); - - const auto blockId = dataZero["blockId"]; - ASSERT_STREQ("14847399772737279404", blockId); - - const auto sender = dataZero["sender"]; - ASSERT_STREQ("DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN", sender); + EXPECT_CALL(connection.api.wallets, votes(_, _)) + .Times(1) + .WillOnce(Return(expected_response)); - const auto recipient = dataZero["recipient"]; - ASSERT_STREQ("DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN", recipient); +const auto votes = connection.api.wallets.votes( + "DL6wmfnA2acPLpBjKS4zPGsSwxkTtGANsK", "?limit=1&page=1"); - const auto signature = dataZero["signature"]; - ASSERT_STREQ( - "304402207ba0e8aaee93695360081b7ce713f13d62b544038ac440bd46357398af86cae6022059ac74586738be1ef622e0baba992d0e417d9aed7ab980f374eb0c9d53e25f8e", - signature); + auto responseMatches = strcmp(expected_response.c_str(), + votes.c_str()) == 0; + ASSERT_TRUE(responseMatches); } diff --git a/test/connection/connection.cpp b/test/connection/connection.cpp index 4aaf990c..882dc71b 100644 --- a/test/connection/connection.cpp +++ b/test/connection/connection.cpp @@ -1,15 +1,76 @@ -#include "arkClient.h" -#include "gmock/gmock.h" #include "gtest/gtest.h" +#include "gmock/gmock.h" + +#include + #include "mocks/mock_api.h" +#include "host/host.h" +#include "http/http.h" +#include "api/base.h" + +namespace { +using namespace Ark::Client; +constexpr const char* tIp = "167.114.29.55"; +constexpr const int tPort = 4003; +constexpr const char* tHost = "167.114.29.55:4003"; +constexpr const int tUPort = -1; +} // namespace + +/**/ + +namespace { +class IMockTestApi : public Ark::Client::api::Base { + public: + virtual ~IMockTestApi() = default; + virtual std::string get() = 0; + protected: + IMockTestApi(Ark::Client::Host& host, Ark::Client::IHTTP& http) + : Ark::Client::api::Base(host, http) {} +}; +/**/ +class MockTestApi : public IMockTestApi { + public: + MockTestApi(Ark::Client::Host& host, Ark::Client::IHTTP& http) + : IMockTestApi(host, http) {} + std::string get() override { return "test"; }; +}; +/**/ +class tApi : public Ark::Client::api::Abstract { + public: + tApi(): Abstract(new MockHTTP()), test_(host_, *http_) {} -TEST(api, test_connection) { // NOLINT - Ark::Client::Connection connection("167.114.29.55", 4003); + MockTestApi test() { return this->test_; }; + private: + MockTestApi test_; +}; +/**/ +constexpr const char* tMockApi2Response = "test"; +} // namespace + +/**/ + +TEST(connection, constructor_default) { + Connection connection; + ASSERT_TRUE(connection.host.ip().empty()); + ASSERT_EQ(connection.host.port(), tUPort); +} + +/**/ + +TEST(connection, constructor_api) { + Connection connection1; + auto connection2 = (Connection()); + + ASSERT_STREQ(connection2.api.test().get().c_str(), tMockApi2Response); +} - const auto ip = connection.host.ip().c_str(); - ASSERT_STREQ("167.114.29.55", ip); +/**/ - int port = connection.host.port(); - ASSERT_EQ(4003, port); +TEST(connection, constructor_ip_port) { + Connection connection(tIp, tPort); + const auto hostIp = connection.host.ip(); + ASSERT_STREQ(hostIp.c_str(), tIp); + ASSERT_EQ(connection.host.port(), tPort); + ASSERT_STREQ(connection.host.toString().c_str(), tHost); } diff --git a/test/host/host.cpp b/test/host/host.cpp index 030f37a1..41115e64 100644 --- a/test/host/host.cpp +++ b/test/host/host.cpp @@ -1,36 +1,58 @@ -#include "host/host.h" #include "gtest/gtest.h" -TEST(api, test_host) { // NOLINT - const auto expectedIp = "167.114.29.55"; - const auto expectedPort = 4003; - const auto expectedHost = "167.114.29.55:4003"; - - // create a test host - Ark::Client::Host host(expectedIp, expectedPort); - - // check the host // - // check the IP - const auto ip = host.ip().c_str(); - ASSERT_STREQ(expectedIp, ip); - // check the Port - int port = host.port(); - ASSERT_EQ(expectedPort, port); - // check the host string - const auto hostString = host.toString().c_str(); - ASSERT_STREQ(expectedHost, hostString); - - // test setting the host // - Ark::Client::Host setHost; - setHost.set(expectedIp, expectedPort); - ASSERT_STREQ(setHost.toString().c_str(), host.toString().c_str()); - - // test the copy constructor // - Ark::Client::Host copiedHost(host); - ASSERT_STREQ(copiedHost.toString().c_str(), host.toString().c_str()); - - // test the assignment constructor // - Ark::Client::Host assignedHost(host); - ASSERT_STREQ(assignedHost.toString().c_str(), host.toString().c_str()); +#include "host/host.h" + +namespace { +using namespace Ark::Client; +constexpr const char* tIp = "167.114.29.55"; +constexpr const int tPort = 4003; +constexpr const char* tHost = "167.114.29.55:4003"; +constexpr const int tUPort = -1; +} // namespace + +/**/ + +TEST(host, constructor_default) { + Host host; + ASSERT_TRUE(host.ip().empty()); + ASSERT_EQ(host.port(), tUPort); +} + +/**/ + +TEST(host, constructor_ip_port) { + Host host(tIp, tPort); + ASSERT_STREQ(host.ip().c_str(), tIp); + ASSERT_EQ(host.port(), tPort); +} + +/**/ + +TEST(host, get_ip) { + Host host(tIp, tPort); + ASSERT_STREQ(host.ip().c_str(), tIp); +} + +/**/ + +TEST(host, get_port) { + Host host(tIp, tPort); + ASSERT_EQ(host.port(), tPort); +} + +/**/ + +TEST(host, set_host) { + Host host; + ASSERT_TRUE(host.set(tIp, tPort)); + ASSERT_STREQ(host.ip().c_str(), tIp); + ASSERT_EQ(host.port(), tPort); +} + +/**/ + +TEST(host, to_string) { + Host host(tIp, tPort); + ASSERT_STREQ(host.toString().c_str(), tHost); } diff --git a/test/http/http.cpp b/test/http/http.cpp index 57da9308..5386954a 100644 --- a/test/http/http.cpp +++ b/test/http/http.cpp @@ -1,26 +1,29 @@ + #include "gtest/gtest.h" + +#include +#include + #include "http/http.h" -#include "utils/json.h" -// Note: These test HTTP against a live node +// Note: These test HTTP against a live server -#include +namespace { +using namespace Ark::Client; +constexpr const size_t HTTPS_MAX_ELEMENTS = 3U; +} // namespace TEST(api, test_http_get) { // NOLINT // Create the HTTP object - const auto http = Ark::Client::makeHTTP(); + const auto http = makeHTTP(); + + // Create a request + const auto request = "postman-echo.com/get?foo=bar"; // Get the response using HTTP - const auto response = http->get("167.114.29.55:4003/api/node/status"); - - // Create a JSON object of the result - const size_t capacity = JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(4) + 50; - DynamicJsonDocument doc(capacity); - DeserializationError error = deserializeJson(doc, response); - ASSERT_FALSE(error); - // Test JSON object for the "data" key. - // The correct response will include this key. - ASSERT_TRUE(doc.containsKey("data")); + const auto response = http->get(request); + + ASSERT_LT(response.find("bar"), response.length()); } /**/ @@ -28,25 +31,16 @@ TEST(api, test_http_get) { // NOLINT // Tests POSTing of HTTP body. TEST(api, test_http_post_body) { // NOLINT // Create the HTTP object - const auto http = Ark::Client::makeHTTP(); + const auto http = makeHTTP(); // Create a Request URL and 'Post' body. - const auto request = "167.114.29.55:4003/api/v2/wallets/search?limit=1&page=1"; - const auto body = "{\"username\":\"baldninja\"}"; + const auto request = "postman-echo.com/post"; + const auto body = "This should be sent back as part of response body."; // Post the 'request' and 'body' for a response using HTTP const auto response = http->post(request, body); - // Create a JSON object of the result - const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(2) - + JSON_OBJECT_SIZE(6) + JSON_OBJECT_SIZE(8) + 470; - DynamicJsonDocument doc(capacity); - DeserializationError error = deserializeJson(doc, response); - ASSERT_FALSE(error); - - // Test JSON object for the "meta" key. - // The correct response will include this key - ASSERT_TRUE(doc.containsKey("meta")); + ASSERT_LT(response.find(body), response.length()); } /**/ @@ -54,11 +48,11 @@ TEST(api, test_http_post_body) { // NOLINT // Tests invalid POSTing of HTTP body. TEST(api, test_http_invalid_post_body) { // NOLINT // Create the HTTP object - const auto http = Ark::Client::makeHTTP(); + const auto http = makeHTTP(); // Create a malformed Request URL and 'Post' body. - const auto request = "/167.114.29.55:4003/api/v2/wallets/search"; - const auto body = "{\"username\":\"baldninja\"}"; + const auto request = "/167.114.29.55:4003/api/wallets/search"; + const auto body = R"({"username":"baldninja"})"; // Post the 'request' and 'body' for a response using HTTP const auto response = http->post(request, body); @@ -75,61 +69,41 @@ TEST(api, test_http_invalid_post_body) { // NOLINT // Tests POSTing of JSON. TEST(api, test_http_post_json) { // NOLINT // Create the HTTP object - const auto http = Ark::Client::makeHTTP(); + const auto http = makeHTTP(); // Create a Request URL and an empty Transaction JSON. - const auto request = "167.114.29.55:4003/api/v2/transactions"; - const auto txJson = "{\"transactions\":[]}"; + const auto request = "167.114.29.55:4003/api/transactions"; + const auto txJson = R"({"transactions":[]})"; // Post the 'request' and 'txJson' for a response using HTTP const auto response = http->post(request, txJson); - // Create a JSON object of the result - const size_t capacity = JSON_OBJECT_SIZE(3) + 90; - DynamicJsonDocument doc(capacity); - DeserializationError error = deserializeJson(doc, response); - ASSERT_FALSE(error); - - // Test JSON object for the "message" key. - // The correct response will include the following - ASSERT_EQ(422, doc["statusCode"]); + ASSERT_LT(response.find("422"), response.length()); } /**/ // This tests the use of "http://" in single-line HTTP requests. TEST(api, test_http_request_strings) { // NOLINT - char requests[3][43] = { - "167.114.29.55:4003/api/node/status", // No HTTP - "http://167.114.29.55:4003/api/node/status", // HTTP - "https://dexplorer.ark.io/api/node/status" // HTTPS + std::array requests = { + "postman-echo.com/get", // No HTTP prefix + "http://postman-echo.com/get", // HTTP + "https://postman-echo.com/get" // HTTPS }; // Create the HTTP object - const auto http = Ark::Client::makeHTTP(); + const auto http = makeHTTP(); - for (auto i: requests) { + for (auto& i: requests) { // Get the response using HTTP - const auto response = http->get(i); - - // Create a JSON object of the result - const size_t capacity = JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(4) + 50; - DynamicJsonDocument doc(capacity); - DeserializationError error = deserializeJson(doc, response); - - // Test JSON object for the "data" key. + const auto response = http->get(i.c_str()); #ifdef USE_IOT // HTTPS is NOT supported on IoT and should fail to parse. - if (std::string(i).find("https://") != 0) { - ASSERT_FALSE(error); - ASSERT_TRUE(doc.containsKey("data")); - } else { - ASSERT_TRUE(error); - ASSERT_FALSE(doc.containsKey("data")); - }; + response.find("https://") < response.length()) + ? ASSERT_TRUE(response.empth()) + : ASSERT_LT(response.find("args"), response.length()); #else // OS Builds - ASSERT_FALSE(error); - ASSERT_TRUE(doc.containsKey("data")); + ASSERT_LT(response.find("args"), response.length()); #endif }; } diff --git a/test/lib/ArduinoJson b/test/lib/ArduinoJson deleted file mode 160000 index 2af003e4..00000000 --- a/test/lib/ArduinoJson +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2af003e4e23daae15b4156ea58a2ddba905b04e0 diff --git a/test/lib/googletest b/test/lib/googletest deleted file mode 160000 index 3cf8f514..00000000 --- a/test/lib/googletest +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 3cf8f514d859d65b7202e51c662a03a92887b8e2 diff --git a/test/mocks/mock_api.h b/test/mocks/mock_api.h index 897e46fc..df7676fa 100644 --- a/test/mocks/mock_api.h +++ b/test/mocks/mock_api.h @@ -17,109 +17,135 @@ #include "http/http.h" #include "mocks/mock_http.h" -class MockBlocks : public Ark::Client::API::IBlocks { +class MockBlockchain : public Ark::Client::api::IBlockchain { // NOLINT +public: + MockBlockchain(Ark::Client::Host& host, Ark::Client::IHTTP& http) : IBlockchain(host, http) {} + + MOCK_METHOD0(get, std::string()); +}; + +/**/ + +class MockBlocks : public Ark::Client::api::IBlocks { // NOLINT public: MockBlocks(Ark::Client::Host& host, Ark::Client::IHTTP& http) : IBlocks(host, http) {} MOCK_METHOD1(get, std::string(const char* const)); - MOCK_METHOD2(all, std::string(int, int)); + MOCK_METHOD1(all, std::string(const char* const)); MOCK_METHOD1(transactions, std::string(const char* const)); - MOCK_METHOD3(search, std::string(const std::map&, int, int)); + MOCK_METHOD2(search, std::string(const std::map&, const char* const)); }; /**/ -class MockDelegates : public Ark::Client::API::IDelegates { +class MockDelegates : public Ark::Client::api::IDelegates { // NOLINT public: MockDelegates(Ark::Client::Host& host, Ark::Client::IHTTP& http) : IDelegates(host, http) {} MOCK_METHOD1(get, std::string(const char* const)); - MOCK_METHOD2(all, std::string(int, int)); - MOCK_METHOD3(blocks, std::string(const char* const, int, int)); - MOCK_METHOD3(voters, std::string(const char* const, int, int)); + MOCK_METHOD1(all, std::string(const char* const)); + MOCK_METHOD2(blocks, std::string(const char* const, const char* const)); + MOCK_METHOD2(voters, std::string(const char* const, const char* const)); }; /**/ -class MockNode : public Ark::Client::API::INode { +class MockNode : public Ark::Client::api::INode { // NOLINT public: MockNode(Ark::Client::Host& host, Ark::Client::IHTTP& http) : INode(host, http) {} MOCK_METHOD0(configuration, std::string()); + MOCK_METHOD0(crypto, std::string()); + MOCK_METHOD1(fees, std::string(const char* const)); MOCK_METHOD0(status, std::string()); MOCK_METHOD0(syncing, std::string()); }; /**/ -class MockPeers : public Ark::Client::API::IPeers { +class MockPeers : public Ark::Client::api::IPeers { // NOLINT public: MockPeers(Ark::Client::Host& host, Ark::Client::IHTTP& http) : IPeers(host, http) {} MOCK_METHOD1(get, std::string(const char* const)); - MOCK_METHOD2(all, std::string(int, int)); + MOCK_METHOD1(all, std::string(const char* const)); +}; + +/**/ + +class MockRounds : public Ark::Client::api::IRounds { // NOLINT +public: + MockRounds(Ark::Client::Host& host, Ark::Client::IHTTP& http) : IRounds(host, http) {} + + MOCK_METHOD1(delegates, std::string(const char* const)); }; -class MockTransactions : public Ark::Client::API::ITransactions { +/**/ + +class MockTransactions : public Ark::Client::api::ITransactions { // NOLINT public: MockTransactions(Ark::Client::Host& host, Ark::Client::IHTTP& http) : ITransactions(host, http) {} MOCK_METHOD1(getUnconfirmed, std::string(const char* const)); MOCK_METHOD1(get, std::string(const char* const)); - MOCK_METHOD2(all, std::string(int, int)); - MOCK_METHOD2(allUnconfirmed, std::string(int, int)); + MOCK_METHOD1(all, std::string(const char* const)); + MOCK_METHOD1(allUnconfirmed, std::string(const char* const)); MOCK_METHOD0(types, std::string()); - MOCK_METHOD3(search, std::string(const std::map&, int, int)); + MOCK_METHOD0(fees, std::string()); + MOCK_METHOD2(search, std::string(const std::map&, const char* const)); MOCK_METHOD1(send, std::string(std::string&)); }; /**/ -class MockVotes : public Ark::Client::API::IVotes { +class MockVotes : public Ark::Client::api::IVotes { // NOLINT public: MockVotes(Ark::Client::Host& host, Ark::Client::IHTTP& http) : IVotes(host, http) {} MOCK_METHOD1(get, std::string(const char* const)); - MOCK_METHOD2(all, std::string(int, int)); + MOCK_METHOD1(all, std::string(const char* const)); }; /**/ -class MockWallets : public Ark::Client::API::IWallets { +class MockWallets : public Ark::Client::api::IWallets { // NOLINT public: MockWallets(Ark::Client::Host& host, Ark::Client::IHTTP& http) : IWallets(host, http) {} MOCK_METHOD1(get, std::string(const char* const)); - MOCK_METHOD2(all, std::string(int, int)); - MOCK_METHOD2(top, std::string(int, int)); - MOCK_METHOD3(transactions, std::string(const char* const, int, int)); - MOCK_METHOD3(transactionsReceived, std::string(const char* const, int, int)); - MOCK_METHOD3(transactionsSent, std::string(const char* const, int, int)); - MOCK_METHOD3(votes, std::string(const char* const, int, int)); - MOCK_METHOD3(search, std::string(const std::map&, int, int)); + MOCK_METHOD1(all, std::string(const char* const)); + MOCK_METHOD1(top, std::string(const char* const)); + MOCK_METHOD2(transactions, std::string(const char* const, const char* const)); + MOCK_METHOD2(transactionsReceived, std::string(const char* const, const char* const)); + MOCK_METHOD2(transactionsSent, std::string(const char* const, const char* const)); + MOCK_METHOD2(votes, std::string(const char* const, const char* const)); + MOCK_METHOD2(search, std::string(const std::map&, const char* const)); }; /**/ -class MockApi : public Ark::Client::API::Abstract { +class MockApi : public Ark::Client::api::Abstract { public: + MockBlockchain blockchain; MockBlocks blocks; MockDelegates delegates; MockNode node; MockPeers peers; + MockRounds rounds; MockTransactions transactions; MockVotes votes; MockWallets wallets; - MockApi() - : Abstract(new MockHTTP()), - blocks(host_, *http_), - delegates(host_, *http_), - node(host_, *http_), - peers(host_, *http_), - transactions(host_, *http_), - votes(host_, *http_), - wallets(host_, *http_) {} + MockApi() : Abstract(new MockHTTP()), + blockchain(host_, *http_), + blocks(host_, *http_), + delegates(host_, *http_), + node(host_, *http_), + peers(host_, *http_), + rounds(host_, *http_), + transactions(host_, *http_), + votes(host_, *http_), + wallets(host_, *http_) {} }; #endif diff --git a/test/mocks/mock_http.h b/test/mocks/mock_http.h index 1e9240a9..6aba784f 100644 --- a/test/mocks/mock_http.h +++ b/test/mocks/mock_http.h @@ -7,8 +7,8 @@ class MockHTTP : public Ark::Client::IHTTP { public: - MOCK_METHOD1(get, std::string(const char* const)); - MOCK_METHOD2(post, std::string(const char* const, const char* const)); + MOCK_METHOD1(get, std::string(const char*)); + MOCK_METHOD2(post, std::string(const char*, const char*)); }; #endif diff --git a/test/platformio.ini b/test/platformio.ini index 0434a752..f833d017 100644 --- a/test/platformio.ini +++ b/test/platformio.ini @@ -10,16 +10,16 @@ [platformio] description = "Unit Tests for Ark-Cpp-Client" -src_dir = .. -lib_dir = .. +src_dir = ../src +build_dir = ../build/.pioenvs +libdeps_dir = ../extern/.piolibdeps [common] -lib_ldf_mode = deep -lib_deps = ArduinoJson@6.10.1, googletest +lib_deps = googletest@1.8.1 # ignore the 'test' lib. This isn't real but the build system somehow thinks that the test directory is also a library and does some double compiling of files lib_ignore = test -build_flags = -I../src -I../src/include/cpp-client -I./test -I. -I.. -DUNIT_TEST -src_filter = +<*> -<.git/> - - - -<_3rdParty> - - - - #ignore live HTTP tests on IoT +build_flags = -I../test -I../src -I../src/include/cpp-client -DUNIT_TEST +src_filter = +<../src> +<../test/iot> -<../src/http/os> -<../test/http> #ignore live HTTP tests on IoT upload_speed = 921600 # esp8266 unit tests disabled until GTest/GMock support is worked out @@ -27,7 +27,6 @@ upload_speed = 921600 #platform = espressif8266 #board = huzzah #framework = arduino -#lib_ldf_mode = ${common.lib_ldf_mode} #lib_deps = ${common.lib_deps} #lib_ignore = ${common.lib_ignore} #build_flags = ${common.build_flags} @@ -38,7 +37,6 @@ upload_speed = 921600 platform = espressif32 board = esp32dev framework = arduino -lib_ldf_mode = ${common.lib_ldf_mode} lib_ignore = ${common.lib_ignore} lib_deps = ${common.lib_deps} build_flags = ${common.build_flags} diff --git a/test/utils/json.h b/test/utils/json.h deleted file mode 100644 index a81f9f25..00000000 --- a/test/utils/json.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef JSON_H -#define JSON_H - -/* ArduinoJson Presets */ -#define ARDUINOJSON_USE_LONG_LONG 1 -#define ARDUINOJSON_ENABLE_STD_STRING 1 // Enable 'std::string' -#define ARDUINOJSON_ENABLE_ARDUINO_STRING 0 // disable 'String' - -/* ArduinoJson Header */ -#include "ArduinoJson.h" - -#endif