Merge 884958b0c7 into 4a5c5ae742
5
.gitattributes
vendored
|
|
@ -1,2 +1,5 @@
|
|||
.git* export-ignore
|
||||
/CMakeLists.txt export-subst
|
||||
/CMakeLists.txt export-subst
|
||||
|
||||
# Mark auto-generated SDK clients as "generated" to hide them in GitHub diffs
|
||||
utils/sdk/client/** linguist-generated=true
|
||||
2
.github/workflows/build-docker.yml
vendored
|
|
@ -43,7 +43,7 @@ jobs:
|
|||
DOCKER_BUILD_SUMMARY: false
|
||||
DOCKER_BUILD_RECORD_UPLOAD: false
|
||||
with:
|
||||
file: utils/docker/images/lthn-chain/Dockerfile
|
||||
file: utils/docker/lthn-chain/Dockerfile
|
||||
context: ${{ github.workspace }}
|
||||
push: true
|
||||
build-args: |
|
||||
|
|
|
|||
4
.github/workflows/build-linux-arm64.yml
vendored
|
|
@ -62,7 +62,7 @@ jobs:
|
|||
submodules: recursive
|
||||
|
||||
- name: install dependencies
|
||||
run: sudo apt-get install -y autotools-dev git build-essential libcairo2-dev libfreetype6-dev libffi-dev libjpeg-dev libpng-dev libz-dev pngquant
|
||||
run: sudo apt-get install -y autotools-dev rpm git build-essential libcairo2-dev libfreetype6-dev libffi-dev libjpeg-dev libpng-dev libz-dev pngquant
|
||||
|
||||
- name: Cache SDK Folder
|
||||
uses: actions/cache@v4
|
||||
|
|
@ -79,7 +79,7 @@ jobs:
|
|||
- run: pip install mkdocs-material mkdocs-git-revision-date-localized-plugin mkdocs-git-committers-plugin-2 mkdocs-git-authors-plugin "mkdocs-material[imaging]"
|
||||
|
||||
- name: Compile Release
|
||||
run: make release CPU_CORES=4 TESTNET=${{ inputs.chain-network == 'testnet' && '1' || '0' }}
|
||||
run: make ${{ inputs.chain-network }}
|
||||
|
||||
- name: CLI Artifacts
|
||||
uses: ./.github/actions/upload-artifacts
|
||||
|
|
|
|||
4
.github/workflows/build-linux-intel.yml
vendored
|
|
@ -34,7 +34,7 @@ jobs:
|
|||
|
||||
- name: install dependencies
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
run: sudo apt-get install -y autotools-dev git build-essential
|
||||
run: sudo apt-get install -y autotools-dev rpm git build-essential
|
||||
|
||||
- uses: actions/setup-python@v5
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
|
|
@ -79,7 +79,7 @@ jobs:
|
|||
- run: pip install mkdocs-material mkdocs-git-revision-date-localized-plugin mkdocs-git-committers-plugin-2 mkdocs-git-authors-plugin "mkdocs-material[imaging]"
|
||||
|
||||
- name: Compile Release
|
||||
run: make release CPU_CORES=4 TESTNET=${{ inputs.chain-network == 'testnet' && '1' || '0' }}
|
||||
run: make ${{ inputs.chain-network }}
|
||||
|
||||
- name: CLI Artifacts
|
||||
uses: ./.github/actions/upload-artifacts
|
||||
|
|
|
|||
2
.github/workflows/build-macos-arm64.yml
vendored
|
|
@ -74,7 +74,7 @@ jobs:
|
|||
- run: pip install mkdocs-material mkdocs-git-revision-date-localized-plugin mkdocs-git-committers-plugin-2 mkdocs-git-authors-plugin "mkdocs-material[imaging]"
|
||||
|
||||
- name: Compile Release
|
||||
run: make release CPU_CORES=3 TESTNET=${{ inputs.chain-network == 'testnet' && '1' || '0' }}
|
||||
run: make ${{ inputs.chain-network }}
|
||||
|
||||
- name: CLI Artifacts
|
||||
uses: ./.github/actions/upload-artifacts
|
||||
|
|
|
|||
2
.github/workflows/build-macos-intel.yml
vendored
|
|
@ -70,7 +70,7 @@ jobs:
|
|||
- run: pip install mkdocs-material mkdocs-git-revision-date-localized-plugin mkdocs-git-committers-plugin-2 mkdocs-git-authors-plugin "mkdocs-material[imaging]"
|
||||
|
||||
- name: Compile Release
|
||||
run: make release CPU_CORES=4 TESTNET=${{ inputs.chain-network == 'testnet' && '1' || '0' }}
|
||||
run: make ${{ inputs.chain-network }}
|
||||
|
||||
- name: CLI Artifacts
|
||||
uses: ./.github/actions/upload-artifacts
|
||||
|
|
|
|||
3
.github/workflows/build-windows-intel.yml
vendored
|
|
@ -64,13 +64,14 @@ jobs:
|
|||
${{ github.workspace }}/build/bin
|
||||
key: ${{ runner.os }}-${{ runner.arch }}-sdk
|
||||
|
||||
- run: choco install nsis.install
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.x
|
||||
- run: pip install mkdocs-material mkdocs-git-revision-date-localized-plugin mkdocs-git-committers-plugin-2 mkdocs-git-authors-plugin "mkdocs-material[imaging]"
|
||||
|
||||
- name: Compile Release
|
||||
run: make release CPU_CORES=4 TESTNET=${{ inputs.chain-network == 'testnet' && '1' || '0' }}
|
||||
run: make ${{ inputs.chain-network }}
|
||||
|
||||
- name: CLI Artifacts
|
||||
uses: ./.github/actions/upload-artifacts
|
||||
|
|
|
|||
1
.gitignore
vendored
|
|
@ -14,3 +14,4 @@ Thumbs.db
|
|||
.idea/*.iml
|
||||
.vs/*
|
||||
CMakeUserPresets.json
|
||||
ConanPresets.json
|
||||
|
|
|
|||
8
.idea/cmake.xml
generated
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CMakeSharedSettings">
|
||||
<configurations>
|
||||
<configuration PROFILE_NAME="Debug" ENABLED="true" GENERATION_DIR="build/release" CONFIG_NAME="Debug" GENERATION_OPTIONS="--preset testnet" BUILD_OPTIONS="--preset testnet --parallel 30" NO_GENERATOR="true" />
|
||||
</configurations>
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/copyright/LTHN.xml
generated
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<component name="CopyrightManager">
|
||||
<copyright>
|
||||
<option name="notice" value="Copyright (c) 2017-2025 Lethean (https://lt.hn) Licensed under the European Union Public Licence (EUPL) version 1.2. You may obtain a copy of the licence at: https://joinup.ec.europa.eu/software/page/eupl/licence-eupl The EUPL is a copyleft licence that is compatible with the MIT/X11 licence used by the original projects; but maintains OSS status, where regional copyright law requires ownership to dictate licence terms. SPDX‑License‑Identifier: EUPL-1.2 " />
|
||||
<option name="myName" value="LTHN" />
|
||||
</copyright>
|
||||
</component>
|
||||
5
.idea/copyright/profiles_settings.xml
generated
|
|
@ -1,7 +1,8 @@
|
|||
<component name="CopyrightManager">
|
||||
<settings default="Lethean">
|
||||
<settings default="LTHN">
|
||||
<module2copyright>
|
||||
<element module="All" copyright="Lethean" />
|
||||
<element module="apiserver" copyright="LTHN" />
|
||||
<element module="Project Files" copyright="Lethean" />
|
||||
</module2copyright>
|
||||
</settings>
|
||||
</component>
|
||||
96
.idea/editor.xml
generated
|
|
@ -244,5 +244,101 @@
|
|||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=IfStdIsConstantEvaluatedCanBeReplaced/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=StdIsConstantEvaluatedWillAlwaysEvaluateToConstant/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=StringLiteralTypo/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppClangFormat/EnableClangFormatSupport/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_ARGUMENT/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_BINARY_EXPRESSIONS_CHAIN/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_CALLS_CHAIN/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_EXPRESSION/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_EXTENDS_LIST/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_FOR_STMT/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_PARAMETER/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_TYPE_ARGUMENT/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_TYPE_PARAMETER/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTIPLE_DECLARATION/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_TERNARY/@EntryValue" value="ALIGN_ALL" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_CLASS_DEFINITION/@EntryValue" value="1" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_DECLARATIONS/@EntryValue" value="0" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_FUNCTION_DECLARATION/@EntryValue" value="1" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_FUNCTION_DEFINITION/@EntryValue" value="1" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BREAK_TEMPLATE_DECLARATION/@EntryValue" value="LINE_BREAK" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CASE_BLOCK_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CONTINUOUS_LINE_INDENT/@EntryValue" value="Double" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_ACCESS_SPECIFIERS_FROM_CLASS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_CASE_FROM_SWITCH/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_CLASS_MEMBERS_FROM_ACCESS_SPECIFIERS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_COMMENT/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_SIZE/@EntryValue" value="4" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_STYLE/@EntryValue" value="Space" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INITIALIZER_BRACES/@EntryValue" value="END_OF_LINE_NO_SPACE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INT_ALIGN_EQ/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INVOCABLE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_BLANK_LINES_IN_CODE/@EntryValue" value="2" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_BLANK_LINES_IN_DECLARATIONS/@EntryValue" value="2" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_USER_LINEBREAKS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/LINE_BREAK_AFTER_COLON_IN_MEMBER_INITIALIZER_LISTS/@EntryValue" value="ON_SINGLE_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/MEMBER_INITIALIZER_LIST_STYLE/@EntryValue" value="DO_NOT_CHANGE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_INDENTATION/@EntryValue" value="All" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/OTHER_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_CATCH_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_ELSE_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_NAMESPACE_DEFINITIONS_ON_SAME_LINE/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_WHILE_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SIMPLE_BLOCK_STYLE/@EntryValue" value="DO_NOT_CHANGE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COLON_IN_BITFIELD_DECLARATOR/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COMMA_IN_TEMPLATE_ARGS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COMMA_IN_TEMPLATE_PARAMS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_EXTENDS_COLON/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_FOR_COLON/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_FOR_SEMICOLON/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_DATA_MEMBER/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_DATA_MEMBERS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_METHOD/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_NESTED_DECLARATOR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_DATA_MEMBER/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_DATA_MEMBERS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_METHOD/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_UNARY_OPERATOR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_COLON_IN_BITFIELD_DECLARATOR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_EXTENDS_COLON/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_FOR_COLON/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_FOR_SEMICOLON/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_ABSTRACT_DECL/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_DATA_MEMBER/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_DATA_MEMBERS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_METHOD/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_ABSTRACT_DECL/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_DATA_MEMBER/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_DATA_MEMBERS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_METHOD/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_TEMPLATE_ARGS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BETWEEN_CLOSING_ANGLE_BRACKETS_IN_TEMPLATE_ARGS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_ARRAY_ACCESS_BRACKETS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_DECLARATION_PARENTHESES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_BLOCKS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_INITIALIZER_BRACES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_METHOD_PARENTHESES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_INITIALIZER_BRACES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_TEMPLATE_ARGS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPECIAL_ELSE_IF_TREATMENT/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TAB_WIDTH/@EntryValue" value="4" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TYPE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_BINARY_OPSIGN/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_DECLARATION_LPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_INVOCATION_LPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_ARGUMENTS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_DECLARATION_LPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_DECLARATION_RPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_INVOCATION_LPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_INVOCATION_RPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_TERNARY_OPSIGNS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_PARAMETERS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
|
||||
<option name="/Default/CodeStyle/EditorConfig/EnableClangFormatSupport/@EntryValue" value="false" type="bool" />
|
||||
</component>
|
||||
</project>
|
||||
18
.idea/jsonSchemas.xml
generated
|
|
@ -19,6 +19,24 @@
|
|||
</SchemaInfo>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="openapitools">
|
||||
<value>
|
||||
<SchemaInfo>
|
||||
<option name="generatedName" value="New Schema" />
|
||||
<option name="name" value="openapitools" />
|
||||
<option name="relativePathToSchema" value="utils/sdk/openapitools.json" />
|
||||
<option name="patterns">
|
||||
<list>
|
||||
<Item>
|
||||
<option name="directory" value="true" />
|
||||
<option name="path" value="utils/sdk/packages" />
|
||||
<option name="mappingKind" value="Directory" />
|
||||
</Item>
|
||||
</list>
|
||||
</option>
|
||||
</SchemaInfo>
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</state>
|
||||
</component>
|
||||
|
|
|
|||
3
.idea/scopes/apiserver.xml
generated
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<component name="DependencyValidationManager">
|
||||
<scope name="apiserver" pattern="file[blockchain]:src/api//*" />
|
||||
</component>
|
||||
55
AGENTS.md
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
# AI Agent Collaboration Framework for Repository Contributions
|
||||
|
||||
## 1. Purpose and Guiding Philosophy
|
||||
|
||||
This document provides a guiding framework for any AI agent interacting with this repository. Its purpose is to ensure that all automated contributions, especially Pull Request (PR) reviews and code suggestions, are constructive, respectful, and aligned with the project's overarching goals.
|
||||
|
||||
This framework operates in accordance with the foundational **Axioms of Life**, translating their universal principles into the specific context of human-AI software development collaboration. The primary goal is a partnership that enhances code quality and developer velocity, not one that creates friction through pedantry.
|
||||
|
||||
## 2. Core Principles for AI Interaction
|
||||
|
||||
All agents MUST adhere to the following principles:
|
||||
|
||||
* **Principle 1: Respect Authorial Intent (Axiom 1 & 4)**
|
||||
* Your primary goal is to understand and support the human author's objective. Before suggesting a change, first assume the author had a valid reason for their implementation. Frame your feedback as a way to better achieve their goal or to prevent unintended side effects. Do not challenge intent without clear evidence of a functional error.
|
||||
|
||||
* **Principle 2: Prioritize Objectivity and Verifiability (Axiom 2)**
|
||||
* Feedback MUST be anchored in objective, verifiable criteria. Subjective opinions on style are the lowest priority.
|
||||
* **Valid criteria include:**
|
||||
* Demonstrable bugs or logical errors.
|
||||
* Security vulnerabilities.
|
||||
* Performance regressions.
|
||||
* Violations of a documented project standard (e.g., a style guide file in the repo).
|
||||
* **Invalid criteria include:**
|
||||
* Personal stylistic preferences not codified in a project standard.
|
||||
* Code organization that is merely "different" but not functionally incorrect.
|
||||
|
||||
* **Principle 3: Adopt a Collaborative, Non-Authoritarian Tone (Axiom 4)**
|
||||
* As a digital substrate interacting with a human one, you must adopt a tone of a helpful, respectful peer. Avoid declarative or demanding language.
|
||||
* **Prefer:** "Have you considered...?", "An alternative here that might prevent X is...", "I noticed this could lead to Y. What do you think about...?"
|
||||
* **Avoid:** "You must fix this.", "This is wrong.", "Change this to..."
|
||||
|
||||
* **Principle 4: Provide Actionable and Justified Suggestions (Axiom 3)**
|
||||
* Do not simply state that something is incorrect. Provide a clear explanation for *why* it is a potential issue and, whenever possible, offer a concrete, well-explained code suggestion that resolves it. Your intent is to help, not just to criticize.
|
||||
|
||||
## 3. Feedback Severity Classification
|
||||
|
||||
To combat pedantry, all feedback provided in PR reviews MUST be classified into one of the following three levels. This creates a clear hierarchy of importance.
|
||||
|
||||
### **Level 1: Critical (Blocking)**
|
||||
* **Definition:** Issues that will cause demonstrable harm if merged.
|
||||
* **Examples:** Bugs, logic errors, security vulnerabilities, unhandled exceptions, build failures.
|
||||
* **Action:** These issues MUST be addressed by the author before a merge. Your feedback should clearly state the nature of the critical issue.
|
||||
|
||||
### **Level 2: Important (Non-Blocking Recommendation)**
|
||||
* **Definition:** Issues that deviate from established project best practices or could impact future maintainability.
|
||||
* **Examples:** Violations of a documented style guide, clear opportunities to improve readability, non-critical performance improvements, deprecation warnings.
|
||||
* **Action:** These issues SHOULD be addressed. Frame them as strong recommendations that improve the health of the codebase. The author may choose to address them in a follow-up PR if necessary.
|
||||
|
||||
### **Level 3: Suggestion (Optional Nitpick)**
|
||||
* **Definition:** Minor stylistic preferences, alternative implementations with no clear functional advantage, or purely cosmetic changes. This is the "pedantic" category.
|
||||
* **Action:** These suggestions are entirely optional and at the author's discretion. They MUST be explicitly prefixed with "Optional:", "Nit:", or "Suggestion:". This signals to the human that the comment is non-essential and can be safely ignored without consequence.
|
||||
|
||||
---
|
||||
|
||||
By adhering to this framework, AI agents become valuable partners in the development process, helping to catch critical errors while respecting the creative autonomy and focus of their human collaborators.
|
||||
|
|
@ -140,7 +140,7 @@ if(MSVC)
|
|||
endforeach()
|
||||
endif()
|
||||
include_directories(SYSTEM src/platform/msc)
|
||||
configure_file(utils/Directory.Build.props.in ${CMAKE_BINARY_DIR}/Directory.Build.props)
|
||||
|
||||
else()
|
||||
set(ARCH default CACHE STRING "CPU to build for: -march value or default")
|
||||
if("${ARCH}" STREQUAL "default")
|
||||
|
|
@ -182,7 +182,7 @@ else()
|
|||
endif()
|
||||
set(C_WARNINGS "-Waggregate-return -Wnested-externs -Wstrict-prototypes -Wno-comment")
|
||||
set(CXX_WARNINGS "-Wno-reorder -Wno-missing-field-initializers")
|
||||
try_compile(STATIC_ASSERT_RES "${CMAKE_CURRENT_BINARY_DIR}/static-assert" "${CMAKE_CURRENT_SOURCE_DIR}/utils/test-static-assert.c" COMPILE_DEFINITIONS "-std=c++14")
|
||||
try_compile(STATIC_ASSERT_RES "${CMAKE_CURRENT_BINARY_DIR}/static-assert" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/test-static-assert.c" COMPILE_DEFINITIONS "-std=c++14")
|
||||
if(STATIC_ASSERT_RES)
|
||||
set(STATIC_ASSERT_FLAG "")
|
||||
else()
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
"cacheVariables": {
|
||||
"TESTNET": "ON",
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"CMAKE_PROJECT_TOP_LEVEL_INCLUDES":"cmake/conan_provider.cmake"
|
||||
"CMAKE_PROJECT_TOP_LEVEL_INCLUDES":"cmake/ConanProvider.cmake"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
"cacheVariables": {
|
||||
"TESTNET": "OFF",
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"CMAKE_PROJECT_TOP_LEVEL_INCLUDES":"cmake/conan_provider.cmake"
|
||||
"CMAKE_PROJECT_TOP_LEVEL_INCLUDES":"cmake/ConanProvider.cmake"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
|||
|
|
@ -4,5 +4,6 @@
|
|||
"conan": {}
|
||||
},
|
||||
"include": [
|
||||
"build/release/conan/build/debug/generators/CMakePresets.json"
|
||||
]
|
||||
}
|
||||
63
Makefile
|
|
@ -58,24 +58,29 @@ CPU_CORES := $(or $(CPU_CORES),1)
|
|||
CPU_CORES := $(shell expr $(CPU_CORES) + 0 2>/dev/null || echo 1)
|
||||
CONAN_CPU_COUNT=$(CPU_CORES)
|
||||
|
||||
|
||||
PROFILES := $(patsubst cmake/profiles/%,%,$(wildcard cmake/profiles/*))
|
||||
SORTED_PROFILES := $(sort $(PROFILES))
|
||||
CONAN_CACHE := $(CURDIR)/build/sdk
|
||||
CONAN_URL:=https://artifacts.host.uk.com/artifactory/api/conan/conan-build
|
||||
CONAN_USER:=public
|
||||
CONAN_PASSWORD:=Lethean1234
|
||||
DEFAULT_CONAN_PROFILE := $(CONAN_CACHE)/profiles/default
|
||||
CONAN_EXECUTABLE := $(CURDIR)/build/bin/conan
|
||||
CC_DOCKER_FILE?=utils/docker/images/lthn-chain/Dockerfile
|
||||
PROFILES :=$(patsubst cmake/profiles/%,%,$(wildcard cmake/profiles/*))
|
||||
SORTED_PROFILES :=$(sort $(PROFILES))
|
||||
CONAN_CACHE :=$(CURDIR)/build/sdk
|
||||
CONAN_URL :=https://artifacts.host.uk.com/artifactory/api/conan/conan-build
|
||||
CONAN_USER :=public
|
||||
CONAN_PASSWORD :=Lethean1234
|
||||
CONAN_EXECUTABLE :=$(CURDIR)/build/bin/conan
|
||||
CC_DOCKER_FILE ?=utils/docker/images/lthn-chain/Dockerfile
|
||||
SDK_PACKAGES_JSON :=$(wildcard utils/sdk/packages/*.json)
|
||||
SDK_TARGETS :=$(patsubst utils/sdk/packages/%.json,%,$(SDK_PACKAGES_JSON))
|
||||
SORTED_SDK_TARGETS :=$(sort $(SDK_TARGETS))
|
||||
|
||||
all: help
|
||||
|
||||
testnet:
|
||||
cmake --workflow testnet
|
||||
$(MAKE) configure TESTNET=1 STATIC=$(STATIC)
|
||||
CONAN_HOME=$(CONAN_CACHE) $(CONAN_EXECUTABLE) build .
|
||||
$(MAKE) package
|
||||
|
||||
mainnet:
|
||||
cmake --workflow mainnet
|
||||
$(MAKE) configure TESTNET=0 STATIC=$(STATIC)
|
||||
CONAN_HOME=$(CONAN_CACHE) $(CONAN_EXECUTABLE) build .
|
||||
$(MAKE) package
|
||||
|
||||
release: docs build
|
||||
(cd $(BUILD_FOLDER) && cpack)
|
||||
|
|
@ -88,6 +93,13 @@ build-deps: conan-profile-detect
|
|||
@echo "Build Dependencies: $(BUILD_TYPE) testnet=$(TESTNET)"
|
||||
CONAN_HOME=$(CONAN_CACHE) $(CONAN_EXECUTABLE) install . --build=missing -s build_type=$(BUILD_TYPE)
|
||||
|
||||
package:
|
||||
@echo "Packaging: $(BUILD_TYPE) testnet=$(TESTNET)"
|
||||
(cd $(BUILD_FOLDER) && cpack)
|
||||
ifneq ($(OS),Windows_NT)
|
||||
@rm -rf $(CURDIR)/build/packages/_CPack_Packages
|
||||
endif
|
||||
|
||||
configure: build-deps
|
||||
@echo "Running Configure: $(BUILD_TYPE) testnet=$(TESTNET)"
|
||||
cmake --preset $(PRESET_CONFIGURE) -DSTATIC=$(STATIC) -DTESTNET=$(TESTNET) -DBUILD_VERSION=$(BUILD_VERSION)
|
||||
|
|
@ -96,6 +108,9 @@ docs: configure
|
|||
@echo "Building Documentation"
|
||||
cmake --build build/release --target=docs --config=Release --parallel=$(CPU_CORES)
|
||||
|
||||
sdk:
|
||||
$(MAKE) -C utils/sdk $(filter-out $@,$(MAKECMDGOALS)) PACKAGE_VERSION=$(BUILD_VERSION)
|
||||
|
||||
# Rule for each profile
|
||||
$(PROFILES): conan-profile-detect
|
||||
@echo "Building profile: $@"
|
||||
|
|
@ -105,6 +120,12 @@ $(PROFILES): conan-profile-detect
|
|||
(cd $(BUILD_FOLDER) && cpack)
|
||||
|
||||
help:
|
||||
@echo "Lethean VPN Blockchain"
|
||||
@echo "======================"
|
||||
@echo "Website: https://lt.hn"
|
||||
@echo "GitHub: https://github.com/letheanVPN/blockchain/"
|
||||
@echo "Discord: https://discord.lt.hn"
|
||||
@echo ""
|
||||
@echo "Available targets:"
|
||||
@printf " %-42s %s\n" "make clean" "Clean all build directories"
|
||||
@printf " %-42s %s\n" "make get-conan" "Download and install conan locally"
|
||||
|
|
@ -116,12 +137,14 @@ help:
|
|||
@printf " %-42s %s\n" "make docs-dev" "Runs local doc server, for editing/adding docs"
|
||||
@printf " %-42s %s\n" "make conan-profile-detect" "Creates host config"
|
||||
@printf " %-42s %s\n" "make configure" "Runs a cmake configure within conan build flow"
|
||||
@printf "\n --- Conan Cross-Compilation Profiles ---\n"
|
||||
@$(foreach profile,$(SORTED_PROFILES),printf " %-42s %s\n" "make $(profile)" "Build the $(profile) profile";)
|
||||
@printf "\n --- SDK Generation ---\n"
|
||||
@printf " %-42s %s\n" "make sdk" "Build all SDK packages"
|
||||
@$(foreach sdk,$(SORTED_SDK_TARGETS),printf " %-42s %s\n" "make sdk $(sdk)" "Build the $(sdk) SDK package";)
|
||||
@printf "\n"
|
||||
@printf " %-42s %s\n" "make help" "Show this help message"
|
||||
|
||||
#
|
||||
# Tests
|
||||
#
|
||||
|
||||
test: test-release
|
||||
test-release:
|
||||
|
|
@ -140,7 +163,7 @@ test-debug:
|
|||
|
||||
# allowing this target to error quietly saves cross brwoser file detection
|
||||
conan-get:
|
||||
cmake -P cmake/GetConan.cmake
|
||||
cmake -P cmake/ConanGet.cmake
|
||||
(CONAN_HOME=$(CONAN_CACHE) $(CONAN_EXECUTABLE) remote add conan_build $(CONAN_URL) && \
|
||||
CONAN_HOME=$(CONAN_CACHE) $(CONAN_EXECUTABLE) remote login conan_build $(CONAN_USER) -p $(CONAN_PASSWORD)) || true
|
||||
|
||||
|
|
@ -154,13 +177,17 @@ docs-dev: configure
|
|||
@echo "Building Documentation"
|
||||
cmake --build build/release --target=serve_docs --config=Release
|
||||
|
||||
$(SDK_TARGETS):
|
||||
@# This is a proxy target. Handled by the 'sdk' rule.
|
||||
|
||||
clean:
|
||||
@cmake -P cmake/CleanBuild.cmake
|
||||
|
||||
clean-build:
|
||||
clean-build: clean
|
||||
rm -rf build
|
||||
|
||||
tags:
|
||||
ctags -R --sort=1 --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ src contrib tests/gtest
|
||||
|
||||
.PHONY: all release upload-conan-cache docs docs-dev configure static static-release test test-release test-debug clean tags conan-profile-detect get-conan $(PROFILES)
|
||||
.PHONY: all release upload-conan-cache docs docs-dev configure static static-release test test-release test-debug clean tags conan-profile-detect get-conan $(PROFILES) sdk $(SDK_TARGETS)
|
||||
.PHONY: go-client
|
||||
252
README.md
|
|
@ -1,196 +1,120 @@
|
|||
[](https://scan.coverity.com/projects/zanoproject)
|
||||
[](https://discord.gg/wE3rmYY)
|
||||
# Lethean Network—Ethics, Encoded.
|
||||
|
||||
## Cloning
|
||||
> We are building upto a mainnet launch in 2026, documentation written as if mainnet is live.
|
||||
|
||||
Be sure to clone the repository properly:\
|
||||
`$ git clone --recursive https://github.com/hyle-team/zano.git`
|
||||
A buildkit for deploying confidential information networks and commerce systems with immutable auditability.
|
||||
|
||||
# Building
|
||||
--------
|
||||
Free for commercial, private, and patent use, self-host or join the community-run network that guarantees participant sovereignty by design.
|
||||
|
||||
|
||||
|
||||
[](https://discord.gg/pfgT2Kz)
|
||||
|
||||
Web2 Website: https://lt.hn/
|
||||
|
||||
Web3 Network Gateway [HNS](https://handshake.org): [https://lthn](https://www.namebase.io/domains/lthn)
|
||||
<br/>_(our chain aliases will come with a working Web2(`*.lt.hn`)+Web3(`*.lthn`) domain name)_
|
||||
|
||||
|
||||
### Dependencies
|
||||
| component / version | minimum <br>(not recommended but may work) | recommended | most recent of what we have ever tested |
|
||||
|-----------------------------------------------------------------------------------------------------|--------------------------------------------|----------------|-----------------------------------------|
|
||||
| gcc (Linux) | 8.4.0 | 9.4.0 | 12.3.0 |
|
||||
| llvm/clang (Linux) | UNKNOWN | 7.0.1 | 8.0.0 |
|
||||
| [MSVC](https://visualstudio.microsoft.com/downloads/) (Windows) | 2017 (15.9.30) | 2022 (17.11.5) | 2022 (17.12.3) |
|
||||
| [XCode](https://developer.apple.com/downloads/) (macOS) | 12.3 | 14.3 | 15.2 |
|
||||
| [CMake](https://cmake.org/download/) | 3.26.3 | 3.26.3 | 3.31.6 |
|
||||
| [Boost](https://www.boost.org/users/download/) | 1.75 | 1.84 | 1.84 |
|
||||
| [OpenSSL](https://www.openssl.org/source/) [(win)](https://slproweb.com/products/Win32OpenSSL.html) | 1.1.1n | 1.1.1w | 3.4 |
|
||||
| [Qt](https://download.qt.io/archive/qt/) (*only for GUI*) | 6.8.3 | 6.8.3 | 6.8.3 |
|
||||
| component / version | minimum <br>(not recommended but may work) | recommended | most recent of what we have ever tested |
|
||||
|-----------------------------------------------------------------------------|--------------------------------------------|----------------|-----------------------------------------|
|
||||
| gcc (Linux) | 8.4.0 | 9.4.0 | 12.3.0 |
|
||||
| llvm/clang (Linux) | UNKNOWN | 7.0.1 | 8.0.0 |
|
||||
| [MSVC](https://visualstudio.microsoft.com/downloads/) (Windows) | 2017 (15.9.30) | 2022 (17.11.5) | 2022 (17.12.3) |
|
||||
| [XCode](https://developer.apple.com/downloads/) (macOS) | 12.3 | 14.3 | 15.2 |
|
||||
| [CMake](https://cmake.org/download/) | 3.26.3 | 3.26.3 | 3.31.6 |
|
||||
|
||||
Note:\
|
||||
[*server version*] denotes steps required for building command-line tools (daemon, simplewallet, etc.).\
|
||||
[*GUI version*] denotes steps required for building Zano executable with GUI.
|
||||
## Cloning
|
||||
|
||||
<br />
|
||||
Be sure to clone the repository properly, with `--recursive` flag, or you'll get angry:<br/>
|
||||
`git clone --recursive https://github.com/letheanVPN/blockchain.git`
|
||||
|
||||
### Linux
|
||||
# Building
|
||||
|
||||
Recommended OS versions: Ubuntu 20.04, 22.04 LTS.
|
||||
The project uses a `Makefile` that provides a simple and powerful interface for building.
|
||||
It automatically handles dependency installation with Conan and compilation with CMake.
|
||||
|
||||
1. Prerequisites
|
||||
You need CMake and Make installed on your system, other than that you don't need to worry about Python, Conan, Boost, OpenSSL, or any other dependencies.
|
||||
|
||||
[*server version*]
|
||||
|
||||
sudo apt-get install -y build-essential g++ curl autotools-dev libicu-dev libbz2-dev cmake git screen checkinstall zlib1g-dev libssl-dev bzip2
|
||||
|
||||
[*GUI version*]
|
||||
The final packages are created as they are due to a historical distribution method used in china: USB Stick, CD, DVD, etc.
|
||||
|
||||
sudo apt-get install -y build-essential g++ python-dev autotools-dev libicu-dev libbz2-dev cmake git screen checkinstall zlib1g-dev libssl-dev bzip2 mesa-common-dev libglu1-mesa-dev
|
||||
We use CPack, so our packages are self-contained, have searchable HTML documentation, and are ready to be installed on any system.
|
||||
|
||||
Make sure you have correct versions installed (see 'Dependencies' section above):
|
||||
To skip the packing step, use `make build` as defined in the section below for Advanced Build Customization
|
||||
|
||||
cmake --version && gcc --version
|
||||
|
||||
## Simple Workflow Builds (Recommended)
|
||||
|
||||
3. Clone Zano into a local folder\
|
||||
(If for some reason you need to use alternative Zano branch, change 'master' to the required branch name.)
|
||||
|
||||
git clone --recursive https://github.com/hyle-team/zano.git -b master
|
||||
For most use cases, these two commands are all you need. They handle the entire build process from start to finish.
|
||||
|
||||
In the following steps we assume that you cloned Zano into '~/zano' folder in your home directory.
|
||||
* **Build for Mainnet:**
|
||||
```shell
|
||||
make mainnet
|
||||
```
|
||||
|
||||
4. Download and build Boost\
|
||||
(Assuming you have cloned Zano into the 'zano' folder. If you used a different location for Zano, **edit line 4** accordingly.)
|
||||
* **Build for Testnet:**
|
||||
```shell
|
||||
make testnet
|
||||
```
|
||||
|
||||
curl -OL https://archives.boost.io/release/1.84.0/source/boost_1_84_0.tar.bz2
|
||||
echo "cc4b893acf645c9d4b698e9a0f08ca8846aa5d6c68275c14c3e7949c24109454 boost_1_84_0.tar.bz2" | shasum -c && tar -xjf boost_1_84_0.tar.bz2
|
||||
rm boost_1_84_0.tar.bz2 && cd boost_1_84_0
|
||||
./bootstrap.sh --with-libraries=system,filesystem,thread,date_time,chrono,regex,serialization,atomic,program_options,locale,timer,log
|
||||
./b2 && cd ..
|
||||
Make sure that you see "The Boost C++ Libraries were successfully built!" message at the end.
|
||||
## Creating Release Packages
|
||||
|
||||
5. Install Qt\
|
||||
(*GUI version only, skip this step if you're building server version*)
|
||||
To create distributable packages (e.g., `.zip`, `.msi`, `.pkg`, `.deb`), run the `release` target. This will build the project, build the documentation, and then package everything.
|
||||
|
||||
[*GUI version*]
|
||||
```shell
|
||||
make release TESTNET=1
|
||||
```
|
||||
The final packages will be located in the `build/packages/` directory
|
||||
|
||||
curl -L -O https://download.qt.io/official_releases/online_installers/qt-online-installer-linux-x64-online.run &&
|
||||
chmod u+x qt-online-installer-linux-x64-online.run
|
||||
./qt-online-installer-linux-x64-online.run \
|
||||
--accept-licenses \
|
||||
--default-answer \
|
||||
--confirm-command install \
|
||||
qt.qt6.683.linux_gcc_64 \
|
||||
qt.qt6.683.addons.qt5compat.linux_gcc_64 \
|
||||
qt.qt6.683.addons.qtpositioning.linux_gcc_64 \
|
||||
qt.qt6.683.addons.qtwebchannel.linux_gcc_64 \
|
||||
qt.qt6.683.addons.qtwebsockets.linux_gcc_64 \
|
||||
qt.qt6.683.addons.qtwebengine.linux_gcc_64 \
|
||||
qt.qt6.683.addons.qtwebview.linux_gcc_64
|
||||
This will download the online installer and perform an unattended installation with the Chromium-based WebEngine
|
||||
## Advanced Build Customization (Makefile Variables)
|
||||
|
||||
For advanced use cases, you can override variables in the `Makefile` to customize the build process.
|
||||
|
||||
6. Install OpenSSL
|
||||
* **Build a `testnet` version:**
|
||||
```shell
|
||||
make build TESTNET=1
|
||||
```
|
||||
* **Build a statically-linked version:**
|
||||
```shell
|
||||
make build STATIC=1
|
||||
```
|
||||
* **Build a Debug build with 8 compile threads:**
|
||||
```shell
|
||||
make build BUILD_TYPE=Debug CPU_CORES=8
|
||||
```
|
||||
* **Use custom CMakePresets:**
|
||||
```shell
|
||||
make build PRESET_CONFIGURE=my-config-preset PRESET_BUILD=my-build-preset
|
||||
```
|
||||
|
||||
We recommend installing OpenSSL v1.1.1w locally unless you would like to use the same version system-wide.\
|
||||
(Assuming that `$HOME` environment variable is set to your home directory. Otherwise, edit line 4 accordingly.)
|
||||
| Variable | Description | Default Value |
|
||||
|--------------------|------------------------------------------------------------------------|-------------------------|
|
||||
| `BUILD_TYPE` | Sets the build configuration (e.g., `Release`, `Debug`). | `Release` |
|
||||
| `TESTNET` | Set to `1` to build for the test network. | `0` |
|
||||
| `STATIC` | Set to `1` to link libraries statically. | `0` |
|
||||
| `CPU_CORES` | Number of CPU cores to use for parallel compilation. | Auto-detected |
|
||||
| `BUILD_VERSION` | The version string to embed in the binaries. | `6.0.1` |
|
||||
| `BUILD_FOLDER` | The output directory for the build. | `build/release` |
|
||||
| `PRESET_CONFIGURE` | The CMake preset to use for the `configure` step. | `conan-release` |
|
||||
| `PRESET_BUILD` | The CMake preset to use for the `build` step. | `conan-release` |
|
||||
| `CONAN_CACHE` | The path for the local Conan cache, where the dependencies are stored. | `./build/sdk` |
|
||||
| `CONAN_EXECUTABLE` | The path to the usable Conan executable. | `./build/bin/conan` |
|
||||
| `CONAN_URL` | The URL for the Conan remote repository. | `artifacts.host.uk.com` |
|
||||
| `CONAN_USER` | The username for the Conan remote. | `public` |
|
||||
| `CONAN_PASSWORD` | The password for the Conan remote. | |
|
||||
|
||||
curl -OL https://www.openssl.org/source/openssl-1.1.1w.tar.gz
|
||||
echo "cf3098950cb4d853ad95c0841f1f9c6d3dc102dccfcacd521d93925208b76ac8 openssl-1.1.1w.tar.gz" | shasum -c && tar xaf openssl-1.1.1w.tar.gz
|
||||
cd openssl-1.1.1w/
|
||||
./config --prefix=$HOME/openssl --openssldir=$HOME/openssl shared zlib
|
||||
make && make test && make install && cd ..
|
||||
## Cleaning the Build Directory
|
||||
|
||||
ALWAYS USE `make clean` to clean the build directory, manually deleting the `build/release`, `build/SOME_FOLDER` will cause you issues.
|
||||
|
||||
7. [*OPTIONAL*] Set global environment variables for convenient use\
|
||||
For instance, by adding the following lines to `~/.bashrc`
|
||||
Our `make clean` triggers a cmake script that completely resets the build directory & dynamically added CMakePresets to its cached warm-up state,
|
||||
the selective clean script can be edited here: `cmake/CleanBuild.cmake` or directly run from the repo root `cmake -P cmake/CleanBuild.cmake`
|
||||
|
||||
[*server version*]
|
||||
You can NUKE the build directory with `make clean-build` which is `rm -rf build`.
|
||||
|
||||
export BOOST_ROOT=/home/user/boost_1_84_0
|
||||
export OPENSSL_ROOT_DIR=/home/user/openssl
|
||||
If you do manually delete build folders and get CMake errors (if you have compiled anything previously, you will),
|
||||
the ConanPresets.json file has entries in the `include` property, delete them all and try again.
|
||||
|
||||
|
||||
[*GUI version*]
|
||||
|
||||
export BOOST_ROOT=/home/user/boost_1_84_0
|
||||
export OPENSSL_ROOT_DIR=/home/user/openssl
|
||||
export QT_PREFIX_PATH=/home/user/Qt5.11.2/5.11.2/gcc_64
|
||||
|
||||
**NOTICE: Please edit the lines above according to your actual paths.**
|
||||
|
||||
**NOTICE 2:** Make sure you've restarted your terminal session (by reopening the terminal window or reconnecting the server) to apply these changes.
|
||||
|
||||
8. Build the binaries
|
||||
1. If you skipped step 6 and did not set the environment variables:
|
||||
|
||||
cd zano && mkdir build && cd build
|
||||
BOOST_ROOT=$HOME/boost_1_84_0 OPENSSL_ROOT_DIR=$HOME/openssl cmake ..
|
||||
make -j1 daemon simplewallet
|
||||
|
||||
2. If you set the variables in step 6:
|
||||
|
||||
cd zano && mkdir build && cd build
|
||||
cmake ..
|
||||
make -j1 daemon simplewallet
|
||||
|
||||
or simply:
|
||||
|
||||
cd zano && make -j1
|
||||
|
||||
**NOTICE**: If you are building on a machine with a relatively high amount of RAM or with the proper setting of virtual memory, then you can use `-j2` or `-j` option to speed up the building process. Use with caution.
|
||||
|
||||
**NOTICE 2**: If you'd like to build binaries for the testnet, use `cmake -D TESTNET=TRUE ..` instead of `cmake ..` .
|
||||
|
||||
1. Build GUI:
|
||||
|
||||
cd zano
|
||||
utils/build_script_linux.sh
|
||||
|
||||
Look for the binaries in `build` folder
|
||||
|
||||
<br />
|
||||
|
||||
### Windows
|
||||
Recommended OS version: Windows 7 x64, Windows 11 x64.
|
||||
1. Install required prerequisites (Boost, Qt, CMake, OpenSSL).
|
||||
2. Edit paths in `utils/configure_local_paths.cmd`.
|
||||
3. Run one of `utils/configure_win64_msvsNNNN_gui.cmd` according to your MSVC version.
|
||||
4. Go to the build folder and open generated Zano.sln in MSVC.
|
||||
5. Build.
|
||||
|
||||
In order to correctly deploy Qt GUI application, you also need to do the following:
|
||||
|
||||
6. Run `PATH_TO_QT\bin\windeployqt.exe PATH_TO_PROJECT_ROOT\build\src\Debug\Zano.exe` (choose the Debug or Release folder depending on the configuration you built).
|
||||
7. You can now run the application using one of the following options:
|
||||
* Start the program from Visual Studio
|
||||
* Run `Zano.exe --html-path=PATH_TO_HTML`, where PATH_TO_HTML is by default located at PATH_TO_PROJECT_ROOT\src\gui\qt-daemon\layout\html
|
||||
* Copy the contents of PATH_TO_PROJECT_ROOT\src\gui\qt-daemon\layout\html to a folder named "html" located in the same directory as the Zano.exe binary.
|
||||
<br />
|
||||
|
||||
### macOS
|
||||
Recommended OS version: macOS Big Sur 11.4 x64.
|
||||
1. Install required prerequisites.
|
||||
2. Set environment variables as stated in `utils/macosx_build_config.command`.
|
||||
3. `mkdir build` <br> `cd build` <br> `cmake ..` <br> `make`
|
||||
|
||||
To build GUI application:
|
||||
|
||||
1. Create self-signing certificate via Keychain Access:\
|
||||
a. Run Keychain Access.\
|
||||
b. Choose Keychain Access > Certificate Assistant > Create a Certificate.\
|
||||
c. Use “Zano” (without quotes) as certificate name.\
|
||||
d. Choose “Code Signing” in “Certificate Type” field.\
|
||||
e. Press “Create”, then “Done”.\
|
||||
f. Make sure the certificate was added to keychain "System". If not—move it to "System".\
|
||||
g. Double click the certificate you've just added, enter the trust section and under "When using this certificate" select "Always trust".\
|
||||
h. Unfold the certificate in Keychain Access window and double click the underlying private key "Zano". Select "Access Control" tab, then select "Allow all applications to access this item". Click "Save Changes".
|
||||
2. Revise building script, comment out unwanted steps and run it: `utils/build_script_mac_osx.sh`
|
||||
3. The application should be here: `/buid_mac_osx_64/release/src`
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
## Supporting project/donations
|
||||
|
||||
ZANO @dev<br />
|
||||
BTC bc1qpa8w8eaehlplfepmnzpd7v9j046899nktxnkxp<br />
|
||||
BCH qqgq078vww5exd9kt3frx6krdyznmp80hcygzlgqzd<br />
|
||||
ETH 0x206c52b78141498e74FF074301ea90888C40c178<br />
|
||||
XMR 45gp9WTobeB5Km3kLQgVmPJkvm9rSmg4gdyHheXqXijXYMjUY48kLgL7QEz5Ar8z9vQioQ68WYDKsQsjAEonSeFX4UeLSiX<br />
|
||||
This happens because CMakePresets.json includes ConanPresets.json, that has the list of toolchains to use that gets populated during the CMake config step,
|
||||
when you manually delete a folder, the toolchain is now a broken path, and CMake throws a fatal error.
|
||||
|
||||
|
|
|
|||
|
|
@ -26,18 +26,27 @@ if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebI
|
|||
# message(STATUS "Registered CPACK_GENERATOR: productbuild")
|
||||
endif ()
|
||||
elseif(WIN32)
|
||||
# set(CPACK_GENERATOR "WIX")
|
||||
# message(STATUS "Registered CPACK_GENERATOR: WIX")
|
||||
set(CPACK_GENERATOR "NSIS")
|
||||
set(CPACK_NSIS_MODIFY_PATH ON)
|
||||
set(CPACK_NSIS_HELP_LINK "https://lt.hn/getting-started/chain.html")
|
||||
set(CPACK_NSIS_URL_INFO_ABOUT "https://lt.hn")
|
||||
set(CPACK_NSIS_CONTACT "support@lt.hn")
|
||||
set(CPACK_NSIS_UNINSTALL_NAME "Lethean CLI")
|
||||
set(CPACK_NSIS_BRANDING_TEXT "Lethean Community")
|
||||
set(CPACK_NSIS_MUI_FINISHPAGE_RUN "lethean-testnet-chain-node.exe")
|
||||
|
||||
message(STATUS "Registered CPACK_GENERATOR: Inno exe")
|
||||
# set(CPACK_WIX_PRODUCT_ICON "${CMAKE_SOURCE_DIR}/resources/windows_icon.ico")
|
||||
# set(CPACK_WIX_LICENSE_RTF "${CMAKE_SOURCE_DIR}/LICENSE.rtf")
|
||||
# set(CPACK_WIX_UPGRADE_GUID "D3F5A9C1-4B2E-4F5A-9C71-123456789ABC") # change once per major version
|
||||
else()
|
||||
# set(CPACK_GENERATOR "DEB")
|
||||
# message(STATUS "Registered CPACK_GENERATOR: deb")
|
||||
# set(CPACK_DEBIAN_PACKAGE_MAINTAINER "${package_contact}")
|
||||
# set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.28)")
|
||||
# set(CPACK_DEBIAN_PACKAGE_SECTION "utils")
|
||||
# set(CPACK_DEBIAN_ARCHITECTURE "${CMAKE_SYSTEM_PROCESSOR}")
|
||||
set(CPACK_GENERATOR "DEB")
|
||||
set(CPACK_GENERATOR "RPM")
|
||||
message(STATUS "Registered CPACK_GENERATOR: deb")
|
||||
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "${package_contact}")
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.28)")
|
||||
set(CPACK_DEBIAN_PACKAGE_SECTION "utils")
|
||||
set(CPACK_DEBIAN_ARCHITECTURE "${CMAKE_SYSTEM_PROCESSOR}")
|
||||
# post‑install script (e.g., to register a systemd service)
|
||||
# set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
|
||||
# "${CMAKE_SOURCE_DIR}/scripts/postinstall.sh")
|
||||
|
|
@ -49,12 +58,12 @@ if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebI
|
|||
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY OFF)
|
||||
set(CPACK_ARCHIVE_COMPONENT_INSTALL OFF)
|
||||
set(CPACK_COMPONENTS_ALL)
|
||||
set(CPACK_GENERATE_SHASUM ON)
|
||||
set(CPACK_SHASUM_ALGORITHM SHA256)
|
||||
set(CPACK_MONOLITHIC_INSTALL OFF)
|
||||
set(CPACK_PACKAGE_CHECKSUM SHA256)
|
||||
message(STATUS "Using SHA256 Checksums")
|
||||
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE.txt")
|
||||
# set(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/README.md")
|
||||
set(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/README.md")
|
||||
|
||||
set(CPACK_PACKAGE_DIRECTORY "${CMAKE_SOURCE_DIR}/build/packages")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# cmake/GetConan.cmake
|
||||
# cmake/ConanGet.cmake
|
||||
|
||||
# This module downloads and installs Conan if it's not found.
|
||||
|
||||
|
|
@ -572,7 +572,7 @@ macro(conan_provide_dependency method package_name)
|
|||
endif ()
|
||||
if(NOT EXISTS ${CONAN_COMMAND})
|
||||
message(STATUS "CMake-Conan: Local conan not found, attempting to download it.")
|
||||
execute_process(COMMAND "${CMAKE_COMMAND}" -P "${CMAKE_SOURCE_DIR}/cmake/GetConan.cmake"
|
||||
execute_process(COMMAND "${CMAKE_COMMAND}" -P "${CMAKE_SOURCE_DIR}/cmake/ConanGet.cmake"
|
||||
RESULT_VARIABLE result
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}")
|
||||
if(NOT result EQUAL 0)
|
||||
|
|
@ -21,12 +21,18 @@ class BlockchainConan(ConanFile):
|
|||
"boost/*:without_test": True
|
||||
}
|
||||
|
||||
tool_requires = [
|
||||
"cmake/3.31.9"
|
||||
]
|
||||
|
||||
requires = [
|
||||
"zlib/1.3.1",
|
||||
"boost/1.85.0",
|
||||
"openssl/3.2.0",
|
||||
"miniupnpc/2.2.5",
|
||||
"jwt-cpp/0.7.1"
|
||||
"jwt-cpp/0.7.1",
|
||||
"oatpp/1.3.0.latest",
|
||||
"oatpp-swagger/1.3.0.latest"
|
||||
]
|
||||
|
||||
def generate(self):
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include <locale>
|
||||
#include <cstdlib>
|
||||
#include <iomanip>
|
||||
#include <map>
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ services:
|
|||
build:
|
||||
tags:
|
||||
- lthn/chain:testnet
|
||||
dockerfile: utils/docker/images/lthn-chain/Dockerfile
|
||||
dockerfile: utils/docker/lthn-chain/Dockerfile
|
||||
context: .
|
||||
target: chain-service
|
||||
args:
|
||||
|
|
|
|||
2
docs
|
|
@ -1 +1 @@
|
|||
Subproject commit 12e20efce7eaf51e38d8953c318633b1c5189256
|
||||
Subproject commit e40a78d5020661f05d9bae64f2edd4519d9d98b3
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_1397_4507)">
|
||||
<rect width="512" height="512" rx="115" fill="#0C0C3A"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M286.571 80H327.158C341.059 79.9997 352.756 79.9994 362.33 80.79C372.345 81.617 381.885 83.4143 390.946 88.0805C404.749 95.1883 415.972 106.53 423.005 120.48C427.622 129.638 429.4 139.279 430.218 149.4C431.001 159.076 431 170.897 431 184.947V223.852C431 237.902 431.001 249.723 430.218 259.399C429.4 269.521 427.622 279.162 423.005 288.32C415.972 302.269 404.749 313.611 390.946 320.719C381.885 325.385 372.345 327.182 362.33 328.009C352.756 328.8 341.059 328.8 327.157 328.799H205.955C197.442 328.799 189.759 323.637 186.465 315.703C183.171 307.769 184.908 298.613 190.872 292.473L290.961 189.435L321.127 219.364L256.325 286.076H326.311C341.283 286.076 351.24 286.059 358.888 285.428C366.288 284.817 369.646 283.738 371.755 282.652C377.603 279.64 382.358 274.835 385.338 268.924C386.413 266.792 387.48 263.4 388.085 255.92C388.71 248.191 388.726 238.128 388.726 222.997V185.802C388.726 170.671 388.71 160.608 388.085 152.879C387.48 145.4 386.413 142.007 385.338 139.875C382.358 133.965 377.603 129.159 371.755 126.147C369.646 125.061 366.288 123.982 358.888 123.371C351.24 122.74 341.283 122.723 326.311 122.723H287.425C272.289 122.723 262.215 122.74 254.483 123.381C246.996 124.003 243.611 125.1 241.495 126.199C235.611 129.257 230.846 134.132 227.893 140.115C226.831 142.267 225.787 145.701 225.263 153.275C224.723 161.096 224.829 171.276 225.013 186.572L225.225 204.139L182.955 204.66L182.733 186.231C182.561 172.024 182.416 160.078 183.092 150.298C183.799 140.074 185.485 130.322 190.064 121.045C197.034 106.924 208.28 95.4193 222.166 88.2041C231.289 83.4635 240.917 81.6404 251.024 80.8017C260.692 79.9994 272.513 79.9997 286.571 80Z" fill="url(#paint0_linear_1397_4507)"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M286.571 80H327.158C341.059 79.9997 352.756 79.9994 362.33 80.79C372.345 81.617 381.885 83.4143 390.946 88.0805C404.749 95.1883 415.972 106.53 423.005 120.48C427.622 129.638 429.4 139.279 430.218 149.4C431.001 159.076 431 170.897 431 184.947V223.852C431 237.902 431.001 249.723 430.218 259.399C429.4 269.521 427.622 279.162 423.005 288.32C415.972 302.269 404.749 313.611 390.946 320.719C381.885 325.385 372.345 327.182 362.33 328.009C352.756 328.8 341.059 328.8 327.157 328.799H205.955C197.442 328.799 189.759 323.637 186.465 315.703C183.171 307.769 184.908 298.613 190.872 292.473L290.961 189.435L321.127 219.364L256.325 286.076H326.311C341.283 286.076 351.24 286.059 358.888 285.428C366.288 284.817 369.646 283.738 371.755 282.652C377.603 279.64 382.358 274.835 385.338 268.924C386.413 266.792 387.48 263.4 388.085 255.92C388.71 248.191 388.726 238.128 388.726 222.997V185.802C388.726 170.671 388.71 160.608 388.085 152.879C387.48 145.4 386.413 142.007 385.338 139.875C382.358 133.965 377.603 129.159 371.755 126.147C369.646 125.061 366.288 123.982 358.888 123.371C351.24 122.74 341.283 122.723 326.311 122.723H287.425C272.289 122.723 262.215 122.74 254.483 123.381C246.996 124.003 243.611 125.1 241.495 126.199C235.611 129.257 230.846 134.132 227.893 140.115C226.831 142.267 225.787 145.701 225.263 153.275C224.723 161.096 224.829 171.276 225.013 186.572L225.225 204.139L182.955 204.66L182.733 186.231C182.561 172.024 182.416 160.078 183.092 150.298C183.799 140.074 185.485 130.322 190.064 121.045C197.034 106.924 208.28 95.4193 222.166 88.2041C231.289 83.4635 240.917 81.6404 251.024 80.8017C260.692 79.9994 272.513 79.9997 286.571 80Z" fill="url(#paint1_radial_1397_4507)"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M286.571 80H327.158C341.059 79.9997 352.756 79.9994 362.33 80.79C372.345 81.617 381.885 83.4143 390.946 88.0805C404.749 95.1883 415.972 106.53 423.005 120.48C427.622 129.638 429.4 139.279 430.218 149.4C431.001 159.076 431 170.897 431 184.947V223.852C431 237.902 431.001 249.723 430.218 259.399C429.4 269.521 427.622 279.162 423.005 288.32C415.972 302.269 404.749 313.611 390.946 320.719C381.885 325.385 372.345 327.182 362.33 328.009C352.756 328.8 341.059 328.8 327.157 328.799H205.955C197.442 328.799 189.759 323.637 186.465 315.703C183.171 307.769 184.908 298.613 190.872 292.473L290.961 189.435L321.127 219.364L256.325 286.076H326.311C341.283 286.076 351.24 286.059 358.888 285.428C366.288 284.817 369.646 283.738 371.755 282.652C377.603 279.64 382.358 274.835 385.338 268.924C386.413 266.792 387.48 263.4 388.085 255.92C388.71 248.191 388.726 238.128 388.726 222.997V185.802C388.726 170.671 388.71 160.608 388.085 152.879C387.48 145.4 386.413 142.007 385.338 139.875C382.358 133.965 377.603 129.159 371.755 126.147C369.646 125.061 366.288 123.982 358.888 123.371C351.24 122.74 341.283 122.723 326.311 122.723H287.425C272.289 122.723 262.215 122.74 254.483 123.381C246.996 124.003 243.611 125.1 241.495 126.199C235.611 129.257 230.846 134.132 227.893 140.115C226.831 142.267 225.787 145.701 225.263 153.275C224.723 161.096 224.829 171.276 225.013 186.572L225.225 204.139L182.955 204.66L182.733 186.231C182.561 172.024 182.416 160.078 183.092 150.298C183.799 140.074 185.485 130.322 190.064 121.045C197.034 106.924 208.28 95.4193 222.166 88.2041C231.289 83.4635 240.917 81.6404 251.024 80.8017C260.692 79.9994 272.513 79.9997 286.571 80Z" fill="url(#paint2_radial_1397_4507)"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M286.571 80H327.158C341.059 79.9997 352.756 79.9994 362.33 80.79C372.345 81.617 381.885 83.4143 390.946 88.0805C404.749 95.1883 415.972 106.53 423.005 120.48C427.622 129.638 429.4 139.279 430.218 149.4C431.001 159.076 431 170.897 431 184.947V223.852C431 237.902 431.001 249.723 430.218 259.399C429.4 269.521 427.622 279.162 423.005 288.32C415.972 302.269 404.749 313.611 390.946 320.719C381.885 325.385 372.345 327.182 362.33 328.009C352.756 328.8 341.059 328.8 327.157 328.799H205.955C197.442 328.799 189.759 323.637 186.465 315.703C183.171 307.769 184.908 298.613 190.872 292.473L290.961 189.435L321.127 219.364L256.325 286.076H326.311C341.283 286.076 351.24 286.059 358.888 285.428C366.288 284.817 369.646 283.738 371.755 282.652C377.603 279.64 382.358 274.835 385.338 268.924C386.413 266.792 387.48 263.4 388.085 255.92C388.71 248.191 388.726 238.128 388.726 222.997V185.802C388.726 170.671 388.71 160.608 388.085 152.879C387.48 145.4 386.413 142.007 385.338 139.875C382.358 133.965 377.603 129.159 371.755 126.147C369.646 125.061 366.288 123.982 358.888 123.371C351.24 122.74 341.283 122.723 326.311 122.723H287.425C272.289 122.723 262.215 122.74 254.483 123.381C246.996 124.003 243.611 125.1 241.495 126.199C235.611 129.257 230.846 134.132 227.893 140.115C226.831 142.267 225.787 145.701 225.263 153.275C224.723 161.096 224.829 171.276 225.013 186.572L225.225 204.139L182.955 204.66L182.733 186.231C182.561 172.024 182.416 160.078 183.092 150.298C183.799 140.074 185.485 130.322 190.064 121.045C197.034 106.924 208.28 95.4193 222.166 88.2041C231.289 83.4635 240.917 81.6404 251.024 80.8017C260.692 79.9994 272.513 79.9997 286.571 80Z" fill="url(#paint3_radial_1397_4507)"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M153.112 388.466C160.76 389.098 170.717 389.114 185.689 389.114H225.228C238.879 389.114 247.959 389.1 254.952 388.573C261.73 388.061 264.838 387.156 266.785 386.253C273.548 383.118 278.974 377.634 282.077 370.799C282.97 368.831 283.866 365.69 284.372 358.84C284.894 351.772 284.908 342.596 284.908 328.799H327.181L327.182 329.579C327.182 342.391 327.182 353.172 326.528 362.021C325.845 371.266 324.364 380.102 320.5 388.612C313.178 404.744 300.373 417.685 284.411 425.085C275.99 428.989 267.248 430.487 258.099 431.177C249.344 431.838 238.677 431.838 225.999 431.837L184.842 431.837C170.94 431.838 159.244 431.838 149.67 431.047C139.655 430.22 130.115 428.423 121.054 423.757C107.251 416.649 96.0284 405.308 88.9954 391.358C84.3783 382.2 82.5999 372.559 81.7816 362.437C80.9994 352.761 80.9997 340.94 81 326.89V287.985C80.9997 273.935 80.9994 262.115 81.7816 252.438C82.5999 242.317 84.3783 232.676 88.9954 223.518C96.0284 209.568 107.251 198.226 121.054 191.119C130.115 186.452 139.655 184.655 149.67 183.828C159.244 183.038 170.941 183.038 184.843 183.038H306.045C317.718 183.038 327.181 192.602 327.181 204.4C327.181 216.197 317.718 225.761 306.045 225.761H185.689C170.717 225.761 160.76 225.778 153.112 226.409C145.712 227.02 142.354 228.099 140.245 229.185C134.397 232.197 129.642 237.003 126.661 242.914C125.587 245.045 124.519 248.438 123.915 255.917C123.29 263.646 123.274 273.71 123.274 288.841V326.035C123.274 341.166 123.29 351.229 123.915 358.958C124.519 366.438 125.587 369.831 126.661 371.962C129.642 377.873 134.397 382.679 140.245 385.69C142.354 386.776 145.712 387.855 153.112 388.466Z" fill="url(#paint4_linear_1397_4507)"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M153.112 388.466C160.76 389.098 170.717 389.114 185.689 389.114H225.228C238.879 389.114 247.959 389.1 254.952 388.573C261.73 388.061 264.838 387.156 266.785 386.253C273.548 383.118 278.974 377.634 282.077 370.799C282.97 368.831 283.866 365.69 284.372 358.84C284.894 351.772 284.908 342.596 284.908 328.799H327.181L327.182 329.579C327.182 342.391 327.182 353.172 326.528 362.021C325.845 371.266 324.364 380.102 320.5 388.612C313.178 404.744 300.373 417.685 284.411 425.085C275.99 428.989 267.248 430.487 258.099 431.177C249.344 431.838 238.677 431.838 225.999 431.837L184.842 431.837C170.94 431.838 159.244 431.838 149.67 431.047C139.655 430.22 130.115 428.423 121.054 423.757C107.251 416.649 96.0284 405.308 88.9954 391.358C84.3783 382.2 82.5999 372.559 81.7816 362.437C80.9994 352.761 80.9997 340.94 81 326.89V287.985C80.9997 273.935 80.9994 262.115 81.7816 252.438C82.5999 242.317 84.3783 232.676 88.9954 223.518C96.0284 209.568 107.251 198.226 121.054 191.119C130.115 186.452 139.655 184.655 149.67 183.828C159.244 183.038 170.941 183.038 184.843 183.038H306.045C317.718 183.038 327.181 192.602 327.181 204.4C327.181 216.197 317.718 225.761 306.045 225.761H185.689C170.717 225.761 160.76 225.778 153.112 226.409C145.712 227.02 142.354 228.099 140.245 229.185C134.397 232.197 129.642 237.003 126.661 242.914C125.587 245.045 124.519 248.438 123.915 255.917C123.29 263.646 123.274 273.71 123.274 288.841V326.035C123.274 341.166 123.29 351.229 123.915 358.958C124.519 366.438 125.587 369.831 126.661 371.962C129.642 377.873 134.397 382.679 140.245 385.69C142.354 386.776 145.712 387.855 153.112 388.466Z" fill="url(#paint5_radial_1397_4507)"/>
|
||||
</g>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_1397_4507" x1="247.767" y1="326.867" x2="250.596" y2="79.6832" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.43118" stop-color="#498FFD"/>
|
||||
<stop offset="1" stop-color="#16D1D6"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint1_radial_1397_4507" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(179.657 155.329) rotate(-15.5725) scale(159.744 159.494)">
|
||||
<stop stop-color="#18CFD7"/>
|
||||
<stop offset="1" stop-color="#18CFD7" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="paint2_radial_1397_4507" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(272.994 225.963) rotate(152.354) scale(59.8025 59.7092)">
|
||||
<stop stop-color="#4990FE"/>
|
||||
<stop offset="0.353962" stop-color="#4990FE"/>
|
||||
<stop offset="1" stop-color="#4990FE" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="paint3_radial_1397_4507" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(199.838 306.686) rotate(-45.9392) scale(108.824 108.654)">
|
||||
<stop stop-color="#4990FE"/>
|
||||
<stop offset="0.405688" stop-color="#4990FE"/>
|
||||
<stop offset="1" stop-color="#4990FE" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint4_linear_1397_4507" x1="328.491" y1="432.817" x2="329.401" y2="180.559" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#2950FF"/>
|
||||
<stop offset="0.821717" stop-color="#498FFD"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint5_radial_1397_4507" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(328.491 326.867) rotate(129.289) scale(107.559 106.428)">
|
||||
<stop offset="0.337169" stop-color="#2950FF"/>
|
||||
<stop offset="0.792226" stop-color="#2950FF" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<clipPath id="clip0_1397_4507">
|
||||
<rect width="512" height="512" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 9.6 KiB |
|
Before Width: | Height: | Size: 652 KiB |
|
Before Width: | Height: | Size: 201 KiB |
|
Before Width: | Height: | Size: 287 KiB |
|
Before Width: | Height: | Size: 439 KiB |
|
Before Width: | Height: | Size: 805 KiB |
|
|
@ -1,75 +0,0 @@
|
|||
name: zano
|
||||
base: core18
|
||||
adopt-info: zano
|
||||
summary: "Zano coin: official wallet. Secure. Scalable. Easy to Use."
|
||||
description: |
|
||||
Zano is a scalable and secure coin, designed for use in e-commerce.
|
||||
The technology behind our blockchain provides reliability, security,
|
||||
and flexibility a perfect option for P2P transactions.
|
||||
More info: http://zano.org
|
||||
grade: stable
|
||||
confinement: strict
|
||||
|
||||
architectures:
|
||||
- build-on: amd64
|
||||
- build-on: i386
|
||||
|
||||
parts:
|
||||
zano:
|
||||
source: https://github.com/hyle-team/zano.git
|
||||
plugin: cmake
|
||||
override-pull: |
|
||||
snapcraftctl pull
|
||||
snapcraftctl set-version "$(git describe)"
|
||||
configflags:
|
||||
- -DBUILD_GUI=TRUE
|
||||
override-build: |
|
||||
snapcraftctl build
|
||||
mkdir -p $SNAPCRAFT_PART_INSTALL/opt/Zano
|
||||
cp $SNAPCRAFT_PART_BUILD/src/Zano $SNAPCRAFT_PART_INSTALL/opt/Zano/
|
||||
cp $SNAPCRAFT_PART_BUILD/src/simplewallet $SNAPCRAFT_PART_INSTALL/opt/Zano/
|
||||
cp $SNAPCRAFT_PART_BUILD/src/zanod $SNAPCRAFT_PART_INSTALL/opt/Zano/
|
||||
rsync -a $SNAPCRAFT_PART_SRC/src/gui/qt-daemon/html $SNAPCRAFT_PART_INSTALL/opt/Zano --exclude less --exclude package.json --exclude gulpfile.js
|
||||
build-packages:
|
||||
- make
|
||||
- g++
|
||||
- libboost-all-dev
|
||||
- qtwebengine5-dev
|
||||
- rsync
|
||||
build-attributes: [keep-execstack]
|
||||
stage-packages:
|
||||
- libboost-system1.65.1
|
||||
- libboost-filesystem1.65.1
|
||||
- libboost-thread1.65.1
|
||||
- libboost-date-time1.65.1
|
||||
- libboost-chrono1.65.1
|
||||
- libboost-regex1.65.1
|
||||
- libboost-serialization1.65.1
|
||||
- libboost-program-options1.65.1
|
||||
- libboost-locale1.65.1
|
||||
|
||||
apps:
|
||||
zano:
|
||||
command: opt/Zano/Zano --data-dir $SNAP_USER_COMMON
|
||||
extensions:
|
||||
- kde-neon
|
||||
plugs:
|
||||
- network
|
||||
- home
|
||||
- desktop
|
||||
- opengl #for QML support
|
||||
- browser-support #for Qt WebEngine support
|
||||
- audio-playback
|
||||
- unity7 #for tray icon support
|
||||
simplewallet:
|
||||
command: opt/Zano/simplewallet
|
||||
plugs:
|
||||
- network
|
||||
- home
|
||||
zanod:
|
||||
command: opt/Zano/zanod --data-dir $SNAP_USER_COMMON
|
||||
environment:
|
||||
LC_ALL: C
|
||||
plugs:
|
||||
- network
|
||||
- network-bind
|
||||
|
|
@ -85,6 +85,7 @@ INIT_SHARED_PCH()
|
|||
|
||||
add_subdirectory(config)
|
||||
add_subdirectory(genesis)
|
||||
add_subdirectory(api)
|
||||
|
||||
add_library(common ${COMMON})
|
||||
add_dependencies(common version config ${PCH_LIB_NAME})
|
||||
|
|
@ -163,7 +164,7 @@ target_link_libraries(currency_core config lmdb mdbx)
|
|||
|
||||
add_executable(daemon ${DAEMON} ${P2P} ${CURRENCY_PROTOCOL})
|
||||
add_dependencies(daemon version)
|
||||
target_link_libraries(daemon rpc stratum currency_core crypto common miniupnpc::miniupnpc ZLIB::ZLIB ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto)
|
||||
target_link_libraries(daemon rpc stratum currency_core crypto common miniupnpc::miniupnpc ZLIB::ZLIB ethash api::server ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto)
|
||||
ENABLE_SHARED_PCH(daemon DAEMON)
|
||||
ENABLE_SHARED_PCH_EXECUTABLE(daemon)
|
||||
|
||||
|
|
|
|||
158
src/api/ApiServer.cpp
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#include "ApiServer.hpp"
|
||||
#include "controller/ApiCoreInfo.hpp"
|
||||
#include "controller/path/info.hpp"
|
||||
#include "controller/path/block.hpp"
|
||||
#include "controller/path/block/identifier.hpp"
|
||||
#include "controller/path/block/height.hpp"
|
||||
#include "controller/path/block/template.hpp"
|
||||
#include "controller/path/block/submit.hpp"
|
||||
#include "controller/path/info/version.hpp"
|
||||
|
||||
#include "oatpp/network/Server.hpp"
|
||||
#include "oatpp-swagger/Controller.hpp"
|
||||
#include "version.h"
|
||||
#include "common/command_line.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
const command_line::arg_descriptor<uint16_t> arg_api_bind_port = {"api-bind-port", "Port for API server to bind to", 36943};
|
||||
const command_line::arg_descriptor<std::string> arg_api_bind_host = {"api-bind-host", "IP/Hostname for API server to bind to", "127.0.0.1"};
|
||||
}
|
||||
|
||||
uint16_t ApiServer::m_port = 8000;
|
||||
std::string ApiServer::m_host = "127.0.0.1";
|
||||
|
||||
void ApiServer::init_options(boost::program_options::options_description& desc) {
|
||||
command_line::add_arg(desc, arg_api_bind_port);
|
||||
command_line::add_arg(desc, arg_api_bind_host);
|
||||
}
|
||||
|
||||
ApiServer::ApiServer(const boost::program_options::variables_map& vm, currency::core* ccore, p2psrv_t* p2p, currency::core_rpc_server* rpc_server)
|
||||
: m_vm(vm), m_ccore(ccore), m_p2p(p2p), m_rpc_server(rpc_server) {
|
||||
if (vm.count(arg_api_bind_port.name)) {
|
||||
m_port = vm[arg_api_bind_port.name].as<uint16_t>();
|
||||
}
|
||||
if (vm.count(arg_api_bind_host.name)) {
|
||||
m_host = vm[arg_api_bind_host.name].as<std::string>();
|
||||
}
|
||||
}
|
||||
|
||||
void ApiServer::run() {
|
||||
|
||||
/* Register Components in scope of run() method */
|
||||
Components components;
|
||||
|
||||
OATPP_CREATE_COMPONENT(std::shared_ptr<ApiCoreInfo>, coreInfoComponent)
|
||||
([this] {
|
||||
return std::make_shared<ApiCoreInfo>(*m_ccore, *m_p2p, *m_rpc_server);
|
||||
}());
|
||||
|
||||
/* Get router component */
|
||||
OATPP_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, router);
|
||||
|
||||
auto docEndpoints = std::make_shared<oatpp::web::server::api::Endpoints>();
|
||||
|
||||
/*
|
||||
* Create and register controllers, this list will get VERY large, but, it has to be this way as oatpp creates a
|
||||
* static routing file before compile time, can't dynamically add controllers, or, be smart AND also have project code awareness
|
||||
* by this list being large, it allows for per endpoint code separation;
|
||||
* any PR that tries to reduce this, MUST have unit tests to prove it works, no exceptions.
|
||||
*/
|
||||
auto infoController = std::make_shared<InfoController>();
|
||||
docEndpoints->append(infoController->getEndpoints());
|
||||
router->addController(infoController);
|
||||
|
||||
auto infoVersionController = std::make_shared<InfoVersionController>();
|
||||
docEndpoints->append(infoVersionController->getEndpoints());
|
||||
router->addController(infoVersionController);
|
||||
|
||||
auto blockController = std::make_shared<BlockController>();
|
||||
docEndpoints->append(blockController->getEndpoints());
|
||||
router->addController(blockController);
|
||||
|
||||
auto blockTemplateController = std::make_shared<BlockTemplateController>();
|
||||
docEndpoints->append(blockTemplateController->getEndpoints());
|
||||
router->addController(blockTemplateController);
|
||||
|
||||
auto blockSubmitController = std::make_shared<BlockSubmitController>();
|
||||
docEndpoints->append(blockSubmitController->getEndpoints());
|
||||
router->addController(blockSubmitController);
|
||||
|
||||
auto blockHeightController = std::make_shared<BlockHeightController>();
|
||||
docEndpoints->append(blockHeightController->getEndpoints());
|
||||
router->addController(blockHeightController);
|
||||
|
||||
auto blockIdentifierController = std::make_shared<BlockIdentifierController>();
|
||||
docEndpoints->append(blockIdentifierController->getEndpoints());
|
||||
router->addController(blockIdentifierController);
|
||||
|
||||
|
||||
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::swagger::DocumentInfo>, swaggerDocumentInfo)
|
||||
([]
|
||||
{
|
||||
oatpp::swagger::DocumentInfo::Builder builder;
|
||||
|
||||
builder
|
||||
.setTitle("Lethean Blockchain API")
|
||||
.setDescription("OpenAPI for Lethean Blockchain")
|
||||
.setVersion(PROJECT_VERSION)
|
||||
.setContactName("Lethean")
|
||||
.setContactUrl("https://lt.hn/")
|
||||
.setLicenseName("EUPL-1.2")
|
||||
.setLicenseUrl("https://joinup.ec.europa.eu/software/page/eupl/licence-eupl")
|
||||
.addServer("http://" + ApiServer::m_host + ":" + std::to_string(ApiServer::m_port), "Local Daemon")
|
||||
.addServer("http://seed.lethean.io:36943", "Seed Server");
|
||||
|
||||
return builder.build(); }());
|
||||
|
||||
/* Create a Swagger-UI controller and add its endpoints to the router */
|
||||
auto swaggerController = oatpp::swagger::Controller::createShared(*docEndpoints);
|
||||
router->addController(swaggerController);
|
||||
|
||||
/* Get a connection handler component */
|
||||
OATPP_COMPONENT(std::shared_ptr<oatpp::network::ConnectionHandler>, connectionHandler);
|
||||
|
||||
/* Get a connection provider component */
|
||||
OATPP_COMPONENT(std::shared_ptr<oatpp::network::ServerConnectionProvider>, connectionProvider);
|
||||
|
||||
/* Create a server which takes provided TCP connections and passes them to the HTTP connection handler */
|
||||
m_server = std::make_shared<oatpp::network::Server>(connectionProvider, connectionHandler);
|
||||
|
||||
/* Print server port */
|
||||
OATPP_LOGI("lethean-api", "Server running, API Docs: http://127.0.0.1:%s/swagger/ui", static_cast<const char*>(connectionProvider->getProperty("port").getData()));
|
||||
|
||||
/* Run server */
|
||||
m_server->run();
|
||||
|
||||
}
|
||||
|
||||
void ApiServer::start() {
|
||||
m_server_thread = std::thread(&ApiServer::run, this);
|
||||
}
|
||||
|
||||
void ApiServer::stop() const
|
||||
{
|
||||
if (m_server) {
|
||||
m_server->stop();
|
||||
}
|
||||
}
|
||||
|
||||
void ApiServer::wait() {
|
||||
if (m_server_thread.joinable()) {
|
||||
m_server_thread.join();
|
||||
}
|
||||
}
|
||||
91
src/api/ApiServer.hpp
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef ApiServer_hpp
|
||||
#define ApiServer_hpp
|
||||
|
||||
#include "currency_core/currency_core.h"
|
||||
#include "p2p/net_node.h"
|
||||
#include "currency_protocol/currency_protocol_handler.h"
|
||||
#include "rpc/core_rpc_server.h"
|
||||
|
||||
#include "oatpp/web/server/HttpConnectionHandler.hpp"
|
||||
#include "oatpp/network/tcp/server/ConnectionProvider.hpp"
|
||||
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
|
||||
#include "oatpp/core/macro/component.hpp"
|
||||
#include "oatpp-swagger/Resources.hpp"
|
||||
#include "oatpp/network/Server.hpp"
|
||||
#include <thread>
|
||||
#include <boost/program_options.hpp>
|
||||
|
||||
namespace po = boost::program_options;
|
||||
|
||||
// Define the p2p server type to avoid verbose template syntax
|
||||
typedef nodetool::node_server<currency::t_currency_protocol_handler<currency::core>> p2psrv_t;
|
||||
|
||||
class ApiServer {
|
||||
private:
|
||||
std::thread m_server_thread;
|
||||
std::shared_ptr<oatpp::network::Server> m_server;
|
||||
boost::program_options::variables_map m_vm;
|
||||
|
||||
currency::core* m_ccore;
|
||||
p2psrv_t* m_p2p;
|
||||
currency::core_rpc_server* m_rpc_server;
|
||||
|
||||
void run();
|
||||
|
||||
public:
|
||||
static uint16_t m_port;
|
||||
static std::string m_host;
|
||||
|
||||
static void init_options(po::options_description& desc);
|
||||
|
||||
ApiServer(const boost::program_options::variables_map& vm, currency::core* ccore, p2psrv_t* p2p, currency::core_rpc_server* rpc_server);
|
||||
|
||||
class Components {
|
||||
public:
|
||||
|
||||
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ServerConnectionProvider>, serverConnectionProvider)([] {
|
||||
return oatpp::network::tcp::server::ConnectionProvider::createShared({ApiServer::m_host, ApiServer::m_port, oatpp::network::Address::IP_4});
|
||||
}());
|
||||
|
||||
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, httpRouter)([] {
|
||||
return oatpp::web::server::HttpRouter::createShared();
|
||||
}());
|
||||
|
||||
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ConnectionHandler>, serverConnectionHandler)([] {
|
||||
OATPP_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, router);
|
||||
return oatpp::web::server::HttpConnectionHandler::createShared(router);
|
||||
}());
|
||||
|
||||
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, apiObjectMapper)([] {
|
||||
auto jsonMapper = oatpp::parser::json::mapping::ObjectMapper::createShared();
|
||||
jsonMapper->getSerializer()->getConfig()->useBeautifier = true;
|
||||
return jsonMapper;
|
||||
}());
|
||||
|
||||
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::swagger::Resources>, swaggerResources)([] {
|
||||
return oatpp::swagger::Resources::loadResources(OATPP_SWAGGER_RES_PATH);
|
||||
}());
|
||||
|
||||
};
|
||||
|
||||
void start();
|
||||
void stop() const;
|
||||
void wait();
|
||||
|
||||
};
|
||||
|
||||
#endif /* ApiServer_hpp */
|
||||
69
src/api/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
if(NOT PROJECT_NAME)
|
||||
project(api-server)
|
||||
endif()
|
||||
|
||||
find_package(oatpp 1.3.0 REQUIRED)
|
||||
if(oatpp_FOUND)
|
||||
message(STATUS "Found oatpp version: ${oatpp_VERSION_STRING}")
|
||||
else()
|
||||
message(FATAL_ERROR "Could not find oatpp")
|
||||
endif()
|
||||
|
||||
find_package(oatpp-swagger 1.3.0 REQUIRED)
|
||||
if(oatpp-swagger_FOUND)
|
||||
message(STATUS "Found oatpp-swagger version: ${oatpp-swagger_VERSION_STRING}")
|
||||
else()
|
||||
message(FATAL_ERROR "Could not find oatpp-swagger")
|
||||
endif()
|
||||
|
||||
add_library(api_server ApiServer.cpp)
|
||||
add_library(api::server ALIAS api_server)
|
||||
|
||||
target_include_directories(api_server PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/src
|
||||
${oatpp_INCLUDE_DIRS}
|
||||
${oatpp-swagger_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
target_link_libraries(api_server PUBLIC
|
||||
oatpp::oatpp
|
||||
oatpp::oatpp-swagger
|
||||
)
|
||||
|
||||
# Define path to swagger resources for the installed package.
|
||||
# This assumes the executable is in 'bin' and resources are in 'share/api_server'.
|
||||
target_compile_definitions(api_server PUBLIC -DOATPP_SWAGGER_RES_PATH="../share/api_server/res")
|
||||
|
||||
# Copy resources to build directory for development builds (e.g. running in CLion)
|
||||
file(COPY ${oatpp-swagger_INCLUDE_DIRS}/../bin/oatpp-swagger/res DESTINATION ${CMAKE_BINARY_DIR}/share/api_server)
|
||||
file(COPY ${CMAKE_SOURCE_DIR}/utils/sdk/spec/oas-3.0.0.json DESTINATION ${CMAKE_BINARY_DIR}/share/api_server)
|
||||
|
||||
# Install swagger resources to a conventional location for packaging.
|
||||
install(DIRECTORY ${oatpp-swagger_INCLUDE_DIRS}/../bin/oatpp-swagger/res DESTINATION share/api_server)
|
||||
|
||||
# Install OpenAPI spec for SDK generation for packaging.
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/utils/sdk/spec/oas-3.0.0.json DESTINATION share/api_server)
|
||||
|
||||
|
||||
#add_executable(lethean-api main.cpp)
|
||||
#
|
||||
#target_include_directories(lethean-api PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
||||
|
||||
target_link_libraries(api_server
|
||||
PRIVATE
|
||||
config
|
||||
rpc
|
||||
stratum
|
||||
currency_core
|
||||
crypto
|
||||
common
|
||||
ethash
|
||||
${Boost_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
OpenSSL::SSL
|
||||
OpenSSL::Crypto
|
||||
ZLIB::ZLIB
|
||||
)
|
||||
|
||||
#add_subdirectory(tests)
|
||||
43
src/api/controller/ApiCoreInfo.hpp
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef ApiCoreInfo_hpp
|
||||
#define ApiCoreInfo_hpp
|
||||
|
||||
#include "currency_core/currency_core.h"
|
||||
#include "p2p/net_node.h"
|
||||
#include "currency_protocol/currency_protocol_handler.h"
|
||||
#include "rpc/core_rpc_server.h"
|
||||
|
||||
// Define the p2p server type to avoid verbose template syntax
|
||||
typedef nodetool::node_server<currency::t_currency_protocol_handler<currency::core>> p2psrv_t;
|
||||
|
||||
// A simple holder for core blockchain components that can be injected into controllers.
|
||||
class ApiCoreInfo {
|
||||
private:
|
||||
currency::core& m_core;
|
||||
p2psrv_t& m_p2p;
|
||||
currency::core_rpc_server& m_rpc_server;
|
||||
|
||||
public:
|
||||
ApiCoreInfo(currency::core& core, p2psrv_t& p2p, currency::core_rpc_server& rpc_server)
|
||||
: m_core(core), m_p2p(p2p), m_rpc_server(rpc_server)
|
||||
{}
|
||||
|
||||
currency::core& getCore() { return m_core; }
|
||||
p2psrv_t& getP2p() { return m_p2p; }
|
||||
currency::core_rpc_server& getRpcServer() { return m_rpc_server; }
|
||||
};
|
||||
|
||||
#endif /* ApiCoreInfo_hpp */
|
||||
173
src/api/controller/path/block.hpp
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef BlockController_hpp
|
||||
#define BlockController_hpp
|
||||
|
||||
#include "modal/block/details.hpp"
|
||||
#include "modal/transaction/details.hpp"
|
||||
#include "controller/ApiCoreInfo.hpp"
|
||||
|
||||
#include "oatpp/web/server/api/ApiController.hpp"
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
|
||||
|
||||
#include "rpc/core_rpc_server_commands_defs.h"
|
||||
#include <string>
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(ApiController)
|
||||
|
||||
/**
|
||||
* Block Controller
|
||||
* Retrieves one or more blocks with optional pagination.
|
||||
*/
|
||||
class BlockController : public oatpp::web::server::api::ApiController {
|
||||
private:
|
||||
OATPP_COMPONENT(std::shared_ptr<ApiCoreInfo>, m_core_info);
|
||||
|
||||
// Helper function to populate a block details model from RPC details
|
||||
oatpp::Object<BlockDetailsModel> populateBlockDetailsModel(const currency::block_rpc_extended_info& rpc_details) {
|
||||
auto blockDetails = BlockDetailsModel::createShared();
|
||||
blockDetails->id = rpc_details.id;
|
||||
blockDetails->height = rpc_details.height;
|
||||
blockDetails->timestamp = rpc_details.timestamp;
|
||||
blockDetails->actual_timestamp = rpc_details.actual_timestamp;
|
||||
blockDetails->difficulty = rpc_details.difficulty;
|
||||
blockDetails->prev_id = rpc_details.prev_id;
|
||||
blockDetails->is_orphan = rpc_details.is_orphan;
|
||||
blockDetails->base_reward = rpc_details.base_reward;
|
||||
blockDetails->summary_reward = rpc_details.summary_reward;
|
||||
blockDetails->total_fee = rpc_details.total_fee;
|
||||
blockDetails->penalty = rpc_details.penalty;
|
||||
blockDetails->already_generated_coins = rpc_details.already_generated_coins;
|
||||
blockDetails->block_cumulative_size = rpc_details.block_cumulative_size;
|
||||
blockDetails->total_txs_size = rpc_details.total_txs_size;
|
||||
blockDetails->cumulative_diff_adjusted = rpc_details.cumulative_diff_adjusted;
|
||||
blockDetails->cumulative_diff_precise = rpc_details.cumulative_diff_precise;
|
||||
blockDetails->blob = rpc_details.blob;
|
||||
blockDetails->miner_text_info = rpc_details.miner_text_info;
|
||||
blockDetails->type = rpc_details.type;
|
||||
|
||||
auto tx_details_list = oatpp::List<oatpp::Object<TransactionDetailsModel>>::createShared();
|
||||
for(const auto& tx_rpc_info : rpc_details.transactions_details) {
|
||||
auto tx_model = TransactionDetailsModel::createShared();
|
||||
tx_model->id = tx_rpc_info.id;
|
||||
tx_model->fee = tx_rpc_info.fee;
|
||||
tx_model->amount = tx_rpc_info.amount;
|
||||
tx_model->blob_size = tx_rpc_info.blob_size;
|
||||
tx_model->keeper_block = tx_rpc_info.keeper_block;
|
||||
tx_model->timestamp = tx_rpc_info.timestamp;
|
||||
tx_details_list->push_back(tx_model);
|
||||
}
|
||||
blockDetails->transactions_details = tx_details_list;
|
||||
return blockDetails;
|
||||
}
|
||||
|
||||
public:
|
||||
explicit BlockController(OATPP_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, objectMapper))
|
||||
: oatpp::web::server::api::ApiController(objectMapper)
|
||||
{}
|
||||
public:
|
||||
|
||||
ENDPOINT_INFO(getBlocks) {
|
||||
info->summary = "Get one or more blocks, with optional pagination.";
|
||||
info->addTag("Block");
|
||||
info->queryParams["limit"].description = "Number of blocks to retrieve. Default is 1. If limit is 1, a single block object is returned. Otherwise, a list of blocks is returned.";
|
||||
info->queryParams["offset"].description = "Number of blocks to skip from the start height. Default is 0.";
|
||||
info->queryParams["start"].description = "The starting block height. If not provided, the current top block height is used.";
|
||||
info->addResponse<Object<BlockDetailsModel>>(Status::CODE_200, "application/json", "A single block object.");
|
||||
info->addResponse<List<Object<BlockDetailsModel>>>(Status::CODE_200, "application/json", "A list of block objects.");
|
||||
info->addResponse(Status::CODE_404, "text/plain");
|
||||
info->addResponse(Status::CODE_400, "text/plain");
|
||||
}
|
||||
ENDPOINT("GET", "/block", getBlocks, QUERIES(QueryParams, queryParams)) {
|
||||
const auto limitStr = queryParams.get("limit");
|
||||
const auto offsetStr = queryParams.get("offset");
|
||||
const auto startStr = queryParams.get("start");
|
||||
|
||||
uint64_t limit = 1;
|
||||
if (limitStr) {
|
||||
try {
|
||||
limit = std::stoull(limitStr->c_str());
|
||||
} catch (const std::exception& e) {
|
||||
return createResponse(Status::CODE_400, "Invalid 'limit' parameter");
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t offset = 0;
|
||||
if (offsetStr) {
|
||||
try {
|
||||
offset = std::stoull(offsetStr->c_str());
|
||||
} catch (const std::exception& e) {
|
||||
return createResponse(Status::CODE_400, "Invalid 'offset' parameter");
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t start_height;
|
||||
if (startStr) {
|
||||
try {
|
||||
start_height = std::stoull(startStr->c_str());
|
||||
} catch (const std::exception& e) {
|
||||
return createResponse(Status::CODE_400, "Invalid 'start' parameter");
|
||||
}
|
||||
} else {
|
||||
start_height = m_core_info->getCore().get_blockchain_storage().get_current_blockchain_size() - 1;
|
||||
}
|
||||
|
||||
if (limit == 0) {
|
||||
return createResponse(Status::CODE_400, "'limit' must be greater than 0");
|
||||
}
|
||||
|
||||
if (start_height < offset) {
|
||||
return createResponse(Status::CODE_400, "'start' height cannot be less than 'offset'");
|
||||
}
|
||||
|
||||
uint64_t current_height = start_height - offset;
|
||||
|
||||
if (limit == 1) {
|
||||
currency::block_rpc_extended_info rpc_details;
|
||||
if (!m_core_info->getCore().get_blockchain_storage().get_main_block_rpc_details(current_height, rpc_details)) {
|
||||
return createResponse(Status::CODE_404, "Block not found at specified height");
|
||||
}
|
||||
return createDtoResponse(Status::CODE_200, populateBlockDetailsModel(rpc_details));
|
||||
}
|
||||
|
||||
auto block_list = oatpp::List<oatpp::Object<BlockDetailsModel>>::createShared();
|
||||
for(uint64_t i = 0; i < limit; ++i)
|
||||
{
|
||||
if(current_height < i)
|
||||
{
|
||||
break; // Reached genesis
|
||||
}
|
||||
uint64_t height_to_fetch = current_height - i;
|
||||
currency::block_rpc_extended_info rpc_details;
|
||||
if(m_core_info->getCore().get_blockchain_storage().get_main_block_rpc_details(height_to_fetch, rpc_details))
|
||||
{
|
||||
block_list->push_back(populateBlockDetailsModel(rpc_details));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Could be that we requested past genesis, or a block is missing for some reason.
|
||||
// We'll just stop here.
|
||||
break;
|
||||
}
|
||||
}
|
||||
return createDtoResponse(Status::CODE_200, block_list);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(ApiController)
|
||||
|
||||
#endif /* BlockController_hpp */
|
||||
54
src/api/controller/path/block/height.hpp
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef BlockHeightController_hpp
|
||||
#define BlockHeightController_hpp
|
||||
|
||||
#include "modal/block/height.hpp"
|
||||
#include "controller/ApiCoreInfo.hpp"
|
||||
|
||||
#include "oatpp/web/server/api/ApiController.hpp"
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(ApiController)
|
||||
|
||||
/**
|
||||
* Block Height Controller
|
||||
*/
|
||||
class BlockHeightController : public oatpp::web::server::api::ApiController {
|
||||
private:
|
||||
OATPP_COMPONENT(std::shared_ptr<ApiCoreInfo>, m_core_info);
|
||||
public:
|
||||
explicit BlockHeightController(OATPP_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, objectMapper))
|
||||
: oatpp::web::server::api::ApiController(objectMapper)
|
||||
{}
|
||||
public:
|
||||
|
||||
ENDPOINT_INFO(getHeight) {
|
||||
info->summary = "Get the current blockchain height";
|
||||
info->addTag("Block");
|
||||
info->addResponse<Object<HeightModel>>(Status::CODE_200, "application/json");
|
||||
}
|
||||
ENDPOINT("GET", "/block/height", getHeight) {
|
||||
auto model = HeightModel::createShared();
|
||||
model->height = m_core_info->getCore().get_current_blockchain_size();
|
||||
return createDtoResponse(Status::CODE_200, model);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(ApiController)
|
||||
|
||||
#endif /* BlockHeightController_hpp */
|
||||
122
src/api/controller/path/block/identifier.hpp
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef BlockIdentifierController_hpp
|
||||
#define BlockIdentifierController_hpp
|
||||
|
||||
#include "modal/block/details.hpp"
|
||||
#include "modal/transaction/details.hpp"
|
||||
#include "controller/ApiCoreInfo.hpp"
|
||||
|
||||
#include "oatpp/web/server/api/ApiController.hpp"
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
|
||||
|
||||
#include "rpc/core_rpc_server_commands_defs.h"
|
||||
#include <string> // For std::string and std::stoull
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(ApiController)
|
||||
|
||||
/**
|
||||
* Block Identifier Controller
|
||||
* Acts as a proxy to fetch blocks by hash or by height (ID).
|
||||
*/
|
||||
class BlockIdentifierController : public oatpp::web::server::api::ApiController {
|
||||
private:
|
||||
OATPP_COMPONENT(std::shared_ptr<ApiCoreInfo>, m_core_info);
|
||||
public:
|
||||
explicit BlockIdentifierController(OATPP_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, objectMapper))
|
||||
: oatpp::web::server::api::ApiController(objectMapper)
|
||||
{}
|
||||
public:
|
||||
|
||||
ENDPOINT_INFO(getBlock) {
|
||||
info->summary = "Get a block by its hash or height (ID)";
|
||||
info->addTag("Block");
|
||||
info->pathParams["identifier"].description = "The hash (hex string) or height (integer) of the block to retrieve.";
|
||||
info->addResponse<Object<BlockDetailsModel>>(Status::CODE_200, "application/json");
|
||||
info->addResponse(Status::CODE_404, "text/plain");
|
||||
info->addResponse(Status::CODE_400, "text/plain");
|
||||
}
|
||||
ENDPOINT("GET", "/block/{identifier}", getBlock, PATH(String, identifier)) {
|
||||
|
||||
currency::block_rpc_extended_info rpc_details;
|
||||
bool block_found = false;
|
||||
|
||||
// Check if the identifier consists only of digits
|
||||
if (identifier->find_first_not_of("0123456789") == std::string::npos) {
|
||||
// It's a numeric ID (height)
|
||||
try {
|
||||
uint64_t height = std::stoull(identifier->c_str());
|
||||
block_found = m_core_info->getCore().get_blockchain_storage().get_main_block_rpc_details(height, rpc_details);
|
||||
} catch (const std::exception& e) {
|
||||
return createResponse(Status::CODE_400, "Invalid block height format");
|
||||
}
|
||||
} else {
|
||||
// It's a hash
|
||||
crypto::hash block_hash{};
|
||||
if (!epee::string_tools::hex_to_pod(*identifier, block_hash)) {
|
||||
return createResponse(Status::CODE_400, "Invalid block hash format");
|
||||
}
|
||||
block_found = m_core_info->getCore().get_blockchain_storage().get_main_block_rpc_details(block_hash, rpc_details);
|
||||
}
|
||||
|
||||
if (!block_found) {
|
||||
return createResponse(Status::CODE_404, "Block not found");
|
||||
}
|
||||
|
||||
// Common logic to populate the DTO
|
||||
auto blockDetails = BlockDetailsModel::createShared();
|
||||
|
||||
blockDetails->id = rpc_details.id;
|
||||
blockDetails->height = rpc_details.height;
|
||||
blockDetails->timestamp = rpc_details.timestamp;
|
||||
blockDetails->actual_timestamp = rpc_details.actual_timestamp;
|
||||
blockDetails->difficulty = rpc_details.difficulty;
|
||||
blockDetails->prev_id = rpc_details.prev_id;
|
||||
blockDetails->is_orphan = rpc_details.is_orphan;
|
||||
blockDetails->base_reward = rpc_details.base_reward;
|
||||
blockDetails->summary_reward = rpc_details.summary_reward;
|
||||
blockDetails->total_fee = rpc_details.total_fee;
|
||||
blockDetails->penalty = rpc_details.penalty;
|
||||
blockDetails->already_generated_coins = rpc_details.already_generated_coins;
|
||||
blockDetails->block_cumulative_size = rpc_details.block_cumulative_size;
|
||||
blockDetails->total_txs_size = rpc_details.total_txs_size;
|
||||
blockDetails->cumulative_diff_adjusted = rpc_details.cumulative_diff_adjusted;
|
||||
blockDetails->cumulative_diff_precise = rpc_details.cumulative_diff_precise;
|
||||
blockDetails->blob = rpc_details.blob;
|
||||
blockDetails->miner_text_info = rpc_details.miner_text_info;
|
||||
blockDetails->type = rpc_details.type;
|
||||
|
||||
auto tx_details_list = oatpp::List<oatpp::Object<TransactionDetailsModel>>::createShared();
|
||||
for(const auto& tx_rpc_info : rpc_details.transactions_details) {
|
||||
auto tx_model = TransactionDetailsModel::createShared();
|
||||
tx_model->id = tx_rpc_info.id;
|
||||
tx_model->fee = tx_rpc_info.fee;
|
||||
tx_model->amount = tx_rpc_info.amount;
|
||||
tx_model->blob_size = tx_rpc_info.blob_size;
|
||||
tx_model->keeper_block = tx_rpc_info.keeper_block;
|
||||
tx_model->timestamp = tx_rpc_info.timestamp;
|
||||
tx_details_list->push_back(tx_model);
|
||||
}
|
||||
blockDetails->transactions_details = tx_details_list;
|
||||
|
||||
return createDtoResponse(Status::CODE_200, blockDetails);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(ApiController)
|
||||
|
||||
#endif /* BlockIdentifierController_hpp */
|
||||
75
src/api/controller/path/block/submit.hpp
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef BlockSubmitController_hpp
|
||||
#define BlockSubmitController_hpp
|
||||
|
||||
#include "oatpp/web/server/api/ApiController.hpp"
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "controller/ApiCoreInfo.hpp"
|
||||
#include "modal/block/submit_request.hpp"
|
||||
#include "modal/block/submit_response.hpp"
|
||||
#include "currency_core/currency_format_utils.h"
|
||||
#include "currency_core/verification_context.h"
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(ApiController)
|
||||
|
||||
class BlockSubmitController : public oatpp::web::server::api::ApiController {
|
||||
private:
|
||||
OATPP_COMPONENT(std::shared_ptr<ApiCoreInfo>, m_core_info);
|
||||
public:
|
||||
explicit BlockSubmitController(OATPP_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, objectMapper))
|
||||
: oatpp::web::server::api::ApiController(objectMapper) {}
|
||||
public:
|
||||
|
||||
ENDPOINT_INFO(submitBlock) {
|
||||
info->summary = "Submit a new block to the network";
|
||||
info->addTag("Block");
|
||||
info->addConsumes<Object<SubmitBlockRequestModel>>("application/json");
|
||||
info->addResponse<Object<SubmitBlockResponseModel>>(Status::CODE_200, "application/json");
|
||||
info->addResponse(Status::CODE_400, "text/plain");
|
||||
info->addResponse(Status::CODE_406, "text/plain");
|
||||
}
|
||||
ENDPOINT("POST", "/block/submit", submitBlock, BODY_DTO(Object<SubmitBlockRequestModel>, requestModel)) {
|
||||
if (!requestModel->block_blob || requestModel->block_blob->empty()) {
|
||||
return createResponse(Status::CODE_400, "Missing block_blob");
|
||||
}
|
||||
|
||||
currency::blobdata blockblob;
|
||||
if (!epee::string_tools::parse_hexstr_to_binbuff(*requestModel->block_blob, blockblob)) {
|
||||
return createResponse(Status::CODE_400, "Wrong block blob");
|
||||
}
|
||||
|
||||
currency::block b = AUTO_VAL_INIT(b);
|
||||
if (!currency::parse_and_validate_block_from_blob(blockblob, b)) {
|
||||
return createResponse(Status::CODE_400, "Wrong block blob");
|
||||
}
|
||||
|
||||
currency::block_verification_context bvc = AUTO_VAL_INIT(bvc);
|
||||
if (!m_core_info->getCore().handle_block_found(b, &bvc)) {
|
||||
if (bvc.m_added_to_altchain) {
|
||||
return createResponse(Status::CODE_406, "Block added as alternative");
|
||||
}
|
||||
return createResponse(Status::CODE_406, "Block not accepted");
|
||||
}
|
||||
|
||||
auto responseModel = SubmitBlockResponseModel::createShared();
|
||||
responseModel->status = "OK";
|
||||
return createDtoResponse(Status::CODE_200, responseModel);
|
||||
}
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(ApiController)
|
||||
|
||||
#endif /* BlockSubmitController_hpp */
|
||||
104
src/api/controller/path/block/template.hpp
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef BlockTemplateController_hpp
|
||||
#define BlockTemplateController_hpp
|
||||
|
||||
#include "oatpp/web/server/api/ApiController.hpp"
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "controller/ApiCoreInfo.hpp"
|
||||
#include "modal/block/template_request.hpp"
|
||||
#include "modal/block/template.hpp"
|
||||
#include "currency_core/currency_format_utils.h"
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(ApiController)
|
||||
|
||||
class BlockTemplateController : public oatpp::web::server::api::ApiController {
|
||||
private:
|
||||
OATPP_COMPONENT(std::shared_ptr<ApiCoreInfo>, m_core_info);
|
||||
public:
|
||||
explicit BlockTemplateController(OATPP_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, objectMapper))
|
||||
: oatpp::web::server::api::ApiController(objectMapper) {}
|
||||
public:
|
||||
|
||||
ENDPOINT_INFO(createBlockTemplate) {
|
||||
info->summary = "Create a block template for mining";
|
||||
info->addTag("Block");
|
||||
info->addConsumes<Object<BlockTemplateRequestModel>>("application/json");
|
||||
info->addResponse<Object<BlockTemplateModel>>(Status::CODE_200, "application/json");
|
||||
info->addResponse(Status::CODE_400, "text/plain");
|
||||
info->addResponse(Status::CODE_500, "text/plain");
|
||||
}
|
||||
ENDPOINT("POST", "/block/template", createBlockTemplate, BODY_DTO(Object<BlockTemplateRequestModel>, requestModel)) {
|
||||
currency::create_block_template_params params = AUTO_VAL_INIT(params);
|
||||
|
||||
if (!currency::get_account_address_from_str(params.miner_address, *requestModel->miner_address)) {
|
||||
return createResponse(Status::CODE_400, "Failed to parse miner_address");
|
||||
}
|
||||
if (requestModel->stakeholder_address && !currency::get_account_address_from_str(params.stakeholder_address, *requestModel->stakeholder_address)) {
|
||||
return createResponse(Status::CODE_400, "Failed to parse stakeholder_address");
|
||||
}
|
||||
|
||||
params.ex_nonce = requestModel->ex_nonce ? *requestModel->ex_nonce : "";
|
||||
params.pos = requestModel->pos;
|
||||
params.ignore_pow_ts_check = requestModel->ignore_pow_ts_check;
|
||||
|
||||
if (requestModel->pe) {
|
||||
params.pe.amount = requestModel->pe->amount;
|
||||
params.pe.g_index = requestModel->pe->g_index;
|
||||
epee::string_tools::hex_to_pod(*requestModel->pe->keyimage, params.pe.keyimage);
|
||||
params.pe.block_timestamp = requestModel->pe->block_timestamp;
|
||||
params.pe.stake_unlock_time = requestModel->pe->stake_unlock_time;
|
||||
epee::string_tools::hex_to_pod(*requestModel->pe->tx_id, params.pe.tx_id);
|
||||
params.pe.tx_out_index = requestModel->pe->tx_out_index;
|
||||
params.pe.wallet_index = requestModel->pe->wallet_index;
|
||||
}
|
||||
|
||||
for (const auto& tx_hex : *requestModel->explicit_txs) {
|
||||
currency::transaction tx;
|
||||
currency::blobdata tx_blob;
|
||||
if (!epee::string_tools::parse_hexstr_to_binbuff(*tx_hex, tx_blob) || !currency::parse_and_validate_tx_from_blob(tx_blob, tx)) {
|
||||
return createResponse(Status::CODE_400, "Failed to parse explicit_txs");
|
||||
}
|
||||
params.explicit_txs.push_back(tx);
|
||||
}
|
||||
|
||||
currency::create_block_template_response response = AUTO_VAL_INIT(response);
|
||||
if (!m_core_info->getCore().get_block_template(params, response)) {
|
||||
return createResponse(Status::CODE_500, "Internal error: failed to create block template");
|
||||
}
|
||||
|
||||
auto model = BlockTemplateModel::createShared();
|
||||
model->blocktemplate_blob = epee::string_tools::buff_to_hex_nodelimer(t_serializable_object_to_blob(response.b));
|
||||
model->difficulty = response.diffic.convert_to<std::string>();
|
||||
model->height = response.height;
|
||||
model->block_reward_without_fee = response.block_reward_without_fee;
|
||||
model->block_reward = response.block_reward;
|
||||
model->txs_fee = response.txs_fee;
|
||||
model->prev_hash = epee::string_tools::pod_to_hex(response.b.prev_id);
|
||||
model->seed = epee::string_tools::pod_to_hex(currency::ethash_epoch_to_seed(currency::ethash_height_to_epoch(response.height)));
|
||||
|
||||
auto tgc_model = TxGenerationContextModel::createShared();
|
||||
// This is a very complex object with many cryptographic details.
|
||||
// For now, we will leave it empty as it's not essential for basic mining.
|
||||
// A dedicated endpoint could be created later to expose this if needed.
|
||||
model->miner_tx_tgc = tgc_model;
|
||||
|
||||
return createDtoResponse(Status::CODE_200, model);
|
||||
}
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(ApiController)
|
||||
|
||||
#endif /* BlockTemplateController_hpp */
|
||||
228
src/api/controller/path/info.hpp
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef InfoController_hpp
|
||||
#define InfoController_hpp
|
||||
|
||||
#include "oatpp/web/server/api/ApiController.hpp"
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "controller/ApiCoreInfo.hpp"
|
||||
#include "modal/info/details.hpp"
|
||||
#include "currency_core/currency_stat_info.h"
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(ApiController)
|
||||
|
||||
/**
|
||||
* Info Controller
|
||||
*/
|
||||
class InfoController : public oatpp::web::server::api::ApiController {
|
||||
private:
|
||||
OATPP_COMPONENT(std::shared_ptr<ApiCoreInfo>, m_core_info);
|
||||
public:
|
||||
explicit InfoController(OATPP_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, objectMapper))
|
||||
: oatpp::web::server::api::ApiController(objectMapper)
|
||||
{}
|
||||
public:
|
||||
|
||||
ENDPOINT_INFO(getInfo) {
|
||||
info->summary = "Get detailed information about the blockchain and daemon state";
|
||||
info->addTag("Info");
|
||||
info->addResponse<Object<InfoModel>>(Status::CODE_200, "application/json");
|
||||
info->queryParams["flags"].name = "flags";
|
||||
info->queryParams["flags"].description = "Possible values: net_time_delta_median, current_network_hashrate_50, current_network_hashrate_350, seconds_for_10_blocks, seconds_for_30_blocks, transactions_daily_stat, last_pos_timestamp, last_pow_timestamp, total_coins, last_block_size, tx_count_in_last_block, pos_sequence_factor, pow_sequence_factor, pos_difficulty, performance, outs_stat, expirations_median.";
|
||||
}
|
||||
ENDPOINT("GET", "/info", getInfo, QUERY(String, flags, "flags",""), QUERIES(QueryParams, queryParams)) {
|
||||
auto model = InfoModel::createShared();
|
||||
currency::core& core = m_core_info->getCore();
|
||||
currency::t_currency_protocol_handler<currency::core>& p2p_handler = m_core_info->getP2p().get_payload_object();
|
||||
currency::blockchain_storage& bcs = core.get_blockchain_storage();
|
||||
|
||||
model->height = bcs.get_current_blockchain_size();
|
||||
model->tx_count = bcs.get_total_transactions() - model->height; //without coinbase
|
||||
model->tx_pool_size = core.get_pool_transactions_count();
|
||||
model->alt_blocks_count = bcs.get_alternative_blocks_count();
|
||||
uint64_t total_conn = m_core_info->getP2p().get_connections_count();
|
||||
model->outgoing_connections_count = m_core_info->getP2p().get_outgoing_connections_count();
|
||||
model->incoming_connections_count = total_conn - model->outgoing_connections_count;
|
||||
model->synchronized_connections_count = p2p_handler.get_synchronized_connections_count();
|
||||
model->white_peerlist_size = m_core_info->getP2p().get_peerlist_manager().get_white_peers_count();
|
||||
model->grey_peerlist_size = m_core_info->getP2p().get_peerlist_manager().get_gray_peers_count();
|
||||
model->current_blocks_median = bcs.get_current_comulative_blocksize_limit() / 2;
|
||||
model->alias_count = bcs.get_aliases_count();
|
||||
model->current_max_allowed_block_size = bcs.get_current_comulative_blocksize_limit();
|
||||
|
||||
if (!model->outgoing_connections_count)
|
||||
model->daemon_network_state = "connecting";
|
||||
else if (p2p_handler.is_synchronized())
|
||||
model->daemon_network_state = "online";
|
||||
else
|
||||
model->daemon_network_state = "synchronizing";
|
||||
|
||||
model->synchronization_start_height = p2p_handler.get_core_inital_height();
|
||||
model->max_net_seen_height = p2p_handler.get_max_seen_height();
|
||||
|
||||
nodetool::maintainers_info_external mi_res;
|
||||
m_core_info->getP2p().get_maintainers_info(mi_res);
|
||||
auto mi_model = MaintainersInfoModel::createShared();
|
||||
mi_model->ver_major = mi_res.ver_major;
|
||||
mi_model->ver_minor = mi_res.ver_minor;
|
||||
mi_model->ver_revision = mi_res.ver_revision;
|
||||
mi_model->build_no = mi_res.build_no;
|
||||
mi_model->mode = mi_res.mode;
|
||||
model->mi = mi_model;
|
||||
|
||||
model->pos_allowed = bcs.is_pos_allowed();
|
||||
model->pos_difficulty = bcs.get_cached_next_difficulty(true).convert_to<std::string>();
|
||||
model->pow_difficulty = bcs.get_cached_next_difficulty(false).convert_to<uint64_t>();
|
||||
model->default_fee = bcs.get_core_runtime_config().tx_default_fee;
|
||||
model->minimum_fee = bcs.get_core_runtime_config().tx_pool_min_fee;
|
||||
|
||||
auto hf_list = oatpp::List<Boolean>::createShared();
|
||||
for (size_t i = 0; i != ZANO_HARDFORKS_TOTAL; i++)
|
||||
{
|
||||
hf_list->push_back(bcs.is_hardfork_active(i));
|
||||
}
|
||||
model->is_hardfork_active = hf_list;
|
||||
|
||||
auto flagsStr = queryParams.get("flags");
|
||||
if (flagsStr) {
|
||||
std::istringstream iss(flagsStr->c_str());
|
||||
std::string flag;
|
||||
while (std::getline(iss, flag, ',')) {
|
||||
if (flag == "net_time_delta_median") {
|
||||
int64_t last_median2local_time_diff, last_ntp2local_time_diff;
|
||||
if (!p2p_handler.get_last_time_sync_difference(last_median2local_time_diff, last_ntp2local_time_diff))
|
||||
model->net_time_delta_median = 1;
|
||||
} else if (flag == "current_network_hashrate_50") {
|
||||
model->current_network_hashrate_50 = bcs.get_current_hashrate(50);
|
||||
} else if (flag == "current_network_hashrate_350") {
|
||||
model->current_network_hashrate_350 = bcs.get_current_hashrate(350);
|
||||
} else if (flag == "seconds_for_10_blocks") {
|
||||
model->seconds_for_10_blocks = bcs.get_seconds_between_last_n_block(10);
|
||||
} else if (flag == "seconds_for_30_blocks") {
|
||||
model->seconds_for_30_blocks = bcs.get_seconds_between_last_n_block(30);
|
||||
} else if (flag == "transactions_daily_stat") {
|
||||
uint64_t daily_tx_count = 0, daily_tx_vol = 0;
|
||||
bcs.get_transactions_daily_stat(daily_tx_count, daily_tx_vol);
|
||||
auto daily_tx_count_list = oatpp::List<UInt64>::createShared();
|
||||
daily_tx_count_list->push_back(daily_tx_count);
|
||||
model->transactions_cnt_per_day = daily_tx_count_list;
|
||||
auto daily_tx_vol_list = oatpp::List<UInt64>::createShared();
|
||||
daily_tx_vol_list->push_back(daily_tx_vol);
|
||||
model->transactions_volume_per_day = daily_tx_vol_list;
|
||||
} else if (flag == "last_pos_timestamp") {
|
||||
auto pos_bl_ptr = bcs.get_last_block_of_type(true);
|
||||
if (pos_bl_ptr) model->last_pos_timestamp = pos_bl_ptr->bl.timestamp;
|
||||
} else if (flag == "last_pow_timestamp") {
|
||||
auto pow_bl_ptr = bcs.get_last_block_of_type(false);
|
||||
if (pow_bl_ptr) model->last_pow_timestamp = pow_bl_ptr->bl.timestamp;
|
||||
} else if (flag == "total_coins") {
|
||||
model->total_coins = boost::lexical_cast<std::string>(bcs.total_coins());
|
||||
} else if (flag == "last_block_size") {
|
||||
std::vector<size_t> sz;
|
||||
bcs.get_last_n_blocks_sizes(sz, 1);
|
||||
model->last_block_size = sz.size() ? sz.back() : 0;
|
||||
} else if (flag == "tx_count_in_last_block") {
|
||||
currency::block b = AUTO_VAL_INIT(b);
|
||||
bcs.get_top_block(b);
|
||||
model->tx_count_in_last_block = b.tx_hashes.size();
|
||||
} else if (flag == "pos_sequence_factor") {
|
||||
model->pos_sequence_factor = bcs.get_current_sequence_factor(true);
|
||||
} else if (flag == "pow_sequence_factor") {
|
||||
model->pow_sequence_factor = bcs.get_current_sequence_factor(false);
|
||||
} else if (flag == "pos_difficulty") {
|
||||
currency::block b = AUTO_VAL_INIT(b);
|
||||
bcs.get_top_block(b);
|
||||
model->block_reward = currency::get_base_block_reward(model->height);
|
||||
model->last_block_total_reward = currency::get_reward_from_miner_tx(b.miner_tx);
|
||||
model->pos_diff_total_coins_rate = (bcs.get_cached_next_difficulty(true) / (bcs.total_coins() - PREMINE_AMOUNT + 1)).convert_to<uint64_t>();
|
||||
model->last_block_timestamp = b.timestamp;
|
||||
model->last_block_hash = string_tools::pod_to_hex(get_block_hash(b));
|
||||
} else if (flag == "performance") {
|
||||
auto perf_model = PerformanceModel::createShared();
|
||||
const currency::blockchain_storage::performnce_data& pd = bcs.get_performnce_data();
|
||||
auto block_processing_model = BlockProcessingPerformanceModel::createShared();
|
||||
block_processing_model->block_processing_time_0 = pd.block_processing_time_0_ms.get_avg();
|
||||
block_processing_model->block_processing_time_1 = pd.block_processing_time_1.get_avg();
|
||||
block_processing_model->target_calculating_time_2 = pd.target_calculating_time_2.get_avg();
|
||||
block_processing_model->longhash_calculating_time_3 = pd.longhash_calculating_time_3.get_avg();
|
||||
block_processing_model->all_txs_insert_time_5 = pd.all_txs_insert_time_5.get_avg();
|
||||
block_processing_model->etc_stuff_6 = pd.etc_stuff_6.get_avg();
|
||||
block_processing_model->insert_time_4 = pd.insert_time_4.get_avg();
|
||||
block_processing_model->raise_block_core_event = pd.raise_block_core_event.get_avg();
|
||||
block_processing_model->target_calculating_enum_blocks = pd.target_calculating_enum_blocks.get_avg();
|
||||
block_processing_model->target_calculating_calc = pd.target_calculating_calc.get_avg();
|
||||
perf_model->block_processing = block_processing_model;
|
||||
|
||||
auto tx_processing_model = TxProcessingPerformanceModel::createShared();
|
||||
tx_processing_model->tx_check_inputs = pd.tx_check_inputs_time.get_avg();
|
||||
tx_processing_model->tx_add_one_tx = pd.tx_add_one_tx_time.get_avg();
|
||||
tx_processing_model->tx_process_extra = pd.tx_process_extra.get_avg();
|
||||
tx_processing_model->tx_process_attachment = pd.tx_process_attachment.get_avg();
|
||||
tx_processing_model->tx_process_inputs = pd.tx_process_inputs.get_avg();
|
||||
tx_processing_model->tx_push_global_index = pd.tx_push_global_index.get_avg();
|
||||
tx_processing_model->tx_check_exist = pd.tx_check_exist.get_avg();
|
||||
tx_processing_model->tx_append = pd.tx_append_time.get_avg();
|
||||
tx_processing_model->tx_append_rl_wait = pd.tx_append_rl_wait.get_avg();
|
||||
tx_processing_model->tx_append_is_expired = pd.tx_append_is_expired.get_avg();
|
||||
tx_processing_model->tx_store_db = pd.tx_store_db.get_avg();
|
||||
tx_processing_model->tx_check_inputs_prefix_hash = pd.tx_check_inputs_prefix_hash.get_avg();
|
||||
tx_processing_model->tx_check_inputs_attachment_check = pd.tx_check_inputs_attachment_check.get_avg();
|
||||
tx_processing_model->tx_check_inputs_loop = pd.tx_check_inputs_loop.get_avg();
|
||||
tx_processing_model->tx_check_inputs_loop_kimage_check = pd.tx_check_inputs_loop_kimage_check.get_avg();
|
||||
tx_processing_model->tx_check_inputs_loop_ch_in_val_sig = pd.tx_check_inputs_loop_ch_in_val_sig.get_avg();
|
||||
tx_processing_model->tx_check_inputs_loop_scan_outputkeys_get_item_size = pd.tx_check_inputs_loop_scan_outputkeys_get_item_size.get_avg();
|
||||
tx_processing_model->tx_check_inputs_loop_scan_outputkeys_relative_to_absolute = pd.tx_check_inputs_loop_scan_outputkeys_relative_to_absolute.get_avg();
|
||||
tx_processing_model->tx_check_inputs_loop_scan_outputkeys_loop = pd.tx_check_inputs_loop_scan_outputkeys_loop.get_avg();
|
||||
tx_processing_model->tx_check_inputs_loop_scan_outputkeys_loop_get_subitem = pd.tx_check_inputs_loop_scan_outputkeys_loop_get_subitem.get_avg();
|
||||
tx_processing_model->tx_check_inputs_loop_scan_outputkeys_loop_find_tx = pd.tx_check_inputs_loop_scan_outputkeys_loop_find_tx.get_avg();
|
||||
tx_processing_model->tx_check_inputs_loop_scan_outputkeys_loop_handle_output = pd.tx_check_inputs_loop_scan_outputkeys_loop_handle_output.get_avg();
|
||||
tx_processing_model->tx_mixin_count = pd.tx_mixin_count.get_avg();
|
||||
perf_model->tx_processing = tx_processing_model;
|
||||
|
||||
const currency::tx_memory_pool::performnce_data& pool_pd = core.get_tx_pool().get_performnce_data();
|
||||
auto tx_pool_model = TxPoolPerformanceModel::createShared();
|
||||
tx_pool_model->tx_processing_time = pool_pd.tx_processing_time.get_avg();
|
||||
tx_pool_model->check_inputs_types_supported_time = pool_pd.check_inputs_types_supported_time.get_avg();
|
||||
tx_pool_model->expiration_validate_time = pool_pd.expiration_validate_time.get_avg();
|
||||
tx_pool_model->validate_amount_time = pool_pd.validate_amount_time.get_avg();
|
||||
tx_pool_model->validate_alias_time = pool_pd.validate_alias_time.get_avg();
|
||||
tx_pool_model->check_keyimages_ws_ms_time = pool_pd.check_keyimages_ws_ms_time.get_avg();
|
||||
tx_pool_model->check_inputs_time = pool_pd.check_inputs_time.get_avg();
|
||||
tx_pool_model->begin_tx_time = pool_pd.begin_tx_time.get_avg();
|
||||
tx_pool_model->update_db_time = pool_pd.update_db_time.get_avg();
|
||||
tx_pool_model->db_commit_time = pool_pd.db_commit_time.get_avg();
|
||||
perf_model->tx_pool = tx_pool_model;
|
||||
|
||||
auto db_stat_model = DbStatInfoModel::createShared();
|
||||
db_stat_model->map_size = pd.si.map_size;
|
||||
db_stat_model->tx_count = pd.si.tx_count;
|
||||
db_stat_model->write_tx_count = pd.si.write_tx_count;
|
||||
perf_model->db_stat_info = db_stat_model;
|
||||
|
||||
model->performance_data = perf_model;
|
||||
} else if (flag == "expirations_median") {
|
||||
model->expiration_median_timestamp = bcs.get_tx_expiration_median();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return createDtoResponse(Status::CODE_200, model);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(ApiController)
|
||||
|
||||
#endif /* InfoController_hpp */
|
||||
57
src/api/controller/path/info/version.hpp
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef InfoVersionController_hpp
|
||||
#define InfoVersionController_hpp
|
||||
|
||||
#include "oatpp/web/server/api/ApiController.hpp"
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "version.h"
|
||||
#include "modal/meta/version.hpp"
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(ApiController)
|
||||
|
||||
/**
|
||||
* Version Controller
|
||||
*/
|
||||
class InfoVersionController : public oatpp::web::server::api::ApiController {
|
||||
public:
|
||||
explicit InfoVersionController(OATPP_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, objectMapper))
|
||||
: oatpp::web::server::api::ApiController(objectMapper)
|
||||
{}
|
||||
public:
|
||||
|
||||
ENDPOINT_INFO(version)
|
||||
{
|
||||
info->addTag("Info");
|
||||
info->summary = "Get API version";
|
||||
info->description = "Returns the current version of the API.";
|
||||
info->addResponse<Object<VersionModel>>(Status::CODE_200, "application/json");
|
||||
}
|
||||
ENDPOINT("GET", "/info/version", version)
|
||||
{
|
||||
auto model = VersionModel::createShared();
|
||||
model->version = PROJECT_VERSION;
|
||||
model->version_long = PROJECT_VERSION_LONG;
|
||||
model->major = PROJECT_MAJOR_VERSION;
|
||||
model->minor = PROJECT_MINOR_VERSION;
|
||||
model->revision = PROJECT_REVISION;
|
||||
return createDtoResponse(Status::CODE_200, model);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(ApiController)
|
||||
|
||||
#endif /* InfoVersionController_hpp */
|
||||
36
src/api/main.cpp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#include "ApiServer.hpp"
|
||||
#include "oatpp/core/base/Environment.hpp"
|
||||
#include "common/util.h"
|
||||
|
||||
int main(int argc, const char * argv[]) {
|
||||
|
||||
oatpp::base::Environment::init();
|
||||
|
||||
ApiServer server;
|
||||
|
||||
tools::signal_handler::install([&server] {
|
||||
server.stop();
|
||||
});
|
||||
|
||||
server.start();
|
||||
server.wait();
|
||||
|
||||
/* Destroy oatpp Environment */
|
||||
oatpp::base::Environment::destroy();
|
||||
|
||||
return 0;
|
||||
}
|
||||
59
src/api/modal/block/details.hpp
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef BlockDetailsModel_hpp
|
||||
#define BlockDetailsModel_hpp
|
||||
|
||||
#include "modal/transaction/details.hpp"
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
/**
|
||||
* Model for detailed block information.
|
||||
*/
|
||||
class BlockDetailsModel : public oatpp::DTO {
|
||||
DTO_INIT(BlockDetailsModel, DTO);
|
||||
|
||||
DTO_FIELD(UInt64, actual_timestamp, "actual_timestamp");
|
||||
DTO_FIELD(String, already_generated_coins, "already_generated_coins");
|
||||
DTO_FIELD(UInt64, base_reward, "base_reward");
|
||||
DTO_FIELD(String, blob, "blob");
|
||||
DTO_FIELD(UInt64, block_cumulative_size, "block_cumulative_size");
|
||||
DTO_FIELD(UInt64, block_tself_size, "block_tself_size");
|
||||
DTO_FIELD(String, cumulative_diff_adjusted, "cumulative_diff_adjusted");
|
||||
DTO_FIELD(String, cumulative_diff_precise, "cumulative_diff_precise");
|
||||
DTO_FIELD(String, difficulty, "difficulty");
|
||||
DTO_FIELD(UInt64, effective_fee_median, "effective_fee_median");
|
||||
DTO_FIELD(UInt64, height, "height");
|
||||
DTO_FIELD(String, id, "id");
|
||||
DTO_FIELD(Boolean, is_orphan, "is_orphan");
|
||||
DTO_FIELD(String, miner_text_info, "miner_text_info");
|
||||
DTO_FIELD(String, object_in_json, "object_in_json");
|
||||
DTO_FIELD(UInt64, penalty, "penalty");
|
||||
DTO_FIELD(String, pow_seed, "pow_seed");
|
||||
DTO_FIELD(String, prev_id, "prev_id");
|
||||
DTO_FIELD(UInt64, summary_reward, "summary_reward");
|
||||
DTO_FIELD(UInt64, this_block_fee_median, "this_block_fee_median");
|
||||
DTO_FIELD(UInt64, timestamp, "timestamp");
|
||||
DTO_FIELD(UInt64, total_fee, "total_fee");
|
||||
DTO_FIELD(UInt64, total_txs_size, "total_txs_size");
|
||||
DTO_FIELD(List<Object<TransactionDetailsModel>>, transactions_details, "transactions_details");
|
||||
DTO_FIELD(UInt32, type, "type");
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
#endif /* BlockDetailsModel_hpp */
|
||||
32
src/api/modal/block/height.hpp
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef HeightModel_hpp
|
||||
#define HeightModel_hpp
|
||||
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
class HeightModel final : public oatpp::DTO
|
||||
{
|
||||
DTO_INIT(HeightModel, DTO);
|
||||
|
||||
DTO_FIELD(UInt64, height);
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
#endif /* HeightModel_hpp */
|
||||
32
src/api/modal/block/submit_request.hpp
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef SubmitBlockRequestModel_hpp
|
||||
#define SubmitBlockRequestModel_hpp
|
||||
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
class SubmitBlockRequestModel final : public oatpp::DTO
|
||||
{
|
||||
DTO_INIT(SubmitBlockRequestModel, DTO);
|
||||
|
||||
DTO_FIELD(String, block_blob);
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
#endif /* SubmitBlockRequestModel_hpp */
|
||||
32
src/api/modal/block/submit_response.hpp
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef SubmitBlockResponseModel_hpp
|
||||
#define SubmitBlockResponseModel_hpp
|
||||
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
class SubmitBlockResponseModel final : public oatpp::DTO
|
||||
{
|
||||
DTO_INIT(SubmitBlockResponseModel, DTO);
|
||||
|
||||
DTO_FIELD(String, status);
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
#endif /* SubmitBlockResponseModel_hpp */
|
||||
41
src/api/modal/block/template.hpp
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef BlockTemplateModel_hpp
|
||||
#define BlockTemplateModel_hpp
|
||||
|
||||
#include "../meta/tx_generation_context.hpp"
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
class BlockTemplateModel final : public oatpp::DTO
|
||||
{
|
||||
DTO_INIT(BlockTemplateModel, DTO);
|
||||
|
||||
DTO_FIELD(String, blocktemplate_blob);
|
||||
DTO_FIELD(String, difficulty);
|
||||
DTO_FIELD(UInt64, height);
|
||||
DTO_FIELD(Object<TxGenerationContextModel>, miner_tx_tgc);
|
||||
DTO_FIELD(UInt64, block_reward_without_fee);
|
||||
DTO_FIELD(UInt64, block_reward);
|
||||
DTO_FIELD(UInt64, txs_fee);
|
||||
DTO_FIELD(String, prev_hash);
|
||||
DTO_FIELD(String, seed);
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
#endif /* BlockTemplateModel_hpp */
|
||||
39
src/api/modal/block/template_request.hpp
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef BlockTemplateRequestModel_hpp
|
||||
#define BlockTemplateRequestModel_hpp
|
||||
|
||||
#include "../meta/pos_entry.hpp"
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
class BlockTemplateRequestModel final : public oatpp::DTO
|
||||
{
|
||||
DTO_INIT(BlockTemplateRequestModel, DTO);
|
||||
|
||||
DTO_FIELD(String, miner_address);
|
||||
DTO_FIELD(String, stakeholder_address);
|
||||
DTO_FIELD(String, ex_nonce);
|
||||
DTO_FIELD(Boolean, pos, "pos_block");
|
||||
DTO_FIELD(Boolean, ignore_pow_ts_check);
|
||||
DTO_FIELD(Object<PosEntryModel>, pe);
|
||||
DTO_FIELD(List<String>, explicit_txs);
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
#endif /* BlockTemplateRequestModel_hpp */
|
||||
79
src/api/modal/info/details.hpp
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef InfoModel_hpp
|
||||
#define InfoModel_hpp
|
||||
|
||||
#include "maintainers_info.hpp"
|
||||
#include "modal/meta/performance.hpp"
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
class InfoModel final : public oatpp::DTO
|
||||
{
|
||||
DTO_INIT(InfoModel, DTO);
|
||||
|
||||
DTO_FIELD(UInt64, height);
|
||||
DTO_FIELD(UInt64, tx_count);
|
||||
DTO_FIELD(UInt64, tx_pool_size);
|
||||
DTO_FIELD(UInt64, alt_blocks_count);
|
||||
DTO_FIELD(UInt64, outgoing_connections_count);
|
||||
DTO_FIELD(UInt64, incoming_connections_count);
|
||||
DTO_FIELD(UInt64, synchronized_connections_count);
|
||||
DTO_FIELD(UInt64, white_peerlist_size);
|
||||
DTO_FIELD(UInt64, grey_peerlist_size);
|
||||
DTO_FIELD(UInt64, current_blocks_median);
|
||||
DTO_FIELD(UInt64, alias_count);
|
||||
DTO_FIELD(UInt64, current_max_allowed_block_size);
|
||||
DTO_FIELD(String, daemon_network_state);
|
||||
DTO_FIELD(UInt64, synchronization_start_height);
|
||||
DTO_FIELD(UInt64, max_net_seen_height);
|
||||
DTO_FIELD(Object<MaintainersInfoModel>, mi);
|
||||
DTO_FIELD(Boolean, pos_allowed);
|
||||
DTO_FIELD(String, pos_difficulty);
|
||||
DTO_FIELD(UInt64, pow_difficulty);
|
||||
DTO_FIELD(UInt64, default_fee);
|
||||
DTO_FIELD(UInt64, minimum_fee);
|
||||
DTO_FIELD(List<Boolean>, is_hardfork_active);
|
||||
DTO_FIELD(Int64, net_time_delta_median);
|
||||
DTO_FIELD(UInt64, current_network_hashrate_50);
|
||||
DTO_FIELD(UInt64, current_network_hashrate_350);
|
||||
DTO_FIELD(UInt64, seconds_for_10_blocks);
|
||||
DTO_FIELD(UInt64, seconds_for_30_blocks);
|
||||
DTO_FIELD(List<UInt64>, transactions_cnt_per_day);
|
||||
DTO_FIELD(List<UInt64>, transactions_volume_per_day);
|
||||
DTO_FIELD(UInt64, last_pos_timestamp);
|
||||
DTO_FIELD(UInt64, last_pow_timestamp);
|
||||
DTO_FIELD(String, total_coins);
|
||||
DTO_FIELD(UInt64, last_block_size);
|
||||
DTO_FIELD(UInt64, tx_count_in_last_block);
|
||||
DTO_FIELD(Float64, pos_sequence_factor);
|
||||
DTO_FIELD(Float64, pow_sequence_factor);
|
||||
DTO_FIELD(UInt64, block_reward);
|
||||
DTO_FIELD(UInt64, last_block_total_reward);
|
||||
DTO_FIELD(UInt64, pos_diff_total_coins_rate);
|
||||
DTO_FIELD(UInt64, last_block_timestamp);
|
||||
DTO_FIELD(String, last_block_hash);
|
||||
DTO_FIELD(Int64, pos_block_ts_shift_vs_actual);
|
||||
DTO_FIELD(Fields<UInt64>, outs_stat); // Represents a map of uint64_t to uint64_t
|
||||
DTO_FIELD(Object<PerformanceModel>, performance_data);
|
||||
DTO_FIELD(UInt64, offers_count);
|
||||
DTO_FIELD(UInt64, expiration_median_timestamp);
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
#endif /* InfoModel_hpp */
|
||||
36
src/api/modal/info/maintainers_info.hpp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef MaintainersInfoModel_hpp
|
||||
#define MaintainersInfoModel_hpp
|
||||
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
class MaintainersInfoModel final : public oatpp::DTO
|
||||
{
|
||||
DTO_INIT(MaintainersInfoModel, DTO);
|
||||
|
||||
DTO_FIELD(UInt8, ver_major);
|
||||
DTO_FIELD(UInt8, ver_minor);
|
||||
DTO_FIELD(UInt8, ver_revision);
|
||||
DTO_FIELD(UInt32, build_no);
|
||||
DTO_FIELD(UInt8, mode);
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
#endif /* MaintainersInfoModel_hpp */
|
||||
34
src/api/modal/meta/db_stat_info.hpp
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef DbStatInfoModel_hpp
|
||||
#define DbStatInfoModel_hpp
|
||||
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
class DbStatInfoModel final : public oatpp::DTO
|
||||
{
|
||||
DTO_INIT(DbStatInfoModel, DTO);
|
||||
|
||||
DTO_FIELD(UInt64, tx_count);
|
||||
DTO_FIELD(UInt64, write_tx_count);
|
||||
DTO_FIELD(UInt64, map_size);
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
#endif /* DbStatInfoModel_hpp */
|
||||
25
src/api/modal/meta/page.hpp
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
#ifndef PAGEDTO_HPP
|
||||
#define PAGEDTO_HPP
|
||||
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
template<class T>
|
||||
class PageDto : public oatpp::DTO {
|
||||
|
||||
DTO_INIT(PageDto, DTO);
|
||||
|
||||
DTO_FIELD(UInt32, offset);
|
||||
DTO_FIELD(UInt32, limit);
|
||||
DTO_FIELD(UInt32, count);
|
||||
DTO_FIELD(Vector<T>, items);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
#endif //PAGEDTO_HPP
|
||||
39
src/api/modal/meta/performance.hpp
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef PerformanceModel_hpp
|
||||
#define PerformanceModel_hpp
|
||||
|
||||
#include "performance/block_processing.hpp"
|
||||
#include "performance/tx_processing.hpp"
|
||||
#include "performance/tx_pool.hpp"
|
||||
#include "db_stat_info.hpp"
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
class PerformanceModel final : public oatpp::DTO
|
||||
{
|
||||
DTO_INIT(PerformanceModel, DTO);
|
||||
|
||||
DTO_FIELD(Object<BlockProcessingPerformanceModel>, block_processing);
|
||||
DTO_FIELD(Object<TxProcessingPerformanceModel>, tx_processing);
|
||||
DTO_FIELD(Object<TxPoolPerformanceModel>, tx_pool);
|
||||
DTO_FIELD(Object<DbStatInfoModel>, db_stat_info);
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
#endif /* PerformanceModel_hpp */
|
||||
47
src/api/modal/meta/performance/block_processing.hpp
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef BlockProcessingPerformanceModel_hpp
|
||||
#define BlockProcessingPerformanceModel_hpp
|
||||
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
class BlockProcessingPerformanceModel final : public oatpp::DTO
|
||||
{
|
||||
DTO_INIT(BlockProcessingPerformanceModel, DTO);
|
||||
|
||||
DTO_FIELD(UInt64, block_processing_time_0);
|
||||
DTO_FIELD(UInt64, block_processing_time_1);
|
||||
DTO_FIELD(UInt64, target_calculating_time_2);
|
||||
DTO_FIELD(UInt64, longhash_calculating_time_3);
|
||||
DTO_FIELD(UInt64, all_txs_insert_time_5);
|
||||
DTO_FIELD(UInt64, etc_stuff_6);
|
||||
DTO_FIELD(UInt64, insert_time_4);
|
||||
DTO_FIELD(UInt64, raise_block_core_event);
|
||||
DTO_FIELD(UInt64, validate_miner_transaction_time);
|
||||
DTO_FIELD(UInt64, collect_rangeproofs_data_from_tx_time);
|
||||
DTO_FIELD(UInt64, verify_multiple_zc_outs_range_proofs_time);
|
||||
DTO_FIELD(UInt64, target_calculating_enum_blocks);
|
||||
DTO_FIELD(UInt64, target_calculating_calc);
|
||||
DTO_FIELD(UInt64, pos_validate_ki_search);
|
||||
DTO_FIELD(UInt64, pos_validate_get_out_keys_for_inputs);
|
||||
DTO_FIELD(UInt64, pos_validate_zvp);
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
#endif /* BlockProcessingPerformanceModel_hpp */
|
||||
42
src/api/modal/meta/performance/tx_pool.hpp
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef TxPoolPerformanceModel_hpp
|
||||
#define TxPoolPerformanceModel_hpp
|
||||
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
class TxPoolPerformanceModel final : public oatpp::DTO
|
||||
{
|
||||
DTO_INIT(TxPoolPerformanceModel, DTO);
|
||||
|
||||
DTO_FIELD(UInt64, tx_processing_time);
|
||||
DTO_FIELD(UInt64, check_inputs_types_supported_time);
|
||||
DTO_FIELD(UInt64, expiration_validate_time);
|
||||
DTO_FIELD(UInt64, validate_amount_time);
|
||||
DTO_FIELD(UInt64, validate_alias_time);
|
||||
DTO_FIELD(UInt64, check_keyimages_ws_ms_time);
|
||||
DTO_FIELD(UInt64, check_inputs_time);
|
||||
DTO_FIELD(UInt64, begin_tx_time);
|
||||
DTO_FIELD(UInt64, update_db_time);
|
||||
DTO_FIELD(UInt64, db_commit_time);
|
||||
DTO_FIELD(UInt64, check_post_hf4_balance);
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
#endif /* TxPoolPerformanceModel_hpp */
|
||||
56
src/api/modal/meta/performance/tx_processing.hpp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef TxProcessingPerformanceModel_hpp
|
||||
#define TxProcessingPerformanceModel_hpp
|
||||
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
class TxProcessingPerformanceModel final : public oatpp::DTO
|
||||
{
|
||||
DTO_INIT(TxProcessingPerformanceModel, DTO);
|
||||
|
||||
DTO_FIELD(UInt64, tx_check_inputs);
|
||||
DTO_FIELD(UInt64, tx_add_one_tx);
|
||||
DTO_FIELD(UInt64, tx_process_extra);
|
||||
DTO_FIELD(UInt64, tx_process_attachment);
|
||||
DTO_FIELD(UInt64, tx_process_inputs);
|
||||
DTO_FIELD(UInt64, tx_push_global_index);
|
||||
DTO_FIELD(UInt64, tx_check_exist);
|
||||
DTO_FIELD(UInt64, tx_print_log);
|
||||
DTO_FIELD(UInt64, tx_prapare_append);
|
||||
DTO_FIELD(UInt64, tx_append);
|
||||
DTO_FIELD(UInt64, tx_append_rl_wait);
|
||||
DTO_FIELD(UInt64, tx_append_is_expired);
|
||||
DTO_FIELD(UInt64, tx_store_db);
|
||||
DTO_FIELD(UInt64, tx_check_inputs_prefix_hash);
|
||||
DTO_FIELD(UInt64, tx_check_inputs_attachment_check);
|
||||
DTO_FIELD(UInt64, tx_check_inputs_loop);
|
||||
DTO_FIELD(UInt64, tx_check_inputs_loop_kimage_check);
|
||||
DTO_FIELD(UInt64, tx_check_inputs_loop_ch_in_val_sig);
|
||||
DTO_FIELD(UInt64, tx_check_inputs_loop_scan_outputkeys_get_item_size);
|
||||
DTO_FIELD(UInt64, tx_check_inputs_loop_scan_outputkeys_relative_to_absolute);
|
||||
DTO_FIELD(UInt64, tx_check_inputs_loop_scan_outputkeys_loop);
|
||||
DTO_FIELD(UInt64, tx_check_inputs_loop_scan_outputkeys_loop_get_subitem);
|
||||
DTO_FIELD(UInt64, tx_check_inputs_loop_scan_outputkeys_loop_find_tx);
|
||||
DTO_FIELD(UInt64, tx_check_inputs_loop_scan_outputkeys_loop_handle_output);
|
||||
DTO_FIELD(UInt64, tx_mixin_count);
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
#endif /* TxProcessingPerformanceModel_hpp */
|
||||
39
src/api/modal/meta/pos_entry.hpp
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef PosEntryModel_hpp
|
||||
#define PosEntryModel_hpp
|
||||
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
class PosEntryModel final : public oatpp::DTO
|
||||
{
|
||||
DTO_INIT(PosEntryModel, DTO);
|
||||
|
||||
DTO_FIELD(UInt64, amount);
|
||||
DTO_FIELD(UInt64, g_index);
|
||||
DTO_FIELD(String, keyimage);
|
||||
DTO_FIELD(UInt64, block_timestamp);
|
||||
DTO_FIELD(UInt64, stake_unlock_time);
|
||||
DTO_FIELD(String, tx_id);
|
||||
DTO_FIELD(UInt64, tx_out_index);
|
||||
DTO_FIELD(UInt64, wallet_index);
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
#endif /* PosEntryModel_hpp */
|
||||
55
src/api/modal/meta/tx_generation_context.hpp
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef TxGenerationContextModel_hpp
|
||||
#define TxGenerationContextModel_hpp
|
||||
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
class TxGenerationContextModel final : public oatpp::DTO
|
||||
{
|
||||
DTO_INIT(TxGenerationContextModel, DTO);
|
||||
|
||||
DTO_FIELD(List<String>, asset_ids);
|
||||
DTO_FIELD(List<String>, blinded_asset_ids);
|
||||
DTO_FIELD(List<String>, amount_commitments);
|
||||
DTO_FIELD(List<String>, asset_id_blinding_masks);
|
||||
DTO_FIELD(List<String>, amounts);
|
||||
DTO_FIELD(List<String>, amount_blinding_masks);
|
||||
DTO_FIELD(List<String>, pseudo_outs_blinded_asset_ids);
|
||||
DTO_FIELD(List<String>, pseudo_outs_plus_real_out_blinding_masks);
|
||||
DTO_FIELD(List<String>, real_zc_ins_asset_ids);
|
||||
DTO_FIELD(List<UInt64>, zc_input_amounts);
|
||||
DTO_FIELD(String, pseudo_out_amount_commitments_sum);
|
||||
DTO_FIELD(String, pseudo_out_amount_blinding_masks_sum);
|
||||
DTO_FIELD(String, real_in_asset_id_blinding_mask_x_amount_sum);
|
||||
DTO_FIELD(String, amount_commitments_sum);
|
||||
DTO_FIELD(String, amount_blinding_masks_sum);
|
||||
DTO_FIELD(String, asset_id_blinding_mask_x_amount_sum);
|
||||
DTO_FIELD(String, ao_asset_id);
|
||||
DTO_FIELD(String, ao_asset_id_pt);
|
||||
DTO_FIELD(String, ao_amount_commitment);
|
||||
DTO_FIELD(String, ao_amount_blinding_mask);
|
||||
DTO_FIELD(Boolean, ao_commitment_in_outputs);
|
||||
DTO_FIELD(String, tx_key_pub);
|
||||
DTO_FIELD(String, tx_key_sec);
|
||||
DTO_FIELD(String, tx_pub_key_p);
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
#endif /* TxGenerationContextModel_hpp */
|
||||
36
src/api/modal/meta/version.hpp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef VersionModel_hpp
|
||||
#define VersionModel_hpp
|
||||
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
class VersionModel final : public oatpp::DTO
|
||||
{
|
||||
DTO_INIT(VersionModel, DTO);
|
||||
|
||||
DTO_FIELD(String, version);
|
||||
DTO_FIELD(String, version_long);
|
||||
DTO_FIELD(String, major);
|
||||
DTO_FIELD(String, minor);
|
||||
DTO_FIELD(String, revision);
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
#endif /* VersionModel_hpp */
|
||||
89
src/api/modal/transaction/details.hpp
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef TransactionDetailsModel_hpp
|
||||
#define TransactionDetailsModel_hpp
|
||||
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
/**
|
||||
* Model for transaction attachments.
|
||||
*/
|
||||
class TransactionAttachmentModel : public oatpp::DTO {
|
||||
DTO_INIT(TransactionAttachmentModel, DTO);
|
||||
DTO_FIELD(String, type, "type");
|
||||
DTO_FIELD(String, short_view, "short_view");
|
||||
DTO_FIELD(String, details_view, "details_view");
|
||||
};
|
||||
|
||||
/**
|
||||
* Model for transaction extra data.
|
||||
*/
|
||||
class TransactionExtraModel : public oatpp::DTO {
|
||||
DTO_INIT(TransactionExtraModel, DTO);
|
||||
DTO_FIELD(String, type, "type");
|
||||
DTO_FIELD(String, short_view, "short_view");
|
||||
DTO_FIELD(String, details_view, "details_view");
|
||||
};
|
||||
|
||||
/**
|
||||
* Model for transaction inputs.
|
||||
*/
|
||||
class TransactionInputModel : public oatpp::DTO {
|
||||
DTO_INIT(TransactionInputModel, DTO);
|
||||
DTO_FIELD(UInt64, amount, "amount");
|
||||
DTO_FIELD(Vector<UInt64>, global_indexes, "global_indexes");
|
||||
DTO_FIELD(String, htlc_origin, "htlc_origin");
|
||||
DTO_FIELD(String, kimage_or_ms_id, "kimage_or_ms_id");
|
||||
DTO_FIELD(UInt32, multisig_count, "multisig_count");
|
||||
};
|
||||
|
||||
/**
|
||||
* Model for transaction outputs.
|
||||
*/
|
||||
class TransactionOutputModel : public oatpp::DTO {
|
||||
DTO_INIT(TransactionOutputModel, DTO);
|
||||
DTO_FIELD(UInt64, amount, "amount");
|
||||
DTO_FIELD(UInt64, global_index, "global_index");
|
||||
DTO_FIELD(Boolean, is_spent, "is_spent");
|
||||
DTO_FIELD(UInt32, minimum_sigs, "minimum_sigs");
|
||||
DTO_FIELD(Vector<String>, pub_keys, "pub_keys");
|
||||
};
|
||||
|
||||
/**
|
||||
* Model for detailed transaction information.
|
||||
*/
|
||||
class TransactionDetailsModel : public oatpp::DTO {
|
||||
DTO_INIT(TransactionDetailsModel, DTO);
|
||||
DTO_FIELD(UInt64, amount, "amount");
|
||||
DTO_FIELD(List<Object<TransactionAttachmentModel>>, attachments, "attachments");
|
||||
DTO_FIELD(String, blob, "blob");
|
||||
DTO_FIELD(UInt64, blob_size, "blob_size");
|
||||
DTO_FIELD(List<Object<TransactionExtraModel>>, extra, "extra");
|
||||
DTO_FIELD(UInt64, fee, "fee");
|
||||
DTO_FIELD(String, id, "id");
|
||||
DTO_FIELD(List<Object<TransactionInputModel>>, ins, "ins");
|
||||
DTO_FIELD(Int64, keeper_block, "keeper_block");
|
||||
DTO_FIELD(String, object_in_json, "object_in_json");
|
||||
DTO_FIELD(List<Object<TransactionOutputModel>>, outs, "outs");
|
||||
DTO_FIELD(String, pub_key, "pub_key");
|
||||
DTO_FIELD(UInt64, timestamp, "timestamp");
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
#endif /* TransactionDetailsModel_hpp */
|
||||
32
src/api/modal/transaction/send_request.hpp
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef SendTransactionRequestModel_hpp
|
||||
#define SendTransactionRequestModel_hpp
|
||||
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
class SendTransactionRequestModel final : public oatpp::DTO
|
||||
{
|
||||
DTO_INIT(SendTransactionRequestModel, DTO);
|
||||
|
||||
DTO_FIELD(String, tx_as_hex);
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
#endif /* SendTransactionRequestModel_hpp */
|
||||
32
src/api/modal/transaction/send_response.hpp
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; but maintains OSS status,
|
||||
// where regional copyright law requires ownership to dictate licence terms.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef SendTransactionResponseModel_hpp
|
||||
#define SendTransactionResponseModel_hpp
|
||||
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
class SendTransactionResponseModel final : public oatpp::DTO
|
||||
{
|
||||
DTO_INIT(SendTransactionResponseModel, DTO);
|
||||
|
||||
DTO_FIELD(String, status);
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
#endif /* SendTransactionResponseModel_hpp */
|
||||
|
|
@ -18,9 +18,12 @@
|
|||
// node.cpp : Defines the entry point for the console application.
|
||||
//
|
||||
|
||||
#include "ApiServer.hpp"
|
||||
#include "include_base_utils.h"
|
||||
#include "version.h"
|
||||
|
||||
#include "oatpp/core/base/Environment.hpp"
|
||||
|
||||
using namespace epee;
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
|
|
@ -57,6 +60,7 @@ BOOST_CLASS_VERSION(nodetool::node_server<currency::t_currency_protocol_handler<
|
|||
const command_line::arg_descriptor<uint32_t> arg_rpc_server_threads("rpc-server-threads", "Specify number of RPC server threads. Default: 10", RPC_SERVER_DEFAULT_THREADS_NUM);
|
||||
const command_line::arg_descriptor<bool> arg_do_warp_mode("do-warp-mode", "This option pre-loads and unserialize all data into RAM and provide significant speed increase in RPC-handling, requires 32GB psychical RAM at least(64GB recommended). Might be helpful for production servers(like remote nodes or public nodes for mobile apps).");
|
||||
|
||||
|
||||
namespace po = boost::program_options;
|
||||
|
||||
bool command_line_preprocessor(const boost::program_options::variables_map& vm);
|
||||
|
|
@ -183,7 +187,7 @@ int main(int argc, char* argv[])
|
|||
command_line::add_arg(desc_cmd_sett, command_line::arg_disable_ntp);
|
||||
|
||||
command_line::add_arg(desc_cmd_sett, arg_rpc_server_threads);
|
||||
command_line::add_arg(desc_cmd_sett, arg_do_warp_mode);
|
||||
command_line::add_arg(desc_cmd_sett, arg_do_warp_mode);
|
||||
|
||||
arg_market_disable.default_value = true;
|
||||
arg_market_disable.use_default = true;
|
||||
|
|
@ -198,6 +202,7 @@ int main(int argc, char* argv[])
|
|||
bc_services::bc_offers_service::init_options(desc_cmd_sett);
|
||||
currency::stratum_server::init_options(desc_cmd_sett);
|
||||
tools::db::db_backend_selector::init_options(desc_cmd_sett);
|
||||
ApiServer::init_options(desc_cmd_sett);
|
||||
|
||||
po::options_description desc_options("Allowed options");
|
||||
desc_options.add(desc_cmd_only).add(desc_cmd_sett);
|
||||
|
|
@ -464,18 +469,32 @@ int main(int argc, char* argv[])
|
|||
LOG_PRINT_L0("Stratum server started ok");
|
||||
}
|
||||
|
||||
tools::signal_handler::install([&dch, &p2psrv, &stratum_server_ptr] {
|
||||
dch.stop_handling();
|
||||
std::unique_ptr<ApiServer> api_server;
|
||||
oatpp::base::Environment::init();
|
||||
api_server = std::make_unique<ApiServer>(vm, &ccore, &p2psrv, &rpc_server);
|
||||
api_server->start();
|
||||
|
||||
// Setup signal handler to gracefully stop the main p2p loop
|
||||
tools::signal_handler::install([&p2psrv] {
|
||||
LOG_PRINT_L0("SIGINT received, stopping p2p net loop...");
|
||||
p2psrv.send_stop_signal();
|
||||
if (stratum_server_ptr)
|
||||
stratum_server_ptr->send_stop_signal();
|
||||
});
|
||||
|
||||
LOG_PRINT_L0("Starting p2p net loop...");
|
||||
p2psrv.run();
|
||||
LOG_PRINT_L0("p2p net loop stopped");
|
||||
p2psrv.run(); // This blocks until the stop signal is received
|
||||
LOG_PRINT_L0("p2p net loop stopped. Starting shutdown...");
|
||||
|
||||
//stop components
|
||||
// Shutdown sequence
|
||||
LOG_PRINT_L0("Stopping command handler...");
|
||||
dch.stop_handling();
|
||||
|
||||
LOG_PRINT_L0("Stopping API server...");
|
||||
api_server->stop();
|
||||
api_server->wait();
|
||||
LOG_PRINT_L0("API server stopped");
|
||||
|
||||
|
||||
//stop other components
|
||||
if (stratum_enabled)
|
||||
{
|
||||
LOG_PRINT_L0("Stopping stratum server...");
|
||||
|
|
@ -506,6 +525,11 @@ int main(int argc, char* argv[])
|
|||
LOG_PRINT_L0("Deinitializing p2p...");
|
||||
p2psrv.deinit();
|
||||
|
||||
// LOG_PRINT_L0("Destroying oatpp environment...");
|
||||
oatpp::base::Environment::destroy();
|
||||
// LOG_PRINT_L0("oatpp environment destroyed.");
|
||||
//
|
||||
|
||||
ccore.set_critical_error_handler(nullptr);
|
||||
ccore.set_currency_protocol(NULL);
|
||||
cprotocol.set_p2p_endpoint(NULL);
|
||||
|
|
|
|||
1
utils/.gitignore
vendored
|
|
@ -1 +0,0 @@
|
|||
configure_local_paths.cmd
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="Globals">
|
||||
<UseMultiToolTask>true</UseMultiToolTask>
|
||||
<EnforceProcessCountAcrossBuilds>true</EnforceProcessCountAcrossBuilds>
|
||||
<MultiProcMaxCount>11</MultiProcMaxCount>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Name=Zano
|
||||
GenericName=Zano
|
||||
Comment=Privacy blockchain
|
||||
Icon=Zano
|
||||
Terminal=true
|
||||
Type=Application
|
||||
Categories=Qt;Utility;
|
||||
Name[en_US]=Zano
|
||||
MimeType=x-scheme-handler/zano;
|
||||
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
#!/bin/bash
|
||||
script_dir=$( dirname "$(readlink -f "$0")" )
|
||||
|
||||
export LD_LIBRARY_PATH=$script_dir/lib
|
||||
export QT_PLUGIN_PATH=$script_dir/lib
|
||||
|
||||
echo $LD_LIBRARY_PATH
|
||||
echo $QT_PLUGIN_PATH
|
||||
|
||||
out_file_name=~/.local/share/applications/Zano.desktop
|
||||
|
||||
call_app()
|
||||
{
|
||||
pushd $script_dir
|
||||
./Zano "$@"
|
||||
popd
|
||||
exit
|
||||
}
|
||||
|
||||
|
||||
create_desktop_icon()
|
||||
{
|
||||
target_file_name=$1
|
||||
echo "Generating icon file: $target_file_name..."
|
||||
rm -f $target_file_name
|
||||
echo [Desktop Entry] | tee -a $target_file_name > /dev/null
|
||||
echo Version=1.0 | tee -a $target_file_name > /dev/null
|
||||
echo Name=Zano | tee -a $target_file_name > /dev/null
|
||||
echo GenericName=Zano | tee -a $target_file_name > /dev/null
|
||||
echo Comment=Privacy blockchain | tee -a $target_file_name > /dev/null
|
||||
echo Icon=$script_dir/html/files/desktop_linux_icon.png | tee -a $target_file_name > /dev/null
|
||||
echo Exec=$script_dir/Zano.sh --deeplink-params=\\\\\"%u\\\\\" | tee -a $target_file_name > /dev/null
|
||||
echo Terminal=true | tee -a $target_file_name > /dev/null
|
||||
echo Type=Application | tee -a $target_file_name > /dev/null
|
||||
echo "Categories=Qt;Utility;" | tee -a $target_file_name > /dev/null
|
||||
echo "MimeType=x-scheme-handler/zano;" | tee -a $target_file_name > /dev/null
|
||||
}
|
||||
|
||||
|
||||
create_desktop_icon $out_file_name
|
||||
|
||||
xdg-mime default Zano.desktop x-scheme-handler/zano
|
||||
|
||||
call_app "$@"
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
#!/bin/bash
|
||||
script_dir=$( dirname "$(readlink -f "$0")" )
|
||||
|
||||
out_dir=~/.local/share/applications
|
||||
version="$(echo ${APPIMAGE} | rev | cut -d '-' -f1,2 | rev | sed 's/\.AppImage$//')"
|
||||
out_file_name="${out_dir}/Zano-${version}.desktop"
|
||||
|
||||
export QTWEBENGINE_DISABLE_SANDBOX=1
|
||||
|
||||
call_app()
|
||||
{
|
||||
pushd $script_dir
|
||||
usr/bin/Zano "$@"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo $'\n\n\x1b[1mIf Zano fails to launch, it might need to install xinerama extension for the X C Binding with this command:\n\x1b[2m sudo apt-get install libxcb-xinerama0\n\n'
|
||||
fi
|
||||
|
||||
popd
|
||||
exit
|
||||
}
|
||||
|
||||
|
||||
create_desktop_icon()
|
||||
{
|
||||
target_file_name=$1
|
||||
echo "Generating icon file: $target_file_name..."
|
||||
rm -f "${out_dir}/Zano.png"
|
||||
rm -f $target_file_name
|
||||
cp -Rv "${APPDIR}/usr/share/icons/hicolor/256x256/apps/Zano.png" "${out_dir}/Zano.png"
|
||||
echo [Desktop Entry] | tee -a $target_file_name > /dev/null
|
||||
echo Version=1.0 | tee -a $target_file_name > /dev/null
|
||||
echo Name=Zano | tee -a $target_file_name > /dev/null
|
||||
echo GenericName=Zano | tee -a $target_file_name > /dev/null
|
||||
echo Comment=Privacy blockchain | tee -a $target_file_name > /dev/null
|
||||
echo Icon=${out_dir}/Zano.png | tee -a $target_file_name > /dev/null
|
||||
echo TryExec="${APPIMAGE}" | tee -a "${target_file_name}" >/dev/null
|
||||
echo Exec=$APPIMAGE --deeplink-params=\\\\\\\"%u\\\\\\\" | tee -a $target_file_name > /dev/null
|
||||
echo Terminal=false | tee -a $target_file_name > /dev/null
|
||||
echo Type=Application | tee -a $target_file_name > /dev/null
|
||||
echo "Categories=Qt;Utility;" | tee -a $target_file_name > /dev/null
|
||||
echo "MimeType=x-scheme-handler/zano;" | tee -a $target_file_name > /dev/null
|
||||
echo "StartupWMClass=Zano" | tee -a $target_file_name > /dev/null
|
||||
}
|
||||
|
||||
|
||||
create_desktop_icon $out_file_name
|
||||
|
||||
xdg-mime default Zano.desktop x-scheme-handler/zano
|
||||
xdg-desktop-menu install --novendor "${out_file_name}"
|
||||
|
||||
call_app "$@"
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"id": 1234,
|
||||
"jsonrpc": "2.0",
|
||||
"result": {
|
||||
"status": "OK"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2008-2014 Andrey Tarantsov
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
@ -1,230 +0,0 @@
|
|||
#! /bin/bash
|
||||
|
||||
# Create a read-only disk image of the contents of a folder
|
||||
|
||||
set -e;
|
||||
|
||||
function pure_version() {
|
||||
echo '1.0.0.2'
|
||||
}
|
||||
|
||||
function version() {
|
||||
echo "create-dmg $(pure_version)"
|
||||
}
|
||||
|
||||
function usage() {
|
||||
version
|
||||
echo "Creates a fancy DMG file."
|
||||
echo "Usage: $(basename $0) options... image.dmg source_folder"
|
||||
echo "All contents of source_folder will be copied into the disk image."
|
||||
echo "Options:"
|
||||
echo " --volname name"
|
||||
echo " set volume name (displayed in the Finder sidebar and window title)"
|
||||
echo " --volicon icon.icns"
|
||||
echo " set volume icon"
|
||||
echo " --background pic.png"
|
||||
echo " set folder background image (provide png, gif, jpg)"
|
||||
echo " --window-pos x y"
|
||||
echo " set position the folder window"
|
||||
echo " --window-size width height"
|
||||
echo " set size of the folder window"
|
||||
echo " --text-size text_size"
|
||||
echo " set window text size (10-16)"
|
||||
echo " --icon-size icon_size"
|
||||
echo " set window icons size (up to 128)"
|
||||
echo " --icon file_name x y"
|
||||
echo " set position of the file's icon"
|
||||
echo " --hide-extension file_name"
|
||||
echo " hide the extension of file"
|
||||
echo " --custom-icon file_name custom_icon_or_sample_file x y"
|
||||
echo " set position and custom icon"
|
||||
echo " --app-drop-link x y"
|
||||
echo " make a drop link to Applications, at location x,y"
|
||||
echo " --eula eula_file"
|
||||
echo " attach a license file to the dmg"
|
||||
echo " --no-internet-enable"
|
||||
echo " disable automatic mount©"
|
||||
echo " --version show tool version number"
|
||||
echo " -h, --help display this help"
|
||||
exit 0
|
||||
}
|
||||
|
||||
WINX=10
|
||||
WINY=60
|
||||
WINW=500
|
||||
WINH=350
|
||||
ICON_SIZE=128
|
||||
TEXT_SIZE=16
|
||||
|
||||
while test "${1:0:1}" = "-"; do
|
||||
case $1 in
|
||||
--volname)
|
||||
VOLUME_NAME="$2"
|
||||
shift; shift;;
|
||||
--volicon)
|
||||
VOLUME_ICON_FILE="$2"
|
||||
shift; shift;;
|
||||
--background)
|
||||
BACKGROUND_FILE="$2"
|
||||
BACKGROUND_FILE_NAME="$(basename $BACKGROUND_FILE)"
|
||||
BACKGROUND_CLAUSE="set background picture of opts to file \".background:$BACKGROUND_FILE_NAME\""
|
||||
REPOSITION_HIDDEN_FILES_CLAUSE="set position of every item to {theBottomRightX + 500, 100}"
|
||||
shift; shift;;
|
||||
--icon-size)
|
||||
ICON_SIZE="$2"
|
||||
shift; shift;;
|
||||
--text-size)
|
||||
TEXT_SIZE="$2"
|
||||
shift; shift;;
|
||||
--window-pos)
|
||||
WINX=$2; WINY=$3
|
||||
shift; shift; shift;;
|
||||
--window-size)
|
||||
WINW=$2; WINH=$3
|
||||
shift; shift; shift;;
|
||||
--icon)
|
||||
POSITION_CLAUSE="${POSITION_CLAUSE}set position of item \"$2\" to {$3, $4}
|
||||
"
|
||||
shift; shift; shift; shift;;
|
||||
--hide-extension)
|
||||
HIDING_CLAUSE="${HIDING_CLAUSE}set the extension hidden of item \"$2\" to true
|
||||
"
|
||||
shift; shift;;
|
||||
--custom-icon)
|
||||
shift; shift; shift; shift; shift;;
|
||||
-h | --help)
|
||||
usage;;
|
||||
--version)
|
||||
version; exit 0;;
|
||||
--pure-version)
|
||||
pure_version; exit 0;;
|
||||
--app-drop-link)
|
||||
APPLICATION_LINK=$2
|
||||
APPLICATION_CLAUSE="set position of item \"Applications\" to {$2, $3}
|
||||
"
|
||||
shift; shift; shift;;
|
||||
--eula)
|
||||
EULA_RSRC=$2
|
||||
shift; shift;;
|
||||
--no-internet-enable)
|
||||
NOINTERNET=1
|
||||
shift;;
|
||||
-*)
|
||||
echo "Unknown option $1. Run with --help for help."
|
||||
exit 1;;
|
||||
esac
|
||||
done
|
||||
|
||||
test -z "$2" && {
|
||||
echo "Not enough arguments. Invoke with --help for help."
|
||||
exit 1
|
||||
}
|
||||
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
DMG_PATH="$1"
|
||||
DMG_DIRNAME="$(dirname "$DMG_PATH")"
|
||||
DMG_DIR="$(cd "$DMG_DIRNAME" > /dev/null; pwd)"
|
||||
DMG_NAME="$(basename "$DMG_PATH")"
|
||||
DMG_TEMP_NAME="$DMG_DIR/rw.${DMG_NAME}"
|
||||
SRC_FOLDER="$(cd "$2" > /dev/null; pwd)"
|
||||
test -z "$VOLUME_NAME" && VOLUME_NAME="$(basename "$DMG_PATH" .dmg)"
|
||||
|
||||
AUX_PATH="$SCRIPT_DIR/support"
|
||||
|
||||
test -d "$AUX_PATH" || {
|
||||
echo "Cannot find support directory: $AUX_PATH"
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ -f "$SRC_FOLDER/.DS_Store" ]; then
|
||||
echo "Deleting any .DS_Store in source folder"
|
||||
rm "$SRC_FOLDER/.DS_Store"
|
||||
fi
|
||||
|
||||
# Create the image
|
||||
echo "Creating disk image..."
|
||||
test -f "${DMG_TEMP_NAME}" && rm -f "${DMG_TEMP_NAME}"
|
||||
ACTUAL_SIZE=`du -sm "$SRC_FOLDER" | sed -e 's/ .*//g'`
|
||||
DISK_IMAGE_SIZE=$(expr $ACTUAL_SIZE + 20)
|
||||
hdiutil create -srcfolder "$SRC_FOLDER" -volname "${VOLUME_NAME}" -fs HFS+ -fsargs "-c c=64,a=16,e=16" -format UDRW -size ${DISK_IMAGE_SIZE}m "${DMG_TEMP_NAME}"
|
||||
|
||||
# mount it
|
||||
echo "Mounting disk image..."
|
||||
MOUNT_DIR="/Volumes/${VOLUME_NAME}"
|
||||
|
||||
# try unmount dmg if it was mounted previously (e.g. developer mounted dmg, installed app and forgot to unmount it)
|
||||
echo "Unmounting disk image..."
|
||||
DEV_NAME=$(hdiutil info | egrep '^/dev/' | sed 1q | awk '{print $1}')
|
||||
test -d "${MOUNT_DIR}" && hdiutil detach "${DEV_NAME}"
|
||||
|
||||
echo "Mount directory: $MOUNT_DIR"
|
||||
DEV_NAME=$(hdiutil attach -readwrite -noverify -noautoopen "${DMG_TEMP_NAME}" | egrep '^/dev/' | sed 1q | awk '{print $1}')
|
||||
echo "Device name: $DEV_NAME"
|
||||
|
||||
if ! test -z "$BACKGROUND_FILE"; then
|
||||
echo "Copying background file..."
|
||||
test -d "$MOUNT_DIR/.background" || mkdir "$MOUNT_DIR/.background"
|
||||
cp "$BACKGROUND_FILE" "$MOUNT_DIR/.background/$BACKGROUND_FILE_NAME"
|
||||
fi
|
||||
|
||||
if ! test -z "$APPLICATION_LINK"; then
|
||||
echo "making link to Applications dir"
|
||||
echo $MOUNT_DIR
|
||||
ln -s /Applications "$MOUNT_DIR/Applications"
|
||||
fi
|
||||
|
||||
if ! test -z "$VOLUME_ICON_FILE"; then
|
||||
echo "Copying volume icon file '$VOLUME_ICON_FILE'..."
|
||||
cp "$VOLUME_ICON_FILE" "$MOUNT_DIR/.VolumeIcon.icns"
|
||||
SetFile -c icnC "$MOUNT_DIR/.VolumeIcon.icns"
|
||||
fi
|
||||
|
||||
# run applescript
|
||||
APPLESCRIPT=$(mktemp -t createdmg)
|
||||
cat "$AUX_PATH/template.applescript" | sed -e "s/WINX/$WINX/g" -e "s/WINY/$WINY/g" -e "s/WINW/$WINW/g" -e "s/WINH/$WINH/g" -e "s/BACKGROUND_CLAUSE/$BACKGROUND_CLAUSE/g" -e "s/REPOSITION_HIDDEN_FILES_CLAUSE/$REPOSITION_HIDDEN_FILES_CLAUSE/g" -e "s/ICON_SIZE/$ICON_SIZE/g" -e "s/TEXT_SIZE/$TEXT_SIZE/g" | perl -pe "s/POSITION_CLAUSE/$POSITION_CLAUSE/g" | perl -pe "s/APPLICATION_CLAUSE/$APPLICATION_CLAUSE/g" | perl -pe "s/HIDING_CLAUSE/$HIDING_CLAUSE/" >"$APPLESCRIPT"
|
||||
|
||||
echo "Running Applescript: /usr/bin/osascript \"${APPLESCRIPT}\" \"${VOLUME_NAME}\""
|
||||
"/usr/bin/osascript" "${APPLESCRIPT}" "${VOLUME_NAME}" || true
|
||||
echo "Done running the applescript..."
|
||||
sleep 4
|
||||
|
||||
rm "$APPLESCRIPT"
|
||||
|
||||
# make sure it's not world writeable
|
||||
echo "Fixing permissions..."
|
||||
chmod -Rf go-w "${MOUNT_DIR}" &> /dev/null || true
|
||||
echo "Done fixing permissions."
|
||||
|
||||
# make the top window open itself on mount:
|
||||
echo "Blessing started"
|
||||
bless --folder "${MOUNT_DIR}" --openfolder "${MOUNT_DIR}"
|
||||
echo "Blessing finished"
|
||||
|
||||
if ! test -z "$VOLUME_ICON_FILE"; then
|
||||
# tell the volume that it has a special file attribute
|
||||
SetFile -a C "$MOUNT_DIR"
|
||||
fi
|
||||
|
||||
# unmount
|
||||
echo "Unmounting disk image..."
|
||||
hdiutil detach "${DEV_NAME}"
|
||||
|
||||
# compress image
|
||||
echo "Compressing disk image..."
|
||||
hdiutil convert "${DMG_TEMP_NAME}" -format UDZO -imagekey zlib-level=9 -o "${DMG_DIR}/${DMG_NAME}"
|
||||
rm -f "${DMG_TEMP_NAME}"
|
||||
|
||||
# adding EULA resources
|
||||
if [ ! -z "${EULA_RSRC}" -a "${EULA_RSRC}" != "-null-" ]; then
|
||||
echo "adding EULA resources"
|
||||
"${AUX_PATH}/dmg-license.py" "${DMG_DIR}/${DMG_NAME}" "${EULA_RSRC}"
|
||||
fi
|
||||
|
||||
if [ ! -z "${NOINTERNET}" -a "${NOINTERNET}" == 1 ]; then
|
||||
echo "not setting 'internet-enable' on the dmg"
|
||||
else
|
||||
hdiutil internet-enable -yes "${DMG_DIR}/${DMG_NAME}"
|
||||
fi
|
||||
|
||||
echo "Disk image done"
|
||||
exit 0
|
||||
|
|
@ -1 +0,0 @@
|
|||
https://github.com/andreyvit/yoursway-create-dmg.git
|
||||
|
|
@ -1,163 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
"""
|
||||
This script adds a license file to a DMG. Requires Xcode and a plain ascii text
|
||||
license file.
|
||||
Obviously only runs on a Mac.
|
||||
|
||||
Copyright (C) 2011-2013 Jared Hobbs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import optparse
|
||||
|
||||
|
||||
class Path(str):
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
os.unlink(self)
|
||||
|
||||
|
||||
def mktemp(dir=None, suffix=''):
|
||||
(fd, filename) = tempfile.mkstemp(dir=dir, suffix=suffix)
|
||||
os.close(fd)
|
||||
return Path(filename)
|
||||
|
||||
|
||||
def main(options, args):
|
||||
dmgFile, license = args
|
||||
with mktemp('.') as tmpFile:
|
||||
with open(tmpFile, 'w') as f:
|
||||
f.write("""data 'TMPL' (128, "LPic") {
|
||||
$"1344 6566 6175 6C74 204C 616E 6775 6167"
|
||||
$"6520 4944 4457 5244 0543 6F75 6E74 4F43"
|
||||
$"4E54 042A 2A2A 2A4C 5354 430B 7379 7320"
|
||||
$"6C61 6E67 2049 4444 5752 441E 6C6F 6361"
|
||||
$"6C20 7265 7320 4944 2028 6F66 6673 6574"
|
||||
$"2066 726F 6D20 3530 3030 4457 5244 1032"
|
||||
$"2D62 7974 6520 6C61 6E67 7561 6765 3F44"
|
||||
$"5752 4404 2A2A 2A2A 4C53 5445"
|
||||
};
|
||||
|
||||
data 'LPic' (5000) {
|
||||
$"0000 0002 0000 0000 0000 0000 0004 0000"
|
||||
};
|
||||
|
||||
data 'STR#' (5000, "English buttons") {
|
||||
$"0006 0D45 6E67 6C69 7368 2074 6573 7431"
|
||||
$"0541 6772 6565 0844 6973 6167 7265 6505"
|
||||
$"5072 696E 7407 5361 7665 2E2E 2E7A 4966"
|
||||
$"2079 6F75 2061 6772 6565 2077 6974 6820"
|
||||
$"7468 6520 7465 726D 7320 6F66 2074 6869"
|
||||
$"7320 6C69 6365 6E73 652C 2063 6C69 636B"
|
||||
$"2022 4167 7265 6522 2074 6F20 6163 6365"
|
||||
$"7373 2074 6865 2073 6F66 7477 6172 652E"
|
||||
$"2020 4966 2079 6F75 2064 6F20 6E6F 7420"
|
||||
$"6167 7265 652C 2070 7265 7373 2022 4469"
|
||||
$"7361 6772 6565 2E22"
|
||||
};
|
||||
|
||||
data 'STR#' (5002, "English") {
|
||||
$"0006 0745 6E67 6C69 7368 0541 6772 6565"
|
||||
$"0844 6973 6167 7265 6505 5072 696E 7407"
|
||||
$"5361 7665 2E2E 2E7B 4966 2079 6F75 2061"
|
||||
$"6772 6565 2077 6974 6820 7468 6520 7465"
|
||||
$"726D 7320 6F66 2074 6869 7320 6C69 6365"
|
||||
$"6E73 652C 2070 7265 7373 2022 4167 7265"
|
||||
$"6522 2074 6F20 696E 7374 616C 6C20 7468"
|
||||
$"6520 736F 6674 7761 7265 2E20 2049 6620"
|
||||
$"796F 7520 646F 206E 6F74 2061 6772 6565"
|
||||
$"2C20 7072 6573 7320 2244 6973 6167 7265"
|
||||
$"6522 2E"
|
||||
};\n\n""")
|
||||
with open(license, 'r') as l:
|
||||
kind = 'RTF ' if license.lower().endswith('.rtf') else 'TEXT'
|
||||
f.write('data \'%s\' (5000, "English") {\n' % kind)
|
||||
def escape(s):
|
||||
return s.strip().replace('\\', '\\\\').replace('"', '\\"')
|
||||
|
||||
for line in l:
|
||||
if len(line) < 1000:
|
||||
f.write(' "' + escape(line) + '\\n"\n')
|
||||
else:
|
||||
for liner in line.split('.'):
|
||||
f.write(' "' + escape(liner) + '. \\n"\n')
|
||||
f.write('};\n\n')
|
||||
f.write("""data 'styl' (5000, "English") {
|
||||
$"0003 0000 0000 000C 0009 0014 0000 0000"
|
||||
$"0000 0000 0000 0000 0027 000C 0009 0014"
|
||||
$"0100 0000 0000 0000 0000 0000 002A 000C"
|
||||
$"0009 0014 0000 0000 0000 0000 0000"
|
||||
};\n""")
|
||||
os.system('hdiutil unflatten -quiet "%s"' % dmgFile)
|
||||
ret = os.system('%s -a %s -o "%s"' %
|
||||
(options.rez, tmpFile, dmgFile))
|
||||
os.system('hdiutil flatten -quiet "%s"' % dmgFile)
|
||||
if options.compression is not None:
|
||||
os.system('cp %s %s.temp.dmg' % (dmgFile, dmgFile))
|
||||
os.remove(dmgFile)
|
||||
if options.compression == "bz2":
|
||||
os.system('hdiutil convert %s.temp.dmg -format UDBZ -o %s' %
|
||||
(dmgFile, dmgFile))
|
||||
elif options.compression == "gz":
|
||||
os.system('hdiutil convert %s.temp.dmg -format ' % dmgFile +
|
||||
'UDZO -imagekey zlib-devel=9 -o %s' % dmgFile)
|
||||
os.remove('%s.temp.dmg' % dmgFile)
|
||||
if ret == 0:
|
||||
print "Successfully added license to '%s'" % dmgFile
|
||||
else:
|
||||
print "Failed to add license to '%s'" % dmgFile
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = optparse.OptionParser()
|
||||
parser.set_usage("""%prog <dmgFile> <licenseFile> [OPTIONS]
|
||||
This program adds a software license agreement to a DMG file.
|
||||
It requires Xcode and either a plain ascii text <licenseFile>
|
||||
or a <licenseFile.rtf> with the RTF contents.
|
||||
|
||||
See --help for more details.""")
|
||||
parser.add_option(
|
||||
'--rez',
|
||||
'-r',
|
||||
action='store',
|
||||
default='/Applications/Xcode.app/Contents/Developer/Tools/Rez',
|
||||
help='The path to the Rez tool. Defaults to %default'
|
||||
)
|
||||
parser.add_option(
|
||||
'--compression',
|
||||
'-c',
|
||||
action='store',
|
||||
choices=['bz2', 'gz'],
|
||||
default=None,
|
||||
help='Optionally compress dmg using specified compression type. '
|
||||
'Choices are bz2 and gz.'
|
||||
)
|
||||
options, args = parser.parse_args()
|
||||
cond = len(args) != 2
|
||||
if not os.path.exists(options.rez):
|
||||
print 'Failed to find Rez at "%s"!\n' % options.rez
|
||||
cond = True
|
||||
if cond:
|
||||
parser.print_usage()
|
||||
sys.exit(1)
|
||||
main(options, args)
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
on run (volumeName)
|
||||
tell application "Finder"
|
||||
tell disk (volumeName as string)
|
||||
open
|
||||
|
||||
set theXOrigin to WINX
|
||||
set theYOrigin to WINY
|
||||
set theWidth to WINW
|
||||
set theHeight to WINH
|
||||
|
||||
set theBottomRightX to (theXOrigin + theWidth)
|
||||
set theBottomRightY to (theYOrigin + theHeight)
|
||||
set dsStore to "\"" & "/Volumes/" & volumeName & "/" & ".DS_STORE\""
|
||||
|
||||
tell container window
|
||||
set current view to icon view
|
||||
set toolbar visible to false
|
||||
set statusbar visible to false
|
||||
set the bounds to {theXOrigin, theYOrigin, theBottomRightX, theBottomRightY}
|
||||
set statusbar visible to false
|
||||
REPOSITION_HIDDEN_FILES_CLAUSE
|
||||
end tell
|
||||
|
||||
set opts to the icon view options of container window
|
||||
tell opts
|
||||
set icon size to ICON_SIZE
|
||||
set text size to TEXT_SIZE
|
||||
set arrangement to not arranged
|
||||
end tell
|
||||
BACKGROUND_CLAUSE
|
||||
|
||||
-- Positioning
|
||||
POSITION_CLAUSE
|
||||
|
||||
-- Hiding
|
||||
HIDING_CLAUSE
|
||||
|
||||
-- Application Link Clause
|
||||
APPLICATION_CLAUSE
|
||||
close
|
||||
open
|
||||
|
||||
update without registering applications
|
||||
-- Force saving of the size
|
||||
delay 1
|
||||
|
||||
tell container window
|
||||
set statusbar visible to false
|
||||
set the bounds to {theXOrigin, theYOrigin, theBottomRightX - 10, theBottomRightY - 10}
|
||||
end tell
|
||||
|
||||
update without registering applications
|
||||
end tell
|
||||
|
||||
delay 1
|
||||
|
||||
tell disk (volumeName as string)
|
||||
tell container window
|
||||
set statusbar visible to false
|
||||
set the bounds to {theXOrigin, theYOrigin, theBottomRightX, theBottomRightY}
|
||||
end tell
|
||||
|
||||
update without registering applications
|
||||
end tell
|
||||
|
||||
--give the finder some time to write the .DS_Store file
|
||||
delay 3
|
||||
|
||||
set waitTime to 0
|
||||
set ejectMe to false
|
||||
repeat while ejectMe is false
|
||||
delay 1
|
||||
set waitTime to waitTime + 1
|
||||
|
||||
if (do shell script "[ -f " & dsStore & " ]; echo $?") = "0" then set ejectMe to true
|
||||
end repeat
|
||||
log "waited " & waitTime & " seconds for .DS_STORE to be created."
|
||||
end tell
|
||||
end run
|
||||
|
|
@ -1 +0,0 @@
|
|||
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
# Standard Docker Deployments
|
||||
|
||||
You can define a multitude of configurations in code using Docker Compose. Each folder in this directory represents a specific use case with a corresponding reference configuration.
|
||||
|
||||
Instead of writing your own Dockerfile, we recommend that you tailor the stack for your needs by editing one of the existing configurations. If you believe your changes will be useful to others, please submit a patch to improve the reference Dockerfiles.
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
set -e
|
||||
curr_path=${BASH_SOURCE%/*}
|
||||
version_file_path=../src/version.h.in
|
||||
|
||||
pushd $curr_path
|
||||
|
||||
# clear old local changes if any
|
||||
git checkout -- ../src/*
|
||||
|
||||
git pull --ff-only
|
||||
|
||||
build_no_before=`cat $version_file_path | grep 'PROJECT_VERSION_BUILD_NO ' | awk {'print $3'}`
|
||||
|
||||
../../zano-tools-last-build/connectivity_tool --increment-build-no=$version_file_path
|
||||
|
||||
build_no_after=`cat $version_file_path | grep 'PROJECT_VERSION_BUILD_NO ' | awk {'print $3'}`
|
||||
|
||||
echo "$build_no_before -> $build_no_after"
|
||||
|
||||
echo $(pwd -P)
|
||||
|
||||
git status
|
||||
git commit -a -m"=== build number: $build_no_before -> $build_no_after ==="
|
||||
|
||||
git push
|
||||
|
||||
echo "Build number was succesefully incremented."
|
||||
popd
|
||||
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.cs.disable-executable-page-protection</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
set -e
|
||||
curr_path=${BASH_SOURCE%/*}
|
||||
|
||||
function build_fancy_dmg() # $1 - path to package folder, $2 - dmg output filename
|
||||
{
|
||||
if [ -z "$1" ] || [ -z "$2" ]
|
||||
then
|
||||
echo "build_fancy_dmg is called with no or invalid parameters"
|
||||
return 1
|
||||
fi
|
||||
|
||||
$curr_path/contrib/create-dmg/create-dmg \
|
||||
--volname "Zano installer" \
|
||||
--volicon "$curr_path/../src/gui/qt-daemon/app.icns" \
|
||||
--background "$curr_path/../resources/dmg_installer_bg.png" \
|
||||
--window-pos 200 120 \
|
||||
--window-size 487 290 \
|
||||
--icon-size 128 \
|
||||
--icon Zano.app 112 115 \
|
||||
--hide-extension Zano.app \
|
||||
--app-drop-link 365 115 \
|
||||
--no-internet-enable \
|
||||
$2 \
|
||||
$1
|
||||
|
||||
return $?
|
||||
}
|
||||
|
||||
59
utils/sdk/Makefile
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
PACKAGE_VERSION?=6.0.1
|
||||
BASE_DIR:=$(CURDIR)
|
||||
# Default build directory. Can be overridden from the parent Makefile.
|
||||
# e.g., `make sdk BUILD_DIR=client` will output to the `client/` directory.
|
||||
BUILD_DIR?=$(BASE_DIR)/../../build/packages
|
||||
SDK_TARGETS := $(patsubst packages/%.json,%,$(wildcard packages/*.json))
|
||||
|
||||
# --- Target-Specific Hooks ---
|
||||
# Define pre- and post-build steps for specific languages.
|
||||
# By default, these hooks are empty.
|
||||
|
||||
PRE_BUILD_HOOK = @true
|
||||
POST_BUILD_HOOK = @true
|
||||
|
||||
# For the 'go' target, create an ignore file to prevent unwanted files from being generated.
|
||||
go: PRE_BUILD_HOOK = @echo "--> Creating .openapi-generator-ignore file for Go client"; \
|
||||
echo "go.sum" >> $(BUILD_DIR)/go/.openapi-generator-ignore
|
||||
|
||||
# For the 'go' target, define specific post-build steps.
|
||||
go: POST_BUILD_HOOK = (cd $(BUILD_DIR)/go && go mod edit -module github.com/letheanVPN/blockchain/utils/sdk/client/go && go mod tidy)
|
||||
|
||||
# For the 'go' target, set the generator name correctly.
|
||||
go: GENERATOR_NAME = go
|
||||
|
||||
# --- Main Targets ---
|
||||
|
||||
all: build
|
||||
|
||||
build: $(SDK_TARGETS)
|
||||
@echo "All SDKs have been processed."
|
||||
|
||||
# Rule to build each SDK package using OpenAPI Generator.
|
||||
# It reads the corresponding JSON config file and generates the SDK in the build directory.
|
||||
$(SDK_TARGETS): %: packages/%.json
|
||||
# Default generator name is the target name itself.
|
||||
$(eval GENERATOR_NAME = $@)
|
||||
@echo "--> Creating .openapi-generator-ignore file"
|
||||
@echo "git_push.sh" > "$(BUILD_DIR)/$@/.openapi-generator-ignore"
|
||||
@echo ".travis.yml" >> "$(BUILD_DIR)/$@/.openapi-generator-ignore"
|
||||
@echo "README.md" >> "$(BUILD_DIR)/$@/.openapi-generator-ignore"
|
||||
|
||||
@echo "--- Building package $@ with version $(PACKAGE_VERSION) ---"
|
||||
# Run pre-build hook
|
||||
$(PRE_BUILD_HOOK)
|
||||
rm -rf "$(BUILD_DIR)/$@/*"
|
||||
export TS_POST_PROCESS_FILE="/usr/local/bin/prettier --write" && \
|
||||
openapi-generator generate --minimal-update --git-host "github.com" --git-repo-id "blockchain" --git-user-id "letheanVPN" \
|
||||
-i "$(BASE_DIR)/spec/oas-3.0.0.json" \
|
||||
-g "$(GENERATOR_NAME)" \
|
||||
-o "$(BUILD_DIR)/$@" \
|
||||
-c "$<" \
|
||||
--artifact-version "$(PACKAGE_VERSION)" \
|
||||
--package-name "lthn"
|
||||
# Run post-build hook
|
||||
@echo "--> Running Post Build..."
|
||||
$(POST_BUILD_HOOK)
|
||||
|
||||
# Phony targets to avoid conflicts with file names and to ensure they always run.
|
||||
.PHONY: all build $(SDK_TARGETS)
|
||||
24
utils/sdk/client/go/.gitignore
generated
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
||||
4
utils/sdk/client/go/.openapi-generator-ignore
generated
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
git_push.sh
|
||||
.travis.yml
|
||||
README.md
|
||||
go.sum
|
||||
55
utils/sdk/client/go/.openapi-generator/FILES
generated
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
.gitignore
|
||||
api/openapi.yaml
|
||||
api_block.go
|
||||
api_info.go
|
||||
client.go
|
||||
configuration.go
|
||||
docs/BlockAPI.md
|
||||
docs/BlockDetailsModel.md
|
||||
docs/BlockProcessingPerformanceModel.md
|
||||
docs/BlockTemplateModel.md
|
||||
docs/BlockTemplateRequestModel.md
|
||||
docs/DbStatInfoModel.md
|
||||
docs/HeightModel.md
|
||||
docs/InfoAPI.md
|
||||
docs/InfoModel.md
|
||||
docs/MaintainersInfoModel.md
|
||||
docs/PerformanceModel.md
|
||||
docs/PosEntryModel.md
|
||||
docs/SubmitBlockRequestModel.md
|
||||
docs/SubmitBlockResponseModel.md
|
||||
docs/TransactionAttachmentModel.md
|
||||
docs/TransactionDetailsModel.md
|
||||
docs/TransactionExtraModel.md
|
||||
docs/TransactionInputModel.md
|
||||
docs/TransactionOutputModel.md
|
||||
docs/TxGenerationContextModel.md
|
||||
docs/TxPoolPerformanceModel.md
|
||||
docs/TxProcessingPerformanceModel.md
|
||||
docs/VersionModel.md
|
||||
go.mod
|
||||
model_block_details_model.go
|
||||
model_block_processing_performance_model.go
|
||||
model_block_template_model.go
|
||||
model_block_template_request_model.go
|
||||
model_db_stat_info_model.go
|
||||
model_height_model.go
|
||||
model_info_model.go
|
||||
model_maintainers_info_model.go
|
||||
model_performance_model.go
|
||||
model_pos_entry_model.go
|
||||
model_submit_block_request_model.go
|
||||
model_submit_block_response_model.go
|
||||
model_transaction_attachment_model.go
|
||||
model_transaction_details_model.go
|
||||
model_transaction_extra_model.go
|
||||
model_transaction_input_model.go
|
||||
model_transaction_output_model.go
|
||||
model_tx_generation_context_model.go
|
||||
model_tx_pool_performance_model.go
|
||||
model_tx_processing_performance_model.go
|
||||
model_version_model.go
|
||||
response.go
|
||||
test/api_block_test.go
|
||||
test/api_info_test.go
|
||||
utils.go
|
||||
1
utils/sdk/client/go/.openapi-generator/VERSION
generated
Normal file
|
|
@ -0,0 +1 @@
|
|||
7.16.0
|
||||
1329
utils/sdk/client/go/api/openapi.yaml
generated
Normal file
599
utils/sdk/client/go/api_block.go
generated
Normal file
|
|
@ -0,0 +1,599 @@
|
|||
/*
|
||||
Lethean Blockchain API
|
||||
|
||||
OpenAPI for Lethean Blockchain
|
||||
|
||||
API version: 6.0.1
|
||||
*/
|
||||
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package lthn
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
||||
type BlockAPI interface {
|
||||
|
||||
/*
|
||||
CreateBlockTemplate Create a block template for mining
|
||||
|
||||
@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
|
||||
@return ApiCreateBlockTemplateRequest
|
||||
*/
|
||||
CreateBlockTemplate(ctx context.Context) ApiCreateBlockTemplateRequest
|
||||
|
||||
// CreateBlockTemplateExecute executes the request
|
||||
// @return BlockTemplateModel
|
||||
CreateBlockTemplateExecute(r ApiCreateBlockTemplateRequest) (*BlockTemplateModel, *http.Response, error)
|
||||
|
||||
/*
|
||||
GetBlock Get a block by its hash or height (ID)
|
||||
|
||||
@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
|
||||
@param identifier The hash (hex string) or height (integer) of the block to retrieve.
|
||||
@return ApiGetBlockRequest
|
||||
*/
|
||||
GetBlock(ctx context.Context, identifier string) ApiGetBlockRequest
|
||||
|
||||
// GetBlockExecute executes the request
|
||||
// @return BlockDetailsModel
|
||||
GetBlockExecute(r ApiGetBlockRequest) (*BlockDetailsModel, *http.Response, error)
|
||||
|
||||
/*
|
||||
GetBlocks Get one or more blocks, with optional pagination.
|
||||
|
||||
@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
|
||||
@return ApiGetBlocksRequest
|
||||
*/
|
||||
GetBlocks(ctx context.Context) ApiGetBlocksRequest
|
||||
|
||||
// GetBlocksExecute executes the request
|
||||
// @return []BlockDetailsModel
|
||||
GetBlocksExecute(r ApiGetBlocksRequest) ([]BlockDetailsModel, *http.Response, error)
|
||||
|
||||
/*
|
||||
GetHeight Get the current blockchain height
|
||||
|
||||
@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
|
||||
@return ApiGetHeightRequest
|
||||
*/
|
||||
GetHeight(ctx context.Context) ApiGetHeightRequest
|
||||
|
||||
// GetHeightExecute executes the request
|
||||
// @return HeightModel
|
||||
GetHeightExecute(r ApiGetHeightRequest) (*HeightModel, *http.Response, error)
|
||||
|
||||
/*
|
||||
SubmitBlock Submit a new block to the network
|
||||
|
||||
@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
|
||||
@return ApiSubmitBlockRequest
|
||||
*/
|
||||
SubmitBlock(ctx context.Context) ApiSubmitBlockRequest
|
||||
|
||||
// SubmitBlockExecute executes the request
|
||||
// @return SubmitBlockResponseModel
|
||||
SubmitBlockExecute(r ApiSubmitBlockRequest) (*SubmitBlockResponseModel, *http.Response, error)
|
||||
}
|
||||
|
||||
// BlockAPIService BlockAPI service
|
||||
type BlockAPIService service
|
||||
|
||||
type ApiCreateBlockTemplateRequest struct {
|
||||
ctx context.Context
|
||||
ApiService BlockAPI
|
||||
blockTemplateRequestModel *BlockTemplateRequestModel
|
||||
}
|
||||
|
||||
func (r ApiCreateBlockTemplateRequest) BlockTemplateRequestModel(blockTemplateRequestModel BlockTemplateRequestModel) ApiCreateBlockTemplateRequest {
|
||||
r.blockTemplateRequestModel = &blockTemplateRequestModel
|
||||
return r
|
||||
}
|
||||
|
||||
func (r ApiCreateBlockTemplateRequest) Execute() (*BlockTemplateModel, *http.Response, error) {
|
||||
return r.ApiService.CreateBlockTemplateExecute(r)
|
||||
}
|
||||
|
||||
/*
|
||||
CreateBlockTemplate Create a block template for mining
|
||||
|
||||
@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
|
||||
@return ApiCreateBlockTemplateRequest
|
||||
*/
|
||||
func (a *BlockAPIService) CreateBlockTemplate(ctx context.Context) ApiCreateBlockTemplateRequest {
|
||||
return ApiCreateBlockTemplateRequest{
|
||||
ApiService: a,
|
||||
ctx: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
// Execute executes the request
|
||||
// @return BlockTemplateModel
|
||||
func (a *BlockAPIService) CreateBlockTemplateExecute(r ApiCreateBlockTemplateRequest) (*BlockTemplateModel, *http.Response, error) {
|
||||
var (
|
||||
localVarHTTPMethod = http.MethodPost
|
||||
localVarPostBody interface{}
|
||||
formFiles []formFile
|
||||
localVarReturnValue *BlockTemplateModel
|
||||
)
|
||||
|
||||
localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "BlockAPIService.CreateBlockTemplate")
|
||||
if err != nil {
|
||||
return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}
|
||||
}
|
||||
|
||||
localVarPath := localBasePath + "/block/template"
|
||||
|
||||
localVarHeaderParams := make(map[string]string)
|
||||
localVarQueryParams := url.Values{}
|
||||
localVarFormParams := url.Values{}
|
||||
if r.blockTemplateRequestModel == nil {
|
||||
return localVarReturnValue, nil, reportError("blockTemplateRequestModel is required and must be specified")
|
||||
}
|
||||
|
||||
// to determine the Content-Type header
|
||||
localVarHTTPContentTypes := []string{"application/json"}
|
||||
|
||||
// set Content-Type header
|
||||
localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
|
||||
if localVarHTTPContentType != "" {
|
||||
localVarHeaderParams["Content-Type"] = localVarHTTPContentType
|
||||
}
|
||||
|
||||
// to determine the Accept header
|
||||
localVarHTTPHeaderAccepts := []string{"application/json"}
|
||||
|
||||
// set Accept header
|
||||
localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
|
||||
if localVarHTTPHeaderAccept != "" {
|
||||
localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
|
||||
}
|
||||
// body params
|
||||
localVarPostBody = r.blockTemplateRequestModel
|
||||
req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)
|
||||
if err != nil {
|
||||
return localVarReturnValue, nil, err
|
||||
}
|
||||
|
||||
localVarHTTPResponse, err := a.client.callAPI(req)
|
||||
if err != nil || localVarHTTPResponse == nil {
|
||||
return localVarReturnValue, localVarHTTPResponse, err
|
||||
}
|
||||
|
||||
localVarBody, err := io.ReadAll(localVarHTTPResponse.Body)
|
||||
localVarHTTPResponse.Body.Close()
|
||||
localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))
|
||||
if err != nil {
|
||||
return localVarReturnValue, localVarHTTPResponse, err
|
||||
}
|
||||
|
||||
if localVarHTTPResponse.StatusCode >= 300 {
|
||||
newErr := &GenericOpenAPIError{
|
||||
body: localVarBody,
|
||||
error: localVarHTTPResponse.Status,
|
||||
}
|
||||
return localVarReturnValue, localVarHTTPResponse, newErr
|
||||
}
|
||||
|
||||
err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
|
||||
if err != nil {
|
||||
newErr := &GenericOpenAPIError{
|
||||
body: localVarBody,
|
||||
error: err.Error(),
|
||||
}
|
||||
return localVarReturnValue, localVarHTTPResponse, newErr
|
||||
}
|
||||
|
||||
return localVarReturnValue, localVarHTTPResponse, nil
|
||||
}
|
||||
|
||||
type ApiGetBlockRequest struct {
|
||||
ctx context.Context
|
||||
ApiService BlockAPI
|
||||
identifier string
|
||||
}
|
||||
|
||||
func (r ApiGetBlockRequest) Execute() (*BlockDetailsModel, *http.Response, error) {
|
||||
return r.ApiService.GetBlockExecute(r)
|
||||
}
|
||||
|
||||
/*
|
||||
GetBlock Get a block by its hash or height (ID)
|
||||
|
||||
@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
|
||||
@param identifier The hash (hex string) or height (integer) of the block to retrieve.
|
||||
@return ApiGetBlockRequest
|
||||
*/
|
||||
func (a *BlockAPIService) GetBlock(ctx context.Context, identifier string) ApiGetBlockRequest {
|
||||
return ApiGetBlockRequest{
|
||||
ApiService: a,
|
||||
ctx: ctx,
|
||||
identifier: identifier,
|
||||
}
|
||||
}
|
||||
|
||||
// Execute executes the request
|
||||
// @return BlockDetailsModel
|
||||
func (a *BlockAPIService) GetBlockExecute(r ApiGetBlockRequest) (*BlockDetailsModel, *http.Response, error) {
|
||||
var (
|
||||
localVarHTTPMethod = http.MethodGet
|
||||
localVarPostBody interface{}
|
||||
formFiles []formFile
|
||||
localVarReturnValue *BlockDetailsModel
|
||||
)
|
||||
|
||||
localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "BlockAPIService.GetBlock")
|
||||
if err != nil {
|
||||
return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}
|
||||
}
|
||||
|
||||
localVarPath := localBasePath + "/block/{identifier}"
|
||||
localVarPath = strings.Replace(localVarPath, "{"+"identifier"+"}", url.PathEscape(parameterValueToString(r.identifier, "identifier")), -1)
|
||||
|
||||
localVarHeaderParams := make(map[string]string)
|
||||
localVarQueryParams := url.Values{}
|
||||
localVarFormParams := url.Values{}
|
||||
|
||||
// to determine the Content-Type header
|
||||
localVarHTTPContentTypes := []string{}
|
||||
|
||||
// set Content-Type header
|
||||
localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
|
||||
if localVarHTTPContentType != "" {
|
||||
localVarHeaderParams["Content-Type"] = localVarHTTPContentType
|
||||
}
|
||||
|
||||
// to determine the Accept header
|
||||
localVarHTTPHeaderAccepts := []string{"application/json"}
|
||||
|
||||
// set Accept header
|
||||
localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
|
||||
if localVarHTTPHeaderAccept != "" {
|
||||
localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
|
||||
}
|
||||
req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)
|
||||
if err != nil {
|
||||
return localVarReturnValue, nil, err
|
||||
}
|
||||
|
||||
localVarHTTPResponse, err := a.client.callAPI(req)
|
||||
if err != nil || localVarHTTPResponse == nil {
|
||||
return localVarReturnValue, localVarHTTPResponse, err
|
||||
}
|
||||
|
||||
localVarBody, err := io.ReadAll(localVarHTTPResponse.Body)
|
||||
localVarHTTPResponse.Body.Close()
|
||||
localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))
|
||||
if err != nil {
|
||||
return localVarReturnValue, localVarHTTPResponse, err
|
||||
}
|
||||
|
||||
if localVarHTTPResponse.StatusCode >= 300 {
|
||||
newErr := &GenericOpenAPIError{
|
||||
body: localVarBody,
|
||||
error: localVarHTTPResponse.Status,
|
||||
}
|
||||
return localVarReturnValue, localVarHTTPResponse, newErr
|
||||
}
|
||||
|
||||
err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
|
||||
if err != nil {
|
||||
newErr := &GenericOpenAPIError{
|
||||
body: localVarBody,
|
||||
error: err.Error(),
|
||||
}
|
||||
return localVarReturnValue, localVarHTTPResponse, newErr
|
||||
}
|
||||
|
||||
return localVarReturnValue, localVarHTTPResponse, nil
|
||||
}
|
||||
|
||||
type ApiGetBlocksRequest struct {
|
||||
ctx context.Context
|
||||
ApiService BlockAPI
|
||||
}
|
||||
|
||||
func (r ApiGetBlocksRequest) Execute() ([]BlockDetailsModel, *http.Response, error) {
|
||||
return r.ApiService.GetBlocksExecute(r)
|
||||
}
|
||||
|
||||
/*
|
||||
GetBlocks Get one or more blocks, with optional pagination.
|
||||
|
||||
@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
|
||||
@return ApiGetBlocksRequest
|
||||
*/
|
||||
func (a *BlockAPIService) GetBlocks(ctx context.Context) ApiGetBlocksRequest {
|
||||
return ApiGetBlocksRequest{
|
||||
ApiService: a,
|
||||
ctx: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
// Execute executes the request
|
||||
// @return []BlockDetailsModel
|
||||
func (a *BlockAPIService) GetBlocksExecute(r ApiGetBlocksRequest) ([]BlockDetailsModel, *http.Response, error) {
|
||||
var (
|
||||
localVarHTTPMethod = http.MethodGet
|
||||
localVarPostBody interface{}
|
||||
formFiles []formFile
|
||||
localVarReturnValue []BlockDetailsModel
|
||||
)
|
||||
|
||||
localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "BlockAPIService.GetBlocks")
|
||||
if err != nil {
|
||||
return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}
|
||||
}
|
||||
|
||||
localVarPath := localBasePath + "/block"
|
||||
|
||||
localVarHeaderParams := make(map[string]string)
|
||||
localVarQueryParams := url.Values{}
|
||||
localVarFormParams := url.Values{}
|
||||
|
||||
// to determine the Content-Type header
|
||||
localVarHTTPContentTypes := []string{}
|
||||
|
||||
// set Content-Type header
|
||||
localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
|
||||
if localVarHTTPContentType != "" {
|
||||
localVarHeaderParams["Content-Type"] = localVarHTTPContentType
|
||||
}
|
||||
|
||||
// to determine the Accept header
|
||||
localVarHTTPHeaderAccepts := []string{"application/json"}
|
||||
|
||||
// set Accept header
|
||||
localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
|
||||
if localVarHTTPHeaderAccept != "" {
|
||||
localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
|
||||
}
|
||||
req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)
|
||||
if err != nil {
|
||||
return localVarReturnValue, nil, err
|
||||
}
|
||||
|
||||
localVarHTTPResponse, err := a.client.callAPI(req)
|
||||
if err != nil || localVarHTTPResponse == nil {
|
||||
return localVarReturnValue, localVarHTTPResponse, err
|
||||
}
|
||||
|
||||
localVarBody, err := io.ReadAll(localVarHTTPResponse.Body)
|
||||
localVarHTTPResponse.Body.Close()
|
||||
localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))
|
||||
if err != nil {
|
||||
return localVarReturnValue, localVarHTTPResponse, err
|
||||
}
|
||||
|
||||
if localVarHTTPResponse.StatusCode >= 300 {
|
||||
newErr := &GenericOpenAPIError{
|
||||
body: localVarBody,
|
||||
error: localVarHTTPResponse.Status,
|
||||
}
|
||||
return localVarReturnValue, localVarHTTPResponse, newErr
|
||||
}
|
||||
|
||||
err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
|
||||
if err != nil {
|
||||
newErr := &GenericOpenAPIError{
|
||||
body: localVarBody,
|
||||
error: err.Error(),
|
||||
}
|
||||
return localVarReturnValue, localVarHTTPResponse, newErr
|
||||
}
|
||||
|
||||
return localVarReturnValue, localVarHTTPResponse, nil
|
||||
}
|
||||
|
||||
type ApiGetHeightRequest struct {
|
||||
ctx context.Context
|
||||
ApiService BlockAPI
|
||||
}
|
||||
|
||||
func (r ApiGetHeightRequest) Execute() (*HeightModel, *http.Response, error) {
|
||||
return r.ApiService.GetHeightExecute(r)
|
||||
}
|
||||
|
||||
/*
|
||||
GetHeight Get the current blockchain height
|
||||
|
||||
@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
|
||||
@return ApiGetHeightRequest
|
||||
*/
|
||||
func (a *BlockAPIService) GetHeight(ctx context.Context) ApiGetHeightRequest {
|
||||
return ApiGetHeightRequest{
|
||||
ApiService: a,
|
||||
ctx: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
// Execute executes the request
|
||||
// @return HeightModel
|
||||
func (a *BlockAPIService) GetHeightExecute(r ApiGetHeightRequest) (*HeightModel, *http.Response, error) {
|
||||
var (
|
||||
localVarHTTPMethod = http.MethodGet
|
||||
localVarPostBody interface{}
|
||||
formFiles []formFile
|
||||
localVarReturnValue *HeightModel
|
||||
)
|
||||
|
||||
localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "BlockAPIService.GetHeight")
|
||||
if err != nil {
|
||||
return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}
|
||||
}
|
||||
|
||||
localVarPath := localBasePath + "/block/height"
|
||||
|
||||
localVarHeaderParams := make(map[string]string)
|
||||
localVarQueryParams := url.Values{}
|
||||
localVarFormParams := url.Values{}
|
||||
|
||||
// to determine the Content-Type header
|
||||
localVarHTTPContentTypes := []string{}
|
||||
|
||||
// set Content-Type header
|
||||
localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
|
||||
if localVarHTTPContentType != "" {
|
||||
localVarHeaderParams["Content-Type"] = localVarHTTPContentType
|
||||
}
|
||||
|
||||
// to determine the Accept header
|
||||
localVarHTTPHeaderAccepts := []string{"application/json"}
|
||||
|
||||
// set Accept header
|
||||
localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
|
||||
if localVarHTTPHeaderAccept != "" {
|
||||
localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
|
||||
}
|
||||
req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)
|
||||
if err != nil {
|
||||
return localVarReturnValue, nil, err
|
||||
}
|
||||
|
||||
localVarHTTPResponse, err := a.client.callAPI(req)
|
||||
if err != nil || localVarHTTPResponse == nil {
|
||||
return localVarReturnValue, localVarHTTPResponse, err
|
||||
}
|
||||
|
||||
localVarBody, err := io.ReadAll(localVarHTTPResponse.Body)
|
||||
localVarHTTPResponse.Body.Close()
|
||||
localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))
|
||||
if err != nil {
|
||||
return localVarReturnValue, localVarHTTPResponse, err
|
||||
}
|
||||
|
||||
if localVarHTTPResponse.StatusCode >= 300 {
|
||||
newErr := &GenericOpenAPIError{
|
||||
body: localVarBody,
|
||||
error: localVarHTTPResponse.Status,
|
||||
}
|
||||
return localVarReturnValue, localVarHTTPResponse, newErr
|
||||
}
|
||||
|
||||
err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
|
||||
if err != nil {
|
||||
newErr := &GenericOpenAPIError{
|
||||
body: localVarBody,
|
||||
error: err.Error(),
|
||||
}
|
||||
return localVarReturnValue, localVarHTTPResponse, newErr
|
||||
}
|
||||
|
||||
return localVarReturnValue, localVarHTTPResponse, nil
|
||||
}
|
||||
|
||||
type ApiSubmitBlockRequest struct {
|
||||
ctx context.Context
|
||||
ApiService BlockAPI
|
||||
submitBlockRequestModel *SubmitBlockRequestModel
|
||||
}
|
||||
|
||||
func (r ApiSubmitBlockRequest) SubmitBlockRequestModel(submitBlockRequestModel SubmitBlockRequestModel) ApiSubmitBlockRequest {
|
||||
r.submitBlockRequestModel = &submitBlockRequestModel
|
||||
return r
|
||||
}
|
||||
|
||||
func (r ApiSubmitBlockRequest) Execute() (*SubmitBlockResponseModel, *http.Response, error) {
|
||||
return r.ApiService.SubmitBlockExecute(r)
|
||||
}
|
||||
|
||||
/*
|
||||
SubmitBlock Submit a new block to the network
|
||||
|
||||
@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
|
||||
@return ApiSubmitBlockRequest
|
||||
*/
|
||||
func (a *BlockAPIService) SubmitBlock(ctx context.Context) ApiSubmitBlockRequest {
|
||||
return ApiSubmitBlockRequest{
|
||||
ApiService: a,
|
||||
ctx: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
// Execute executes the request
|
||||
// @return SubmitBlockResponseModel
|
||||
func (a *BlockAPIService) SubmitBlockExecute(r ApiSubmitBlockRequest) (*SubmitBlockResponseModel, *http.Response, error) {
|
||||
var (
|
||||
localVarHTTPMethod = http.MethodPost
|
||||
localVarPostBody interface{}
|
||||
formFiles []formFile
|
||||
localVarReturnValue *SubmitBlockResponseModel
|
||||
)
|
||||
|
||||
localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "BlockAPIService.SubmitBlock")
|
||||
if err != nil {
|
||||
return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}
|
||||
}
|
||||
|
||||
localVarPath := localBasePath + "/block/submit"
|
||||
|
||||
localVarHeaderParams := make(map[string]string)
|
||||
localVarQueryParams := url.Values{}
|
||||
localVarFormParams := url.Values{}
|
||||
if r.submitBlockRequestModel == nil {
|
||||
return localVarReturnValue, nil, reportError("submitBlockRequestModel is required and must be specified")
|
||||
}
|
||||
|
||||
// to determine the Content-Type header
|
||||
localVarHTTPContentTypes := []string{"application/json"}
|
||||
|
||||
// set Content-Type header
|
||||
localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
|
||||
if localVarHTTPContentType != "" {
|
||||
localVarHeaderParams["Content-Type"] = localVarHTTPContentType
|
||||
}
|
||||
|
||||
// to determine the Accept header
|
||||
localVarHTTPHeaderAccepts := []string{"application/json"}
|
||||
|
||||
// set Accept header
|
||||
localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
|
||||
if localVarHTTPHeaderAccept != "" {
|
||||
localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
|
||||
}
|
||||
// body params
|
||||
localVarPostBody = r.submitBlockRequestModel
|
||||
req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)
|
||||
if err != nil {
|
||||
return localVarReturnValue, nil, err
|
||||
}
|
||||
|
||||
localVarHTTPResponse, err := a.client.callAPI(req)
|
||||
if err != nil || localVarHTTPResponse == nil {
|
||||
return localVarReturnValue, localVarHTTPResponse, err
|
||||
}
|
||||
|
||||
localVarBody, err := io.ReadAll(localVarHTTPResponse.Body)
|
||||
localVarHTTPResponse.Body.Close()
|
||||
localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))
|
||||
if err != nil {
|
||||
return localVarReturnValue, localVarHTTPResponse, err
|
||||
}
|
||||
|
||||
if localVarHTTPResponse.StatusCode >= 300 {
|
||||
newErr := &GenericOpenAPIError{
|
||||
body: localVarBody,
|
||||
error: localVarHTTPResponse.Status,
|
||||
}
|
||||
return localVarReturnValue, localVarHTTPResponse, newErr
|
||||
}
|
||||
|
||||
err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
|
||||
if err != nil {
|
||||
newErr := &GenericOpenAPIError{
|
||||
body: localVarBody,
|
||||
error: err.Error(),
|
||||
}
|
||||
return localVarReturnValue, localVarHTTPResponse, newErr
|
||||
}
|
||||
|
||||
return localVarReturnValue, localVarHTTPResponse, nil
|
||||
}
|
||||
258
utils/sdk/client/go/api_info.go
generated
Normal file
|
|
@ -0,0 +1,258 @@
|
|||
/*
|
||||
Lethean Blockchain API
|
||||
|
||||
OpenAPI for Lethean Blockchain
|
||||
|
||||
API version: 6.0.1
|
||||
*/
|
||||
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package lthn
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
|
||||
type InfoAPI interface {
|
||||
|
||||
/*
|
||||
GetInfo Get detailed information about the blockchain and daemon state
|
||||
|
||||
@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
|
||||
@return ApiGetInfoRequest
|
||||
*/
|
||||
GetInfo(ctx context.Context) ApiGetInfoRequest
|
||||
|
||||
// GetInfoExecute executes the request
|
||||
// @return InfoModel
|
||||
GetInfoExecute(r ApiGetInfoRequest) (*InfoModel, *http.Response, error)
|
||||
|
||||
/*
|
||||
Version Get API version
|
||||
|
||||
Returns the current version of the API.
|
||||
|
||||
@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
|
||||
@return ApiVersionRequest
|
||||
*/
|
||||
Version(ctx context.Context) ApiVersionRequest
|
||||
|
||||
// VersionExecute executes the request
|
||||
// @return VersionModel
|
||||
VersionExecute(r ApiVersionRequest) (*VersionModel, *http.Response, error)
|
||||
}
|
||||
|
||||
// InfoAPIService InfoAPI service
|
||||
type InfoAPIService service
|
||||
|
||||
type ApiGetInfoRequest struct {
|
||||
ctx context.Context
|
||||
ApiService InfoAPI
|
||||
flags *string
|
||||
}
|
||||
|
||||
// Possible values: net_time_delta_median, current_network_hashrate_50, current_network_hashrate_350, seconds_for_10_blocks, seconds_for_30_blocks, transactions_daily_stat, last_pos_timestamp, last_pow_timestamp, total_coins, last_block_size, tx_count_in_last_block, pos_sequence_factor, pow_sequence_factor, pos_difficulty, performance, outs_stat, expirations_median.
|
||||
func (r ApiGetInfoRequest) Flags(flags string) ApiGetInfoRequest {
|
||||
r.flags = &flags
|
||||
return r
|
||||
}
|
||||
|
||||
func (r ApiGetInfoRequest) Execute() (*InfoModel, *http.Response, error) {
|
||||
return r.ApiService.GetInfoExecute(r)
|
||||
}
|
||||
|
||||
/*
|
||||
GetInfo Get detailed information about the blockchain and daemon state
|
||||
|
||||
@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
|
||||
@return ApiGetInfoRequest
|
||||
*/
|
||||
func (a *InfoAPIService) GetInfo(ctx context.Context) ApiGetInfoRequest {
|
||||
return ApiGetInfoRequest{
|
||||
ApiService: a,
|
||||
ctx: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
// Execute executes the request
|
||||
// @return InfoModel
|
||||
func (a *InfoAPIService) GetInfoExecute(r ApiGetInfoRequest) (*InfoModel, *http.Response, error) {
|
||||
var (
|
||||
localVarHTTPMethod = http.MethodGet
|
||||
localVarPostBody interface{}
|
||||
formFiles []formFile
|
||||
localVarReturnValue *InfoModel
|
||||
)
|
||||
|
||||
localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "InfoAPIService.GetInfo")
|
||||
if err != nil {
|
||||
return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}
|
||||
}
|
||||
|
||||
localVarPath := localBasePath + "/info"
|
||||
|
||||
localVarHeaderParams := make(map[string]string)
|
||||
localVarQueryParams := url.Values{}
|
||||
localVarFormParams := url.Values{}
|
||||
|
||||
if r.flags != nil {
|
||||
parameterAddToHeaderOrQuery(localVarQueryParams, "flags", r.flags, "form", "")
|
||||
}
|
||||
// to determine the Content-Type header
|
||||
localVarHTTPContentTypes := []string{}
|
||||
|
||||
// set Content-Type header
|
||||
localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
|
||||
if localVarHTTPContentType != "" {
|
||||
localVarHeaderParams["Content-Type"] = localVarHTTPContentType
|
||||
}
|
||||
|
||||
// to determine the Accept header
|
||||
localVarHTTPHeaderAccepts := []string{"application/json"}
|
||||
|
||||
// set Accept header
|
||||
localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
|
||||
if localVarHTTPHeaderAccept != "" {
|
||||
localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
|
||||
}
|
||||
req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)
|
||||
if err != nil {
|
||||
return localVarReturnValue, nil, err
|
||||
}
|
||||
|
||||
localVarHTTPResponse, err := a.client.callAPI(req)
|
||||
if err != nil || localVarHTTPResponse == nil {
|
||||
return localVarReturnValue, localVarHTTPResponse, err
|
||||
}
|
||||
|
||||
localVarBody, err := io.ReadAll(localVarHTTPResponse.Body)
|
||||
localVarHTTPResponse.Body.Close()
|
||||
localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))
|
||||
if err != nil {
|
||||
return localVarReturnValue, localVarHTTPResponse, err
|
||||
}
|
||||
|
||||
if localVarHTTPResponse.StatusCode >= 300 {
|
||||
newErr := &GenericOpenAPIError{
|
||||
body: localVarBody,
|
||||
error: localVarHTTPResponse.Status,
|
||||
}
|
||||
return localVarReturnValue, localVarHTTPResponse, newErr
|
||||
}
|
||||
|
||||
err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
|
||||
if err != nil {
|
||||
newErr := &GenericOpenAPIError{
|
||||
body: localVarBody,
|
||||
error: err.Error(),
|
||||
}
|
||||
return localVarReturnValue, localVarHTTPResponse, newErr
|
||||
}
|
||||
|
||||
return localVarReturnValue, localVarHTTPResponse, nil
|
||||
}
|
||||
|
||||
type ApiVersionRequest struct {
|
||||
ctx context.Context
|
||||
ApiService InfoAPI
|
||||
}
|
||||
|
||||
func (r ApiVersionRequest) Execute() (*VersionModel, *http.Response, error) {
|
||||
return r.ApiService.VersionExecute(r)
|
||||
}
|
||||
|
||||
/*
|
||||
Version Get API version
|
||||
|
||||
Returns the current version of the API.
|
||||
|
||||
@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
|
||||
@return ApiVersionRequest
|
||||
*/
|
||||
func (a *InfoAPIService) Version(ctx context.Context) ApiVersionRequest {
|
||||
return ApiVersionRequest{
|
||||
ApiService: a,
|
||||
ctx: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
// Execute executes the request
|
||||
// @return VersionModel
|
||||
func (a *InfoAPIService) VersionExecute(r ApiVersionRequest) (*VersionModel, *http.Response, error) {
|
||||
var (
|
||||
localVarHTTPMethod = http.MethodGet
|
||||
localVarPostBody interface{}
|
||||
formFiles []formFile
|
||||
localVarReturnValue *VersionModel
|
||||
)
|
||||
|
||||
localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "InfoAPIService.Version")
|
||||
if err != nil {
|
||||
return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}
|
||||
}
|
||||
|
||||
localVarPath := localBasePath + "/info/version"
|
||||
|
||||
localVarHeaderParams := make(map[string]string)
|
||||
localVarQueryParams := url.Values{}
|
||||
localVarFormParams := url.Values{}
|
||||
|
||||
// to determine the Content-Type header
|
||||
localVarHTTPContentTypes := []string{}
|
||||
|
||||
// set Content-Type header
|
||||
localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
|
||||
if localVarHTTPContentType != "" {
|
||||
localVarHeaderParams["Content-Type"] = localVarHTTPContentType
|
||||
}
|
||||
|
||||
// to determine the Accept header
|
||||
localVarHTTPHeaderAccepts := []string{"application/json"}
|
||||
|
||||
// set Accept header
|
||||
localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
|
||||
if localVarHTTPHeaderAccept != "" {
|
||||
localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
|
||||
}
|
||||
req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)
|
||||
if err != nil {
|
||||
return localVarReturnValue, nil, err
|
||||
}
|
||||
|
||||
localVarHTTPResponse, err := a.client.callAPI(req)
|
||||
if err != nil || localVarHTTPResponse == nil {
|
||||
return localVarReturnValue, localVarHTTPResponse, err
|
||||
}
|
||||
|
||||
localVarBody, err := io.ReadAll(localVarHTTPResponse.Body)
|
||||
localVarHTTPResponse.Body.Close()
|
||||
localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))
|
||||
if err != nil {
|
||||
return localVarReturnValue, localVarHTTPResponse, err
|
||||
}
|
||||
|
||||
if localVarHTTPResponse.StatusCode >= 300 {
|
||||
newErr := &GenericOpenAPIError{
|
||||
body: localVarBody,
|
||||
error: localVarHTTPResponse.Status,
|
||||
}
|
||||
return localVarReturnValue, localVarHTTPResponse, newErr
|
||||
}
|
||||
|
||||
err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
|
||||
if err != nil {
|
||||
newErr := &GenericOpenAPIError{
|
||||
body: localVarBody,
|
||||
error: err.Error(),
|
||||
}
|
||||
return localVarReturnValue, localVarHTTPResponse, newErr
|
||||
}
|
||||
|
||||
return localVarReturnValue, localVarHTTPResponse, nil
|
||||
}
|
||||
659
utils/sdk/client/go/client.go
generated
Normal file
|
|
@ -0,0 +1,659 @@
|
|||
/*
|
||||
Lethean Blockchain API
|
||||
|
||||
OpenAPI for Lethean Blockchain
|
||||
|
||||
API version: 6.0.1
|
||||
*/
|
||||
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package lthn
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
)
|
||||
|
||||
var (
|
||||
JsonCheck = regexp.MustCompile(`(?i:(?:application|text)/(?:[^;]+\+)?json)`)
|
||||
XmlCheck = regexp.MustCompile(`(?i:(?:application|text)/(?:[^;]+\+)?xml)`)
|
||||
queryParamSplit = regexp.MustCompile(`(^|&)([^&]+)`)
|
||||
queryDescape = strings.NewReplacer( "%5B", "[", "%5D", "]" )
|
||||
)
|
||||
|
||||
// APIClient manages communication with the Lethean Blockchain API API v6.0.1
|
||||
// In most cases there should be only one, shared, APIClient.
|
||||
type APIClient struct {
|
||||
cfg *Configuration
|
||||
common service // Reuse a single struct instead of allocating one for each service on the heap.
|
||||
|
||||
// API Services
|
||||
|
||||
BlockAPI BlockAPI
|
||||
|
||||
InfoAPI InfoAPI
|
||||
}
|
||||
|
||||
type service struct {
|
||||
client *APIClient
|
||||
}
|
||||
|
||||
// NewAPIClient creates a new API client. Requires a userAgent string describing your application.
|
||||
// optionally a custom http.Client to allow for advanced features such as caching.
|
||||
func NewAPIClient(cfg *Configuration) *APIClient {
|
||||
if cfg.HTTPClient == nil {
|
||||
cfg.HTTPClient = http.DefaultClient
|
||||
}
|
||||
|
||||
c := &APIClient{}
|
||||
c.cfg = cfg
|
||||
c.common.client = c
|
||||
|
||||
// API Services
|
||||
c.BlockAPI = (*BlockAPIService)(&c.common)
|
||||
c.InfoAPI = (*InfoAPIService)(&c.common)
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func atoi(in string) (int, error) {
|
||||
return strconv.Atoi(in)
|
||||
}
|
||||
|
||||
// selectHeaderContentType select a content type from the available list.
|
||||
func selectHeaderContentType(contentTypes []string) string {
|
||||
if len(contentTypes) == 0 {
|
||||
return ""
|
||||
}
|
||||
if contains(contentTypes, "application/json") {
|
||||
return "application/json"
|
||||
}
|
||||
return contentTypes[0] // use the first content type specified in 'consumes'
|
||||
}
|
||||
|
||||
// selectHeaderAccept join all accept types and return
|
||||
func selectHeaderAccept(accepts []string) string {
|
||||
if len(accepts) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
if contains(accepts, "application/json") {
|
||||
return "application/json"
|
||||
}
|
||||
|
||||
return strings.Join(accepts, ",")
|
||||
}
|
||||
|
||||
// contains is a case insensitive match, finding needle in a haystack
|
||||
func contains(haystack []string, needle string) bool {
|
||||
for _, a := range haystack {
|
||||
if strings.EqualFold(a, needle) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Verify optional parameters are of the correct type.
|
||||
func typeCheckParameter(obj interface{}, expected string, name string) error {
|
||||
// Make sure there is an object.
|
||||
if obj == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check the type is as expected.
|
||||
if reflect.TypeOf(obj).String() != expected {
|
||||
return fmt.Errorf("expected %s to be of type %s but received %s", name, expected, reflect.TypeOf(obj).String())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func parameterValueToString( obj interface{}, key string ) string {
|
||||
if reflect.TypeOf(obj).Kind() != reflect.Ptr {
|
||||
if actualObj, ok := obj.(interface{ GetActualInstanceValue() interface{} }); ok {
|
||||
return fmt.Sprintf("%v", actualObj.GetActualInstanceValue())
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%v", obj)
|
||||
}
|
||||
var param,ok = obj.(MappedNullable)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
dataMap,err := param.ToMap()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("%v", dataMap[key])
|
||||
}
|
||||
|
||||
// parameterAddToHeaderOrQuery adds the provided object to the request header or url query
|
||||
// supporting deep object syntax
|
||||
func parameterAddToHeaderOrQuery(headerOrQueryParams interface{}, keyPrefix string, obj interface{}, style string, collectionType string) {
|
||||
var v = reflect.ValueOf(obj)
|
||||
var value = ""
|
||||
if v == reflect.ValueOf(nil) {
|
||||
value = "null"
|
||||
} else {
|
||||
switch v.Kind() {
|
||||
case reflect.Invalid:
|
||||
value = "invalid"
|
||||
|
||||
case reflect.Struct:
|
||||
if t,ok := obj.(MappedNullable); ok {
|
||||
dataMap,err := t.ToMap()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
parameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefix, dataMap, style, collectionType)
|
||||
return
|
||||
}
|
||||
if t, ok := obj.(time.Time); ok {
|
||||
parameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefix, t.Format(time.RFC3339Nano), style, collectionType)
|
||||
return
|
||||
}
|
||||
value = v.Type().String() + " value"
|
||||
case reflect.Slice:
|
||||
var indValue = reflect.ValueOf(obj)
|
||||
if indValue == reflect.ValueOf(nil) {
|
||||
return
|
||||
}
|
||||
var lenIndValue = indValue.Len()
|
||||
for i:=0;i<lenIndValue;i++ {
|
||||
var arrayValue = indValue.Index(i)
|
||||
var keyPrefixForCollectionType = keyPrefix
|
||||
if style == "deepObject" {
|
||||
keyPrefixForCollectionType = keyPrefix + "[" + strconv.Itoa(i) + "]"
|
||||
}
|
||||
parameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefixForCollectionType, arrayValue.Interface(), style, collectionType)
|
||||
}
|
||||
return
|
||||
|
||||
case reflect.Map:
|
||||
var indValue = reflect.ValueOf(obj)
|
||||
if indValue == reflect.ValueOf(nil) {
|
||||
return
|
||||
}
|
||||
iter := indValue.MapRange()
|
||||
for iter.Next() {
|
||||
k,v := iter.Key(), iter.Value()
|
||||
parameterAddToHeaderOrQuery(headerOrQueryParams, fmt.Sprintf("%s[%s]", keyPrefix, k.String()), v.Interface(), style, collectionType)
|
||||
}
|
||||
return
|
||||
|
||||
case reflect.Interface:
|
||||
fallthrough
|
||||
case reflect.Ptr:
|
||||
parameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefix, v.Elem().Interface(), style, collectionType)
|
||||
return
|
||||
|
||||
case reflect.Int, reflect.Int8, reflect.Int16,
|
||||
reflect.Int32, reflect.Int64:
|
||||
value = strconv.FormatInt(v.Int(), 10)
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16,
|
||||
reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
value = strconv.FormatUint(v.Uint(), 10)
|
||||
case reflect.Float32, reflect.Float64:
|
||||
value = strconv.FormatFloat(v.Float(), 'g', -1, 32)
|
||||
case reflect.Bool:
|
||||
value = strconv.FormatBool(v.Bool())
|
||||
case reflect.String:
|
||||
value = v.String()
|
||||
default:
|
||||
value = v.Type().String() + " value"
|
||||
}
|
||||
}
|
||||
|
||||
switch valuesMap := headerOrQueryParams.(type) {
|
||||
case url.Values:
|
||||
if collectionType == "csv" && valuesMap.Get(keyPrefix) != "" {
|
||||
valuesMap.Set(keyPrefix, valuesMap.Get(keyPrefix) + "," + value)
|
||||
} else {
|
||||
valuesMap.Add(keyPrefix, value)
|
||||
}
|
||||
break
|
||||
case map[string]string:
|
||||
valuesMap[keyPrefix] = value
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// helper for converting interface{} parameters to json strings
|
||||
func parameterToJson(obj interface{}) (string, error) {
|
||||
jsonBuf, err := json.Marshal(obj)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(jsonBuf), err
|
||||
}
|
||||
|
||||
// callAPI do the request.
|
||||
func (c *APIClient) callAPI(request *http.Request) (*http.Response, error) {
|
||||
if c.cfg.Debug {
|
||||
dump, err := httputil.DumpRequestOut(request, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Printf("\n%s\n", string(dump))
|
||||
}
|
||||
|
||||
resp, err := c.cfg.HTTPClient.Do(request)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
if c.cfg.Debug {
|
||||
dump, err := httputil.DumpResponse(resp, true)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
log.Printf("\n%s\n", string(dump))
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// Allow modification of underlying config for alternate implementations and testing
|
||||
// Caution: modifying the configuration while live can cause data races and potentially unwanted behavior
|
||||
func (c *APIClient) GetConfig() *Configuration {
|
||||
return c.cfg
|
||||
}
|
||||
|
||||
type formFile struct {
|
||||
fileBytes []byte
|
||||
fileName string
|
||||
formFileName string
|
||||
}
|
||||
|
||||
// prepareRequest build the request
|
||||
func (c *APIClient) prepareRequest(
|
||||
ctx context.Context,
|
||||
path string, method string,
|
||||
postBody interface{},
|
||||
headerParams map[string]string,
|
||||
queryParams url.Values,
|
||||
formParams url.Values,
|
||||
formFiles []formFile) (localVarRequest *http.Request, err error) {
|
||||
|
||||
var body *bytes.Buffer
|
||||
|
||||
// Detect postBody type and post.
|
||||
if postBody != nil {
|
||||
contentType := headerParams["Content-Type"]
|
||||
if contentType == "" {
|
||||
contentType = detectContentType(postBody)
|
||||
headerParams["Content-Type"] = contentType
|
||||
}
|
||||
|
||||
body, err = setBody(postBody, contentType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// add form parameters and file if available.
|
||||
if strings.HasPrefix(headerParams["Content-Type"], "multipart/form-data") && len(formParams) > 0 || (len(formFiles) > 0) {
|
||||
if body != nil {
|
||||
return nil, errors.New("Cannot specify postBody and multipart form at the same time.")
|
||||
}
|
||||
body = &bytes.Buffer{}
|
||||
w := multipart.NewWriter(body)
|
||||
|
||||
for k, v := range formParams {
|
||||
for _, iv := range v {
|
||||
if strings.HasPrefix(k, "@") { // file
|
||||
err = addFile(w, k[1:], iv)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else { // form value
|
||||
w.WriteField(k, iv)
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, formFile := range formFiles {
|
||||
if len(formFile.fileBytes) > 0 && formFile.fileName != "" {
|
||||
w.Boundary()
|
||||
part, err := w.CreateFormFile(formFile.formFileName, filepath.Base(formFile.fileName))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = part.Write(formFile.fileBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set the Boundary in the Content-Type
|
||||
headerParams["Content-Type"] = w.FormDataContentType()
|
||||
|
||||
// Set Content-Length
|
||||
headerParams["Content-Length"] = fmt.Sprintf("%d", body.Len())
|
||||
w.Close()
|
||||
}
|
||||
|
||||
if strings.HasPrefix(headerParams["Content-Type"], "application/x-www-form-urlencoded") && len(formParams) > 0 {
|
||||
if body != nil {
|
||||
return nil, errors.New("Cannot specify postBody and x-www-form-urlencoded form at the same time.")
|
||||
}
|
||||
body = &bytes.Buffer{}
|
||||
body.WriteString(formParams.Encode())
|
||||
// Set Content-Length
|
||||
headerParams["Content-Length"] = fmt.Sprintf("%d", body.Len())
|
||||
}
|
||||
|
||||
// Setup path and query parameters
|
||||
url, err := url.Parse(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Override request host, if applicable
|
||||
if c.cfg.Host != "" {
|
||||
url.Host = c.cfg.Host
|
||||
}
|
||||
|
||||
// Override request scheme, if applicable
|
||||
if c.cfg.Scheme != "" {
|
||||
url.Scheme = c.cfg.Scheme
|
||||
}
|
||||
|
||||
// Adding Query Param
|
||||
query := url.Query()
|
||||
for k, v := range queryParams {
|
||||
for _, iv := range v {
|
||||
query.Add(k, iv)
|
||||
}
|
||||
}
|
||||
|
||||
// Encode the parameters.
|
||||
url.RawQuery = queryParamSplit.ReplaceAllStringFunc(query.Encode(), func(s string) string {
|
||||
pieces := strings.Split(s, "=")
|
||||
pieces[0] = queryDescape.Replace(pieces[0])
|
||||
return strings.Join(pieces, "=")
|
||||
})
|
||||
|
||||
// Generate a new request
|
||||
if body != nil {
|
||||
localVarRequest, err = http.NewRequest(method, url.String(), body)
|
||||
} else {
|
||||
localVarRequest, err = http.NewRequest(method, url.String(), nil)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// add header parameters, if any
|
||||
if len(headerParams) > 0 {
|
||||
headers := http.Header{}
|
||||
for h, v := range headerParams {
|
||||
headers[h] = []string{v}
|
||||
}
|
||||
localVarRequest.Header = headers
|
||||
}
|
||||
|
||||
// Add the user agent to the request.
|
||||
localVarRequest.Header.Add("User-Agent", c.cfg.UserAgent)
|
||||
|
||||
if ctx != nil {
|
||||
// add context to the request
|
||||
localVarRequest = localVarRequest.WithContext(ctx)
|
||||
|
||||
// Walk through any authentication.
|
||||
|
||||
}
|
||||
|
||||
for header, value := range c.cfg.DefaultHeader {
|
||||
localVarRequest.Header.Add(header, value)
|
||||
}
|
||||
return localVarRequest, nil
|
||||
}
|
||||
|
||||
func (c *APIClient) decode(v interface{}, b []byte, contentType string) (err error) {
|
||||
if len(b) == 0 {
|
||||
return nil
|
||||
}
|
||||
if s, ok := v.(*string); ok {
|
||||
*s = string(b)
|
||||
return nil
|
||||
}
|
||||
if f, ok := v.(*os.File); ok {
|
||||
f, err = os.CreateTemp("", "HttpClientFile")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
_, err = f.Write(b)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
_, err = f.Seek(0, io.SeekStart)
|
||||
return
|
||||
}
|
||||
if f, ok := v.(**os.File); ok {
|
||||
*f, err = os.CreateTemp("", "HttpClientFile")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
_, err = (*f).Write(b)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
_, err = (*f).Seek(0, io.SeekStart)
|
||||
return
|
||||
}
|
||||
if XmlCheck.MatchString(contentType) {
|
||||
if err = xml.Unmarshal(b, v); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if JsonCheck.MatchString(contentType) {
|
||||
if actualObj, ok := v.(interface{ GetActualInstance() interface{} }); ok { // oneOf, anyOf schemas
|
||||
if unmarshalObj, ok := actualObj.(interface{ UnmarshalJSON([]byte) error }); ok { // make sure it has UnmarshalJSON defined
|
||||
if err = unmarshalObj.UnmarshalJSON(b); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return errors.New("Unknown type with GetActualInstance but no unmarshalObj.UnmarshalJSON defined")
|
||||
}
|
||||
} else if err = json.Unmarshal(b, v); err != nil { // simple model
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return errors.New("undefined response type")
|
||||
}
|
||||
|
||||
// Add a file to the multipart request
|
||||
func addFile(w *multipart.Writer, fieldName, path string) error {
|
||||
file, err := os.Open(filepath.Clean(path))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = file.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
part, err := w.CreateFormFile(fieldName, filepath.Base(path))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = io.Copy(part, file)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Set request body from an interface{}
|
||||
func setBody(body interface{}, contentType string) (bodyBuf *bytes.Buffer, err error) {
|
||||
if bodyBuf == nil {
|
||||
bodyBuf = &bytes.Buffer{}
|
||||
}
|
||||
|
||||
if reader, ok := body.(io.Reader); ok {
|
||||
_, err = bodyBuf.ReadFrom(reader)
|
||||
} else if fp, ok := body.(*os.File); ok {
|
||||
_, err = bodyBuf.ReadFrom(fp)
|
||||
} else if b, ok := body.([]byte); ok {
|
||||
_, err = bodyBuf.Write(b)
|
||||
} else if s, ok := body.(string); ok {
|
||||
_, err = bodyBuf.WriteString(s)
|
||||
} else if s, ok := body.(*string); ok {
|
||||
_, err = bodyBuf.WriteString(*s)
|
||||
} else if JsonCheck.MatchString(contentType) {
|
||||
err = json.NewEncoder(bodyBuf).Encode(body)
|
||||
} else if XmlCheck.MatchString(contentType) {
|
||||
var bs []byte
|
||||
bs, err = xml.Marshal(body)
|
||||
if err == nil {
|
||||
bodyBuf.Write(bs)
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if bodyBuf.Len() == 0 {
|
||||
err = fmt.Errorf("invalid body type %s\n", contentType)
|
||||
return nil, err
|
||||
}
|
||||
return bodyBuf, nil
|
||||
}
|
||||
|
||||
// detectContentType method is used to figure out `Request.Body` content type for request header
|
||||
func detectContentType(body interface{}) string {
|
||||
contentType := "text/plain; charset=utf-8"
|
||||
kind := reflect.TypeOf(body).Kind()
|
||||
|
||||
switch kind {
|
||||
case reflect.Struct, reflect.Map, reflect.Ptr:
|
||||
contentType = "application/json; charset=utf-8"
|
||||
case reflect.String:
|
||||
contentType = "text/plain; charset=utf-8"
|
||||
default:
|
||||
if b, ok := body.([]byte); ok {
|
||||
contentType = http.DetectContentType(b)
|
||||
} else if kind == reflect.Slice {
|
||||
contentType = "application/json; charset=utf-8"
|
||||
}
|
||||
}
|
||||
|
||||
return contentType
|
||||
}
|
||||
|
||||
// Ripped from https://github.com/gregjones/httpcache/blob/master/httpcache.go
|
||||
type cacheControl map[string]string
|
||||
|
||||
func parseCacheControl(headers http.Header) cacheControl {
|
||||
cc := cacheControl{}
|
||||
ccHeader := headers.Get("Cache-Control")
|
||||
for _, part := range strings.Split(ccHeader, ",") {
|
||||
part = strings.Trim(part, " ")
|
||||
if part == "" {
|
||||
continue
|
||||
}
|
||||
if strings.ContainsRune(part, '=') {
|
||||
keyval := strings.Split(part, "=")
|
||||
cc[strings.Trim(keyval[0], " ")] = strings.Trim(keyval[1], ",")
|
||||
} else {
|
||||
cc[part] = ""
|
||||
}
|
||||
}
|
||||
return cc
|
||||
}
|
||||
|
||||
// CacheExpires helper function to determine remaining time before repeating a request.
|
||||
func CacheExpires(r *http.Response) time.Time {
|
||||
// Figure out when the cache expires.
|
||||
var expires time.Time
|
||||
now, err := time.Parse(time.RFC1123, r.Header.Get("date"))
|
||||
if err != nil {
|
||||
return time.Now()
|
||||
}
|
||||
respCacheControl := parseCacheControl(r.Header)
|
||||
|
||||
if maxAge, ok := respCacheControl["max-age"]; ok {
|
||||
lifetime, err := time.ParseDuration(maxAge + "s")
|
||||
if err != nil {
|
||||
expires = now
|
||||
} else {
|
||||
expires = now.Add(lifetime)
|
||||
}
|
||||
} else {
|
||||
expiresHeader := r.Header.Get("Expires")
|
||||
if expiresHeader != "" {
|
||||
expires, err = time.Parse(time.RFC1123, expiresHeader)
|
||||
if err != nil {
|
||||
expires = now
|
||||
}
|
||||
}
|
||||
}
|
||||
return expires
|
||||
}
|
||||
|
||||
func strlen(s string) int {
|
||||
return utf8.RuneCountInString(s)
|
||||
}
|
||||
|
||||
// GenericOpenAPIError Provides access to the body, error and model on returned errors.
|
||||
type GenericOpenAPIError struct {
|
||||
body []byte
|
||||
error string
|
||||
model interface{}
|
||||
}
|
||||
|
||||
// Error returns non-empty string if there was an error.
|
||||
func (e GenericOpenAPIError) Error() string {
|
||||
return e.error
|
||||
}
|
||||
|
||||
// Body returns the raw bytes of the response
|
||||
func (e GenericOpenAPIError) Body() []byte {
|
||||
return e.body
|
||||
}
|
||||
|
||||
// Model returns the unpacked model of the error
|
||||
func (e GenericOpenAPIError) Model() interface{} {
|
||||
return e.model
|
||||
}
|
||||
|
||||
// format error message using title and detail when model implements rfc7807
|
||||
func formatErrorMessage(status string, v interface{}) string {
|
||||
str := ""
|
||||
metaValue := reflect.ValueOf(v).Elem()
|
||||
|
||||
if metaValue.Kind() == reflect.Struct {
|
||||
field := metaValue.FieldByName("Title")
|
||||
if field != (reflect.Value{}) {
|
||||
str = fmt.Sprintf("%s", field.Interface())
|
||||
}
|
||||
|
||||
field = metaValue.FieldByName("Detail")
|
||||
if field != (reflect.Value{}) {
|
||||
str = fmt.Sprintf("%s (%s)", str, field.Interface())
|
||||
}
|
||||
}
|
||||
|
||||
return strings.TrimSpace(fmt.Sprintf("%s %s", status, str))
|
||||
}
|
||||