Compare commits

..

25 Commits

Author SHA1 Message Date
Bogdan-Ștefan Neacşu 5d5c402ff6 Apply 250GB/30 days to magura 2024-11-13 12:06:06 +02:00
Tommy Verrall 4fab7eac3f temporarily disable playground and test my node in the wallet
once we have time to fix these we will import these again
2024-11-13 10:56:19 +01:00
Jon Häggblad ac77712cc0 nym-credential-proxy-requests: reqwest use rustls-tls (#5116)
* nym-credential-proxy-requests: reqwest use rustls-tls

* nym-credential-proxy: reqwest default-features false
2024-11-11 17:38:21 +01:00
Jędrzej Stuczyński a400aa8928 bugfix: preserve as much as possible of the rewarded set during migration (#5103) 2024-11-08 09:33:30 +00:00
Jędrzej Stuczyński c001059af9 Feature/force refresh node (#5101)
* introduced nym-api endpoint for force refreshing described node data

* client code + updated return types

* nym-node to update self-described data cache on startup + change request type

* send request to all available nym-apis

* fixed 'is_stale' check
2024-11-06 09:17:44 +00:00
Jędrzej Stuczyński fd8dc63c88 fixed HistoricalUptimeUpdater (#5097) 2024-11-05 14:40:50 +00:00
Dinko Zdravac d03c5b3650 Graceful agent 1.1.5 (#5093)
* Bump NS agent to 0.1.5

* API improvements
- agent exits gracefully when no testrun available
- API doesn't log every error

* Bump NSAPI to 0.1.6
2024-11-05 15:36:16 +01:00
Bogdan-Ștefan Neacşu 69e97b3bbc Remove old use of 1GB constant (#5096)
* Remove old use of 1GB constant

* Fix clippy
2024-11-05 16:16:59 +02:00
Bogdan-Ștefan Neacşu 15ca24b848 Add more translations from v2 to v3 authenticator (#5091) 2024-11-05 15:30:00 +02:00
Fouad fa551b6d9d Nym node - Fix claim delegator rewards (#5090)
* update function param from mixId to nodeId

* fix claim operator rewards
2024-11-05 13:01:22 +00:00
Bogdan-Ștefan Neacşu c6959d3e2d Make 250 GB/30 days for free ride mode (#5083) 2024-11-05 11:14:43 +02:00
Jędrzej Stuczyński 2569deb080 bugfix: [wallet] displaying delegations for native nymnodes (#5087)
* fixed return type for getting nymnode details

* fixed nym-api queries if using relative paths

* fixed queries for delegations of native nymnodes
2024-11-04 21:15:29 +00:00
Bogdan-Ștefan Neacşu 5cefa7fdd4 Don't increase bandwidth again (#5081) 2024-11-04 13:15:27 +02:00
Mark Sinclair 80b590d50d bug-fix: nym-credential-proxy webhook request is the correct shape and added reporting errors via webhook (#5077)
Co-authored-by: Mark Sinclair <mmsinclair@users.noreply.github.com>
2024-11-01 21:48:04 +01:00
Bogdan-Ștefan Neacşu f9b363648f Fix expiration date as today + 7 days (#5076) 2024-11-01 16:01:24 +02:00
Bogdan-Ștefan Neacşu b73561f1c9 Fix gateway decreasing bandwidth (#5075)
* Update storage peers after periodic check

* Reset storage bytes on restart

* Fix clippy
2024-11-01 15:40:22 +02:00
Dinko Zdravac 09b68a8204 Cherry pick NS API from develop (#5074)
* Revert "NS API with directory v2 (#5068)"

This reverts commit cf4fe5f875.

* Merge pull request #5050 from nymtech/dz-node-status-api

Node Status API

* Ns agent workflow (#5055)

* feat: add dockerfile

* add github workflow for node status agent

---------

Co-authored-by: Fran Arbanas <arbanasfran@gmail.com>

* NS API with directory v2 (#5058)

* Use unstable explorer client

* Clean up stale testruns & logging
- log gw identity key
- better agent testrun logging
- log responses
- change response code for agents

* Better logging on agent

* Testrun stores gw identity key instead of gw pk

* Agent 0.1.3

* Agent 0.1.4

* Sqlx offline query data + clippy

* Compatible with directory v2

* Point to internal deps + rebase + v0.1.5

* self described field not null

* Fix build.rs typo

* Fix clippy

---------

Co-authored-by: Fran Arbanas <arbanasfran@gmail.com>
2024-11-01 01:24:41 +01:00
Fouad 0374626960 Allow custom http port to be reset (#5073)
* allow custom port to be reset in wallet
2024-10-31 16:53:55 +00:00
Dinko Zdravac cf4fe5f875 NS API with directory v2 (#5068)
* Use unstable explorer client

* Clean up stale testruns & logging
- log gw identity key
- better agent testrun logging
- log responses
- change response code for agents

* Better logging on agent

* Testrun stores gw identity key instead of gw pk

* Agent 0.1.3

* Agent 0.1.4

* Sqlx offline query data + clippy

* Compatible with directory v2

* Point to internal deps + rebase + v0.1.5

* self described field not null

* Fix build.rs typo
2024-10-31 13:52:20 +01:00
Jędrzej Stuczyński 9f8bf2d080 bugfix: wallet backend fixes (#5070)
* fixed simulation arguments

* make sure 'try_convert_pubkey_to_node_id' checks for native nymnodes
2024-10-31 12:23:20 +00:00
Jędrzej Stuczyński b9d1fc40e7 deprecated old nym-api client methods and replaced them when possible (#5069) 2024-10-31 12:08:58 +00:00
Jędrzej Stuczyński be67234093 bugfix: credential-proxy obtain-async (#5067)
* removed foreign key constraint on deposit table

* fixed sql nullability

* fixed swagger arguments for '/api/v1/ticketbook/shares/device/{device_id}/credential/{credential_id}' route

* fixed missing swagger component definitions
2024-10-31 10:33:38 +00:00
Fouad 8b0b70a727 allow nym node config updates (#5066) 2024-10-31 09:59:22 +00:00
Fouad c90ebf0a6a Feature/wallet bonding fixes (#5064)
* bonding and unbonding for nym nodes
2024-10-30 17:15:38 +00:00
Jędrzej Stuczyński 07ff2639ec bugfix: use corrext axum extractors for ecash route arguments (#5065) 2024-10-30 16:05:16 +00:00
803 changed files with 22220 additions and 39865 deletions
+28 -15
View File
@@ -6,27 +6,20 @@ on:
jobs:
build:
runs-on: arc-ubuntu-20.04
defaults:
run:
working-directory: documentation/docs
steps:
- uses: actions/checkout@v4
- name: Install Dependencies (Linux)
run: sudo apt-get update && sudo apt-get install -y build-essential curl wget libssl-dev libudev-dev squashfs-tools protobuf-compiler git python3 && sudo apt-get update --fix-missing
- name: Install pip3
run: sudo apt install -y python3-pip
run: sudo apt install -y python3-pip
- name: Install Python3 modules
run: sudo pip3 install pandas tabulate
- name: Install rsync
run: sudo apt-get install rsync
- uses: rlespinasse/github-slug-action@v3.x
- name: Setup pnpm
uses: pnpm/action-setup@v4.0.0
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 20
node-version: 18
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
@@ -36,13 +29,33 @@ jobs:
with:
command: build
args: --workspace --release
- name: Install mdbook and plugins
run: cd documentation && ./install_mdbook_deps.sh
- name: Remove existing Nym config directory (`~/.nym/`)
run: cd documentation && ./remove_existing_config.sh
continue-on-error: false
# This is the original flow
# - name: Build all projects in documentation/ & move to ~/dist/docs/
# run: cd documentation && ./build_all_to_dist.sh
- name: Install project dependencies
run: pnpm i
- name: Build project
run: pnpm run build
- name: Move files to /dist/
run: ../scripts/move-to-dist.sh
# This is a workaround replacement which builds on the last working commit b332a6b55668f60988e36961f3f62a794ba82ddb and then on current branch
- name: Save current branch to ~/current_branch
run: git rev-parse --abbrev-ref HEAD > ~/current_branch
- name: Git pull, reset & switch to b332a6b55668f60988e36961f3f62a794ba82ddb
run: git pull && git reset --hard && git checkout b332a6b55668f60988e36961f3f62a794ba82ddb
- name: Build all projects in documentation/ & move to ~/dist/docs/ from b332a6b55668f60988e36961f3f62a794ba82ddb
run: cd documentation && ./build_all_to_dist.sh
- name: Switch to current branch
run: git checkout $echo "$(cat ~/current_branch)"
- name: Build all projects in documentation/ & move to ~/dist/docs/ on current branch
run: cd documentation && ./build_all_to_dist.sh && rm ~/current_branch
# End of replacemet
- name: Post process
run: cd documentation && ./post_process.sh
continue-on-error: false
- name: Create Vercel project file
uses: mobiledevops/secret-to-file-action@v1
+29 -19
View File
@@ -3,35 +3,28 @@ name: ci-docs
on:
workflow_dispatch:
push:
branches-ignore: [master]
branches-ignore: master
paths:
- "documentation/docs/**"
- ".github/workflows/ci-docs.yml"
- 'documentation/docs/**'
- '.github/workflows/ci-docs.yml'
jobs:
build:
runs-on: arc-ubuntu-20.04
defaults:
run:
working-directory: documentation/docs
steps:
- uses: actions/checkout@v4
- name: Install Dependencies (Linux)
run: sudo apt-get update && sudo apt-get install -y build-essential curl wget libssl-dev libudev-dev squashfs-tools protobuf-compiler git python3 && sudo apt-get update --fix-missing
- name: Install pip3
run: sudo apt install -y python3-pip
run: sudo apt install -y python3-pip
- name: Install Python3 modules
run: sudo pip3 install pandas tabulate
- name: Install rsync
run: sudo apt-get install rsync
- uses: rlespinasse/github-slug-action@v3.x
- name: Setup pnpm
uses: pnpm/action-setup@v4.0.0
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 20
node-version: 18
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
@@ -41,13 +34,30 @@ jobs:
with:
command: build
args: --workspace --release
- name: Install mdbook and plugins
run: cd documentation && ./install_mdbook_deps.sh
- name: Remove existing Nym config directory (`~/.nym/`)
run: cd documentation && ./remove_existing_config.sh
continue-on-error: false
- name: Install project dependencies
run: pnpm i
- name: Build project
run: pnpm run build
- name: Move files to /dist/
run: ../scripts/move-to-dist.sh
# This is the original flow
# - name: Build all projects in documentation/ & move to ~/dist/docs/
# run: cd documentation && ./build_all_to_dist.sh
# This is a workaround replacement which builds on the last working commit b332a6b55668f60988e36961f3f62a794ba82ddb and then on current branch
- name: Save current branch to ~/current_branch
run: git rev-parse --abbrev-ref HEAD > ~/current_branch
- name: Git pull, reset & switch to b332a6b55668f60988e36961f3f62a794ba82ddb
run: git pull && git reset --hard && git checkout b332a6b55668f60988e36961f3f62a794ba82ddb
- name: Build all projects in documentation/ & move to ~/dist/docs/ from b332a6b55668f60988e36961f3f62a794ba82ddb
run: cd documentation && ./build_all_to_dist.sh
- name: Switch to current branch
run: git checkout $echo "$(cat ~/current_branch)"
- name: Build all projects in documentation/ & move to ~/dist/docs/ on current branch
run: cd documentation && ./build_all_to_dist.sh && rm ~/current_branch
# End of replacemet
- name: Deploy branch to CI www
continue-on-error: true
@@ -58,5 +68,5 @@ jobs:
SOURCE: "dist/docs/"
REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }}
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/docs-nextra-${{ env.GITHUB_REF_SLUG }}
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/docs-${{ env.GITHUB_REF_SLUG }}
EXCLUDE: "/node_modules/"
@@ -0,0 +1,45 @@
name: ci-nym-credential-proxy
on:
pull_request:
paths:
- 'common/**'
- 'nym-credential-proxy/**'
- '.github/workspace/ci-nym-credential-proxy.yml'
workflow_dispatch:
jobs:
build:
runs-on: arc-ubuntu-22.04
env:
CARGO_TERM_COLOR: always
MANIFEST_PATH: "--manifest-path nym-credential-proxy/Cargo.toml"
steps:
- name: Check out repository code
uses: actions/checkout@v4
- name: Install rust toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
components: rustfmt, clippy
- name: Check formatting
uses: actions-rs/cargo@v1
with:
command: fmt
args: ${{ env.MANIFEST_PATH }} --all -- --check
- name: Build
uses: actions-rs/cargo@v1
with:
command: build
args: ${{ env.MANIFEST_PATH }} --workspace --all-targets
- name: Clippy
uses: actions-rs/cargo@v1
with:
command: clippy
args: ${{ env.MANIFEST_PATH }} --workspace --all-targets -- -D warnings
@@ -0,0 +1,79 @@
name: ci-sdk-docs-typescript
on:
pull_request:
paths:
- "sdk/typescript/**"
- "wasm/**"
- '.github/workflows/ci-sdk-docs-typescript.yml'
jobs:
build:
runs-on: custom-linux
steps:
- uses: actions/checkout@v4
- name: Install rsync
run: sudo apt-get install rsync
continue-on-error: true
- uses: rlespinasse/github-slug-action@v3.x
- uses: actions/setup-node@v4
with:
node-version: 18.17
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Setup yarn
run: npm install -g yarn
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.20'
- name: Install wasm-pack
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
- name: Install wasm-opt
uses: ./.github/actions/install-wasm-opt
with:
version: '116'
- name: Build branch WASM packages
run: make sdk-wasm-build
- name: Install
run: yarn
- name: Build
run: yarn docs:prod:build
- name: Deploy branch to CI www (docs)
continue-on-error: true
uses: easingthemes/ssh-deploy@main
env:
SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }}
ARGS: "-rltgoDzvO --delete"
SOURCE: "dist/ts/"
REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }}
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/sdk-ts-docs-${{ env.GITHUB_REF_SLUG }}
EXCLUDE: "/dist/, /node_modules/"
- name: Matrix - Node Install
run: npm install
working-directory: .github/workflows/support-files
- name: Matrix - Send Notification
env:
NYM_NOTIFICATION_KIND: ts-packages
NYM_PROJECT_NAME: "sdk-ts-docs"
NYM_CI_WWW_BASE: "${{ secrets.NYM_CI_WWW_BASE }}/docs/sdk/typescript"
NYM_CI_WWW_LOCATION: "sdk-ts-docs-${{ env.GITHUB_REF_SLUG }}"
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
GIT_BRANCH: "${GITHUB_REF##*/}"
IS_SUCCESS: "${{ job.status == 'success' }}"
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}"
MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}"
MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}"
MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}"
uses: docker://keybaseio/client:stable-node
with:
args: .github/workflows/support-files/notifications/entry_point.sh
+1 -3
View File
@@ -4,9 +4,7 @@ on:
pull_request:
branches:
- develop
- "release/**"
paths-ignore:
- "documentation/**"
- 'release/**'
types:
- labeled
- unlabeled
@@ -1,55 +0,0 @@
name: Build and upload Data observatory container to harbor.nymte.ch
on:
workflow_dispatch:
env:
WORKING_DIRECTORY: "nym-data-observatory"
CONTAINER_NAME: "data-observatory"
jobs:
build-container:
runs-on: arc-ubuntu-22.04-dind
steps:
- name: Login to Harbor
uses: docker/login-action@v3
with:
registry: harbor.nymte.ch
username: ${{ secrets.HARBOR_ROBOT_USERNAME }}
password: ${{ secrets.HARBOR_ROBOT_SECRET }}
- name: Checkout repo
uses: actions/checkout@v4
- name: Configure git identity
run: |
git config --global user.email "lawrence@nymtech.net"
git config --global user.name "Lawrence Stalder"
- name: Get version from cargo.toml
uses: mikefarah/yq@v4.44.3
id: get_version
with:
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
- name: Check if tag exists
run: |
if git rev-parse ${{ steps.get_version.outputs.value }} >/dev/null 2>&1; then
echo "Tag ${{ steps.get_version.outputs.value }} already exists"
fi
- name: Remove existing tag if exists
run: |
if git rev-parse ${{ env.WORKING_DIRECTORY }}-${{ steps.get_version.outputs.result }} >/dev/null 2>&1; then
git push --delete origin ${{ env.WORKING_DIRECTORY }}-${{ steps.get_version.outputs.result }}
git tag -d ${{ env.WORKING_DIRECTORY }}-${{ steps.get_version.outputs.result }}
fi
- name: Create tag
run: |
git tag -a ${{ env.WORKING_DIRECTORY }}-${{ steps.get_version.outputs.result }} -m "Version ${{ steps.get_version.outputs.result }}"
git push origin ${{ env.WORKING_DIRECTORY }}-${{ steps.get_version.outputs.result }}
- name: BuildAndPushImageOnHarbor
run: |
docker build -f ${{ env.WORKING_DIRECTORY }}/Dockerfile . -t harbor.nymte.ch/nym/${{ env.CONTAINER_NAME }}:${{ steps.get_version.outputs.result }} -t harbor.nymte.ch/nym/${{ env.CONTAINER_NAME }}:latest
docker push harbor.nymte.ch/nym/${{ env.CONTAINER_NAME }} --all-tags
-55
View File
@@ -1,55 +0,0 @@
name: Build and upload nym node container to harbor.nymte.ch
on:
workflow_dispatch:
env:
WORKING_DIRECTORY: "nym-node"
CONTAINER_NAME: "nym-node"
jobs:
build-container:
runs-on: arc-ubuntu-22.04-dind
steps:
- name: Login to Harbor
uses: docker/login-action@v3
with:
registry: harbor.nymte.ch
username: ${{ secrets.HARBOR_ROBOT_USERNAME }}
password: ${{ secrets.HARBOR_ROBOT_SECRET }}
- name: Checkout repo
uses: actions/checkout@v4
- name: Configure git identity
run: |
git config --global user.email "lawrence@nymtech.net"
git config --global user.name "Lawrence Stalder"
- name: Get version from cargo.toml
uses: mikefarah/yq@v4.44.3
id: get_version
with:
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
- name: Check if tag exists
run: |
if git rev-parse ${{ steps.get_version.outputs.value }} >/dev/null 2>&1; then
echo "Tag ${{ steps.get_version.outputs.value }} already exists"
fi
- name: Remove existing tag if exists
run: |
if git rev-parse ${{ env.WORKING_DIRECTORY }}-${{ steps.get_version.outputs.result }} >/dev/null 2>&1; then
git push --delete origin ${{ env.WORKING_DIRECTORY }}-${{ steps.get_version.outputs.result }}
git tag -d ${{ env.WORKING_DIRECTORY }}-${{ steps.get_version.outputs.result }}
fi
- name: Create tag
run: |
git tag -a ${{ env.WORKING_DIRECTORY }}-${{ steps.get_version.outputs.result }} -m "Version ${{ steps.get_version.outputs.result }}"
git push origin ${{ env.WORKING_DIRECTORY }}-${{ steps.get_version.outputs.result }}
- name: BuildAndPushImageOnHarbor
run: |
docker build -f ${{ env.WORKING_DIRECTORY }}/Dockerfile . -t harbor.nymte.ch/nym/${{ env.CONTAINER_NAME }}:${{ steps.get_version.outputs.result }} -t harbor.nymte.ch/nym/${{ env.CONTAINER_NAME }}:latest
docker push harbor.nymte.ch/nym/${{ env.CONTAINER_NAME }} --all-tags
Generated
+135 -258
View File
File diff suppressed because it is too large Load Diff
+30 -32
View File
@@ -19,33 +19,33 @@ members = [
"clients/native",
"clients/native/websocket-requests",
"clients/socks5",
"common/async-file-watcher",
"common/authenticator-requests",
"common/async-file-watcher",
"common/bandwidth-controller",
"common/bin-common",
"common/client-core",
"common/client-core/config-types",
"common/client-core/gateways-storage",
"common/client-core/surb-storage",
"common/client-core/gateways-storage",
"common/client-libs/gateway-client",
"common/client-libs/mixnet-client",
"common/client-libs/validator-client",
"common/commands",
"common/config",
"common/cosmwasm-smart-contracts/coconut-bandwidth-contract",
"common/cosmwasm-smart-contracts/ecash-contract",
"common/cosmwasm-smart-contracts/coconut-dkg",
"common/cosmwasm-smart-contracts/contracts-common",
"common/cosmwasm-smart-contracts/ecash-contract",
"common/cosmwasm-smart-contracts/group-contract",
"common/cosmwasm-smart-contracts/mixnet-contract",
"common/cosmwasm-smart-contracts/multisig-contract",
"common/cosmwasm-smart-contracts/vesting-contract",
"common/country-group",
"common/credential-storage",
"common/credential-utils",
"common/credential-verification",
"common/credentials",
"common/credential-utils",
"common/credentials-interface",
"common/credential-verification",
"common/crypto",
"common/dkg",
"common/ecash-double-spending",
@@ -54,7 +54,6 @@ members = [
"common/exit-policy",
"common/gateway-requests",
"common/gateway-storage",
"common/gateway-stats-storage",
"common/http-api-client",
"common/http-api-common",
"common/inclusion-probability",
@@ -65,10 +64,10 @@ members = [
"common/network-defaults",
"common/node-tester-utils",
"common/nonexhaustive-delayqueue",
"common/nymcoconut",
"common/nym_offline_compact_ecash",
"common/nym-id",
"common/nym-metrics",
"common/nym_offline_compact_ecash",
"common/nymcoconut",
"common/nymsphinx",
"common/nymsphinx/acknowledgements",
"common/nymsphinx/addressing",
@@ -98,30 +97,26 @@ members = [
"common/wasm/utils",
"common/wireguard",
"common/wireguard-types",
# "documentation/autodoc",
"explorer-api",
"explorer-api/explorer-api-requests",
"explorer-api/explorer-client",
"gateway",
"integrations/bity",
"mixnode",
"sdk/ffi/cpp",
"sdk/ffi/go",
"sdk/ffi/shared",
"sdk/lib/socks5-listener",
"sdk/rust/nym-sdk",
"sdk/ffi/shared",
"sdk/ffi/go",
"sdk/ffi/cpp",
"service-providers/authenticator",
"service-providers/common",
"service-providers/ip-packet-router",
"service-providers/network-requester",
"nym-api",
"nym-api/nym-api-requests",
"nym-browser-extension/storage",
"nym-credential-proxy/nym-credential-proxy",
"nym-credential-proxy/nym-credential-proxy-requests",
"nym-credential-proxy/vpn-api-lib-wasm",
"nym-data-observatory",
"nym-network-monitor",
"nym-api",
"nym-browser-extension/storage",
"nym-api/nym-api-requests",
"nym-data-observatory",
"nym-node",
"nym-node/nym-node-http-api",
"nym-node/nym-node-requests",
@@ -144,11 +139,11 @@ members = [
"wasm/mix-fetch",
"wasm/node-tester",
"wasm/zknym-lib",
"tools/internal/testnet-manager",
"tools/internal/testnet-manager/dkg-bypass-contract",
"tools/echo-server",
"tools/internal/contract-state-importer/importer-cli",
"tools/internal/contract-state-importer/importer-contract",
"tools/internal/testnet-manager",
"tools/internal/testnet-manager/dkg-bypass-contract",
]
default-members = [
@@ -159,7 +154,6 @@ default-members = [
"gateway",
"mixnode",
"nym-api",
"nym-credential-proxy/nym-credential-proxy",
"nym-data-observatory",
"nym-node",
"nym-node-status-api",
@@ -195,7 +189,7 @@ aes = "0.8.1"
aes-gcm = "0.10.1"
aes-gcm-siv = "0.11.1"
aead = "0.5.2"
anyhow = "1.0.90"
anyhow = "1.0.89"
argon2 = "0.5.0"
async-trait = "0.1.83"
axum-client-ip = "0.6.1"
@@ -204,8 +198,11 @@ axum-extra = "0.9.4"
base64 = "0.22.1"
bincode = "1.3.3"
bip39 = { version = "2.0.0", features = ["zeroize"] }
bit-vec = "0.7.0" # can we unify those?
# can we unify those?
bit-vec = "0.7.0"
bitvec = "1.0.0"
blake3 = "1.5.4"
bloomfilter = "1.0.14"
bs58 = "0.5.1"
@@ -218,7 +215,7 @@ chacha20 = "0.9.0"
chacha20poly1305 = "0.10.1"
chrono = "0.4.31"
cipher = "0.4.3"
clap = "4.5.20"
clap = "4.5.18"
clap_complete = "4.5"
clap_complete_fig = "4.5"
colored = "2.0"
@@ -272,7 +269,7 @@ ipnetwork = "0.20"
isocountry = "0.3.2"
itertools = "0.13.0"
k256 = "0.13"
lazy_static = "1.5.0"
lazy_static = "1.4.0"
ledger-transport = "0.10.0"
ledger-transport-hid = "0.10.0"
log = "0.4"
@@ -282,13 +279,13 @@ moka = { version = "0.12", features = ["future"] }
nix = "0.27.1"
notify = "5.1.0"
okapi = "0.7.0"
once_cell = "1.20.2"
once_cell = "1.7.2"
opentelemetry = "0.19.0"
opentelemetry-jaeger = "0.18.0"
parking_lot = "0.12.3"
pem = "0.8"
petgraph = "0.6.5"
pin-project = "1.1"
pin-project = "1.0"
pin-project-lite = "0.2.14"
pretty_env_logger = "0.4.0"
publicsuffix = "2.2.3"
@@ -308,7 +305,7 @@ rocket_okapi = "0.8.0"
safer-ffi = "0.1.13"
schemars = "0.8.21"
semver = "1.0.23"
serde = "1.0.211"
serde = "1.0.210"
serde_bytes = "0.11.15"
serde_derive = "1.0"
serde_json = "1.0.132"
@@ -405,10 +402,11 @@ indexed_db_futures = { git = "https://github.com/TiemenSch/rust-indexed-db", bra
js-sys = "0.3.70"
serde-wasm-bindgen = "0.6.5"
tsify = "0.4.5"
wasm-bindgen = "0.2.95"
wasm-bindgen-futures = "0.4.45"
wasm-bindgen = "0.2.93"
wasm-bindgen-futures = "0.4.43"
wasmtimer = "0.2.0"
web-sys = "0.3.72"
web-sys = "0.3.70"
# Profile settings for individual crates
@@ -27,7 +27,7 @@ pub type HmacSha256 = Hmac<Sha256>;
pub type Nonce = u64;
pub type Taken = Option<SystemTime>;
pub const BANDWIDTH_CAP_PER_DAY: u64 = 1024 * 1024 * 1024; // 1 GB
pub const BANDWIDTH_CAP_PER_DAY: u64 = 250 * 1024 * 1024 * 1024; // 250 GB
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct InitMessage {
@@ -98,6 +98,16 @@ impl TryFrom<v3::response::AuthenticatorResponse> for v2::response::Authenticato
}
}
impl From<v2::response::AuthenticatorResponse> for v3::response::AuthenticatorResponse {
fn from(value: v2::response::AuthenticatorResponse) -> Self {
Self {
protocol: value.protocol,
data: value.data.into(),
reply_to: value.reply_to,
}
}
}
impl TryFrom<v3::response::AuthenticatorResponseData> for v2::response::AuthenticatorResponseData {
type Error = crate::Error;
@@ -129,6 +139,22 @@ impl TryFrom<v3::response::AuthenticatorResponseData> for v2::response::Authenti
}
}
impl From<v2::response::AuthenticatorResponseData> for v3::response::AuthenticatorResponseData {
fn from(value: v2::response::AuthenticatorResponseData) -> Self {
match value {
v2::response::AuthenticatorResponseData::PendingRegistration(
pending_registration_response,
) => Self::PendingRegistration(pending_registration_response.into()),
v2::response::AuthenticatorResponseData::Registered(registered_response) => {
Self::Registered(registered_response.into())
}
v2::response::AuthenticatorResponseData::RemainingBandwidth(
remaining_bandwidth_response,
) => Self::RemainingBandwidth(remaining_bandwidth_response.into()),
}
}
}
impl From<v3::response::PendingRegistrationResponse> for v2::response::PendingRegistrationResponse {
fn from(value: v3::response::PendingRegistrationResponse) -> Self {
Self {
@@ -139,6 +165,16 @@ impl From<v3::response::PendingRegistrationResponse> for v2::response::PendingRe
}
}
impl From<v2::response::PendingRegistrationResponse> for v3::response::PendingRegistrationResponse {
fn from(value: v2::response::PendingRegistrationResponse) -> Self {
Self {
request_id: value.request_id,
reply_to: value.reply_to,
reply: value.reply.into(),
}
}
}
impl From<v3::response::RegisteredResponse> for v2::response::RegisteredResponse {
fn from(value: v3::response::RegisteredResponse) -> Self {
Self {
@@ -149,6 +185,16 @@ impl From<v3::response::RegisteredResponse> for v2::response::RegisteredResponse
}
}
impl From<v2::response::RegisteredResponse> for v3::response::RegisteredResponse {
fn from(value: v2::response::RegisteredResponse) -> Self {
Self {
request_id: value.request_id,
reply_to: value.reply_to,
reply: value.reply.into(),
}
}
}
impl From<v3::response::RemainingBandwidthResponse> for v2::response::RemainingBandwidthResponse {
fn from(value: v3::response::RemainingBandwidthResponse) -> Self {
Self {
@@ -159,6 +205,16 @@ impl From<v3::response::RemainingBandwidthResponse> for v2::response::RemainingB
}
}
impl From<v2::response::RemainingBandwidthResponse> for v3::response::RemainingBandwidthResponse {
fn from(value: v2::response::RemainingBandwidthResponse) -> Self {
Self {
request_id: value.request_id,
reply_to: value.reply_to,
reply: value.reply.map(Into::into),
}
}
}
impl From<v3::registration::RegistrationData> for v2::registration::RegistrationData {
fn from(value: v3::registration::RegistrationData) -> Self {
Self {
@@ -169,6 +225,16 @@ impl From<v3::registration::RegistrationData> for v2::registration::Registration
}
}
impl From<v2::registration::RegistrationData> for v3::registration::RegistrationData {
fn from(value: v2::registration::RegistrationData) -> Self {
Self {
nonce: value.nonce,
gateway_data: value.gateway_data.into(),
wg_port: value.wg_port,
}
}
}
impl From<v3::registration::RegistredData> for v2::registration::RegistredData {
fn from(value: v3::registration::RegistredData) -> Self {
Self {
@@ -179,6 +245,16 @@ impl From<v3::registration::RegistredData> for v2::registration::RegistredData {
}
}
impl From<v2::registration::RegistredData> for v3::registration::RegistredData {
fn from(value: v2::registration::RegistredData) -> Self {
Self {
pub_key: value.pub_key,
private_ip: value.private_ip,
wg_port: value.wg_port,
}
}
}
impl From<v3::registration::RemainingBandwidthData> for v2::registration::RemainingBandwidthData {
fn from(value: v3::registration::RemainingBandwidthData) -> Self {
Self {
@@ -186,3 +262,11 @@ impl From<v3::registration::RemainingBandwidthData> for v2::registration::Remain
}
}
}
impl From<v2::registration::RemainingBandwidthData> for v3::registration::RemainingBandwidthData {
fn from(value: v2::registration::RemainingBandwidthData) -> Self {
Self {
available_bandwidth: value.available_bandwidth,
}
}
}
@@ -27,7 +27,7 @@ pub type HmacSha256 = Hmac<Sha256>;
pub type Nonce = u64;
pub type Taken = Option<SystemTime>;
pub const BANDWIDTH_CAP_PER_DAY: u64 = 1024 * 1024 * 1024; // 1 GB
pub const BANDWIDTH_CAP_PER_DAY: u64 = 250 * 1024 * 1024 * 1024; // 250 GB
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct InitMessage {
@@ -18,19 +18,19 @@ use nym_api_requests::ecash::{
PartialExpirationDateSignatureResponse, VerificationKeyResponse,
};
use nym_api_requests::models::{
GatewayCoreStatusResponse, MixnodeCoreStatusResponse, MixnodeStatusResponse,
ApiHealthResponse, GatewayCoreStatusResponse, MixnodeCoreStatusResponse, MixnodeStatusResponse,
NymNodeDescription, RewardEstimationResponse, StakeSaturationResponse,
};
use nym_api_requests::models::{LegacyDescribedGateway, MixNodeBondAnnotated};
use nym_api_requests::nym_nodes::SkimmedNode;
use nym_coconut_dkg_common::types::EpochId;
use nym_http_api_client::UserAgent;
use nym_mixnet_contract_common::NymNodeDetails;
use nym_network_defaults::NymNetworkDetails;
use time::Date;
use url::Url;
pub use crate::nym_api::NymApiClientExt;
use nym_mixnet_contract_common::NymNodeDetails;
pub use nym_mixnet_contract_common::{
mixnode::MixNodeDetails, GatewayBond, IdentityKey, IdentityKeyRef, NodeId,
};
@@ -192,6 +192,8 @@ impl<C, S> Client<C, S> {
}
// validator-api wrappers
// we have to allow the use of deprecated method here as they're calling the deprecated trait methods
#[allow(deprecated)]
impl<C, S> Client<C, S> {
pub fn api_url(&self) -> &Url {
self.nym_api.current_url()
@@ -201,46 +203,54 @@ impl<C, S> Client<C, S> {
self.nym_api.change_base_url(new_endpoint)
}
#[deprecated]
pub async fn get_cached_mixnodes(&self) -> Result<Vec<MixNodeDetails>, ValidatorClientError> {
Ok(self.nym_api.get_mixnodes().await?)
}
#[deprecated]
pub async fn get_cached_mixnodes_detailed(
&self,
) -> Result<Vec<MixNodeBondAnnotated>, ValidatorClientError> {
Ok(self.nym_api.get_mixnodes_detailed().await?)
}
#[deprecated]
pub async fn get_cached_mixnodes_detailed_unfiltered(
&self,
) -> Result<Vec<MixNodeBondAnnotated>, ValidatorClientError> {
Ok(self.nym_api.get_mixnodes_detailed_unfiltered().await?)
}
#[deprecated]
pub async fn get_cached_rewarded_mixnodes(
&self,
) -> Result<Vec<MixNodeDetails>, ValidatorClientError> {
Ok(self.nym_api.get_rewarded_mixnodes().await?)
}
#[deprecated]
pub async fn get_cached_rewarded_mixnodes_detailed(
&self,
) -> Result<Vec<MixNodeBondAnnotated>, ValidatorClientError> {
Ok(self.nym_api.get_rewarded_mixnodes_detailed().await?)
}
#[deprecated]
pub async fn get_cached_active_mixnodes(
&self,
) -> Result<Vec<MixNodeDetails>, ValidatorClientError> {
Ok(self.nym_api.get_active_mixnodes().await?)
}
#[deprecated]
pub async fn get_cached_active_mixnodes_detailed(
&self,
) -> Result<Vec<MixNodeBondAnnotated>, ValidatorClientError> {
Ok(self.nym_api.get_active_mixnodes_detailed().await?)
}
#[deprecated]
pub async fn get_cached_gateways(&self) -> Result<Vec<GatewayBond>, ValidatorClientError> {
Ok(self.nym_api.get_gateways().await?)
}
@@ -304,6 +314,8 @@ pub struct NymApiClient {
// we could re-implement the communication with the REST API on port 1317
}
// we have to allow the use of deprecated method here as they're calling the deprecated trait methods
#[allow(deprecated)]
impl NymApiClient {
pub fn new(api_url: Url) -> Self {
let nym_api = nym_api::Client::new(api_url, None);
@@ -318,10 +330,10 @@ impl NymApiClient {
NymApiClient { nym_api }
}
pub fn new_with_user_agent(api_url: Url, user_agent: UserAgent) -> Self {
pub fn new_with_user_agent(api_url: Url, user_agent: impl Into<UserAgent>) -> Self {
let nym_api = nym_api::Client::builder::<_, ValidatorClientError>(api_url)
.expect("invalid api url")
.with_user_agent(user_agent)
.with_user_agent(user_agent.into())
.build::<ValidatorClientError>()
.expect("failed to build nym api client");
@@ -424,6 +436,38 @@ impl NymApiClient {
Ok(nodes)
}
/// retrieve basic information for nodes are capable of operating as a mixnode
/// this includes legacy mixnodes and nym-nodes
pub async fn get_all_basic_mixing_capable_nodes(
&self,
semver_compatibility: Option<String>,
) -> Result<Vec<SkimmedNode>, ValidatorClientError> {
// TODO: deal with paging in macro or some helper function or something, because it's the same pattern everywhere
let mut page = 0;
let mut nodes = Vec::new();
loop {
let mut res = self
.nym_api
.get_basic_mixing_capable_nodes(
semver_compatibility.clone(),
false,
Some(page),
None,
)
.await?;
nodes.append(&mut res.nodes.data);
if nodes.len() < res.nodes.pagination.total {
page += 1
} else {
break;
}
}
Ok(nodes)
}
/// retrieve basic information for all bonded nodes on the network
pub async fn get_all_basic_nodes(
&self,
@@ -450,26 +494,35 @@ impl NymApiClient {
Ok(nodes)
}
pub async fn health(&self) -> Result<ApiHealthResponse, ValidatorClientError> {
Ok(self.nym_api.health().await?)
}
#[deprecated]
pub async fn get_cached_active_mixnodes(
&self,
) -> Result<Vec<MixNodeDetails>, ValidatorClientError> {
Ok(self.nym_api.get_active_mixnodes().await?)
}
#[deprecated]
pub async fn get_cached_rewarded_mixnodes(
&self,
) -> Result<Vec<MixNodeDetails>, ValidatorClientError> {
Ok(self.nym_api.get_rewarded_mixnodes().await?)
}
#[deprecated]
pub async fn get_cached_mixnodes(&self) -> Result<Vec<MixNodeDetails>, ValidatorClientError> {
Ok(self.nym_api.get_mixnodes().await?)
}
#[deprecated]
pub async fn get_cached_gateways(&self) -> Result<Vec<GatewayBond>, ValidatorClientError> {
Ok(self.nym_api.get_gateways().await?)
}
#[deprecated]
pub async fn get_cached_described_gateways(
&self,
) -> Result<Vec<LegacyDescribedGateway>, ValidatorClientError> {
@@ -518,6 +571,7 @@ impl NymApiClient {
Ok(bonds)
}
#[deprecated]
pub async fn get_gateway_core_status_count(
&self,
identity: IdentityKeyRef<'_>,
@@ -529,6 +583,7 @@ impl NymApiClient {
.await?)
}
#[deprecated]
pub async fn get_mixnode_core_status_count(
&self,
mix_id: NodeId,
@@ -540,6 +595,7 @@ impl NymApiClient {
.await?)
}
#[deprecated]
pub async fn get_mixnode_status(
&self,
mix_id: NodeId,
@@ -547,6 +603,7 @@ impl NymApiClient {
Ok(self.nym_api.get_mixnode_status(mix_id).await?)
}
#[deprecated]
pub async fn get_mixnode_reward_estimation(
&self,
mix_id: NodeId,
@@ -554,6 +611,7 @@ impl NymApiClient {
Ok(self.nym_api.get_mixnode_reward_estimation(mix_id).await?)
}
#[deprecated]
pub async fn get_mixnode_stake_saturation(
&self,
mix_id: NodeId,
@@ -585,6 +643,7 @@ impl NymApiClient {
.await?)
}
#[deprecated]
pub async fn spent_credentials_filter(
&self,
) -> Result<SpentCredentialsResponse, ValidatorClientError> {
@@ -164,7 +164,7 @@ async fn test_nym_api_connection(
) -> ConnectionResult {
let result = match timeout(
Duration::from_secs(CONNECTION_TEST_TIMEOUT_SEC),
client.get_cached_mixnodes(),
client.health(),
)
.await
{
@@ -11,7 +11,8 @@ use nym_api_requests::ecash::models::{
};
use nym_api_requests::ecash::VerificationKeyResponse;
use nym_api_requests::models::{
AnnotationResponse, LegacyDescribedMixNode, NodePerformanceResponse, NymNodeDescription,
AnnotationResponse, ApiHealthResponse, LegacyDescribedMixNode, NodePerformanceResponse,
NodeRefreshBody, NymNodeDescription,
};
use nym_api_requests::nym_nodes::PaginatedCachedNodesResponse;
use nym_api_requests::pagination::PaginatedResponse;
@@ -54,12 +55,26 @@ pub fn rfc_3339_date() -> Vec<BorrowedFormatItem<'static>> {
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
pub trait NymApiClientExt: ApiClient {
async fn health(&self) -> Result<ApiHealthResponse, NymAPIError> {
self.get_json(
&[
routes::API_VERSION,
routes::API_STATUS_ROUTES,
routes::HEALTH,
],
NO_PARAMS,
)
.await
}
#[deprecated]
#[instrument(level = "debug", skip(self))]
async fn get_mixnodes(&self) -> Result<Vec<MixNodeDetails>, NymAPIError> {
self.get_json(&[routes::API_VERSION, routes::MIXNODES], NO_PARAMS)
.await
}
#[deprecated]
#[instrument(level = "debug", skip(self))]
async fn get_mixnodes_detailed(&self) -> Result<Vec<MixNodeBondAnnotated>, NymAPIError> {
self.get_json(
@@ -74,6 +89,7 @@ pub trait NymApiClientExt: ApiClient {
.await
}
#[deprecated]
#[instrument(level = "debug", skip(self))]
async fn get_gateways_detailed(&self) -> Result<Vec<GatewayBondAnnotated>, NymAPIError> {
self.get_json(
@@ -88,6 +104,7 @@ pub trait NymApiClientExt: ApiClient {
.await
}
#[deprecated]
#[instrument(level = "debug", skip(self))]
async fn get_mixnodes_detailed_unfiltered(
&self,
@@ -104,12 +121,14 @@ pub trait NymApiClientExt: ApiClient {
.await
}
#[deprecated]
#[instrument(level = "debug", skip(self))]
async fn get_gateways(&self) -> Result<Vec<GatewayBond>, NymAPIError> {
self.get_json(&[routes::API_VERSION, routes::GATEWAYS], NO_PARAMS)
.await
}
#[deprecated]
#[instrument(level = "debug", skip(self))]
async fn get_gateways_described(&self) -> Result<Vec<LegacyDescribedGateway>, NymAPIError> {
self.get_json(
@@ -119,6 +138,7 @@ pub trait NymApiClientExt: ApiClient {
.await
}
#[deprecated]
#[instrument(level = "debug", skip(self))]
async fn get_mixnodes_described(&self) -> Result<Vec<LegacyDescribedMixNode>, NymAPIError> {
self.get_json(
@@ -128,6 +148,7 @@ pub trait NymApiClientExt: ApiClient {
.await
}
#[tracing::instrument(level = "debug", skip_all)]
async fn get_nodes_described(
&self,
page: Option<u32>,
@@ -147,6 +168,7 @@ pub trait NymApiClientExt: ApiClient {
.await
}
#[tracing::instrument(level = "debug", skip_all)]
async fn get_nym_nodes(
&self,
page: Option<u32>,
@@ -166,6 +188,7 @@ pub trait NymApiClientExt: ApiClient {
.await
}
#[deprecated]
#[tracing::instrument(level = "debug", skip_all)]
async fn get_basic_mixnodes(
&self,
@@ -190,6 +213,7 @@ pub trait NymApiClientExt: ApiClient {
.await
}
#[deprecated]
#[instrument(level = "debug", skip(self))]
async fn get_basic_gateways(
&self,
@@ -298,6 +322,49 @@ pub trait NymApiClientExt: ApiClient {
.await
}
/// retrieve basic information for nodes that got assigned 'mixing' node in this epoch
/// this includes legacy mixnodes and nym-nodes
#[instrument(level = "debug", skip(self))]
async fn get_basic_mixing_capable_nodes(
&self,
semver_compatibility: Option<String>,
no_legacy: bool,
page: Option<u32>,
per_page: Option<u32>,
) -> Result<PaginatedCachedNodesResponse<SkimmedNode>, NymAPIError> {
let mut params = Vec::new();
if let Some(arg) = &semver_compatibility {
params.push(("semver_compatibility", arg.clone()))
}
if no_legacy {
params.push(("no_legacy", "true".to_string()))
}
if let Some(page) = page {
params.push(("page", page.to_string()))
}
if let Some(per_page) = per_page {
params.push(("per_page", per_page.to_string()))
}
self.get_json(
&[
routes::API_VERSION,
"unstable",
"nym-nodes",
"skimmed",
"mixnodes",
"all",
],
&params,
)
.await
}
#[instrument(level = "debug", skip(self))]
async fn get_basic_nodes(
&self,
semver_compatibility: Option<String>,
@@ -330,6 +397,7 @@ pub trait NymApiClientExt: ApiClient {
.await
}
#[deprecated]
#[instrument(level = "debug", skip(self))]
async fn get_active_mixnodes(&self) -> Result<Vec<MixNodeDetails>, NymAPIError> {
self.get_json(
@@ -339,6 +407,7 @@ pub trait NymApiClientExt: ApiClient {
.await
}
#[deprecated]
#[instrument(level = "debug", skip(self))]
async fn get_active_mixnodes_detailed(&self) -> Result<Vec<MixNodeBondAnnotated>, NymAPIError> {
self.get_json(
@@ -354,6 +423,7 @@ pub trait NymApiClientExt: ApiClient {
.await
}
#[deprecated]
#[instrument(level = "debug", skip(self))]
async fn get_rewarded_mixnodes(&self) -> Result<Vec<MixNodeDetails>, NymAPIError> {
self.get_json(
@@ -363,6 +433,7 @@ pub trait NymApiClientExt: ApiClient {
.await
}
#[deprecated]
#[instrument(level = "debug", skip(self))]
async fn get_mixnode_report(
&self,
@@ -381,6 +452,7 @@ pub trait NymApiClientExt: ApiClient {
.await
}
#[deprecated]
#[instrument(level = "debug", skip(self))]
async fn get_gateway_report(
&self,
@@ -399,6 +471,7 @@ pub trait NymApiClientExt: ApiClient {
.await
}
#[deprecated]
#[instrument(level = "debug", skip(self))]
async fn get_mixnode_history(
&self,
@@ -417,6 +490,7 @@ pub trait NymApiClientExt: ApiClient {
.await
}
#[deprecated]
#[instrument(level = "debug", skip(self))]
async fn get_gateway_history(
&self,
@@ -435,6 +509,7 @@ pub trait NymApiClientExt: ApiClient {
.await
}
#[deprecated]
#[instrument(level = "debug", skip(self))]
async fn get_rewarded_mixnodes_detailed(
&self,
@@ -452,6 +527,7 @@ pub trait NymApiClientExt: ApiClient {
.await
}
#[deprecated]
#[instrument(level = "debug", skip(self))]
async fn get_gateway_core_status_count(
&self,
@@ -484,6 +560,7 @@ pub trait NymApiClientExt: ApiClient {
}
}
#[deprecated]
#[instrument(level = "debug", skip(self))]
async fn get_mixnode_core_status_count(
&self,
@@ -517,6 +594,7 @@ pub trait NymApiClientExt: ApiClient {
}
}
#[deprecated]
#[instrument(level = "debug", skip(self))]
async fn get_mixnode_status(
&self,
@@ -535,6 +613,7 @@ pub trait NymApiClientExt: ApiClient {
.await
}
#[deprecated]
#[instrument(level = "debug", skip(self))]
async fn get_mixnode_reward_estimation(
&self,
@@ -553,6 +632,7 @@ pub trait NymApiClientExt: ApiClient {
.await
}
#[deprecated]
#[instrument(level = "debug", skip(self))]
async fn compute_mixnode_reward_estimation(
&self,
@@ -573,6 +653,7 @@ pub trait NymApiClientExt: ApiClient {
.await
}
#[deprecated]
#[instrument(level = "debug", skip(self))]
async fn get_mixnode_stake_saturation(
&self,
@@ -591,6 +672,7 @@ pub trait NymApiClientExt: ApiClient {
.await
}
#[deprecated]
#[instrument(level = "debug", skip(self))]
async fn get_mixnode_inclusion_probability(
&self,
@@ -614,18 +696,35 @@ pub trait NymApiClientExt: ApiClient {
&self,
node_id: NodeId,
) -> Result<NodePerformanceResponse, NymAPIError> {
self.get_json_from(format!("/v1/nym-nodes/performance/{node_id}"))
.await
self.get_json(
&[
routes::API_VERSION,
"nym-nodes",
"performance",
&node_id.to_string(),
],
NO_PARAMS,
)
.await
}
async fn get_node_annotation(
&self,
node_id: NodeId,
) -> Result<AnnotationResponse, NymAPIError> {
self.get_json_from(format!("/v1/nym-nodes/annotation/{node_id}"))
.await
self.get_json(
&[
routes::API_VERSION,
"nym-nodes",
"annotation",
&node_id.to_string(),
],
NO_PARAMS,
)
.await
}
#[deprecated]
async fn get_mixnode_avg_uptime(&self, mix_id: NodeId) -> Result<UptimeResponse, NymAPIError> {
self.get_json(
&[
@@ -640,6 +739,7 @@ pub trait NymApiClientExt: ApiClient {
.await
}
#[deprecated]
#[instrument(level = "debug", skip(self))]
async fn get_mixnodes_blacklisted(&self) -> Result<Vec<NodeId>, NymAPIError> {
self.get_json(
@@ -649,6 +749,7 @@ pub trait NymApiClientExt: ApiClient {
.await
}
#[deprecated]
#[instrument(level = "debug", skip(self))]
async fn get_gateways_blacklisted(&self) -> Result<Vec<IdentityKey>, NymAPIError> {
self.get_json(
@@ -709,6 +810,7 @@ pub trait NymApiClientExt: ApiClient {
.await
}
#[deprecated]
#[instrument(level = "debug", skip(self))]
async fn double_spending_filter_v1(&self) -> Result<SpentCredentialsResponse, NymAPIError> {
self.get_json(
@@ -832,6 +934,18 @@ pub trait NymApiClientExt: ApiClient {
.await
}
async fn force_refresh_describe_cache(
&self,
request: &NodeRefreshBody,
) -> Result<(), NymAPIError> {
self.post_json(
&[routes::API_VERSION, "nym-nodes", "refresh-described"],
NO_PARAMS,
request,
)
.await
}
#[instrument(level = "debug", skip(self))]
async fn epoch_credentials(
&self,
@@ -36,6 +36,8 @@ pub mod ecash {
}
pub const STATUS_ROUTES: &str = "status";
pub const API_STATUS_ROUTES: &str = "api-status";
pub const HEALTH: &str = "health";
pub const MIXNODE: &str = "mixnode";
pub const GATEWAY: &str = "gateway";
pub const NYM_NODES: &str = "nym-nodes";
@@ -10,10 +10,10 @@ use cosmrs::AccountId;
use nym_contracts_common::signing::Nonce;
use nym_mixnet_contract_common::gateway::{PreassignedGatewayIdsResponse, PreassignedId};
use nym_mixnet_contract_common::nym_node::{
EpochAssignmentResponse, NodeDetailsByIdentityResponse, NodeOwnershipResponse,
NodeRewardingDetailsResponse, PagedNymNodeBondsResponse, PagedNymNodeDetailsResponse,
PagedUnbondedNymNodesResponse, Role, RolesMetadataResponse, StakeSaturationResponse,
UnbondedNodeResponse, UnbondedNymNode,
EpochAssignmentResponse, NodeDetailsByIdentityResponse, NodeDetailsResponse,
NodeOwnershipResponse, NodeRewardingDetailsResponse, PagedNymNodeBondsResponse,
PagedNymNodeDetailsResponse, PagedUnbondedNymNodesResponse, Role, RolesMetadataResponse,
StakeSaturationResponse, UnbondedNodeResponse, UnbondedNymNode,
};
use nym_mixnet_contract_common::reward_params::WorkFactor;
use nym_mixnet_contract_common::{
@@ -316,10 +316,7 @@ pub trait MixnetQueryClient {
.await
}
async fn get_nymnode_details(
&self,
node_id: NodeId,
) -> Result<NodeOwnershipResponse, NyxdError> {
async fn get_nymnode_details(&self, node_id: NodeId) -> Result<NodeDetailsResponse, NyxdError> {
self.query_mixnet_contract(MixnetQueryMsg::GetNymNodeDetails { node_id })
.await
}
@@ -2,10 +2,9 @@
// SPDX-License-Identifier: Apache-2.0
use crate::context::QueryClientWithNyxd;
use crate::utils::{pretty_cosmwasm_coin, show_error};
use crate::utils::show_error;
use clap::Parser;
use comfy_table::Table;
use nym_validator_client::client::NymApiClientExt;
#[derive(Debug, Parser)]
pub struct Args {
@@ -15,12 +14,11 @@ pub struct Args {
}
pub async fn query(args: Args, client: &QueryClientWithNyxd) {
match client.nym_api.get_gateways().await {
match client.get_all_cached_described_nodes().await {
Ok(res) => match args.identity_key {
Some(identity_key) => {
let node = res.iter().find(|node| {
node.gateway
.identity_key
node.ed25519_identity_key()
.to_string()
.eq_ignore_ascii_case(&identity_key)
});
@@ -32,14 +30,16 @@ pub async fn query(args: Args, client: &QueryClientWithNyxd) {
None => {
let mut table = Table::new();
table.set_header(vec!["Identity Key", "Owner", "Host", "Bond", "Version"]);
for node in res {
table.set_header(vec!["Node Id", "Identity Key", "Version", "Is Legacy"]);
for node in res
.into_iter()
.filter(|node| node.description.declared_role.entry)
{
table.add_row(vec![
node.gateway.identity_key.to_string(),
node.owner.to_string(),
node.gateway.host.to_string(),
pretty_cosmwasm_coin(&node.pledge_amount),
node.gateway.version.clone(),
node.node_id.to_string(),
node.ed25519_identity_key().to_base58_string(),
node.description.build_information.build_version,
(!node.contract_node_type.is_nym_node()).to_string(),
]);
}
@@ -2,10 +2,9 @@
// SPDX-License-Identifier: Apache-2.0
use crate::context::QueryClientWithNyxd;
use crate::utils::{pretty_decimal_with_denom, show_error};
use crate::utils::show_error;
use clap::Parser;
use comfy_table::Table;
use nym_validator_client::client::NymApiClientExt;
#[derive(Debug, Parser)]
pub struct Args {
@@ -15,13 +14,11 @@ pub struct Args {
}
pub async fn query(args: Args, client: &QueryClientWithNyxd) {
match client.nym_api.get_mixnodes().await {
match client.get_all_cached_described_nodes().await {
Ok(res) => match args.identity_key {
Some(identity_key) => {
let node = res.iter().find(|node| {
node.bond_information
.mix_node
.identity_key
node.ed25519_identity_key()
.to_string()
.eq_ignore_ascii_case(&identity_key)
});
@@ -33,25 +30,16 @@ pub async fn query(args: Args, client: &QueryClientWithNyxd) {
None => {
let mut table = Table::new();
table.set_header(vec![
"Mix id",
"Identity Key",
"Owner",
"Host",
"Bond",
"Total Delegations",
"Version",
]);
for node in res {
let denom = &node.bond_information.original_pledge().denom;
table.set_header(vec!["Node Id", "Identity Key", "Version", "Is Legacy"]);
for node in res
.into_iter()
.filter(|node| node.description.declared_role.mixnode)
{
table.add_row(vec![
node.mix_id().to_string(),
node.bond_information.mix_node.identity_key.clone(),
node.bond_information.owner.clone().into_string(),
node.bond_information.mix_node.host.clone(),
pretty_decimal_with_denom(node.rewarding_details.operator, denom),
pretty_decimal_with_denom(node.rewarding_details.delegates, denom),
node.bond_information.mix_node.version,
node.node_id.to_string(),
node.ed25519_identity_key().to_base58_string(),
node.description.build_information.build_version,
(!node.contract_node_type.is_nym_node()).to_string(),
]);
}
+2 -2
View File
@@ -6,7 +6,7 @@ use std::sync::Arc;
use time::{Date, OffsetDateTime};
use tracing::*;
use nym_credentials::ecash::utils::{ecash_today, EcashTime};
use nym_credentials::ecash::utils::{cred_exp_date, ecash_today, EcashTime};
use nym_credentials_interface::{Bandwidth, ClientTicket, TicketType};
use nym_gateway_requests::models::CredentialSpendingRequest;
use nym_gateway_storage::Storage;
@@ -131,7 +131,7 @@ impl<S: Storage + Clone + 'static> CredentialVerifier<S> {
let bandwidth = Bandwidth::ticket_amount(credential_type.into());
self.bandwidth_storage_manager
.increase_bandwidth(bandwidth, spend_date)
.increase_bandwidth(bandwidth, cred_exp_date())
.await?;
Ok(self
-34
View File
@@ -1,34 +0,0 @@
[package]
name = "nym-gateway-stats-storage"
version = "0.1.0"
authors.workspace = true
repository.workspace = true
homepage.workspace = true
documentation.workspace = true
edition.workspace = true
license.workspace = true
[dependencies]
sqlx = { workspace = true, features = [
"runtime-tokio-rustls",
"sqlite",
"macros",
"migrate",
"time",
] }
time = { workspace = true }
thiserror = { workspace = true }
tracing = { workspace = true }
nym-sphinx = { path = "../nymsphinx" }
nym-credentials-interface = { path = "../credentials-interface" }
[build-dependencies]
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
sqlx = { workspace = true, features = [
"runtime-tokio-rustls",
"sqlite",
"macros",
"migrate",
] }
-28
View File
@@ -1,28 +0,0 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only
use sqlx::{Connection, SqliteConnection};
use std::env;
#[tokio::main]
async fn main() {
let out_dir = env::var("OUT_DIR").unwrap();
let database_path = format!("{}/gateway-stats-example.sqlite", out_dir);
let mut conn = SqliteConnection::connect(&format!("sqlite://{}?mode=rwc", database_path))
.await
.expect("Failed to create SQLx database connection");
sqlx::migrate!("./migrations")
.run(&mut conn)
.await
.expect("Failed to perform SQLx migrations");
#[cfg(target_family = "unix")]
println!("cargo:rustc-env=DATABASE_URL=sqlite://{}", &database_path);
#[cfg(target_family = "windows")]
// for some strange reason we need to add a leading `/` to the windows path even though it's
// not a valid windows path... but hey, it works...
println!("cargo:rustc-env=DATABASE_URL=sqlite:///{}", &database_path);
}
@@ -1,26 +0,0 @@
/*
* Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
* SPDX-License-Identifier: GPL-3.0-only
*/
CREATE TABLE sessions_active
(
client_address TEXT NOT NULL PRIMARY KEY UNIQUE,
start_time TIMESTAMP WITHOUT TIME ZONE NOT NULL,
typ TEXT NOT NULL
);
CREATE TABLE sessions_finished
(
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
day DATE NOT NULL,
duration_ms INTEGER NOT NULL,
typ TEXT NOT NULL
);
CREATE TABLE sessions_unique_users
(
day DATE NOT NULL,
client_address TEXT NOT NULL,
PRIMARY KEY (day, client_address)
);
-13
View File
@@ -1,13 +0,0 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only
use thiserror::Error;
#[derive(Error, Debug)]
pub enum StatsStorageError {
#[error("Database experienced an internal error: {0}")]
InternalDatabaseError(#[from] sqlx::Error),
#[error("Failed to perform database migration: {0}")]
MigrationError(#[from] sqlx::migrate::MigrateError),
}
-195
View File
@@ -1,195 +0,0 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only
use error::StatsStorageError;
use models::{ActiveSession, FinishedSession, SessionType, StoredFinishedSession};
use nym_sphinx::DestinationAddressBytes;
use sessions::SessionManager;
use sqlx::ConnectOptions;
use std::path::Path;
use time::Date;
use tracing::{debug, error};
pub mod error;
pub mod models;
mod sessions;
// note that clone here is fine as upon cloning the same underlying pool will be used
#[derive(Clone)]
pub struct PersistentStatsStorage {
session_manager: SessionManager,
}
impl PersistentStatsStorage {
/// Initialises `PersistentStatsStorage` using the provided path.
///
/// # Arguments
///
/// * `database_path`: path to the database.
pub async fn init<P: AsRef<Path> + Send>(database_path: P) -> Result<Self, StatsStorageError> {
debug!(
"Attempting to connect to database {:?}",
database_path.as_ref().as_os_str()
);
// TODO: we can inject here more stuff based on our gateway global config
// struct. Maybe different pool size or timeout intervals?
let opts = sqlx::sqlite::SqliteConnectOptions::new()
.filename(database_path)
.create_if_missing(true)
.disable_statement_logging();
// TODO: do we want auto_vacuum ?
let connection_pool = match sqlx::SqlitePool::connect_with(opts).await {
Ok(db) => db,
Err(err) => {
error!("Failed to connect to SQLx database: {err}");
return Err(err.into());
}
};
if let Err(err) = sqlx::migrate!("./migrations").run(&connection_pool).await {
error!("Failed to perform migration on the SQLx database: {err}");
return Err(err.into());
}
// the cloning here are cheap as connection pool is stored behind an Arc
Ok(PersistentStatsStorage {
session_manager: sessions::SessionManager::new(connection_pool),
})
}
//Sessions fn
pub async fn insert_finished_session(
&self,
date: Date,
session: FinishedSession,
) -> Result<(), StatsStorageError> {
Ok(self
.session_manager
.insert_finished_session(
date,
session.duration.whole_milliseconds() as i64,
session.typ.to_string().into(),
)
.await?)
}
pub async fn get_finished_sessions(
&self,
date: Date,
) -> Result<Vec<StoredFinishedSession>, StatsStorageError> {
Ok(self.session_manager.get_finished_sessions(date).await?)
}
pub async fn delete_finished_sessions(
&self,
before_date: Date,
) -> Result<(), StatsStorageError> {
Ok(self
.session_manager
.delete_finished_sessions(before_date)
.await?)
}
pub async fn insert_unique_user(
&self,
date: Date,
client_address_bs58: String,
) -> Result<(), StatsStorageError> {
Ok(self
.session_manager
.insert_unique_user(date, client_address_bs58)
.await?)
}
pub async fn get_unique_users_count(&self, date: Date) -> Result<i32, StatsStorageError> {
Ok(self.session_manager.get_unique_users_count(date).await?)
}
pub async fn delete_unique_users(&self, before_date: Date) -> Result<(), StatsStorageError> {
Ok(self
.session_manager
.delete_unique_users(before_date)
.await?)
}
pub async fn insert_active_session(
&self,
client_address: DestinationAddressBytes,
session: ActiveSession,
) -> Result<(), StatsStorageError> {
Ok(self
.session_manager
.insert_active_session(
client_address.as_base58_string(),
session.start,
session.typ.to_string().into(),
)
.await?)
}
pub async fn update_active_session_type(
&self,
client_address: DestinationAddressBytes,
session_type: SessionType,
) -> Result<(), StatsStorageError> {
Ok(self
.session_manager
.update_active_session_type(
client_address.as_base58_string(),
session_type.to_string().into(),
)
.await?)
}
pub async fn get_active_session(
&self,
client_address: DestinationAddressBytes,
) -> Result<Option<ActiveSession>, StatsStorageError> {
Ok(self
.session_manager
.get_active_session(client_address.as_base58_string())
.await?
.map(Into::into))
}
pub async fn get_all_active_sessions(&self) -> Result<Vec<ActiveSession>, StatsStorageError> {
Ok(self
.session_manager
.get_all_active_sessions()
.await?
.into_iter()
.map(Into::into)
.collect())
}
pub async fn get_started_sessions_count(
&self,
start_date: Date,
) -> Result<i32, StatsStorageError> {
Ok(self
.session_manager
.get_started_sessions_count(start_date)
.await?)
}
pub async fn get_active_users(&self) -> Result<Vec<String>, StatsStorageError> {
Ok(self.session_manager.get_active_users().await?)
}
pub async fn delete_active_session(
&self,
client_address: DestinationAddressBytes,
) -> Result<(), StatsStorageError> {
Ok(self
.session_manager
.delete_active_session(client_address.as_base58_string())
.await?)
}
pub async fn cleanup_active_sessions(&self) -> Result<(), StatsStorageError> {
Ok(self.session_manager.cleanup_active_sessions().await?)
}
}
-109
View File
@@ -1,109 +0,0 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only
use nym_credentials_interface::TicketType;
use sqlx::prelude::FromRow;
use time::{Duration, OffsetDateTime};
#[derive(FromRow)]
pub struct StoredFinishedSession {
duration_ms: i64,
typ: String,
}
impl StoredFinishedSession {
pub fn serialize(&self) -> (u64, String) {
(
self.duration_ms as u64, //we are sure that it fits in a u64, see `fn end_at`
self.typ.clone(),
)
}
}
pub struct FinishedSession {
pub duration: Duration,
pub typ: SessionType,
}
#[derive(PartialEq)]
pub enum SessionType {
Vpn,
Mixnet,
Unknown,
}
impl SessionType {
pub fn to_string(&self) -> &str {
match self {
Self::Vpn => "vpn",
Self::Mixnet => "mixnet",
Self::Unknown => "unknown",
}
}
pub fn from_string(s: &str) -> Self {
match s {
"vpn" => Self::Vpn,
"mixnet" => Self::Mixnet,
_ => Self::Unknown,
}
}
}
impl From<TicketType> for SessionType {
fn from(value: TicketType) -> Self {
match value {
TicketType::V1MixnetEntry => Self::Mixnet,
TicketType::V1MixnetExit => Self::Mixnet,
TicketType::V1WireguardEntry => Self::Vpn,
TicketType::V1WireguardExit => Self::Vpn,
}
}
}
#[derive(FromRow)]
pub(crate) struct StoredActiveSession {
start_time: OffsetDateTime,
typ: String,
}
pub struct ActiveSession {
pub start: OffsetDateTime,
pub typ: SessionType,
}
impl ActiveSession {
pub fn new(start_time: OffsetDateTime) -> Self {
ActiveSession {
start: start_time,
typ: SessionType::Unknown,
}
}
pub fn set_type(&mut self, ticket_type: TicketType) {
self.typ = ticket_type.into();
}
pub fn end_at(self, stop_time: OffsetDateTime) -> Option<FinishedSession> {
let session_duration = stop_time - self.start;
//ensure duration is positive to fit in a u64
//u64::max milliseconds is 500k millenia so no overflow issue
if session_duration > Duration::ZERO {
Some(FinishedSession {
duration: session_duration,
typ: self.typ,
})
} else {
None
}
}
}
impl From<StoredActiveSession> for ActiveSession {
fn from(value: StoredActiveSession) -> Self {
ActiveSession {
start: value.start_time,
typ: SessionType::from_string(&value.typ),
}
}
}
@@ -1,177 +0,0 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only
use time::{Date, OffsetDateTime};
use crate::models::{StoredActiveSession, StoredFinishedSession};
pub(crate) type Result<T> = std::result::Result<T, sqlx::Error>;
#[derive(Clone)]
pub(crate) struct SessionManager {
connection_pool: sqlx::SqlitePool,
}
impl SessionManager {
/// Creates new instance of the `SessionsManager` with the provided sqlite connection pool.
///
/// # Arguments
///
/// * `connection_pool`: database connection pool to use.
pub(crate) fn new(connection_pool: sqlx::SqlitePool) -> Self {
SessionManager { connection_pool }
}
pub(crate) async fn insert_finished_session(
&self,
date: Date,
duration_ms: i64,
typ: String,
) -> Result<()> {
sqlx::query!(
"INSERT INTO sessions_finished (day, duration_ms, typ) VALUES (?, ?, ?)",
date,
duration_ms,
typ
)
.execute(&self.connection_pool)
.await?;
Ok(())
}
pub(crate) async fn get_finished_sessions(
&self,
date: Date,
) -> Result<Vec<StoredFinishedSession>> {
sqlx::query_as("SELECT duration_ms, typ FROM sessions_finished WHERE day = ?")
.bind(date)
.fetch_all(&self.connection_pool)
.await
}
pub(crate) async fn delete_finished_sessions(&self, before_date: Date) -> Result<()> {
sqlx::query!("DELETE FROM sessions_finished WHERE day <= ? ", before_date)
.execute(&self.connection_pool)
.await?;
Ok(())
}
pub(crate) async fn insert_unique_user(
&self,
date: Date,
client_address_b58: String,
) -> Result<()> {
sqlx::query!(
"INSERT OR IGNORE INTO sessions_unique_users (day, client_address) VALUES (?, ?)",
date,
client_address_b58,
)
.execute(&self.connection_pool)
.await?;
Ok(())
}
pub(crate) async fn get_unique_users_count(&self, date: Date) -> Result<i32> {
Ok(sqlx::query!(
"SELECT COUNT(*) as count FROM sessions_unique_users WHERE day = ?",
date
)
.fetch_one(&self.connection_pool)
.await?
.count)
}
pub(crate) async fn delete_unique_users(&self, before_date: Date) -> Result<()> {
sqlx::query!(
"DELETE FROM sessions_unique_users WHERE day <= ? ",
before_date
)
.execute(&self.connection_pool)
.await?;
Ok(())
}
pub(crate) async fn insert_active_session(
&self,
client_address_b58: String,
start_time: OffsetDateTime,
typ: String,
) -> Result<()> {
sqlx::query!(
"INSERT INTO sessions_active (client_address, start_time, typ) VALUES (?, ?, ?)",
client_address_b58,
start_time,
typ
)
.execute(&self.connection_pool)
.await?;
Ok(())
}
pub(crate) async fn update_active_session_type(
&self,
client_address_b58: String,
typ: String,
) -> Result<()> {
sqlx::query!(
"UPDATE sessions_active SET typ = ? WHERE client_address = ?",
typ,
client_address_b58,
)
.execute(&self.connection_pool)
.await?;
Ok(())
}
pub(crate) async fn get_active_session(
&self,
client_address_b58: String,
) -> Result<Option<StoredActiveSession>> {
sqlx::query_as("SELECT start_time, typ FROM sessions_active WHERE client_address = ?")
.bind(client_address_b58)
.fetch_optional(&self.connection_pool)
.await
}
pub(crate) async fn get_all_active_sessions(&self) -> Result<Vec<StoredActiveSession>> {
sqlx::query_as("SELECT start_time, typ FROM sessions_active")
.fetch_all(&self.connection_pool)
.await
}
pub(crate) async fn get_started_sessions_count(&self, start_date: Date) -> Result<i32> {
Ok(sqlx::query!(
"SELECT COUNT(*) as count FROM sessions_active WHERE date(start_time) = ?",
start_date
)
.fetch_one(&self.connection_pool)
.await?
.count)
}
pub(crate) async fn get_active_users(&self) -> Result<Vec<String>> {
Ok(sqlx::query!("SELECT client_address from sessions_active")
.fetch_all(&self.connection_pool)
.await?
.into_iter()
.map(|record| record.client_address)
.collect())
}
pub(crate) async fn delete_active_session(&self, client_address_b58: String) -> Result<()> {
sqlx::query!(
"DELETE FROM sessions_active WHERE client_address = ?",
client_address_b58
)
.execute(&self.connection_pool)
.await?;
Ok(())
}
pub(crate) async fn cleanup_active_sessions(&self) -> Result<()> {
sqlx::query!("DELETE FROM sessions_active")
.execute(&self.connection_pool)
.await?;
Ok(())
}
}
+13 -10
View File
@@ -315,6 +315,7 @@ impl Client {
parse_response(res, true).await
}
#[instrument(level = "debug", skip_all)]
pub async fn get_json_endpoint<T, S, E>(&self, endpoint: S) -> Result<T, HttpClientError<E>>
where
for<'a> T: Deserialize<'a>,
@@ -534,17 +535,19 @@ where
}
if res.status().is_success() {
let text = res.text().await?;
match serde_json::from_str(&text) {
Ok(res) => Ok(res),
Err(source) => {
#[cfg(debug_assertions)]
{
tracing::trace!("Result:\n{:#?}", text);
}
Err(HttpClientError::ResponseDeserialisationFailure { source })
}
#[cfg(debug_assertions)]
{
let text = res.text().await.inspect_err(|err| {
tracing::error!("Couldn't even get response text: {err}");
})?;
tracing::trace!("Result:\n{:#?}", text);
serde_json::from_str(&text)
.map_err(|err| HttpClientError::GenericRequestFailure(err.to_string()))
}
#[cfg(not(debug_assertions))]
Ok(res.json().await?)
} else if res.status() == StatusCode::NOT_FOUND {
Err(HttpClientError::NotFound)
} else {
+6 -15
View File
@@ -14,7 +14,6 @@ use nym_task::TaskClient;
use rand::seq::SliceRandom;
use rand::thread_rng;
use std::net::SocketAddr;
use std::net::ToSocketAddrs;
use std::sync::Arc;
use std::time::Duration;
use tokio::task::JoinHandle;
@@ -313,7 +312,7 @@ impl VerlocMeasurer {
info!("Starting verloc measurements");
// TODO: should we also measure gateways?
let all_mixes = match self.validator_client.get_cached_mixnodes().await {
let all_mixes = match self.validator_client.get_all_described_nodes().await {
Ok(nodes) => nodes,
Err(err) => {
error!(
@@ -332,22 +331,14 @@ impl VerlocMeasurer {
// we only care about address and identity
let tested_nodes = all_mixes
.into_iter()
.filter(|n| n.description.declared_role.mixnode)
.filter_map(|node| {
let mix_node = node.bond_information.mix_node;
// check if the node has sufficient version to be able to understand the packets
let node_version = parse_version(&mix_node.version).ok()?;
if node_version < self.config.minimum_compatible_node_version {
return None;
}
// try to parse the identity and host
let node_identity =
identity::PublicKey::from_base58_string(mix_node.identity_key).ok()?;
let node_identity = node.ed25519_identity_key();
let verloc_host = (&*mix_node.host, mix_node.verloc_port)
.to_socket_addrs()
.ok()?
.next()?;
let ip = node.description.host_information.ip_address.first()?;
let verloc_port = node.description.verloc_port();
let verloc_host = SocketAddr::new(*ip, verloc_port);
// TODO: possible problem in the future, this does name resolution and theoretically
// if a lot of nodes maliciously mis-configured themselves, it might take a while to resolve them all
@@ -21,7 +21,7 @@ nym-sphinx-types = { path = "../types" }
nym-topology = { path = "../../topology" }
[target."cfg(target_arch = \"wasm32\")".dependencies.wasm-bindgen]
version = "0.2.95"
version = "0.2.93"
[dev-dependencies]
rand_chacha = { workspace = true }
+9 -1
View File
@@ -3,7 +3,7 @@ use crate::deprecated::DelegationEvent;
use crate::error::TypesError;
use crate::mixnode::NodeCostParams;
use cosmwasm_std::Decimal;
use nym_mixnet_contract_common::{Delegation as MixnetContractDelegation, NodeId};
use nym_mixnet_contract_common::{Delegation as MixnetContractDelegation, NodeId, NodeRewarding};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
@@ -70,6 +70,14 @@ pub struct DelegationWithEverything {
pub mixnode_is_unbonding: Option<bool>,
}
pub struct NodeInformation {
pub owner: String,
pub mix_id: NodeId,
pub node_identity: String,
pub rewarding_details: NodeRewarding,
pub is_unbonding: bool,
}
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
+14 -1
View File
@@ -99,12 +99,25 @@ pub async fn start_wireguard<St: nym_gateway_storage::Storage + Clone + 'static>
let peers = all_peers
.into_iter()
.map(Peer::try_from)
.collect::<Result<Vec<_>, _>>()?;
.collect::<Result<Vec<_>, _>>()?
.into_iter()
.map(|mut peer| {
// since WGApi doesn't set those values on init, let's set them to 0
peer.rx_bytes = 0;
peer.tx_bytes = 0;
peer
})
.collect::<Vec<_>>();
for peer in peers.iter() {
let bandwidth_manager =
PeerController::generate_bandwidth_manager(storage.clone(), &peer.public_key)
.await?
.map(|bw_m| Arc::new(RwLock::new(bw_m)));
// Update storage with *x_bytes set to 0, as in kernel peers we can't set those values
// so we need to restart counting. Hopefully the bandwidth was counted in available_bandwidth
storage
.insert_wireguard_peer(peer, bandwidth_manager.is_some())
.await?;
peer_bandwidth_managers.insert(peer.public_key.clone(), bandwidth_manager);
}
wg_api.create_interface()?;
+3 -3
View File
@@ -7,8 +7,8 @@ use defguard_wireguard_rs::{
WireguardInterfaceApi,
};
use futures::channel::oneshot;
use nym_authenticator_requests::{
latest::registration::RemainingBandwidthData, v1::registration::BANDWIDTH_CAP_PER_DAY,
use nym_authenticator_requests::latest::registration::{
RemainingBandwidthData, BANDWIDTH_CAP_PER_DAY,
};
use nym_credential_verification::{
bandwidth_storage_manager::BandwidthStorageManager, BandwidthFlushingBehaviourConfig,
@@ -230,7 +230,7 @@ impl<St: Storage + Clone + 'static> PeerController<St> {
// host information not updated yet
return Ok(None);
};
BANDWIDTH_CAP_PER_DAY.saturating_sub((peer.rx_bytes + peer.tx_bytes) as i64)
BANDWIDTH_CAP_PER_DAY.saturating_sub(peer.rx_bytes + peer.tx_bytes) as i64
};
Ok(Some(RemainingBandwidthData {
+9 -6
View File
@@ -6,7 +6,7 @@ use crate::peer_controller::PeerControlRequest;
use defguard_wireguard_rs::host::Peer;
use defguard_wireguard_rs::{host::Host, key::Key};
use futures::channel::oneshot;
use nym_authenticator_requests::v2::registration::BANDWIDTH_CAP_PER_DAY;
use nym_authenticator_requests::latest::registration::BANDWIDTH_CAP_PER_DAY;
use nym_credential_verification::bandwidth_storage_manager::BandwidthStorageManager;
use nym_gateway_storage::models::WireguardPeer;
use nym_gateway_storage::Storage;
@@ -18,7 +18,7 @@ use tokio::sync::{mpsc, RwLock};
use tokio_stream::{wrappers::IntervalStream, StreamExt};
pub(crate) type SharedBandwidthStorageManager<St> = Arc<RwLock<BandwidthStorageManager<St>>>;
const AUTO_REMOVE_AFTER: Duration = Duration::from_secs(60 * 60 * 24); // 24 hours
const AUTO_REMOVE_AFTER: Duration = Duration::from_secs(60 * 60 * 24 * 30); // 30 days
pub struct PeerHandle<St> {
storage: St,
@@ -75,8 +75,8 @@ impl<St: Storage + Clone + 'static> PeerHandle<St> {
async fn active_peer(
&mut self,
storage_peer: WireguardPeer,
kernel_peer: Peer,
storage_peer: &WireguardPeer,
kernel_peer: &Peer,
) -> Result<bool, Error> {
if let Some(bandwidth_manager) = &self.bandwidth_storage_manager {
let spent_bandwidth = (kernel_peer.rx_bytes + kernel_peer.tx_bytes)
@@ -98,7 +98,7 @@ impl<St: Storage + Clone + 'static> PeerHandle<St> {
} else {
if SystemTime::now().duration_since(self.startup_timestamp)? >= AUTO_REMOVE_AFTER {
log::debug!(
"Peer {} has been present for 24 hours, removing it",
"Peer {} has been present for 30 days, removing it",
self.public_key.to_string()
);
let success = self.remove_peer().await?;
@@ -136,9 +136,12 @@ impl<St: Storage + Clone + 'static> PeerHandle<St> {
log::debug!("Peer {:?} not in storage anymore, shutting down handle", self.public_key);
return Ok(());
};
if !self.active_peer(storage_peer, kernel_peer).await? {
if !self.active_peer(&storage_peer, &kernel_peer).await? {
log::debug!("Peer {:?} doesn't have bandwidth anymore, shutting down handle", self.public_key);
return Ok(());
} else {
// Update storage values
self.storage.insert_wireguard_peer(&kernel_peer, self.bandwidth_storage_manager.is_some()).await?;
}
}
+15 -15
View File
@@ -433,7 +433,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.59",
]
[[package]]
@@ -1483,9 +1483,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.89"
version = "1.0.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e"
checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba"
dependencies = [
"unicode-ident",
]
@@ -1660,7 +1660,7 @@ dependencies = [
"proc-macro2",
"quote",
"serde_derive_internals",
"syn 2.0.85",
"syn 2.0.59",
]
[[package]]
@@ -1702,9 +1702,9 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.214"
version = "1.0.210"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5"
checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"
dependencies = [
"serde_derive",
]
@@ -1729,13 +1729,13 @@ dependencies = [
[[package]]
name = "serde_derive"
version = "1.0.214"
version = "1.0.210"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766"
checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.59",
]
[[package]]
@@ -1746,7 +1746,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.59",
]
[[package]]
@@ -1769,7 +1769,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.59",
]
[[package]]
@@ -1928,9 +1928,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.85"
version = "2.0.59"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56"
checksum = "4a6531ffc7b071655e4ce2e04bd464c4830bb585a61cabb96cf808f05172615a"
dependencies = [
"proc-macro2",
"quote",
@@ -1954,7 +1954,7 @@ checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.59",
]
[[package]]
@@ -2120,5 +2120,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.59",
]
+8 -17
View File
@@ -104,7 +104,10 @@ pub(crate) fn next_nymnode_id_counter(store: &mut dyn Storage) -> StdResult<Node
}
pub(crate) fn initialise_storage(storage: &mut dyn Storage) -> Result<(), MixnetContractError> {
ACTIVE_ROLES_BUCKET.save(storage, &RoleStorageBucket::default())?;
let active_bucket = RoleStorageBucket::default();
let inactive_bucket = active_bucket.other();
ACTIVE_ROLES_BUCKET.save(storage, &active_bucket)?;
let roles = vec![
Role::Layer1,
Role::Layer2,
@@ -114,24 +117,12 @@ pub(crate) fn initialise_storage(storage: &mut dyn Storage) -> Result<(), Mixnet
Role::Standby,
];
for role in roles {
ROLES.save(storage, (RoleStorageBucket::default() as u8, role), &vec![])?;
ROLES.save(
storage,
(RoleStorageBucket::default().other() as u8, role),
&vec![],
)?
ROLES.save(storage, (active_bucket as u8, role), &vec![])?;
ROLES.save(storage, (inactive_bucket as u8, role), &vec![])?
}
ROLES_METADATA.save(
storage,
RoleStorageBucket::default() as u8,
&Default::default(),
)?;
ROLES_METADATA.save(
storage,
RoleStorageBucket::default().other() as u8,
&Default::default(),
)?;
ROLES_METADATA.save(storage, active_bucket as u8, &Default::default())?;
ROLES_METADATA.save(storage, inactive_bucket as u8, &Default::default())?;
Ok(())
}
+119 -10
View File
@@ -90,12 +90,16 @@ mod families_purge {
mod nym_nodes_usage {
use crate::constants::{CONTRACT_STATE_KEY, REWARDING_PARAMS_KEY};
use crate::interval::storage::current_interval;
use crate::mixnet_contract_settings::storage::CONTRACT_STATE;
use crate::nodes::storage::helpers::RoleStorageBucket;
use crate::nodes::storage::rewarded_set::{ACTIVE_ROLES_BUCKET, ROLES, ROLES_METADATA};
use crate::rewards::storage::RewardingStorage;
use crate::support::helpers::ensure_epoch_in_progress_state;
use cosmwasm_std::{Addr, Coin, DepsMut, Order, StdResult, Storage};
use cw_storage_plus::{Item, Map};
use mixnet_contract_common::error::MixnetContractError;
use mixnet_contract_common::nym_node::{RewardedSetMetadata, Role};
use mixnet_contract_common::reward_params::RewardedSetParams;
use mixnet_contract_common::{
ContractState, ContractStateParams, IntervalRewardParams, MigrateMsg, NodeId,
@@ -173,7 +177,9 @@ mod nym_nodes_usage {
Ok(())
}
fn preassign_gateway_ids(storage: &mut dyn Storage) -> Result<(), MixnetContractError> {
fn preassign_gateway_ids(
storage: &mut dyn Storage,
) -> Result<(Option<NodeId>, Option<NodeId>), MixnetContractError> {
// that one is a big if. we have ~100 gateways so we **might** be able to fit it within migration.
// if not, then we'll have to do it in batches/change our approach
@@ -182,8 +188,15 @@ mod nym_nodes_usage {
.map(|res| res.map(|row| row.1))
.collect::<StdResult<Vec<_>>>()?;
let mut start = None;
let mut end = None;
for gateway in gateways {
let id = crate::nodes::storage::next_nymnode_id_counter(storage)?;
if start.is_none() {
start = Some(id)
}
end = Some(id);
crate::gateways::storage::PREASSIGNED_LEGACY_IDS.save(
storage,
gateway.gateway.identity_key,
@@ -191,10 +204,12 @@ mod nym_nodes_usage {
)?;
}
Ok(())
Ok((start, end))
}
fn cleanup_legacy_storage(storage: &mut dyn Storage) -> Result<(), MixnetContractError> {
fn cleanup_legacy_storage(
storage: &mut dyn Storage,
) -> Result<Vec<NodeId>, MixnetContractError> {
#[derive(Copy, Clone, Default, Serialize, Deserialize)]
pub struct LayerDistribution {
pub layer1: u64,
@@ -224,11 +239,11 @@ mod nym_nodes_usage {
.keys(storage, None, None, Order::Ascending)
.collect::<Result<Vec<_>, _>>()?;
for node_id in rewarded_ids {
for &node_id in &rewarded_ids {
REWARDED_SET.remove(storage, node_id)
}
Ok(())
Ok(rewarded_ids)
}
fn migrate_rewarded_set_params(storage: &mut dyn Storage) -> Result<(), MixnetContractError> {
@@ -268,6 +283,98 @@ mod nym_nodes_usage {
Ok(())
}
fn assign_temporary_rewarded_set(
storage: &mut dyn Storage,
(min_available_gateway, max_available_gateway): (Option<NodeId>, Option<NodeId>),
current_rewarded_set_mixnodes: Vec<NodeId>,
) -> Result<(), MixnetContractError> {
let epoch_id = current_interval(storage)?.current_epoch_absolute_id();
// in the previous step we explicitly set rewarded set to 120 mixnodes and 50 entry gateways
// note: we can't assign exit gateways because the contract itself doesn't know which might support it
let active_bucket = RoleStorageBucket::default();
let inactive_bucket = active_bucket.other();
ACTIVE_ROLES_BUCKET.save(storage, &active_bucket)?;
// ACTIVE BUCKET:
let mut active_metadata = RewardedSetMetadata::new(epoch_id);
let mut current_rewarded_set_mixnodes = current_rewarded_set_mixnodes;
// ensure it's sorted. it should have already been, but better safe than sorry..
current_rewarded_set_mixnodes.sort();
let mut layer1 = Vec::new();
let mut layer2 = Vec::new();
let mut layer3 = Vec::new();
let mut entry = Vec::new();
for (i, mix_id) in current_rewarded_set_mixnodes
.into_iter()
.take(120)
.enumerate()
{
if i % 3 == 0 {
layer1.push(mix_id);
} else if i % 3 == 1 {
layer2.push(mix_id);
} else if i % 3 == 2 {
layer3.push(mix_id);
}
}
if let (Some(min_id), Some(max_id)) = (min_available_gateway, max_available_gateway) {
// we can assign the gateway nodes
entry = (min_id..=max_id).take(50).collect();
}
// ACTIVE BUCKET:
active_metadata.fully_assigned = true;
// layer1
ROLES.save(storage, (active_bucket as u8, Role::Layer1), &layer1)?;
active_metadata.layer1_metadata.num_nodes = layer1.len() as u32;
active_metadata.layer1_metadata.highest_id = layer1.last().copied().unwrap_or_default();
// layer2
ROLES.save(storage, (active_bucket as u8, Role::Layer2), &layer2)?;
active_metadata.layer2_metadata.num_nodes = layer2.len() as u32;
active_metadata.layer2_metadata.highest_id = layer2.last().copied().unwrap_or_default();
// layer3
ROLES.save(storage, (active_bucket as u8, Role::Layer3), &layer3)?;
active_metadata.layer3_metadata.num_nodes = layer3.len() as u32;
active_metadata.layer3_metadata.highest_id = layer3.last().copied().unwrap_or_default();
// entry
ROLES.save(storage, (active_bucket as u8, Role::EntryGateway), &entry)?;
active_metadata.entry_gateway_metadata.num_nodes = entry.len() as u32;
active_metadata.entry_gateway_metadata.highest_id =
entry.last().copied().unwrap_or_default();
// nothing for exit or standby
ROLES.save(storage, (active_bucket as u8, Role::ExitGateway), &vec![])?;
ROLES.save(storage, (active_bucket as u8, Role::Standby), &vec![])?;
ROLES_METADATA.save(storage, active_bucket as u8, &active_metadata)?;
// SECONDARY BUCKET
let roles = vec![
Role::Layer1,
Role::Layer2,
Role::Layer3,
Role::EntryGateway,
Role::ExitGateway,
Role::Standby,
];
for role in roles {
ROLES.save(storage, (inactive_bucket as u8, role), &vec![])?
}
ROLES_METADATA.save(storage, inactive_bucket as u8, &Default::default())?;
Ok(())
}
pub(crate) fn migrate_to_nym_nodes_usage(
deps: DepsMut<'_>,
_msg: &MigrateMsg,
@@ -284,16 +391,18 @@ mod nym_nodes_usage {
// pre-assign NodeId to all gateways (that will be applied during nym-node migration)
// to simplify all other code during the intermediate period
preassign_gateway_ids(deps.storage)?;
// initialise all the storage structures required by nym-nodes
crate::nodes::storage::initialise_storage(deps.storage)?;
let gateways = preassign_gateway_ids(deps.storage)?;
// update the simple active/rewarded set sizes to actually contain the distribution of roles
migrate_rewarded_set_params(deps.storage)?;
// remove all redundant storage items
cleanup_legacy_storage(deps.storage)?;
let old_rewarded_set_mixnodes = cleanup_legacy_storage(deps.storage)?;
// assign initial rewarded set
// and initialise all the storage structures required by nym-nodes
// based on the nodes that are in the contract right now
assign_temporary_rewarded_set(deps.storage, gateways, old_rewarded_set_mixnodes)?;
Ok(())
}
-1
View File
@@ -1 +0,0 @@
todo.md
+21 -43
View File
@@ -1,53 +1,30 @@
# Nym Docs v2
This is v2 of the nym docs, condensed from various mdbooks projects that we had previously.
These docs are hosted at [nymtech.net/docs](www.nymtech.net/docs).
# Documentation
## Doc projects
`docs/pages/` contains several subdirs, each hosting a subsection of the docs:
* `network` contains key concepts, cryptosystems, architecture.
* `developers` contains key concepts for developers, required architecture, and Rust/Typescript SDK docs.
* `operators` contains node setup and maintenance guides.
Each directory contains a readme with more information about running and contributing to the projects. Each is built with [`mdbook`](https://rust-lang.github.io/mdBook/index.html) - use `mdbook serve` to build and serve them (defaults to `localhost:3000`).
* `docs` contains technical documentation hosted at [https://nymtech.net/docs](https://nymtech.net/docs)
* `dev-portal` contains developer documentation hosted at [https://nymtech.net/developers](https://nymtech.net/developers)
* `operators` contains node setup and maintenance guides hosted at [https://nymtech.net/operators](https://nymtech.net/operators)
## Local development
### Dependencies
Our `prebuild` script relies on the following:
- `python`
- `pip`
- [`pandas`](https://pandas.pydata.org/)
- [`tabulate`](https://pypi.org/project/tabulate/)
- `jq`
> If you are looking for the Typescript SDK documentation located at [sdk.nymtech.net](https://sdk.nymtech.net) this can be found in `../sdk/typescript/docs/`
Otherwise make sure to have `node` installed.
## Contribution
* If you wish to add to the documentation please create a PR against this repo.
* If you are **adding a plugin dependency** make sure to also **add that to the list of plugins in `install_mdbook_deps.sh` line 12**.
### Serve Local (Hot Reload)
```sh
pnpm i
pnpm run dev
```
## Scripts
* `bump_versions.sh` allows you to update the ~~`platform_release_version` and~~ `wallet_release_version` variable~~s~~ in the `book.toml` of each mdbook project at once. You can also optionally update the `minimum_rust_version` as well. Helpful for lazy-updating when cutting a new version of the docs.
Open `http://localhost:3000`.
* The following scripts are used by the `ci-dev.yml` and `cd-dev.yml` scripts (located in `../.github/workflows/`):
* `build_all_to_dist.sh` is used for building all mdbook projects and moving the rendered html to `../dist/` to be rsynced with various servers.
* `install_mdbook_deps.sh` checks for an existing install of mdbook (and plugins), uninstalls them, and then installs them on a clean slate. This is to avoid weird dependency clashes if relying on an existing mdbook version.
* `post_process.sh` is used to post process CSS/image/href links for serving several mdbooks from a subdirectory.
* `removed_existing_config.sh` is used to check for existing nym client/node config files on the CI/CD server and remove it if it exists. This is to mitigate issues with `mdbook-cmdrun` where e.g. a node is already initialised, and the command fails.
## Build
```sh
pnpm run build
```
The static output will be in `./out`;
## Contribution
* If you wish to add to the documentation please create a PR against this repo, with a `patch` against `develop`.
## Scripts
* There are several autogenerated command files for clients and binaries. These are generated with `generate:commands`, which runs the `autodoc` rust binary, moves the files to their required places, and then if there is an update, commits them to git. This is for remote deployments.
* Python scripts TODO
### Autodoc
`autodoc` is a script that generates markdown files containing commands and their output (both command and `--help` output). For the moment the binaries and their commands are manually configured in the script.
## CI/CD
TODO
## CI/CD
Deployment of the docs is partially automated and partially manual.
* `ci-docs.yml` will run on pushes to all branches **apart from `master`**
* `cd-docs.yml` must be run manually. This pushes to a staging branch which then must be manually promoted to production.
## Licensing and copyright information
This is a monorepo and components that make up Nym as a system are licensed individually, so for accurate information, please check individual files.
@@ -59,3 +36,4 @@ As a general approach, licensing is as follows this pattern:
* Nym applications and binaries are [GPL-3.0-only](https://www.gnu.org/licenses/)
* Used libraries and different components are [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0.html) or [MIT](https://mit-license.org/)
-1
View File
@@ -1 +0,0 @@
autodoc-generated-markdown/*
-13
View File
@@ -1,13 +0,0 @@
[package]
name = "autodoc"
version = "0.1.0"
authors.workspace = true
repository.workspace = true
homepage.workspace = true
documentation.workspace = true
edition.workspace = true
license.workspace = true
[dependencies]
env_logger = "0.11.3"
log.workspace = true
-44
View File
@@ -1,44 +0,0 @@
# Autodoc
WIP command output documentation generator. Run via `../scripts/next-scripts/autodoc.sh` to create a bunch of markdown files which are then moved around for importing into the documentation.
## `Error: Os { code: 2, kind: NotFound, message: "No such file or directory" }`
If you run into this error, make sure that you have the following directory structure:
```sh
autodoc/
├── autodoc-generated-markdown/
│ └── commands/
├── Cargo.toml
├── README.md
└── src
└── main.rs
```
And if you don't - create it and re-run.
If you are encountering this error with this dir structure in place, check that all Nym binaries that are listed in `main.rs` also exist in `nym/target/release/`.
Run this crate on its own with `debug` logging and it should panic on the missing binary:
```sh
RUST_LOG="debug" cargo run --release
Finished `release` profile [optimized] target(s) in 0.20s
Running `/home/______/src/nym/target/release/autodoc`
[2024-10-23T08:11:01Z DEBUG autodoc] now running Some(
"nym-api",
)
[2024-10-23T08:11:01Z DEBUG autodoc] stderr: " 2024-10-23T08:11:01.981Z INFO nym_api > Starting nym api...\n"
[2024-10-23T08:11:01Z DEBUG autodoc] stderr: " 2024-10-23T08:11:01.985Z INFO nym_api > Starting nym api...\n"
[2024-10-23T08:11:01Z INFO autodoc] SKIPPING ../../target/release/nym-api init
[2024-10-23T08:11:01Z INFO autodoc] creating own file for ../../target/release/nym-api init --help
[2024-10-23T08:11:01Z DEBUG autodoc] stderr: " 2024-10-23T08:11:01.993Z INFO nym_api > Starting nym api...\n"
< snip >
[2024-10-23T08:11:02Z DEBUG autodoc] now running Some(
"nym-cli",
)
Error: Os { code: 2, kind: NotFound, message: "No such file or directory" }
```
@@ -1,9 +0,0 @@
```sh
Show build information of this binary
Usage: nym-api build-info [OPTIONS]
Options:
-o, --output <OUTPUT> [default: text] [possible values: text, json]
-h, --help Print help
```
@@ -1,13 +0,0 @@
```sh
Binary Name: nym-api
Build Timestamp: 2024-10-09T13:56:14.428750844Z
Build Version: 1.1.42
Commit SHA: fac373c1db4fa5389ba61de7943c77023467bccb
Commit Date: 2024-10-09T14:59:40.000000000+02:00
Commit Branch: max/new-docs-framework
rustc Version: 1.80.0
rustc Channel: stable
cargo Profile: release
```
@@ -1,95 +0,0 @@
# `nym-api` Binary Commands (Autogenerated)
These docs are autogenerated by the [`autodocs`](https://github.com/nymtech/nym/tree/max/new-docs-framework/documentation/autodoc) script.
```sh
2024-10-29T09:51:44.008469Z  INFO nym-api/src/main.rs:41: Starting nym api...
Usage: nym-api [OPTIONS] <COMMAND>
Commands:
init Initialise a Nym Api instance with persistent config.toml file
run Run the Nym Api with provided configuration optionally overriding set parameters
build-info Show build information of this binary
help Print this message or the help of the given subcommand(s)
Options:
-c, --config-env-file <CONFIG_ENV_FILE>
Path pointing to an env file that configures the Nym API [env: NYMAPI_CONFIG_ENV_FILE_ARG=]
--no-banner
A no-op flag included for consistency with other binaries (and compatibility with nymvisor, oops) [env: NYMAPI_NO_BANNER_ARG=]
-h, --help
Print help
-V, --version
Print version
```
### `init`
```sh
2024-10-29T09:51:44.013292Z  INFO nym-api/src/main.rs:41: Starting nym api...
Initialise a Nym Api instance with persistent config.toml file
Usage: nym-api init [OPTIONS]
Options:
--id <ID>
Id of the nym-api we want to initialise. if unspecified, a default value will be used. default: "default" [env: NYMAPI_ID_ARG=] [default: default]
-m, --enable-monitor
Specifies whether network monitoring is enabled on this API default: false [env: NYMAPI_ENABLE_MONITOR_ARG=]
-r, --enable-rewarding
Specifies whether network rewarding is enabled on this API default: false [env: NYMAPI_ENABLE_REWARDING_ARG=]
--nyxd-validator <NYXD_VALIDATOR>
Endpoint to nyxd instance used for contract information. default: http://localhost:26657 [env: NYMAPI_NYXD_VALIDATOR_ARG=]
--mnemonic <MNEMONIC>
Mnemonic of the network monitor used for sending rewarding and zk-nyms transactions default: None [env: NYMAPI_MNEMONIC_ARG=]
--enable-zk-nym
Flag to indicate whether credential signer authority is enabled on this API default: false [env: NYMAPI_ENABLE_ZK_NYM_ARG=]
--announce-address <ANNOUNCE_ADDRESS>
Announced address that is going to be put in the DKG contract where zk-nym clients will connect to obtain their credentials default: None [env: NYMAPI_ANNOUNCE_ADDRESS_NYM_ARG=]
--monitor-credentials-mode
Set this nym api to work in a enabled credentials that would attempt to use gateway with the bandwidth credential requirement [env: NYMAPI_MONITOR_CREDENTIALS_MODE_ARG=]
--bind-address <BIND_ADDRESS>
Socket address this api will use for binding its http API. default: `127.0.0.1:8080` in `debug` builds and `0.0.0.0:8080` in `release`
-h, --help
Print help
```
### `run`
```sh
2024-10-29T09:51:44.032688Z  INFO nym-api/src/main.rs:41: Starting nym api...
Run the Nym Api with provided configuration optionally overriding set parameters
Usage: nym-api run [OPTIONS]
Options:
--id <ID>
Id of the nym-api we want to run.if unspecified, a default value will be used. default: "default" [env: NYMAPI_ID_ARG=] [default: default]
-m, --enable-monitor <ENABLE_MONITOR>
Specifies whether network monitoring is enabled on this API default: None - config value will be used instead [env: NYMAPI_ENABLE_MONITOR_ARG=] [possible values: true, false]
-r, --enable-rewarding <ENABLE_REWARDING>
Specifies whether network rewarding is enabled on this API default: None - config value will be used instead [env: NYMAPI_ENABLE_REWARDING_ARG=] [possible values: true, false]
--nyxd-validator <NYXD_VALIDATOR>
Endpoint to nyxd instance used for contract information. default: None - config value will be used instead [env: NYMAPI_NYXD_VALIDATOR_ARG=]
--mnemonic <MNEMONIC>
Mnemonic of the network monitor used for sending rewarding and zk-nyms transactions default: None - config value will be used instead [env: NYMAPI_MNEMONIC_ARG=]
--enable-zk-nym <ENABLE_ZK_NYM>
Flag to indicate whether coconut signer authority is enabled on this API default: None - config value will be used instead [env: NYMAPI_ENABLE_ZK_NYM_ARG=] [possible values: true, false]
--announce-address <ANNOUNCE_ADDRESS>
Announced address that is going to be put in the DKG contract where zk-nym clients will connect to obtain their credentials default: None - config value will be used instead [env: NYMAPI_ANNOUNCE_ADDRESS_ARG=]
--monitor-credentials-mode <MONITOR_CREDENTIALS_MODE>
Set this nym api to work in a enabled credentials that would attempt to use gateway with the bandwidth credential requirement default: None - config value will be used instead [env: NYMAPI_MONITOR_CREDENTIALS_MODE_ARG=] [possible values: true, false]
--bind-address <BIND_ADDRESS>
Socket address this api will use for binding its http API. default: `127.0.0.1:8080` in `debug` builds and `0.0.0.0:8080` in `release`
-h, --help
Print help
```
### `build-info`
```sh
2024-10-29T09:51:44.037915Z  INFO nym-api/src/main.rs:41: Starting nym api...
Show build information of this binary
Usage: nym-api build-info [OPTIONS]
Options:
-o, --output <OUTPUT> [default: text] [possible values: text, json]
-h, --help Print help
```
@@ -1,25 +0,0 @@
```sh
Initialise a Nym Api instance with persistent config.toml file
Usage: nym-api init [OPTIONS]
Options:
--id <ID>
Id of the nym-api we want to initialise. if unspecified, a default value will be used. default: "default" [default: default]
-m, --enable-monitor
Specifies whether network monitoring is enabled on this API default: false
-r, --enable-rewarding
Specifies whether network rewarding is enabled on this API default: false
--nyxd-validator <NYXD_VALIDATOR>
Endpoint to nyxd instance used for contract information. default: http://localhost:26657
--mnemonic <MNEMONIC>
Mnemonic of the network monitor used for sending rewarding and zk-nyms transactions default: None
--enable-zk-nym
Flag to indicate whether credential signer authority is enabled on this API default: false
--announce-address <ANNOUNCE_ADDRESS>
Announced address that is going to be put in the DKG contract where zk-nym clients will connect to obtain their credentials default: None
--monitor-credentials-mode
Set this nym api to work in a enabled credentials that would attempt to use gateway with the bandwidth credential requirement
-h, --help
Print help
```
@@ -1,9 +0,0 @@
```sh
Show build information of this binary
Usage: nym-client build-info [OPTIONS]
Options:
-o, --output <OUTPUT> [default: text] [possible values: text, json]
-h, --help Print help
```
@@ -1,13 +0,0 @@
```sh
Binary Name: nym-client
Build Timestamp: 2024-10-09T13:56:14.428750844Z
Build Version: 1.1.39
Commit SHA: fac373c1db4fa5389ba61de7943c77023467bccb
Commit Date: 2024-10-09T14:59:40.000000000+02:00
Commit Branch: max/new-docs-framework
rustc Version: 1.80.0
rustc Channel: stable
cargo Profile: release
```
@@ -1,11 +0,0 @@
```sh
Generate shell completions
Usage: nym-client completions <SHELL>
Arguments:
<SHELL> [possible values: bash, elvish, fish, power-shell, zsh]
Options:
-h, --help Print help
```
@@ -1,8 +0,0 @@
```sh
Generate Fig specification
Usage: nym-client generate-fig-spec
Options:
-h, --help Print help
```
@@ -1,585 +0,0 @@
```sh
const completion: Fig.Spec = {
name: "nym-native-client",
description: "Implementation of the Nym Client",
subcommands: [
{
name: "init",
description: "Initialise a Nym client. Do this first!",
options: [
{
name: "--id",
description: "Id of client we want to create config for",
isRepeatable: true,
args: {
name: "id",
},
},
{
name: "--gateway",
description: "Id of the gateway we are going to connect to",
isRepeatable: true,
args: {
name: "gateway",
isOptional: true,
},
},
{
name: "--nyxd-urls",
description: "Comma separated list of rest endpoints of the nyxd validators",
hidden: true,
isRepeatable: true,
args: {
name: "nyxd_urls",
isOptional: true,
},
},
{
name: "--nym-apis",
description: "Comma separated list of rest endpoints of the API validators",
isRepeatable: true,
args: {
name: "nym_apis",
isOptional: true,
},
},
{
name: "--custom-mixnet",
description: "Path to .json file containing custom network specification",
hidden: true,
isRepeatable: true,
args: {
name: "custom_mixnet",
isOptional: true,
template: "filepaths",
},
},
{
name: "--enabled-credentials-mode",
description: "Set this client to work in a enabled credentials mode that would attempt to use gateway with bandwidth credential requirement",
hidden: true,
isRepeatable: true,
args: {
name: "enabled_credentials_mode",
isOptional: true,
suggestions: [
"true",
"false",
],
},
},
{
name: "--disable-socket",
description: "Whether to not start the websocket",
isRepeatable: true,
args: {
name: "disable_socket",
isOptional: true,
suggestions: [
"true",
"false",
],
},
},
{
name: ["-p", "--port"],
description: "Port for the socket (if applicable) to listen on in all subsequent runs",
isRepeatable: true,
args: {
name: "port",
isOptional: true,
},
},
{
name: "--host",
description: "Ip for the socket (if applicable) to listen for requests",
isRepeatable: true,
args: {
name: "host",
isOptional: true,
},
},
{
name: ["-o", "--output"],
isRepeatable: true,
args: {
name: "output",
isOptional: true,
suggestions: [
"text",
"json",
],
},
},
{
name: "--force-tls-gateway",
description: "Specifies whether the client will attempt to enforce tls connection to the desired gateway",
},
{
name: "--latency-based-selection",
description: "Specifies whether the new gateway should be determined based by latency as opposed to being chosen uniformly",
exclusiveOn: [
"--gateway",
],
},
{
name: "--fastmode",
description: "Mostly debug-related option to increase default traffic rate so that you would not need to modify config post init",
},
{
name: "--no-cover",
description: "Disable loop cover traffic and the Poisson rate limiter (for debugging only)",
},
{
name: ["-h", "--help"],
description: "Print help",
},
],
},
{
name: "run",
description: "Run the Nym client with provided configuration client optionally overriding set parameters",
options: [
{
name: "--id",
description: "Id of client we want to create config for",
isRepeatable: true,
args: {
name: "id",
},
},
{
name: "--gateway",
description: "Id of the gateway we want to connect to. If overridden, it is user's responsibility to ensure prior registration happened",
isRepeatable: true,
args: {
name: "gateway",
isOptional: true,
},
},
{
name: "--nyxd-urls",
description: "Comma separated list of rest endpoints of the nyxd validators",
hidden: true,
isRepeatable: true,
args: {
name: "nyxd_urls",
isOptional: true,
},
},
{
name: "--nym-apis",
description: "Comma separated list of rest endpoints of the API validators",
isRepeatable: true,
args: {
name: "nym_apis",
isOptional: true,
},
},
{
name: "--custom-mixnet",
description: "Path to .json file containing custom network specification",
hidden: true,
isRepeatable: true,
args: {
name: "custom_mixnet",
isOptional: true,
template: "filepaths",
},
},
{
name: "--enabled-credentials-mode",
description: "Set this client to work in a enabled credentials mode that would attempt to use gateway with bandwidth credential requirement",
hidden: true,
isRepeatable: true,
args: {
name: "enabled_credentials_mode",
isOptional: true,
suggestions: [
"true",
"false",
],
},
},
{
name: "--disable-socket",
description: "Whether to not start the websocket",
isRepeatable: true,
args: {
name: "disable_socket",
isOptional: true,
suggestions: [
"true",
"false",
],
},
},
{
name: ["-p", "--port"],
description: "Port for the socket to listen on",
isRepeatable: true,
args: {
name: "port",
isOptional: true,
},
},
{
name: "--host",
description: "Ip for the socket (if applicable) to listen for requests",
isRepeatable: true,
args: {
name: "host",
isOptional: true,
},
},
{
name: "--fastmode",
description: "Mostly debug-related option to increase default traffic rate so that you would not need to modify config post init",
},
{
name: "--no-cover",
description: "Disable loop cover traffic and the Poisson rate limiter (for debugging only)",
},
{
name: ["-h", "--help"],
description: "Print help",
},
],
},
{
name: "import-credential",
description: "Import a pre-generated credential",
options: [
{
name: "--id",
description: "Id of client that is going to import the credential",
isRepeatable: true,
args: {
name: "id",
},
},
{
name: "--credential-data",
description: "Explicitly provide the encoded credential data (as base58)",
isRepeatable: true,
args: {
name: "credential_data",
isOptional: true,
},
},
{
name: "--credential-path",
description: "Specifies the path to file containing binary credential data",
isRepeatable: true,
args: {
name: "credential_path",
isOptional: true,
template: "filepaths",
},
},
{
name: "--version",
hidden: true,
isRepeatable: true,
args: {
name: "version",
isOptional: true,
},
},
{
name: ["-h", "--help"],
description: "Print help",
},
],
},
{
name: "list-gateways",
description: "List all registered with gateways",
options: [
{
name: "--id",
description: "Id of client we want to list gateways for",
isRepeatable: true,
args: {
name: "id",
},
},
{
name: ["-o", "--output"],
isRepeatable: true,
args: {
name: "output",
isOptional: true,
suggestions: [
"text",
"json",
],
},
},
{
name: ["-h", "--help"],
description: "Print help",
},
],
},
{
name: "add-gateway",
description: "Add new gateway to this client",
options: [
{
name: "--id",
description: "Id of client we want to add gateway for",
isRepeatable: true,
args: {
name: "id",
},
},
{
name: "--gateway-id",
description: "Explicitly specify id of the gateway to register with. If unspecified, a random gateway will be chosen instead",
isRepeatable: true,
args: {
name: "gateway_id",
isOptional: true,
},
},
{
name: "--nym-apis",
description: "Comma separated list of rest endpoints of the API validators",
isRepeatable: true,
args: {
name: "nym_apis",
isOptional: true,
},
},
{
name: "--custom-mixnet",
description: "Path to .json file containing custom network specification",
hidden: true,
isRepeatable: true,
args: {
name: "custom_mixnet",
isOptional: true,
template: "filepaths",
},
},
{
name: ["-o", "--output"],
isRepeatable: true,
args: {
name: "output",
isOptional: true,
suggestions: [
"text",
"json",
],
},
},
{
name: "--force-tls-gateway",
description: "Specifies whether the client will attempt to enforce tls connection to the desired gateway",
},
{
name: "--latency-based-selection",
description: "Specifies whether the new gateway should be determined based by latency as opposed to being chosen uniformly",
exclusiveOn: [
"--gateway-id",
],
},
{
name: "--set-active",
description: "Specify whether this new gateway should be set as the active one",
},
{
name: ["-h", "--help"],
description: "Print help",
},
],
},
{
name: "switch-gateway",
description: "Change the currently active gateway. Note that you must have already registered with the new gateway!",
options: [
{
name: "--id",
description: "Id of client we want to list gateways for",
isRepeatable: true,
args: {
name: "id",
},
},
{
name: "--gateway-id",
description: "Id of the gateway we want to switch to",
isRepeatable: true,
args: {
name: "gateway_id",
},
},
{
name: ["-h", "--help"],
description: "Print help",
},
],
},
{
name: "show-ticketbooks",
description: "Display information associated with the imported ticketbooks,",
options: [
{
name: "--id",
description: "Id of client that is going to display the ticketbook information",
isRepeatable: true,
args: {
name: "id",
},
},
{
name: ["-o", "--output"],
isRepeatable: true,
args: {
name: "output",
isOptional: true,
suggestions: [
"text",
"json",
],
},
},
{
name: ["-h", "--help"],
description: "Print help",
},
],
},
{
name: "build-info",
description: "Show build information of this binary",
options: [
{
name: ["-o", "--output"],
isRepeatable: true,
args: {
name: "output",
isOptional: true,
suggestions: [
"text",
"json",
],
},
},
{
name: ["-h", "--help"],
description: "Print help",
},
],
},
{
name: "completions",
description: "Generate shell completions",
options: [
{
name: ["-h", "--help"],
description: "Print help",
},
],
args: {
name: "shell",
suggestions: [
"bash",
"elvish",
"fish",
"power-shell",
"zsh",
],
},
},
{
name: "generate-fig-spec",
description: "Generate Fig specification",
options: [
{
name: ["-h", "--help"],
description: "Print help",
},
],
},
{
name: "help",
description: "Print this message or the help of the given subcommand(s)",
subcommands: [
{
name: "init",
description: "Initialise a Nym client. Do this first!",
},
{
name: "run",
description: "Run the Nym client with provided configuration client optionally overriding set parameters",
},
{
name: "import-credential",
description: "Import a pre-generated credential",
},
{
name: "list-gateways",
description: "List all registered with gateways",
},
{
name: "add-gateway",
description: "Add new gateway to this client",
},
{
name: "switch-gateway",
description: "Change the currently active gateway. Note that you must have already registered with the new gateway!",
},
{
name: "show-ticketbooks",
description: "Display information associated with the imported ticketbooks,",
},
{
name: "build-info",
description: "Show build information of this binary",
},
{
name: "completions",
description: "Generate shell completions",
},
{
name: "generate-fig-spec",
description: "Generate Fig specification",
},
{
name: "help",
description: "Print this message or the help of the given subcommand(s)",
},
],
},
],
options: [
{
name: ["-c", "--config-env-file"],
description: "Path pointing to an env file that configures the client",
isRepeatable: true,
args: {
name: "config_env_file",
isOptional: true,
template: "filepaths",
},
},
{
name: "--no-banner",
description: "Flag used for disabling the printed banner in tty",
},
{
name: ["-h", "--help"],
description: "Print help",
},
{
name: ["-V", "--version"],
description: "Print version",
},
],
};
export default completion;
```
@@ -1,15 +0,0 @@
```sh
Import a pre-generated credential
Usage: nym-client import-credential --id <ID> <--credential-data <CREDENTIAL_DATA>|--credential-path <CREDENTIAL_PATH>>
Options:
--id <ID>
Id of client that is going to import the credential
--credential-data <CREDENTIAL_DATA>
Explicitly provide the encoded credential data (as base58)
--credential-path <CREDENTIAL_PATH>
Specifies the path to file containing binary credential data
-h, --help
Print help
```
@@ -1,27 +0,0 @@
```sh
Initialise a Nym client. Do this first!
Usage: nym-client init [OPTIONS] --id <ID>
Options:
--id <ID>
Id of client we want to create config for
--gateway <GATEWAY>
Id of the gateway we are going to connect to
--force-tls-gateway
Specifies whether the client will attempt to enforce tls connection to the desired gateway
--latency-based-selection
Specifies whether the new gateway should be determined based by latency as opposed to being chosen uniformly
--nym-apis <NYM_APIS>
Comma separated list of rest endpoints of the API validators
--disable-socket <DISABLE_SOCKET>
Whether to not start the websocket [possible values: true, false]
-p, --port <PORT>
Port for the socket (if applicable) to listen on in all subsequent runs
--host <HOST>
Ip for the socket (if applicable) to listen for requests
-o, --output <OUTPUT>
[default: text] [possible values: text, json]
-h, --help
Print help
```
@@ -1,10 +0,0 @@
```sh
List all registered with gateways
Usage: nym-client list-gateways [OPTIONS] --id <ID>
Options:
--id <ID> Id of client we want to list gateways for
-o, --output <OUTPUT> [default: text] [possible values: text, json]
-h, --help Print help
```
@@ -1,21 +0,0 @@
```sh
Run the Nym client with provided configuration client optionally overriding set parameters
Usage: nym-client run [OPTIONS] --id <ID>
Options:
--id <ID>
Id of client we want to create config for
--gateway <GATEWAY>
Id of the gateway we want to connect to. If overridden, it is user's responsibility to ensure prior registration happened
--nym-apis <NYM_APIS>
Comma separated list of rest endpoints of the API validators
--disable-socket <DISABLE_SOCKET>
Whether to not start the websocket [possible values: true, false]
-p, --port <PORT>
Port for the socket to listen on
--host <HOST>
Ip for the socket (if applicable) to listen for requests
-h, --help
Print help
```
@@ -1,10 +0,0 @@
```sh
Change the currently active gateway. Note that you must have already registered with the new gateway!
Usage: nym-client switch-gateway --id <ID> --gateway-id <GATEWAY_ID>
Options:
--id <ID> Id of client we want to list gateways for
--gateway-id <GATEWAY_ID> Id of the gateway we want to switch to
-h, --help Print help
```
@@ -1,12 +0,0 @@
```sh
Show bonding information of this node depending on its currently selected mode
Usage: nym-node bonding-information [OPTIONS]
Options:
--id <ID> Id of the nym-node to use [env: NYMNODE_ID=] [default: default-nym-node]
--config-file <CONFIG_FILE> Path to a configuration file of this node [env: NYMNODE_CONFIG=]
--mode <MODE> [env: NYMNODE_MODE=] [possible values: mixnode, entry-gateway, exit-gateway]
-o, --output <OUTPUT> Specify the output format of the bonding information (`text` or `json`) [default: text] [possible values: text, json]
-h, --help Print help
```
@@ -1,3 +0,0 @@
```sh
2024-10-22T13:00:32.542213Z ERROR nym-node/src/config/upgrade_helpers.rs:16: Failed to finish upgrade - failed to load config file using path '/home/m/.nym/nym-nodes/default-nym-node/config/config.toml'. detailed message: No such file or directory (os error 2)
```
@@ -1,9 +0,0 @@
```sh
Show build information of this binary
Usage: nym-node build-info [OPTIONS]
Options:
-o, --output <OUTPUT> [default: text] [possible values: text, json]
-h, --help Print help
```
@@ -1,13 +0,0 @@
```sh
Binary Name: nym-node
Build Timestamp: 2024-10-09T13:56:14.428750844Z
Build Version: 1.1.6
Commit SHA: fac373c1db4fa5389ba61de7943c77023467bccb
Commit Date: 2024-10-09T14:59:40.000000000+02:00
Commit Branch: max/new-docs-framework
rustc Version: 1.80.0
rustc Channel: stable
cargo Profile: release
```
@@ -1,237 +0,0 @@
# `nym-node` Binary Commands (Autogenerated)
These docs are autogenerated by the [`autodocs`](https://github.com/nymtech/nym/tree/max/new-docs-framework/documentation/autodoc) script.
```sh
Usage: nym-node [OPTIONS] <COMMAND>
Commands:
build-info Show build information of this binary
bonding-information Show bonding information of this node depending on its currently selected mode
node-details Show details of this node
migrate Attempt to migrate an existing mixnode or gateway into a nym-node
run Start this nym-node
sign Use identity key of this node to sign provided message
help Print this message or the help of the given subcommand(s)
Options:
-c, --config-env-file <CONFIG_ENV_FILE>
Path pointing to an env file that configures the nym-node and overrides any preconfigured values [env: NYMNODE_CONFIG_ENV_FILE_ARG=]
--no-banner
Flag used for disabling the printed banner in tty [env: NYMNODE_NO_BANNER=]
-h, --help
Print help
-V, --version
Print version
```
### `build-info`
```sh
Show build information of this binary
Usage: nym-node build-info [OPTIONS]
Options:
-o, --output <OUTPUT> [default: text] [possible values: text, json]
-h, --help Print help
```
### `bonding-information`
```sh
Show bonding information of this node depending on its currently selected mode
Usage: nym-node bonding-information [OPTIONS]
Options:
--id <ID> Id of the nym-node to use [env: NYMNODE_ID=] [default: default-nym-node]
--config-file <CONFIG_FILE> Path to a configuration file of this node [env: NYMNODE_CONFIG=]
--mode <MODE> [env: NYMNODE_MODE=] [possible values: mixnode, entry-gateway, exit-gateway]
-o, --output <OUTPUT> Specify the output format of the bonding information (`text` or `json`) [default: text] [possible values: text, json]
-h, --help Print help
```
### `node-details`
```sh
Show details of this node
Usage: nym-node node-details [OPTIONS]
Options:
--id <ID> Id of the nym-node to use [env: NYMNODE_ID=] [default: default-nym-node]
--config-file <CONFIG_FILE> Path to a configuration file of this node [env: NYMNODE_CONFIG=]
-o, --output <OUTPUT> Specify the output format of the node details (`text` or `json`) [default: text] [possible values: text, json]
-h, --help Print help
```
### `migrate`
```sh
Attempt to migrate an existing mixnode or gateway into a nym-node
Usage: nym-node migrate [OPTIONS] <--id <ID>|--config-file <CONFIG_FILE>> <NODE_TYPE>
Arguments:
<NODE_TYPE> Type of node (mixnode or gateway) to migrate into a nym-node [possible values: mixnode, gateway]
Options:
--id <ID>
Id of the node that's going to get migrated
--config-file <CONFIG_FILE>
Path to a configuration file of the node that's going to get migrated
--preserve-id
Specify whether to preserve id of the imported node
--public-ips <PUBLIC_IPS>
Comma separated list of public ip addresses that will be announced to the nym-api and subsequently to the clients. In nearly all circumstances, it's going to be identical to the address you're going to use for bonding [env: NYMNODE_PUBLIC_IPS=]
--hostname <HOSTNAME>
Optional hostname associated with this gateway that will be announced to the nym-api and subsequently to the clients [env: NYMNODE_HOSTNAME=]
--location <LOCATION>
Optional **physical** location of this node's server. Either full country name (e.g. 'Poland'), two-letter alpha2 (e.g. 'PL'), three-letter alpha3 (e.g. 'POL') or three-digit numeric-3 (e.g. '616') can be provided [env: NYMNODE_LOCATION=]
--http-bind-address <HTTP_BIND_ADDRESS>
Socket address this node will use for binding its http API. default: `0.0.0.0:8080` [env: NYMNODE_HTTP_BIND_ADDRESS=]
--landing-page-assets-path <LANDING_PAGE_ASSETS_PATH>
Path to assets directory of custom landing page of this node [env: NYMNODE_HTTP_LANDING_ASSETS=]
--http-access-token <HTTP_ACCESS_TOKEN>
An optional bearer token for accessing certain http endpoints. Currently only used for prometheus metrics [env: NYMNODE_HTTP_ACCESS_TOKEN=]
--expose-system-info <EXPOSE_SYSTEM_INFO>
Specify whether basic system information should be exposed. default: true [env: NYMNODE_HTTP_EXPOSE_SYSTEM_INFO=] [possible values: true, false]
--expose-system-hardware <EXPOSE_SYSTEM_HARDWARE>
Specify whether basic system hardware information should be exposed. default: true [env: NYMNODE_HTTP_EXPOSE_SYSTEM_HARDWARE=] [possible values: true, false]
--expose-crypto-hardware <EXPOSE_CRYPTO_HARDWARE>
Specify whether detailed system crypto hardware information should be exposed. default: true [env: NYMNODE_HTTP_EXPOSE_CRYPTO_HARDWARE=] [possible values: true, false]
--mixnet-bind-address <MIXNET_BIND_ADDRESS>
Address this node will bind to for listening for mixnet packets default: `0.0.0.0:1789` [env: NYMNODE_MIXNET_BIND_ADDRESS=]
--mixnet-announce-port <MIXNET_ANNOUNCE_PORT>
If applicable, custom port announced in the self-described API that other clients and nodes will use. Useful when the node is behind a proxy [env: NYMNODE_MIXNET_ANNOUNCE_PORT=]
--nym-api-urls <NYM_API_URLS>
Addresses to nym APIs from which the node gets the view of the network [env: NYMNODE_NYM_APIS=]
--nyxd-urls <NYXD_URLS>
Addresses to nyxd chain endpoint which the node will use for chain interactions [env: NYMNODE_NYXD=]
--wireguard-enabled <WIREGUARD_ENABLED>
Specifies whether the wireguard service is enabled on this node [env: NYMNODE_WG_ENABLED=] [possible values: true, false]
--wireguard-bind-address <WIREGUARD_BIND_ADDRESS>
Socket address this node will use for binding its wireguard interface. default: `0.0.0.0:51822` [env: NYMNODE_WG_BIND_ADDRESS=]
--wireguard-private-ip <WIREGUARD_PRIVATE_IP>
Private IP address of the wireguard gateway. default: `10.1.0.1` [env: NYMNODE_WG_IP=]
--wireguard-announced-port <WIREGUARD_ANNOUNCED_PORT>
Port announced to external clients wishing to connect to the wireguard interface. Useful in the instances where the node is behind a proxy [env: NYMNODE_WG_ANNOUNCED_PORT=]
--wireguard-private-network-prefix <WIREGUARD_PRIVATE_NETWORK_PREFIX>
The prefix denoting the maximum number of the clients that can be connected via Wireguard. The maximum value for IPv4 is 32 and for IPv6 is 128 [env: NYMNODE_WG_PRIVATE_NETWORK_PREFIX=]
--verloc-bind-address <VERLOC_BIND_ADDRESS>
Socket address this node will use for binding its verloc API. default: `0.0.0.0:1790` [env: NYMNODE_VERLOC_BIND_ADDRESS=]
--verloc-announce-port <VERLOC_ANNOUNCE_PORT>
If applicable, custom port announced in the self-described API that other clients and nodes will use. Useful when the node is behind a proxy [env: NYMNODE_VERLOC_ANNOUNCE_PORT=]
--entry-bind-address <ENTRY_BIND_ADDRESS>
Socket address this node will use for binding its client websocket API. default: `0.0.0.0:9000` [env: NYMNODE_ENTRY_BIND_ADDRESS=]
--announce-ws-port <ANNOUNCE_WS_PORT>
Custom announced port for listening for websocket client traffic. If unspecified, the value from the `bind_address` will be used instead [env: NYMNODE_ENTRY_ANNOUNCE_WS_PORT=]
--announce-wss-port <ANNOUNCE_WSS_PORT>
If applicable, announced port for listening for secure websocket client traffic [env: NYMNODE_ENTRY_ANNOUNCE_WSS_PORT=]
--enforce-zk-nyms <ENFORCE_ZK_NYMS>
Indicates whether this gateway is accepting only coconut credentials for accessing the mixnet or if it also accepts non-paying clients [env: NYMNODE_ENFORCE_ZK_NYMS=] [possible values: true, false]
--mnemonic <MNEMONIC>
Custom cosmos wallet mnemonic used for zk-nym redemption. If no value is provided, a fresh mnemonic is going to be generated [env: NYMNODE_MNEMONIC=]
--upstream-exit-policy-url <UPSTREAM_EXIT_POLICY_URL>
Specifies the url for an upstream source of the exit policy used by this node [env: NYMNODE_UPSTREAM_EXIT_POLICY=]
--open-proxy <OPEN_PROXY>
Specifies whether this exit node should run in 'open-proxy' mode and thus would attempt to resolve **ANY** request it receives [env: NYMNODE_OPEN_PROXY=] [possible values: true, false]
-h, --help
Print help
```
### `run`
```sh
Start this nym-node
Usage: nym-node run [OPTIONS]
Options:
--id <ID>
Id of the nym-node to use [env: NYMNODE_ID=] [default: default-nym-node]
--config-file <CONFIG_FILE>
Path to a configuration file of this node [env: NYMNODE_CONFIG=]
--accept-operator-terms-and-conditions
Explicitly specify whether you agree with the terms and conditions of a nym node operator as defined at <https://nymtech.net/terms-and-conditions/operators/v1.0.0> [env: NYMNODE_ACCEPT_OPERATOR_TERMS=]
--deny-init
Forbid a new node from being initialised if configuration file for the provided specification doesn't already exist [env: NYMNODE_DENY_INIT=]
--init-only
If this is a brand new nym-node, specify whether it should only be initialised without actually running the subprocesses [env: NYMNODE_INIT_ONLY=]
--local
Flag specifying this node will be running in a local setting [env: NYMNODE_LOCAL=]
--mode <MODE>
Specifies the current mode of this nym-node [env: NYMNODE_MODE=] [possible values: mixnode, entry-gateway, exit-gateway]
-w, --write-changes
If this node has been initialised before, specify whether to write any new changes to the config file [env: NYMNODE_WRITE_CONFIG_CHANGES=]
--bonding-information-output <BONDING_INFORMATION_OUTPUT>
Specify output file for bonding information of this nym-node, i.e. its encoded keys. NOTE: the required bonding information is still a subject to change and this argument should be treated only as a preview of future features [env: NYMNODE_BONDING_INFORMATION_OUTPUT=]
-o, --output <OUTPUT>
Specify the output format of the bonding information (`text` or `json`) [env: NYMNODE_OUTPUT=] [default: text] [possible values: text, json]
--public-ips <PUBLIC_IPS>
Comma separated list of public ip addresses that will be announced to the nym-api and subsequently to the clients. In nearly all circumstances, it's going to be identical to the address you're going to use for bonding [env: NYMNODE_PUBLIC_IPS=]
--hostname <HOSTNAME>
Optional hostname associated with this gateway that will be announced to the nym-api and subsequently to the clients [env: NYMNODE_HOSTNAME=]
--location <LOCATION>
Optional **physical** location of this node's server. Either full country name (e.g. 'Poland'), two-letter alpha2 (e.g. 'PL'), three-letter alpha3 (e.g. 'POL') or three-digit numeric-3 (e.g. '616') can be provided [env: NYMNODE_LOCATION=]
--http-bind-address <HTTP_BIND_ADDRESS>
Socket address this node will use for binding its http API. default: `0.0.0.0:8080` [env: NYMNODE_HTTP_BIND_ADDRESS=]
--landing-page-assets-path <LANDING_PAGE_ASSETS_PATH>
Path to assets directory of custom landing page of this node [env: NYMNODE_HTTP_LANDING_ASSETS=]
--http-access-token <HTTP_ACCESS_TOKEN>
An optional bearer token for accessing certain http endpoints. Currently only used for prometheus metrics [env: NYMNODE_HTTP_ACCESS_TOKEN=]
--expose-system-info <EXPOSE_SYSTEM_INFO>
Specify whether basic system information should be exposed. default: true [env: NYMNODE_HTTP_EXPOSE_SYSTEM_INFO=] [possible values: true, false]
--expose-system-hardware <EXPOSE_SYSTEM_HARDWARE>
Specify whether basic system hardware information should be exposed. default: true [env: NYMNODE_HTTP_EXPOSE_SYSTEM_HARDWARE=] [possible values: true, false]
--expose-crypto-hardware <EXPOSE_CRYPTO_HARDWARE>
Specify whether detailed system crypto hardware information should be exposed. default: true [env: NYMNODE_HTTP_EXPOSE_CRYPTO_HARDWARE=] [possible values: true, false]
--mixnet-bind-address <MIXNET_BIND_ADDRESS>
Address this node will bind to for listening for mixnet packets default: `0.0.0.0:1789` [env: NYMNODE_MIXNET_BIND_ADDRESS=]
--mixnet-announce-port <MIXNET_ANNOUNCE_PORT>
If applicable, custom port announced in the self-described API that other clients and nodes will use. Useful when the node is behind a proxy [env: NYMNODE_MIXNET_ANNOUNCE_PORT=]
--nym-api-urls <NYM_API_URLS>
Addresses to nym APIs from which the node gets the view of the network [env: NYMNODE_NYM_APIS=]
--nyxd-urls <NYXD_URLS>
Addresses to nyxd chain endpoint which the node will use for chain interactions [env: NYMNODE_NYXD=]
--wireguard-enabled <WIREGUARD_ENABLED>
Specifies whether the wireguard service is enabled on this node [env: NYMNODE_WG_ENABLED=] [possible values: true, false]
--wireguard-bind-address <WIREGUARD_BIND_ADDRESS>
Socket address this node will use for binding its wireguard interface. default: `0.0.0.0:51822` [env: NYMNODE_WG_BIND_ADDRESS=]
--wireguard-private-ip <WIREGUARD_PRIVATE_IP>
Private IP address of the wireguard gateway. default: `10.1.0.1` [env: NYMNODE_WG_IP=]
--wireguard-announced-port <WIREGUARD_ANNOUNCED_PORT>
Port announced to external clients wishing to connect to the wireguard interface. Useful in the instances where the node is behind a proxy [env: NYMNODE_WG_ANNOUNCED_PORT=]
--wireguard-private-network-prefix <WIREGUARD_PRIVATE_NETWORK_PREFIX>
The prefix denoting the maximum number of the clients that can be connected via Wireguard. The maximum value for IPv4 is 32 and for IPv6 is 128 [env: NYMNODE_WG_PRIVATE_NETWORK_PREFIX=]
--verloc-bind-address <VERLOC_BIND_ADDRESS>
Socket address this node will use for binding its verloc API. default: `0.0.0.0:1790` [env: NYMNODE_VERLOC_BIND_ADDRESS=]
--verloc-announce-port <VERLOC_ANNOUNCE_PORT>
If applicable, custom port announced in the self-described API that other clients and nodes will use. Useful when the node is behind a proxy [env: NYMNODE_VERLOC_ANNOUNCE_PORT=]
--entry-bind-address <ENTRY_BIND_ADDRESS>
Socket address this node will use for binding its client websocket API. default: `0.0.0.0:9000` [env: NYMNODE_ENTRY_BIND_ADDRESS=]
--announce-ws-port <ANNOUNCE_WS_PORT>
Custom announced port for listening for websocket client traffic. If unspecified, the value from the `bind_address` will be used instead [env: NYMNODE_ENTRY_ANNOUNCE_WS_PORT=]
--announce-wss-port <ANNOUNCE_WSS_PORT>
If applicable, announced port for listening for secure websocket client traffic [env: NYMNODE_ENTRY_ANNOUNCE_WSS_PORT=]
--enforce-zk-nyms <ENFORCE_ZK_NYMS>
Indicates whether this gateway is accepting only coconut credentials for accessing the mixnet or if it also accepts non-paying clients [env: NYMNODE_ENFORCE_ZK_NYMS=] [possible values: true, false]
--mnemonic <MNEMONIC>
Custom cosmos wallet mnemonic used for zk-nym redemption. If no value is provided, a fresh mnemonic is going to be generated [env: NYMNODE_MNEMONIC=]
--upstream-exit-policy-url <UPSTREAM_EXIT_POLICY_URL>
Specifies the url for an upstream source of the exit policy used by this node [env: NYMNODE_UPSTREAM_EXIT_POLICY=]
--open-proxy <OPEN_PROXY>
Specifies whether this exit node should run in 'open-proxy' mode and thus would attempt to resolve **ANY** request it receives [env: NYMNODE_OPEN_PROXY=] [possible values: true, false]
-h, --help
Print help
```
### `sign`
```sh
Use identity key of this node to sign provided message
Usage: nym-node sign [OPTIONS] <--text <TEXT>|--contract-msg <CONTRACT_MSG>>
Options:
--id <ID> Id of the nym-node to use [env: NYMNODE_ID=] [default: default-nym-node]
--config-file <CONFIG_FILE> Path to a configuration file of this node [env: NYMNODE_CONFIG=]
--text <TEXT> Signs an arbitrary piece of text with your identity key
--contract-msg <CONTRACT_MSG> Signs a transaction-specific payload, that is going to be sent to the smart contract, with your identity key
-o, --output <OUTPUT> [default: text] [possible values: text, json]
-h, --help Print help
```
@@ -1,68 +0,0 @@
```sh
Attempt to migrate an existing mixnode or gateway into a nym-node
Usage: nym-node migrate [OPTIONS] <--id <ID>|--config-file <CONFIG_FILE>> <NODE_TYPE>
Arguments:
<NODE_TYPE> Type of node (mixnode or gateway) to migrate into a nym-node [possible values: mixnode, gateway]
Options:
--id <ID>
Id of the node that's going to get migrated
--config-file <CONFIG_FILE>
Path to a configuration file of the node that's going to get migrated
--preserve-id
Specify whether to preserve id of the imported node
--public-ips <PUBLIC_IPS>
Comma separated list of public ip addresses that will be announced to the nym-api and subsequently to the clients. In nearly all circumstances, it's going to be identical to the address you're going to use for bonding [env: NYMNODE_PUBLIC_IPS=]
--hostname <HOSTNAME>
Optional hostname associated with this gateway that will be announced to the nym-api and subsequently to the clients [env: NYMNODE_HOSTNAME=]
--location <LOCATION>
Optional **physical** location of this node's server. Either full country name (e.g. 'Poland'), two-letter alpha2 (e.g. 'PL'), three-letter alpha3 (e.g. 'POL') or three-digit numeric-3 (e.g. '616') can be provided [env: NYMNODE_LOCATION=]
--http-bind-address <HTTP_BIND_ADDRESS>
Socket address this node will use for binding its http API. default: `0.0.0.0:8080` [env: NYMNODE_HTTP_BIND_ADDRESS=]
--landing-page-assets-path <LANDING_PAGE_ASSETS_PATH>
Path to assets directory of custom landing page of this node [env: NYMNODE_HTTP_LANDING_ASSETS=]
--http-access-token <HTTP_ACCESS_TOKEN>
An optional bearer token for accessing certain http endpoints. Currently only used for prometheus metrics [env: NYMNODE_HTTP_ACCESS_TOKEN=]
--expose-system-info <EXPOSE_SYSTEM_INFO>
Specify whether basic system information should be exposed. default: true [env: NYMNODE_HTTP_EXPOSE_SYSTEM_INFO=] [possible values: true, false]
--expose-system-hardware <EXPOSE_SYSTEM_HARDWARE>
Specify whether basic system hardware information should be exposed. default: true [env: NYMNODE_HTTP_EXPOSE_SYSTEM_HARDWARE=] [possible values: true, false]
--expose-crypto-hardware <EXPOSE_CRYPTO_HARDWARE>
Specify whether detailed system crypto hardware information should be exposed. default: true [env: NYMNODE_HTTP_EXPOSE_CRYPTO_HARDWARE=] [possible values: true, false]
--mixnet-bind-address <MIXNET_BIND_ADDRESS>
Address this node will bind to for listening for mixnet packets default: `0.0.0.0:1789` [env: NYMNODE_MIXNET_BIND_ADDRESS=]
--nym-api-urls <NYM_API_URLS>
Addresses to nym APIs from which the node gets the view of the network [env: NYMNODE_NYM_APIS=]
--nyxd-urls <NYXD_URLS>
Addresses to nyxd chain endpoint which the node will use for chain interactions [env: NYMNODE_NYXD=]
--wireguard-enabled <WIREGUARD_ENABLED>
Specifies whether the wireguard service is enabled on this node [env: NYMNODE_WG_ENABLED=] [possible values: true, false]
--wireguard-bind-address <WIREGUARD_BIND_ADDRESS>
Socket address this node will use for binding its wireguard interface. default: `0.0.0.0:51822` [env: NYMNODE_WG_BIND_ADDRESS=]
--wireguard-private-ip <WIREGUARD_PRIVATE_IP>
Private IP address of the wireguard gateway. default: `10.1.0.1` [env: NYMNODE_WG_IP=]
--wireguard-announced-port <WIREGUARD_ANNOUNCED_PORT>
Port announced to external clients wishing to connect to the wireguard interface. Useful in the instances where the node is behind a proxy [env: NYMNODE_WG_ANNOUNCED_PORT=]
--wireguard-private-network-prefix <WIREGUARD_PRIVATE_NETWORK_PREFIX>
The prefix denoting the maximum number of the clients that can be connected via Wireguard. The maximum value for IPv4 is 32 and for IPv6 is 128 [env: NYMNODE_WG_PRIVATE_NETWORK_PREFIX=]
--verloc-bind-address <VERLOC_BIND_ADDRESS>
Socket address this node will use for binding its verloc API. default: `0.0.0.0:1790` [env: NYMNODE_VERLOC_BIND_ADDRESS=]
--entry-bind-address <ENTRY_BIND_ADDRESS>
Socket address this node will use for binding its client websocket API. default: `0.0.0.0:9000` [env: NYMNODE_ENTRY_BIND_ADDRESS=]
--announce-ws-port <ANNOUNCE_WS_PORT>
Custom announced port for listening for websocket client traffic. If unspecified, the value from the `bind_address` will be used instead [env: NYMNODE_ENTRY_ANNOUNCE_WS_PORT=]
--announce-wss-port <ANNOUNCE_WSS_PORT>
If applicable, announced port for listening for secure websocket client traffic [env: NYMNODE_ENTRY_ANNOUNCE_WSS_PORT=]
--enforce-zk-nyms <ENFORCE_ZK_NYMS>
Indicates whether this gateway is accepting only coconut credentials for accessing the mixnet or if it also accepts non-paying clients [env: NYMNODE_ENFORCE_ZK_NYMS=] [possible values: true, false]
--mnemonic <MNEMONIC>
Custom cosmos wallet mnemonic used for zk-nym redemption. If no value is provided, a fresh mnemonic is going to be generated [env: NYMNODE_MNEMONIC=]
--upstream-exit-policy-url <UPSTREAM_EXIT_POLICY_URL>
Specifies the url for an upstream source of the exit policy used by this node [env: NYMNODE_UPSTREAM_EXIT_POLICY=]
--open-proxy <OPEN_PROXY>
Specifies whether this exit node should run in 'open-proxy' mode and thus would attempt to resolve **ANY** request it receives [env: NYMNODE_OPEN_PROXY=] [possible values: true, false]
-h, --help
Print help
```
@@ -1,11 +0,0 @@
```sh
Show details of this node
Usage: nym-node node-details [OPTIONS]
Options:
--id <ID> Id of the nym-node to use [env: NYMNODE_ID=] [default: default-nym-node]
--config-file <CONFIG_FILE> Path to a configuration file of this node [env: NYMNODE_CONFIG=]
-o, --output <OUTPUT> Specify the output format of the node details (`text` or `json`) [default: text] [possible values: text, json]
-h, --help Print help
```
@@ -1,3 +0,0 @@
```sh
2024-10-22T13:00:32.562750Z ERROR nym-node/src/config/upgrade_helpers.rs:16: Failed to finish upgrade - failed to load config file using path '/home/m/.nym/nym-nodes/default-nym-node/config/config.toml'. detailed message: No such file or directory (os error 2)
```
@@ -1,13 +0,0 @@
```sh
Use identity key of this node to sign provided message
Usage: nym-node sign [OPTIONS] <--text <TEXT>|--contract-msg <CONTRACT_MSG>>
Options:
--id <ID> Id of the nym-node to use [env: NYMNODE_ID=] [default: default-nym-node]
--config-file <CONFIG_FILE> Path to a configuration file of this node [env: NYMNODE_CONFIG=]
--text <TEXT> Signs an arbitrary piece of text with your identity key
--contract-msg <CONTRACT_MSG> Signs a transaction-specific payload, that is going to be sent to the smart contract, with your identity key
-o, --output <OUTPUT> [default: text] [possible values: text, json]
-h, --help Print help
```
@@ -1,15 +0,0 @@
```sh
Add new gateway to this client
Usage: nym-socks5-client add-gateway [OPTIONS] --id <ID>
Options:
--id <ID> Id of client we want to add gateway for
--gateway-id <GATEWAY_ID> Explicitly specify id of the gateway to register with. If unspecified, a random gateway will be chosen instead
--force-tls-gateway Specifies whether the client will attempt to enforce tls connection to the desired gateway
--latency-based-selection Specifies whether the new gateway should be determined based by latency as opposed to being chosen uniformly
--set-active Specify whether this new gateway should be set as the active one
--nym-apis <NYM_APIS> Comma separated list of rest endpoints of the API validators
-o, --output <OUTPUT> [default: text] [possible values: text, json]
-h, --help Print help
```
@@ -1,9 +0,0 @@
```sh
Show build information of this binary
Usage: nym-socks5-client build-info [OPTIONS]
Options:
-o, --output <OUTPUT> [default: text] [possible values: text, json]
-h, --help Print help
```
@@ -1,13 +0,0 @@
```sh
Binary Name: nym-socks5-client
Build Timestamp: 2024-10-09T13:56:14.428750844Z
Build Version: 1.1.39
Commit SHA: fac373c1db4fa5389ba61de7943c77023467bccb
Commit Date: 2024-10-09T14:59:40.000000000+02:00
Commit Branch: max/new-docs-framework
rustc Version: 1.80.0
rustc Channel: stable
cargo Profile: release
```
@@ -1,11 +0,0 @@
```sh
Generate shell completions
Usage: nym-socks5-client completions <SHELL>
Arguments:
<SHELL> [possible values: bash, elvish, fish, power-shell, zsh]
Options:
-h, --help Print help
```
@@ -1,8 +0,0 @@
```sh
Generate Fig specification
Usage: nym-socks5-client generate-fig-spec
Options:
-h, --help Print help
```
@@ -1,619 +0,0 @@
```sh
const completion: Fig.Spec = {
name: "nym-socks5-client",
description: "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address",
subcommands: [
{
name: "init",
description: "Initialise a Nym client. Do this first!",
options: [
{
name: "--id",
description: "Id of client we want to create config for",
isRepeatable: true,
args: {
name: "id",
},
},
{
name: "--gateway",
description: "Id of the gateway we are going to connect to",
isRepeatable: true,
args: {
name: "gateway",
isOptional: true,
},
},
{
name: "--nyxd-urls",
description: "Comma separated list of rest endpoints of the nyxd validators",
hidden: true,
isRepeatable: true,
args: {
name: "nyxd_urls",
isOptional: true,
},
},
{
name: "--nym-apis",
description: "Comma separated list of rest endpoints of the API validators",
isRepeatable: true,
args: {
name: "nym_apis",
isOptional: true,
},
},
{
name: "--custom-mixnet",
description: "Path to .json file containing custom network specification",
hidden: true,
isRepeatable: true,
args: {
name: "custom_mixnet",
isOptional: true,
template: "filepaths",
},
},
{
name: "--enabled-credentials-mode",
description: "Set this client to work in a enabled credentials mode that would attempt to use gateway with bandwidth credential requirement",
hidden: true,
isRepeatable: true,
args: {
name: "enabled_credentials_mode",
isOptional: true,
suggestions: [
"true",
"false",
],
},
},
{
name: "--provider",
description: "Address of the socks5 provider to send messages to",
isRepeatable: true,
args: {
name: "provider",
},
},
{
name: "--use-reply-surbs",
description: "Specifies whether this client is going to use an anonymous sender tag for communication with the service provider. While this is going to hide its actual address information, it will make the actual communication slower and consume nearly double the bandwidth as it will require sending reply SURBs",
isRepeatable: true,
args: {
name: "use_reply_surbs",
isOptional: true,
suggestions: [
"true",
"false",
],
},
},
{
name: ["-p", "--port"],
description: "Port for the socket to listen on in all subsequent runs",
isRepeatable: true,
args: {
name: "port",
isOptional: true,
},
},
{
name: "--host",
description: "The custom host on which the socks5 client will be listening for requests",
isRepeatable: true,
args: {
name: "host",
isOptional: true,
},
},
{
name: ["-o", "--output"],
isRepeatable: true,
args: {
name: "output",
isOptional: true,
suggestions: [
"text",
"json",
],
},
},
{
name: "--force-tls-gateway",
description: "Specifies whether the client will attempt to enforce tls connection to the desired gateway",
},
{
name: "--latency-based-selection",
description: "Specifies whether the new gateway should be determined based by latency as opposed to being chosen uniformly",
exclusiveOn: [
"--gateway",
],
},
{
name: "--fastmode",
description: "Mostly debug-related option to increase default traffic rate so that you would not need to modify config post init",
},
{
name: "--no-cover",
description: "Disable loop cover traffic and the Poisson rate limiter (for debugging only)",
},
{
name: ["-h", "--help"],
description: "Print help (see more with '--help')",
},
],
},
{
name: "run",
description: "Run the Nym client with provided configuration client optionally overriding set parameters",
options: [
{
name: "--id",
description: "Id of client we want to create config for",
isRepeatable: true,
args: {
name: "id",
},
},
{
name: "--gateway",
description: "Id of the gateway we want to connect to. If overridden, it is user's responsibility to ensure prior registration happened",
isRepeatable: true,
args: {
name: "gateway",
isOptional: true,
},
},
{
name: "--nyxd-urls",
description: "Comma separated list of rest endpoints of the nyxd validators",
hidden: true,
isRepeatable: true,
args: {
name: "nyxd_urls",
isOptional: true,
},
},
{
name: "--nym-apis",
description: "Comma separated list of rest endpoints of the API validators",
isRepeatable: true,
args: {
name: "nym_apis",
isOptional: true,
},
},
{
name: "--custom-mixnet",
description: "Path to .json file containing custom network specification",
hidden: true,
isRepeatable: true,
args: {
name: "custom_mixnet",
isOptional: true,
template: "filepaths",
},
},
{
name: "--enabled-credentials-mode",
description: "Set this client to work in a enabled credentials mode that would attempt to use gateway with bandwidth credential requirement",
hidden: true,
isRepeatable: true,
args: {
name: "enabled_credentials_mode",
isOptional: true,
suggestions: [
"true",
"false",
],
},
},
{
name: "--use-anonymous-replies",
description: "Specifies whether this client is going to use an anonymous sender tag for communication with the service provider. While this is going to hide its actual address information, it will make the actual communication slower and consume nearly double the bandwidth as it will require sending reply SURBs",
isRepeatable: true,
args: {
name: "use_anonymous_replies",
isOptional: true,
suggestions: [
"true",
"false",
],
},
},
{
name: "--provider",
description: "Address of the socks5 provider to send messages to",
isRepeatable: true,
args: {
name: "provider",
isOptional: true,
},
},
{
name: ["-p", "--port"],
description: "Port for the socket to listen on",
isRepeatable: true,
args: {
name: "port",
isOptional: true,
},
},
{
name: "--host",
description: "The custom host on which the socks5 client will be listening for requests",
isRepeatable: true,
args: {
name: "host",
isOptional: true,
},
},
{
name: "--geo-routing",
description: "Set geo-aware mixnode selection when sending mixnet traffic, for experiments only",
hidden: true,
isRepeatable: true,
args: {
name: "geo_routing",
isOptional: true,
},
},
{
name: "--fastmode",
description: "Mostly debug-related option to increase default traffic rate so that you would not need to modify config post init",
},
{
name: "--no-cover",
description: "Disable loop cover traffic and the Poisson rate limiter (for debugging only)",
},
{
name: "--medium-toggle",
description: "Enable medium mixnet traffic, for experiments only. This includes things like disabling cover traffic, no per hop delays, etc",
},
{
name: "--outfox",
},
{
name: ["-h", "--help"],
description: "Print help (see more with '--help')",
},
],
},
{
name: "import-credential",
description: "Import a pre-generated credential",
options: [
{
name: "--id",
description: "Id of client that is going to import the credential",
isRepeatable: true,
args: {
name: "id",
},
},
{
name: "--credential-data",
description: "Explicitly provide the encoded credential data (as base58)",
isRepeatable: true,
args: {
name: "credential_data",
isOptional: true,
},
},
{
name: "--credential-path",
description: "Specifies the path to file containing binary credential data",
isRepeatable: true,
args: {
name: "credential_path",
isOptional: true,
template: "filepaths",
},
},
{
name: "--version",
hidden: true,
isRepeatable: true,
args: {
name: "version",
isOptional: true,
},
},
{
name: ["-h", "--help"],
description: "Print help",
},
],
},
{
name: "list-gateways",
description: "List all registered with gateways",
options: [
{
name: "--id",
description: "Id of client we want to list gateways for",
isRepeatable: true,
args: {
name: "id",
},
},
{
name: ["-o", "--output"],
isRepeatable: true,
args: {
name: "output",
isOptional: true,
suggestions: [
"text",
"json",
],
},
},
{
name: ["-h", "--help"],
description: "Print help",
},
],
},
{
name: "add-gateway",
description: "Add new gateway to this client",
options: [
{
name: "--id",
description: "Id of client we want to add gateway for",
isRepeatable: true,
args: {
name: "id",
},
},
{
name: "--gateway-id",
description: "Explicitly specify id of the gateway to register with. If unspecified, a random gateway will be chosen instead",
isRepeatable: true,
args: {
name: "gateway_id",
isOptional: true,
},
},
{
name: "--nym-apis",
description: "Comma separated list of rest endpoints of the API validators",
isRepeatable: true,
args: {
name: "nym_apis",
isOptional: true,
},
},
{
name: "--custom-mixnet",
description: "Path to .json file containing custom network specification",
hidden: true,
isRepeatable: true,
args: {
name: "custom_mixnet",
isOptional: true,
template: "filepaths",
},
},
{
name: ["-o", "--output"],
isRepeatable: true,
args: {
name: "output",
isOptional: true,
suggestions: [
"text",
"json",
],
},
},
{
name: "--force-tls-gateway",
description: "Specifies whether the client will attempt to enforce tls connection to the desired gateway",
},
{
name: "--latency-based-selection",
description: "Specifies whether the new gateway should be determined based by latency as opposed to being chosen uniformly",
exclusiveOn: [
"--gateway-id",
],
},
{
name: "--set-active",
description: "Specify whether this new gateway should be set as the active one",
},
{
name: ["-h", "--help"],
description: "Print help",
},
],
},
{
name: "switch-gateway",
description: "Change the currently active gateway. Note that you must have already registered with the new gateway!",
options: [
{
name: "--id",
description: "Id of client we want to list gateways for",
isRepeatable: true,
args: {
name: "id",
},
},
{
name: "--gateway-id",
description: "Id of the gateway we want to switch to",
isRepeatable: true,
args: {
name: "gateway_id",
},
},
{
name: ["-h", "--help"],
description: "Print help",
},
],
},
{
name: "show-ticketbooks",
description: "Display information associated with the imported ticketbooks,",
options: [
{
name: "--id",
description: "Id of client that is going to display the ticketbook information",
isRepeatable: true,
args: {
name: "id",
},
},
{
name: ["-o", "--output"],
isRepeatable: true,
args: {
name: "output",
isOptional: true,
suggestions: [
"text",
"json",
],
},
},
{
name: ["-h", "--help"],
description: "Print help",
},
],
},
{
name: "build-info",
description: "Show build information of this binary",
options: [
{
name: ["-o", "--output"],
isRepeatable: true,
args: {
name: "output",
isOptional: true,
suggestions: [
"text",
"json",
],
},
},
{
name: ["-h", "--help"],
description: "Print help",
},
],
},
{
name: "completions",
description: "Generate shell completions",
options: [
{
name: ["-h", "--help"],
description: "Print help",
},
],
args: {
name: "shell",
suggestions: [
"bash",
"elvish",
"fish",
"power-shell",
"zsh",
],
},
},
{
name: "generate-fig-spec",
description: "Generate Fig specification",
options: [
{
name: ["-h", "--help"],
description: "Print help",
},
],
},
{
name: "help",
description: "Print this message or the help of the given subcommand(s)",
subcommands: [
{
name: "init",
description: "Initialise a Nym client. Do this first!",
},
{
name: "run",
description: "Run the Nym client with provided configuration client optionally overriding set parameters",
},
{
name: "import-credential",
description: "Import a pre-generated credential",
},
{
name: "list-gateways",
description: "List all registered with gateways",
},
{
name: "add-gateway",
description: "Add new gateway to this client",
},
{
name: "switch-gateway",
description: "Change the currently active gateway. Note that you must have already registered with the new gateway!",
},
{
name: "show-ticketbooks",
description: "Display information associated with the imported ticketbooks,",
},
{
name: "build-info",
description: "Show build information of this binary",
},
{
name: "completions",
description: "Generate shell completions",
},
{
name: "generate-fig-spec",
description: "Generate Fig specification",
},
{
name: "help",
description: "Print this message or the help of the given subcommand(s)",
},
],
},
],
options: [
{
name: ["-c", "--config-env-file"],
description: "Path pointing to an env file that configures the client",
isRepeatable: true,
args: {
name: "config_env_file",
isOptional: true,
template: "filepaths",
},
},
{
name: "--no-banner",
description: "Flag used for disabling the printed banner in tty",
},
{
name: ["-h", "--help"],
description: "Print help",
},
{
name: ["-V", "--version"],
description: "Print version",
},
],
};
export default completion;
```
@@ -1,15 +0,0 @@
```sh
Import a pre-generated credential
Usage: nym-socks5-client import-credential --id <ID> <--credential-data <CREDENTIAL_DATA>|--credential-path <CREDENTIAL_PATH>>
Options:
--id <ID>
Id of client that is going to import the credential
--credential-data <CREDENTIAL_DATA>
Explicitly provide the encoded credential data (as base58)
--credential-path <CREDENTIAL_PATH>
Specifies the path to file containing binary credential data
-h, --help
Print help
```
@@ -1,44 +0,0 @@
```sh
Initialise a Nym client. Do this first!
Usage: nym-socks5-client init [OPTIONS] --id <ID> --provider <PROVIDER>
Options:
--id <ID>
Id of client we want to create config for
--gateway <GATEWAY>
Id of the gateway we are going to connect to
--force-tls-gateway
Specifies whether the client will attempt to enforce tls connection to the desired gateway
--latency-based-selection
Specifies whether the new gateway should be determined based by latency as opposed to being chosen uniformly
--nym-apis <NYM_APIS>
Comma separated list of rest endpoints of the API validators
--provider <PROVIDER>
Address of the socks5 provider to send messages to
--use-reply-surbs <USE_REPLY_SURBS>
Specifies whether this client is going to use an anonymous sender tag for communication with the service provider. While this is going to hide its actual address information, it will make the actual communication slower and consume nearly double the bandwidth as it will require sending reply SURBs.
Note that some service providers might not support this.
[possible values: true, false]
-p, --port <PORT>
Port for the socket to listen on in all subsequent runs
--host <HOST>
The custom host on which the socks5 client will be listening for requests
-o, --output <OUTPUT>
[default: text]
[possible values: text, json]
-h, --help
Print help (see a summary with '-h')
```
@@ -1,10 +0,0 @@
```sh
List all registered with gateways
Usage: nym-socks5-client list-gateways [OPTIONS] --id <ID>
Options:
--id <ID> Id of client we want to list gateways for
-o, --output <OUTPUT> [default: text] [possible values: text, json]
-h, --help Print help
```
@@ -1,34 +0,0 @@
```sh
Run the Nym client with provided configuration client optionally overriding set parameters
Usage: nym-socks5-client run [OPTIONS] --id <ID>
Options:
--id <ID>
Id of client we want to create config for
--gateway <GATEWAY>
Id of the gateway we want to connect to. If overridden, it is user's responsibility to ensure prior registration happened
--nym-apis <NYM_APIS>
Comma separated list of rest endpoints of the API validators
--use-anonymous-replies <USE_ANONYMOUS_REPLIES>
Specifies whether this client is going to use an anonymous sender tag for communication with the service provider. While this is going to hide its actual address information, it will make the actual communication slower and consume nearly double the bandwidth as it will require sending reply SURBs.
Note that some service providers might not support this.
[possible values: true, false]
--provider <PROVIDER>
Address of the socks5 provider to send messages to
-p, --port <PORT>
Port for the socket to listen on
--host <HOST>
The custom host on which the socks5 client will be listening for requests
-h, --help
Print help (see a summary with '-h')
```
@@ -1,19 +0,0 @@
```sh
Queues up another upgrade for the associated daemon
Usage: nymvisor add-upgrade [OPTIONS] --upgrade-name <UPGRADE_NAME> <DAEMON_BINARY>
Arguments:
<DAEMON_BINARY> Path to the daemon's upgrade executable
Options:
--upgrade-name <UPGRADE_NAME> Name of this upgrade
--force Overwrite existing upgrade binary / upgrade-info.json file
--add-binary Indicate that this command should only add binary to an *existing* scheduled upgrade
--now Force the upgrade to happen immediately
--publish-date <PUBLISH_DATE> Specifies the publish date metadata field of this upgrade. If unset, the current time will be used
--upgrade-time <UPGRADE_TIME> Specifies the time at which the provided upgrade will be performed (RFC3339 formatted). If left unset, the upgrade will be performed in 15min
--upgrade-delay <UPGRADE_DELAY> Specifies delay until the provided upgrade is going to get performed. If let unset, the upgrade will be performed in 15min
-o, --output <OUTPUT> [default: text] [possible values: text, json]
-h, --help Print help
```
@@ -1,9 +0,0 @@
```sh
Show build information of this binary
Usage: nymvisor build-info [OPTIONS]
Options:
-o, --output <OUTPUT> [default: text] [possible values: text, json]
-h, --help Print help
```
@@ -1,13 +0,0 @@
```sh
Binary Name: nymvisor
Build Timestamp: 2024-10-09T13:56:14.428750844Z
Build Version: 0.1.5
Commit SHA: fac373c1db4fa5389ba61de7943c77023467bccb
Commit Date: 2024-10-09T14:59:40.000000000+02:00
Commit Branch: max/new-docs-framework
rustc Version: 1.80.0
rustc Channel: stable
cargo Profile: release
```
@@ -1,154 +0,0 @@
# `nymvisor` Binary Commands (Autogenerated)
These docs are autogenerated by the [`autodocs`](https://github.com/nymtech/nym/tree/max/new-docs-framework/documentation/autodoc) script.
```sh
Usage: nymvisor [OPTIONS] <COMMAND>
Commands:
init Initialise a nymvisor instance with persistent Config.toml file
run Run the associated daemon with the preconfigured settings
build-info Show build information of this binary
daemon-build-info Show build information of the associated daemon
add-upgrade Queues up another upgrade for the associated daemon
config Show configuration options being used by this instance of nymvisor
help Print this message or the help of the given subcommand(s)
Options:
-c, --config-env-file <CONFIG_ENV_FILE>
Path pointing to an env file that configures the nymvisor and overrides any preconfigured values
-h, --help
Print help
-V, --version
Print version
```
### `init`
```sh
Initialise a nymvisor instance with persistent Config.toml file
Usage: nymvisor init [OPTIONS] <DAEMON_BINARY>
Arguments:
<DAEMON_BINARY> Path to the daemon's executable
Options:
--id <ID>
ID specifies the human readable ID of this particular nymvisor instance. Can be overridden with $NYMVISOR_ID environmental variable
--upstream-base-upgrade-url <UPSTREAM_BASE_UPGRADE_URL>
Sets the base url of the upstream source for obtaining upgrade information for the deaemon. It will be used fo constructing the full url, i.e. $NYMVISOR_UPSTREAM_BASE_UPGRADE_URL/$DAEMON_NAME/upgrade-info.json Can be overridden with $NYMVISOR_UPSTREAM_BASE_UPGRADE_URL environmental variable
--upstream-polling-rate <UPSTREAM_POLLING_RATE>
Specifies the rate of polling the upstream url for upgrade information. default: 1h Can be overridden with $NYMVISOR_UPSTREAM_POLLING_RATE
--disable-nymvisor-logs
If enabled, this will disable `nymvisor` logs (but not the underlying process) Can be overridden with $NYMVISOR_DISABLE_LOGS environmental variable
--upgrade-data-directory <UPGRADE_DATA_DIRECTORY>
Set custom directory for upgrade data - binaries and upgrade plans. If not set, the global nymvisors' data directory will be used instead. Can be overridden with $NYMVISOR_UPGRADE_DATA_DIRECTORY environmental variable
--daemon-home <DAEMON_HOME>
The location where the `nymvisor/` directory is kept that contains the auxiliary files associated with the underlying daemon, such as any backups or current version information. (e.g. $HOME/.nym/nym-api/my-nym-api, $HOME/.nym/mixnodes/my-mixnode, etc.). Can be overridden with $DAEMON_HOME environmental variable
--daemon-absolute-upstream-upgrade-url <DAEMON_ABSOLUTE_UPSTREAM_UPGRADE_URL>
Override url to the upstream source for upgrade plans for this daeamon. The Url has to point to an endpoint containing a valid [`UpgradeInfo`] json. Note: if set this takes precedence over `upstream_base_upgrade_url` Can be overridden with $DAEMON_ABSOLUTE_UPSTREAM_UPGRADE_URL environmental variable
--allow-download-upgrade-binaries <ALLOW_DOWNLOAD_UPGRADE_BINARIES>
If set to true, this will enable auto-downloading of new binaries using the url provided in the `upgrade-info.json` Can be overridden with $DAEMON_ALLOW_BINARIES_DOWNLOAD environmental variable [possible values: true, false]
--enforce-download-checksum <ENFORCE_DOWNLOAD_CHECKSUM>
If enabled nymvisor will require that a checksum is provided in the upgrade plan for the binary to be downloaded. If disabled, nymvisor will not require a checksum to be provided, but still check the checksum if one is provided. Can be overridden with $DAEMON_ENFORCE_DOWNLOAD_CHECKSUM environmental variable [possible values: true, false]
--restart-daemon-after-upgrade <RESTART_DAEMON_AFTER_UPGRADE>
If enabled, nymvisor will restart the subprocess with the same command-line arguments and flags (but with the new binary) after a successful upgrade. Otherwise (if disabled), nymvisor will stop running after an upgrade and will require the system administrator to manually restart it. Note restart is only after the upgrade and does not auto-restart the subprocess after an error occurs. Can be overridden with $DAEMON_RESTART_AFTER_UPGRADE environmental variable [possible values: true, false]
--restart-daemon-on-failure
If enabled, nymvisor will restart the subprocess with the same command-line arguments and flags after it has crashed Can be overridden with $DAEMON_RESTART_ON_FAILURE environmental variable
--on-failure-daemon-restart-delay <ON_FAILURE_DAEMON_RESTART_DELAY>
If `restart_on_failure` is enabled, the following value defines the amount of time `nymvisor` shall wait before restarting the subprocess. Can be overridden with $DAEMON_FAILURE_RESTART_DELAY environmental variable
--max-daemon-startup-failures <MAX_DAEMON_STARTUP_FAILURES>
Defines the maximum number of startup failures the subprocess can experience in a quick succession before no further restarts will be attempted and `nymvisor` will exit. Can be overridden with $DAEMON_MAX_STARTUP_FAILURES environmental variable
--startup-period-duration <STARTUP_PERIOD_DURATION>
Defines the length of time during which the subprocess is still considered to be in the startup phase when its failures are going to be considered in `max_startup_failures`. Can be overridden with $DAEMON_STARTUP_PERIOD_DURATION environmental variable
--daemon-shutdown-grace-period <DAEMON_SHUTDOWN_GRACE_PERIOD>
Specifies the amount of time `nymvisor` is willing to wait for the subprocess to undergo graceful shutdown after receiving an interrupt (for either an upgrade or shutdown of the `nymvisor` itself) Once the time passes, a kill signal is going to be sent instead. Can be overridden with $DAEMON_SHUTDOWN_GRACE_PERIOD environmental variable
--daemon-backup-data-directory <DAEMON_BACKUP_DATA_DIRECTORY>
Set custom backup directory for daemon data. If not set, the daemon's home directory will be used instead. Can be overridden with $DAEMON_BACKUP_DATA_DIRECTORY environmental variable
--unsafe-skip-backup
If enabled, `nymvisor` will perform upgrades directly without performing any backups. default: false Can be overridden with $DAEMON_UNSAFE_SKIP_BACKUP environmental variable
-o, --output <OUTPUT>
[default: text] [possible values: text, json]
-h, --help
Print help
```
### `run`
```sh
Run the associated daemon with the preconfigured settings
Usage: nymvisor run [DAEMON_ARGS]...
Arguments:
[DAEMON_ARGS]...
Options:
-h, --help Print help
```
### `build-info`
```sh
Show build information of this binary
Usage: nymvisor build-info [OPTIONS]
Options:
-o, --output <OUTPUT> [default: text] [possible values: text, json]
-h, --help Print help
```
Example output:
```sh
Binary Name: nymvisor
Build Timestamp: 2024-10-29T09:48:31.988049207Z
Build Version: 0.1.8
Commit SHA: 299552881810511273af13eb135297a4cf7a38de
Commit Date: 2024-10-29T10:48:07.000000000+01:00
Commit Branch: max/new-docs-framework
rustc Version: 1.80.0
rustc Channel: stable
cargo Profile: release
```
### `daemon-build-info`
```sh
Show build information of the associated daemon
Usage: nymvisor daemon-build-info [OPTIONS]
Options:
-o, --output <OUTPUT> [default: text] [possible values: text, json]
-h, --help Print help
```
### `add-upgrade`
```sh
Queues up another upgrade for the associated daemon
Usage: nymvisor add-upgrade [OPTIONS] --upgrade-name <UPGRADE_NAME> <DAEMON_BINARY>
Arguments:
<DAEMON_BINARY> Path to the daemon's upgrade executable
Options:
--upgrade-name <UPGRADE_NAME> Name of this upgrade
--force Overwrite existing upgrade binary / upgrade-info.json file
--add-binary Indicate that this command should only add binary to an *existing* scheduled upgrade
--now Force the upgrade to happen immediately
--publish-date <PUBLISH_DATE> Specifies the publish date metadata field of this upgrade. If unset, the current time will be used
--upgrade-time <UPGRADE_TIME> Specifies the time at which the provided upgrade will be performed (RFC3339 formatted). If left unset, the upgrade will be performed in 15min
--upgrade-delay <UPGRADE_DELAY> Specifies delay until the provided upgrade is going to get performed. If let unset, the upgrade will be performed in 15min
-o, --output <OUTPUT> [default: text] [possible values: text, json]
-h, --help Print help
```
### `config`
```sh
Show configuration options being used by this instance of nymvisor
Usage: nymvisor config [OPTIONS]
Options:
-o, --output <OUTPUT> [default: text] [possible values: text, json]
-h, --help Print help
```
@@ -1,9 +0,0 @@
```sh
Show configuration options being used by this instance of nymvisor
Usage: nymvisor config [OPTIONS]
Options:
-o, --output <OUTPUT> [default: text] [possible values: text, json]
-h, --help Print help
```
@@ -1,9 +0,0 @@
```sh
Show build information of the associated daemon
Usage: nymvisor daemon-build-info [OPTIONS]
Options:
-o, --output <OUTPUT> [default: text] [possible values: text, json]
-h, --help Print help
```
@@ -1,48 +0,0 @@
```sh
Initialise a nymvisor instance with persistent Config.toml file
Usage: nymvisor init [OPTIONS] <DAEMON_BINARY>
Arguments:
<DAEMON_BINARY> Path to the daemon's executable
Options:
--id <ID>
ID specifies the human readable ID of this particular nymvisor instance. Can be overridden with $NYMVISOR_ID environmental variable
--upstream-base-upgrade-url <UPSTREAM_BASE_UPGRADE_URL>
Sets the base url of the upstream source for obtaining upgrade information for the deaemon. It will be used fo constructing the full url, i.e. $NYMVISOR_UPSTREAM_BASE_UPGRADE_URL/$DAEMON_NAME/upgrade-info.json Can be overridden with $NYMVISOR_UPSTREAM_BASE_UPGRADE_URL environmental variable
--upstream-polling-rate <UPSTREAM_POLLING_RATE>
Specifies the rate of polling the upstream url for upgrade information. default: 1h Can be overridden with $NYMVISOR_UPSTREAM_POLLING_RATE
--disable-nymvisor-logs
If enabled, this will disable `nymvisor` logs (but not the underlying process) Can be overridden with $NYMVISOR_DISABLE_LOGS environmental variable
--upgrade-data-directory <UPGRADE_DATA_DIRECTORY>
Set custom directory for upgrade data - binaries and upgrade plans. If not set, the global nymvisors' data directory will be used instead. Can be overridden with $NYMVISOR_UPGRADE_DATA_DIRECTORY environmental variable
--daemon-home <DAEMON_HOME>
The location where the `nymvisor/` directory is kept that contains the auxiliary files associated with the underlying daemon, such as any backups or current version information. (e.g. $HOME/.nym/nym-api/my-nym-api, $HOME/.nym/mixnodes/my-mixnode, etc.). Can be overridden with $DAEMON_HOME environmental variable
--daemon-absolute-upstream-upgrade-url <DAEMON_ABSOLUTE_UPSTREAM_UPGRADE_URL>
Override url to the upstream source for upgrade plans for this daeamon. The Url has to point to an endpoint containing a valid [`UpgradeInfo`] json. Note: if set this takes precedence over `upstream_base_upgrade_url` Can be overridden with $DAEMON_ABSOLUTE_UPSTREAM_UPGRADE_URL environmental variable
--allow-download-upgrade-binaries <ALLOW_DOWNLOAD_UPGRADE_BINARIES>
If set to true, this will enable auto-downloading of new binaries using the url provided in the `upgrade-info.json` Can be overridden with $DAEMON_ALLOW_BINARIES_DOWNLOAD environmental variable [possible values: true, false]
--enforce-download-checksum <ENFORCE_DOWNLOAD_CHECKSUM>
If enabled nymvisor will require that a checksum is provided in the upgrade plan for the binary to be downloaded. If disabled, nymvisor will not require a checksum to be provided, but still check the checksum if one is provided. Can be overridden with $DAEMON_ENFORCE_DOWNLOAD_CHECKSUM environmental variable [possible values: true, false]
--restart-daemon-after-upgrade <RESTART_DAEMON_AFTER_UPGRADE>
If enabled, nymvisor will restart the subprocess with the same command-line arguments and flags (but with the new binary) after a successful upgrade. Otherwise (if disabled), nymvisor will stop running after an upgrade and will require the system administrator to manually restart it. Note restart is only after the upgrade and does not auto-restart the subprocess after an error occurs. Can be overridden with $DAEMON_RESTART_AFTER_UPGRADE environmental variable [possible values: true, false]
--restart-daemon-on-failure
If enabled, nymvisor will restart the subprocess with the same command-line arguments and flags after it has crashed Can be overridden with $DAEMON_RESTART_ON_FAILURE environmental variable
--on-failure-daemon-restart-delay <ON_FAILURE_DAEMON_RESTART_DELAY>
If `restart_on_failure` is enabled, the following value defines the amount of time `nymvisor` shall wait before restarting the subprocess. Can be overridden with $DAEMON_FAILURE_RESTART_DELAY environmental variable
--max-daemon-startup-failures <MAX_DAEMON_STARTUP_FAILURES>
Defines the maximum number of startup failures the subprocess can experience in a quick succession before no further restarts will be attempted and `nymvisor` will exit. Can be overridden with $DAEMON_MAX_STARTUP_FAILURES environmental variable
--startup-period-duration <STARTUP_PERIOD_DURATION>
Defines the length of time during which the subprocess is still considered to be in the startup phase when its failures are going to be considered in `max_startup_failures`. Can be overridden with $DAEMON_STARTUP_PERIOD_DURATION environmental variable
--daemon-shutdown-grace-period <DAEMON_SHUTDOWN_GRACE_PERIOD>
Specifies the amount of time `nymvisor` is willing to wait for the subprocess to undergo graceful shutdown after receiving an interrupt (for either an upgrade or shutdown of the `nymvisor` itself) Once the time passes, a kill signal is going to be sent instead. Can be overridden with $DAEMON_SHUTDOWN_GRACE_PERIOD environmental variable
--daemon-backup-data-directory <DAEMON_BACKUP_DATA_DIRECTORY>
Set custom backup directory for daemon data. If not set, the daemon's home directory will be used instead. Can be overridden with $DAEMON_BACKUP_DATA_DIRECTORY environmental variable
--unsafe-skip-backup
If enabled, `nymvisor` will perform upgrades directly without performing any backups. default: false Can be overridden with $DAEMON_UNSAFE_SKIP_BACKUP environmental variable
-o, --output <OUTPUT>
[default: text] [possible values: text, json]
-h, --help
Print help
```
-347
View File
@@ -1,347 +0,0 @@
use log::{debug, info};
use std::fs::File;
use std::io::{self, Write};
use std::process::{Command, Output};
use std::{fs, vec};
const WRITE_PATH: &str = "./autodoc-generated-markdown/";
const COMMAND_PATH: &str = "./autodoc-generated-markdown/commands/";
fn main() -> io::Result<()> {
env_logger::init();
// TODO if this balloons write automated way of grabbing commands from crates.
let commands_with_subcommands = vec![
(
"../../target/release/nym-api",
vec!["init", "run", "build-info"],
),
(
"../../target/release/nym-client",
vec![
"init",
"run",
"import-credential",
"list-gateways",
"switch-gateway",
"build-info",
"completions",
"generate-fig-spec",
],
),
(
"../../target/release/nym-socks5-client",
vec![
"init",
"run",
"import-credential",
"list-gateways",
"add-gateway",
"build-info",
"completions",
"generate-fig-spec",
],
),
(
"../../target/release/nym-node",
vec![
"build-info",
"bonding-information",
"node-details",
"migrate",
"run",
"sign",
],
),
(
"../../target/release/nymvisor",
vec![
"init",
"run",
"build-info",
"daemon-build-info",
"add-upgrade",
"config",
],
),
];
let commands_with_subsubcommands = vec![(
"../../target/release/nym-cli",
vec![
(
"account",
vec!["create", "balance", "pub-key", "send", "send-multiple"],
),
("signature", vec!["sign", "verify"]),
(
"ecash",
vec![
"issue-ticket-book",
"recover-ticket-book",
"import-ticket-book",
],
),
(
"coconut",
vec![
"generate-freepass",
"issue-credentials",
"recover-credentials",
"import-credential",
],
),
("block", vec!["get", "time", "current-height"]),
(
"cosmwasm",
vec![
"upload",
"init",
"generate-init-message",
"migrate",
"execute",
],
),
("tx", vec!["get", "query"]),
(
"vesting-schedule",
vec!["create", "query", "vested-balance", "withdraw-vested"],
),
("mixnet", vec!["query", "delegators", "operators"]),
("generate-fig", vec![""]),
],
)];
for (main_command, subcommands) in commands_with_subcommands {
let last_word = get_last_word_from_filepath(main_command);
debug!("now running {last_word:#?}");
if !fs::metadata(WRITE_PATH)
.map(|metadata| metadata.is_dir())
.unwrap_or(false)
{
fs::create_dir_all(WRITE_PATH)?;
}
let mut file = File::create(format!("{}/{}-commands.md", WRITE_PATH, last_word.unwrap()))?;
writeln!(
file,
"# {} Binary Commands (Autogenerated)",
format!("`{}`", last_word.unwrap())
)?;
writeln!(
file,
"\nThese docs are autogenerated by the [`autodocs`](https://github.com/nymtech/nym/tree/max/new-docs-framework/documentation/autodoc) script."
)?;
let output = Command::new(main_command).arg("--help").output()?;
write_output_to_file(&mut file, output)?;
for subcommand in subcommands {
// single file
execute_command(&mut file, main_command, subcommand, None)?;
// file per command
execute_command_own_file(main_command, subcommand)?;
}
}
// nym-cli has subsubcommands so needs its own loop
for (main_command, subcommands) in &commands_with_subsubcommands {
let last_word = get_last_word_from_filepath(main_command);
debug!("now running {last_word:#?}");
let mut file = File::create(format!("{}/{}-commands.md", WRITE_PATH, last_word.unwrap()))?;
writeln!(
file,
"# {} Binary Commands (Autogenerated)",
format!("`{}`", last_word.unwrap())
)?;
writeln!(
file,
"\nThese docs are autogenerated by the [`autodocs`](https://github.com/nymtech/nym/tree/max/new-docs-framework/documentation/autodoc) script."
)?;
let output = Command::new(main_command).arg("--help").output()?;
write_output_to_file(&mut file, output)?;
for (subcommand, subsubcommands) in subcommands {
writeln!(file, "\n## `{}` ", subcommand)?;
let output = Command::new(main_command)
.arg(subcommand)
.arg("--help")
.output()?;
if !output.stdout.is_empty() {
write_output_to_file(&mut file, output)?;
} else {
debug!("empty stdout - nothing to write");
}
for subsubcommand in subsubcommands {
execute_command(&mut file, main_command, subcommand, Some(subsubcommand))?;
}
}
}
Ok(())
}
fn get_last_word_from_filepath(filepath: &str) -> Option<&str> {
let parts: Vec<&str> = filepath.split('/').collect();
parts.last().copied()
}
fn execute_command_own_file(main_command: &str, subcommand: &str) -> io::Result<()> {
// this check is basically checking for the rare commands (rn just one) that start a process with no params
// perhaps if this list grows we could just add a timeout and shunt the running and writing
// into a thread with a timeout or something but for right now its fine / thats overkill
if get_last_word_from_filepath(main_command).unwrap() == "nym-node" && subcommand == "run"
|| get_last_word_from_filepath(main_command).unwrap() == "nym-api" && subcommand == "run"
|| get_last_word_from_filepath(main_command).unwrap() == "nymvisor" && subcommand == "run"
{
info!("SKIPPING {} {}", main_command, subcommand);
} else {
let last_word = get_last_word_from_filepath(main_command);
let output = Command::new(main_command).arg(subcommand).output()?;
if !output.stdout.is_empty() {
info!("creating own file for {} {}", main_command, subcommand,);
if !fs::metadata(WRITE_PATH)
.map(|metadata| metadata.is_dir())
.unwrap_or(false)
{
fs::create_dir_all(COMMAND_PATH)?;
}
let mut file = File::create(format!(
"{}/{}-{}.md",
COMMAND_PATH,
last_word.unwrap(),
subcommand
))?;
write_output_to_file(&mut file, output)?;
// execute help
info!(
"creating own file for {} {} --help",
main_command, subcommand,
);
if !fs::metadata(COMMAND_PATH)
.map(|metadata| metadata.is_dir())
.unwrap_or(false)
{
fs::create_dir_all(COMMAND_PATH)?;
}
let mut help_file = File::create(format!(
"{}/{}-{}-help.md",
COMMAND_PATH,
last_word.unwrap(),
subcommand
))?;
let output = Command::new(main_command)
.arg(subcommand)
.arg("--help")
.output()?;
if !output.stdout.is_empty() {
write_output_to_file(&mut help_file, output)?;
} else {
debug!("empty stdout - nothing to write");
}
} else {
info!(
"creating own file for {} {} --help",
main_command, subcommand,
);
if !fs::metadata(COMMAND_PATH)
.map(|metadata| metadata.is_dir())
.unwrap_or(false)
{
fs::create_dir_all(COMMAND_PATH)?;
}
let mut help_file = File::create(format!(
"{}/{}-{}-help.md",
COMMAND_PATH,
last_word.unwrap(),
subcommand
))?;
let output = Command::new(main_command)
.arg(subcommand)
.arg("--help")
.output()?;
write_output_to_file(&mut help_file, output)?;
debug!("empty stdout - nothing to write");
}
}
Ok(())
}
fn execute_command(
file: &mut File,
main_command: &str,
subcommand: &str,
subsubcommand: Option<&str>,
) -> io::Result<()> {
// checking for the nym-cli subsubcommands
if subsubcommand.is_some() {
writeln!(file, "\n### `{} {}`", subcommand, subsubcommand.unwrap())?;
info!("executing {} {} --help ", main_command, subcommand);
let output = Command::new(main_command)
.arg(subcommand)
.arg(subsubcommand.unwrap())
.arg("--help")
.output()?;
if !output.stdout.is_empty() {
write_output_to_file(file, output)?;
} else {
debug!("empty stdout - nothing to write");
}
// just subcommands
} else {
writeln!(file, "\n### `{}`", subcommand)?;
// execute help
let output = Command::new(main_command)
.arg(subcommand)
.arg("--help")
.output()?;
if !output.stdout.is_empty() {
write_output_to_file(file, output)?;
} else {
debug!("empty stdout - nothing to write");
}
// then execute w/out help: the majority of functions will fail since you're not passing
// required params but thats fine as we can just not render stderr into the final file.
//
// this check is basically checking for the rare commands (rn just one) that start a process with no params
// perhaps if this list grows we could just add a timeout and shunt the running and writing
// into a thread with a timeout or something but for right now its fine / thats overkill
if get_last_word_from_filepath(main_command).unwrap() == "nym-node"
|| get_last_word_from_filepath(main_command).unwrap() == "nym-api"
|| get_last_word_from_filepath(main_command).unwrap() == "nymvisor"
&& subcommand == "run"
{
info!("SKIPPING {} {}", main_command, subcommand);
} else {
info!("executing {} {}", main_command, subcommand);
let output = Command::new(main_command).arg(subcommand).output()?;
if !output.stdout.is_empty() {
writeln!(file, "Example output:")?;
write_output_to_file(file, output)?;
} else {
debug!("empty stdout - nothing to write");
if !&output.stderr.is_empty() {
debug!("stderr: {:#?}", String::from_utf8_lossy(&output.stderr));
}
}
}
}
Ok(())
}
fn write_output_to_file(file: &mut File, output: Output) -> io::Result<()> {
writeln!(file, "```sh")?;
file.write_all(&output.stdout)?;
writeln!(file, "```")?;
if !&output.stderr.is_empty() {
debug!("stderr: {:#?}", String::from_utf8_lossy(&output.stderr));
}
Ok(())
}
+51
View File
@@ -0,0 +1,51 @@
#!/usr/bin/env bash
set -o errexit
set -o nounset
set -o pipefail
# this is a script called by the github CI and CD workflows to build all 3 docs projects
# and move them to /dist/ in the root of the monorepo. They are rsynced to various servers
# from there by subsequent workflow tasks.
# array of project dirs
declare -a projects=("docs" "dev-portal" "operators")
# check you're calling from the right place
if [ $(pwd | awk -F/ '{print $NF}') != "documentation" ]
then
echo "failure: please run script from documentation/"
else
for i in "${projects[@]}"
do
# cd to project dir
cd "./$i" &&
# little sanity checks
echo $(pwd) && echo $(mdbook --version) &&
# clean old book
echo "cleaning old book"
rm -rf ./book/
# build book
# mdbook test || true
mdbook build
# check for destination, if ! then mkdir & check again else echo thumbs up
if [ ! -d ../../dist/docs/$i ]; then
echo "dest doesn't exist: creating dir"
mkdir -p ../../dist/docs/$i
fi
if [ -d ../../dist/docs/$i ]; then
echo "cp destination exists, all good"
fi
# clean old dist/$i
rm -rf ../../dist/docs/$i
# move newly rendered book/ to dist
rsync -r ./book/html/ ../../dist/docs/$i
# sanity check
ls -laF ../../dist/docs/
# cd back to ../documentation/
cd ../
done
# rename for server paths
rm -rf ../dist/docs/developers
mv ../dist/docs/dev-portal ../dist/docs/developers
fi
+45
View File
@@ -0,0 +1,45 @@
#!/usr/bin/env bash
set -o errexit
set -o nounset
set -o pipefail
# takes one manadatory arg and one optional arg: wallet release and minimum rust versions
# it then uses sed to bump them in the three book.toml files.
#
# e.g if the upcoming wallet release version was 1.2.9 you'd run this as:
# `./bump_versions.sh "1.2.9"`
#
# you can also set the minumum rust version by passing an optional additional argument:
# `./bump_versions.sh "1.2.9" "1.67"`
# array of project dirs
declare -a projects=("docs" "dev-portal" "operators")
# check number of args passed
if [ "$#" -lt 1 ] || [ "$#" -gt 2 ];
then
echo "failure: please pass at least 1 and at most 2 args: "
echo "./bump_version.sh <new wallet_release_version> [OPTIONAL]<new minimum_rust_version>"
exit 0
fi
# check you're calling from the right place
if [ $(pwd | awk -F/ '{print $NF}') != "documentation" ]
then
echo "failure: please run script from documentation/"
exit 0
else
## now loop through the above array sed-ing the variable values in the book.toml files
for i in "${projects[@]}"
do
# sed the vars in the book.toml file for each project
echo "setting wallet version in $i/"
sed -i 's/wallet_release_version =.*/wallet_release_version = "'$2'"/' "$i"/book.toml
if [ "$3" ]
then
echo "setting minimum rust version in $i/"
sed -i 's/minimum_rust_version = .*/minimum_rust_version = "'$3'"/' "$i"/book.toml
fi
done
fi
+24
View File
@@ -0,0 +1,24 @@
# Generated by Cargo
# will have compiled files and executables
/target/
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk
# Book specific
book
# OSX
.DS_Store
theme/
theme
theme/*
.idea
notes
+201
View File
@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+24
View File
@@ -0,0 +1,24 @@
# Nym Developer Portal
Developer Portal for the Nym privacy platform built using the [mdBook](https://rust-lang.github.io/mdBook/) docs framework. Deployed version can be found [here](https://nymtech.net/developers).
## Contributing
Contributions to our documentation are very welcome. Please work on your contribution in either a `feature/<feature-name>` or `chore/<chore-name>` branch from `master` and target your pull request at `master`.
Changes merged to `master` will be autodeployed to the production site.
### Adding community projects and resources
If you have built a project with Nym or are compiling and writing resources about Nym, we want to include your work in the `community-resources/` section to share with the rest of the community! Just follow the existing formatting and add your project to the page, then put in a pull request.
## Variables
There are some variables that are shared across this book, such as the current latest software version.
Variables are denoted in the `.md` files wrapped in `{{}}` (e.g `{{wallet_release_version}}`), and are located in the `book.toml` file under the `[preprocessor.variables.variables]` heading. If you are changing something like the software release version, minimum code versions in prerequisites, etc, **check in here first!**
## Building
When working locally, it is recommended that you use `mdbook serve` to have a local version of the docs served on `localhost:3000`, with hot reloading on any changes made to files in the `src/` directory.
You can find other commands in the [mdBook CLI tool docs](https://rust-lang.github.io/mdBook/cli/index.html).
### I tried to edit files in `theme/` and they aren't taking effect / `mdbook serve` causes a looping reload on file changes after changing fields in `[preprocessor.theme]` config
Looping reload is a known issue with the `mdbook-theme` preprocessor used for the table of contents and layout of these docs. As outlined in the `mdbook-theme` [readme](https://github.com/zjp-CN/mdbook-theme#avoid-repeating-call-on-this-tool-when-mdbook-watch) one way to mitigate this is to set `turn-off = true` under `[preprocessor.theme]`. This means that `mdbook serve` or `mdbook watch` ignores changes to the `theme/` directory, which is the source of the looping reload. If you have changed or commented out this line, reintroduce it to remove the looping reload. If you are trying to edit the theme of the docs and want to apply the change, see [here](https://github.com/zjp-CN/mdbook-theme#avoid-repeating-call-on-this-tool-when-mdbook-watch) for more info on how to remove the block, change the theme, and reintroduce the block.
+118
View File
@@ -0,0 +1,118 @@
[book]
title = "Nym Docs"
authors = ["Max Hampshire, Serinko, Alexia Lorenza Martinel"]
description = "Nym technical documentation"
language = "en"
multilingual = false # for the moment - ideally work on chinese, brazillian ,portugese spanish next
src = "src"
[rust]
edition = "2018"
#################
# PREPROCESSORS #
#################
[preprocessor.theme]
pagetoc = true
sidebar-width = "280px"
content-max-width = "80%"
root-font-size = "70%"
# if you need to change anything in the index.hbs file you need to turn this to `false`, rebuild the book,
# probably remove the additional `comment` that gets appended to the header, and then change this back to `true`.
# this is because of a bug in the `mdbook-theme` plugin
turn-off = true
[preprocessor.admonish]
command = "mdbook-admonish"
assets_version = "3.0.2" # do not edit: managed by `mdbook-admonish install`
# https://gitlab.com/tglman/mdbook-variables/
[preprocessor.variables.variables]
minimum_rust_version = "1.66"
wallet_release_version = "1.2.8"
# nym-vpn related variables
nym_vpn_releases = "https://github.com/nymtech/nym-vpn-client/releases"
nym_vpn_form_url = "https://opnform.com/forms/nymvpn-user-research-at-37c3-yccqko-2"
# versions are pulled by cmdrun now
# nym_vpn_gui_version = "0.0.6"
# nym_vpn_cli_version = "0.0.4"
[preprocessor.last-changed]
command = "mdbook-last-changed"
renderer = ["html"]
# used for grabbing output of binary commands for automation https://github.com/FauconFan/mdbook-cmdrun
[preprocessor.cmdrun]
# more pre-processor plugins to look into from https://github.com/rust-lang/mdBook/wiki/Third-party-plugins & https://lib.rs/keywords/mdbook-preprocessor
# mdbook-i18n
#########
# BUILD #
#########
[build]
build-dir = "book" # the directory where the output is placed
create-missing = true # whether or not to create missing pages
use-default-preprocessors = true # use the default preprocessors
extra-watch-dirs = [] # directories to watch for triggering builds
##########
# OUTPUT #
##########
[output.html]
theme = "themes"
default-theme = "coal"
preferred-dark-theme = "coal"
curly-quotes = true
copy-fonts = true
no-section-label = false
additional-css = [
"./themes/custom.css",
"./themes/mdbook-admonish.css",
"./themes/pagetoc.css",
]
additional-js = ["./themes/pagetoc.js"]
git-repository-url = "https://github.com/nymtech/nym"
git-repository-icon = "fa-github"
input-404 = "not-found.md"
[output.html.fold]
enable = true # whether or not to enable section folding
level = 0 # the depth to start folding
# controlling rust sample code blocks
[output.html.playground]
editable = false # allows editing the source code
copyable = true # include the copy button for copying code snippets
copy-js = true # includes the JavaScript for the code editor
line-numbers = true # displays line numbers for editable code
runnable = true # displays a run button for rust code
# options for the built in text search
[output.html.search]
enable = true # enables the search feature
limit-results = 30 # maximum number of search results
teaser-word-count = 30 # number of words used for a search result teaser
use-boolean-and = true # multiple search terms must all match
boost-title = 2 # ranking boost factor for matches in headers
boost-hierarchy = 1 # ranking boost factor for matches in page names
boost-paragraph = 1 # ranking boost factor for matches in text
expand = true # partial words will match longer terms
heading-split-level = 3 # link results to heading levels
copy-js = true # include Javascript code for search
[output.linkcheck]
warning-policy = "warn"
[output.html.redirect]
"/faq/general-faq.html" = "https://nymtech.net/developers/faq/integrations-faq.html"
"/tutorials/simple-service-provider/user-client.html" = "https://nymtech.net/developers/examples/custom-services.html"
"/quickstart/socks-proxy.html" = "https://nymtech.net/developers/clients/socks5/setup.html"
"/tutorials/matrix.html" = "https://nymtech.net/developers/archive/nym-connect.html#matrix-element-via-nymconnect"
"/tutorials/monero.html" = "https://nymtech.net/developers/archive/nym-connect.html#monero-wallet-via-nymconnect"
"/tutorials/telegram.html" = "https://nymtech.net/developers/archive/nym-connect.html#telegram-via-nymconnect"
@@ -0,0 +1,24 @@
+-----------+
| Gateway |
+-----------+
^
|
|
|
|
|
|
+-------------------+
| +---------------+ |
| | Nym client | |
| +---------------+ |
| ^ |
| | |
| | |
| | |
| v |
| +---------------+ |
| | Your app code | |
| +---------------+ |
+-------------------+
Your Local Machine
@@ -0,0 +1,33 @@
+----------+ +----------+ +----------+
| Mix Node |<-----------> | Mix Node |<----------->| Mix Node |
| Layer 1 | | Layer 2 | | Layer 3 |
+----------+ +----------+ +----------+
^ ^
| |
| |
v v
+--------------+ +-----------------+
| Your gateway | | Service gateway |
+--------------+ +-----------------+
^ ^
| |
| |
v v
+-------------------+ +-------------------+
| +---------------+ | | +---------------+ |
| | Nym client | | | | Nym Client | |
| +---------------+ | | +---------------+ |
| ^ | | ^ |
| | | | | |
| | | | | |
| v | | v |
| +---------------+ | | +---------------+ |
| | Your app code | | | | Service Code | |
| +---------------+ | | +---------------+ |
+-------------------+ +-------------------+
Your Local Machine** Service Provider Machine**
** note that depending on the technical setup, the Nym client running on these machines may
be either a seperate process or embedded in the same process as the app code via one of our SDKs.
@@ -0,0 +1,34 @@
+----------+ +----------+ +----------+
| Mix Node |<-----------> | Mix Node |<----------->| Mix Node |
| Layer 1 | | Layer 2 | | Layer 3 |
+----------+ +----------+ +----------+
^ ^
| |
|<--------------------------------------------------+
|
v
+--------------+
| Your gateway |
+--------------+
^
|
|
v
+-------------------+
| +---------------+ |
| | Nym client | |
| +---------------+ |
| ^ |
| | |
| | |
| v |
| +---------------+ |
| | Your app code | |
| +---------------+ |
+-------------------+
Your Local Machine**
** note that depending on the technical setup, the Nym client running on this machine may
be either a seperate process or embedded in the same process as the app code via one of our SDKs.
@@ -0,0 +1,14 @@
+-------------------+
| +---------------+ |
| | Nym client | |
| +---------------+ |
| ^ |
| | |
| | |
| | |
| v |
| +---------------+ |
| | Your app code | |
| +---------------+ |
+-------------------+
Your Local Machine
@@ -0,0 +1,15 @@
+-------------------+
| +---------------+ |
| | Nym client | |
| +---------------+ |
| ^ |
| | |
| | |
| | |
| v |
| +---------------+ |
| | Service code | |
| +---------------+ |
+-------------------+
Service Machine
+67
View File
@@ -0,0 +1,67 @@
#
- [Introduction](introduction.md)
- [Clients Overview - Start Here!](clients-overview.md)
# SDKs
- [Rust SDK](sdk/rust/rust.md)
- [Message Types](sdk/rust/message-types.md)
- [Message Helpers](sdk/rust/message-helpers.md)
- [Troubleshooting](sdk/rust/troubleshooting.md)
- [Examples](sdk/rust/examples.md)
- [Simple Send](sdk/rust/examples/simple.md)
- [Create and Store Keys](sdk/rust/examples/keys.md)
- [Manual Storage](sdk/rust/examples/storage.md)
- [Anonymous Replies](sdk/rust/examples/surbs.md)
- [Use Custom Network Topology](sdk/rust/examples/custom-network.md)
- [Socks Proxy](sdk/rust/examples/socks.md)
- [Split Send and Receive](sdk/rust/examples/split-send.md)
- [Testnet Bandwidth Cred](sdk/rust/examples/credential.md)
- [Example Cargo file](sdk/rust/examples/cargo.md)
- [Typescript SDK](sdk/typescript.md)
# Binaries
- [Pre-built Binaries](binaries/pre-built-binaries.md)
- [Building from Source](binaries/building-nym.md)
# Standalone Clients
- [Websocket Client](clients/websocket-client.md)
- [Setup & Run](clients/websocket/setup.md)
- [Configuration](clients/websocket/config.md)
- [Using Your Client](clients/websocket/usage.md)
- [Examples](clients/websocket/examples.md)
- [Socks5 Client](clients/socks5-client.md)
- [Setup & Run](clients/socks5/setup.md)
- [Using Your Client](clients/socks5/usage.md)
- [Webassembly Client](clients/webassembly-client.md)
# Tutorials
- [Stub: Updates Coming Soon!](./tutorials/coming-soon.md)
# Code Examples
- [Custom Service Providers](examples/custom-services.md)
- [Apps Using Network Requesters](examples/using-nrs.md)
- [Browser only](examples/browser-only.md)
- [Monorepo examples](examples/monorepo-examples.md)
# Integrations
- [Integration Options](integrations/integration-options.md)
[//]: # (- [Mixnet Integration]&#40;integrations/mixnet-integration.md&#41;)
- [Payment Integration](integrations/payment-integration.md)
# FAQ
- [Integrations](faq/integrations-faq.md)
# User Manuals
- [NymVPN beta](nymvpn/intro.md)
- [CLI](nymvpn/cli.md)
---
# Archive
- [NymConnect Setup](archive/nym-connect.md)
---
# Misc.
- [Code of Conduct](coc.md)
- [Licensing](licensing.md)
---
@@ -33,7 +33,7 @@ To download Electrum visit the [official webpage](https://electrum.org/#download
4. Set *Use proxy* to ✅, choose `SOCKS5` from the drop-down and add (copy-paste) the values from your NymConnect application
5. Now your Electrum Bitcoin wallet runs through the Mixnet and it will be connected only if your NymConnect or `nym-socks5-client` are connected.
![Electrum Bitcoin wallet setup](/images/developers/electrum.gif)
![Electrum Bitcoin wallet setup](../images/electrum_tutorial/electrum.gif)
### Monero wallet via NymConnect
@@ -44,6 +44,7 @@ To download Monero wallet visit [getmonero.org](https://www.getmonero.org/downlo
3. Go to: *Settings* -> *Interface* -> *Socks5 proxy* -> Add values: IP address `127.0.0.1`, Port `1080` (the values copied from NymConnect)
5. Now your Monero wallet runs through the Mixnet and it will be connected only if your NymConnect or `nym-socks5-client` are connected.
![Monero wallet setup](../images/monero_tutorial/monero-gui-NC.gif)
### Matrix (Element) via NymConnect
@@ -1,6 +1,4 @@
# Nym Binaries
## Building from Source
# Building from Source
> Nym runs on Mac OS X, Linux, and Windows. All nodes **except the Desktop Wallet and NymConnect** on Windows should be considered experimental - it works fine if you're an app developer but isn't recommended for running nodes.
@@ -10,7 +8,7 @@ Nym has two main codebases:
- the [Nym platform](https://github.com/nymtech/nym), written in Rust. This contains all of our code _except_ for the validators.
- the [Nym validators](https://github.com/nymtech/nyxd), written in Go.
> This page details how to build the main Nym platform code. **If you want to build and run a validator, [go here](../operators/nodes/validator-setup) instead.**
> This page details how to build the main Nym platform code.
## Prerequisites
- Debian/Ubuntu: `pkg-config`, `build-essential`, `libssl-dev`, `curl`, `jq`, `git`
@@ -54,11 +52,10 @@ git checkout master # master branch has the latest release version: `develop` wi
cargo build --release # build your binaries with **mainnet** configuration
```
Quite a bit of stuff gets built. The key working parts for devs are the Client binaries and the CLI tool:
* [websocket client](../clients/websocket-client.md): `nym-client`
* [socks5 client](../clients/socks5-client.md): `nym-socks5-client`
* [nym-cli tool](https://nymtech.net/docs/tools/nym-cli.html): `nym-cli`
> You cannot build from GitHub's .zip or .tar.gz archive files on the releases page - the Nym build scripts automatically include the current git commit hash in the built binary during compilation, so the build will fail if you use the archive code (which isn't a Git repository). Check the code out from github using `git clone` instead.
## Pre-built Binaries
The [Github releases page](https://github.com/nymtech/nym/releases) has pre-built binaries which should work on Ubuntu 20.04 and other Debian-based systems, but at this stage cannot be guaranteed to work everywhere.
If the pre-built binaries don't work or are unavailable for your system, you will need to build the platform yourself.
@@ -0,0 +1,6 @@
# Pre-built Binaries
The [Github releases page](https://github.com/nymtech/nym/releases) has pre-built binaries which should work on Ubuntu 20.04 and other Debian-based systems, but at this stage cannot be guaranteed to work everywhere.
If the pre-built binaries don't work or are unavailable for your system, you will need to build the platform yourself.
@@ -0,0 +1,49 @@
# Clients Overview
A large proportion of the Nym mixnet's functionality is implemented client-side.
Clients perform the following actions on behalf of users:
* determine network topology - what mixnodes exist, what their keys are, etc.
* register with a gateway
* authenticate with a gateway
* receive and decrypt messages from the gateway
* create layer-encrypted Sphinx packets
* send Sphinx packets with real messages
* send Sphinx packet _cover traffic_ when no real messages are being sent
* retransmit un-acknowledged packet sends - if a client sends 100 packets to a gateway, but only receives an acknowledgement ('ack') for 95 of them, it will resend those 5 packets to the gateway again, to make sure that all packets are received.
> As a developer, you'll want to use a Nym client to send your application network traffic through the mixnet; whether that is an RPC call, a TCP connection request, or treating it like a UDP pipe, you need to send whatever bytes your app needs to send through it. However, unlike (e.g.) a TCP Socket, Nym client communication is message-based, so you cannot (yet) simply plug-and-play using the mixnet as a seamless drop-in replacement. We are currently working on stream-like abstractions for ease of integration with the Rust SDK.
## Types of Nym clients
At present, there are three Nym clients:
- the websocket (native) client
- the SOCKS5 client
- the wasm (webassembly) client
You need to choose which one you want incorporate into your app. Which one you use will depend largely on your preferred programming style and the purpose of your app.
### The websocket client
Your first option is the native websocket client (`nym-client`). This is a compiled program that can run on Linux, Mac OS X, and Windows machines. It can be run as a persistent process on a desktop or server machine. You can connect to it with **any language that supports websockets**.
> Rust developers can import websocket client functionality into their code via the [Rust SDK](sdk/rust/rust.md).
### The webassembly client
If you're working in JavaScript or Typescript in the browser, or building an [edge computing](https://en.wikipedia.org/wiki/Edge_computing) app, you'll likely want to choose the webassembly client.
It's packaged and [available on the npm registry](https://www.npmjs.com/package/@nymproject/nym-client-wasm), so you can `npm install` it into your JavaScript or TypeScript application.
> The webassembly client is most easily used via the [Typescript SDK](sdk/typescript.md). Typescript developers who wish to send API requests through the mixnet can can also check the [`mixfetch`]() package.
### The SOCKS5 client
The `nym-socks5-client` is useful for allowing existing applications to use the Nym mixnet without any code changes. All that's necessary is that they can use one of the SOCKS5, SOCKS4a, or SOCKS4 proxy protocols (which many applications can - crypto wallets, browsers, chat applications etc).
When used as a standalone client, it's less flexible as a way of writing custom applications than the other clients, but able to be used to proxy application traffic through the mixnet without having to make any code changes.
> Rust developers can import socks client functionality into their code via the [Rust SDK](sdk/rust/rust.md).
## Commonalities between clients
All Nym client packages present basically the same capabilities to the privacy application developer. They need to run as a persistent process in order to stay connected and ready to receive any incoming messages from their gateway nodes. They register and authenticate to gateways, and encrypt Sphinx packets.
@@ -0,0 +1,45 @@
# Clients Overview
A large proportion of the Nym mixnet's functionality is implemented client-side.
Clients perform the following actions on behalf of users:
* determine network topology - what mixnodes exist, what their keys are, etc.
* register with a gateway
* authenticate with a gateway
* receive and decrypt messages from the gateway
* create layer-encrypted Sphinx packets
* send Sphinx packets with real messages
* send Sphinx packet _cover traffic_ when no real messages are being sent
* retransmit un-acknowledged packet sends - if a client sends 100 packets to a gateway, but only receives an acknowledgement ('ack') for 95 of them, it will resend those 5 packets to the gateway again, to make sure that all packets are received.
## Types of Nym clients
At present, there are three Nym clients:
- the websocket (native) client
- the SOCKS5 client
- the wasm (webassembly) client
You need to choose which one you want incorporate into your app. Which one you use will depend largely on your preferred programming style and the purpose of your app.
### The websocket client
Your first option is the native websocket client (`nym-client`). This is a compiled program that can run on Linux, Mac OS X, and Windows machines. It can be run as a persistent process on a desktop or server machine. You can connect to it with **any language that supports websockets**.
> Rust developers can import websocket client functionality into their code via the [Rust SDK](../sdk/rust/rust.md).
### The webassembly client
If you're working in JavaScript or Typescript in the browser, or building an [edge computing](https://en.wikipedia.org/wiki/Edge_computing) app, you'll likely want to choose the webassembly client.
It's packaged and [available on the npm registry](https://www.npmjs.com/package/@nymproject/nym-client-wasm), so you can `npm install` it into your JavaScript or TypeScript application.
> The webassembly client is most easily used via the [Typescript SDK](../sdk/typescript.md). Typescript developers who wish to send API requests through the mixnet can can also check the [`mixfetch`]() package.
### The SOCKS5 client
The `nym-socks5-client` is useful for allowing existing applications to use the Nym mixnet without any code changes. All that's necessary is that they can use one of the SOCKS5, SOCKS4a, or SOCKS4 proxy protocols (which many applications can - crypto wallets, browsers, chat applications etc).
When used as a standalone client, it's less flexible as a way of writing custom applications than the other clients, but able to be used to proxy application traffic through the mixnet without having to make any code changes.
_Rust developers can import socks client functionality into their code via the [Rust SDK](../sdk/rust/rust.md)_.
## Commonalities between clients
All Nym client packages present basically the same capabilities to the privacy application developer. They need to run as a persistent process in order to stay connected and ready to receive any incoming messages from their gateway nodes. They register and authenticate to gateways, and encrypt Sphinx packets.

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