Compare commits

..

56 commits

Author SHA1 Message Date
Snider
1674deb771
Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-05 13:27:26 +01:00
Snider
1f3c167427
Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-05 13:27:04 +01:00
Snider
6bc491e7e2
Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-05 13:26:24 +01:00
Snider
7bdc12bcff
Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-05 13:26:10 +01:00
Snider
f93ab75384 Update action.yml 2025-10-05 13:23:39 +01:00
Snider
9507316f69 Update Dockerfile 2025-10-05 13:21:01 +01:00
Snider
9fe542bdd1 merge prep 2025-10-05 13:05:51 +01:00
Snider
6a8cd52802 Add new seed node and improve build scripts
Added a new hardcoded seed node (34.13.212.174) for both mainnet and testnet in net_node.inl. Updated Makefile to separate dependency installation into a new 'build-deps' target and improved configure messaging. CMakeLists.txt now prints the CMake version being used. Also commented out a connection close call after handshake for further review.
2025-10-05 12:45:46 +01:00
Snider
391f9a5a63 Update address prefix macros and enable connection close
Uncommented the call to close the connection after handshake in net_node.inl to ensure proper connection handling.
2025-10-03 20:23:19 +01:00
Snider
d75019350e Add docker-compose and update lthn-chain Dockerfile
Introduces a docker-compose.yml for the lethean-chain service with build arguments and volume mapping. Updates the lthn-chain Dockerfile to expose required ports and modifies the entrypoint to include data directory and additional flags.
2025-10-02 19:22:10 +01:00
Snider
d258daca4c Update build-windows-intel.yml 2025-10-02 14:05:05 +01:00
Snider
34e3224b72 Update build-windows-intel.yml 2025-10-02 13:52:13 +01:00
Snider
e2b3ed9825 Update build-windows-intel.yml 2025-10-02 13:42:00 +01:00
Snider
764fae7977 Update build-windows-intel.yml 2025-10-02 13:24:17 +01:00
Snider
bf59665902 Update build-windows-intel.yml 2025-10-02 13:23:33 +01:00
Snider
34835fdbc7 Update build-windows-intel.yml 2025-10-02 13:02:22 +01:00
Snider
031856ec0a Update build-windows-intel.yml 2025-10-02 12:49:43 +01:00
Snider
26fe9eb243 Update Makefile 2025-10-02 12:43:22 +01:00
Snider
426214c749 Update build-windows-intel.yml 2025-10-02 12:34:52 +01:00
Snider
1ce5ba1d92 Update build-windows-intel.yml 2025-10-02 12:26:02 +01:00
Snider
30f17eed8f Update MSVC toolset and comment out CPack config options
Set the MSVC toolset to 14.3 in the Windows workflow. Commented out several CPack configuration options in CPackConfig.cmake, including install prefixes and package generator settings for all platforms, likely to disable or defer packaging configuration.
2025-10-02 12:21:46 +01:00
Snider
e47280554d Update build-windows-intel.yml 2025-10-02 12:16:11 +01:00
Snider
f4b33fce19 Update build-windows-intel.yml 2025-10-02 12:04:50 +01:00
Snider
aed34e103d Update build-windows-intel.yml 2025-10-02 12:01:59 +01:00
Snider
bcb5f366e5 Update MSVC setup and set build type to Release
Adds TheMrMilchmann/setup-msvc-dev action to the Windows workflow with toolset 17.11.5 and x64 architecture. Also sets build_type to Release in the MSVC 194 x86_64 CMake profile.
2025-10-02 11:57:28 +01:00
Snider
747853297e Fix Windows build by clearing CFLAGS/CXXFLAGS in Makefile
Adds logic to the Makefile to clear CFLAGS and CXXFLAGS when running Conan on Windows, addressing issues caused by problematic environment variables. This ensures consistent build behavior across platforms.
2025-10-02 11:40:00 +01:00
Snider
299cdf9521 Update Makefile 2025-10-02 01:13:29 +01:00
Snider
ec7951afd5 Update Docker build env and MSVC C++ standard
Set DOCKER_BUILD_SUMMARY and DOCKER_BUILD_RECORD_UPLOAD to false in the GitHub Actions workflow to control Docker build output. Update MSVC profile to use C++17 instead of C++14 for improved language features and compatibility.
2025-10-02 00:59:47 +01:00
Snider
9290ec794f Update build process and Dockerfile dependencies
Refactored Makefile to use $(BUILD_FOLDER) and updated Conan and CMake commands for improved flexibility. Dockerfile now installs additional mkdocs plugins and uses 'make build' instead of 'make release' for building, aligning with updated Makefile targets.
2025-10-02 00:49:42 +01:00
Snider
32e31bd11d Update Makefile 2025-10-02 00:31:50 +01:00
Snider
e83edb7661 Refactor Docker build workflow and update build configs
Simplifies the GitHub Actions Docker build workflow by removing matrix builds and standardizing steps. Updates the MSVC CMake profile to use C++14 instead of C++17. Removes an unused make configure step from the Dockerfile.
2025-10-02 00:27:45 +01:00
Snider
973baa12c0 Update CI workflows and Makefile for improved builds
Refactors the Docker build workflow to use a matrix for multi-arch builds, updates build arguments, and improves Docker image tagging. Disables Conan package caching on Linux ARM64 and macOS Intel workflows. Changes the Windows build to use the 'msvc-194-x86_64' target and updates artifact paths accordingly. Enhances the Makefile to pass additional CMake variables and run cpack after building.
2025-10-02 00:08:44 +01:00
Snider
370ec64a53 Disable Conan package caching in CI workflows
Set cache_packages to false in build workflows for Linux, macOS ARM64, and Windows Intel. This change ensures Conan does not use cached packages during CI builds, which may help avoid issues with stale or incompatible dependencies.
2025-10-01 23:57:05 +01:00
Snider
eadf6ebfec Refactor CI workflows and build process
Enable Conan package caching and remove redundant doc build steps from all platform workflows. Update Makefile to ensure docs are built as part of the release target. Clean up MSVC runtime variable logic in conanfile.py and adjust Docker workflow runner and build args.
2025-10-01 23:52:43 +01:00
Snider
eba315040c Update build-docker.yml 2025-10-01 23:35:46 +01:00
Snider
c8b2735cff Refactor Docker build and Makefile for improved CI/CD
Streamlines Docker build workflow by introducing a builder target and registry-based build cache in GitHub Actions. Refactors the Makefile to improve static/dynamic build flag handling, adds MSVC support, and separates configure/build steps. Updates Dockerfile to use new Makefile targets, simplifies build context handling, and fixes artifact copying. Removes redundant Docker build targets from the Makefile and enhances Conan MSVC runtime configuration.
2025-10-01 23:33:44 +01:00
Snider
1f90b3350e Update Makefile 2025-10-01 22:34:03 +01:00
Snider
9389b67880 Add STATIC build option and update CI workflows
Introduces a STATIC flag to the Makefile for controlling static builds, passing the appropriate Conan and CMake options. Updates the Windows CI workflow to use STATIC=1 for release builds and adjusts Docker build arguments for consistency.
2025-10-01 22:28:07 +01:00
Snider
87605db373 Update Docker build workflow and CPack config
Refactored the Docker build workflow to use a single job with multi-platform support and removed the manifest creation step. Cleaned up the macOS build workflow by removing unnecessary Homebrew installs. Updated CPackConfig.cmake to set the install prefix by default and fixed the documentation install destination to use PROJECT_NAME.
2025-10-01 21:55:16 +01:00
Snider
235b0cb41b Add documentation build steps to CI workflows
Introduces a reusable GitHub Action for building documentation and updates all platform build workflows to install documentation dependencies and run 'make docs'. This ensures documentation is built and available as part of the CI process across Linux, macOS, and Windows. Also updates the docs workflow to adjust pip dependencies.
2025-10-01 21:10:21 +01:00
Snider
c70b383ce6 Update build-docker.yml 2025-10-01 20:50:30 +01:00
Snider
d11cee2229 Update build-docker.yml 2025-10-01 20:45:28 +01:00
Snider
56bb2a1abf Update build-docker.yml 2025-10-01 20:29:12 +01:00
Snider
f9f249be28 Update build-docker.yml 2025-10-01 20:26:45 +01:00
Snider
38d6a183d4 Update build-docker.yml 2025-10-01 20:25:45 +01:00
Snider
79034cbbbf Update build-docker.yml 2025-10-01 20:20:24 +01:00
Snider
6987a33f83 Add multi-arch Docker build and manifest to CI workflow
Refactors the build-docker GitHub Actions workflow to build and push Docker images for both amd64 and arm64 architectures using a matrix strategy. Adds a manifest job to create and push a multi-arch manifest for the lthn/chain image, supporting both 'testnet' and 'latest' tags based on input.
2025-10-01 20:19:06 +01:00
Snider
0089a308fd Update conanfile.py 2025-10-01 18:26:40 +01:00
Snider
34a5d6bea1 Update CMake toolchain file path in Makefile
Changed the CMake toolchain file path in the 'configure' target to use 'build/release/generators/conan_toolchain.cmake' instead of 'build/release/conan_toolchain.cmake' to match the new Conan output structure.
2025-10-01 18:23:43 +01:00
Snider
f5b66b4fd9 Update artifact tag suffix and build folder name
Appends 'alpha' to artifact tag suffix for pull requests in the GitHub Action and changes the build folder name from 'build/Release' to 'build/release' in the Makefile for consistency.
2025-10-01 18:19:49 +01:00
Snider
ba3296cec6 Customize build folder layout based on compiler
Updated the layout method to set different build and generator folder paths depending on whether the compiler is MSVC or not. This improves compatibility with multi-configuration generators on MSVC and single-configuration generators on other platforms.
2025-10-01 18:15:27 +01:00
Snider
89c6833845 Switch to conanfile.py, update build scripts and genesis data
Replaces conanfile.txt with conanfile.py for improved Conan package management. Updates Makefile and CMakeLists.txt to align with new Conan workflow and build folder structure. Increases premine amount in default.cmake and updates genesis transaction data. Comments out a hardcoded seed node in net_node.inl.
2025-10-01 18:04:44 +01:00
Snider
edbbf2888b config updates 2025-10-01 14:20:02 +01:00
Snider
336de95f46 Update _on-push.yml 2025-10-01 13:58:57 +01:00
Snider
0fad340a06 Update _on-pr-fast.yml 2025-10-01 13:58:23 +01:00
Snider
cf14549cee Update build process and genesis data for static builds
Refactors Makefile and Dockerfile to support static builds via a STATIC variable, simplifying static build targets. Updates genesis transaction data and public key in generated files. Improves GitHub Actions artifact upload by refining tag and prerelease logic.
2025-10-01 13:57:08 +01:00
669 changed files with 2655 additions and 111175 deletions

@ -1 +0,0 @@
Subproject commit 9c9346d5494688a78ea573f3bc0547ad12b9be2a

View file

@ -1,83 +0,0 @@
# Lethean Blockchain Build Configuration
# Used by: core compile
version: 1
project:
name: blockchain
type: cpp
description: "Lethean Blockchain - SASE infrastructure chain"
version: "6.0.1"
cpp:
standard: 17
build_type: Release
static: false
conan:
version: "2.21.0"
requires:
- zlib/1.3.1
- boost/1.85.0
- openssl/3.2.0
- miniupnpc/2.2.5
- jwt-cpp/0.7.1
- oatpp/1.3.0.latest
- oatpp-swagger/1.3.0.latest
tool_requires:
- cmake/3.31.9
options:
boost/*:without_test: true
registry:
url: http://forge.snider.dev:4000/api/packages/host-uk/conan
remote: conan_build
cmake:
minimum_version: "3.16"
variables:
USE_CCACHE: "ON"
options:
testnet: false
targets:
- os: linux
arch: x86_64
profile: gcc-linux-x86_64
- os: linux
arch: arm64
profile: gcc-linux-armv8
- os: darwin
arch: arm64
profile: apple-clang-armv8
- os: darwin
arch: x86_64
profile: apple-clang-x86_64
- os: windows
arch: x86_64
profile: msvc-194-x86_64
package:
generators:
- TGZ
- ZIP
- NSIS
- DEB
- RPM
vendor: Lethean
contact: support@lt.hn
website: https://lt.hn
docker:
dockerfile: utils/docker/lthn-chain/Dockerfile
image: lthn/chain
platforms:
- linux/amd64
tags:
- testnet
- "{{.Version}}"
build_args:
BUILD_THREADS: auto
BUILD_TESTNET: "1"
BUILD_STATIC: "0"
BUILD_TYPE: Release

View file

@ -1,234 +0,0 @@
name: Build & Release
on:
workflow_dispatch:
push:
branches:
- dev
- main
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
FORGEJO_URL: ${{ github.server_url }}
jobs:
# ──────────────────────────────────────────────
# Linux x86_64 — native build on snider-linux
# ──────────────────────────────────────────────
build-linux:
name: Linux x86_64
runs-on: linux-native
env:
CPU_CORES: "24"
steps:
- name: Checkout
uses: https://code.forgejo.org/actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
submodules: false
- name: Init submodules
run: |
git config --global url."${{ env.FORGEJO_URL }}/".insteadOf "http://forge.snider.dev:4000/"
git -c http.extraHeader="Authorization: token ${{ secrets.RELEASE_TOKEN }}" submodule update --init --recursive
git submodule foreach --recursive 'git fetch --tags origin 2>/dev/null || true'
- name: Build dependencies
run: |
make build-deps \
CPU_CORES=${{ env.CPU_CORES }} \
CONAN_URL=${{ env.FORGEJO_URL }}/api/packages/host-uk/conan \
CONAN_USER=claude \
CONAN_PASSWORD=${{ secrets.RELEASE_TOKEN }}
- name: Compile
run: |
make ${{ github.ref_name == 'main' && 'mainnet' || 'testnet' }} \
CPU_CORES=${{ env.CPU_CORES }} \
CONAN_URL=${{ env.FORGEJO_URL }}/api/packages/host-uk/conan \
CONAN_USER=claude \
CONAN_PASSWORD=${{ secrets.RELEASE_TOKEN }}
- name: Upload artifacts
uses: https://code.forgejo.org/forgejo/upload-artifact@v4
with:
name: linux-x86_64
path: build/packages/lethean-*
retention-days: 7
# ──────────────────────────────────────────────
# macOS ARM64 — native build on M3 Ultra
# ──────────────────────────────────────────────
build-macos:
name: macOS ARM64
runs-on: macos-native
env:
CPU_CORES: "24"
steps:
- name: Checkout
uses: https://code.forgejo.org/actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
submodules: false
- name: Init submodules
run: |
git config --global url."${{ env.FORGEJO_URL }}/".insteadOf "http://forge.snider.dev:4000/"
git -c http.extraHeader="Authorization: token ${{ secrets.RELEASE_TOKEN }}" submodule update --init --recursive
git submodule foreach --recursive 'git fetch --tags origin 2>/dev/null || true'
- name: Build dependencies
run: |
export PATH="/opt/homebrew/bin:$PATH"
make build-deps \
CPU_CORES=${{ env.CPU_CORES }} \
CONAN_URL=${{ env.FORGEJO_URL }}/api/packages/host-uk/conan \
CONAN_USER=claude \
CONAN_PASSWORD=${{ secrets.RELEASE_TOKEN }}
- name: Compile
run: |
export PATH="/opt/homebrew/bin:$PATH"
make ${{ github.ref_name == 'main' && 'mainnet' || 'testnet' }} \
CPU_CORES=${{ env.CPU_CORES }} \
CONAN_URL=${{ env.FORGEJO_URL }}/api/packages/host-uk/conan \
CONAN_USER=claude \
CONAN_PASSWORD=${{ secrets.RELEASE_TOKEN }}
- name: Upload artifacts
uses: https://code.forgejo.org/forgejo/upload-artifact@v4
with:
name: macos-arm64
path: build/packages/lethean-*
retention-days: 7
# ──────────────────────────────────────────────
# Aggregate artifacts and create release
# ──────────────────────────────────────────────
release:
name: Create Release
needs: [build-linux, build-macos]
runs-on: linux-native
steps:
- name: Checkout
uses: https://code.forgejo.org/actions/checkout@v4
with:
fetch-depth: 1
submodules: false
- name: Download Linux artifacts
uses: https://code.forgejo.org/forgejo/download-artifact@v4
with:
name: linux-x86_64
path: artifacts/linux
- name: Download macOS artifacts
uses: https://code.forgejo.org/forgejo/download-artifact@v4
with:
name: macos-arm64
path: artifacts/macos
- name: List artifacts
run: find artifacts/ -type f | sort
- name: Compute release tag
id: release
run: |
VERSION=$(grep '^BUILD_VERSION:=' Makefile | cut -d'=' -f2)
if [ "${{ github.ref_name }}" = "main" ]; then
TAG="v${VERSION}+${{ github.run_number }}"
PRERELEASE=false
TITLE="v${VERSION} (build ${{ github.run_number }})"
else
TAG="v${VERSION}-beta+${{ github.run_number }}"
PRERELEASE=true
TITLE="v${VERSION}-beta (build ${{ github.run_number }})"
fi
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
echo "prerelease=${PRERELEASE}" >> "$GITHUB_OUTPUT"
echo "title=${TITLE}" >> "$GITHUB_OUTPUT"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
- name: Create release
id: create_release
run: |
RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \
"${{ env.FORGEJO_URL }}/api/v1/repos/${{ github.repository }}/releases" \
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" \
-H "Content-Type: application/json" \
-d "{
\"tag_name\": \"${{ steps.release.outputs.tag }}\",
\"target_commitish\": \"${{ github.sha }}\",
\"name\": \"${{ steps.release.outputs.title }}\",
\"body\": \"Automated build from \`${{ github.ref_name }}\` branch (run #${{ github.run_number }})\n\n## Platforms\n- Linux x86_64\n- macOS ARM64 (Apple Silicon)\",
\"draft\": false,
\"prerelease\": ${{ steps.release.outputs.prerelease }}
}")
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
BODY=$(echo "$RESPONSE" | sed '$d')
if [ "$HTTP_CODE" -ge 400 ]; then
echo "Failed to create release (HTTP ${HTTP_CODE}):"
echo "$BODY"
exit 1
fi
RELEASE_ID=$(echo "$BODY" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
echo "id=${RELEASE_ID}" >> "$GITHUB_OUTPUT"
echo "Created release ID: ${RELEASE_ID}"
- name: Upload release assets
run: |
for dir in artifacts/linux artifacts/macos; do
for file in "$dir"/lethean-*; do
[ -f "$file" ] || continue
FILENAME=$(basename "$file")
echo "Uploading: ${FILENAME}"
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST \
"${{ env.FORGEJO_URL }}/api/v1/repos/${{ github.repository }}/releases/${{ steps.create_release.outputs.id }}/assets?name=${FILENAME}" \
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" \
-H "Content-Type: application/octet-stream" \
--data-binary "@${file}")
if [ "$HTTP_CODE" -ge 400 ]; then
echo "Failed to upload ${FILENAME} (HTTP ${HTTP_CODE})"
exit 1
fi
echo "Uploaded ${FILENAME} (HTTP ${HTTP_CODE})"
done
done
- name: Prune old releases
run: |
TAG_PREFIX="${{ github.ref_name == 'main' && 'v6' || 'v6.*-beta' }}"
CURRENT_ID="${{ steps.create_release.outputs.id }}"
echo "Keeping release ${CURRENT_ID}, pruning older ${TAG_PREFIX} releases..."
PAGE=1
while true; do
RELEASES=$(curl -s "${{ env.FORGEJO_URL }}/api/v1/repos/${{ github.repository }}/releases?limit=50&page=${PAGE}" \
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}")
COUNT=$(echo "$RELEASES" | python3 -c "import sys,json; print(len(json.load(sys.stdin)))" 2>/dev/null || echo 0)
[ "$COUNT" = "0" ] && break
echo "$RELEASES" | python3 -c "
import sys, json, fnmatch
for r in json.load(sys.stdin):
rid = r['id']
tag = r['tag_name']
if rid == ${CURRENT_ID}:
continue
if fnmatch.fnmatch(tag, '${TAG_PREFIX}*'):
print(f'{rid} {tag}')
" | while read -r RID RTAG; do
echo "Deleting release ${RTAG} (id=${RID})"
curl -s -o /dev/null -X DELETE \
"${{ env.FORGEJO_URL }}/api/v1/repos/${{ github.repository }}/releases/${RID}" \
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}"
curl -s -o /dev/null -X DELETE \
"${{ env.FORGEJO_URL }}/api/v1/repos/${{ github.repository }}/tags/${RTAG}" \
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}"
done
PAGE=$((PAGE + 1))
done
echo "Prune complete"

5
.gitattributes vendored
View file

@ -1,5 +1,2 @@
.git* export-ignore .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

View file

@ -38,7 +38,7 @@ runs:
echo "version=${VERSION}" >> "$GITHUB_OUTPUT" echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
if [ "${{ github.event_name }}" == "pull_request" ]; then if [ "${{ github.event_name }}" == "pull_request" ]; then
TAG_SUFFIX="-alpha.${{ github.event.number }}" TAG_SUFFIX="-${{ github.event.number }}alpha"
PRERELEASE=true PRERELEASE=true
elif [ "${{ inputs.chain-network }}" != "mainnet" ]; then elif [ "${{ inputs.chain-network }}" != "mainnet" ]; then
TAG_SUFFIX="-beta" TAG_SUFFIX="-beta"
@ -86,5 +86,5 @@ runs:
with: with:
tag_name: ${{ steps.asset.outputs.tag_name }} tag_name: ${{ steps.asset.outputs.tag_name }}
prerelease: ${{ steps.asset.outputs.prerelease }} prerelease: ${{ steps.asset.outputs.prerelease }}
files: ${{ inputs.asset-directory }}/* files: ${{ inputs.asset-directory }}/lethean-*
target_commitish: ${{ github.sha }} target_commitish: ${{ github.sha }}

28
.github/workflows/_on-pr-fast.yml vendored Normal file
View file

@ -0,0 +1,28 @@
name: PR Fast
permissions:
contents: write
on:
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
pull_request:
types:
- opened
- synchronize
- reopened
branches:
- dev
- main
- dev-*
paths-ignore:
- '**.md'
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
build-macos-arm64:
name: Compile
uses: ./.github/workflows/build-macos-arm64.yml
with:
chain-network: ${{ github.ref_name == 'main' && 'mainnet' || 'testnet' }}

View file

@ -7,10 +7,7 @@ on:
pull_request_review: pull_request_review:
pull_request: pull_request:
types: types:
- opened - review_requested
- synchronize
- reopened
- ready_for_review
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
@ -18,39 +15,50 @@ concurrency:
jobs: jobs:
build-linux-intel: build-linux-intel:
name: Linux name: Chain
if: ${{!github.event.pull_request.draft}} if: |
(github.actor == 'Snider' && github.event.pull_request.user.login == 'Snider') ||
(github.event.review.state == 'approved' && !github.event.pull_request.draft)
uses: ./.github/workflows/build-linux-intel.yml uses: ./.github/workflows/build-linux-intel.yml
secrets: inherit secrets: inherit
with: with:
chain-network: ${{ github.ref_name == 'main' && 'mainnet' || 'testnet' }} chain-network: ${{ github.ref_name == 'main' && 'mainnet' || 'testnet' }}
build-linux-arm: build-linux-arm:
name: Linux name: Chain
if: ${{!github.event.pull_request.draft}} if: |
(github.actor == 'Snider' && github.event.pull_request.user.login == 'Snider') ||
(github.event.review.state == 'approved' && !github.event.pull_request.draft)
uses: ./.github/workflows/build-linux-arm64.yml uses: ./.github/workflows/build-linux-arm64.yml
secrets: inherit secrets: inherit
with: with:
chain-network: ${{ github.ref_name == 'main' && 'mainnet' || 'testnet' }} chain-network: ${{ github.ref_name == 'main' && 'mainnet' || 'testnet' }}
build-windows-intel: build-windows-intel:
name: Windows name: Chain
if: ${{!github.event.pull_request.draft}} if: |
(github.actor == 'Snider' && github.event.pull_request.user.login == 'Snider') ||
(github.event.review.state == 'approved' && !github.event.pull_request.draft)
uses: ./.github/workflows/build-windows-intel.yml uses: ./.github/workflows/build-windows-intel.yml
secrets: inherit secrets: inherit
with: with:
chain-network: ${{ github.ref_name == 'main' && 'mainnet' || 'testnet' }} chain-network: ${{ github.ref_name == 'main' && 'mainnet' || 'testnet' }}
build-macos-arm64: build-macos-arm64:
name: MacOS name: Chain
if: |
(github.actor == 'Snider' && github.event.pull_request.user.login == 'Snider') ||
(github.event.review.state == 'approved' && !github.event.pull_request.draft)
uses: ./.github/workflows/build-macos-arm64.yml uses: ./.github/workflows/build-macos-arm64.yml
secrets: inherit secrets: inherit
with: with:
chain-network: ${{ github.ref_name == 'main' && 'mainnet' || 'testnet' }} chain-network: ${{ github.ref_name == 'main' && 'mainnet' || 'testnet' }}
build-macos-intel: build-macos-intel:
name: MacOS name: Chain
if: ${{!github.event.pull_request.draft}} if: |
(github.actor == 'Snider' && github.event.pull_request.user.login == 'Snider') ||
(github.event.review.state == 'approved' && !github.event.pull_request.draft)
uses: ./.github/workflows/build-macos-intel.yml uses: ./.github/workflows/build-macos-intel.yml
secrets: inherit secrets: inherit
with: with:
@ -58,7 +66,9 @@ jobs:
build-docker: build-docker:
name: Docker name: Docker
if: ${{!github.event.pull_request.draft}} if: |
(github.actor == 'Snider' && github.event.pull_request.user.login == 'Snider') ||
(github.event.review.state == 'approved' && !github.event.pull_request.draft)
uses: ./.github/workflows/build-docker.yml uses: ./.github/workflows/build-docker.yml
secrets: inherit secrets: inherit
with: with:
@ -66,5 +76,7 @@ jobs:
build-docs: build-docs:
name: Docs name: Docs
if: ${{!github.event.pull_request.draft}} if: |
(github.actor == 'Snider' && github.event.pull_request.user.login == 'Snider') ||
(github.event.review.state == 'approved' && !github.event.pull_request.draft)
uses: ./.github/workflows/build-docs.yml uses: ./.github/workflows/build-docs.yml

View file

@ -16,46 +16,41 @@ concurrency:
jobs: jobs:
build-linux-intel: build-linux-intel:
name: Linux name: Chain
uses: ./.github/workflows/build-linux-intel.yml uses: ./.github/workflows/build-linux-intel.yml
secrets: inherit
with: with:
chain-network: ${{ github.ref_name == 'main' && 'mainnet' || 'testnet' }} chain-network: ${{ github.ref_name == 'main' && 'mainnet' || 'testnet' }}
build-linux-arm: build-linux-arm:
name: Linux name: Chain
uses: ./.github/workflows/build-linux-arm64.yml uses: ./.github/workflows/build-linux-arm64.yml
secrets: inherit
with: with:
chain-network: ${{ github.ref_name == 'main' && 'mainnet' || 'testnet' }} chain-network: ${{ github.ref_name == 'main' && 'mainnet' || 'testnet' }}
build-windows-intel: build-windows-intel:
name: Windows name: Chain
uses: ./.github/workflows/build-windows-intel.yml uses: ./.github/workflows/build-windows-intel.yml
secrets: inherit
with: with:
chain-network: ${{ github.ref_name == 'main' && 'mainnet' || 'testnet' }} chain-network: ${{ github.ref_name == 'main' && 'mainnet' || 'testnet' }}
build-macos-arm64: build-macos-arm64:
name: MacOS name: Chain
uses: ./.github/workflows/build-macos-arm64.yml uses: ./.github/workflows/build-macos-arm64.yml
secrets: inherit
with: with:
chain-network: ${{ github.ref_name == 'main' && 'mainnet' || 'testnet' }} chain-network: ${{ github.ref_name == 'main' && 'mainnet' || 'testnet' }}
build-macos-intel: build-macos-intel:
name: MacOS name: Chain
uses: ./.github/workflows/build-macos-intel.yml uses: ./.github/workflows/build-macos-intel.yml
secrets: inherit
with: with:
chain-network: ${{ github.ref_name == 'main' && 'mainnet' || 'testnet' }} chain-network: ${{ github.ref_name == 'main' && 'mainnet' || 'testnet' }}
build-docker: build-docker:
name: Docker name: Docker
uses: ./.github/workflows/build-docker.yml uses: ./.github/workflows/build-docker.yml
secrets: inherit
with: with:
chain-network: ${{ github.ref_name == 'main' && 'mainnet' || 'testnet' }} chain-network: ${{ github.ref_name == 'main' && 'mainnet' || 'testnet' }}
secrets: inherit
build-docs: build-docs:
name: Docs name: Docs

View file

@ -43,7 +43,7 @@ jobs:
DOCKER_BUILD_SUMMARY: false DOCKER_BUILD_SUMMARY: false
DOCKER_BUILD_RECORD_UPLOAD: false DOCKER_BUILD_RECORD_UPLOAD: false
with: with:
file: utils/docker/lthn-chain/Dockerfile file: utils/docker/images/lthn-chain/Dockerfile
context: ${{ github.workspace }} context: ${{ github.workspace }}
push: true push: true
build-args: | build-args: |

View file

@ -1,6 +1,6 @@
name: docs name: docs
permissions: permissions:
contents: write contents: read
on: on:
workflow_call: workflow_call:
@ -17,13 +17,16 @@ jobs:
with: with:
python-version: 3.x python-version: 3.x
- name: Cache SDK Folder - name: Install Conan
uses: actions/cache@v4 uses: conan-io/setup-conan@v1
with: with:
path: | home: ${{ github.workspace }}/build/sdk
${{ github.workspace }}/build/sdk cache_packages: true
${{ github.workspace }}/build/bin
key: ${{ runner.os }}-${{ runner.arch }}-sdk - uses: actions/cache@v4
with:
key: ${{ github.ref }}
path: .cache
- run: sudo apt-get install -y libcairo2-dev libfreetype6-dev libffi-dev libjpeg-dev libpng-dev libz-dev pngquant - run: sudo apt-get install -y libcairo2-dev libfreetype6-dev libffi-dev libjpeg-dev libpng-dev libz-dev pngquant
- run: pip install mkdocs-git-revision-date-localized-plugin mkdocs-git-committers-plugin-2 mkdocs-git-authors-plugin mkdocs-material[imaging] - run: pip install mkdocs-git-revision-date-localized-plugin mkdocs-git-committers-plugin-2 mkdocs-git-authors-plugin mkdocs-material[imaging]
@ -31,10 +34,13 @@ jobs:
- name: Build Offline Version - name: Build Offline Version
run: make docs run: make docs
- name: CLI Artifacts - name: Zip Build
uses: ./.github/actions/upload-artifacts run: |
cd build/docs
zip -qq -r ../documentation.zip *
- name: Upload Artifacts
uses: actions/upload-artifact@v4.6.2
with: with:
chain-network: ${{ inputs.chain-network }} name: Documentation
assets: "*" path: build/documentation.zip
asset-type: 'docs'
asset-directory: ${{ github.workspace }}/build/docs

View file

@ -11,65 +11,23 @@ on:
type: string type: string
jobs: jobs:
cache: build:
name: cache-arm64 name: gcc-linux-arm64
runs-on: ubuntu-22.04-arm runs-on: ubuntu-22.04-arm
steps: steps:
- name: Cache SDK Folder
id: cache
uses: actions/cache@v4
with:
path: |
${{ github.workspace }}/build/sdk
${{ github.workspace }}/build/bin
key: ${{ runner.os }}-${{ runner.arch }}-sdk
- name: Checkout Project - name: Checkout Project
if: steps.cache.outputs.cache-hit != 'true'
uses: actions/checkout@v4.2.2 uses: actions/checkout@v4.2.2
with: with:
fetch-depth: 0 fetch-depth: 0
submodules: recursive submodules: recursive
- name: install dependencies - name: install dependencies
if: steps.cache.outputs.cache-hit != 'true'
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 git build-essential libcairo2-dev libfreetype6-dev libffi-dev libjpeg-dev libpng-dev libz-dev pngquant
- uses: actions/setup-python@v5
if: steps.cache.outputs.cache-hit != 'true'
with:
python-version: 3.x
- if: steps.cache.outputs.cache-hit != 'true'
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 Dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: |
make build-deps CPU_CORES=4 TESTNET=${{ inputs.chain-network == 'testnet' && '1' || '0' }} CONAN_USER=ci-user CONAN_PASSWORD=${{ secrets.CONAN_PASSWORD }}
make upload-conan-cache
build:
name: compile-arm64
needs: cache
runs-on: ubuntu-22.04-arm
steps:
- name: Checkout Project
uses: actions/checkout@v4.2.2
with:
fetch-depth: 0
submodules: recursive
- name: install dependencies
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 - name: Cache SDK Folder
uses: actions/cache@v4 uses: actions/cache@v4
with: with:
path: | path: ${{ github.workspace }}/build/sdk
${{ github.workspace }}/build/sdk
${{ github.workspace }}/build/bin
key: ${{ runner.os }}-${{ runner.arch }}-sdk key: ${{ runner.os }}-${{ runner.arch }}-sdk
- uses: actions/setup-python@v5 - uses: actions/setup-python@v5
@ -78,8 +36,15 @@ jobs:
- run: pip install mkdocs-material mkdocs-git-revision-date-localized-plugin mkdocs-git-committers-plugin-2 mkdocs-git-authors-plugin "mkdocs-material[imaging]" - run: pip install mkdocs-material mkdocs-git-revision-date-localized-plugin mkdocs-git-committers-plugin-2 mkdocs-git-authors-plugin "mkdocs-material[imaging]"
- name: Install Conan
uses: conan-io/setup-conan@v1
with:
home: ${{ github.workspace }}/build/sdk
cache_packages: false
- name: Compile Release - name: Compile Release
run: make ${{ inputs.chain-network }} run: make release CPU_CORES=4 TESTNET=${{ inputs.chain-network == 'testnet' && '1' || '0' }}
- name: CLI Artifacts - name: CLI Artifacts
uses: ./.github/actions/upload-artifacts uses: ./.github/actions/upload-artifacts
@ -87,4 +52,4 @@ jobs:
chain-network: ${{ inputs.chain-network }} chain-network: ${{ inputs.chain-network }}
assets: lethean-* assets: lethean-*
asset-type: 'cli' asset-type: 'cli'
asset-directory: ${{ github.workspace }}/build/packages asset-directory: ${{ github.workspace }}/build/release/packages

View file

@ -11,49 +11,8 @@ on:
type: string type: string
jobs: jobs:
cache:
name: cache-x86_64
runs-on: ubuntu-22.04
steps:
- name: Cache SDK Folder
id: cache
uses: actions/cache@v4
with:
lookup-only: true
path: |
${{ github.workspace }}/build/sdk
${{ github.workspace }}/build/bin
key: ${{ runner.os }}-${{ runner.arch }}-sdk
- name: Checkout Project
if: steps.cache.outputs.cache-hit != 'true'
uses: actions/checkout@v4.2.2
with:
fetch-depth: 0
submodules: recursive
- name: install dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: sudo apt-get install -y autotools-dev rpm git build-essential
- uses: actions/setup-python@v5
if: steps.cache.outputs.cache-hit != 'true'
with:
python-version: 3.x
- if: steps.cache.outputs.cache-hit != 'true'
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 Dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: |
make build-deps CPU_CORES=4 TESTNET=${{ inputs.chain-network == 'testnet' && '1' || '0' }} CONAN_USER=ci-user CONAN_PASSWORD=${{ secrets.CONAN_PASSWORD }}
make upload-conan-cache
build: build:
name: compile-x86_64 name: gcc-linux-x86_64
needs: cache
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- name: Checkout Project - name: Checkout Project
@ -68,9 +27,7 @@ jobs:
- name: Cache SDK Folder - name: Cache SDK Folder
uses: actions/cache@v4 uses: actions/cache@v4
with: with:
path: | path: ${{ github.workspace }}/build/sdk
${{ github.workspace }}/build/sdk
${{ github.workspace }}/build/bin
key: ${{ runner.os }}-${{ runner.arch }}-sdk key: ${{ runner.os }}-${{ runner.arch }}-sdk
- uses: actions/setup-python@v5 - uses: actions/setup-python@v5
@ -78,8 +35,14 @@ jobs:
python-version: 3.x 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]" - run: pip install mkdocs-material mkdocs-git-revision-date-localized-plugin mkdocs-git-committers-plugin-2 mkdocs-git-authors-plugin "mkdocs-material[imaging]"
- name: Install Conan
uses: conan-io/setup-conan@v1
with:
home: ${{ github.workspace }}/build/sdk
cache_packages: false
- name: Compile Release - name: Compile Release
run: make ${{ inputs.chain-network }} run: make release CPU_CORES=4 TESTNET=${{ inputs.chain-network == 'testnet' && '1' || '0' }}
- name: CLI Artifacts - name: CLI Artifacts
uses: ./.github/actions/upload-artifacts uses: ./.github/actions/upload-artifacts
@ -87,4 +50,4 @@ jobs:
chain-network: ${{ inputs.chain-network }} chain-network: ${{ inputs.chain-network }}
assets: lethean-* assets: lethean-*
asset-type: 'cli' asset-type: 'cli'
asset-directory: ${{ github.workspace }}/build/packages asset-directory: ${{ github.workspace }}/build/release/packages

View file

@ -12,45 +12,8 @@ on:
jobs: jobs:
cache: build-cli:
name: cache-armv8 name: apple-clang-armv8
runs-on: macos-15
steps:
- name: Cache SDK Folder
id: cache
uses: actions/cache@v4
with:
lookup-only: true
path: |
${{ github.workspace }}/build/sdk
${{ github.workspace }}/build/bin
key: ${{ runner.os }}-${{ runner.arch }}-sdk
- name: Checkout Project
if: steps.cache.outputs.cache-hit != 'true'
uses: actions/checkout@v4.2.2
with:
fetch-depth: 0
submodules: recursive
- uses: actions/setup-python@v5
if: steps.cache.outputs.cache-hit != 'true'
with:
python-version: 3.x
- if: steps.cache.outputs.cache-hit != 'true'
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 Dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: |
make build-deps CPU_CORES=3 TESTNET=${{ inputs.chain-network == 'testnet' && '1' || '0' }} CONAN_USER=ci-user CONAN_PASSWORD=${{ secrets.CONAN_PASSWORD }}
make upload-conan-cache
build:
name: compile-armv8
needs: cache
runs-on: macos-15 runs-on: macos-15
steps: steps:
- name: Checkout Project - name: Checkout Project
@ -59,12 +22,11 @@ jobs:
fetch-depth: 0 fetch-depth: 0
submodules: recursive submodules: recursive
- name: Cache SDK Folder - name: Cache SDK Folder
uses: actions/cache@v4 uses: actions/cache@v4
with: with:
path: | path: ${{ github.workspace }}/build/sdk
${{ github.workspace }}/build/sdk
${{ github.workspace }}/build/bin
key: ${{ runner.os }}-${{ runner.arch }}-sdk key: ${{ runner.os }}-${{ runner.arch }}-sdk
- uses: actions/setup-python@v5 - uses: actions/setup-python@v5
@ -73,8 +35,18 @@ jobs:
- run: pip install mkdocs-material mkdocs-git-revision-date-localized-plugin mkdocs-git-committers-plugin-2 mkdocs-git-authors-plugin "mkdocs-material[imaging]" - run: pip install mkdocs-material mkdocs-git-revision-date-localized-plugin mkdocs-git-committers-plugin-2 mkdocs-git-authors-plugin "mkdocs-material[imaging]"
- name: Install Conan
uses: conan-io/setup-conan@v1
with:
home: ${{ github.workspace }}/build/sdk
cache_packages: false
# - name: Compile Release
# run: make apple-clang-armv8 TESTNET=${{ inputs.chain-network == 'testnet' && '1' || '0' }}
- name: Compile Release - name: Compile Release
run: make ${{ inputs.chain-network }} run: make release CPU_CORES=3 TESTNET=${{ inputs.chain-network == 'testnet' && '1' || '0' }}
- name: CLI Artifacts - name: CLI Artifacts
uses: ./.github/actions/upload-artifacts uses: ./.github/actions/upload-artifacts
@ -82,4 +54,4 @@ jobs:
chain-network: ${{ inputs.chain-network }} chain-network: ${{ inputs.chain-network }}
assets: lethean-* assets: lethean-*
asset-type: 'cli' asset-type: 'cli'
asset-directory: ${{ github.workspace }}/build/packages asset-directory: ${{ github.workspace }}/build/release/packages

View file

@ -11,43 +11,8 @@ on:
type: string type: string
jobs: jobs:
cache:
name: cache-x86_64
runs-on: macos-13
steps:
- name: Cache SDK Folder
id: cache
uses: actions/cache@v4
with:
lookup-only: true
path: |
${{ github.workspace }}/build/sdk
${{ github.workspace }}/build/bin
key: ${{ runner.os }}-${{ runner.arch }}-sdk
- name: Checkout Project
if: steps.cache.outputs.cache-hit != 'true'
uses: actions/checkout@v4.2.2
with:
fetch-depth: 0
submodules: recursive
- uses: actions/setup-python@v5
if: steps.cache.outputs.cache-hit != 'true'
with:
python-version: 3.x
- if: steps.cache.outputs.cache-hit != 'true'
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 Dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: |
make build-deps CPU_CORES=4 TESTNET=${{ inputs.chain-network == 'testnet' && '1' || '0' }} CONAN_USER=ci-user CONAN_PASSWORD=${{ secrets.CONAN_PASSWORD }}
make upload-conan-cache
build: build:
name: compile-x86_64 name: apple-clang-x86_64
needs: cache
runs-on: macos-13 runs-on: macos-13
steps: steps:
- name: Checkout Project - name: Checkout Project
@ -56,12 +21,11 @@ jobs:
fetch-depth: 0 fetch-depth: 0
submodules: recursive submodules: recursive
- name: Cache SDK Folder - name: Cache SDK Folder
uses: actions/cache@v4 uses: actions/cache@v4
with: with:
path: | path: ${{ github.workspace }}/build/sdk
${{ github.workspace }}/build/sdk
${{ github.workspace }}/build/bin
key: ${{ runner.os }}-${{ runner.arch }}-sdk key: ${{ runner.os }}-${{ runner.arch }}-sdk
- uses: actions/setup-python@v5 - uses: actions/setup-python@v5
@ -69,8 +33,14 @@ jobs:
python-version: 3.x 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]" - run: pip install mkdocs-material mkdocs-git-revision-date-localized-plugin mkdocs-git-committers-plugin-2 mkdocs-git-authors-plugin "mkdocs-material[imaging]"
- name: Install Conan
uses: conan-io/setup-conan@v1
with:
home: ${{ github.workspace }}/build/sdk
cache_packages: false
- name: Compile Release - name: Compile Release
run: make ${{ inputs.chain-network }} run: make release CPU_CORES=4 TESTNET=${{ inputs.chain-network == 'testnet' && '1' || '0' }}
- name: CLI Artifacts - name: CLI Artifacts
uses: ./.github/actions/upload-artifacts uses: ./.github/actions/upload-artifacts
@ -78,4 +48,4 @@ jobs:
chain-network: ${{ inputs.chain-network }} chain-network: ${{ inputs.chain-network }}
assets: lethean-* assets: lethean-*
asset-type: 'cli' asset-type: 'cli'
asset-directory: ${{ github.workspace }}/build/packages asset-directory: ${{ github.workspace }}/build/release/packages

View file

@ -11,43 +11,8 @@ on:
type: string type: string
jobs: jobs:
cache: msvc-194:
name: cache-x86_64 name: msvc-194-x86_64
runs-on: windows-latest
steps:
- name: Cache SDK Folder
id: cache
uses: actions/cache@v4
with:
lookup-only: true
path: |
${{ github.workspace }}/build/sdk
${{ github.workspace }}/build/bin
key: ${{ runner.os }}-${{ runner.arch }}-sdk
- name: Checkout Project
if: steps.cache.outputs.cache-hit != 'true'
uses: actions/checkout@v4.2.2
with:
fetch-depth: 0
submodules: recursive
- uses: actions/setup-python@v5
if: steps.cache.outputs.cache-hit != 'true'
with:
python-version: 3.x
- if: steps.cache.outputs.cache-hit != 'true'
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 Dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: |
make build-deps CPU_CORES=4 TESTNET=${{ inputs.chain-network == 'testnet' && '1' || '0' }} CONAN_USER=ci-user CONAN_PASSWORD=${{ secrets.CONAN_PASSWORD }}
make upload-conan-cache
build:
name: compile-x86_64
needs: cache
runs-on: windows-latest runs-on: windows-latest
steps: steps:
- name: Checkout Project - name: Checkout Project
@ -59,19 +24,22 @@ jobs:
- name: Cache SDK Folder - name: Cache SDK Folder
uses: actions/cache@v4 uses: actions/cache@v4
with: with:
path: | path: ${{ github.workspace }}/build/sdk
${{ github.workspace }}/build/sdk
${{ github.workspace }}/build/bin
key: ${{ runner.os }}-${{ runner.arch }}-sdk key: ${{ runner.os }}-${{ runner.arch }}-sdk
- run: choco install nsis.install
- uses: actions/setup-python@v5 - uses: actions/setup-python@v5
with: with:
python-version: 3.x 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]" - run: pip install mkdocs-material mkdocs-git-revision-date-localized-plugin mkdocs-git-committers-plugin-2 mkdocs-git-authors-plugin "mkdocs-material[imaging]"
- name: Install Conan
uses: conan-io/setup-conan@v1
with:
home: ${{ github.workspace }}/build/sdk
cache_packages: false
- name: Compile Release - name: Compile Release
run: make ${{ inputs.chain-network }} run: make release CPU_CORES=4 TESTNET=${{ inputs.chain-network == 'testnet' && '1' || '0' }}
- name: CLI Artifacts - name: CLI Artifacts
uses: ./.github/actions/upload-artifacts uses: ./.github/actions/upload-artifacts
@ -79,4 +47,4 @@ jobs:
chain-network: ${{ inputs.chain-network }} chain-network: ${{ inputs.chain-network }}
assets: lethean-* assets: lethean-*
asset-type: 'cli' asset-type: 'cli'
asset-directory: ${{ github.workspace }}/build/packages asset-directory: ${{ github.workspace }}/build/release/packages

10
.gitignore vendored
View file

@ -5,14 +5,6 @@
._.DS_Store ._.DS_Store
Thumbs.db Thumbs.db
._* ._*
.idea/workspace.xml .idea
.idea/usage.statistics.xml
.idea/dictionaries
.idea/shelf
.idea/copilot*
.idea/modules.xml
.idea/*.iml
.vs/* .vs/*
CMakeUserPresets.json CMakeUserPresets.json
ConanPresets.json
docker/dist/

6
.gitmodules vendored
View file

@ -10,9 +10,3 @@
[submodule "docs"] [submodule "docs"]
path = docs path = docs
url = https://github.com/letheanVPN/documentation.git url = https://github.com/letheanVPN/documentation.git
[submodule "contrib/randomx"]
path = contrib/randomx
url = https://github.com/tevador/RandomX.git
[submodule ".core/build"]
path = .core/build
url = http://forge.snider.dev:4000/host-uk/build.git

8
.idea/.gitignore generated vendored
View file

@ -1,8 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

1
.idea/.name generated
View file

@ -1 +0,0 @@
Lethean

8
.idea/cmake.xml generated
View file

@ -1,8 +0,0 @@
<?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>

View file

@ -1,105 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<RiderCodeStyleSettings>
<option name="/Default/CodeStyle/CodeFormatting/CppClangFormat/EnableClangFormatSupport/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/EditorConfig/EnableClangFormatSupport/@EntryValue" value="false" 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_FOR_STMT/@EntryValue" value="true" 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/BLANK_LINES_AROUND_CLASS_DEFINITION/@EntryValue" value="1" 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_BLANK_LINES_IN_CODE/@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/INDENT_CASE_FROM_SWITCH/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_COMMENT/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INT_ALIGN_EQ/@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_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_FOR_SEMICOLON/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_FOR_SEMICOLON/@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_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_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_INITIALIZER_BRACES/@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/SPACE_AFTER_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_BINARY_OPSIGN/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_TERNARY_OPSIGNS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TYPE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/OTHER_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CASE_BLOCK_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<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/PLACE_WHILE_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_CATCH_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_INDENTATION/@EntryValue" value="All" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_ARGUMENT/@EntryValue" value="true" 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_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/BLANK_LINES_AROUND_DECLARATIONS/@EntryValue" value="0" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_ACCESS_SPECIFIERS_FROM_CLASS/@EntryValue" value="false" 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/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/PLACE_NAMESPACE_DEFINITIONS_ON_SAME_LINE/@EntryValue" value="false" 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_BEFORE_COLON_IN_BITFIELD_DECLARATOR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_EXTENDS_COLON/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_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_BEFORE_FOR_COLON/@EntryValue" value="false" 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_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_EMPTY_TEMPLATE_PARAMS/@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/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/WRAP_BEFORE_INVOCATION_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_BEFORE_INVOCATION_RPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_DECLARATION_LPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_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_ARGUMENTS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_PARAMETERS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BREAK_TEMPLATE_DECLARATION/@EntryValue" value="LINE_BREAK" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INVOCABLE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" 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/INITIALIZER_BRACES/@EntryValue" value="END_OF_LINE_NO_SPACE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_STYLE/@EntryValue" value="Space" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_SIZE/@EntryValue" value="4" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CONTINUOUS_LINE_INDENT/@EntryValue" value="Double" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TAB_WIDTH/@EntryValue" value="4" type="int" />
</RiderCodeStyleSettings>
<clangFormatSettings>
<option name="ENABLED" value="true" />
</clangFormatSettings>
</code_scheme>
</component>

View file

@ -1,5 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

View file

@ -1,6 +0,0 @@
<component name="CopyrightManager">
<copyright>
<option name="notice" value="Copyright (c) 2017-2025 Lethean (https://lt.hn)&#10;&#10;Licensed under the European Union Public Licence (EUPL) version 1.2.&#10;You may obtain a copy of the licence at:&#10;&#10; https://joinup.ec.europa.eu/software/page/eupl/licence-eupl&#10;&#10;The EUPL is a copyleft licence that is compatible with the MIT/X11&#10;licence used by the original projects; but maintains OSS status, &#10;where regional copyright law requires ownership to dictate licence terms.&#10;&#10;SPDXLicenseIdentifier: EUPL-1.2&#10;" />
<option name="myName" value="LTHN" />
</copyright>
</component>

View file

@ -1,6 +0,0 @@
<component name="CopyrightManager">
<copyright>
<option name="notice" value="Copyright (c) 2014-2018 Zano Project&#10;Copyright (c) 2014-2018 The Louisdor Project&#10;Copyright (c) 2012-2013 The Boolberry developers&#10;Copyright (c) 2017-2025 Lethean (https://lt.hn)&#10;&#10;Licensed under the European Union Public Licence (EUPL) version 1.2.&#10;You may obtain a copy of the licence at:&#10;&#10; https://joinup.ec.europa.eu/software/page/eupl/licence-eupl&#10;&#10;The EUPL is a copyleft licence that is compatible with the MIT/X11&#10;licence used by the original projects; the MIT terms are therefore&#10;considered “grandfathered” under the EUPL for this code.&#10;&#10;SPDXLicenseIdentifier: EUPL-1.2&#10;" />
<option name="myName" value="Lethean" />
</copyright>
</component>

View file

@ -1,8 +0,0 @@
<component name="CopyrightManager">
<settings default="LTHN">
<module2copyright>
<element module="apiserver" copyright="LTHN" />
<element module="Project Files" copyright="Lethean" />
</module2copyright>
</settings>
</component>

344
.idea/editor.xml generated
View file

@ -1,344 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="BackendCodeEditorSettings">
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CDeclarationWithImplicitIntType/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CommentTypo/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConstevalIfIsAlwaysConstant/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAbstractClassWithoutSpecifier/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAbstractFinalClass/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAbstractVirtualFunctionCallInCtor/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAccessSpecifierWithNoDeclarations/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAwaiterTypeIsNotClass/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBooleanIncrementExpression/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatBadCode/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatLegacyCode/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatMixedArgs/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatTooFewArgs/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatTooManyArgs/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCStyleCast/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCVQualifierCanNotBeAppliedToReference/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassCanBeFinal/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassIsIncomplete/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassNeedsConstructorBecauseOfUninitializedMember/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCompileTimeConstantCanBeReplacedWithBooleanConstant/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConceptNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConditionalExpressionCanBeSimplified/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConstParameterInDeclaration/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConstValueFunctionReturnType/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCoroutineCallResolveError/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAArrayIndexOutOfBounds/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAConstantConditions/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAConstantFunctionResult/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAConstantParameter/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFADeletedPointer/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAEndlessLoop/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAInfiniteRecursion/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAInvalidatedMemory/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFALocalValueEscapesFunction/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFALocalValueEscapesScope/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFALoopConditionNotUpdated/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAMemoryLeak/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFANotInitializedField/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFANullDereference/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFATimeOver/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnreachableCode/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnreachableFunctionCall/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnreadVariable/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnusedValue/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclarationHidesLocal/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclarationHidesUncapturedLocal/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclarationSpecifierWithoutDeclarators/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclaratorDisambiguatedAsFunction/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclaratorNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclaratorUsedBeforeInitialization/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultCaseNotHandledInSwitchStatement/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultInitializationWithNoUserConstructor/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultIsUsedAsIdentifier/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultedSpecialMemberFunctionIsImplicitlyDeleted/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeletingVoidPointer/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDependentTemplateWithoutTemplateKeyword/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDependentTypeWithoutTypenameKeyword/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeprecatedEntity/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeprecatedOverridenMethod/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeprecatedRegisterStorageClassSpecifier/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDereferenceOperatorLimitExceeded/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDiscardedPostfixOperatorResult/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDoxygenSyntaxError/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDoxygenUndocumentedParameter/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDoxygenUnresolvedReference/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEmptyDeclaration/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceCVQualifiersOrder/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceCVQualifiersPlacement/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceDoStatementBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceForStatementBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceFunctionDeclarationStyle/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceIfStatementBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceNestedNamespacesStyle/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceOverridingDestructorStyle/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceOverridingFunctionStyle/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceTypeAliasCodeStyle/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceWhileStatementBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEntityAssignedButNoRead/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEntityUsedOnlyInUnevaluatedContext/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnumeratorNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEqualOperandsInBinaryExpression/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEvaluationFailure/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppExplicitSpecializationInNonNamespaceScope/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppExpressionWithoutSideEffects/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFinalFunctionInFinalClass/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFinalNonOverridingVirtualFunction/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppForLoopCanBeReplacedWithWhile/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppForwardEnumDeclarationWithoutUnderlyingType/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionDoesntReturnValue/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionIsNotImplemented/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionResultShouldBeUsed/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionalStyleCast/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppHeaderHasBeenAlreadyIncluded/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppHiddenFunction/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppHidingFunction/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIdenticalOperandsInBinaryExpression/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIfCanBeReplacedByConstexprIf/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppImplicitDefaultConstructorNotAvailable/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIncompatiblePointerConversion/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIncompleteSwitchStatement/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppInconsistentNaming/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIntegralToPointerConversion/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppInvalidLineContinuation/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppJoinDeclarationAndAssignment/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLambdaCaptureNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLocalVariableMayBeConst/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLocalVariableMightNotBeInitialized/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLocalVariableWithNonTrivialDtorIsNeverUsed/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLongFloat/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMemberFunctionMayBeConst/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMemberFunctionMayBeStatic/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMemberInitializersOrder/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMismatchedClassTags/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMissingIncludeGuard/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMissingKeywordThrow/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppModulePartitionWithSeveralPartitionUnits/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtAddressOfClassRValue/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtBindingRValueToLvalueReference/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtCopyElisionInCopyInitDeclarator/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtDoubleUserConversionInCopyInit/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtNotInitializedStaticConstLocalVar/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtReinterpretCastFromNullptr/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMultiCharacterLiteral/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMultiCharacterWideLiteral/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMustBePublicVirtualToImplementInterface/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMutableSpecifierOnReferenceMember/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNoDiscardExpression/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNodiscardFunctionWithoutReturnValue/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonExceptionSafeResourceAcquisition/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonExplicitConversionOperator/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonExplicitConvertingConstructor/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonInlineFunctionDefinitionInHeaderFile/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonInlineVariableDefinitionInHeaderFile/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNotAllPathsReturnValue/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppObjectMemberMightNotBeInitialized/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppOutParameterMustBeWritten/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterMayBeConst/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterMayBeConstPtrOrRef/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterNamesMismatch/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterNeverUsed/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPassValueParameterByConstReference/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPointerConversionDropsQualifiers/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPointerToIntegralConversion/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPolymorphicClassWithNonVirtualPublicDestructor/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPossiblyErroneousEmptyStatements/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPossiblyUninitializedMember/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPossiblyUnintendedObjectSlicing/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrecompiledHeaderIsNotIncluded/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrecompiledHeaderNotFound/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfBadFormat/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfExtraArg/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfMissedArg/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfRiskyFormat/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrivateSpecialMemberFunctionIsNotImplemented/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRangeBasedForIncompatibleReference/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedefinitionOfDefaultArgumentInOverrideFunction/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantAccessSpecifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantBaseClassAccessSpecifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantBaseClassInitializer/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantBooleanExpressionArgument/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantCastExpression/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantComplexityInComparison/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantConditionalExpression/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantConstSpecifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantControlFlowJump/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantDereferencingAndTakingAddress/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantElaboratedTypeSpecifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantElseKeyword/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantElseKeywordInsideCompoundStatement/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantEmptyDeclaration/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantEmptyStatement/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantExportKeyword/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantFwdClassOrEnumSpecifier/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantInlineSpecifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantLambdaParameterList/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantMemberInitializer/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantNamespaceDefinition/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantParentheses/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantQualifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantQualifierADL/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantStaticSpecifierOnMemberAllocationFunction/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantStaticSpecifierOnThreadLocalLocalVariable/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantTemplateArguments/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantTemplateKeyword/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantTypenameKeyword/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantVoidArgumentList/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantZeroInitializerInAggregateInitialization/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReinterpretCastFromVoidPtr/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRemoveRedundantBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReplaceMemsetWithZeroInitialization/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReplaceTieWithStructuredBinding/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReturnNoValueInNonVoidFunction/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppSmartPointerVsMakeFunction/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppSomeObjectMembersMightNotBeInitialized/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppSpecialFunctionWithoutNoexceptSpecification/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStaticAssertFailure/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStaticDataMemberInUnnamedStruct/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStaticSpecifierOnAnonymousNamespaceMember/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStringLiteralToCharPointerConversion/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTabsAreDisallowed/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTemplateArgumentsCanBeDeduced/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTemplateParameterNeverUsed/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTemplateParameterShadowing/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppThrowExpressionCanBeReplacedWithRethrow/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTooWideScope/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTooWideScopeInitStatement/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTypeAliasNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUninitializedDependentBaseClass/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUninitializedNonStaticDataMember/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnionMemberOfReferenceType/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnmatchedPragmaEndRegionDirective/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnmatchedPragmaRegionDirective/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnnamedNamespaceInHeaderFile/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnnecessaryWhitespace/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnsignedZeroComparison/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnusedIncludeDirective/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAlgorithmWithCount/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAssociativeContains/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAuto/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAutoForNumeric/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseElementsView/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseEraseAlgorithm/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseFamiliarTemplateSyntaxForGenericLambdas/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseRangeAlgorithm/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseStdSize/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseStructuredBinding/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseTypeTraitAlias/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUserDefinedLiteralSuffixDoesNotStartWithUnderscore/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUsingResultOfAssignmentAsCondition/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVariableCanBeMadeConstexpr/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVirtualFunctionCallInsideCtor/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVirtualFunctionInFinalClass/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVolatileParameterInDeclaration/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppWarningDirective/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppWrongIncludesOrder/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppWrongSlashesInIncludeDirective/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppZeroConstantCanBeReplacedWithNullptr/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppZeroValuedExpressionUsedAsNullPointer/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=IdentifierTypo/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<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>

View file

@ -1,13 +0,0 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoredIdentifiers">
<list>
<option value="tuple.*" />
</list>
</option>
</inspection_tool>
</profile>
</component>

43
.idea/jsonSchemas.xml generated
View file

@ -1,43 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JsonSchemaMappingsProjectConfiguration">
<state>
<map>
<entry key="GitHub Action JSON Schema">
<value>
<SchemaInfo>
<option name="name" value="GitHub Action JSON Schema" />
<option name="relativePathToSchema" value="jar://$APPLICATION_PLUGINS_DIR$/vcs-github-IU/lib/vcs-github.jar!/schemas/github-action.json" />
<option name="applicationDefined" value="true" />
<option name="patterns">
<list>
<Item>
<option name="path" value=".github/actions/**/*.yml" />
</Item>
</list>
</option>
</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>
</project>

34
.idea/misc.xml generated
View file

@ -1,34 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.13 virtualenv at $PROJECT_DIR$.venv" />
</component>
<component name="CMakePythonSetting">
<option name="pythonIntegrationState" value="YES" />
</component>
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
<component name="CidrRootsConfiguration">
<excludeRoots>
<file path="$PROJECT_DIR$/build" />
</excludeRoots>
</component>
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MakefileSettings">
<option name="linkedExternalProjectsSettings">
<MakefileProjectSettings>
<option name="buildOptions" value="--jobs=30" />
<option name="buildTarget" value="build" />
<option name="cleanTarget" value="clean-build" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
<option name="switches" value="TESTNET=1 STATIC=1" />
<option name="version" value="2" />
</MakefileProjectSettings>
</option>
</component>
<component name="MakefileWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
</project>

6
.idea/prettier.xml generated
View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PrettierConfiguration">
<option name="myConfigurationMode" value="AUTOMATIC" />
</component>
</project>

View file

@ -1,3 +0,0 @@
<component name="DependencyValidationManager">
<scope name="apiserver" pattern="file[blockchain]:src/api//*" />
</component>

10
.idea/vcs.xml generated
View file

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
<mapping directory="$PROJECT_DIR$/contrib/bitcoin-secp256k1" vcs="Git" />
<mapping directory="$PROJECT_DIR$/contrib/jwt-cpp" vcs="Git" />
<mapping directory="$PROJECT_DIR$/contrib/tor-connect" vcs="Git" />
<mapping directory="$PROJECT_DIR$/docs" vcs="Git" />
</component>
</project>

View file

@ -1,55 +0,0 @@
# 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.

View file

@ -6,11 +6,15 @@ set(DISABLE_TOR TRUE CACHE BOOL "Disable TOR library(and related tor-connect sub
PROJECT(Lethean) PROJECT(Lethean)
set(VERSION "1.0" CACHE STRING "Build version") set(VERSION "1.0" CACHE STRING "Build version")
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
message("OPENSSL_INCLUDE_DIR: ${OPENSSL_INCLUDE_DIR}")
message("OPENSSL_CRYPTO_LIBRARY: ${OPENSSL_CRYPTO_LIBRARY}")
message("OPENSSL_SSL_LIBRARY: ${OPENSSL_SSL_LIBRARY}")
list(INSERT CMAKE_MODULE_PATH 0 list(INSERT CMAKE_MODULE_PATH 0
"${CMAKE_CURRENT_SOURCE_DIR}/.core/build/cmake") "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(DocBuilder)
if(POLICY CMP0043) if(POLICY CMP0043)
cmake_policy(SET CMP0043 NEW) cmake_policy(SET CMP0043 NEW)
@ -18,9 +22,6 @@ endif()
if(POLICY CMP0043) if(POLICY CMP0043)
cmake_policy(SET CMP0074 NEW) cmake_policy(SET CMP0074 NEW)
endif() endif()
if(POLICY CMP0091)
cmake_policy(SET CMP0091 NEW)
endif()
if(POLICY CMP0144) if(POLICY CMP0144)
cmake_policy(SET CMP0144 NEW) cmake_policy(SET CMP0144 NEW)
endif() endif()
@ -28,13 +29,16 @@ if(POLICY CMP0167)
cmake_policy(SET CMP0167 OLD) cmake_policy(SET CMP0167 OLD)
endif() endif()
include(DocBuilder) #option (USE_CCACHE "Use ccache if a usable instance is found" ON)
option (USE_CCACHE "Use ccache if a usable instance is found" OFF) #if (USE_CCACHE)
if (USE_CCACHE) # include(FindCcache) # Has to be included after the project() macro, to be able to read the CXX variable.
include(FindCcache) #else()
else() # message(STATUS "ccache deselected")
message(STATUS "ccache deselected") #endif()
endif()
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(CMAKE_SYSTEM_NAME STREQUAL "iOS" OR CMAKE_SYSTEM_NAME STREQUAL "Android") if(CMAKE_SYSTEM_NAME STREQUAL "iOS" OR CMAKE_SYSTEM_NAME STREQUAL "Android")
add_definitions(-DMOBILE_WALLET_BUILD) add_definitions(-DMOBILE_WALLET_BUILD)
@ -90,6 +94,12 @@ if(NOT USE_BITCOIN_SECP256K1_FOR_ECDSA)
add_definitions(-DUSE_OPEN_SSL_FOR_ECDSA) add_definitions(-DUSE_OPEN_SSL_FOR_ECDSA)
endif() endif()
find_package(miniupnpc REQUIRED)
find_package(ZLIB REQUIRED)
include_directories(src contrib/eos_portable_archive ${ZLIB_INCLUDE_DIRS} contrib contrib/epee/include contrib/jwt-cpp/include ${OPENSSL_INCLUDE_DIR} "${CMAKE_BINARY_DIR}/version")
add_definitions(-DSTATICLIB) add_definitions(-DSTATICLIB)
if(TESTNET) if(TESTNET)
@ -140,7 +150,7 @@ if(MSVC)
endforeach() endforeach()
endif() endif()
include_directories(SYSTEM src/platform/msc) include_directories(SYSTEM src/platform/msc)
configure_file(utils/Directory.Build.props.in ${CMAKE_BINARY_DIR}/Directory.Build.props)
else() else()
set(ARCH default CACHE STRING "CPU to build for: -march value or default") set(ARCH default CACHE STRING "CPU to build for: -march value or default")
if("${ARCH}" STREQUAL "default") if("${ARCH}" STREQUAL "default")
@ -182,7 +192,7 @@ else()
endif() endif()
set(C_WARNINGS "-Waggregate-return -Wnested-externs -Wstrict-prototypes -Wno-comment") set(C_WARNINGS "-Waggregate-return -Wnested-externs -Wstrict-prototypes -Wno-comment")
set(CXX_WARNINGS "-Wno-reorder -Wno-missing-field-initializers") set(CXX_WARNINGS "-Wno-reorder -Wno-missing-field-initializers")
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") 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")
if(STATIC_ASSERT_RES) if(STATIC_ASSERT_RES)
set(STATIC_ASSERT_FLAG "") set(STATIC_ASSERT_FLAG "")
else() else()
@ -208,9 +218,9 @@ else()
if(NOT APPLE AND NOT (CMAKE_SYSTEM_NAME STREQUAL "Android")) if(NOT APPLE AND NOT (CMAKE_SYSTEM_NAME STREQUAL "Android"))
set(RELEASE_FLAGS "${RELEASE_FLAGS} -flto=auto -g3") set(RELEASE_FLAGS "${RELEASE_FLAGS} -flto=auto -g3")
endif() endif()
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND NOT MINGW) #if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND NOT MINGW)
set(RELEASE_FLAGS "${RELEASE_FLAGS} -fno-fat-lto-objects") # set(RELEASE_FLAGS "${RELEASE_FLAGS} -fno-fat-lto-objects")
endif() #endif()
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${DEBUG_FLAGS}") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${DEBUG_FLAGS}")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${DEBUG_FLAGS}") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${DEBUG_FLAGS}")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${RELEASE_FLAGS}") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${RELEASE_FLAGS}")
@ -242,25 +252,14 @@ set(BOOST_COMPONENTS system filesystem locale thread timer date_time chrono rege
if(NOT APPLE) if(NOT APPLE)
list(APPEND BOOST_COMPONENTS log) list(APPEND BOOST_COMPONENTS log)
endif() endif()
message(STATUS "Using Boost ${Boost_VERSION} from Conan")
find_package(miniupnpc REQUIRED) # Find Boost package using Conan
find_package(ZLIB REQUIRED)
find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS}) find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS})
include_directories(src "${CMAKE_BINARY_DIR}/version") message(STATUS "Using Boost ${Boost_VERSION} from Conan")
include_directories(SYSTEM include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
${Boost_INCLUDE_DIRS} include_directories(SYSTEM ${PROJECT_SOURCE_DIR}/contrib/ethereum/libethash)
${ZLIB_INCLUDE_DIRS}
${OPENSSL_INCLUDE_DIR}
${PROJECT_SOURCE_DIR}/contrib/ethereum/libethash
contrib
contrib/epee/include
contrib/jwt-cpp/include
contrib/eos_portable_archive
)
# Append other needed libraries # Append other needed libraries
if(MINGW) if(MINGW)

View file

@ -1,109 +0,0 @@
{
"version": 8,
"cmakeMinimumRequired": {
"major": 3,
"minor": 23,
"patch": 0
},
"include": [
"ConanPresets.json"
],
"configurePresets": [
{
"name": "testnet",
"binaryDir": "${sourceDir}/build/release",
"environment": {
"CONAN_HOME": "${sourceDir}/build/sdk"
},
"cacheVariables": {
"TESTNET": "ON",
"CMAKE_BUILD_TYPE": "Release",
"CMAKE_PROJECT_TOP_LEVEL_INCLUDES":".core/build/cmake/ConanProvider.cmake"
}
},
{
"name": "mainnet",
"binaryDir": "${sourceDir}/build/release",
"environment": {
"CONAN_HOME": "${sourceDir}/build/sdk"
},
"cacheVariables": {
"TESTNET": "OFF",
"CMAKE_BUILD_TYPE": "Release",
"CMAKE_PROJECT_TOP_LEVEL_INCLUDES":".core/build/cmake/ConanProvider.cmake"
}
}
],
"buildPresets": [
{
"name": "testnet",
"configurePreset": "testnet"
},
{
"name": "mainnet",
"configurePreset": "mainnet"
}
],
"testPresets": [
{
"name": "mainnet",
"configurePreset": "mainnet",
"output": {"outputOnFailure": true},
"execution": {"noTestsAction": "error", "stopOnFailure": true}
}
],
"packagePresets": [
{
"name": "mainnet",
"configurePreset": "mainnet",
"generators": [
"TGZ",
"ZIP"
]
},
{
"name": "testnet",
"configurePreset": "testnet",
"generators": [
"TGZ",
"ZIP"
]
}
],
"workflowPresets": [
{
"name": "testnet",
"steps": [
{
"type": "configure",
"name": "testnet"
},
{
"type": "build",
"name": "testnet"
},
{
"type": "package",
"name": "testnet"
}
]
},
{
"name": "mainnet",
"steps": [
{
"type": "configure",
"name": "mainnet"
},
{
"type": "build",
"name": "mainnet"
},
{
"type": "package",
"name": "mainnet"
}
]
}
]
}

View file

@ -1,9 +0,0 @@
{
"version": 4,
"vendor": {
"conan": {}
},
"include": [
"build/release/generators/CMakePresets.json"
]
}

172
Makefile
View file

@ -4,193 +4,175 @@
# Distributed under the MIT/X11 software license, see the accompanying # Distributed under the MIT/X11 software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php. # file COPYING or http://www.opensource.org/licenses/mit-license.php.
# ============================================================ # ------------------------------------------------------------
# Build system from host-uk/build submodule # Detect the number of logical CPU cores works on Linux,
# ============================================================ # macOS, BSD, and Windows (both cmd.exe and PowerShell).
BUILD_SYS := .core/build # ------------------------------------------------------------
CMAKE_DIR := $(BUILD_SYS)/cmake
# ============================================================ # Default to “unknown” will be overwritten below.
# Project Configuration
# ============================================================
CPU_CORES := 1 CPU_CORES := 1
TESTNET:= 0 TESTNET:= 0
STATIC:= 0 STATIC:= 0
BUILD_TYPE ?=Release BUILD_TYPE ?=Release
BUILD_VERSION:=6.0.1 BUILD_VERSION:=6.0.1
BUILD_FOLDER:=build/release BUILD_FOLDER:=build/release
PRESET_BUILD:=conan-release
PRESET_CONFIGURE:=conan-release
# ------------------------------------------------------------ # -----------------------------------------------------------------
# Detect the number of logical CPU cores works on Linux, # Unixlike systems (Linux, macOS, *BSD, etc.)
# macOS, BSD, and Windows (both cmd.exe and PowerShell). # -----------------------------------------------------------------
# ------------------------------------------------------------
UNAME_S := $(shell uname -s 2>/dev/null || echo Unknown) UNAME_S := $(shell uname -s 2>/dev/null || echo Unknown)
ifeq ($(UNAME_S),Linux) ifeq ($(UNAME_S),Linux)
# Linux: try nproc first, fall back to /proc
CPU_CORES := $(shell nproc 2>/dev/null || \ CPU_CORES := $(shell nproc 2>/dev/null || \
grep -c ^processor /proc/cpuinfo 2>/dev/null || echo 1) grep -c ^processor /proc/cpuinfo 2>/dev/null || echo 1)
endif endif
ifeq ($(UNAME_S),Darwin) ifeq ($(UNAME_S),Darwin)
# macOS: sysctl reports the number of logical CPUs
CPU_CORES := $(shell sysctl -n hw.logicalcpu 2>/dev/null || echo 1) CPU_CORES := $(shell sysctl -n hw.logicalcpu 2>/dev/null || echo 1)
endif endif
ifeq ($(filter %BSD,$(UNAME_S)),%BSD) ifeq ($(filter %BSD,$(UNAME_S)),%BSD)
# *BSD: also sysctl, but the key differs on some variants
CPU_CORES := $(shell sysctl -n hw.ncpu 2>/dev/null || echo 1) CPU_CORES := $(shell sysctl -n hw.ncpu 2>/dev/null || echo 1)
endif endif
# -----------------------------------------------------------------
# Windows (detected by the builtin $(OS) variable set by GNU make)
# -----------------------------------------------------------------
ifeq ($(OS),Windows_NT) ifeq ($(OS),Windows_NT)
# Prefer the environment variable that Windows sets for us.
PRESET_CONFIGURE:=conan-default # It works in both cmd.exe and PowerShell.
CPU_CORES := $(NUMBER_OF_PROCESSORS) CPU_CORES := $(NUMBER_OF_PROCESSORS)
# If for some reason the env var is empty, fall back to PowerShell.
ifeq ($(CPU_CORES),) ifeq ($(CPU_CORES),)
CPU_CORES := $(shell powershell -NoProfile -Command ^ "[Environment]::ProcessorCount") CPU_CORES := $(shell powershell -NoProfile -Command ^ "[Environment]::ProcessorCount")
endif endif
endif endif
# Safety net #testnet-genesis-new:
# $(eval command += $(cmake_release) $(testnet))
# $(call CMAKE,$(dir_release),$(command) -DGENERATE_PREMINE_WALLET=1 -DPREMINE_WALLET_PASSWORD=12345678) && cmake --build ./src --target premine_wallet || true
# $(eval command += $(cmake_release) $(testnet))
# $(call CMAKE,$(dir_release),$(command) -DGENERATE_FRESH_GENESIS=1) && cmake --build ./src --target genesis_generator
# $(eval command += $(cmake_release) $(testnet))
# $(call CMAKE,$(dir_release),$(command)) && $(MAKE)
#
#genesis-new:
# $(eval command += $(cmake_release))
# $(call CMAKE,$(dir_release),$(command) -DGENERATE_FRESH_GENESIS=1) && cmake --build ./src --target genesis_generator
# $(eval command += $(cmake_release))
# $(call CMAKE,$(dir_release),$(command)) && $(MAKE)
# -----------------------------------------------------------------
# Safety net ensure we always have a positive integer.
# -----------------------------------------------------------------
CPU_CORES := $(or $(CPU_CORES),1) CPU_CORES := $(or $(CPU_CORES),1)
CPU_CORES := $(shell expr $(CPU_CORES) + 0 2>/dev/null || echo 1) CPU_CORES := $(shell expr $(CPU_CORES) + 0 2>/dev/null || echo 1)
CONAN_CPU_COUNT=$(CPU_CORES) #CONAN_CPU_COUNT=$(CPU_CORES)
# ============================================================
# Paths — profiles and cmake modules from .build submodule
# ============================================================
PROFILES :=$(patsubst $(CMAKE_DIR)/profiles/%,%,$(wildcard $(CMAKE_DIR)/profiles/*))
SORTED_PROFILES :=$(sort $(PROFILES))
CONAN_CACHE :=$(CURDIR)/build/sdk
CONAN_URL :=http://forge.snider.dev:4000/api/packages/host-uk/conan
CONAN_USER ?=$(shell echo $$CONAN_USER)
CONAN_PASSWORD ?=$(shell echo $$CONAN_PASSWORD)
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))
PROFILES := $(patsubst cmake/profiles/%,%,$(wildcard cmake/profiles/*))
SORTED_PROFILES := $(sort $(PROFILES))
CONAN_CACHE := $(CURDIR)/build/sdk
DEFAULT_CONAN_PROFILE := $(CONAN_CACHE)/profiles/default
CC_DOCKER_FILE?=utils/docker/images/lthn-chain/Dockerfile
# Detect if we are on Windows
ifeq ($(OS), Windows_NT)
# If so, define a prefix to clear the problematic env vars
FIX_ENV := CFLAGS="" CXXFLAGS=""
else
# Otherwise, the prefix is empty
FIX_ENV :=
endif
all: help all: help
testnet:
$(MAKE) configure TESTNET=1 STATIC=$(STATIC)
CONAN_HOME=$(CONAN_CACHE) $(CONAN_EXECUTABLE) build .
$(MAKE) package
mainnet:
$(MAKE) configure TESTNET=0 STATIC=$(STATIC)
CONAN_HOME=$(CONAN_CACHE) $(CONAN_EXECUTABLE) build .
$(MAKE) package
release: docs build release: docs build
(cd $(BUILD_FOLDER) && cpack) (cd $(BUILD_FOLDER) && cpack)
@rm -rf $(CURDIR)/build/packages/_CPack_Packages
build: configure build: configure
cmake --build --preset $(PRESET_BUILD) --parallel=$(CPU_CORES) cmake --build $(BUILD_FOLDER) --config=$(BUILD_TYPE) --parallel=$(CPU_CORES)
debug: conan-profile-detect
@echo "Building profile: debug"
$(FIX_ENV) CONAN_HOME=$(CONAN_CACHE) conan install . --output-folder=build/debug --build=missing -s build_type=Debug
cmake -S . -B build/debug -DCMAKE_TOOLCHAIN_FILE=build/debug/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Debug -DTESTNET=$(TESTNET)
cmake --build build/debug --config=Debug --parallel=$(CPU_CORES)
build-deps: conan-profile-detect build-deps: conan-profile-detect
@echo "Build Dependencies: $(BUILD_TYPE) testnet=$(TESTNET)" @echo "Build Dependencies: $(BUILD_TYPE) testnet=$(TESTNET)"
CONAN_HOME=$(CONAN_CACHE) $(CONAN_EXECUTABLE) install . --build=missing -s build_type=$(BUILD_TYPE) $(FIX_ENV) CONAN_HOME=$(CONAN_CACHE) conan 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 configure: build-deps
@echo "Running Configure: $(BUILD_TYPE) testnet=$(TESTNET)" @echo "Running Configure: $(BUILD_TYPE) testnet=$(TESTNET)"
cmake --preset $(PRESET_CONFIGURE) -DSTATIC=$(STATIC) -DTESTNET=$(TESTNET) -DBUILD_VERSION=$(BUILD_VERSION) cmake -S . -B $(BUILD_FOLDER) -DCMAKE_TOOLCHAIN_FILE=$(BUILD_FOLDER)/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -DSTATIC=$(STATIC) -DTESTNET=$(TESTNET) -DBUILD_VERSION=$(BUILD_VERSION)
docs: configure
@echo "Building Documentation"
cmake --build build/release --target=docs --config=Release --parallel=$(CPU_CORES)
sdk: conan-profile-detect:
$(MAKE) -C utils/sdk $(filter-out $@,$(MAKECMDGOALS)) PACKAGE_VERSION=$(BUILD_VERSION) @if [ ! -f "$(DEFAULT_CONAN_PROFILE)" ]; then \
echo "Default conan profile not found. Detecting a new one..."; \
CONAN_HOME=$(CONAN_CACHE) conan profile detect --name=default --force; \
fi
# Rule for each profile — uses .build/cmake/profiles/
# Rule for each profile
$(PROFILES): conan-profile-detect $(PROFILES): conan-profile-detect
@echo "Building profile: $@" @echo "Building profile: $@"
CONAN_HOME=$(CONAN_CACHE) $(CONAN_EXECUTABLE) install . -pr:h=$(CMAKE_DIR)/profiles/$@ --build=missing -s build_type=$(BUILD_TYPE) CFLAGS="" CXXFLAGS="" CONAN_HOME=$(CONAN_CACHE) conan install . -pr:h=cmake/profiles/$@ --build=missing -s build_type=$(BUILD_TYPE)
cmake -S . -B $(BUILD_FOLDER) -DCMAKE_TOOLCHAIN_FILE=$(BUILD_FOLDER)/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -DSTATIC=$(STATIC) -DTESTNET=$(TESTNET) -DBUILD_VERSION=$(BUILD_VERSION) cmake -S . -B $(BUILD_FOLDER) -DCMAKE_TOOLCHAIN_FILE=$(BUILD_FOLDER)/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -DSTATIC=$(STATIC) -DTESTNET=$(TESTNET) -DBUILD_VERSION=$(BUILD_VERSION)
cmake --build $(BUILD_FOLDER) --config=$(BUILD_TYPE) --parallel=$(CPU_CORES) cmake --build $(BUILD_FOLDER) --config=$(BUILD_TYPE) --parallel=$(CPU_CORES)
(cd $(BUILD_FOLDER) && cpack) (cd $(BUILD_FOLDER) && cpack)
help: 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:" @echo "Available targets:"
@printf " %-42s %s\n" "make clean" "Clean all build directories" @printf " %-42s %s\n" "make clean" "Clean all build directories"
@printf " %-42s %s\n" "make conan-get" "Download and install conan locally"
@printf " %-42s %s\n" "make release" "Build release" @printf " %-42s %s\n" "make release" "Build release"
@printf " %-42s %s\n" "make testnet" "Build testnet" @printf " %-42s %s\n" "make static" "Build static release"
@printf " %-42s %s\n" "make mainnet" "Build mainnet" @printf " %-42s %s\n" "make debug" "Build debug"
@printf " %-42s %s\n" "make test" "Build & run tests" @printf " %-42s %s\n" "make test" "Build & run tests"
@printf " %-42s %s\n" "make docs" "Builds offline documentation website" @printf " %-42s %s\n" "make docs" "Builds offline documentation website"
@printf " %-42s %s\n" "make docs-dev" "Runs local doc server, for editing/adding docs" @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 conan-profile-detect" "Creates host config"
@printf " %-42s %s\n" "make configure" "Runs a cmake configure within conan build flow" @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";) @$(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" @printf " %-42s %s\n" "make help" "Show this help message"
#
# Tests
#
test: test-release test: test-release
test-release: test-release:
@echo "Building profile: test-release" @echo "Building profile: test-release"
CONAN_HOME=$(CONAN_CACHE) $(CONAN_EXECUTABLE) install . --output-folder=build/test-release --build=missing -s build_type=$(BUILD_TYPE) CONAN_HOME=$(CONAN_CACHE) conan install . --output-folder=build/test-release --build=missing -s build_type=$(BUILD_TYPE)
cmake -S . -B build/test-release -DCMAKE_TOOLCHAIN_FILE=build/test-release/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release -D BUILD_TESTS=ON cmake -S . -B build/test-release -DCMAKE_TOOLCHAIN_FILE=build/test-release/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release -D BUILD_TESTS=ON
cmake --build build/test-release --config=Release --parallel=$(CPU_CORES) cmake --build build/test-release --config=Release --parallel=$(CPU_CORES)
$(MAKE) test $(MAKE) test
test-debug: test-debug:
@echo "Building profile: test-debug" @echo "Building profile: test-debug"
CONAN_HOME=$(CONAN_CACHE) $(CONAN_EXECUTABLE) install . --output-folder=build/test-debug --build=missing -s build_type=$(BUILD_TYPE) CONAN_HOME=$(CONAN_CACHE) conan install . --output-folder=build/test-debug --build=missing -s build_type=$(BUILD_TYPE)
cmake -S . -B build/test-debug -DCMAKE_TOOLCHAIN_FILE=build/test-debug/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Debug -D BUILD_TESTS=ON cmake -S . -B build/test-debug -DCMAKE_TOOLCHAIN_FILE=build/test-debug/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Debug -D BUILD_TESTS=ON
cmake --build build/test-debug --config=Debug --parallel=$(CPU_CORES) cmake --build build/test-debug --config=Debug --parallel=$(CPU_CORES)
$(MAKE) test $(MAKE) test
# Conan management — cmake modules from .build submodule
conan-get:
cmake -P $(CMAKE_DIR)/ConanGet.cmake
ifneq ($(CONAN_USER),)
(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
endif
conan-upload: docs: configure
CONAN_HOME=$(CONAN_CACHE) $(CONAN_EXECUTABLE) upload "*" -r=conan_build --confirm @echo "Building Documentation"
cmake --build build/release --target=docs --config=Release --parallel=$(CPU_CORES)
conan-profile-detect: conan-get
cmake -P $(CMAKE_DIR)/ConanProfileSetup.cmake
docs-dev: configure docs-dev: configure
@echo "Building Documentation" @echo "Building Documentation"
cmake --build build/release --target=serve_docs --config=Release cmake --build build/release --target=serve_docs --config=Release
$(SDK_TARGETS):
@# This is a proxy target. Handled by the 'sdk' rule.
clean: clean:
@cmake -P $(CMAKE_DIR)/CleanBuild.cmake
clean-build: clean
rm -rf build rm -rf build
tags: tags:
ctags -R --sort=1 --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ src contrib tests/gtest 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 conan-get $(PROFILES) sdk $(SDK_TARGETS) .PHONY: all release docker-chain-node debug docs docs-dev configure static static-release test test-release test-debug clean tags conan-profile-detect $(PROFILES)

View file

@ -1,209 +0,0 @@
# Mainnet Name Registration Plan
> **Status:** Validating on testnet
> **Date:** 2026-04-03
> **Authors:** Snider, Charon
## Problem
The Lethean chain merges two blockchains — a main chain (aliases) and an HNS sidechain (DNS). The sidechain blocks Alexa top 100K domains and ICANN TLDs from being registered by random users. But the main chain has no such protection — anyone could register `@google` as an alias before the sidechain has a chance to refuse it.
This creates a window for name squatting that corrupts the namespace before real users arrive.
## Numbers
| Category | Count |
|----------|-------|
| Reserved (Alexa top 100K) | 90,016 |
| Locked (ICANN TLDs) | 11,554 |
| **Total unique names** | **90,041** |
| Long names (>=6 chars, public) | 73,977 |
| Short names (<6 chars, need authority key) | 16,062 |
**Source:** `blockchain-network-dcore/lib/covenants/names.json` and `lockup.json`
## Strategy
### Phase 1: Genesis + HF Warmup
1. Mainnet launches with HF0 — 10M LTHN premine in SWAP wallet
2. During HF warmup (HF0 → HF1), send **1,000+ LTHN** from genesis to dedicated namereg wallets
3. Multiple namereg wallets (2-4) for parallel registration
4. Destination for all reserved aliases: a **multi-sig wallet** controlled by the team
### Phase 2: Staking Funds the Protection
1. Network wallet stakes during warmup — earns ~720 LTHN/day from PoS
2. Legacy users haven't reclaimed tokens yet (SWAP happens later)
3. Staking rewards from the network's own balance fund all registrations
4. The network literally pays for its own name protection
### Phase 3: Batch Registration
When aliases activate (HF that enables alias registration):
1. Namereg wallets already have coins and mature UTXOs ready
2. Multiple wallets work in parallel, each tackling a chunk of the 90K list
3. Priority order:
- **Tier 1:** Top brands (google, facebook, amazon, etc) — ~120 names
- **Tier 2:** Long names from Alexa list (>=6 chars) — ~73,977 names
- **Tier 3:** Short names with authority key (<6 chars) ~16,062 names
4. Rate: ~1 alias per 3 seconds per wallet = ~28,800/day with 1 wallet, ~115,200/day with 4
### Phase 4: Ongoing Governance
1. All reserved names sit in a multi-sig wallet
2. Legitimate brand owners can request transfer (proof of domain ownership)
3. Community aliases (common words like "wallet", "exchange") remain locked
4. Infrastructure names (@vpn, @proxy, @exit, etc) transferred to service operators
## Cost Model
| Item | Cost |
|------|------|
| Alias registration fee | 1 LTHN each |
| Transaction fee | 0.01 LTHN each |
| **Total for 90K names** | **~90,900 LTHN** |
| PoS earnings (720/day) | Covered in ~126 days |
| With 1000 LTHN seed | First ~1000 names immediate |
The network earns back the registration cost through staking before legacy users even begin the SWAP process.
## Technical Requirements
### Testnet Validation (current)
- [x] PoS staking working (first PoS block at height 12,382)
- [x] Alias registration via wallet RPC confirmed
- [x] Batch registration script built and tested
- [x] Priority name list generated from HNS data (90,041 names)
- [ ] Multi-wallet parallel registration tested
- [ ] Authority key for short names (<6 chars) tested
- [ ] Full 90K registration completed on testnet
- [ ] Explorer confirms all names visible
- [ ] LNS resolves registered names
### Mainnet Requirements
- [ ] Multi-sig wallet created for reserved names
- [ ] Genesis transaction plan (SWAP wallet → namereg wallets)
- [ ] Authority key provisioned for short-name registration
- [ ] Ansible playbook for deploying namereg wallets on prod
- [ ] Monitoring: alias count dashboard, registration rate, failures
## Alias Comment Format
All reserved names use this comment format for identification:
```
v=lthn1;type=reserved;reason=hns-protected
```
This allows:
- LNS to identify reserved vs user-registered names
- Future tools to query reserved names
- Governance decisions (release to brand owners) to be automated
## Daemon Configuration
PoS staking requires `--rpc-ignore-offline` when the daemon has no peers:
```
lethean-chain-node --rpc-ignore-offline --do-pos-mining
```
Without this flag, the daemon refuses PoS mining requests when disconnected.
## Batch Registration Tool
```bash
# Generate priority list from HNS data
python3 tools/generate-name-list.py
# Register names (3s delay, checks balance every 10)
bash tools/register-reserved.sh /tmp/protected-names-long.txt http://127.0.0.1:46944/json_rpc 10 3
```
Tool location: `docker/tools/register-reserved.sh`
## Option B: TLD Registrar Model (Recommended)
Instead of racing to pre-register 90K names, change one constant to make
ALL alias registration require the authority key:
```c
// currency_config.h — one line change
#define ALIAS_MINIMUM_PUBLIC_SHORT_NAME_ALLOWED 64 // was 6
```
This makes Lethean a proper TLD registrar — every name under `.lthn`
requires authority signature. No squatting possible at any length.
### Why This Is Better
| Pre-reg (Option A) | Registrar (Option B) |
|---------------------|----------------------|
| Race against squatters | No race — authority controls all |
| 90K transactions needed | Zero pre-registration needed |
| ~90K LTHN cost | Zero cost |
| Only covers known names | Covers ALL names, forever |
| New brands unprotected | New brands protected by default |
### Registrar Portal Flow
1. User requests `@myname` via website or CLI
2. Portal checks: not taken, not reserved, not offensive
3. User pays registration fee (1 LTHN + portal fee if desired)
4. Authority key signs the registration transaction
5. Name goes live on chain within 1 block
### Revenue Potential
| Name Type | Price |
|-----------|-------|
| Standard (6+ chars) | 1 LTHN (chain fee only) |
| Short (3-5 chars) | 10-100 LTHN (premium) |
| Ultra-short (1-2 chars) | Auction or reserved |
### Implementation
- **Hardfork:** Change `ALIAS_MINIMUM_PUBLIC_SHORT_NAME_ALLOWED` to 64
- **Portal:** Web API that accepts requests, validates, signs with authority key
- **Key security:** Authority private key in HSM or multi-sig, never on a hot server
- **Delegation:** Portal signs, daemon validates — separation of concerns
### Why Lethean Should Be a Registrar
- Lethean owns `.lthn` on Handshake — it IS the TLD operator
- Names route real traffic (VPN, DNS, service discovery)
- A curated namespace is trustworthy; a squatted one is worthless
- Every TLD in the world works this way — `.com`, `.co.uk`, `.eth`
- Revenue stream from name sales funds network development
### Migration Path
1. Testnet: validate both approaches (pre-reg + registrar)
2. HF proposal: include the constant change in next hardfork
3. Build portal: simple web UI + authority signing service
4. Mainnet launch: registrar model active from HF activation
5. Pre-reg only needed for names registered BEFORE the HF
## Risk Mitigations
| Risk | Mitigation |
|------|-----------|
| Tx pool congestion | Multiple wallets, 3s delay, batch checkpoints |
| Insufficient funds | Staking covers ongoing costs, seed from genesis |
| Authority key compromise | Multi-sig for the key, not single holder |
| Name disputes post-launch | Governance process for brand transfers |
| Testnet/mainnet drift | Same tooling, same scripts, validated on testnet first |
## Timeline
| Phase | When | Duration |
|-------|------|----------|
| Testnet validation | Now (Apr 2026) | 1-2 weeks |
| Mainnet genesis | TBD (Darbs approval) | Day 0 |
| HF warmup | Day 0-7 | 1 week |
| Batch registration | Day 7+ | 1-4 days (with parallel wallets) |
| Full coverage | Day 14 | All 90K protected |

260
README.md
View file

@ -1,120 +1,196 @@
# Lethean Network—Ethics, Encoded. [![Coverity Scan](https://scan.coverity.com/projects/18767/badge.svg)](https://scan.coverity.com/projects/zanoproject)
[![Discord](https://img.shields.io/discord/538361472691077130?label=discord&logo=discord)](https://discord.gg/wE3rmYY)
> We are building upto a mainnet launch in 2026, documentation written as if mainnet is live.
A buildkit for deploying confidential information networks and commerce systems with immutable auditability.
Free for commercial, private, and patent use, self-host or join the community-run network that guarantees participant sovereignty by design.
[![Discord](https://img.shields.io/discord/379876792003067906?label=discord&logo=discord)](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 |
## Cloning ## Cloning
Be sure to clone the repository properly, with `--recursive` flag, or you'll get angry:<br/> Be sure to clone the repository properly:\
`git clone --recursive https://github.com/letheanVPN/blockchain.git` `$ git clone --recursive https://github.com/hyle-team/zano.git`
# Building # Building
--------
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.
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. ### 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 |
The final packages are created as they are due to a historical distribution method used in china: USB Stick, CD, DVD, etc. 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.
We use CPack, so our packages are self-contained, have searchable HTML documentation, and are ready to be installed on any system. <br />
To skip the packing step, use `make build` as defined in the section below for Advanced Build Customization ### Linux
## Simple Workflow Builds (Recommended) Recommended OS versions: Ubuntu 20.04, 22.04 LTS.
For most use cases, these two commands are all you need. They handle the entire build process from start to finish. 1. Prerequisites
* **Build for Mainnet:** [*server version*]
```shell
make mainnet 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*]
* **Build for Testnet:** 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
```shell
make testnet
```
## Creating Release Packages Make sure you have correct versions installed (see 'Dependencies' section above):
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. cmake --version && gcc --version
```shell 3. Clone Zano into a local folder\
make release TESTNET=1 (If for some reason you need to use alternative Zano branch, change 'master' to the required branch name.)
```
The final packages will be located in the `build/packages/` directory git clone --recursive https://github.com/hyle-team/zano.git -b master
## Advanced Build Customization (Makefile Variables) In the following steps we assume that you cloned Zano into '~/zano' folder in your home directory.
For advanced use cases, you can override variables in the `Makefile` to customize the build process. 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 a `testnet` version:** curl -OL https://archives.boost.io/release/1.84.0/source/boost_1_84_0.tar.bz2
```shell echo "cc4b893acf645c9d4b698e9a0f08ca8846aa5d6c68275c14c3e7949c24109454 boost_1_84_0.tar.bz2" | shasum -c && tar -xjf boost_1_84_0.tar.bz2
make build TESTNET=1 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
* **Build a statically-linked version:** ./b2 && cd ..
```shell Make sure that you see "The Boost C++ Libraries were successfully built!" message at the end.
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
```
| Variable | Description | Default Value | 5. Install Qt\
|--------------------|------------------------------------------------------------------------|-------------------------| (*GUI version only, skip this step if you're building server version*)
| `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. | |
## Cleaning the Build Directory [*GUI version*]
ALWAYS USE `make clean` to clean the build directory, manually deleting the `build/release`, `build/SOME_FOLDER` will cause you issues. 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
Our `make clean` triggers a cmake script that completely resets the build directory &amp; 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`
You can NUKE the build directory with `make clean-build` which is `rm -rf build`. 6. Install OpenSSL
If you do manually delete build folders and get CMake errors (if you have compiled anything previously, you will), We recommend installing OpenSSL v1.1.1w locally unless you would like to use the same version system-wide.\
the ConanPresets.json file has entries in the `include` property, delete them all and try again. (Assuming that `$HOME` environment variable is set to your home directory. Otherwise, edit line 4 accordingly.)
This happens because CMakePresets.json includes ConanPresets.json, that has the list of toolchains to use that gets populated during the CMake config step, curl -OL https://www.openssl.org/source/openssl-1.1.1w.tar.gz
when you manually delete a folder, the toolchain is now a broken path, and CMake throws a fatal error. 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 ..
7. [*OPTIONAL*] Set global environment variables for convenient use\
For instance, by adding the following lines to `~/.bashrc`
[*server version*]
export BOOST_ROOT=/home/user/boost_1_84_0
export OPENSSL_ROOT_DIR=/home/user/openssl
[*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 />

79
cmake/CPackConfig.cmake Normal file
View file

@ -0,0 +1,79 @@
if(CMAKE_BUILD_TYPE STREQUAL "Release")
set(CPACK_PACKAGE_NAME "${package_name}")
set(CPACK_PACKAGE_VENDOR "${package_vendor}")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${package_description}")
set(CPACK_PACKAGE_VERSION "${BUILD_VERSION}")
set(CPACK_PACKAGE_CONTACT "${package_contact}")
set(CPACK_PACKAGE_HOMEPAGE_URL "${package_website}")
#set(CPACK_PACKAGING_INSTALL_PREFIX "/usr/local") # Linux/macOS default
#if(WIN32)
# set(CPACK_PACKAGING_INSTALL_PREFIX "C:/Program Files/${PROJECT_NAME}")
#endif()
if(APPLE)
if("${package_macos_installer}" STREQUAL "DMG")
# set(CPACK_GENERATOR "DragNDrop")
# set(CPACK_DMG_BACKGROUND_IMAGE "${CMAKE_SOURCE_DIR}/resources/dmg_background.png")
# set(CPACK_DMG_VOLUME_NAME "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION}")
# message(STATUS "Registered CPACK_GENERATOR: DragNDrop")
else ()
# set(CPACK_GENERATOR "productbuild")
# set(CPACK_PRODUCTBUILD_IDENTIFIER "${package_macos_pkg_productbuild_identifier}")
# set(CPACK_PRODUCTBUILD_SIGNING_IDENTITY "Developer ID Installer: Your Company (TEAMID)")
# message(STATUS "Registered CPACK_GENERATOR: productbuild")
endif ()
elseif(WIN32)
# set(CPACK_GENERATOR "WIX")
# message(STATUS "Registered CPACK_GENERATOR: WIX")
# 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}")
# postinstall script (e.g., to register a systemd service)
# set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
# "${CMAKE_SOURCE_DIR}/scripts/postinstall.sh")
endif()
list(APPEND CPACK_GENERATOR "TXZ" "ZIP")
message(STATUS "Registered CPACK_GENERATOR: tgz")
message(STATUS "Registered CPACK_GENERATOR: zip")
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)
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_PACKAGE_DIRECTORY "${CMAKE_BINARY_DIR}/packages")
install(FILES README.md LICENSE.txt
DESTINATION "share/doc/${PROJECT_NAME}"
)
set(_arch "${CMAKE_SYSTEM_PROCESSOR}")
if(_arch MATCHES "AMD64|x86_64")
set(_arch "x86_64")
elseif(_arch MATCHES "arm64|aarch64")
set(_arch "arm64")
endif()
string(TOLOWER "${CMAKE_SYSTEM_NAME}" _sys_name_lc)
set(CPACK_PACKAGE_FILE_NAME
"${package_name}-${CPACK_PACKAGE_VERSION}-${_sys_name_lc}-${_arch}")
include(CPack)
endif()

45
cmake/DocBuilder.cmake Normal file
View file

@ -0,0 +1,45 @@
set(MKDOCS_SRC "${CMAKE_SOURCE_DIR}/docs")
set(MKDOCS_OUT "${CMAKE_BINARY_DIR}/../docs")
message("MKDocs src: ${MKDOCS_SRC} > ${MKDOCS_OUT}")
file(MAKE_DIRECTORY "${MKDOCS_OUT}")
add_custom_target(docs
COMMAND ${CMAKE_COMMAND} -E env PYTHONUNBUFFERED=1
mkdocs build
--clean
--site-dir "${MKDOCS_OUT}"
--config-file "${MKDOCS_SRC}/mkdocs.yml"
WORKING_DIRECTORY "${MKDOCS_SRC}"
COMMENT "Generating documentation with MkDocs"
VERBATIM
)
# Optional install step
install(DIRECTORY "${MKDOCS_OUT}/"
DESTINATION "share/doc/${PROJECT_NAME}")
add_custom_target(install-docs
DEPENDS docs
COMMAND "${CMAKE_COMMAND}" --install . --component docs
COMMENT "Installing documentation")
# Name of the target that launches the dev server
add_custom_target(
serve_docs # invoke with `make serve_docs`
COMMAND ${CMAKE_COMMAND} -E env PYTHONUNBUFFERED=1
# On Windows we need to run the command through the shell
# so that the `&&` operator works correctly.
${CMAKE_COMMAND} -E env
mkdocs serve
--dev-addr "127.0.0.1:8000" # optional explicit bind address
--watch "${MKDOCS_SRC}" # watch source files for changes
--config-file "${MKDOCS_SRC}/mkdocs.yml"
WORKING_DIRECTORY "${MKDOCS_SRC}"
USES_TERMINAL # tells CMake to attach the child process to the console
COMMENT "Starting MkDocs livepreview server (CtrlC to stop)"
VERBATIM
)
add_dependencies(serve_docs docs) # ensures the static site is uptodate before serving

682
cmake/conan_provider.cmake Normal file
View file

@ -0,0 +1,682 @@
# The MIT License (MIT)
#
# Copyright (c) 2024 JFrog
#
# 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.
set(CONAN_MINIMUM_VERSION 2.0.5)
# Create a new policy scope and set the minimum required cmake version so the
# features behind a policy setting like if(... IN_LIST ...) behaves as expected
# even if the parent project does not specify a minimum cmake version or a minimum
# version less than this module requires (e.g. 3.0) before the first project() call.
# (see: https://cmake.org/cmake/help/latest/variable/CMAKE_PROJECT_TOP_LEVEL_INCLUDES.html)
#
# The policy-affecting calls like cmake_policy(SET...) or `cmake_minimum_required` only
# affects the current policy scope, i.e. between the PUSH and POP in this case.
#
# https://cmake.org/cmake/help/book/mastering-cmake/chapter/Policies.html#the-policy-stack
cmake_policy(PUSH)
cmake_minimum_required(VERSION 3.24)
function(detect_os os os_api_level os_sdk os_subsystem os_version)
# it could be cross compilation
message(STATUS "CMake-Conan: cmake_system_name=${CMAKE_SYSTEM_NAME}")
if(CMAKE_SYSTEM_NAME AND NOT CMAKE_SYSTEM_NAME STREQUAL "Generic")
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(${os} Macos PARENT_SCOPE)
elseif(CMAKE_SYSTEM_NAME STREQUAL "QNX")
set(${os} Neutrino PARENT_SCOPE)
elseif(CMAKE_SYSTEM_NAME STREQUAL "CYGWIN")
set(${os} Windows PARENT_SCOPE)
set(${os_subsystem} cygwin PARENT_SCOPE)
elseif(CMAKE_SYSTEM_NAME MATCHES "^MSYS")
set(${os} Windows PARENT_SCOPE)
set(${os_subsystem} msys2 PARENT_SCOPE)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
# https://github.com/emscripten-core/emscripten/blob/4.0.6/cmake/Modules/Platform/Emscripten.cmake#L17C1-L17C34
set(${os} Emscripten PARENT_SCOPE)
else()
set(${os} ${CMAKE_SYSTEM_NAME} PARENT_SCOPE)
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Android")
if(DEFINED ANDROID_PLATFORM)
string(REGEX MATCH "[0-9]+" _os_api_level ${ANDROID_PLATFORM})
elseif(DEFINED CMAKE_SYSTEM_VERSION)
set(_os_api_level ${CMAKE_SYSTEM_VERSION})
endif()
message(STATUS "CMake-Conan: android api level=${_os_api_level}")
set(${os_api_level} ${_os_api_level} PARENT_SCOPE)
endif()
if(CMAKE_SYSTEM_NAME MATCHES "Darwin|iOS|tvOS|watchOS")
# CMAKE_OSX_SYSROOT contains the full path to the SDK for MakeFile/Ninja
# generators, but just has the original input string for Xcode.
if(NOT IS_DIRECTORY ${CMAKE_OSX_SYSROOT})
set(_os_sdk ${CMAKE_OSX_SYSROOT})
else()
if(CMAKE_OSX_SYSROOT MATCHES Simulator)
set(apple_platform_suffix simulator)
else()
set(apple_platform_suffix os)
endif()
if(CMAKE_OSX_SYSROOT MATCHES AppleTV)
set(_os_sdk "appletv${apple_platform_suffix}")
elseif(CMAKE_OSX_SYSROOT MATCHES iPhone)
set(_os_sdk "iphone${apple_platform_suffix}")
elseif(CMAKE_OSX_SYSROOT MATCHES Watch)
set(_os_sdk "watch${apple_platform_suffix}")
endif()
endif()
if(DEFINED os_sdk)
message(STATUS "CMake-Conan: cmake_osx_sysroot=${CMAKE_OSX_SYSROOT}")
set(${os_sdk} ${_os_sdk} PARENT_SCOPE)
endif()
if(DEFINED CMAKE_OSX_DEPLOYMENT_TARGET)
message(STATUS "CMake-Conan: cmake_osx_deployment_target=${CMAKE_OSX_DEPLOYMENT_TARGET}")
set(${os_version} ${CMAKE_OSX_DEPLOYMENT_TARGET} PARENT_SCOPE)
endif()
endif()
endif()
endfunction()
function(detect_arch arch)
# CMAKE_OSX_ARCHITECTURES can contain multiple architectures, but Conan only supports one.
# Therefore this code only finds one. If the recipes support multiple architectures, the
# build will work. Otherwise, there will be a linker error for the missing architecture(s).
if(DEFINED CMAKE_OSX_ARCHITECTURES)
string(REPLACE " " ";" apple_arch_list "${CMAKE_OSX_ARCHITECTURES}")
list(LENGTH apple_arch_list apple_arch_count)
if(apple_arch_count GREATER 1)
message(WARNING "CMake-Conan: Multiple architectures detected, this will only work if Conan recipe(s) produce fat binaries.")
endif()
endif()
if(CMAKE_SYSTEM_NAME MATCHES "Darwin|iOS|tvOS|watchOS" AND NOT CMAKE_OSX_ARCHITECTURES STREQUAL "")
set(host_arch ${CMAKE_OSX_ARCHITECTURES})
elseif(MSVC)
set(host_arch ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID})
else()
set(host_arch ${CMAKE_SYSTEM_PROCESSOR})
endif()
if(host_arch MATCHES "aarch64|arm64|ARM64")
set(_arch armv8)
elseif(host_arch MATCHES "armv7|armv7-a|armv7l|ARMV7")
set(_arch armv7)
elseif(host_arch MATCHES armv7s)
set(_arch armv7s)
elseif(host_arch MATCHES "i686|i386|X86")
set(_arch x86)
elseif(host_arch MATCHES "AMD64|amd64|x86_64|x64")
set(_arch x86_64)
endif()
if(EMSCRIPTEN)
# https://github.com/emscripten-core/emscripten/blob/4.0.6/cmake/Modules/Platform/Emscripten.cmake#L294C1-L294C80
set(_arch wasm)
endif()
message(STATUS "CMake-Conan: cmake_system_processor=${_arch}")
set(${arch} ${_arch} PARENT_SCOPE)
endfunction()
function(detect_cxx_standard cxx_standard)
set(${cxx_standard} ${CMAKE_CXX_STANDARD} PARENT_SCOPE)
if(CMAKE_CXX_EXTENSIONS)
set(${cxx_standard} "gnu${CMAKE_CXX_STANDARD}" PARENT_SCOPE)
endif()
endfunction()
macro(detect_gnu_libstdcxx)
# _conan_is_gnu_libstdcxx true if GNU libstdc++
check_cxx_source_compiles("
#include <cstddef>
#if !defined(__GLIBCXX__) && !defined(__GLIBCPP__)
static_assert(false);
#endif
int main(){}" _conan_is_gnu_libstdcxx)
# _conan_gnu_libstdcxx_is_cxx11_abi true if C++11 ABI
check_cxx_source_compiles("
#include <string>
static_assert(sizeof(std::string) != sizeof(void*), \"using libstdc++\");
int main () {}" _conan_gnu_libstdcxx_is_cxx11_abi)
set(_conan_gnu_libstdcxx_suffix "")
if(_conan_gnu_libstdcxx_is_cxx11_abi)
set(_conan_gnu_libstdcxx_suffix "11")
endif()
unset (_conan_gnu_libstdcxx_is_cxx11_abi)
endmacro()
macro(detect_libcxx)
# _conan_is_libcxx true if LLVM libc++
check_cxx_source_compiles("
#include <cstddef>
#if !defined(_LIBCPP_VERSION)
static_assert(false);
#endif
int main(){}" _conan_is_libcxx)
endmacro()
function(detect_lib_cxx lib_cxx)
if(CMAKE_SYSTEM_NAME STREQUAL "Android")
message(STATUS "CMake-Conan: android_stl=${CMAKE_ANDROID_STL_TYPE}")
set(${lib_cxx} ${CMAKE_ANDROID_STL_TYPE} PARENT_SCOPE)
return()
endif()
include(CheckCXXSourceCompiles)
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
detect_gnu_libstdcxx()
set(${lib_cxx} "libstdc++${_conan_gnu_libstdcxx_suffix}" PARENT_SCOPE)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang")
set(${lib_cxx} "libc++" PARENT_SCOPE)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_SYSTEM_NAME MATCHES "Windows")
# Check for libc++
detect_libcxx()
if(_conan_is_libcxx)
set(${lib_cxx} "libc++" PARENT_SCOPE)
return()
endif()
# Check for libstdc++
detect_gnu_libstdcxx()
if(_conan_is_gnu_libstdcxx)
set(${lib_cxx} "libstdc++${_conan_gnu_libstdcxx_suffix}" PARENT_SCOPE)
return()
endif()
# TODO: it would be an error if we reach this point
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
# Do nothing - compiler.runtime and compiler.runtime_type
# should be handled separately: https://github.com/conan-io/cmake-conan/pull/516
return()
else()
# TODO: unable to determine, ask user to provide a full profile file instead
endif()
endfunction()
function(detect_compiler compiler compiler_version compiler_runtime compiler_runtime_type)
if(DEFINED CMAKE_CXX_COMPILER_ID)
set(_compiler ${CMAKE_CXX_COMPILER_ID})
set(_compiler_version ${CMAKE_CXX_COMPILER_VERSION})
else()
if(NOT DEFINED CMAKE_C_COMPILER_ID)
message(FATAL_ERROR "C or C++ compiler not defined")
endif()
set(_compiler ${CMAKE_C_COMPILER_ID})
set(_compiler_version ${CMAKE_C_COMPILER_VERSION})
endif()
message(STATUS "CMake-Conan: CMake compiler=${_compiler}")
message(STATUS "CMake-Conan: CMake compiler version=${_compiler_version}")
if(_compiler MATCHES MSVC)
set(_compiler "msvc")
string(SUBSTRING ${MSVC_VERSION} 0 3 _compiler_version)
# Configure compiler.runtime and compiler.runtime_type settings for MSVC
if(CMAKE_MSVC_RUNTIME_LIBRARY)
set(_msvc_runtime_library ${CMAKE_MSVC_RUNTIME_LIBRARY})
else()
set(_msvc_runtime_library MultiThreaded$<$<CONFIG:Debug>:Debug>DLL) # default value documented by CMake
endif()
set(_KNOWN_MSVC_RUNTIME_VALUES "")
list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreaded MultiThreadedDLL)
list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreadedDebug MultiThreadedDebugDLL)
list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreaded$<$<CONFIG:Debug>:Debug> MultiThreaded$<$<CONFIG:Debug>:Debug>DLL)
# only accept the 6 possible values, otherwise we don't don't know to map this
if(NOT _msvc_runtime_library IN_LIST _KNOWN_MSVC_RUNTIME_VALUES)
message(FATAL_ERROR "CMake-Conan: unable to map MSVC runtime: ${_msvc_runtime_library} to Conan settings")
endif()
# Runtime is "dynamic" in all cases if it ends in DLL
if(_msvc_runtime_library MATCHES ".*DLL$")
set(_compiler_runtime "dynamic")
else()
set(_compiler_runtime "static")
endif()
message(STATUS "CMake-Conan: CMake compiler.runtime=${_compiler_runtime}")
# Only define compiler.runtime_type when explicitly requested
# If a generator expression is used, let Conan handle it conditional on build_type
if(NOT _msvc_runtime_library MATCHES "<CONFIG:Debug>:Debug>")
if(_msvc_runtime_library MATCHES "Debug")
set(_compiler_runtime_type "Debug")
else()
set(_compiler_runtime_type "Release")
endif()
message(STATUS "CMake-Conan: CMake compiler.runtime_type=${_compiler_runtime_type}")
endif()
unset(_KNOWN_MSVC_RUNTIME_VALUES)
elseif(_compiler MATCHES AppleClang)
set(_compiler "apple-clang")
string(REPLACE "." ";" VERSION_LIST ${_compiler_version})
list(GET VERSION_LIST 0 _compiler_version)
elseif(_compiler MATCHES Clang)
set(_compiler "clang")
string(REPLACE "." ";" VERSION_LIST ${_compiler_version})
list(GET VERSION_LIST 0 _compiler_version)
elseif(_compiler MATCHES GNU)
set(_compiler "gcc")
string(REPLACE "." ";" VERSION_LIST ${_compiler_version})
list(GET VERSION_LIST 0 _compiler_version)
endif()
message(STATUS "CMake-Conan: [settings] compiler=${_compiler}")
message(STATUS "CMake-Conan: [settings] compiler.version=${_compiler_version}")
if (_compiler_runtime)
message(STATUS "CMake-Conan: [settings] compiler.runtime=${_compiler_runtime}")
endif()
if (_compiler_runtime_type)
message(STATUS "CMake-Conan: [settings] compiler.runtime_type=${_compiler_runtime_type}")
endif()
set(${compiler} ${_compiler} PARENT_SCOPE)
set(${compiler_version} ${_compiler_version} PARENT_SCOPE)
set(${compiler_runtime} ${_compiler_runtime} PARENT_SCOPE)
set(${compiler_runtime_type} ${_compiler_runtime_type} PARENT_SCOPE)
endfunction()
function(detect_build_type build_type)
get_property(multiconfig_generator GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(NOT multiconfig_generator)
# Only set when we know we are in a single-configuration generator
# Note: we may want to fail early if `CMAKE_BUILD_TYPE` is not defined
set(${build_type} ${CMAKE_BUILD_TYPE} PARENT_SCOPE)
endif()
endfunction()
macro(set_conan_compiler_if_appleclang lang command output_variable)
if(CMAKE_${lang}_COMPILER_ID STREQUAL "AppleClang")
execute_process(COMMAND xcrun --find ${command}
OUTPUT_VARIABLE _xcrun_out OUTPUT_STRIP_TRAILING_WHITESPACE)
cmake_path(GET _xcrun_out PARENT_PATH _xcrun_toolchain_path)
cmake_path(GET CMAKE_${lang}_COMPILER PARENT_PATH _compiler_parent_path)
if ("${_xcrun_toolchain_path}" STREQUAL "${_compiler_parent_path}")
set(${output_variable} "")
endif()
unset(_xcrun_out)
unset(_xcrun_toolchain_path)
unset(_compiler_parent_path)
endif()
endmacro()
macro(append_compiler_executables_configuration)
set(_conan_c_compiler "")
set(_conan_cpp_compiler "")
set(_conan_rc_compiler "")
set(_conan_compilers_list "")
if(CMAKE_C_COMPILER)
set(_conan_c_compiler "\"c\":\"${CMAKE_C_COMPILER}\"")
set_conan_compiler_if_appleclang(C cc _conan_c_compiler)
list(APPEND _conan_compilers_list ${_conan_c_compiler})
else()
message(WARNING "CMake-Conan: The C compiler is not defined. "
"Please define CMAKE_C_COMPILER or enable the C language.")
endif()
if(CMAKE_CXX_COMPILER)
set(_conan_cpp_compiler "\"cpp\":\"${CMAKE_CXX_COMPILER}\"")
set_conan_compiler_if_appleclang(CXX c++ _conan_cpp_compiler)
list(APPEND _conan_compilers_list ${_conan_cpp_compiler})
else()
message(WARNING "CMake-Conan: The C++ compiler is not defined. "
"Please define CMAKE_CXX_COMPILER or enable the C++ language.")
endif()
if(CMAKE_RC_COMPILER)
set(_conan_rc_compiler "\"rc\":\"${CMAKE_RC_COMPILER}\"")
list(APPEND _conan_compilers_list ${_conan_rc_compiler})
# Not necessary to warn if RC not defined
endif()
if(NOT "x${_conan_compilers_list}" STREQUAL "x")
string(REPLACE ";" "," _conan_compilers_list "${_conan_compilers_list}")
string(APPEND profile "tools.build:compiler_executables={${_conan_compilers_list}}\n")
endif()
unset(_conan_c_compiler)
unset(_conan_cpp_compiler)
unset(_conan_rc_compiler)
unset(_conan_compilers_list)
endmacro()
function(detect_host_profile output_file)
detect_os(os os_api_level os_sdk os_subsystem os_version)
detect_arch(arch)
detect_compiler(compiler compiler_version compiler_runtime compiler_runtime_type)
detect_cxx_standard(compiler_cppstd)
detect_lib_cxx(compiler_libcxx)
detect_build_type(build_type)
set(profile "")
string(APPEND profile "[settings]\n")
if(arch)
string(APPEND profile arch=${arch} "\n")
endif()
if(os)
string(APPEND profile os=${os} "\n")
endif()
if(os_api_level)
string(APPEND profile os.api_level=${os_api_level} "\n")
endif()
if(os_version)
string(APPEND profile os.version=${os_version} "\n")
endif()
if(os_sdk)
string(APPEND profile os.sdk=${os_sdk} "\n")
endif()
if(os_subsystem)
string(APPEND profile os.subsystem=${os_subsystem} "\n")
endif()
if(compiler)
string(APPEND profile compiler=${compiler} "\n")
endif()
if(compiler_version)
string(APPEND profile compiler.version=${compiler_version} "\n")
endif()
if(compiler_runtime)
string(APPEND profile compiler.runtime=${compiler_runtime} "\n")
endif()
if(compiler_runtime_type)
string(APPEND profile compiler.runtime_type=${compiler_runtime_type} "\n")
endif()
if(compiler_cppstd)
string(APPEND profile compiler.cppstd=${compiler_cppstd} "\n")
endif()
if(compiler_libcxx)
string(APPEND profile compiler.libcxx=${compiler_libcxx} "\n")
endif()
if(build_type)
string(APPEND profile "build_type=${build_type}\n")
endif()
if(NOT DEFINED output_file)
set(file_name "${CMAKE_BINARY_DIR}/profile")
else()
set(file_name ${output_file})
endif()
string(APPEND profile "[conf]\n")
string(APPEND profile "tools.cmake.cmaketoolchain:generator=${CMAKE_GENERATOR}\n")
# propagate compilers via profile
append_compiler_executables_configuration()
if(os STREQUAL "Android")
string(APPEND profile "tools.android:ndk_path=${CMAKE_ANDROID_NDK}\n")
endif()
message(STATUS "CMake-Conan: Creating profile ${file_name}")
file(WRITE ${file_name} ${profile})
message(STATUS "CMake-Conan: Profile: \n${profile}")
endfunction()
function(conan_profile_detect_default)
message(STATUS "CMake-Conan: Checking if a default profile exists")
execute_process(COMMAND ${CONAN_COMMAND} profile path default
RESULT_VARIABLE return_code
OUTPUT_VARIABLE conan_stdout
ERROR_VARIABLE conan_stderr
ECHO_ERROR_VARIABLE # show the text output regardless
ECHO_OUTPUT_VARIABLE
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
if(NOT ${return_code} EQUAL "0")
message(STATUS "CMake-Conan: The default profile doesn't exist, detecting it.")
execute_process(COMMAND ${CONAN_COMMAND} profile detect
RESULT_VARIABLE return_code
OUTPUT_VARIABLE conan_stdout
ERROR_VARIABLE conan_stderr
ECHO_ERROR_VARIABLE # show the text output regardless
ECHO_OUTPUT_VARIABLE
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
endif()
endfunction()
function(conan_install)
set(conan_output_folder ${CMAKE_BINARY_DIR}/conan)
# Invoke "conan install" with the provided arguments
set(conan_args ${conan_args} -of=${conan_output_folder})
message(STATUS "CMake-Conan: conan install ${CMAKE_SOURCE_DIR} ${conan_args} ${ARGN}")
# In case there was not a valid cmake executable in the PATH, we inject the
# same we used to invoke the provider to the PATH
if(DEFINED PATH_TO_CMAKE_BIN)
set(old_path $ENV{PATH})
set(ENV{PATH} "$ENV{PATH}:${PATH_TO_CMAKE_BIN}")
endif()
execute_process(COMMAND ${CONAN_COMMAND} install ${CMAKE_SOURCE_DIR} ${conan_args} ${ARGN} --format=json
RESULT_VARIABLE return_code
OUTPUT_VARIABLE conan_stdout
ERROR_VARIABLE conan_stderr
ECHO_ERROR_VARIABLE # show the text output regardless
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
if(DEFINED PATH_TO_CMAKE_BIN)
set(ENV{PATH} "${old_path}")
endif()
if(NOT "${return_code}" STREQUAL "0")
message(FATAL_ERROR "Conan install failed='${return_code}'")
endif()
# the files are generated in a folder that depends on the layout used, if
# one is specified, but we don't know a priori where this is.
# TODO: this can be made more robust if Conan can provide this in the json output
string(JSON conan_generators_folder GET "${conan_stdout}" graph nodes 0 generators_folder)
cmake_path(CONVERT ${conan_generators_folder} TO_CMAKE_PATH_LIST conan_generators_folder)
message(STATUS "CMake-Conan: CONAN_GENERATORS_FOLDER=${conan_generators_folder}")
set_property(GLOBAL PROPERTY CONAN_GENERATORS_FOLDER "${conan_generators_folder}")
# reconfigure on conanfile changes
string(JSON conanfile GET "${conan_stdout}" graph nodes 0 label)
message(STATUS "CMake-Conan: CONANFILE=${CMAKE_SOURCE_DIR}/${conanfile}")
set_property(DIRECTORY ${CMAKE_SOURCE_DIR} APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/${conanfile}")
# success
set_property(GLOBAL PROPERTY CONAN_INSTALL_SUCCESS TRUE)
endfunction()
function(conan_get_version conan_command conan_current_version)
execute_process(
COMMAND ${conan_command} --version
OUTPUT_VARIABLE conan_output
RESULT_VARIABLE conan_result
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(conan_result)
message(FATAL_ERROR "CMake-Conan: Error when trying to run Conan")
endif()
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" conan_version ${conan_output})
set(${conan_current_version} ${conan_version} PARENT_SCOPE)
endfunction()
function(conan_version_check)
set(options )
set(one_value_args MINIMUM CURRENT)
set(multi_value_args )
cmake_parse_arguments(conan_version_check
"${options}" "${one_value_args}" "${multi_value_args}" ${ARGN})
if(NOT conan_version_check_MINIMUM)
message(FATAL_ERROR "CMake-Conan: Required parameter MINIMUM not set!")
endif()
if(NOT conan_version_check_CURRENT)
message(FATAL_ERROR "CMake-Conan: Required parameter CURRENT not set!")
endif()
if(conan_version_check_CURRENT VERSION_LESS conan_version_check_MINIMUM)
message(FATAL_ERROR "CMake-Conan: Conan version must be ${conan_version_check_MINIMUM} or later")
endif()
endfunction()
macro(construct_profile_argument argument_variable profile_list)
set(${argument_variable} "")
if("${profile_list}" STREQUAL "CONAN_HOST_PROFILE")
set(_arg_flag "--profile:host=")
elseif("${profile_list}" STREQUAL "CONAN_BUILD_PROFILE")
set(_arg_flag "--profile:build=")
endif()
set(_profile_list "${${profile_list}}")
list(TRANSFORM _profile_list REPLACE "auto-cmake" "${CMAKE_BINARY_DIR}/conan_host_profile")
list(TRANSFORM _profile_list PREPEND ${_arg_flag})
set(${argument_variable} ${_profile_list})
unset(_arg_flag)
unset(_profile_list)
endmacro()
macro(conan_provide_dependency method package_name)
set_property(GLOBAL PROPERTY CONAN_PROVIDE_DEPENDENCY_INVOKED TRUE)
get_property(_conan_install_success GLOBAL PROPERTY CONAN_INSTALL_SUCCESS)
if(NOT _conan_install_success)
find_program(CONAN_COMMAND "conan" REQUIRED)
conan_get_version(${CONAN_COMMAND} CONAN_CURRENT_VERSION)
conan_version_check(MINIMUM ${CONAN_MINIMUM_VERSION} CURRENT ${CONAN_CURRENT_VERSION})
message(STATUS "CMake-Conan: first find_package() found. Installing dependencies with Conan")
if("default" IN_LIST CONAN_HOST_PROFILE OR "default" IN_LIST CONAN_BUILD_PROFILE)
conan_profile_detect_default()
endif()
if("auto-cmake" IN_LIST CONAN_HOST_PROFILE)
detect_host_profile(${CMAKE_BINARY_DIR}/conan_host_profile)
endif()
construct_profile_argument(_host_profile_flags CONAN_HOST_PROFILE)
construct_profile_argument(_build_profile_flags CONAN_BUILD_PROFILE)
if(EXISTS "${CMAKE_SOURCE_DIR}/conanfile.py")
file(READ "${CMAKE_SOURCE_DIR}/conanfile.py" outfile)
if(NOT "${outfile}" MATCHES ".*CMakeDeps.*")
message(WARNING "Cmake-conan: CMakeDeps generator was not defined in the conanfile")
endif()
set(generator "")
elseif (EXISTS "${CMAKE_SOURCE_DIR}/conanfile.txt")
file(READ "${CMAKE_SOURCE_DIR}/conanfile.txt" outfile)
if(NOT "${outfile}" MATCHES ".*CMakeDeps.*")
message(WARNING "Cmake-conan: CMakeDeps generator was not defined in the conanfile. "
"Please define the generator as it will be mandatory in the future")
endif()
set(generator "-g;CMakeDeps")
endif()
get_property(_multiconfig_generator GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(NOT _multiconfig_generator)
message(STATUS "CMake-Conan: Installing single configuration ${CMAKE_BUILD_TYPE}")
conan_install(${_host_profile_flags} ${_build_profile_flags} ${CONAN_INSTALL_ARGS} ${generator})
else()
message(STATUS "CMake-Conan: Installing both Debug and Release")
conan_install(${_host_profile_flags} ${_build_profile_flags} -s build_type=Release ${CONAN_INSTALL_ARGS} ${generator})
conan_install(${_host_profile_flags} ${_build_profile_flags} -s build_type=Debug ${CONAN_INSTALL_ARGS} ${generator})
endif()
unset(_host_profile_flags)
unset(_build_profile_flags)
unset(_multiconfig_generator)
unset(_conan_install_success)
else()
message(STATUS "CMake-Conan: find_package(${ARGV1}) found, 'conan install' already ran")
unset(_conan_install_success)
endif()
get_property(_conan_generators_folder GLOBAL PROPERTY CONAN_GENERATORS_FOLDER)
# Ensure that we consider Conan-provided packages ahead of any other,
# irrespective of other settings that modify the search order or search paths
# This follows the guidelines from the find_package documentation
# (https://cmake.org/cmake/help/latest/command/find_package.html):
# find_package (<PackageName> PATHS paths... NO_DEFAULT_PATH)
# find_package (<PackageName>)
# Filter out `REQUIRED` from the argument list, as the first call may fail
set(_find_args_${package_name} "${ARGN}")
list(REMOVE_ITEM _find_args_${package_name} "REQUIRED")
if(NOT "MODULE" IN_LIST _find_args_${package_name})
find_package(${package_name} ${_find_args_${package_name}} BYPASS_PROVIDER PATHS "${_conan_generators_folder}" NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
unset(_find_args_${package_name})
endif()
# Invoke find_package a second time - if the first call succeeded,
# this will simply reuse the result. If not, fall back to CMake default search
# behaviour, also allowing modules to be searched.
if(NOT ${package_name}_FOUND)
list(FIND CMAKE_MODULE_PATH "${_conan_generators_folder}" _index)
if(_index EQUAL -1)
list(PREPEND CMAKE_MODULE_PATH "${_conan_generators_folder}")
endif()
unset(_index)
find_package(${package_name} ${ARGN} BYPASS_PROVIDER)
list(REMOVE_ITEM CMAKE_MODULE_PATH "${_conan_generators_folder}")
endif()
endmacro()
cmake_language(
SET_DEPENDENCY_PROVIDER conan_provide_dependency
SUPPORTED_METHODS FIND_PACKAGE
)
macro(conan_provide_dependency_check)
set(_conan_provide_dependency_invoked FALSE)
get_property(_conan_provide_dependency_invoked GLOBAL PROPERTY CONAN_PROVIDE_DEPENDENCY_INVOKED)
if(NOT _conan_provide_dependency_invoked)
message(WARNING "Conan is correctly configured as dependency provider, "
"but Conan has not been invoked. Please add at least one "
"call to `find_package()`.")
if(DEFINED CONAN_COMMAND)
# supress warning in case `CONAN_COMMAND` was specified but unused.
set(_conan_command ${CONAN_COMMAND})
unset(_conan_command)
endif()
endif()
unset(_conan_provide_dependency_invoked)
endmacro()
# Add a deferred call at the end of processing the top-level directory
# to check if the dependency provider was invoked at all.
cmake_language(DEFER DIRECTORY "${CMAKE_SOURCE_DIR}" CALL conan_provide_dependency_check)
# Configurable variables for Conan profiles
set(CONAN_HOST_PROFILE "default;auto-cmake" CACHE STRING "Conan host profile")
set(CONAN_BUILD_PROFILE "default" CACHE STRING "Conan build profile")
set(CONAN_INSTALL_ARGS "--build=missing" CACHE STRING "Command line arguments for conan install")
find_program(_cmake_program NAMES cmake NO_PACKAGE_ROOT_PATH NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH NO_CMAKE_FIND_ROOT_PATH)
if(NOT _cmake_program)
get_filename_component(PATH_TO_CMAKE_BIN "${CMAKE_COMMAND}" DIRECTORY)
set(PATH_TO_CMAKE_BIN "${PATH_TO_CMAKE_BIN}" CACHE INTERNAL "Path where the CMake executable is")
endif()
cmake_policy(POP)

View file

@ -0,0 +1,9 @@
[settings]
os=Macos
arch=armv8
compiler=apple-clang
compiler.version=13
compiler.libcxx=libc++
[conf]

View file

@ -0,0 +1,8 @@
[settings]
os=Macos
arch=x86_64
compiler=apple-clang
compiler.version=13
compiler.libcxx=libc++
[conf]

View file

@ -0,0 +1,9 @@
[settings]
os=Linux
arch=armv8
compiler=gcc
compiler.version=11
compiler.libcxx=libstdc++11
[conf]
tools.cmake.cmaketoolchain:user_presets=False

View file

@ -0,0 +1,9 @@
[settings]
os=Linux
arch=x86_64
compiler=gcc
compiler.version=11
compiler.libcxx=libstdc++11
[conf]
tools.cmake.cmaketoolchain:user_presets=False

View file

@ -0,0 +1,10 @@
[settings]
arch=x86_64
compiler=msvc
compiler.cppstd=17
compiler.runtime=static
compiler.version=193
os=Windows
[conf]
tools.cmake.cmaketoolchain:user_presets=False

View file

@ -0,0 +1,8 @@
[settings]
arch=x86_64
compiler=msvc
compiler.cppstd=17
compiler.runtime=static
compiler.version=194
os=Windows
build_type=Release

View file

@ -1,7 +1,7 @@
import os import os
from conan import ConanFile from conan import ConanFile
from conan.tools.cmake import CMakeDeps, CMakeToolchain, CMake from conan.tools.cmake import cmake_layout, CMakeDeps, CMakeToolchain, CMake
class BlockchainConan(ConanFile): class BlockchainConan(ConanFile):
@ -11,39 +11,24 @@ class BlockchainConan(ConanFile):
options = { options = {
"static": [True, False], "static": [True, False],
"testnet": [True, False], "testnet": [True, False]
"ci": [True, False]
} }
default_options = { default_options = {
"static": False, "static": False,
"testnet": False, "testnet": False
"ci": False,
"boost/*:without_test": True
} }
tool_requires = [
"cmake/3.31.9"
]
requires = [ requires = [
"zlib/1.3.1", "zlib/1.3.1",
"boost/1.85.0", "boost/1.85.0",
"openssl/3.2.0", "openssl/3.2.0",
"miniupnpc/2.2.5", "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): def generate(self):
tc = CMakeToolchain(self) tc = CMakeToolchain(self)
tc.user_presets_path = False
os_val = str(self.settings.os).lower()
# arch_val = str(self.settings.arch).lower()
# compiler_val = str(self.settings.compiler).lower()
# tc.presets_prefix = f"{os_val}"
tc.user_presets_path = "ConanPresets.json"
tc.variables["STATIC"] = self.options.static tc.variables["STATIC"] = self.options.static
tc.variables["TESTNET"] = self.options.testnet tc.variables["TESTNET"] = self.options.testnet
# tc.preprocessor_definitions["TESTNET"] = None # tc.preprocessor_definitions["TESTNET"] = None
@ -54,17 +39,10 @@ class BlockchainConan(ConanFile):
deps.generate() deps.generate()
def layout(self): def layout(self):
if self.settings.compiler == "msvc": self.folders.generators = os.path.join("build", str(self.settings.build_type).lower(), "generators")
# For multi-config, all configurations go into the same "build" folder. self.folders.build = os.path.join("build", str(self.settings.build_type).lower())
self.folders.build = "build/release"
self.folders.generators = "build/release/generators"
else:
# For single-config, we create a subfolder for each build type.
build_type_str = str(self.settings.build_type).lower()
self.folders.build = os.path.join("build", build_type_str)
self.folders.generators = os.path.join(self.folders.build, "generators")
def build(self): def build(self):
cmake = CMake(self) cmake = CMake(self)
cmake.configure() cmake.configure()
cmake.build() cmake.build()

View file

@ -1,7 +1,6 @@
add_subdirectory(db) add_subdirectory(db)
add_subdirectory(ethereum) add_subdirectory(ethereum)
add_subdirectory(randomx)
if(USE_BITCOIN_SECP256K1_FOR_ECDSA) if(USE_BITCOIN_SECP256K1_FOR_ECDSA)
option(SECP256K1_BUILD_BENCHMARK "Build benchmarks." OFF) option(SECP256K1_BUILD_BENCHMARK "Build benchmarks." OFF)

View file

@ -28,7 +28,6 @@
#include <locale> #include <locale>
#include <cstdlib> #include <cstdlib>
#include <iomanip>
#include <map> #include <map>
#include <boost/uuid/uuid.hpp> #include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_io.hpp> #include <boost/uuid/uuid_io.hpp>

@ -1 +0,0 @@
Subproject commit cf15f4023ec8ddaa842f49111ba80ead1b5937f1

View file

@ -5,7 +5,7 @@ services:
build: build:
tags: tags:
- lthn/chain:testnet - lthn/chain:testnet
dockerfile: utils/docker/lthn-chain/Dockerfile dockerfile: utils/docker/images/lthn-chain/Dockerfile
context: . context: .
target: chain-service target: chain-service
args: args:

View file

@ -1,54 +0,0 @@
# Lethean Testnet Configuration
# Copy to .env and customise before running:
# cp .env.example .env
# docker compose -f docker-compose.pull.yml up -d
# Public hostname (used by explorer and trade frontend)
PUBLIC_HOST=localhost
# Wallet password (empty = no password, change for production)
WALLET_PASSWORD=
# Trade API JWT secret (CHANGE THIS for production)
JWT_SECRET=change-me-before-production
# Explorer database
EXPLORER_DB_USER=explorer
EXPLORER_DB_PASS=explorer
EXPLORER_DB_NAME=lethean_explorer
# Trade database
TRADE_DB_USER=trade
TRADE_DB_PASS=trade
TRADE_DB_NAME=lethean_trade
# Daemon log level (0=minimal, 1=normal, 2=detailed, 3=trace)
DAEMON_LOG_LEVEL=1
# Port overrides (defaults shown)
# DAEMON_RPC_PORT=46941
# DAEMON_P2P_PORT=46942
# WALLET_RPC_PORT=46944
# EXPLORER_PORT=3335
# TRADE_API_PORT=3336
# TRADE_FRONTEND_PORT=3338
# POOL_STRATUM_PORT=5555
# POOL_API_PORT=2117
# LNS_HTTP_PORT=5553
# LNS_DNS_PORT=5354
# === Exit Node Settings (docker-compose.exit.yml) ===
# Your public IP address (required for VPN exit node)
# EXIT_PUBLIC_IP=auto
# Exit node name (registered as on-chain alias)
# EXIT_NAME=my-exit-node
# Maximum VPN peers (WireGuard clients)
# EXIT_MAX_PEERS=25
# Timezone
# TZ=Europe/London
EXIT_PUBLIC_IP=203.0.113.50
EXIT_NAME=my-exit

View file

@ -1,52 +0,0 @@
# Lethean Testnet Configuration
# Copy to .env and customise before running:
# cp .env.example .env
# docker compose -f docker-compose.pull.yml up -d
# Public hostname (used by explorer and trade frontend)
PUBLIC_HOST=localhost
# Wallet password (empty = no password, change for production)
WALLET_PASSWORD=
# Trade API JWT secret (CHANGE THIS for production)
JWT_SECRET=change-me-before-production
# Explorer database
EXPLORER_DB_USER=explorer
EXPLORER_DB_PASS=explorer
EXPLORER_DB_NAME=lethean_explorer
# Trade database
TRADE_DB_USER=trade
TRADE_DB_PASS=trade
TRADE_DB_NAME=lethean_trade
# Daemon log level (0=minimal, 1=normal, 2=detailed, 3=trace)
DAEMON_LOG_LEVEL=1
# Port overrides (defaults shown)
# DAEMON_RPC_PORT=46941
# DAEMON_P2P_PORT=46942
# WALLET_RPC_PORT=46944
# EXPLORER_PORT=3335
# TRADE_API_PORT=3336
# TRADE_FRONTEND_PORT=3338
# POOL_STRATUM_PORT=5555
# POOL_API_PORT=2117
# LNS_HTTP_PORT=5553
# LNS_DNS_PORT=5354
# === Exit Node Settings (docker-compose.exit.yml) ===
# Your public IP address (required for VPN exit node)
# EXIT_PUBLIC_IP=auto
# Exit node name (registered as on-chain alias)
# EXIT_NAME=my-exit-node
# Maximum VPN peers (WireGuard clients)
# EXIT_MAX_PEERS=25
# Timezone
# TZ=Europe/London

View file

@ -1,38 +0,0 @@
# Cross-platform build for Lethean blockchain binaries
# Produces Linux x86_64 and ARM64 binaries
# macOS and Windows need native build environments or cross-compilation toolchains
#
# Usage:
# docker build -f Dockerfile.cross-build --target linux-x64 -o ./out .
# docker build -f Dockerfile.cross-build --target linux-arm64 -o ./out .
# === Base builder ===
FROM ubuntu:24.04 AS base-builder
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y \
build-essential cmake git python3 python3-pip \
libboost-all-dev libssl-dev pkg-config curl \
&& pip3 install conan --break-system-packages \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /build
COPY . /build/
# === Linux x86_64 ===
FROM base-builder AS linux-x64-build
ARG TESTNET=1
RUN make build CPU_CORES=$(nproc) TESTNET=${TESTNET} STATIC=1 || \
(cd build/release && cmake --build . --parallel $(nproc))
FROM scratch AS linux-x64
COPY --from=linux-x64-build /build/build/release/src/lethean-* /
# === Linux ARM64 (cross-compile) ===
FROM base-builder AS linux-arm64-build
RUN apt-get update && apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
ARG TESTNET=1
# ARM64 cross-compilation requires CMAKE_TOOLCHAIN_FILE
# This is a placeholder — actual cross-compile needs Conan profile for aarch64
RUN echo "ARM64 cross-compilation requires additional setup. Use native ARM64 builder or QEMU."
FROM scratch AS linux-arm64
# Placeholder — use buildx with --platform=linux/arm64 for native ARM builds

View file

@ -1,183 +0,0 @@
# Lethean Staking Node — single container, no compose needed
# Runs daemon + wallet with PoS staking in one container.
#
# Build:
# docker build -f Dockerfile.staking-node -t lthn/staking-node .
#
# Run:
# docker run -d --name lthn-staker \
# -p 46941:36941 -p 46942:36942 -p 46944:36944 \
# -v lthn-chain:/data -v lthn-wallet:/wallet \
# lthn/staking-node
#
# Run with password:
# docker run -d --name lthn-staker \
# -e WALLET_PASSWORD=my-pass \
# -p 46941:36941 -p 46942:36942 -p 46944:36944 \
# -v lthn-chain:/data -v lthn-wallet:/wallet \
# lthn/staking-node
#
# Check status:
# docker exec lthn-staker /status.sh
#
# Get wallet address:
# docker exec lthn-staker /wallet-address.sh
#
# Ports:
# 36941 — Daemon RPC (chain queries)
# 36942 — P2P (open on router for full node)
# 36944 — Wallet RPC (balance, transfers)
FROM lthn/chain:testnet
RUN apt-get update && apt-get install -y --no-install-recommends \
curl supervisor bc \
&& rm -rf /var/lib/apt/lists/*
# Supervisor manages both daemon and wallet in one container
COPY <<'SUPERVISOR' /etc/supervisor/conf.d/lethean.conf
[supervisord]
nodaemon=true
logfile=/dev/stdout
logfile_maxbytes=0
loglevel=info
[program:daemon]
command=lethean-chain-node
--data-dir /data
--rpc-bind-ip 0.0.0.0
--rpc-bind-port 36941
--p2p-bind-port 36942
--rpc-enable-admin-api
--allow-local-ip
--log-level %(ENV_DAEMON_LOG_LEVEL)s
--disable-upnp
--rpc-ignore-offline
autorestart=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
[program:wallet]
command=/start-wallet.sh
autorestart=true
startsecs=30
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
SUPERVISOR
# Wallet startup script — waits for daemon, creates wallet if needed
COPY <<'WALLETSH' /start-wallet.sh
#!/bin/bash
set -e
WALLET_FILE="/wallet/staker.wallet"
WALLET_PASS="${WALLET_PASSWORD:-}"
DAEMON="127.0.0.1:36941"
# Wait for daemon RPC
echo "[wallet] Waiting for daemon..."
until curl -sf "http://$DAEMON/json_rpc" \
-d '{"jsonrpc":"2.0","id":"0","method":"getinfo"}' \
-H 'Content-Type: application/json' > /dev/null 2>&1; do
sleep 5
done
echo "[wallet] Daemon ready"
# Create wallet if it doesn't exist
if [ ! -f "$WALLET_FILE" ]; then
echo "[wallet] Creating new wallet..."
echo "$WALLET_PASS" | lethean-wallet-cli \
--generate-new-wallet "$WALLET_FILE" \
--password "$WALLET_PASS" \
--daemon-address "$DAEMON" \
--command exit
echo "[wallet] Wallet created"
fi
# Start wallet with PoS staking
exec lethean-wallet-cli \
--wallet-file "$WALLET_FILE" \
--password "$WALLET_PASS" \
--daemon-address "$DAEMON" \
--rpc-bind-port 36944 \
--rpc-bind-ip 0.0.0.0 \
--do-pos-mining
WALLETSH
# Status helper — shows chain + wallet in one command
COPY <<'STATUSSH' /status.sh
#!/bin/bash
echo "=== Lethean Staking Node ==="
echo ""
# Chain
INFO=$(curl -sf http://127.0.0.1:36941/json_rpc \
-d '{"jsonrpc":"2.0","id":"0","method":"getinfo"}' \
-H 'Content-Type: application/json' 2>/dev/null)
if [ -n "$INFO" ]; then
echo "$INFO" | python3 -c "
import sys,json
d=json.load(sys.stdin)['result']
hf=d.get('is_hardfok_active',[])
active=sum(1 for h in hf if h)
print(f'Chain:')
print(f' Height: {d[\"height\"]:,}')
print(f' Hardforks: HF0-{active-1}')
print(f' PoW diff: {d.get(\"pow_difficulty\",0):,}')
print(f' Aliases: {d.get(\"alias_count\",0)}')
print(f' Peers in: {d.get(\"incoming_connections_count\",0)}')
print(f' Peers out: {d.get(\"outgoing_connections_count\",0)}')
print(f' Status: {d[\"status\"]}')
" 2>/dev/null
else
echo "Chain: starting..."
fi
echo ""
# Wallet
BAL=$(curl -sf http://127.0.0.1:36944/json_rpc \
-d '{"jsonrpc":"2.0","id":"0","method":"getbalance"}' \
-H 'Content-Type: application/json' 2>/dev/null)
if [ -n "$BAL" ]; then
echo "$BAL" | python3 -c "
import sys,json
d=json.load(sys.stdin)['result']
print(f'Wallet:')
print(f' Balance: {d[\"balance\"]/1e12:.4f} LTHN')
print(f' Unlocked: {d[\"unlocked_balance\"]/1e12:.4f} LTHN')
print(f' Staking: yes (PoS mining active)')
" 2>/dev/null
else
echo "Wallet: syncing..."
fi
STATUSSH
# Wallet address helper
COPY <<'ADDRSH' /wallet-address.sh
#!/bin/bash
curl -sf http://127.0.0.1:36944/json_rpc \
-d '{"jsonrpc":"2.0","id":"0","method":"getaddress"}' \
-H 'Content-Type: application/json' | python3 -c "
import sys,json
d=json.load(sys.stdin)['result']
print(d['address'])
" 2>/dev/null || echo "Wallet not ready yet — daemon still syncing"
ADDRSH
RUN chmod +x /start-wallet.sh /status.sh /wallet-address.sh
ENV DAEMON_LOG_LEVEL=1
ENV WALLET_PASSWORD=
EXPOSE 36941 36942 36944
VOLUME ["/data", "/wallet"]
ENTRYPOINT ["supervisord", "-c", "/etc/supervisor/conf.d/lethean.conf"]

View file

@ -1,152 +0,0 @@
# Lethean Testnet — Docker Deployment
Run the full Lethean ecosystem in Docker. No compilation needed.
## Deployment Options
| Compose File | For | Services |
|---|---|---|
| `docker-compose.node.yml` | Home node operator | Daemon + wallet (PoS staking) |
| `docker-compose.exit.yml` | VPN exit node operator | Daemon + wallet + WireGuard |
| `docker-compose.pull.yml` | Full ecosystem | All 8 services + databases |
## Helper Scripts
```bash
bash demos/helpers/chain-info.sh # Chain height, difficulty, status
bash demos/helpers/chain-aliases.sh # List on-chain aliases
bash demos/helpers/wallet-address.sh # Show your wallet address
bash demos/helpers/wallet-balance.sh # Check LTHN balance
bash health.sh # Full ecosystem health check
```
## Quick Start
```bash
# 1. Configure
cp .env.example .env
# Edit .env — at minimum change JWT_SECRET and WALLET_PASSWORD
# 2. Start
docker compose -f docker-compose.pull.yml up -d
# 3. Check
docker compose -f docker-compose.pull.yml ps
```
The daemon takes ~30 seconds to initialise the chain database on first run.
Other services wait for the daemon health check before starting.
## Services
| Service | URL | Description |
|---------|-----|-------------|
| Block Explorer | http://localhost:3335 | Browse blocks, transactions, aliases |
| Trade DEX | http://localhost:3338 | Decentralised exchange frontend |
| Trade API | http://localhost:3336 | REST API for trade operations |
| Mining Pool | http://localhost:2117 | Pool stats API |
| Pool Stratum | localhost:5555 | Connect miners here |
| LNS | http://localhost:5553 | Lethean Name Service HTTP API |
| LNS DNS | localhost:5354 | DNS resolver for .lthn names |
| Daemon RPC | http://localhost:46941 | Chain node JSON-RPC |
| Wallet RPC | http://localhost:46944 | Wallet JSON-RPC |
| Docs | http://localhost:8099 | Documentation site |
## Mining
Connect a ProgPoWZ miner to the pool stratum:
```
stratum+tcp://YOUR_IP:5555
```
Compatible miners:
- **progminer** (recommended) — `progminer -P stratum+tcp://YOUR_WALLET_ADDRESS@localhost:5555`
- **T-Rex** — ProgPoWZ algorithm
- **TeamRedMiner** — ProgPoWZ algorithm
## Wallet
The wallet auto-creates on first start. To check your balance:
```bash
curl -s http://localhost:46944/json_rpc \
-d '{"jsonrpc":"2.0","id":"0","method":"getbalance"}' \
-H 'Content-Type: application/json'
```
The wallet runs with PoS mining enabled (`--do-pos-mining`), so it will stake
any balance automatically.
## Chain Status
```bash
curl -s http://localhost:46941/json_rpc \
-d '{"jsonrpc":"2.0","id":"0","method":"getinfo"}' \
-H 'Content-Type: application/json' | python3 -m json.tool
```
## Volumes
| Volume | Contains | Backup? |
|--------|----------|---------|
| `chain-data` | Blockchain database (LMDB) | Optional — can resync |
| `wallet-data` | Wallet file + keys | **Critical — back up regularly** |
| `explorer-db` | Explorer PostgreSQL | Can recreate from chain |
| `trade-db` | Trade PostgreSQL | Important for trade history |
### Backup wallet
```bash
docker compose -f docker-compose.pull.yml stop wallet
docker cp lthn-wallet:/wallet ./wallet-backup-$(date +%Y%m%d)
docker compose -f docker-compose.pull.yml start wallet
```
## Ports
All ports can be changed via `.env`. See `.env.example` for the full list.
If you're running behind a firewall and want external access:
- **P2P:** Open port 46942 (TCP) for other nodes to connect
- **Stratum:** Open port 5555 (TCP) for external miners
- **Explorer:** Open port 3335 (TCP) for public block explorer
## Troubleshooting
**Daemon crashes on start:**
Check logs with `docker logs lthn-daemon`. Common causes:
- Port already in use — change ports in `.env`
- Corrupt chain data — remove volume: `docker volume rm docker_chain-data`
**Wallet shows 0 balance:**
The wallet needs to sync with the daemon first. Check sync status in daemon logs.
New wallets start empty — mine or receive LTHN to fund them.
**Pool shows "Daemon died":**
The pool needs both the daemon and wallet running. Check both are healthy:
```bash
docker compose -f docker-compose.pull.yml ps daemon wallet
```
**Explorer shows "offline":**
The explorer connects to the daemon internally. If the daemon is still syncing,
the explorer will show offline until sync completes.
## Stopping
```bash
docker compose -f docker-compose.pull.yml down # stop containers
docker compose -f docker-compose.pull.yml down -v # stop + delete data
```
## Building from Source
If you want to build the images yourself instead of pulling pre-built ones:
```bash
docker compose -f docker-compose.ecosystem.yml build
docker compose -f docker-compose.ecosystem.yml up -d
```
This requires the full source tree — see the main repository README.

View file

@ -1,77 +0,0 @@
#!/bin/bash
# Build Lethean binaries for all platforms
# Requires: Docker with buildx for multi-arch
#
# Usage:
# ./build-all-platforms.sh testnet # testnet binaries
# ./build-all-platforms.sh mainnet # mainnet binaries
#
# Outputs to: ../build/packages/
set -e
TARGET=${1:-testnet}
TESTNET=$( [ "$TARGET" = "testnet" ] && echo 1 || echo 0 )
VERSION=$(grep 'BUILD_VERSION:=' ../Makefile | cut -d= -f2)
OUTDIR="../build/packages"
echo "Building Lethean $TARGET v$VERSION for all platforms"
mkdir -p "$OUTDIR"
# === Linux x86_64 (Docker) ===
echo ""
echo "=== Linux x86_64 ==="
docker build -f Dockerfile.cross-build \
--build-arg TESTNET=$TESTNET \
--target linux-x64 \
-o "$OUTDIR/linux-x64" \
.. 2>&1 | tail -5
if ls "$OUTDIR/linux-x64/lethean-"* > /dev/null 2>&1; then
PKG="lethean-${TARGET}-linux-x86_64-v${VERSION}"
mkdir -p "$OUTDIR/$PKG"
cp "$OUTDIR/linux-x64/lethean-"* "$OUTDIR/$PKG/"
cd "$OUTDIR" && tar czf "${PKG}.tar.gz" "$PKG/" && cd -
echo " Package: $OUTDIR/${PKG}.tar.gz"
else
echo " Build failed — check Docker output"
fi
# === Linux ARM64 (needs Docker buildx with QEMU) ===
echo ""
echo "=== Linux ARM64 ==="
if docker buildx ls 2>/dev/null | grep -q "linux/arm64"; then
echo " ARM64 builder available — building..."
docker buildx build -f ../utils/docker/lthn-chain/Dockerfile \
--platform linux/arm64 \
--build-arg BUILD_TESTNET=$TESTNET \
--build-arg BUILD_THREADS=4 \
--target build-artifacts \
-o "$OUTDIR/linux-arm64" \
.. 2>&1 | tail -5
else
echo " SKIP: Docker buildx ARM64 emulation not configured"
echo " To enable: docker run --privileged --rm tonistiigi/binfmt --install arm64"
fi
# === macOS (needs native build or osxcross) ===
echo ""
echo "=== macOS ==="
echo " SKIP: macOS builds require native macOS environment or osxcross toolchain"
echo " Build on Cladius (M3 Ultra): cd blockchain && make $TARGET"
echo " Or use GitHub Actions with macos-latest runner"
# === Windows (needs MSVC or mingw-w64) ===
echo ""
echo "=== Windows ==="
echo " SKIP: Windows builds require MSVC or mingw-w64 cross-compiler"
echo " Recommended: GitHub Actions with windows-latest runner"
echo " Or: Docker with dockcross/windows-shared-x64 image"
# === Summary ===
echo ""
echo "=== Build Summary ==="
ls -lh "$OUTDIR"/*.tar.gz 2>/dev/null || echo "No packages built yet"
echo ""
echo "For macOS/Windows, use CI/CD:"
echo " .forgejo/workflows/build-release.yml (push a tag to trigger)"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 KiB

View file

@ -1,54 +0,0 @@
# 01 — Install Lethean from scratch
# Shows a home user going from zero to running node
Output demos/01-install.gif
Set FontSize 13
Set Width 1000
Set Height 600
Set Theme "Dracula"
Set TypingSpeed 35ms
Set Padding 12
Set Shell bash
Type "# Install Lethean — from zero to running node"
Enter
Sleep 1s
Type "mkdir lethean && cd lethean"
Enter
Sleep 500ms
Type "# Download the compose files"
Enter
Type "curl -sO https://forge.lthn.ai/lthn/blockchain/raw/branch/dev/docker/docker-compose.node.yml"
Enter
Sleep 500ms
Type "curl -sO https://forge.lthn.ai/lthn/blockchain/raw/branch/dev/docker/.env.example"
Enter
Sleep 500ms
Type "cp .env.example .env"
Enter
Sleep 300ms
Type "# Set a wallet password"
Enter
Type "sed -i 's/WALLET_PASSWORD=/WALLET_PASSWORD=my-secure-pass/' .env"
Enter
Sleep 500ms
Type ""
Enter
Type "# Start the node"
Enter
Type "docker compose -f docker-compose.node.yml up -d"
Enter
Sleep 3s
Type ""
Enter
Type "# That's it. Your node is syncing and staking."
Enter
Sleep 2s

Binary file not shown.

Before

Width:  |  Height:  |  Size: 443 KiB

View file

@ -1,39 +0,0 @@
# 02 — Chain Status (live data)
Output demos/02-chain-status.gif
Set FontSize 13
Set Width 1000
Set Height 600
Set Theme "Dracula"
Set TypingSpeed 35ms
Set Padding 12
Set Shell bash
Type "# Lethean Chain — Live Status"
Enter
Sleep 500ms
Type "bash demos/helpers/chain-info.sh"
Enter
Sleep 3s
Type ""
Enter
Type "bash demos/helpers/last-block.sh"
Enter
Sleep 3s
Type ""
Enter
Type "# On-chain service discovery via aliases"
Enter
Type "bash demos/helpers/chain-aliases.sh"
Enter
Sleep 4s
Type ""
Enter
Type "# Blocks arrive every ~2 minutes — PoW and PoS alternating"
Enter
Sleep 2s

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 MiB

View file

@ -1,87 +0,0 @@
# 03 — Ecosystem Tour (the teaser material)
# Every service, live data, no fluff
Output demos/03-ecosystem-tour.gif
Set FontSize 13
Set Width 1000
Set Height 700
Set Theme "Dracula"
Set TypingSpeed 30ms
Set Padding 12
Set Shell bash
Type "# Lethean Ecosystem — Full Tour"
Enter
Sleep 500ms
Type "bash health.sh"
Enter
Sleep 4s
Type ""
Enter
Type "# === Chain ==="
Enter
Type "bash demos/helpers/chain-info.sh"
Enter
Sleep 3s
Type ""
Enter
Type "# === Latest Block ==="
Enter
Type "bash demos/helpers/last-block.sh"
Enter
Sleep 3s
Type ""
Enter
Type "# === Wallet ==="
Enter
Type "bash demos/helpers/wallet-address.sh"
Enter
Sleep 2s
Type "bash demos/helpers/wallet-balance.sh"
Enter
Sleep 2s
Type ""
Enter
Type "# === Explorer ==="
Enter
Type "bash demos/helpers/explorer-stats.sh"
Enter
Sleep 3s
Type ""
Enter
Type "# === Mining Pool ==="
Enter
Type "bash demos/helpers/pool-stats.sh"
Enter
Sleep 3s
Type ""
Enter
Type "# === Name Service ==="
Enter
Type "bash demos/helpers/lns-status.sh"
Enter
Sleep 3s
Type ""
Enter
Type "# === Aliases — services advertise on-chain ==="
Enter
Type "bash demos/helpers/chain-aliases.sh"
Enter
Sleep 4s
Type ""
Enter
Type "# Lethean — privacy by default, earn by participating"
Enter
Type "# https://lethean.io"
Enter
Sleep 3s

Binary file not shown.

Before

Width:  |  Height:  |  Size: 957 KiB

View file

@ -1,50 +0,0 @@
# 04 — Mining
# Shows pool stats and how to connect a miner
Output demos/04-mining.gif
Set FontSize 13
Set Width 1000
Set Height 550
Set Theme "Dracula"
Set TypingSpeed 35ms
Set Padding 12
Set Shell bash
Type "# Lethean Mining — ProgPoWZ GPU Mining"
Enter
Sleep 500ms
Type "bash demos/helpers/pool-stats.sh"
Enter
Sleep 3s
Type ""
Enter
Type "# Get your wallet address for mining"
Enter
Type "bash demos/helpers/wallet-address.sh"
Enter
Sleep 2s
Type ""
Enter
Type "# Connect a GPU miner:"
Enter
Type "echo 'progminer -P stratum+tcp://YOUR_WALLET@localhost:5555'"
Enter
Sleep 1s
Type "echo 't-rex -a progpowz -o stratum+tcp://localhost:5555 -u YOUR_WALLET'"
Enter
Sleep 1s
Type "echo 'teamredminer -a progpow -o stratum+tcp://localhost:5555 -u YOUR_WALLET'"
Enter
Sleep 2s
Type ""
Enter
Type "# Pool dashboard: http://localhost:2117"
Enter
Type "# Block reward: 1 LTHN every ~2 minutes"
Enter
Sleep 2s

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

View file

@ -1,68 +0,0 @@
# 05 — Exit Node Setup
# Shows how to run a VPN exit node and earn LTHN
Output demos/05-exit-node.gif
Set FontSize 13
Set Width 1000
Set Height 600
Set Theme "Dracula"
Set TypingSpeed 35ms
Set Padding 12
Set Shell bash
Type "# Lethean VPN Exit Node — Earn LTHN"
Enter
Sleep 500ms
Type "# Configure your exit node"
Enter
Type "cp .env.example .env"
Enter
Sleep 300ms
Type "echo 'WALLET_PASSWORD=my-secure-pass' >> .env"
Enter
Type "echo 'EXIT_PUBLIC_IP=203.0.113.50' >> .env"
Enter
Type "echo 'EXIT_NAME=my-exit' >> .env"
Enter
Sleep 500ms
Type ""
Enter
Type "# Start the exit node stack"
Enter
Type "docker compose -f docker-compose.exit.yml up -d"
Enter
Sleep 3s
Type ""
Enter
Type "# Your exit node runs:"
Enter
Type "echo ' Chain daemon — syncs blockchain'"
Enter
Type "echo ' Wallet — PoS staking + receives payments'"
Enter
Type "echo ' WireGuard VPN — encrypted tunnel for gateway traffic'"
Enter
Type "echo ' Controller — manages peering and on-chain registration'"
Enter
Sleep 2s
Type ""
Enter
Type "# Gateways discover you via on-chain alias:"
Enter
Type "echo ' @my-exit v=lthn1;type=exit;cap=vpn,proxy;ip=203.0.113.50'"
Enter
Sleep 2s
Type ""
Enter
Type "# Open ports 46942/tcp + 51820/udp on your router"
Enter
Type "# Then sit back and earn LTHN"
Enter
Sleep 3s

View file

@ -1,13 +0,0 @@
#!/bin/bash
curl -s localhost:46941/json_rpc \
-d '{"jsonrpc":"2.0","id":"0","method":"get_all_alias_details"}' \
-H 'Content-Type: application/json' | python3 -c "
import sys,json
aliases=json.load(sys.stdin)['result']['aliases']
print(f'{len(aliases)} aliases registered on-chain:')
print()
for a in aliases:
name = a['alias']
comment = a.get('comment','')
print(f' @{name:12s} {comment[:50]}')
"

View file

@ -1,17 +0,0 @@
#!/bin/bash
curl -s localhost:46941/json_rpc \
-d '{"jsonrpc":"2.0","id":"0","method":"getinfo"}' \
-H 'Content-Type: application/json' | python3 -c "
import sys,json
d=json.load(sys.stdin)['result']
hf = d.get('is_hardfok_active',[])
active = sum(1 for h in hf if h)
print(f'Height: {d[\"height\"]:,}')
print(f'Hardforks: HF0-{active-1} active')
print(f'PoW diff: {d.get(\"pow_difficulty\",0):,}')
print(f'Aliases: {d.get(\"alias_count\",0)}')
print(f'TX count: {d.get(\"tx_count\",0):,}')
print(f'Peers in: {d.get(\"incoming_connections_count\",0)}')
print(f'Peers out: {d.get(\"outgoing_connections_count\",0)}')
print(f'Status: {d[\"status\"]}')
"

View file

@ -1,15 +0,0 @@
#!/bin/bash
curl -s localhost:3335/api/get_info | python3 -c "
import sys,json
try:
d=json.load(sys.stdin)
print('Block Explorer')
print(f' Height: {d.get(\"height\",0):,}')
print(f' PoW diff: {d.get(\"pow_difficulty\",0):,}')
print(f' Aliases: {d.get(\"alias_count\",0)}')
print(f' TX count: {d.get(\"tx_count\",0):,}')
print(f' Hashrate: {d.get(\"current_network_hashrate_350\",0):,} H/s')
print(f' URL: http://localhost:3335')
except:
print('Explorer: connecting...')
"

View file

@ -1,13 +0,0 @@
#!/bin/bash
curl -s localhost:46941/json_rpc \
-d '{"jsonrpc":"2.0","id":"0","method":"getlastblockheader"}' \
-H 'Content-Type: application/json' | python3 -c "
import sys,json
b=json.load(sys.stdin)['result']['block_header']
btype = 'PoW' if b.get('major_version',0)==3 else 'PoS'
print(f'Latest Block #{b[\"height\"]:,}')
print(f' Type: {btype}')
print(f' Reward: {b[\"reward\"]/1e12:.4f} LTHN')
print(f' Difficulty: {b[\"difficulty\"]:,}')
print(f' Hash: {b[\"hash\"][:20]}...')
"

View file

@ -1,15 +0,0 @@
#!/bin/bash
echo "Lethean Name Service (LNS)"
curl -s localhost:5553/health | python3 -c "
import sys,json
d=json.load(sys.stdin)
print(f' Mode: {d.get(\"mode\",\"?\")}')
print(f' Names: {d.get(\"names\",0)} cached')
print(f' Status: {d.get(\"status\",\"?\")}')
"
echo ""
echo "Resolving .lthn names:"
for name in charon gateway explorer trading; do
result=$(curl -s "localhost:5553/resolve?name=$name.lthn" | python3 -c "import sys,json; d=json.load(sys.stdin); print('found' if d.get('found') else 'not cached')" 2>/dev/null)
printf " %-16s %s\n" "$name.lthn" "$result"
done

View file

@ -1,17 +0,0 @@
#!/bin/bash
curl -s localhost:2117/stats | python3 -c "
import sys,json
d=json.load(sys.stdin)
pool = d.get('pool',{})
net = d.get('network',{})
cfg = d.get('config',{})
print(f'Lethean Mining Pool')
print(f' Coin: {cfg.get(\"coin\",\"?\")}')
print(f' Algorithm: ProgPoWZ')
print(f' Pool hash: {pool.get(\"hashrate\",0)} H/s')
print(f' Miners: {pool.get(\"miners\",0)}')
print(f' Blocks found: {pool.get(\"totalBlocks\",0)}')
print(f' Net height: {net.get(\"height\",\"?\")}')
print(f' Net diff: {net.get(\"difficulty\",\"?\")}')
print(f' Stratum: stratum+tcp://localhost:5555')
"

View file

@ -1,8 +0,0 @@
#!/bin/bash
curl -s localhost:46944/json_rpc \
-d '{"jsonrpc":"2.0","id":"0","method":"getaddress"}' \
-H 'Content-Type: application/json' | python3 -c "
import sys,json
d=json.load(sys.stdin)['result']
print('Address:', d['address'])
"

View file

@ -1,9 +0,0 @@
#!/bin/bash
curl -s localhost:46944/json_rpc \
-d '{"jsonrpc":"2.0","id":"0","method":"getbalance"}' \
-H 'Content-Type: application/json' | python3 -c "
import sys,json
d=json.load(sys.stdin)['result']
print(f'Balance: {d[\"balance\"]/1e12:.4f} LTHN')
print(f'Unlocked: {d[\"unlocked_balance\"]/1e12:.4f} LTHN')
"

View file

@ -1,78 +0,0 @@
#!/bin/bash
# Lethean Testnet — Production Deploy Script
# Transfers images and config to a remote server and starts the stack.
#
# Usage:
# bash deploy.sh user@server
# bash deploy.sh user@server /opt/lethean/docker
#
# Prerequisites on the remote server:
# - Docker + Docker Compose v2
# - SSH access
set -e
REMOTE="${1:?Usage: deploy.sh user@server [install_dir]}"
INSTALL_DIR="${2:-/opt/lethean/docker}"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
IMAGES="$SCRIPT_DIR/dist/lethean-testnet-images.tar.gz"
if [ ! -f "$IMAGES" ]; then
echo "Building image bundle..."
mkdir -p "$SCRIPT_DIR/dist"
docker save \
lthn/chain:testnet \
lthn/explorer:testnet \
lthn/trade-api:testnet \
lthn/trade-frontend:testnet \
lthn/pool:testnet \
lthn/lns:testnet \
lthn/docs:testnet \
| gzip > "$IMAGES"
fi
echo "Image bundle: $(du -h "$IMAGES" | cut -f1)"
echo "Deploying to $REMOTE:$INSTALL_DIR"
echo ""
# Create remote directory
ssh "$REMOTE" "mkdir -p $INSTALL_DIR"
# Transfer files
echo "Transferring config files..."
scp "$SCRIPT_DIR/docker-compose.pull.yml" "$REMOTE:$INSTALL_DIR/"
scp "$SCRIPT_DIR/.env.example" "$REMOTE:$INSTALL_DIR/"
scp "$SCRIPT_DIR/pool-config.json" "$REMOTE:$INSTALL_DIR/"
scp "$SCRIPT_DIR/health.sh" "$REMOTE:$INSTALL_DIR/"
scp "$SCRIPT_DIR/lethean-testnet.service" "$REMOTE:$INSTALL_DIR/"
scp "$SCRIPT_DIR/docker-compose.node.yml" "$REMOTE:$INSTALL_DIR/"
scp "$SCRIPT_DIR/docker-compose.exit.yml" "$REMOTE:$INSTALL_DIR/"
scp -r "$SCRIPT_DIR/demos/helpers" "$REMOTE:$INSTALL_DIR/demos/"
# Create .env if it doesn't exist — generate unique JWT secret
ssh "$REMOTE" "
if [ ! -f $INSTALL_DIR/.env ]; then
cp $INSTALL_DIR/.env.example $INSTALL_DIR/.env
JWT=\$(openssl rand -hex 32 2>/dev/null || head -c 64 /dev/urandom | xxd -p | tr -d '\n' | head -c 64)
sed -i \"s/change-me-before-production/\$JWT/\" $INSTALL_DIR/.env
echo 'Generated unique JWT secret'
else
echo '.env already exists — skipping'
fi
"
echo "Transferring images (~$(du -h "$IMAGES" | cut -f1))... this may take a while"
scp "$IMAGES" "$REMOTE:/tmp/lethean-testnet-images.tar.gz"
echo "Loading images on remote..."
ssh "$REMOTE" "docker load < /tmp/lethean-testnet-images.tar.gz && rm /tmp/lethean-testnet-images.tar.gz"
echo "Starting stack..."
ssh "$REMOTE" "cd $INSTALL_DIR && docker compose -f docker-compose.pull.yml up -d"
echo ""
echo "Deploy complete. Run health check:"
echo " ssh $REMOTE 'cd $INSTALL_DIR && bash health.sh'"
echo ""
echo "Install systemd service (optional):"
echo " ssh $REMOTE 'sudo cp $INSTALL_DIR/lethean-testnet.service /etc/systemd/system/ && sudo systemctl daemon-reload && sudo systemctl enable lethean-testnet'"

View file

@ -1,203 +0,0 @@
# Lethean Full Ecosystem
# Chain node + wallet + explorer + trade + pool + LNS + docs
#
# Usage:
# docker compose -f docker-compose.ecosystem.yml up -d
#
# URLs after startup:
# Explorer: http://localhost:3335
# Trade: http://localhost:3337
# Trade API: http://localhost:3336
# Pool API: http://localhost:2117
# Pool Web: http://localhost:8888
# LNS HTTP: http://localhost:5553
# LNS DNS: localhost:5354
# Docs: http://localhost:8098
# Daemon RPC: http://localhost:46941
# Wallet RPC: http://localhost:46944
services:
# --- Chain ---
daemon:
build:
context: ..
dockerfile: utils/docker/lthn-chain/Dockerfile
target: chain-service
args:
BUILD_TESTNET: 1
BUILD_THREADS: 4
container_name: lthn-daemon
ports:
- "46941:36941"
- "46942:36942"
volumes:
- daemon-data:/data
command: >
lethean-chain-node
--data-dir /data
--rpc-bind-ip 0.0.0.0
--rpc-bind-port 36941
--p2p-bind-port 36942
--rpc-enable-admin-api
--allow-local-ip
--log-level 1
--disable-upnp
wallet:
build:
context: ..
dockerfile: utils/docker/lthn-chain/Dockerfile
target: chain-service
args:
BUILD_TESTNET: 1
BUILD_THREADS: 4
container_name: lthn-wallet
ports:
- "46944:36944"
volumes:
- wallet-data:/wallet
entrypoint: >
sh -c "
if [ ! -f /wallet/main.wallet ]; then
echo '' | lethean-wallet-cli --generate-new-wallet /wallet/main.wallet --password '' --daemon-address daemon:36941 --command exit;
fi;
lethean-wallet-cli
--wallet-file /wallet/main.wallet
--password ''
--daemon-address daemon:36941
--rpc-bind-port 36944
--rpc-bind-ip 0.0.0.0
--do-pos-mining
"
depends_on:
- daemon
# --- Explorer ---
explorer-db:
image: postgres:16-alpine
container_name: lthn-explorer-db
environment:
POSTGRES_USER: explorer
POSTGRES_PASSWORD: explorer
POSTGRES_DB: lethean_explorer
volumes:
- explorer-db:/var/lib/postgresql/data
explorer:
build:
context: ../../zano-upstream/zano-explorer-zarcanum
container_name: lthn-explorer
ports:
- "3335:3335"
environment:
API: http://daemon:36941
FRONTEND_API: http://localhost:3335
SERVER_PORT: "3335"
AUDITABLE_WALLET_API: http://daemon:36941
PGUSER: explorer
PGPASSWORD: explorer
PGDATABASE: lethean_explorer
PGHOST: explorer-db
PGPORT: "5432"
MEXC_API_URL: ""
depends_on:
- daemon
- explorer-db
# --- Trade ---
trade-db:
image: postgres:16-alpine
container_name: lthn-trade-db
environment:
POSTGRES_USER: trade
POSTGRES_PASSWORD: trade
POSTGRES_DB: lethean_trade
volumes:
- trade-db:/var/lib/postgresql/data
trade-api:
build:
context: ../../zano-upstream/zano_trade_backend
container_name: lthn-trade-api
ports:
- "3336:3336"
environment:
PORT: "3336"
PGUSER: trade
PGPASSWORD: trade
PGDATABASE: lethean_trade
PGHOST: trade-db
PGPORT: "5432"
JWT_SECRET: testnet-dev-secret
DAEMON_RPC_URL: http://daemon:36941/json_rpc
depends_on:
- daemon
- trade-db
trade-frontend:
build:
context: ../../zano-upstream/zano_trade_frontend
container_name: lthn-trade-frontend
ports:
- "3337:30289"
environment:
NEXT_PUBLIC_API_URL: http://trade-api:3336
depends_on:
- trade-api
# --- Mining Pool ---
pool-redis:
image: redis:7-alpine
container_name: lthn-pool-redis
restart: unless-stopped
pool:
build:
context: ../..
dockerfile: zano-upstream/zano-pool/Dockerfile
container_name: lthn-pool
ports:
- "5555:5555"
- "7777:7777"
- "2117:2117"
- "8888:8888"
volumes:
- ./pool-config.json:/pool/config.json:ro
depends_on:
- daemon
- wallet
- pool-redis
# --- LNS (Lethean Name Service) ---
lns:
build:
context: ../../lns
container_name: lthn-lns
ports:
- "5553:5553" # HTTP API
- "5354:5354/udp" # DNS
- "5354:5354/tcp" # DNS (TCP)
environment:
DAEMON_URL: http://daemon:36941
HSD_URL: http://host.docker.internal:14037
LNS_MODE: light
LNS_HTTP_PORT: "5553"
LNS_DNS_PORT: "5354"
extra_hosts:
- "host.docker.internal:host-gateway"
depends_on:
- daemon
# --- Docs ---
docs:
build:
context: ../../zano-upstream/zano-docs
container_name: lthn-docs
ports:
- "8098:80"
volumes:
daemon-data:
wallet-data:
explorer-db:
trade-db:

View file

@ -1,186 +0,0 @@
# Lethean Exit Node
# Run a VPN exit node and earn LTHN by providing bandwidth to the network.
# Peers with Lethean gateways which route encrypted VPN traffic through your node.
#
# Usage:
# cp .env.example .env
# # Set WALLET_PASSWORD, EXIT_PUBLIC_IP, and EXIT_NAME
# docker compose -f docker-compose.exit.yml up -d
#
# What it does:
# - Runs a full chain node (syncs blockchain)
# - Runs a wallet with PoS staking
# - Runs a WireGuard VPN server
# - Registers as an exit node on-chain via alias
# - Peers with gateway nodes for traffic routing
# - Earns LTHN for bandwidth provided
#
# Requirements:
# - Public IP address (or port forwarding on router)
# - Open ports: 46942 (P2P), 51820/udp (WireGuard)
# - Linux with Docker (WireGuard kernel module)
#
# Ports:
# 46942 — P2P (chain peering)
# 51820 — WireGuard VPN (UDP)
# 8124 — Exit node management API (local only)
services:
# --- Chain Node ---
daemon:
image: lthn/chain:testnet
container_name: lthn-exit-daemon
restart: unless-stopped
ports:
- "${DAEMON_P2P_PORT:-46942}:36942"
volumes:
- chain-data:/data
entrypoint:
- lethean-chain-node
command:
- --data-dir
- /data
- --rpc-bind-ip
- "0.0.0.0"
- --rpc-bind-port
- "36941"
- --p2p-bind-port
- "36942"
- --rpc-enable-admin-api
- --allow-local-ip
- --log-level
- "${DAEMON_LOG_LEVEL:-1}"
- --disable-upnp
- --rpc-ignore-offline
healthcheck:
test: ["CMD-SHELL", "curl -sf http://localhost:36941/json_rpc -d '{\"jsonrpc\":\"2.0\",\"id\":\"0\",\"method\":\"getinfo\"}' -H 'Content-Type: application/json' | grep -q OK"]
interval: 30s
timeout: 10s
retries: 5
start_period: 60s
networks:
exit-net:
# --- Wallet (PoS staking + payment receipt) ---
wallet:
image: lthn/chain:testnet
container_name: lthn-exit-wallet
restart: unless-stopped
volumes:
- wallet-data:/wallet
entrypoint:
- sh
- -c
command:
- |
if [ ! -f /wallet/exit.wallet ]; then
echo '${WALLET_PASSWORD:-}' | lethean-wallet-cli --generate-new-wallet /wallet/exit.wallet --password '${WALLET_PASSWORD:-}' --daemon-address daemon:36941 --command exit;
fi;
lethean-wallet-cli \
--wallet-file /wallet/exit.wallet \
--password '${WALLET_PASSWORD:-}' \
--daemon-address daemon:36941 \
--rpc-bind-port 36944 \
--rpc-bind-ip 0.0.0.0 \
--do-pos-mining
depends_on:
daemon:
condition: service_healthy
networks:
exit-net:
# --- WireGuard VPN Exit ---
wireguard:
image: lscr.io/linuxserver/wireguard:latest
container_name: lthn-exit-wireguard
restart: unless-stopped
cap_add:
- NET_ADMIN
- SYS_MODULE
environment:
PUID: 1000
PGID: 1000
TZ: ${TZ:-Europe/London}
SERVERURL: ${EXIT_PUBLIC_IP:-auto}
SERVERPORT: 51820
PEERS: ${EXIT_MAX_PEERS:-25}
PEERDNS: 1.1.1.1,1.0.0.1
INTERNAL_SUBNET: 10.13.13.0
ALLOWEDIPS: 0.0.0.0/0,::/0
LOG_CONFS: "false"
ports:
- "51820:51820/udp"
volumes:
- wireguard-config:/config
sysctls:
- net.ipv4.conf.all.src_valid_mark=1
- net.ipv4.ip_forward=1
networks:
exit-net:
# --- Exit Node Controller ---
# Manages gateway peering, alias registration, and payment verification
controller:
image: lthn/chain:testnet
container_name: lthn-exit-controller
restart: unless-stopped
volumes:
- controller-data:/data
entrypoint:
- sh
- -c
command:
- |
echo "Lethean Exit Node Controller"
echo "Waiting for daemon and wallet..."
# Wait for daemon
until curl -sf http://daemon:36941/json_rpc -d '{"jsonrpc":"2.0","id":"0","method":"getinfo"}' -H 'Content-Type: application/json' > /dev/null 2>&1; do
sleep 5
done
echo "Daemon ready"
# Wait for wallet
until curl -sf http://wallet:36944/json_rpc -d '{"jsonrpc":"2.0","id":"0","method":"getbalance"}' -H 'Content-Type: application/json' > /dev/null 2>&1; do
sleep 5
done
echo "Wallet ready"
# Get wallet address
ADDR=$$(curl -sf http://wallet:36944/json_rpc -d '{"jsonrpc":"2.0","id":"0","method":"getaddress"}' -H 'Content-Type: application/json' | grep -oP '"address":"[^"]+' | cut -d'"' -f4)
echo "Exit node wallet: $$ADDR"
# Get chain height
HEIGHT=$$(curl -sf http://daemon:36941/json_rpc -d '{"jsonrpc":"2.0","id":"0","method":"getinfo"}' -H 'Content-Type: application/json' | grep -oP '"height":[0-9]+' | cut -d: -f2)
echo "Chain height: $$HEIGHT"
# Register alias if EXIT_NAME is set and we have balance
if [ -n "${EXIT_NAME:-}" ]; then
echo "Exit node name: ${EXIT_NAME}"
echo "To register on-chain: send 1 LTHN to this wallet, then alias will auto-register"
echo "Alias comment: v=lthn1;type=exit;cap=vpn,proxy;ip=${EXIT_PUBLIC_IP:-auto}"
fi
# Status loop
while true; do
BALANCE=$$(curl -sf http://wallet:36944/json_rpc -d '{"jsonrpc":"2.0","id":"0","method":"getbalance"}' -H 'Content-Type: application/json' | grep -oP '"balance":[0-9]+' | cut -d: -f2)
HEIGHT=$$(curl -sf http://daemon:36941/json_rpc -d '{"jsonrpc":"2.0","id":"0","method":"getinfo"}' -H 'Content-Type: application/json' | grep -oP '"height":[0-9]+' | cut -d: -f2)
WG_PEERS=$$(curl -sf http://wireguard:51820 2>/dev/null | wc -l || echo 0)
echo "$$(date +%H:%M:%S) height=$$HEIGHT balance=$$(echo "scale=4; $$BALANCE/1000000000000" | bc 2>/dev/null || echo $$BALANCE) peers=$$WG_PEERS"
sleep 60
done
depends_on:
daemon:
condition: service_healthy
networks:
exit-net:
networks:
exit-net:
driver: bridge
volumes:
chain-data:
wallet-data:
wireguard-config:
controller-data:

View file

@ -1,7 +0,0 @@
# Local override — mounts existing testnet chain data
# Usage: docker compose -f docker-compose.pull.yml -f docker-compose.local.yml up -d
services:
daemon:
volumes:
- /opt/lethean/testnet-data:/data

View file

@ -1,87 +0,0 @@
# Lethean Home Node
# A self-contained chain node for home users who want to support the network.
# Syncs the chain, runs a wallet with PoS staking, and exposes P2P for peering.
#
# Usage:
# cp .env.example .env # edit WALLET_PASSWORD at minimum
# docker compose -f docker-compose.node.yml up -d
#
# What it does:
# - Syncs and validates the Lethean blockchain
# - Peers with other nodes (P2P port 46942)
# - Runs a wallet that stakes automatically (PoS mining)
# - Optionally mines with ProgPoWZ (connect external GPU miner)
#
# Earnings:
# - PoS staking rewards (proportional to balance)
# - PoW block rewards if mining
#
# Ports:
# 46941 — Daemon RPC (local tools)
# 46942 — P2P (open this on your router for full node)
# 46944 — Wallet RPC (local tools)
services:
daemon:
image: lthn/chain:testnet
container_name: lthn-node
restart: unless-stopped
ports:
- "${DAEMON_RPC_PORT:-46941}:36941"
- "${DAEMON_P2P_PORT:-46942}:36942"
volumes:
- chain-data:/data
entrypoint:
- lethean-chain-node
command:
- --data-dir
- /data
- --rpc-bind-ip
- "0.0.0.0"
- --rpc-bind-port
- "36941"
- --p2p-bind-port
- "36942"
- --rpc-enable-admin-api
- --allow-local-ip
- --log-level
- "${DAEMON_LOG_LEVEL:-1}"
- --disable-upnp
- --rpc-ignore-offline
healthcheck:
test: ["CMD-SHELL", "curl -sf http://localhost:36941/json_rpc -d '{\"jsonrpc\":\"2.0\",\"id\":\"0\",\"method\":\"getinfo\"}' -H 'Content-Type: application/json' | grep -q OK"]
interval: 30s
timeout: 10s
retries: 5
start_period: 60s
wallet:
image: lthn/chain:testnet
container_name: lthn-wallet
restart: unless-stopped
ports:
- "${WALLET_RPC_PORT:-46944}:36944"
volumes:
- wallet-data:/wallet
entrypoint:
- sh
- -c
command:
- |
if [ ! -f /wallet/node.wallet ]; then
echo '${WALLET_PASSWORD:-}' | lethean-wallet-cli --generate-new-wallet /wallet/node.wallet --password '${WALLET_PASSWORD:-}' --daemon-address daemon:36941 --command exit;
fi;
lethean-wallet-cli \
--wallet-file /wallet/node.wallet \
--password '${WALLET_PASSWORD:-}' \
--daemon-address daemon:36941 \
--rpc-bind-port 36944 \
--rpc-bind-ip 0.0.0.0 \
--do-pos-mining
depends_on:
daemon:
condition: service_healthy
volumes:
chain-data:
wallet-data:

View file

@ -1,114 +0,0 @@
# Lethean Chain Nodes Only — minimal network simulation
# 3 nodes + miner, no explorer/trade (for testing consensus, HF activation, reorgs)
#
# Usage:
# docker compose -f docker-compose.nodes.yml up -d
# # Start mining on node1:
# docker exec lthn-node1 curl -X POST http://127.0.0.1:36941/start_mining \
# -H 'Content-Type: application/json' \
# -d '{"miner_address":"YOUR_iTHN_ADDRESS","threads_count":2}'
# # Check sync status:
# for n in 1 2 3; do
# echo -n "node$n: "; docker exec lthn-node$n curl -s http://127.0.0.1:36941/json_rpc \
# -H 'Content-Type: application/json' \
# -d '{"jsonrpc":"2.0","id":"0","method":"getinfo"}' | python3 -c "import sys,json; print(json.load(sys.stdin)['result']['height'])"
# done
services:
node1:
build:
context: ..
dockerfile: utils/docker/lthn-chain/Dockerfile
target: chain-service
args:
BUILD_TESTNET: 1
BUILD_THREADS: 4
container_name: lthn-node1
ports:
- "46941:36941"
- "46942:36942"
volumes:
- node1-data:/data
command: >
lethean-chain-node
--data-dir /data
--rpc-bind-ip 0.0.0.0
--rpc-bind-port 36941
--p2p-bind-port 36942
--rpc-enable-admin-api
--allow-local-ip
--log-level 1
--disable-upnp
networks:
lthn-net:
ipv4_address: 172.29.0.10
node2:
build:
context: ..
dockerfile: utils/docker/lthn-chain/Dockerfile
target: chain-service
args:
BUILD_TESTNET: 1
BUILD_THREADS: 4
container_name: lthn-node2
ports:
- "46951:36941"
volumes:
- node2-data:/data
command: >
lethean-chain-node
--data-dir /data
--rpc-bind-ip 0.0.0.0
--rpc-bind-port 36941
--p2p-bind-port 36942
--add-exclusive-node 172.29.0.10:36942
--allow-local-ip
--log-level 1
--disable-upnp
depends_on:
- node1
networks:
lthn-net:
ipv4_address: 172.29.0.11
node3:
build:
context: ..
dockerfile: utils/docker/lthn-chain/Dockerfile
target: chain-service
args:
BUILD_TESTNET: 1
BUILD_THREADS: 4
container_name: lthn-node3
ports:
- "46961:36941"
volumes:
- node3-data:/data
command: >
lethean-chain-node
--data-dir /data
--rpc-bind-ip 0.0.0.0
--rpc-bind-port 36941
--p2p-bind-port 36942
--add-exclusive-node 172.29.0.10:36942
--allow-local-ip
--log-level 1
--disable-upnp
depends_on:
- node1
networks:
lthn-net:
ipv4_address: 172.29.0.12
networks:
lthn-net:
driver: bridge
ipam:
config:
- subnet: 172.29.0.0/16
volumes:
node1-data:
node2-data:
node3-data:

View file

@ -1,235 +0,0 @@
# Lethean Testnet Ecosystem
# Full node + wallet + explorer + trade + pool + LNS
#
# Quick start:
# cp .env.example .env # edit passwords/hostname
# docker compose -f docker-compose.pull.yml up -d
# docker compose -f docker-compose.pull.yml logs -f daemon
#
# Services:
# Explorer: http://${PUBLIC_HOST:-localhost}:3335
# Trade: http://${PUBLIC_HOST:-localhost}:3338
# Trade API: http://${PUBLIC_HOST:-localhost}:3336
# Pool API: http://${PUBLIC_HOST:-localhost}:2117
# LNS HTTP: http://${PUBLIC_HOST:-localhost}:5553
# Docs: http://${PUBLIC_HOST:-localhost}:8099
# Daemon RPC: http://${PUBLIC_HOST:-localhost}:46941
# Wallet RPC: http://${PUBLIC_HOST:-localhost}:46944
services:
# --- Chain ---
daemon:
image: lthn/chain:testnet
container_name: lthn-daemon
restart: unless-stopped
ports:
- "${DAEMON_RPC_PORT:-46941}:36941"
- "${DAEMON_P2P_PORT:-46942}:36942"
volumes:
- chain-data:/data
entrypoint:
- lethean-chain-node
command:
- --data-dir
- /data
- --rpc-bind-ip
- "0.0.0.0"
- --rpc-bind-port
- "36941"
- --p2p-bind-port
- "36942"
- --rpc-enable-admin-api
- --allow-local-ip
- --log-level
- "${DAEMON_LOG_LEVEL:-1}"
- --disable-upnp
- --rpc-ignore-offline
healthcheck:
test: ["CMD-SHELL", "curl -sf http://localhost:36941/json_rpc -d '{\"jsonrpc\":\"2.0\",\"id\":\"0\",\"method\":\"getinfo\"}' -H 'Content-Type: application/json' | grep -q OK"]
interval: 30s
timeout: 10s
retries: 5
start_period: 30s
wallet:
image: lthn/chain:testnet
container_name: lthn-wallet
restart: unless-stopped
ports:
- "${WALLET_RPC_PORT:-46944}:36944"
volumes:
- wallet-data:/wallet
entrypoint:
- sh
- -c
command:
- |
if [ ! -f /wallet/main.wallet ]; then
echo '${WALLET_PASSWORD:-}' | lethean-wallet-cli --generate-new-wallet /wallet/main.wallet --password '${WALLET_PASSWORD:-}' --daemon-address daemon:36941 --command exit;
fi;
lethean-wallet-cli \
--wallet-file /wallet/main.wallet \
--password '${WALLET_PASSWORD:-}' \
--daemon-address daemon:36941 \
--rpc-bind-port 36944 \
--rpc-bind-ip 0.0.0.0 \
--do-pos-mining
depends_on:
daemon:
condition: service_healthy
# --- Explorer ---
explorer-db:
image: postgres:16-alpine
container_name: lthn-explorer-db
restart: unless-stopped
environment:
POSTGRES_USER: ${EXPLORER_DB_USER:-explorer}
POSTGRES_PASSWORD: ${EXPLORER_DB_PASS:-explorer}
POSTGRES_DB: ${EXPLORER_DB_NAME:-lethean_explorer}
volumes:
- explorer-db:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${EXPLORER_DB_USER:-explorer}"]
interval: 10s
timeout: 5s
retries: 5
explorer:
image: lthn/explorer:testnet
container_name: lthn-explorer
restart: unless-stopped
ports:
- "${EXPLORER_PORT:-3335}:3335"
environment:
API: http://daemon:36941
FRONTEND_API: http://${PUBLIC_HOST:-localhost}:${EXPLORER_PORT:-3335}
SERVER_PORT: "3335"
AUDITABLE_WALLET_API: http://daemon:36941
PGUSER: ${EXPLORER_DB_USER:-explorer}
PGPASSWORD: ${EXPLORER_DB_PASS:-explorer}
PGDATABASE: ${EXPLORER_DB_NAME:-lethean_explorer}
PGHOST: explorer-db
PGPORT: "5432"
MEXC_API_URL: ""
ASSETS_WHITELIST_URL: ""
depends_on:
daemon:
condition: service_healthy
explorer-db:
condition: service_healthy
# --- Trade ---
trade-db:
image: postgres:16-alpine
container_name: lthn-trade-db
restart: unless-stopped
environment:
POSTGRES_USER: ${TRADE_DB_USER:-trade}
POSTGRES_PASSWORD: ${TRADE_DB_PASS:-trade}
POSTGRES_DB: ${TRADE_DB_NAME:-lethean_trade}
volumes:
- trade-db:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${TRADE_DB_USER:-trade}"]
interval: 10s
timeout: 5s
retries: 5
trade-api:
image: lthn/trade-api:testnet
container_name: lthn-trade-api
restart: unless-stopped
ports:
- "${TRADE_API_PORT:-3336}:3336"
environment:
PORT: "3336"
PGUSER: ${TRADE_DB_USER:-trade}
PGPASSWORD: ${TRADE_DB_PASS:-trade}
PGDATABASE: ${TRADE_DB_NAME:-lethean_trade}
PGHOST: trade-db
PGPORT: "5432"
JWT_SECRET: ${JWT_SECRET:-change-me-before-production}
DAEMON_RPC_URL: http://daemon:36941/json_rpc
depends_on:
daemon:
condition: service_healthy
trade-db:
condition: service_healthy
trade-frontend:
image: lthn/trade-frontend:testnet
container_name: lthn-trade-frontend
restart: unless-stopped
ports:
- "${TRADE_FRONTEND_PORT:-3338}:30289"
environment:
NEXT_PUBLIC_API_URL: http://${PUBLIC_HOST:-localhost}:${TRADE_API_PORT:-3336}
API_URL: http://trade-api:3336
depends_on:
- trade-api
# --- Mining Pool ---
pool-redis:
image: redis:7-alpine
container_name: lthn-pool-redis
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
pool:
image: lthn/pool:testnet
container_name: lthn-pool
restart: unless-stopped
ports:
- "${POOL_STRATUM_PORT:-5555}:5555"
- "${POOL_API_PORT:-2117}:2117"
- "7777:7777"
- "8888:8888"
volumes:
- ./pool-config.json:/pool/config.json:ro
depends_on:
daemon:
condition: service_healthy
wallet:
condition: service_started
pool-redis:
condition: service_healthy
# --- LNS (Lethean Name Service) ---
lns:
image: lthn/lns:testnet
container_name: lthn-lns
restart: unless-stopped
ports:
- "${LNS_HTTP_PORT:-5553}:5553"
- "${LNS_DNS_PORT:-5354}:5354/udp"
- "${LNS_DNS_PORT:-5354}:5354/tcp"
environment:
DAEMON_URL: http://daemon:36941
HSD_URL: http://host.docker.internal:14037
LNS_MODE: light
LNS_HTTP_PORT: "5553"
LNS_DNS_PORT: "5354"
extra_hosts:
- "host.docker.internal:host-gateway"
depends_on:
daemon:
condition: service_healthy
# --- Docs ---
docs:
image: lthn/docs:testnet
container_name: lthn-docs
restart: unless-stopped
ports:
- "${DOCS_PORT:-8099}:80"
volumes:
chain-data:
wallet-data:
explorer-db:
trade-db:

View file

@ -1,221 +0,0 @@
# Lethean Testnet Network Simulation
# Spins up a 3-node testnet with explorer, wallet RPC, and trade services
#
# Usage:
# docker compose -f docker-compose.testnet.yml up -d
# docker compose -f docker-compose.testnet.yml logs -f node1
# docker compose -f docker-compose.testnet.yml down -v
#
# Nodes discover each other via exclusive-node flags.
# Node1 is the seed node, Node2 and Node3 connect to it.
services:
# === Blockchain Nodes ===
node1:
build:
context: ..
dockerfile: utils/docker/lthn-chain/Dockerfile
target: chain-service
args:
BUILD_TESTNET: 1
BUILD_THREADS: 4
container_name: lthn-node1
ports:
- "46941:36941" # RPC
- "46942:36942" # P2P
volumes:
- node1-data:/data
command: >
lethean-chain-node
--data-dir /data
--rpc-bind-ip 0.0.0.0
--rpc-bind-port 36941
--p2p-bind-port 36942
--rpc-enable-admin-api
--allow-local-ip
--log-level 1
--disable-upnp
networks:
lthn-testnet:
ipv4_address: 172.28.0.10
node2:
build:
context: ..
dockerfile: utils/docker/lthn-chain/Dockerfile
target: chain-service
args:
BUILD_TESTNET: 1
BUILD_THREADS: 4
container_name: lthn-node2
volumes:
- node2-data:/data
command: >
lethean-chain-node
--data-dir /data
--rpc-bind-ip 0.0.0.0
--rpc-bind-port 36941
--p2p-bind-port 36942
--add-exclusive-node 172.28.0.10:36942
--allow-local-ip
--log-level 1
--disable-upnp
depends_on:
- node1
networks:
lthn-testnet:
ipv4_address: 172.28.0.11
node3:
build:
context: ..
dockerfile: utils/docker/lthn-chain/Dockerfile
target: chain-service
args:
BUILD_TESTNET: 1
BUILD_THREADS: 4
container_name: lthn-node3
volumes:
- node3-data:/data
command: >
lethean-chain-node
--data-dir /data
--rpc-bind-ip 0.0.0.0
--rpc-bind-port 36941
--p2p-bind-port 36942
--add-exclusive-node 172.28.0.10:36942
--allow-local-ip
--log-level 1
--disable-upnp
depends_on:
- node1
networks:
lthn-testnet:
ipv4_address: 172.28.0.12
# === Wallet RPC ===
wallet:
build:
context: ..
dockerfile: utils/docker/lthn-chain/Dockerfile
target: chain-service
args:
BUILD_TESTNET: 1
BUILD_THREADS: 4
container_name: lthn-wallet
ports:
- "46944:36944" # Wallet RPC
volumes:
- wallet-data:/wallet
entrypoint: >
sh -c "
if [ ! -f /wallet/testnet.wallet ]; then
echo '' | lethean-wallet-cli --generate-new-wallet /wallet/testnet.wallet --password '' --daemon-address node1:36941 --command exit;
fi;
lethean-wallet-cli
--wallet-file /wallet/testnet.wallet
--password ''
--daemon-address node1:36941
--rpc-bind-port 36944
--rpc-bind-ip 0.0.0.0
--do-pos-mining
"
depends_on:
- node1
networks:
lthn-testnet:
ipv4_address: 172.28.0.20
# === Explorer ===
explorer-db:
image: postgres:16-alpine
container_name: lthn-explorer-db
environment:
POSTGRES_USER: explorer
POSTGRES_PASSWORD: explorer
POSTGRES_DB: lethean_explorer
volumes:
- explorer-db-data:/var/lib/postgresql/data
networks:
lthn-testnet:
ipv4_address: 172.28.0.30
explorer:
build:
context: ../../lthn/zano-upstream/zano-explorer-zarcanum
dockerfile: Dockerfile
container_name: lthn-explorer
ports:
- "3335:3335"
environment:
API: http://node1:36941
FRONTEND_API: http://127.0.0.1:3335
SERVER_PORT: "3335"
AUDITABLE_WALLET_API: http://node1:36941
PGUSER: explorer
PGPASSWORD: explorer
PGDATABASE: lethean_explorer
PGHOST: explorer-db
PGPORT: "5432"
MEXC_API_URL: ""
depends_on:
- node1
- explorer-db
networks:
lthn-testnet:
ipv4_address: 172.28.0.31
# === Trade Backend ===
trade-db:
image: postgres:16-alpine
container_name: lthn-trade-db
environment:
POSTGRES_USER: trade
POSTGRES_PASSWORD: trade
POSTGRES_DB: lethean_trade
volumes:
- trade-db-data:/var/lib/postgresql/data
networks:
lthn-testnet:
ipv4_address: 172.28.0.40
trade-api:
build:
context: ../../lthn/zano-upstream/zano_trade_backend
container_name: lthn-trade-api
ports:
- "3336:3336"
environment:
PORT: "3336"
PGUSER: trade
PGPASSWORD: trade
PGDATABASE: lethean_trade
PGHOST: trade-db
PGPORT: "5432"
JWT_SECRET: testnet-dev-secret
DAEMON_RPC_URL: http://node1:36941/json_rpc
depends_on:
- node1
- trade-db
networks:
lthn-testnet:
ipv4_address: 172.28.0.41
networks:
lthn-testnet:
driver: bridge
ipam:
config:
- subnet: 172.28.0.0/16
volumes:
node1-data:
node2-data:
node3-data:
wallet-data:
explorer-db-data:
trade-db-data:

View file

@ -1,126 +0,0 @@
# Lethean VPN Stack — sandboxed legacy Python + WireGuard
# Chain node + wallet + VPN dispatcher + WireGuard gateway
#
# Usage:
# docker compose -f docker-compose.vpn.yml up -d
#
# This sandboxes the legacy Python VPN code inside containers
# until the CoreGO replacement is ready.
services:
# Chain daemon (testnet)
daemon:
build:
context: ..
dockerfile: utils/docker/lthn-chain/Dockerfile
target: chain-service
args:
BUILD_TESTNET: 1
BUILD_THREADS: 4
container_name: lthn-vpn-daemon
volumes:
- daemon-data:/data
command: >
lethean-chain-node
--data-dir /data
--rpc-bind-ip 0.0.0.0
--rpc-bind-port 36941
--p2p-bind-port 36942
--rpc-enable-admin-api
--allow-local-ip
--log-level 1
--disable-upnp
networks:
vpn-net:
ipv4_address: 172.31.0.10
# Wallet RPC (for payment processing)
wallet:
build:
context: ..
dockerfile: utils/docker/lthn-chain/Dockerfile
target: chain-service
args:
BUILD_TESTNET: 1
BUILD_THREADS: 4
container_name: lthn-vpn-wallet
volumes:
- wallet-data:/wallet
entrypoint: >
sh -c "
if [ ! -f /wallet/vpn.wallet ]; then
echo '' | lethean-wallet-cli --generate-new-wallet /wallet/vpn.wallet --password '' --daemon-address daemon:36941 --command exit;
fi;
lethean-wallet-cli
--wallet-file /wallet/vpn.wallet
--password ''
--daemon-address daemon:36941
--rpc-bind-port 36944
--rpc-bind-ip 0.0.0.0
"
depends_on:
- daemon
networks:
vpn-net:
ipv4_address: 172.31.0.20
# VPN Dispatcher (legacy Python, sandboxed)
dispatcher:
build:
context: ../../lthn/lthn-app-vpn
container_name: lthn-vpn-dispatcher
cap_add:
- NET_ADMIN
environment:
DAEMON_HOST: daemon
DAEMON_RPC_PORT: "36941"
MODE: server
ports:
- "8124:8124" # Server management API
depends_on:
- daemon
- wallet
networks:
vpn-net:
ipv4_address: 172.31.0.30
# WireGuard Gateway
wireguard:
image: lscr.io/linuxserver/wireguard:latest
container_name: lthn-vpn-wireguard
cap_add:
- NET_ADMIN
- SYS_MODULE
environment:
PUID: 1000
PGID: 1000
TZ: Europe/London
SERVERURL: auto
SERVERPORT: 51820
PEERS: 10
PEERDNS: 1.1.1.1
INTERNAL_SUBNET: 10.13.13.0
ALLOWEDIPS: 0.0.0.0/0,::/0
LOG_CONFS: "false"
ports:
- "51820:51820/udp"
volumes:
- wireguard-config:/config
sysctls:
- net.ipv4.conf.all.src_valid_mark=1
- net.ipv4.ip_forward=1
networks:
vpn-net:
ipv4_address: 172.31.0.40
networks:
vpn-net:
driver: bridge
ipam:
config:
- subnet: 172.31.0.0/24
volumes:
daemon-data:
wallet-data:
wireguard-config:

View file

@ -1,58 +0,0 @@
#!/bin/bash
# Lethean Testnet Health Check
# Run: bash health.sh
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
check() {
local name="$1"
local url="$2"
local code
code=$(curl -sf -o /dev/null -w "%{http_code}" "$url" 2>/dev/null)
if [ "$code" = "200" ] || [ "$code" = "307" ] || [ "$code" = "404" ]; then
printf " ${GREEN}%-16s${NC} %s ${YELLOW}(HTTP %s)${NC}\n" "$name" "$url" "$code"
else
printf " ${RED}%-16s${NC} %s ${RED}(DOWN)${NC}\n" "$name" "$url"
fi
}
rpc() {
local name="$1"
local url="$2"
local method="$3"
local result
result=$(curl -sf "$url" -d "{\"jsonrpc\":\"2.0\",\"id\":\"0\",\"method\":\"$method\"}" -H 'Content-Type: application/json' 2>/dev/null)
if [ -n "$result" ]; then
printf " ${GREEN}%-16s${NC} %s\n" "$name" "$(echo "$result" | python3 -c "
import sys,json
d=json.load(sys.stdin).get('result',{})
if 'height' in d:
hf = d.get('is_hardfok_active',[])
active = sum(1 for h in hf if h)
print(f'height={d[\"height\"]}, HF0-{active-1} active, status={d.get(\"status\",\"?\")}')
elif 'balance' in d:
print(f'{d[\"balance\"]/1e12:.4f} LTHN ({d[\"unlocked_balance\"]/1e12:.4f} unlocked)')
else:
print(json.dumps(d)[:80])
" 2>/dev/null)"
else
printf " ${RED}%-16s${NC} %s ${RED}(DOWN)${NC}\n" "$name" "$url"
fi
}
echo ""
echo " Lethean Testnet Health Check"
echo " $(date)"
echo " ---"
rpc "Daemon" "http://localhost:${DAEMON_RPC_PORT:-46941}/json_rpc" "getinfo"
rpc "Wallet" "http://localhost:${WALLET_RPC_PORT:-46944}/json_rpc" "getbalance"
check "Explorer" "http://localhost:${EXPLORER_PORT:-3335}/"
check "Trade API" "http://localhost:${TRADE_API_PORT:-3336}/"
check "Trade Web" "http://localhost:${TRADE_FRONTEND_PORT:-3338}/"
check "Pool API" "http://localhost:${POOL_API_PORT:-2117}/stats"
check "LNS" "http://localhost:${LNS_HTTP_PORT:-5553}/"
check "Docs" "http://localhost:${DOCS_PORT:-8099}/"
echo ""

View file

@ -1,15 +0,0 @@
[Unit]
Description=Lethean Testnet Ecosystem
Requires=docker.service
After=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/lethean/docker
ExecStart=/usr/bin/docker compose -f docker-compose.pull.yml up -d
ExecStop=/usr/bin/docker compose -f docker-compose.pull.yml down
TimeoutStartSec=120
[Install]
WantedBy=multi-user.target

View file

@ -1,52 +0,0 @@
# Lethean Testnet Configuration
# Copy to .env and customise before running:
# cp .env.example .env
# docker compose -f docker-compose.pull.yml up -d
# Public hostname (used by explorer and trade frontend)
PUBLIC_HOST=localhost
# Wallet password (empty = no password, change for production)
WALLET_PASSWORD=my-secure-pass
# Trade API JWT secret (CHANGE THIS for production)
JWT_SECRET=change-me-before-production
# Explorer database
EXPLORER_DB_USER=explorer
EXPLORER_DB_PASS=explorer
EXPLORER_DB_NAME=lethean_explorer
# Trade database
TRADE_DB_USER=trade
TRADE_DB_PASS=trade
TRADE_DB_NAME=lethean_trade
# Daemon log level (0=minimal, 1=normal, 2=detailed, 3=trace)
DAEMON_LOG_LEVEL=1
# Port overrides (defaults shown)
# DAEMON_RPC_PORT=46941
# DAEMON_P2P_PORT=46942
# WALLET_RPC_PORT=46944
# EXPLORER_PORT=3335
# TRADE_API_PORT=3336
# TRADE_FRONTEND_PORT=3338
# POOL_STRATUM_PORT=5555
# POOL_API_PORT=2117
# LNS_HTTP_PORT=5553
# LNS_DNS_PORT=5354
# === Exit Node Settings (docker-compose.exit.yml) ===
# Your public IP address (required for VPN exit node)
# EXIT_PUBLIC_IP=auto
# Exit node name (registered as on-chain alias)
# EXIT_NAME=my-exit-node
# Maximum VPN peers (WireGuard clients)
# EXIT_MAX_PEERS=25
# Timezone
# TZ=Europe/London

View file

@ -1,52 +0,0 @@
# Lethean Testnet Configuration
# Copy to .env and customise before running:
# cp .env.example .env
# docker compose -f docker-compose.pull.yml up -d
# Public hostname (used by explorer and trade frontend)
PUBLIC_HOST=localhost
# Wallet password (empty = no password, change for production)
WALLET_PASSWORD=
# Trade API JWT secret (CHANGE THIS for production)
JWT_SECRET=change-me-before-production
# Explorer database
EXPLORER_DB_USER=explorer
EXPLORER_DB_PASS=explorer
EXPLORER_DB_NAME=lethean_explorer
# Trade database
TRADE_DB_USER=trade
TRADE_DB_PASS=trade
TRADE_DB_NAME=lethean_trade
# Daemon log level (0=minimal, 1=normal, 2=detailed, 3=trace)
DAEMON_LOG_LEVEL=1
# Port overrides (defaults shown)
# DAEMON_RPC_PORT=46941
# DAEMON_P2P_PORT=46942
# WALLET_RPC_PORT=46944
# EXPLORER_PORT=3335
# TRADE_API_PORT=3336
# TRADE_FRONTEND_PORT=3338
# POOL_STRATUM_PORT=5555
# POOL_API_PORT=2117
# LNS_HTTP_PORT=5553
# LNS_DNS_PORT=5354
# === Exit Node Settings (docker-compose.exit.yml) ===
# Your public IP address (required for VPN exit node)
# EXIT_PUBLIC_IP=auto
# Exit node name (registered as on-chain alias)
# EXIT_NAME=my-exit-node
# Maximum VPN peers (WireGuard clients)
# EXIT_MAX_PEERS=25
# Timezone
# TZ=Europe/London

View file

@ -1,86 +0,0 @@
# Lethean Home Node
# A self-contained chain node for home users who want to support the network.
# Syncs the chain, runs a wallet with PoS staking, and exposes P2P for peering.
#
# Usage:
# cp .env.example .env # edit WALLET_PASSWORD at minimum
# docker compose -f docker-compose.node.yml up -d
#
# What it does:
# - Syncs and validates the Lethean blockchain
# - Peers with other nodes (P2P port 46942)
# - Runs a wallet that stakes automatically (PoS mining)
# - Optionally mines with ProgPoWZ (connect external GPU miner)
#
# Earnings:
# - PoS staking rewards (proportional to balance)
# - PoW block rewards if mining
#
# Ports:
# 46941 — Daemon RPC (local tools)
# 46942 — P2P (open this on your router for full node)
# 46944 — Wallet RPC (local tools)
services:
daemon:
image: lthn/chain:testnet
container_name: lthn-node
restart: unless-stopped
ports:
- "${DAEMON_RPC_PORT:-46941}:36941"
- "${DAEMON_P2P_PORT:-46942}:36942"
volumes:
- chain-data:/data
entrypoint:
- lethean-chain-node
command:
- --data-dir
- /data
- --rpc-bind-ip
- "0.0.0.0"
- --rpc-bind-port
- "36941"
- --p2p-bind-port
- "36942"
- --rpc-enable-admin-api
- --allow-local-ip
- --log-level
- "${DAEMON_LOG_LEVEL:-1}"
- --disable-upnp
healthcheck:
test: ["CMD-SHELL", "curl -sf http://localhost:36941/json_rpc -d '{\"jsonrpc\":\"2.0\",\"id\":\"0\",\"method\":\"getinfo\"}' -H 'Content-Type: application/json' | grep -q OK"]
interval: 30s
timeout: 10s
retries: 5
start_period: 60s
wallet:
image: lthn/chain:testnet
container_name: lthn-wallet
restart: unless-stopped
ports:
- "${WALLET_RPC_PORT:-46944}:36944"
volumes:
- wallet-data:/wallet
entrypoint:
- sh
- -c
command:
- |
if [ ! -f /wallet/node.wallet ]; then
echo '${WALLET_PASSWORD:-}' | lethean-wallet-cli --generate-new-wallet /wallet/node.wallet --password '${WALLET_PASSWORD:-}' --daemon-address daemon:36941 --command exit;
fi;
lethean-wallet-cli \
--wallet-file /wallet/node.wallet \
--password '${WALLET_PASSWORD:-}' \
--daemon-address daemon:36941 \
--rpc-bind-port 36944 \
--rpc-bind-ip 0.0.0.0 \
--do-pos-mining
depends_on:
daemon:
condition: service_healthy
volumes:
chain-data:
wallet-data:

View file

@ -1,301 +0,0 @@
{
"poolHost": "lethean.somewhere.com",
"coin": "Lethean",
"symbol": "LTHN",
"coinUnits": 1000000000000,
"coinDecimalPlaces": 12,
"coinDifficultyTarget": 120,
"blockchainExplorer": "http://localhost:3335/block/{id}",
"transactionExplorer": "http://localhost:3335/transaction/{id}",
"daemonType": "default",
"cnAlgorithm": "progpowz",
"cnVariant": 2,
"cnBlobType": 0,
"isRandomX": false,
"includeHeight": false,
"previousOffset": 7,
"offset": 2,
"isCryptonight": false,
"reward": 1000000000000,
"logging": {
"files": {
"level": "info",
"directory": "logs",
"flushInterval": 5,
"prefix": "Lethean"
},
"console": {
"level": "info",
"colors": true
}
},
"childPools": [],
"poolServer": {
"enabled": true,
"mergedMining": false,
"clusterForks": 3,
"poolAddress": "iTHNUNiuu3VP1yy8xH2y5iQaABKXurdjqZmzFiBiyR4dKG3j6534e9jMriY6SM7PH8NibVwVWW1DWJfQEWnSjS8n3Wgx86pQpY",
"intAddressPrefix": null,
"blockRefreshInterval": 1000,
"minerTimeout": 900,
"sslCert": "cert.pem",
"sslKey": "privkey.pem",
"sslCA": "chain.pem",
"ports": [
{
"port": 5555,
"difficulty": 50000,
"desc": "Low end hardware"
},
{
"port": 7777,
"difficulty": 500000,
"desc": "Mid/high end hardware"
},
{
"port": 8888,
"difficulty": 5000000,
"desc": "Nicehash, MRR"
}
],
"varDiff": {
"minDiff": 10000,
"maxDiff": 5000000,
"targetTime": 45,
"retargetTime": 60,
"variancePercent": 30,
"maxJump": 100
},
"paymentId": {
"addressSeparator": "+"
},
"fixedDiff": {
"enabled": true,
"addressSeparator": "."
},
"shareTrust": {
"enabled": true,
"min": 10,
"stepDown": 3,
"threshold": 10,
"penalty": 30
},
"banning": {
"enabled": true,
"time": 600,
"invalidPercent": 25,
"checkThreshold": 30
},
"slushMining": {
"enabled": false,
"weight": 300,
"blockTime": 60,
"lastBlockCheckRate": 1
}
},
"payments": {
"enabled": true,
"interval": 900,
"maxAddresses": 5,
"mixin": 10,
"priority": 0,
"transferFee": 10000000000,
"dynamicTransferFee": true,
"minerPayFee": true,
"minPayment": 1000000000000,
"maxPayment": 100000000000000,
"maxTransactionAmount": 100000000000000,
"denomination": 1000000000000
},
"blockUnlocker": {
"enabled": true,
"interval": 60,
"depth": 10,
"poolFee": 0.2,
"soloFee": 0.2,
"devDonation": 0.5,
"networkFee": 0.0
},
"api": {
"enabled": true,
"hashrateWindow": 600,
"updateInterval": 15,
"bindIp": "0.0.0.0",
"port": 2117,
"blocks": 30,
"payments": 30,
"password": "password",
"ssl": false,
"sslPort": 2119,
"sslCert": "cert.pem",
"sslKey": "privkey.pem",
"sslCA": "chain.pem",
"trustProxyIP": true
},
"zmq": {
"enabled": false,
"host": "127.0.0.1",
"port": 39995
},
"daemon": {
"host": "daemon",
"port": 36941
},
"wallet": {
"host": "wallet",
"port": 36944
},
"redis": {
"host": "pool-redis",
"port": 6379,
"db": 11,
"cleanupInterval": 15
},
"notifications": {
"emailTemplate": "email_templates/default.txt",
"emailSubject": {
"emailAdded": "Your email was registered",
"workerConnected": "Worker %WORKER_NAME% connected",
"workerTimeout": "Worker %WORKER_NAME% stopped hashing",
"workerBanned": "Worker %WORKER_NAME% banned",
"blockFound": "Block %HEIGHT% found !",
"blockUnlocked": "Block %HEIGHT% unlocked !",
"blockOrphaned": "Block %HEIGHT% orphaned !",
"payment": "We sent you a payment !"
},
"emailMessage": {
"emailAdded": "Your email has been registered to receive pool notifications.",
"workerConnected": "Your worker %WORKER_NAME% for address %MINER% is now connected from ip %IP%.",
"workerTimeout": "Your worker %WORKER_NAME% for address %MINER% has stopped submitting hashes on %LAST_HASH%.",
"workerBanned": "Your worker %WORKER_NAME% for address %MINER% has been banned.",
"blockFound": "Block found at height %HEIGHT% by miner %MINER% on %TIME%. Waiting maturity.",
"blockUnlocked": "Block mined at height %HEIGHT% with %REWARD% and %EFFORT% effort on %TIME%.",
"blockOrphaned": "Block orphaned at height %HEIGHT% :(",
"payment": "A payment of %AMOUNT% has been sent to %ADDRESS% wallet."
},
"telegramMessage": {
"workerConnected": "Your worker _%WORKER_NAME%_ for address _%MINER%_ is now connected from ip _%IP%_.",
"workerTimeout": "Your worker _%WORKER_NAME%_ for address _%MINER%_ has stopped submitting hashes on _%LAST_HASH%_.",
"workerBanned": "Your worker _%WORKER_NAME%_ for address _%MINER%_ has been banned.",
"blockFound": "*Block found at height* _%HEIGHT%_ *by miner* _%MINER%_*! Waiting maturity.*",
"blockUnlocked": "*Block mined at height* _%HEIGHT%_ *with* _%REWARD%_ *and* _%EFFORT%_ *effort on* _%TIME%_*.*",
"blockOrphaned": "*Block orphaned at height* _%HEIGHT%_ *:(*",
"payment": "A payment of _%AMOUNT%_ has been sent."
}
},
"email": {
"enabled": false,
"fromAddress": "your@email.com",
"transport": "sendmail",
"sendmail": {
"path": "/usr/sbin/sendmail"
},
"smtp": {
"host": "smtp.example.com",
"port": 587,
"secure": false,
"auth": {
"user": "username",
"pass": "password"
},
"tls": {
"rejectUnauthorized": false
}
},
"mailgun": {
"key": "your-private-key",
"domain": "mg.yourdomain"
}
},
"telegram": {
"enabled": false,
"botName": "",
"token": "",
"channel": "",
"channelStats": {
"enabled": false,
"interval": 30
},
"botCommands": {
"stats": "/stats",
"report": "/report",
"notify": "/notify",
"blocks": "/blocks"
}
},
"monitoring": {
"daemon": {
"checkInterval": 60,
"rpcMethod": "getblockcount"
},
"wallet": {
"checkInterval": 60,
"rpcMethod": "getbalance"
}
},
"prices": {
"source": "tradeogre",
"currency": "USD"
},
"charts": {
"pool": {
"hashrate": {
"enabled": true,
"updateInterval": 60,
"stepInterval": 1800,
"maximumPeriod": 86400
},
"miners": {
"enabled": true,
"updateInterval": 60,
"stepInterval": 1800,
"maximumPeriod": 86400
},
"workers": {
"enabled": true,
"updateInterval": 60,
"stepInterval": 1800,
"maximumPeriod": 86400
},
"difficulty": {
"enabled": true,
"updateInterval": 1800,
"stepInterval": 10800,
"maximumPeriod": 604800
},
"price": {
"enabled": true,
"updateInterval": 1800,
"stepInterval": 10800,
"maximumPeriod": 604800
},
"profit": {
"enabled": true,
"updateInterval": 1800,
"stepInterval": 10800,
"maximumPeriod": 604800
}
},
"user": {
"hashrate": {
"enabled": true,
"updateInterval": 180,
"stepInterval": 1800,
"maximumPeriod": 86400
},
"worker_hashrate": {
"enabled": true,
"updateInterval": 60,
"stepInterval": 60,
"maximumPeriod": 86400
},
"payments": {
"enabled": true
}
},
"blocks": {
"enabled": true,
"days": 30
}
}
}

View file

@ -1,90 +0,0 @@
#!/bin/bash
# Lethean testnet network validation script
# Tests: node sync, mining, wallet, block propagation
#
# Usage: ./test-network.sh [compose-file]
# Default: docker-compose.nodes.yml
set -e
COMPOSE=${1:-docker-compose.nodes.yml}
echo "=== Lethean Network Test ==="
echo "Using: $COMPOSE"
echo ""
# Check all nodes are running
echo "1. Checking node health..."
for n in 1 2 3; do
port=$((46940 + (n-1)*10 + 1))
height=$(curl -s -X POST http://127.0.0.1:$port/json_rpc \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":"0","method":"getinfo"}' 2>/dev/null | \
python3 -c "import sys,json; print(json.load(sys.stdin)['result']['height'])" 2>/dev/null)
echo " node$n (:$port): height=$height"
done
echo ""
echo "2. Checking P2P connectivity..."
peers=$(curl -s -X POST http://127.0.0.1:46941/json_rpc \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":"0","method":"getinfo"}' 2>/dev/null | \
python3 -c "import sys,json; d=json.load(sys.stdin)['result']; print(f'out={d[\"outgoing_connections_count\"]} in={d[\"incoming_connections_count\"]}')" 2>/dev/null)
echo " node1 peers: $peers"
echo ""
echo "3. Testing getblocktemplate..."
template=$(curl -s -X POST http://127.0.0.1:46941/json_rpc \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":"0","method":"getblocktemplate","params":{"wallet_address":"iTHNUNiuu3VP1yy8xH2y5iQaABKXurdjqZmzFiBiyR4dKG3j6534e9jMriY6SM7PH8NibVwVWW1DWJfQEWnSjS8n3Wgx86pQpY"}}' 2>/dev/null | \
python3 -c "import sys,json; r=json.load(sys.stdin)['result']; print(f'height={r[\"height\"]} diff={r[\"difficulty\"]}')" 2>/dev/null)
echo " template: $template"
echo ""
echo "4. Starting mining on node1..."
curl -s -X POST http://127.0.0.1:46941/start_mining \
-H 'Content-Type: application/json' \
-d '{"miner_address":"iTHNUNiuu3VP1yy8xH2y5iQaABKXurdjqZmzFiBiyR4dKG3j6534e9jMriY6SM7PH8NibVwVWW1DWJfQEWnSjS8n3Wgx86pQpY","threads_count":4}' 2>/dev/null | python3 -m json.tool 2>/dev/null
echo ""
echo "5. Waiting 60s for blocks..."
sleep 60
echo ""
echo "6. Checking sync across nodes..."
heights=""
for n in 1 2 3; do
port=$((46940 + (n-1)*10 + 1))
h=$(curl -s -X POST http://127.0.0.1:$port/json_rpc \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":"0","method":"getinfo"}' 2>/dev/null | \
python3 -c "import sys,json; print(json.load(sys.stdin)['result']['height'])" 2>/dev/null)
echo " node$n: height=$h"
heights="$heights $h"
done
# Check all nodes at same height
unique=$(echo $heights | tr ' ' '\n' | sort -u | wc -l)
if [ "$unique" -eq 1 ]; then
echo ""
echo " PASS: All nodes synced at same height"
else
echo ""
echo " WARN: Nodes at different heights (propagation delay normal)"
fi
echo ""
echo "7. Checking HF status..."
curl -s -X POST http://127.0.0.1:46941/json_rpc \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":"0","method":"getinfo"}' 2>/dev/null | \
python3 -c "
import sys,json
d=json.load(sys.stdin)['result']
hf=[i for i,v in enumerate(d['is_hardfok_active']) if v]
print(f' Active HFs: {hf}')
print(f' PoS allowed: {d[\"pos_allowed\"]}')
print(f' Aliases: {d[\"alias_count\"]}')
"
echo ""
echo "=== Test Complete ==="

View file

@ -1,153 +0,0 @@
#!/usr/bin/env python3
"""
Lethean Key Bridge Prototype
Derives an HNS sidechain secp256k1 keypair from a Lethean ed25519 spend key.
One seed phrase both chains.
Lethean seed phrase
ed25519 spend key (32 bytes)
Main chain wallet (native CryptoNote)
HKDF("lethean-hns-bridge", spend_key)
secp256k1 private key (32 bytes)
Sidechain wallet (derived)
Usage:
python3 key-bridge-prototype.py <hex_spend_key>
python3 key-bridge-prototype.py --from-wallet http://127.0.0.1:46944/json_rpc
Dependencies:
pip install cryptography secp256k1 (or use hashlib for prototype)
"""
import hashlib
import hmac
import sys
import json
import urllib.request
def derive_sidechain_key(spend_key_hex: str) -> dict:
"""
Derive a secp256k1 private key from a Lethean ed25519 spend key.
Uses HKDF-like construction:
prk = HMAC-SHA256(key="lethean-hns-bridge", msg=spend_key)
secp256k1_key = HMAC-SHA256(key=prk, msg="hns-sidechain-v1" || 0x01)
The domain separation ensures:
- Different derivation paths produce different keys
- The ed25519 key cannot be recovered from the secp256k1 key
- Future derivation paths (v2, v3) won't collide
"""
spend_key = bytes.fromhex(spend_key_hex)
assert len(spend_key) == 32, f"Spend key must be 32 bytes, got {len(spend_key)}"
# Step 1: Extract — domain-separated PRK
salt = b"lethean-hns-bridge"
prk = hmac.new(salt, spend_key, hashlib.sha256).digest()
# Step 2: Expand — derive the secp256k1 key
info = b"hns-sidechain-v1\x01"
secp256k1_privkey = hmac.new(prk, info, hashlib.sha256).digest()
# secp256k1 requires the key to be in range [1, n-1]
# n = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
key_int = int.from_bytes(secp256k1_privkey, 'big')
if key_int == 0 or key_int >= n:
# Extremely unlikely but handle it — rehash
secp256k1_privkey = hmac.new(prk, b"hns-sidechain-v1\x02", hashlib.sha256).digest()
key_int = int.from_bytes(secp256k1_privkey, 'big') % (n - 1) + 1
secp256k1_privkey = key_int.to_bytes(32, 'big')
# Derive additional keys for future use
document_signing_key = hmac.new(prk, b"document-signing-v1\x01", hashlib.sha256).digest()
audit_key = hmac.new(prk, b"audit-trail-v1\x01", hashlib.sha256).digest()
return {
"source": {
"type": "ed25519",
"chain": "lethean-mainchain",
"spend_key": spend_key_hex,
},
"derived": {
"hns_sidechain": {
"type": "secp256k1",
"chain": "lethean-hns-sidechain",
"private_key": secp256k1_privkey.hex(),
"derivation": "HKDF(salt=lethean-hns-bridge, ikm=spend_key, info=hns-sidechain-v1)",
},
"document_signing": {
"type": "ed25519",
"purpose": "document hash timestamping",
"private_key": document_signing_key.hex(),
"derivation": "HKDF(salt=lethean-hns-bridge, ikm=spend_key, info=document-signing-v1)",
},
"audit": {
"type": "ed25519",
"purpose": "audit trail verification",
"private_key": audit_key.hex(),
"derivation": "HKDF(salt=lethean-hns-bridge, ikm=spend_key, info=audit-trail-v1)",
},
},
"derivation_version": "1.0",
"note": "All keys derived deterministically from the Lethean spend key. One seed, all chains and purposes.",
}
def get_spend_key_from_wallet(rpc_url: str) -> str:
"""Fetch the spend key from a running wallet RPC."""
payload = json.dumps({
"jsonrpc": "2.0",
"id": "0",
"method": "get_wallet_info",
"params": {}
}).encode()
req = urllib.request.Request(
rpc_url,
data=payload,
headers={"Content-Type": "application/json"}
)
try:
with urllib.request.urlopen(req, timeout=5) as resp:
data = json.loads(resp.read())
# The spend key isn't directly in get_wallet_info
# We'd need a custom RPC or the seed to derive it
# For prototype, use the address as a stand-in
print("Note: Full implementation needs 'get_spend_key' RPC or seed phrase input")
print(f"Wallet address: {data.get('result', {}).get('wi', {}).get('address', '?')}")
return None
except Exception as e:
print(f"Error connecting to wallet: {e}")
return None
def main():
if len(sys.argv) < 2:
print(__doc__)
print("\nExample with test key:")
test_key = "a" * 64 # 32 bytes of 0xAA
result = derive_sidechain_key(test_key)
print(json.dumps(result, indent=2))
return
if sys.argv[1] == "--from-wallet":
rpc_url = sys.argv[2] if len(sys.argv) > 2 else "http://127.0.0.1:46944/json_rpc"
spend_key = get_spend_key_from_wallet(rpc_url)
if not spend_key:
print("\nUsing test key for demonstration:")
spend_key = "7b9f1e2a3c4d5e6f708192a3b4c5d6e7f8091a2b3c4d5e6f708192a3b4c5d6e7"
else:
spend_key = sys.argv[1]
result = derive_sidechain_key(spend_key)
print(json.dumps(result, indent=2))
if __name__ == "__main__":
main()

View file

@ -1,130 +0,0 @@
#!/bin/bash
# Lethean Reserved Name Registrar
# Batch-registers protected aliases on the main chain to prevent squatting.
#
# Usage:
# bash register-reserved.sh [names-file] [wallet-rpc] [batch-size] [delay]
#
# Defaults:
# names-file: /tmp/protected-names-priority.txt
# wallet-rpc: http://127.0.0.1:46944/json_rpc
# batch-size: 10 (aliases per batch before checking balance)
# delay: 2 (seconds between registrations)
NAMES_FILE="${1:-/tmp/protected-names-priority.txt}"
WALLET_RPC="${2:-http://127.0.0.1:46944/json_rpc}"
BATCH_SIZE="${3:-10}"
DELAY="${4:-2}"
COMMENT="v=lthn1;type=reserved;reason=hns-protected"
LOG_FILE="/tmp/register-reserved.log"
DONE_FILE="/tmp/registered-names.txt"
touch "$DONE_FILE"
get_balance() {
curl -sf "$WALLET_RPC" -d '{"jsonrpc":"2.0","id":"0","method":"getbalance"}' \
-H 'Content-Type: application/json' | python3 -c "
import sys,json
d=json.load(sys.stdin)['result']
print(d['unlocked_balance'])
" 2>/dev/null
}
get_address() {
curl -sf "$WALLET_RPC" -d '{"jsonrpc":"2.0","id":"0","method":"getaddress"}' \
-H 'Content-Type: application/json' | python3 -c "
import sys,json
print(json.load(sys.stdin)['result']['address'])
" 2>/dev/null
}
register_alias() {
local name="$1"
local address="$2"
result=$(curl -sf "$WALLET_RPC" -d "{
\"jsonrpc\":\"2.0\",\"id\":\"0\",\"method\":\"register_alias\",
\"params\":{
\"alias\":\"$name\",
\"address\":\"$address\",
\"comment\":\"$COMMENT\"
}
}" -H 'Content-Type: application/json' 2>/dev/null)
if echo "$result" | grep -q '"result"'; then
tx=$(echo "$result" | python3 -c "import sys,json; print(json.load(sys.stdin)['result'].get('tx_hash','ok'))" 2>/dev/null)
echo "$name" >> "$DONE_FILE"
echo "$(date +%H:%M:%S) OK @$name ($tx)" | tee -a "$LOG_FILE"
return 0
else
error=$(echo "$result" | python3 -c "import sys,json; print(json.load(sys.stdin).get('error',{}).get('message','unknown')[:80])" 2>/dev/null)
echo "$(date +%H:%M:%S) ERR @$name$error" | tee -a "$LOG_FILE"
return 1
fi
}
# Get wallet address
ADDRESS=$(get_address)
if [ -z "$ADDRESS" ]; then
echo "ERROR: Can't connect to wallet at $WALLET_RPC"
exit 1
fi
echo "Wallet: $ADDRESS"
echo "Names file: $NAMES_FILE ($(wc -l < "$NAMES_FILE") names)"
echo "Already registered: $(wc -l < "$DONE_FILE") names"
echo "Comment: $COMMENT"
echo "Batch: $BATCH_SIZE, Delay: ${DELAY}s"
echo "Log: $LOG_FILE"
echo "---"
BALANCE=$(get_balance)
BALANCE_LTHN=$(echo "scale=2; $BALANCE / 1000000000000" | bc 2>/dev/null)
echo "Balance: $BALANCE_LTHN LTHN"
echo ""
COUNT=0
REGISTERED=0
FAILED=0
SKIPPED=0
while IFS= read -r name; do
# Skip empty lines and comments
[[ -z "$name" || "$name" == \#* ]] && continue
# Skip already registered
if grep -qxF "$name" "$DONE_FILE" 2>/dev/null; then
((SKIPPED++))
continue
fi
# Check balance every batch
if (( COUNT % BATCH_SIZE == 0 && COUNT > 0 )); then
BALANCE=$(get_balance)
BALANCE_LTHN=$(echo "scale=2; $BALANCE / 1000000000000" | bc 2>/dev/null)
echo "--- Batch checkpoint: $BALANCE_LTHN LTHN, $REGISTERED registered, $FAILED failed ---"
# Stop if balance too low (need 1 LTHN + fee)
if (( BALANCE < 1100000000000 )); then
echo "Balance too low ($BALANCE_LTHN LTHN). Stopping."
break
fi
fi
register_alias "$name" "$ADDRESS"
if [ $? -eq 0 ]; then
((REGISTERED++))
else
((FAILED++))
fi
((COUNT++))
sleep "$DELAY"
done < "$NAMES_FILE"
echo ""
echo "=== Done ==="
echo "Registered: $REGISTERED"
echo "Failed: $FAILED"
echo "Skipped: $SKIPPED"
echo "Total processed: $COUNT"

2
docs

@ -1 +1 @@
Subproject commit e40a78d5020661f05d9bae64f2edd4519d9d98b3 Subproject commit 12e20efce7eaf51e38d8953c318633b1c5189256

View file

@ -1,30 +0,0 @@
{
"payments": [
{
"address_this": "iTHNdRWX6pKGXF1HqHgZyXie8EdaCwwdWUmsEnQhNojSUrkrR2eTemhFYkjWXbhdbyGcRBLgV2RYp3HhNAFCQ67w4bTHErZL1J",
"amount_this": 10000000.0,
"this_usd_price": "1.0",
"paid_prm": "",
"prm_usd_price": "",
"paid_xmr": "",
"xmr_usd_price": "",
"paid_qtum": "",
"qtum_usd_price": "",
"paid_bch": "",
"bch_usd_price": "",
"paid_rep": "",
"rep_usd_price": "",
"paid_dash": "",
"dash_usd_price": "",
"paid_ltc": "",
"ltc_usd_price": "",
"paid_eos": "",
"eos_usd_price": "",
"paid_eth": "",
"eth_usd_price": "",
"paid_btc": "",
"btc_usd_price": ""
}
],
"proof_string": "Lethean genesis — the advantage of the nature of information being easy to spread but hard to stifle. - Satoshi Nakamoto"
}

View file

@ -1,7 +0,0 @@
-------------genesis_acc.cpp-------------
const std::string ggenesis_tx_pub_key_str = "503ec7c167e3f2ead7d801bcbcebb3c58a84a2ba26a21ecb1f5c105fa159932b";
const crypto::public_key ggenesis_tx_pub_key = epee::string_tools::parse_tpod_from_hex_string<crypto::public_key>(ggenesis_tx_pub_key_str);
extern const genesis_tx_dictionary_entry ggenesis_dict[1];
const genesis_tx_dictionary_entry ggenesis_dict[1] = {
{12778448838847345770ULL,0}
};

View file

@ -1 +0,0 @@
01010000018080a0cfc8e0c8e38a0103bd6b4dda729d39dc85cb22a0b3db9b4b04d6464be9f3c84640bdca8bc0afb148000516503ec7c167e3f2ead7d801bcbcebb3c58a84a2ba26a21ecb1f5c105fa159932b137a4c65746865616e2067656e6573697320e280942074686520616476616e74616765206f6620746865206e6174757265206f6620696e666f726d6174696f6e206265696e67206561737920746f2073707265616420627574206861726420746f20737469666c652e202d205361746f736869204e616b616d6f746f15000b029e4e0e0a0000

View file

@ -1,14 +0,0 @@
--------- genesis.h---------
#pragma pack(push, 1)
struct genesis_tx_raw_data
{
uint64_t const v[27];
uint8_t const r[1];
};
#pragma pack(pop)
extern const genesis_tx_raw_data ggenesis_tx_raw;
--------- genesis.cpp---------
const genesis_tx_raw_data ggenesis_tx_raw = {{
0xa080800100000101,0x03018ae3c8e0c8cf,0xdc399d72da4d6bbd,0x4b9bdbb3a022cb85,0x46c8f3e94b46d604,0x48b1afc08bcabd40,0x67c1c73e50160500,0xbcbc01d8d7eaf2e3,0x26baa2848ac5b3eb,0xa15f105c1fcb1ea2,0x74654c7a132b9359,0x6e6567206e616568,0x9480e22073697365,0x7664612065687420,0x6f20656761746e61,0x616e206568742066,0x20666f2065727574,0x74616d726f666e69,0x6e696562206e6f69,0x7420797361652067,0x646165727073206f,0x7261682074756220,0x697473206f742064,0x53202d202e656c66,0x4e206968736f7461,0x156f746f6d616b61,0x000a0e4e9e020b00},
{0x00}};

Some files were not shown because too many files have changed in this diff Show more