Compare commits
270 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0303dc690e | |||
| 9f2c425106 | |||
| bd830780e1 | |||
| c79d864c3d | |||
| 25df954112 | |||
| a8de6b75d9 | |||
| 3096a2307f | |||
| 4b882d84ea | |||
| 3b8cff8b32 | |||
| 177cb22a3f | |||
| 809fabfc2b | |||
| 05ff6f0f62 | |||
| d475b7b2ae | |||
| adea6966ea | |||
| ab1c7206a3 | |||
| 4c355848c6 | |||
| 7a6ddc67ed | |||
| 8e6596db48 | |||
| acf149e131 | |||
| acc62252be | |||
| d682bc4573 | |||
| 5eda5cc35d | |||
| 3f243f111a | |||
| 6ac38f80c7 | |||
| a4cf3b9166 | |||
| 002c04051a | |||
| 1aa12886db | |||
| 6552cbaeda | |||
| 8ee31d94ea | |||
| 818d7ee13e | |||
| 81c692d305 | |||
| 1728de57b9 | |||
| 53fcebfd86 | |||
| 4a5ceddeac | |||
| a5c1e4abf0 | |||
| 3a1003c564 | |||
| 1cdd8f6c08 | |||
| 808e3f0562 | |||
| f0dade3c5b | |||
| 0a3c2b3cca | |||
| ac66906980 | |||
| afd9f823d8 | |||
| d818448848 | |||
| a9a1ba2847 | |||
| 2708c0ce10 | |||
| bb3e9b3d4e | |||
| e624f42ad5 | |||
| 7da83397dd | |||
| 26d0b4b159 | |||
| b74490dc50 | |||
| 8113095ff5 | |||
| 8339d6ab49 | |||
| f037b2ae68 | |||
| 2a4c1d96a4 | |||
| ed04ddf1c4 | |||
| 34b5d66df6 | |||
| 0a1a5c25f7 | |||
| 6bdba7046f | |||
| 428d91a536 | |||
| 88e0eaafcb | |||
| dd19cabf15 | |||
| 4ec08da36d | |||
| 16c59d95d3 | |||
| e6f76380f6 | |||
| 6961ecae55 | |||
| dd814c067c | |||
| 666d5945b9 | |||
| ecebf6e84c | |||
| 4663d39505 | |||
| 81a7d7b001 | |||
| 2c0a561cd5 | |||
| d187d252fb | |||
| 4026dc8eef | |||
| c02453b2d1 | |||
| f1a5a0ccd7 | |||
| f9a4ca5a22 | |||
| ee99843b51 | |||
| 05e349cf37 | |||
| 8d51cd1afd | |||
| a2fd78963c | |||
| 59d43e1acd | |||
| 354c529cea | |||
| 435a60aee9 | |||
| a1c9b9b4bb | |||
| 457d1e8615 | |||
| 05eb05643f | |||
| 3d82f84e1d | |||
| c7b3999dcf | |||
| 8336bb0009 | |||
| 4cb0231acf | |||
| 3715860a47 | |||
| 5b2e4158bd | |||
| 2ddd34f343 | |||
| 564cbadc6e | |||
| 5a9920edb8 | |||
| 0e312f66ea | |||
| 8ca2ef28e6 | |||
| 0cd0139307 | |||
| 0041b4a7a7 | |||
| caa18f1661 | |||
| 946ced541c | |||
| fd0c4c2623 | |||
| 9f57ea4309 | |||
| 4c7a30a16d | |||
| 8029136251 | |||
| 2a3d898da1 | |||
| 0dd1f3ac2b | |||
| 2edd704e39 | |||
| e936ba1d26 | |||
| d6a9f4c549 | |||
| 2934d24e53 | |||
| aa65b96ef2 | |||
| b5bb3f36bf | |||
| 9f5c225cf9 | |||
| f0864adfe6 | |||
| 532fea38d5 | |||
| 83eb0cbf54 | |||
| 58e0330f4f | |||
| f47e1793a2 | |||
| 11e01335c2 | |||
| aa8accfbf8 | |||
| efc83bdc1a | |||
| f623a9967c | |||
| 5395eebaef | |||
| 7ffe4dd1d8 | |||
| 1d292d4688 | |||
| dd04d4ea46 | |||
| 3620cc9df0 | |||
| b06d6ff412 | |||
| 6088c835a3 | |||
| 8e3f4ce08d | |||
| 9b4262bb36 | |||
| 9113658a42 | |||
| d09503edf4 | |||
| 09124dafac | |||
| a2ede72798 | |||
| 61296b58e9 | |||
| e3f3c5620d | |||
| c656b3968b | |||
| 6d37d7df8e | |||
| 427f205a58 | |||
| 41f9b9b340 | |||
| 7d12b91bbd | |||
| 2960a4c48e | |||
| 4a84274055 | |||
| c34d89165c | |||
| f1b0a60b34 | |||
| abef9c9768 | |||
| c4b227f66e | |||
| 2389d7e62f | |||
| f5e16cda5e | |||
| 7ea415c082 | |||
| 90bfeb3dd2 | |||
| f8666cec45 | |||
| f6e5892de7 | |||
| 6d2d8ce149 | |||
| d38139be66 | |||
| 46d1ef7892 | |||
| 72bad6bb38 | |||
| 66fd484bd5 | |||
| a1328c96cf | |||
| 18aa4707a4 | |||
| dadfc412f2 | |||
| 3746975b14 | |||
| 2c90229fce | |||
| b461645d3d | |||
| f7f8b9b898 | |||
| 880d2d4edd | |||
| 7bc81a91c5 | |||
| 4ce652af95 | |||
| 8142e5c84c | |||
| 4efe712fc5 | |||
| 03f754cde4 | |||
| 8f53f095fb | |||
| a0c667927c | |||
| 0cc090038b | |||
| af32fe4022 | |||
| 9549d3b681 | |||
| 1be81b96b3 | |||
| eb2ac7630a | |||
| 189fd0ece4 | |||
| b6ccab79d2 | |||
| 93cc281abc | |||
| 1f83b6f4e8 | |||
| 5a96ef4ffe | |||
| dea3f7d4b3 | |||
| 40b2729a01 | |||
| 91f383d5ac | |||
| 268588daac | |||
| c0aff70b37 | |||
| 410ef85165 | |||
| 4af376cb33 | |||
| 66f012c70e | |||
| 198739a126 | |||
| 85a0a3d8b5 | |||
| 789525c35b | |||
| 7ad5ff7770 | |||
| bf56696adc | |||
| 193ea34efc | |||
| 9c0ca32033 | |||
| 76e49476a6 | |||
| 6d30ede01e | |||
| 02459f5d53 | |||
| 4c2c738bba | |||
| 9f2bff2d16 | |||
| ec8c67e67d | |||
| 41bbbed704 | |||
| a7f9cb7db0 | |||
| 14961d231e | |||
| 881602bd9b | |||
| ba48b71b23 | |||
| c1f2bf4f27 | |||
| 43bd1ba419 | |||
| 807e7e588f | |||
| 9d678b4f8a | |||
| 462c15887e | |||
| 60b1c1208a | |||
| 756aca36ad | |||
| 90c40b76f5 | |||
| 71a409cc0d | |||
| 6beb77e464 | |||
| 5f5ac4449c | |||
| bb0fb71a21 | |||
| 833a1b118e | |||
| 22dbdf0cd2 | |||
| 7e6a4c073f | |||
| 50c994d2ed | |||
| d151b907d1 | |||
| 77aa58083d | |||
| 13aeca9c88 | |||
| 3689b6df1a | |||
| d64613006c | |||
| 1582c13f62 | |||
| 554010b5cb | |||
| 60912ff8ef | |||
| a9c40e76dc | |||
| e9a0c6f8d0 | |||
| bcfea21501 | |||
| d073442cfe | |||
| a4bb4ec6c5 | |||
| 72553623a7 | |||
| 30165c10af | |||
| b9088a8dda | |||
| 01605534f7 | |||
| 082886ab19 | |||
| 9a592df4f0 | |||
| 2334109721 | |||
| bc21fa3a7e | |||
| aa7dd1ecf9 | |||
| 6122817ab6 | |||
| c667bb91c7 | |||
| e5ef62d7e7 | |||
| 8cf0b3adae | |||
| d0e51df59a | |||
| 11e3836599 | |||
| a10ebf342b | |||
| b072a080ae | |||
| 4b23cd94fd | |||
| 04fdc1dc60 | |||
| 27810d473d | |||
| d1160350b2 | |||
| 5d8c5224ed | |||
| 15af551139 | |||
| 0347a2bd89 | |||
| b26f70eb6a | |||
| bd10b17272 | |||
| 7b3a8d5bcd | |||
| 0e1548db72 | |||
| 2806931ca1 | |||
| 50e03d08bf |
@@ -3,7 +3,6 @@ name: cd-docs
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: master
|
||||
paths:
|
||||
- 'documentation/docs/**'
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: build
|
||||
args: --manifest-path ${{ env.CARGOTOML_PATH }} --lib --features custom-protocol
|
||||
args: --manifest-path ${{ env.CARGOTOML_PATH }} --features custom-protocol
|
||||
|
||||
# - name: Run all tests
|
||||
# uses: actions-rs/cargo@v1
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
# Simple workflow for deploying static content to GitHub Pages
|
||||
name: Deploy static content to Pages
|
||||
|
||||
on:
|
||||
# Runs on pushes targeting the default branch
|
||||
push:
|
||||
branches: ["feature/ppa-repo"]
|
||||
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
|
||||
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
# Single deploy job since we're just deploying
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v3
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v2
|
||||
with:
|
||||
# Upload entire repository
|
||||
path: './ppa'
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v2
|
||||
@@ -11,7 +11,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
rust: [stable, beta]
|
||||
os: [ubuntu-20.04, windows10, macos-latest]
|
||||
os: [ubuntu-20.04, windows-latest, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
|
||||
- name: Install Protoc
|
||||
uses: arduino/setup-protoc@v2
|
||||
if: matrix.os == 'macos-latest'
|
||||
if: matrix.os == 'macos-latest' || matrix.os == 'windows-latest'
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -56,11 +56,20 @@ jobs:
|
||||
command: build
|
||||
args: --release --workspace --examples
|
||||
|
||||
- name: Set debug to false
|
||||
# To avoid running out of disk space, skip generating debug symbols
|
||||
- name: Set debug to false (unix)
|
||||
if: matrix.os == 'ubuntu-20.04' || matrix.os == 'macos-latest'
|
||||
run: |
|
||||
sed -i.bak 's/\[profile.dev\]/\[profile.dev\]\ndebug = false/' Cargo.toml
|
||||
git diff
|
||||
|
||||
- name: Set debug to false (win)
|
||||
if: matrix.os == 'windows-latest'
|
||||
shell: pwsh
|
||||
run: |
|
||||
(Get-Content Cargo.toml) -replace '\[profile.dev\]', "`$&`ndebug = false" | Set-Content Cargo.toml
|
||||
git diff
|
||||
|
||||
- name: Run unit tests
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
@@ -73,6 +82,11 @@ jobs:
|
||||
command: test
|
||||
args: --workspace -- --ignored
|
||||
|
||||
- name: Clean
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: clean
|
||||
|
||||
- name: Clippy
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
name: nightly-nym-connect-build
|
||||
name: nightly-nym-connect-desktop-build
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
@@ -10,7 +10,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-20.04, macos-latest, windows10]
|
||||
os: [ubuntu-20.04, macos-latest, windows-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
@@ -10,7 +10,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-20.04, macos-latest, windows10]
|
||||
os: [ubuntu-20.04, macos-latest, windows-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
+3
-1
@@ -45,4 +45,6 @@ envs/qwerty.env
|
||||
cpu-cycles/libcpucycles/build
|
||||
foxyfox.env
|
||||
|
||||
.next
|
||||
.next
|
||||
ppa-private-key.b64
|
||||
ppa-private-key.asc
|
||||
@@ -4,6 +4,26 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [2023.nyxd-upgrade] (2023-11-22)
|
||||
|
||||
- Chore/nyxd 043 upgrade ([#3968])
|
||||
|
||||
[#3968]: https://github.com/nymtech/nym/pull/3968
|
||||
|
||||
## [2023.4-galaxy] (2023-11-07)
|
||||
|
||||
- DRY up client cli ([#4077])
|
||||
- [mixnode] replace rocket with axum ([#4071])
|
||||
- incorporate the nym node HTTP api into the mixnode ([#4070])
|
||||
- replaced '--disable-sign-ext' with '--signext-lowering' when running wasm-opt ([#3896])
|
||||
- Added PPA repo hosting support and nym-mixnode package with tooling for publishing ([#4165])
|
||||
|
||||
[#4077]: https://github.com/nymtech/nym/pull/4077
|
||||
[#4071]: https://github.com/nymtech/nym/pull/4071
|
||||
[#4070]: https://github.com/nymtech/nym/issues/4070
|
||||
[#3896]: https://github.com/nymtech/nym/pull/3896
|
||||
[#4165]: https://github.com/nymtech/nym/pull/4165
|
||||
|
||||
## [2023.3-kinder] (2023-10-31)
|
||||
|
||||
- suppress error output ([#4056])
|
||||
@@ -15,6 +35,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
||||
- use saturating sub in case outfox is not enabled ([#3986])
|
||||
- Fix sorting for mixnodes and gateways ([#3985])
|
||||
- Gateway client registry and api routes ([#3955])
|
||||
- Feature/configurable socks5 bind address ([#3992])
|
||||
|
||||
[#4056]: https://github.com/nymtech/nym/pull/4056
|
||||
[#4042]: https://github.com/nymtech/nym/pull/4042
|
||||
@@ -25,6 +46,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
||||
[#3986]: https://github.com/nymtech/nym/pull/3986
|
||||
[#3985]: https://github.com/nymtech/nym/pull/3985
|
||||
[#3955]: https://github.com/nymtech/nym/pull/3955
|
||||
[#3992]: https://github.com/nymtech/nym/pull/3992
|
||||
|
||||
## [2023.1-milka] (2023-09-24)
|
||||
|
||||
|
||||
Generated
+271
-126
@@ -1554,8 +1554,8 @@ version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2895653b4d9f1538a83970077cb01dfc77a4810524e51a110944688e916b18e"
|
||||
dependencies = [
|
||||
"prost",
|
||||
"prost-types",
|
||||
"prost 0.11.9",
|
||||
"prost-types 0.11.9",
|
||||
"tonic",
|
||||
"tracing-core",
|
||||
]
|
||||
@@ -1572,7 +1572,7 @@ dependencies = [
|
||||
"futures",
|
||||
"hdrhistogram",
|
||||
"humantime 2.1.0",
|
||||
"prost-types",
|
||||
"prost-types 0.11.9",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thread_local",
|
||||
@@ -1661,30 +1661,30 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cosmos-sdk-proto"
|
||||
version = "0.19.0"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73c9d2043a9e617b0d602fbc0a0ecd621568edbf3a9774890a6d562389bd8e1c"
|
||||
checksum = "32560304ab4c365791fd307282f76637213d8083c1a98490c35159cd67852237"
|
||||
dependencies = [
|
||||
"prost",
|
||||
"prost-types",
|
||||
"prost 0.12.1",
|
||||
"prost-types 0.12.1",
|
||||
"tendermint-proto",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cosmrs"
|
||||
version = "0.14.0"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af13955d6f356272e6def9ff5e2450a7650df536d8934f47052a20c76513d2f6"
|
||||
checksum = "47126f5364df9387b9d8559dcef62e99010e1d4098f39eb3f7ee4b5c254e40ea"
|
||||
dependencies = [
|
||||
"bip32",
|
||||
"cosmos-sdk-proto",
|
||||
"ecdsa 0.16.8",
|
||||
"eyre",
|
||||
"getrandom 0.2.10",
|
||||
"k256",
|
||||
"rand_core 0.6.4",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"signature 2.1.0",
|
||||
"subtle-encoding",
|
||||
"tendermint",
|
||||
"tendermint-rpc",
|
||||
@@ -2009,15 +2009,6 @@ dependencies = [
|
||||
"subtle 2.4.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ct-logs"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1a816186fa68d9e426e3cb4ae4dff1fcd8e4a2c34b781bf7a822574a0d0aac8"
|
||||
dependencies = [
|
||||
"sct 0.6.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctor"
|
||||
version = "0.1.26"
|
||||
@@ -2346,6 +2337,25 @@ dependencies = [
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "defguard_wireguard_rs"
|
||||
version = "0.3.0"
|
||||
source = "git+https://github.com/DefGuard/wireguard-rs?rev=d40df5c4e598918253682c42c4aa189d0ec2499a#d40df5c4e598918253682c42c4aa189d0ec2499a"
|
||||
dependencies = [
|
||||
"base64 0.21.4",
|
||||
"libc",
|
||||
"log",
|
||||
"netlink-packet-core 0.7.0",
|
||||
"netlink-packet-generic",
|
||||
"netlink-packet-route 0.17.1",
|
||||
"netlink-packet-utils",
|
||||
"netlink-packet-wireguard",
|
||||
"netlink-sys",
|
||||
"nix 0.27.1",
|
||||
"serde",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "der"
|
||||
version = "0.6.1"
|
||||
@@ -2994,7 +3004,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "extension-storage"
|
||||
version = "1.2.0"
|
||||
version = "1.2.4-rc.2"
|
||||
dependencies = [
|
||||
"bip39",
|
||||
"console_error_panic_hook",
|
||||
@@ -3696,30 +3706,6 @@ dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "headers"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270"
|
||||
dependencies = [
|
||||
"base64 0.21.4",
|
||||
"bytes",
|
||||
"headers-core",
|
||||
"http",
|
||||
"httpdate",
|
||||
"mime",
|
||||
"sha1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "headers-core"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429"
|
||||
dependencies = [
|
||||
"http",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.3.3"
|
||||
@@ -3958,40 +3944,17 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-proxy"
|
||||
version = "0.9.1"
|
||||
name = "hyper-rustls"
|
||||
version = "0.24.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca815a891b24fdfb243fa3239c86154392b0953ee584aa1a2a1f66d20cbe75cc"
|
||||
checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures",
|
||||
"headers",
|
||||
"futures-util",
|
||||
"http",
|
||||
"hyper",
|
||||
"hyper-rustls",
|
||||
"rustls-native-certs",
|
||||
"rustls 0.21.7",
|
||||
"tokio",
|
||||
"tokio-rustls 0.22.0",
|
||||
"tower-service",
|
||||
"webpki 0.21.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-rustls"
|
||||
version = "0.22.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64"
|
||||
dependencies = [
|
||||
"ct-logs",
|
||||
"futures-util",
|
||||
"hyper",
|
||||
"log",
|
||||
"rustls 0.19.1",
|
||||
"rustls-native-certs",
|
||||
"tokio",
|
||||
"tokio-rustls 0.22.0",
|
||||
"webpki 0.21.4",
|
||||
"webpki-roots 0.21.1",
|
||||
"tokio-rustls 0.24.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4282,6 +4245,15 @@ version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6"
|
||||
|
||||
[[package]]
|
||||
name = "ipnetwork"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8eca9f51da27bc908ef3dd85c21e1bbba794edaf94d7841e37356275b82d31e"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipnetwork"
|
||||
version = "0.18.0"
|
||||
@@ -4649,7 +4621,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"parking_lot 0.12.1",
|
||||
"pin-project",
|
||||
"prost",
|
||||
"prost 0.11.9",
|
||||
"prost-build",
|
||||
"rand 0.8.5",
|
||||
"rw-stream-sink 0.3.0 (git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6)",
|
||||
@@ -4735,7 +4707,7 @@ dependencies = [
|
||||
"libp2p-swarm 0.42.0",
|
||||
"log",
|
||||
"prometheus-client",
|
||||
"prost",
|
||||
"prost 0.11.9",
|
||||
"prost-build",
|
||||
"prost-codec",
|
||||
"rand 0.8.5",
|
||||
@@ -4793,7 +4765,7 @@ dependencies = [
|
||||
"libp2p-swarm 0.42.0",
|
||||
"log",
|
||||
"lru 0.9.0",
|
||||
"prost",
|
||||
"prost 0.11.9",
|
||||
"prost-build",
|
||||
"prost-codec",
|
||||
"smallvec",
|
||||
@@ -4943,7 +4915,7 @@ dependencies = [
|
||||
"libp2p-core 0.39.0",
|
||||
"log",
|
||||
"once_cell",
|
||||
"prost",
|
||||
"prost 0.11.9",
|
||||
"prost-build",
|
||||
"rand 0.8.5",
|
||||
"sha2 0.10.8",
|
||||
@@ -5195,7 +5167,7 @@ dependencies = [
|
||||
"libp2p-noise 0.42.0",
|
||||
"log",
|
||||
"multihash",
|
||||
"prost",
|
||||
"prost 0.11.9",
|
||||
"prost-build",
|
||||
"prost-codec",
|
||||
"rand 0.8.5",
|
||||
@@ -5559,12 +5531,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "mix-fetch-wasm"
|
||||
version = "1.2.0"
|
||||
version = "1.2.4-rc.2"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"futures",
|
||||
"http-api-client",
|
||||
"js-sys",
|
||||
"nym-bin-common",
|
||||
"nym-ordered-buffer",
|
||||
"nym-service-providers-common",
|
||||
"nym-socks5-requests",
|
||||
@@ -5740,6 +5713,29 @@ dependencies = [
|
||||
"netlink-packet-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "netlink-packet-core"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72724faf704479d67b388da142b186f916188505e7e0b26719019c525882eda4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"byteorder",
|
||||
"netlink-packet-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "netlink-packet-generic"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1cd7eb8ad331c84c6b8cb7f685b448133e5ad82e1ffd5acafac374af4a5a308b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"byteorder",
|
||||
"netlink-packet-core 0.7.0",
|
||||
"netlink-packet-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "netlink-packet-route"
|
||||
version = "0.12.0"
|
||||
@@ -5750,7 +5746,21 @@ dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"byteorder",
|
||||
"libc",
|
||||
"netlink-packet-core",
|
||||
"netlink-packet-core 0.4.2",
|
||||
"netlink-packet-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "netlink-packet-route"
|
||||
version = "0.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "053998cea5a306971f88580d0829e90f270f940befd7cf928da179d4187a5a66"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 1.3.2",
|
||||
"byteorder",
|
||||
"libc",
|
||||
"netlink-packet-core 0.7.0",
|
||||
"netlink-packet-utils",
|
||||
]
|
||||
|
||||
@@ -5766,6 +5776,20 @@ dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "netlink-packet-wireguard"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60b25b050ff1f6a1e23c6777b72db22790fe5b6b5ccfd3858672587a79876c8f"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"byteorder",
|
||||
"libc",
|
||||
"log",
|
||||
"netlink-packet-generic",
|
||||
"netlink-packet-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "netlink-proto"
|
||||
version = "0.10.0"
|
||||
@@ -5775,12 +5799,25 @@ dependencies = [
|
||||
"bytes",
|
||||
"futures",
|
||||
"log",
|
||||
"netlink-packet-core",
|
||||
"netlink-packet-core 0.4.2",
|
||||
"netlink-sys",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "netlink-request"
|
||||
version = "1.6.0"
|
||||
dependencies = [
|
||||
"netlink-packet-core 0.7.0",
|
||||
"netlink-packet-generic",
|
||||
"netlink-packet-route 0.17.1",
|
||||
"netlink-packet-utils",
|
||||
"netlink-sys",
|
||||
"nix 0.25.1",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "netlink-sys"
|
||||
version = "0.8.5"
|
||||
@@ -5816,6 +5853,8 @@ dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"memoffset 0.6.5",
|
||||
"pin-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5827,6 +5866,7 @@ dependencies = [
|
||||
"bitflags 2.4.1",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"memoffset 0.9.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5951,7 +5991,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-api"
|
||||
version = "1.1.32"
|
||||
version = "1.1.33"
|
||||
dependencies = [
|
||||
"actix-web",
|
||||
"anyhow",
|
||||
@@ -6101,7 +6141,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-cli"
|
||||
version = "1.1.31"
|
||||
version = "1.1.32"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64 0.13.1",
|
||||
@@ -6260,11 +6300,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-client-wasm"
|
||||
version = "1.2.0"
|
||||
version = "1.2.4-rc.2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"futures",
|
||||
"js-sys",
|
||||
"nym-bin-common",
|
||||
"nym-node-tester-utils",
|
||||
"nym-node-tester-wasm",
|
||||
"rand 0.7.3",
|
||||
@@ -6527,11 +6568,13 @@ dependencies = [
|
||||
"clap 4.4.7",
|
||||
"colored",
|
||||
"dashmap",
|
||||
"defguard_wireguard_rs",
|
||||
"dirs 4.0.0",
|
||||
"dotenvy",
|
||||
"futures",
|
||||
"humantime-serde",
|
||||
"hyper",
|
||||
"ipnetwork 0.16.0",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"nym-api-requests",
|
||||
@@ -6645,22 +6688,45 @@ dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-ip-packet-requests"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"bytes",
|
||||
"nym-sphinx",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-ip-packet-router"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"bytes",
|
||||
"etherparse",
|
||||
"futures",
|
||||
"log",
|
||||
"nym-bin-common",
|
||||
"nym-client-core",
|
||||
"nym-config",
|
||||
"nym-exit-policy",
|
||||
"nym-ip-packet-requests",
|
||||
"nym-network-requester",
|
||||
"nym-sdk",
|
||||
"nym-service-providers-common",
|
||||
"nym-sphinx",
|
||||
"nym-task",
|
||||
"nym-tun",
|
||||
"nym-wireguard",
|
||||
"nym-wireguard-types",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tap",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6698,7 +6764,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-mixnode"
|
||||
version = "1.1.32"
|
||||
version = "1.1.33"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"axum",
|
||||
@@ -6893,11 +6959,13 @@ dependencies = [
|
||||
"fastrand 2.0.1",
|
||||
"hmac 0.12.1",
|
||||
"hyper",
|
||||
"ipnetwork 0.16.0",
|
||||
"mime",
|
||||
"nym-config",
|
||||
"nym-crypto",
|
||||
"nym-node-requests",
|
||||
"nym-task",
|
||||
"nym-wireguard",
|
||||
"nym-wireguard-types",
|
||||
"rand 0.7.3",
|
||||
"serde",
|
||||
@@ -6953,7 +7021,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-node-tester-wasm"
|
||||
version = "1.2.0"
|
||||
version = "1.2.4-rc.2"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"js-sys",
|
||||
@@ -7440,6 +7508,18 @@ dependencies = [
|
||||
"wasm-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-tun"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"etherparse",
|
||||
"log",
|
||||
"nym-wireguard-types",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-tun",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-types"
|
||||
version = "1.0.0"
|
||||
@@ -7476,6 +7556,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base64 0.13.1",
|
||||
"bip32",
|
||||
"bip39",
|
||||
"colored",
|
||||
"cosmrs",
|
||||
@@ -7506,7 +7587,7 @@ dependencies = [
|
||||
"nym-service-provider-directory-common",
|
||||
"nym-vesting-contract-common",
|
||||
"openssl",
|
||||
"prost",
|
||||
"prost 0.12.1",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -7553,21 +7634,13 @@ dependencies = [
|
||||
"ts-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-wasm-sdk"
|
||||
version = "1.2.0"
|
||||
dependencies = [
|
||||
"mix-fetch-wasm",
|
||||
"nym-client-wasm",
|
||||
"nym-node-tester-wasm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-wireguard"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-recursion",
|
||||
"base64 0.21.4",
|
||||
"bincode",
|
||||
"boringtun",
|
||||
"bytes",
|
||||
"dashmap",
|
||||
@@ -7576,7 +7649,10 @@ dependencies = [
|
||||
"ip_network",
|
||||
"ip_network_table",
|
||||
"log",
|
||||
"nym-network-defaults",
|
||||
"nym-sphinx",
|
||||
"nym-task",
|
||||
"nym-tun",
|
||||
"nym-wireguard-types",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
@@ -7584,6 +7660,7 @@ dependencies = [
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-tun",
|
||||
"wireguard-control",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7592,14 +7669,19 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"base64 0.21.4",
|
||||
"boringtun",
|
||||
"bytes",
|
||||
"dashmap",
|
||||
"hmac 0.12.1",
|
||||
"ip_network",
|
||||
"ip_network_table",
|
||||
"log",
|
||||
"nym-crypto",
|
||||
"rand 0.7.3",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2 0.10.8",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"utoipa",
|
||||
"x25519-dalek 2.0.0",
|
||||
]
|
||||
@@ -8383,7 +8465,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"prost-derive",
|
||||
"prost-derive 0.11.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4fdd22f3b9c31b53c060df4a0613a1c7f062d4115a2b984dd15b1858f7e340d"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"prost-derive 0.12.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8400,8 +8492,8 @@ dependencies = [
|
||||
"multimap",
|
||||
"petgraph",
|
||||
"prettyplease",
|
||||
"prost",
|
||||
"prost-types",
|
||||
"prost 0.11.9",
|
||||
"prost-types 0.11.9",
|
||||
"regex",
|
||||
"syn 1.0.109",
|
||||
"tempfile",
|
||||
@@ -8415,7 +8507,7 @@ source = "git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c
|
||||
dependencies = [
|
||||
"asynchronous-codec",
|
||||
"bytes",
|
||||
"prost",
|
||||
"prost 0.11.9",
|
||||
"thiserror",
|
||||
"unsigned-varint",
|
||||
]
|
||||
@@ -8433,13 +8525,35 @@ dependencies = [
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-derive"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "265baba7fabd416cf5078179f7d2cbeca4ce7a9041111900675ea7c4cb8a4c32"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.11.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.38",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-types"
|
||||
version = "0.11.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13"
|
||||
dependencies = [
|
||||
"prost",
|
||||
"prost 0.11.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-types"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e081b29f63d83a4bc75cfc9f3fe424f9156cf92d8a4f0c9407cce9a1b67327cf"
|
||||
dependencies = [
|
||||
"prost 0.12.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8951,6 +9065,7 @@ dependencies = [
|
||||
"http",
|
||||
"http-body",
|
||||
"hyper",
|
||||
"hyper-rustls",
|
||||
"hyper-tls",
|
||||
"ipnet",
|
||||
"js-sys",
|
||||
@@ -8960,12 +9075,16 @@ dependencies = [
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"pin-project-lite 0.2.13",
|
||||
"rustls 0.21.7",
|
||||
"rustls-native-certs",
|
||||
"rustls-pemfile",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"system-configuration",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tokio-rustls 0.24.1",
|
||||
"tokio-socks",
|
||||
"tower-service",
|
||||
"url",
|
||||
@@ -9189,7 +9308,7 @@ checksum = "322c53fd76a18698f1c27381d58091de3a043d356aa5bd0d510608b565f469a0"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"log",
|
||||
"netlink-packet-route",
|
||||
"netlink-packet-route 0.12.0",
|
||||
"netlink-proto",
|
||||
"nix 0.24.3",
|
||||
"thiserror",
|
||||
@@ -9365,12 +9484,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustls-native-certs"
|
||||
version = "0.5.0"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a07b7c1885bd8ed3831c289b7870b13ef46fe0e856d288c30d9cc17d75a2092"
|
||||
checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00"
|
||||
dependencies = [
|
||||
"openssl-probe",
|
||||
"rustls 0.19.1",
|
||||
"rustls-pemfile",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
]
|
||||
@@ -9429,9 +9548,9 @@ checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
|
||||
|
||||
[[package]]
|
||||
name = "safer-ffi"
|
||||
version = "0.1.3"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9c1d19b288ca9898cd421c7b105fb7269918a7f8e9253a991e228981ca421ad"
|
||||
checksum = "395ace5aff9629c7268ca8255aceb945525b2cb644015f3caec5131a6a537c11"
|
||||
dependencies = [
|
||||
"inventory",
|
||||
"libc",
|
||||
@@ -9446,9 +9565,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "safer_ffi-proc_macros"
|
||||
version = "0.1.3"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2d7a04caa3ca2224f5ea4ddd850e2629c3b36b2b83621f87a8303bf41020110"
|
||||
checksum = "9255504d5467bae9e07d58b8de446ba6739b29bf72e1fa35b2387e30d29dcbfe"
|
||||
dependencies = [
|
||||
"macro_rules_attribute",
|
||||
"prettyplease",
|
||||
@@ -10571,9 +10690,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tendermint"
|
||||
version = "0.32.2"
|
||||
version = "0.34.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f0a7d05cf78524782337f8edd55cbc578d159a16ad4affe2135c92f7dbac7f0"
|
||||
checksum = "bc2294fa667c8b548ee27a9ba59115472d0a09c2ba255771092a7f1dcf03a789"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"digest 0.10.7",
|
||||
@@ -10584,8 +10703,8 @@ dependencies = [
|
||||
"k256",
|
||||
"num-traits",
|
||||
"once_cell",
|
||||
"prost",
|
||||
"prost-types",
|
||||
"prost 0.12.1",
|
||||
"prost-types 0.12.1",
|
||||
"ripemd",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
@@ -10602,9 +10721,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tendermint-config"
|
||||
version = "0.32.2"
|
||||
version = "0.34.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71a72dbbea6dde12045d261f2c70c0de039125675e8a026c8d5ad34522756372"
|
||||
checksum = "5a25dbe8b953e80f3d61789fbdb83bf9ad6c0ef16df5ca6546f49912542cc137"
|
||||
dependencies = [
|
||||
"flex-error",
|
||||
"serde",
|
||||
@@ -10616,16 +10735,16 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tendermint-proto"
|
||||
version = "0.32.2"
|
||||
version = "0.34.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0cec054567d16d85e8c3f6a3139963d1a66d9d3051ed545d31562550e9bcc3d"
|
||||
checksum = "2cc728a4f9e891d71adf66af6ecaece146f9c7a11312288a3107b3e1d6979aaf"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"flex-error",
|
||||
"num-derive",
|
||||
"num-traits",
|
||||
"prost",
|
||||
"prost-types",
|
||||
"prost 0.12.1",
|
||||
"prost-types 0.12.1",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
"subtle-encoding",
|
||||
@@ -10634,21 +10753,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tendermint-rpc"
|
||||
version = "0.32.2"
|
||||
version = "0.34.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d119d83a130537fc4a98c3c9eb6899ebe857fea4860400a61675bfb5f0b35129"
|
||||
checksum = "dfbf0a4753b46a190f367337e0163d0b552a2674a6bac54e74f9f2cdcde2969b"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"flex-error",
|
||||
"futures",
|
||||
"getrandom 0.2.10",
|
||||
"http",
|
||||
"hyper",
|
||||
"hyper-proxy",
|
||||
"hyper-rustls",
|
||||
"peg",
|
||||
"pin-project",
|
||||
"reqwest",
|
||||
"semver 1.0.20",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
@@ -10872,6 +10988,16 @@ dependencies = [
|
||||
"webpki 0.22.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-rustls"
|
||||
version = "0.24.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
|
||||
dependencies = [
|
||||
"rustls 0.21.7",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-socks"
|
||||
version = "0.5.1"
|
||||
@@ -11063,7 +11189,7 @@ dependencies = [
|
||||
"hyper-timeout",
|
||||
"percent-encoding",
|
||||
"pin-project",
|
||||
"prost",
|
||||
"prost 0.11.9",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tower",
|
||||
@@ -12447,6 +12573,25 @@ dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wireguard-control"
|
||||
version = "1.6.0"
|
||||
dependencies = [
|
||||
"base64 0.13.1",
|
||||
"hex",
|
||||
"libc",
|
||||
"log",
|
||||
"netlink-packet-core 0.7.0",
|
||||
"netlink-packet-generic",
|
||||
"netlink-packet-route 0.17.1",
|
||||
"netlink-packet-utils",
|
||||
"netlink-packet-wireguard",
|
||||
"netlink-request",
|
||||
"netlink-sys",
|
||||
"rand_core 0.6.4",
|
||||
"x25519-dalek 2.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "with_builtin_macros"
|
||||
version = "0.0.3"
|
||||
|
||||
+25
-17
@@ -49,6 +49,7 @@ members = [
|
||||
"common/exit-policy",
|
||||
"common/http-api-client",
|
||||
"common/inclusion-probability",
|
||||
"common/ip-packet-requests",
|
||||
"common/ledger",
|
||||
"common/mixnode-common",
|
||||
"common/network-defaults",
|
||||
@@ -74,6 +75,7 @@ members = [
|
||||
"common/store-cipher",
|
||||
"common/task",
|
||||
"common/topology",
|
||||
"common/tun",
|
||||
"common/types",
|
||||
"common/wasm/client-core",
|
||||
"common/wasm/storage",
|
||||
@@ -105,7 +107,7 @@ members = [
|
||||
"tools/nym-nr-query",
|
||||
"tools/ts-rs-cli",
|
||||
"wasm/client",
|
||||
"wasm/full-nym-wasm",
|
||||
# "wasm/full-nym-wasm",
|
||||
"wasm/mix-fetch",
|
||||
"wasm/node-tester",
|
||||
]
|
||||
@@ -140,21 +142,6 @@ bip39 = { version = "2.0.0", features = ["zeroize"] }
|
||||
boringtun = { git = "https://github.com/cloudflare/boringtun", rev = "e1d6360d6ab4529fc942a078e4c54df107abe2ba" }
|
||||
clap = "4.4.7"
|
||||
cfg-if = "1.0.0"
|
||||
cosmwasm-derive = "=1.3.0"
|
||||
cosmwasm-schema = "=1.3.0"
|
||||
cosmwasm-std = "=1.3.0"
|
||||
# use 0.5.0 as that's the version used by cosmwasm-std 1.3.0
|
||||
# (and ideally we don't want to pull the same dependency twice)
|
||||
serde-json-wasm = "=0.5.0"
|
||||
cosmwasm-storage = "=1.3.0"
|
||||
cosmrs = "=0.14.0"
|
||||
# same version as used by cosmrs
|
||||
cw-utils = "=1.0.1"
|
||||
cw-storage-plus = "=1.1.0"
|
||||
cw2 = { version = "=1.1.0" }
|
||||
cw3 = { version = "=1.1.0" }
|
||||
cw4 = { version = "=1.1.0" }
|
||||
cw-controllers = { version = "=1.1.0" }
|
||||
dashmap = "5.5.3"
|
||||
dotenvy = "0.15.6"
|
||||
futures = "0.3.28"
|
||||
@@ -172,7 +159,6 @@ schemars = "0.8.1"
|
||||
serde = "1.0.152"
|
||||
serde_json = "1.0.91"
|
||||
tap = "1.0.1"
|
||||
tendermint-rpc = "0.32" # same version as used by cosmrs
|
||||
thiserror = "1.0.48"
|
||||
tokio = "1.24.1"
|
||||
tokio-tungstenite = "0.20.1"
|
||||
@@ -184,6 +170,28 @@ utoipa-swagger-ui = "3.1.5"
|
||||
url = "2.4"
|
||||
zeroize = "1.6.0"
|
||||
|
||||
# cosmwasm-related
|
||||
cosmwasm-derive = "=1.3.0"
|
||||
cosmwasm-schema = "=1.3.0"
|
||||
cosmwasm-std = "=1.3.0"
|
||||
# use 0.5.0 as that's the version used by cosmwasm-std 1.3.0
|
||||
# (and ideally we don't want to pull the same dependency twice)
|
||||
serde-json-wasm = "=0.5.0"
|
||||
cosmwasm-storage = "=1.3.0"
|
||||
# same version as used by cosmwasm
|
||||
cw-utils = "=1.0.1"
|
||||
cw-storage-plus = "=1.1.0"
|
||||
cw2 = { version = "=1.1.0" }
|
||||
cw3 = { version = "=1.1.0" }
|
||||
cw4 = { version = "=1.1.0" }
|
||||
cw-controllers = { version = "=1.1.0" }
|
||||
|
||||
# cosmrs-related
|
||||
bip32 = "0.5.1"
|
||||
cosmrs = "=0.15.0"
|
||||
tendermint-rpc = "0.34" # same version as used by cosmrs
|
||||
prost = "0.12"
|
||||
|
||||
# wasm-related dependencies
|
||||
gloo-utils = "0.1.7"
|
||||
js-sys = "0.3.63"
|
||||
|
||||
@@ -104,7 +104,7 @@ sdk-wasm-build:
|
||||
$(MAKE) -C wasm/client
|
||||
$(MAKE) -C wasm/node-tester
|
||||
$(MAKE) -C wasm/mix-fetch
|
||||
$(MAKE) -C wasm/full-nym-wasm
|
||||
#$(MAKE) -C wasm/full-nym-wasm
|
||||
|
||||
# run this from npm/yarn to ensure tools are in the path, e.g. yarn build:sdk from root of repo
|
||||
sdk-typescript-build:
|
||||
@@ -114,7 +114,7 @@ sdk-typescript-build:
|
||||
yarn --cwd sdk/typescript/codegen/contract-clients build
|
||||
|
||||
# NOTE: These targets are part of the main workspace (but not as wasm32-unknown-unknown)
|
||||
WASM_CRATES = extension-storage nym-client-wasm nym-node-tester-wasm nym-wasm-sdk
|
||||
WASM_CRATES = extension-storage nym-client-wasm nym-node-tester-wasm
|
||||
|
||||
sdk-wasm-test:
|
||||
#cargo test $(addprefix -p , $(WASM_CRATES)) --target wasm32-unknown-unknown -- -Dwarnings
|
||||
@@ -168,3 +168,7 @@ generate-typescript:
|
||||
run-api-tests:
|
||||
cd nym-api/tests/functional_test && yarn test:qa
|
||||
|
||||
# Build debian package, and update PPA
|
||||
# Requires base64 encode GPG key to be set up in environment PPA_SIGNING_KEY
|
||||
deb:
|
||||
scripts/ppa.sh
|
||||
|
||||
@@ -15,7 +15,6 @@ The platform is composed of multiple Rust crates. Top-level executable binary cr
|
||||
* nym-explorer - a (projected) block explorer and (existing) mixnet viewer.
|
||||
* nym-wallet - a desktop wallet implemented using the [Tauri](https://tauri.studio/en/docs/about/intro) framework.
|
||||
|
||||
[](https://opensource.org/licenses/Apache-2.0)
|
||||
[](https://github.com/nymtech/nym/actions?query=branch%3Adevelop)
|
||||
|
||||
|
||||
@@ -83,4 +82,11 @@ where `s'` is stake `s` scaled over total token circulating supply.
|
||||
|
||||
### Licensing and copyright information
|
||||
|
||||
This program is available as open source under the terms of the Apache 2.0 license. However, some elements are being licensed under CC0-1.0 and MIT. For accurate information, please check individual files.
|
||||
This is a monorepo and components that make up Nym as a system are licensed individually, so for accurate information, please check individual files.
|
||||
|
||||
As a general approach, licensing is as follows this pattern:
|
||||
- applications and binaries are GPLv3
|
||||
- libraries and components are Apache 2.0 or MIT
|
||||
- documentation is Apache 2.0 or CC0-1.0
|
||||
|
||||
Again, for accurate information, please check individual files.
|
||||
|
||||
@@ -22,5 +22,10 @@ async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||
}
|
||||
setup_logging();
|
||||
|
||||
commands::execute(args).await
|
||||
if let Err(err) = commands::execute(args).await {
|
||||
log::error!("{err}");
|
||||
println!("An error occurred: {err}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -21,5 +21,10 @@ async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||
}
|
||||
setup_logging();
|
||||
|
||||
commands::execute(args).await
|
||||
if let Err(err) = commands::execute(args).await {
|
||||
log::error!("{err}");
|
||||
println!("An error occurred: {err}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ pub struct PersistedGatewayConfig {
|
||||
key_hash: Vec<u8>,
|
||||
|
||||
/// Actual gateway details being persisted.
|
||||
pub(crate) details: GatewayEndpointConfig,
|
||||
pub details: GatewayEndpointConfig,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
|
||||
+2
-1
@@ -263,7 +263,7 @@ impl ActionController {
|
||||
pub(super) async fn run_with_shutdown(&mut self, mut shutdown: nym_task::TaskClient) {
|
||||
debug!("Started ActionController with graceful shutdown support");
|
||||
|
||||
while !shutdown.is_shutdown() {
|
||||
loop {
|
||||
tokio::select! {
|
||||
action = self.incoming_actions.next() => match action {
|
||||
Some(action) => self.process_action(action),
|
||||
@@ -283,6 +283,7 @@ impl ActionController {
|
||||
},
|
||||
_ = shutdown.recv_with_delay() => {
|
||||
log::trace!("ActionController: Received shutdown");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -40,7 +40,7 @@ impl SentNotificationListener {
|
||||
pub(super) async fn run_with_shutdown(&mut self, mut shutdown: nym_task::TaskClient) {
|
||||
debug!("Started SentNotificationListener with graceful shutdown support");
|
||||
|
||||
while !shutdown.is_shutdown() {
|
||||
loop {
|
||||
tokio::select! {
|
||||
frag_id = self.sent_notifier.next() => match frag_id {
|
||||
Some(frag_id) => {
|
||||
@@ -53,6 +53,7 @@ impl SentNotificationListener {
|
||||
},
|
||||
_ = shutdown.recv_with_delay() => {
|
||||
log::trace!("SentNotificationListener: Received shutdown");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -500,11 +500,12 @@ where
|
||||
{
|
||||
let mut status_timer = tokio::time::interval(Duration::from_secs(5));
|
||||
|
||||
while !shutdown.is_shutdown() {
|
||||
loop {
|
||||
tokio::select! {
|
||||
biased;
|
||||
_ = shutdown.recv_with_delay() => {
|
||||
log::trace!("OutQueueControl: Received shutdown");
|
||||
break;
|
||||
}
|
||||
_ = status_timer.tick() => {
|
||||
self.log_status(&mut shutdown);
|
||||
|
||||
@@ -39,7 +39,7 @@ where
|
||||
mem_state: CombinedReplyStorage,
|
||||
mut shutdown: nym_task::TaskClient,
|
||||
) {
|
||||
use log::{debug, error, info, warn};
|
||||
use log::{debug, error, info};
|
||||
|
||||
debug!("Started PersistentReplyStorage");
|
||||
if let Err(err) = self.backend.start_storage_session().await {
|
||||
@@ -50,7 +50,7 @@ where
|
||||
shutdown.recv().await;
|
||||
|
||||
info!("PersistentReplyStorage is flushing all reply-related data to underlying storage");
|
||||
warn!("you MUST NOT forcefully shutdown now or you risk data corruption!");
|
||||
info!("you MUST NOT forcefully shutdown now or you risk data corruption!");
|
||||
if let Err(err) = self.backend.flush_surb_storage(&mem_state).await {
|
||||
error!("failed to flush our reply-related data to the persistent storage: {err}")
|
||||
} else {
|
||||
|
||||
@@ -15,34 +15,34 @@ pub enum ClientCoreError {
|
||||
#[error("I/O error: {0}")]
|
||||
IoError(#[from] std::io::Error),
|
||||
|
||||
#[error("Gateway client error ({gateway_id}): {source}")]
|
||||
#[error("gateway client error ({gateway_id}): {source}")]
|
||||
GatewayClientError {
|
||||
gateway_id: String,
|
||||
source: GatewayClientError,
|
||||
},
|
||||
|
||||
#[error("Custom gateway client error: {source}")]
|
||||
#[error("custom gateway client error: {source}")]
|
||||
ErasedGatewayClientError {
|
||||
#[from]
|
||||
source: ErasedGatewayError,
|
||||
},
|
||||
|
||||
#[error("Ed25519 error: {0}")]
|
||||
#[error("ed25519 error: {0}")]
|
||||
Ed25519RecoveryError(#[from] Ed25519RecoveryError),
|
||||
|
||||
#[error("Validator client error: {0}")]
|
||||
#[error("validator client error: {0}")]
|
||||
ValidatorClientError(#[from] ValidatorClientError),
|
||||
|
||||
#[error("No gateway with id: {0}")]
|
||||
#[error("no gateway with id: {0}")]
|
||||
NoGatewayWithId(String),
|
||||
|
||||
#[error("No gateways on network")]
|
||||
#[error("no gateways on network")]
|
||||
NoGatewaysOnNetwork,
|
||||
|
||||
#[error("List of nym apis is empty")]
|
||||
#[error("list of nym apis is empty")]
|
||||
ListOfNymApisIsEmpty,
|
||||
|
||||
#[error("The current network topology seem to be insufficient to route any packets through")]
|
||||
#[error("the current network topology seem to be insufficient to route any packets through")]
|
||||
InsufficientNetworkTopology(#[from] NymTopologyError),
|
||||
|
||||
#[error("experienced a failure with our reply surb persistent storage: {source}")]
|
||||
@@ -60,7 +60,7 @@ pub enum ClientCoreError {
|
||||
source: Box<dyn Error + Send + Sync>,
|
||||
},
|
||||
|
||||
#[error("The gateway id is invalid - {0}")]
|
||||
#[error("the gateway id is invalid - {0}")]
|
||||
UnableToCreatePublicKeyFromGatewayId(Ed25519RecoveryError),
|
||||
|
||||
#[error("The gateway is malformed: {source}")]
|
||||
@@ -79,23 +79,23 @@ pub enum ClientCoreError {
|
||||
#[error("failed to establish gateway connection (wasm)")]
|
||||
GatewayJsConnectionFailure,
|
||||
|
||||
#[error("Gateway connection was abruptly closed")]
|
||||
#[error("gateway connection was abruptly closed")]
|
||||
GatewayConnectionAbruptlyClosed,
|
||||
|
||||
#[error("Timed out while trying to establish gateway connection")]
|
||||
#[error("timed out while trying to establish gateway connection")]
|
||||
GatewayConnectionTimeout,
|
||||
|
||||
#[error("No ping measurements for the gateway ({identity}) performed")]
|
||||
#[error("no ping measurements for the gateway ({identity}) performed")]
|
||||
NoGatewayMeasurements { identity: String },
|
||||
|
||||
#[error("failed to register receiver for reconstructed mixnet messages")]
|
||||
FailedToRegisterReceiver,
|
||||
|
||||
#[error("Unexpected exit")]
|
||||
#[error("unexpected exit")]
|
||||
UnexpectedExit,
|
||||
|
||||
#[error(
|
||||
"This operation would have resulted in clients keys being overwritten without permission"
|
||||
"this operation would have resulted in clients keys being overwritten without permission"
|
||||
)]
|
||||
ForbiddenKeyOverwrite,
|
||||
|
||||
|
||||
@@ -68,13 +68,23 @@ pub async fn current_gateways<R: Rng>(
|
||||
log::trace!("Fetching list of gateways from: {nym_api}");
|
||||
|
||||
let gateways = client.get_cached_described_gateways().await?;
|
||||
log::debug!("Found {} gateways", gateways.len());
|
||||
log::trace!("Gateways: {:#?}", gateways);
|
||||
|
||||
let valid_gateways = gateways
|
||||
.into_iter()
|
||||
.filter_map(|gateway| gateway.try_into().ok())
|
||||
.collect::<Vec<gateway::Node>>();
|
||||
log::debug!("Ater checking validity: {}", valid_gateways.len());
|
||||
log::trace!("Valid gateways: {:#?}", valid_gateways);
|
||||
|
||||
// we were always filtering by version so I'm not removing that 'feature'
|
||||
let filtered_gateways = valid_gateways.filter_by_version(env!("CARGO_PKG_VERSION"));
|
||||
log::debug!("After filtering for version: {}", filtered_gateways.len());
|
||||
log::trace!("Filtered gateways: {:#?}", filtered_gateways);
|
||||
|
||||
log::info!("nym-api reports {} valid gateways", filtered_gateways.len());
|
||||
|
||||
Ok(filtered_gateways)
|
||||
}
|
||||
|
||||
|
||||
@@ -94,6 +94,8 @@ where
|
||||
D::StorageError: Send + Sync + 'static,
|
||||
T: DeserializeOwned + Serialize + Send + Sync,
|
||||
{
|
||||
log::trace!("Setting up new gateway");
|
||||
|
||||
// if we're setting up new gateway, failing to load existing information is fine.
|
||||
// as a matter of fact, it's only potentially a problem if we DO succeed
|
||||
if _load_gateway_details(details_store).await.is_ok() && !overwrite_data {
|
||||
@@ -210,6 +212,7 @@ where
|
||||
D::StorageError: Send + Sync + 'static,
|
||||
T: DeserializeOwned + Serialize + Send + Sync,
|
||||
{
|
||||
log::trace!("Setting up gateway");
|
||||
match setup {
|
||||
GatewaySetup::MustLoad => use_loaded_gateway_details(key_store, details_store).await,
|
||||
GatewaySetup::New {
|
||||
|
||||
@@ -45,13 +45,17 @@ cosmrs = { workspace = true, features = ["bip32", "cosmwasm"] }
|
||||
# import it just for the `Client` trait
|
||||
tendermint-rpc = { workspace = true }
|
||||
|
||||
# this is an extremely nasty import. we're explicitly bringing in bip32 so that via the magic (or curse, pick your poison)
|
||||
# of cargo's feature unification we'd get `bip32/std` meaning we'd get `std::error::Error` for the re-exported (via cosmrs) bip32::Error type
|
||||
bip32 = { workspace = true, default-features = false, features = ["std"] }
|
||||
|
||||
eyre = { version = "0.6" }
|
||||
cw-utils = { workspace = true }
|
||||
cw2 = { workspace = true }
|
||||
cw3 = { workspace = true }
|
||||
cw4 = { workspace = true }
|
||||
cw-controllers = { workspace = true }
|
||||
prost = { version = "0.11", default-features = false }
|
||||
prost = { workspace = true, default-features = false }
|
||||
flate2 = { version = "1.0.20" }
|
||||
sha2 = { version = "0.9.5" }
|
||||
itertools = { version = "0.10" }
|
||||
|
||||
@@ -20,12 +20,12 @@ impl CheckResponse for broadcast::tx_commit::Response {
|
||||
});
|
||||
}
|
||||
|
||||
if self.deliver_tx.code.is_err() {
|
||||
if self.tx_result.code.is_err() {
|
||||
return Err(NyxdError::BroadcastTxErrorDeliverTx {
|
||||
hash: self.hash,
|
||||
height: Some(self.height),
|
||||
code: self.deliver_tx.code.value(),
|
||||
raw_log: self.deliver_tx.log,
|
||||
code: self.tx_result.code.value(),
|
||||
raw_log: self.tx_result.log,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ pub mod gas_price;
|
||||
|
||||
pub type GasAdjustment = f32;
|
||||
|
||||
pub const DEFAULT_SIMULATED_GAS_MULTIPLIER: GasAdjustment = 1.3;
|
||||
pub const DEFAULT_SIMULATED_GAS_MULTIPLIER: GasAdjustment = 1.5;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct AutoFeeGrant {
|
||||
|
||||
@@ -34,7 +34,9 @@ pub use crate::nyxd::fee::Fee;
|
||||
pub use crate::rpc::TendermintRpcClient;
|
||||
pub use coin::Coin;
|
||||
pub use cosmrs::bank::MsgSend;
|
||||
pub use cosmrs::tendermint::abci::{response::DeliverTx, Event, EventAttribute};
|
||||
pub use cosmrs::tendermint::abci::{
|
||||
response::DeliverTx, types::ExecTxResult, Event, EventAttribute,
|
||||
};
|
||||
pub use cosmrs::tendermint::block::Height;
|
||||
pub use cosmrs::tendermint::hash::{self, Algorithm, Hash};
|
||||
pub use cosmrs::tendermint::validator::Info as TendermintValidatorInfo;
|
||||
|
||||
@@ -28,7 +28,7 @@ where
|
||||
U: TryInto<HttpClientUrl, Error = Error>,
|
||||
{
|
||||
HttpRpcClient::builder(url.try_into()?)
|
||||
.compat_mode(CompatMode::V0_34)
|
||||
.compat_mode(CompatMode::V0_37)
|
||||
.build()
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,8 @@ pub struct ReqwestRpcClient {
|
||||
impl ReqwestRpcClient {
|
||||
pub fn new(url: Url) -> Self {
|
||||
ReqwestRpcClient {
|
||||
compat: CompatMode::V0_34,
|
||||
// after updating to nyxd 0.42 and thus updating to cometbft, the compat mode changed
|
||||
compat: CompatMode::V0_37,
|
||||
inner: reqwest::Client::new(),
|
||||
url,
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
use clap::{Args, Subcommand};
|
||||
|
||||
pub mod update_config;
|
||||
pub mod update_cost_params;
|
||||
pub mod vesting_update_config;
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
@@ -20,7 +21,5 @@ pub enum MixnetOperatorsMixnodeSettingsCommands {
|
||||
/// Update mixnode configuration for a mixnode bonded with locked tokens
|
||||
VestingUpdateConfig(vesting_update_config::Args),
|
||||
/// Update mixnode cost parameters
|
||||
UpdateCostParameters,
|
||||
/// Update mixnode cost parameters for a mixnode bonded with locked tokens
|
||||
VestingUpdateCostParameters,
|
||||
UpdateCostParameters(update_cost_params::Args),
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::context::SigningClient;
|
||||
use clap::Parser;
|
||||
use cosmwasm_std::Uint128;
|
||||
use log::info;
|
||||
use nym_mixnet_contract_common::{MixNodeCostParams, Percent};
|
||||
use nym_validator_client::nyxd::contract_traits::MixnetSigningClient;
|
||||
use nym_validator_client::nyxd::CosmWasmCoin;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct Args {
|
||||
#[clap(
|
||||
long,
|
||||
help = "input your profit margin as follows; (so it would be 10, rather than 0.1)"
|
||||
)]
|
||||
pub profit_margin_percent: Option<u8>,
|
||||
|
||||
#[clap(
|
||||
long,
|
||||
help = "operating cost in current DENOMINATION (so it would be 'unym', rather than 'nym')"
|
||||
)]
|
||||
pub interval_operating_cost: Option<u128>,
|
||||
}
|
||||
|
||||
pub async fn update_cost_params(args: Args, client: SigningClient) {
|
||||
let denom = client.current_chain_details().mix_denom.base.as_str();
|
||||
|
||||
let cost_params = MixNodeCostParams {
|
||||
profit_margin_percent: Percent::from_percentage_value(
|
||||
args.profit_margin_percent.unwrap_or(10) as u64,
|
||||
)
|
||||
.unwrap(),
|
||||
interval_operating_cost: CosmWasmCoin {
|
||||
denom: denom.into(),
|
||||
amount: Uint128::new(args.interval_operating_cost.unwrap_or(40_000_000)),
|
||||
},
|
||||
};
|
||||
|
||||
info!("Starting mixnode params updating!");
|
||||
let res = client
|
||||
.update_mixnode_cost_params(cost_params, None)
|
||||
.await
|
||||
.expect("failed to update cost params");
|
||||
|
||||
info!("Cost params result: {:?}", res)
|
||||
}
|
||||
@@ -25,12 +25,20 @@ pub const DEFAULT_CONFIG_FILENAME: &str = "config.toml";
|
||||
|
||||
#[cfg(feature = "dirs")]
|
||||
pub fn must_get_home() -> PathBuf {
|
||||
dirs::home_dir().expect("Failed to evaluate $HOME value")
|
||||
if let Some(home_dir) = std::env::var_os("NYM_HOME_DIR") {
|
||||
home_dir.into()
|
||||
} else {
|
||||
dirs::home_dir().expect("Failed to evaluate $HOME value")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "dirs")]
|
||||
pub fn may_get_home() -> Option<PathBuf> {
|
||||
dirs::home_dir()
|
||||
if let Some(home_dir) = std::env::var_os("NYM_HOME_DIR") {
|
||||
Some(home_dir.into())
|
||||
} else {
|
||||
dirs::home_dir()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait NymConfigTemplate: Serialize {
|
||||
|
||||
@@ -142,7 +142,7 @@ pub fn funds_from_cosmos_msgs(msgs: Vec<CosmosMsg>) -> Option<Coin> {
|
||||
contract_addr: _,
|
||||
msg,
|
||||
funds: _,
|
||||
})) = msgs.get(0)
|
||||
})) = msgs.first()
|
||||
{
|
||||
if let Ok(ExecuteMsg::ReleaseFunds { funds }) = from_binary::<ExecuteMsg>(msg) {
|
||||
return Some(funds);
|
||||
|
||||
@@ -62,7 +62,7 @@ pub fn owner_from_cosmos_msgs(msgs: &[CosmosMsg]) -> Option<Addr> {
|
||||
contract_addr: _,
|
||||
msg,
|
||||
funds: _,
|
||||
})) = msgs.get(0)
|
||||
})) = msgs.first()
|
||||
{
|
||||
if let Ok(ExecuteMsg::VerifyVerificationKeyShare { owner, .. }) =
|
||||
from_binary::<ExecuteMsg>(msg)
|
||||
|
||||
@@ -49,7 +49,7 @@ impl Account {
|
||||
|
||||
pub fn period_duration(&self) -> Result<u64, VestingContractError> {
|
||||
self.periods
|
||||
.get(0)
|
||||
.first()
|
||||
.ok_or(VestingContractError::UnpopulatedVestingPeriods {
|
||||
owner: self.owner_address.clone(),
|
||||
})
|
||||
|
||||
@@ -115,11 +115,7 @@ impl Dealing {
|
||||
.map(|&node_index| polynomial.evaluate_at(&Scalar::from(node_index)).into())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let remote_share_key_pairs = shares
|
||||
.iter()
|
||||
.zip(receivers.values())
|
||||
.map(|(share, key)| (share, key))
|
||||
.collect::<Vec<_>>();
|
||||
let remote_share_key_pairs = shares.iter().zip(receivers.values()).collect::<Vec<_>>();
|
||||
let ordered_public_keys = receivers.values().copied().collect::<Vec<_>>();
|
||||
|
||||
let (ciphertexts, hazmat) = encrypt_shares(&remote_share_key_pairs, params, &mut rng);
|
||||
|
||||
@@ -11,7 +11,7 @@ use thiserror::Error;
|
||||
use tracing::warn;
|
||||
use url::Url;
|
||||
|
||||
pub const DEFAULT_TIMEOUT: Duration = Duration::from_secs(3);
|
||||
pub const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10);
|
||||
|
||||
pub type PathSegments<'a> = &'a [&'a str];
|
||||
pub type Params<'a, K, V> = &'a [(K, V)];
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
[package]
|
||||
name = "nym-ip-packet-requests"
|
||||
version = "0.1.0"
|
||||
authors.workspace = true
|
||||
repository.workspace = true
|
||||
homepage.workspace = true
|
||||
documentation.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
bincode = "1.3.3"
|
||||
bytes = "1.5.0"
|
||||
nym-sphinx = { path = "../nymsphinx" }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
@@ -0,0 +1,40 @@
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
pub struct TaggedIpPacket {
|
||||
pub packet: bytes::Bytes,
|
||||
pub return_address: nym_sphinx::addressing::clients::Recipient,
|
||||
pub return_mix_hops: Option<u8>,
|
||||
// pub return_mix_delays: Option<f64>,
|
||||
}
|
||||
|
||||
impl TaggedIpPacket {
|
||||
pub fn new(
|
||||
packet: bytes::Bytes,
|
||||
return_address: nym_sphinx::addressing::clients::Recipient,
|
||||
return_mix_hops: Option<u8>,
|
||||
) -> Self {
|
||||
TaggedIpPacket {
|
||||
packet,
|
||||
return_address,
|
||||
return_mix_hops,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_reconstructed_message(
|
||||
message: &nym_sphinx::receiver::ReconstructedMessage,
|
||||
) -> Result<Self, bincode::Error> {
|
||||
use bincode::Options;
|
||||
make_bincode_serializer().deserialize(&message.message)
|
||||
}
|
||||
|
||||
pub fn to_bytes(&self) -> Result<Vec<u8>, bincode::Error> {
|
||||
use bincode::Options;
|
||||
make_bincode_serializer().serialize(self)
|
||||
}
|
||||
}
|
||||
|
||||
fn make_bincode_serializer() -> impl bincode::Options {
|
||||
use bincode::Options;
|
||||
bincode::DefaultOptions::new()
|
||||
.with_big_endian()
|
||||
.with_varint_encoding()
|
||||
}
|
||||
@@ -476,3 +476,11 @@ pub const DEFAULT_NYM_NODE_HTTP_PORT: u16 = 8080;
|
||||
pub const TOTAL_SUPPLY: u128 = 1_000_000_000_000_000;
|
||||
|
||||
pub const DEFAULT_PROFIT_MARGIN: u8 = 10;
|
||||
|
||||
// WIREGUARD
|
||||
pub const WG_PORT: u16 = 51822;
|
||||
|
||||
// The interface used to route traffic
|
||||
pub const WG_TUN_BASE_NAME: &str = "nymwg";
|
||||
pub const WG_TUN_DEVICE_ADDRESS: &str = "10.1.0.1";
|
||||
pub const WG_TUN_DEVICE_NETMASK: &str = "255.255.255.0";
|
||||
|
||||
@@ -50,7 +50,7 @@ where
|
||||
impl Aggregatable for PartialSignature {
|
||||
fn aggregate(sigs: &[PartialSignature], indices: Option<&[u64]>) -> Result<Signature> {
|
||||
let h = sigs
|
||||
.get(0)
|
||||
.first()
|
||||
.ok_or_else(|| CoconutError::Aggregation("Empty set of signatures".to_string()))?
|
||||
.sig1();
|
||||
|
||||
|
||||
@@ -493,10 +493,13 @@ impl TaskClient {
|
||||
impl Drop for TaskClient {
|
||||
fn drop(&mut self) {
|
||||
if !self.mode.should_signal_on_drop() {
|
||||
self.log(Level::Debug, "the task client is getting dropped");
|
||||
self.log(
|
||||
Level::Trace,
|
||||
"the task client is getting dropped (but instructed to not signal)",
|
||||
);
|
||||
return;
|
||||
} else {
|
||||
self.log(Level::Info, "the task client is getting dropped");
|
||||
self.log(Level::Debug, "the task client is getting dropped");
|
||||
}
|
||||
|
||||
if !self.is_shutdown_poll() {
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
[package]
|
||||
name = "nym-tun"
|
||||
version = "0.1.0"
|
||||
authors.workspace = true
|
||||
repository.workspace = true
|
||||
homepage.workspace = true
|
||||
documentation.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
thiserror.workspace = true
|
||||
tokio = { workspace = true, features = ["rt-multi-thread", "net", "io-util", "time", "sync", "macros"] }
|
||||
etherparse = "0.13.0"
|
||||
log.workspace = true
|
||||
nym-wireguard-types = { path = "../wireguard-types", optional = true }
|
||||
|
||||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
tokio-tun = "0.9.0"
|
||||
|
||||
[features]
|
||||
wireguard = ["nym-wireguard-types"]
|
||||
@@ -0,0 +1,7 @@
|
||||
#[cfg(target_os = "linux")]
|
||||
mod linux;
|
||||
|
||||
pub mod tun_task_channel;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub use linux::tun_device;
|
||||
@@ -0,0 +1 @@
|
||||
pub mod tun_device;
|
||||
@@ -0,0 +1,289 @@
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
net::{IpAddr, Ipv4Addr},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use etherparse::{InternetSlice, SlicedPacket};
|
||||
use tokio::{
|
||||
io::{AsyncReadExt, AsyncWriteExt},
|
||||
time::timeout,
|
||||
};
|
||||
|
||||
use crate::tun_task_channel::{
|
||||
tun_task_channel, tun_task_response_channel, TunTaskPayload, TunTaskResponseRx,
|
||||
TunTaskResponseSendError, TunTaskResponseTx, TunTaskRx, TunTaskTx,
|
||||
};
|
||||
|
||||
#[cfg(feature = "wireguard")]
|
||||
use nym_wireguard_types::tun_common::{
|
||||
active_peers::{PeerEventSenderError, PeersByIp},
|
||||
event::Event,
|
||||
};
|
||||
|
||||
#[cfg(feature = "wireguard")]
|
||||
const MUTEX_LOCK_TIMEOUT_MS: u64 = 200;
|
||||
const TUN_WRITE_TIMEOUT_MS: u64 = 1000;
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum TunDeviceError {
|
||||
#[error("timeout writing to tun device, dropping packet")]
|
||||
TunWriteTimeout,
|
||||
|
||||
#[error("error writing to tun device: {source}")]
|
||||
TunWriteError { source: std::io::Error },
|
||||
|
||||
#[cfg(feature = "wireguard")]
|
||||
#[error("failed forwarding packet to peer: {source}")]
|
||||
ForwardToPeerFailed {
|
||||
#[from]
|
||||
source: PeerEventSenderError,
|
||||
},
|
||||
|
||||
#[error("failed to forward responding packet with tag: {source}")]
|
||||
ForwardNatResponseFailed {
|
||||
#[from]
|
||||
source: TunTaskResponseSendError,
|
||||
},
|
||||
|
||||
#[error("unable to parse headers in packet")]
|
||||
UnableToParseHeaders {
|
||||
#[from]
|
||||
source: etherparse::ReadError,
|
||||
},
|
||||
|
||||
#[error("unable to parse src and dst address from packet: ip header missing")]
|
||||
UnableToParseAddressIpHeaderMissing,
|
||||
|
||||
#[error("unable to lock peer mutex")]
|
||||
FailedToLockPeer,
|
||||
}
|
||||
|
||||
fn setup_tokio_tun_device(name: &str, address: Ipv4Addr, netmask: Ipv4Addr) -> tokio_tun::Tun {
|
||||
log::info!("Creating TUN device with: address={address}, netmask={netmask}");
|
||||
// Read MTU size from env variable NYM_MTU_SIZE, else default to 1420.
|
||||
let mtu = std::env::var("NYM_MTU_SIZE")
|
||||
.map(|mtu| mtu.parse().expect("NYM_MTU_SIZE must be a valid integer"))
|
||||
.unwrap_or(1420);
|
||||
log::info!("Using MTU size: {mtu}");
|
||||
tokio_tun::Tun::builder()
|
||||
.name(name)
|
||||
.tap(false)
|
||||
.packet_info(false)
|
||||
.mtu(mtu)
|
||||
.up()
|
||||
.address(address)
|
||||
.netmask(netmask)
|
||||
.try_build()
|
||||
.expect("Failed to setup tun device, do you have permission?")
|
||||
}
|
||||
|
||||
pub struct TunDevice {
|
||||
// The TUN device that we read/write to, to send/receive packets
|
||||
tun: tokio_tun::Tun,
|
||||
|
||||
// Incoming data that we should send
|
||||
tun_task_rx: TunTaskRx,
|
||||
|
||||
// And when we get replies, this is where we should send it
|
||||
tun_task_response_tx: TunTaskResponseTx,
|
||||
|
||||
routing_mode: RoutingMode,
|
||||
}
|
||||
|
||||
pub enum RoutingMode {
|
||||
// The routing table, as how wireguard does it
|
||||
#[cfg(feature = "wireguard")]
|
||||
AllowedIps(AllowedIpsInner),
|
||||
|
||||
// This is an alternative to the routing table, where we just match outgoing source IP with
|
||||
// incoming destination IP.
|
||||
Nat(NatInner),
|
||||
}
|
||||
|
||||
impl RoutingMode {
|
||||
pub fn new_nat() -> Self {
|
||||
RoutingMode::Nat(NatInner {
|
||||
nat_table: HashMap::new(),
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "wireguard")]
|
||||
pub fn new_allowed_ips(peers_by_ip: std::sync::Arc<tokio::sync::Mutex<PeersByIp>>) -> Self {
|
||||
RoutingMode::AllowedIps(AllowedIpsInner { peers_by_ip })
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "wireguard")]
|
||||
pub struct AllowedIpsInner {
|
||||
peers_by_ip: std::sync::Arc<tokio::sync::Mutex<PeersByIp>>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "wireguard")]
|
||||
impl AllowedIpsInner {
|
||||
async fn lock(&self) -> Result<tokio::sync::MutexGuard<PeersByIp>, TunDeviceError> {
|
||||
timeout(
|
||||
Duration::from_millis(MUTEX_LOCK_TIMEOUT_MS),
|
||||
self.peers_by_ip.as_ref().lock(),
|
||||
)
|
||||
.await
|
||||
.map_err(|_| TunDeviceError::FailedToLockPeer)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NatInner {
|
||||
nat_table: HashMap<IpAddr, u64>,
|
||||
}
|
||||
|
||||
pub struct TunDeviceConfig {
|
||||
pub base_name: String,
|
||||
pub ip: Ipv4Addr,
|
||||
pub netmask: Ipv4Addr,
|
||||
}
|
||||
|
||||
impl TunDevice {
|
||||
pub fn new(
|
||||
routing_mode: RoutingMode,
|
||||
config: TunDeviceConfig,
|
||||
) -> (Self, TunTaskTx, TunTaskResponseRx) {
|
||||
let TunDeviceConfig {
|
||||
base_name,
|
||||
ip,
|
||||
netmask,
|
||||
} = config;
|
||||
let name = format!("{base_name}%d");
|
||||
|
||||
let tun = setup_tokio_tun_device(&name, ip, netmask);
|
||||
log::info!("Created TUN device: {}", tun.name());
|
||||
|
||||
// Channels to communicate with the other tasks
|
||||
let (tun_task_tx, tun_task_rx) = tun_task_channel();
|
||||
let (tun_task_response_tx, tun_task_response_rx) = tun_task_response_channel();
|
||||
|
||||
let tun_device = TunDevice {
|
||||
tun_task_rx,
|
||||
tun_task_response_tx,
|
||||
tun,
|
||||
routing_mode,
|
||||
};
|
||||
|
||||
(tun_device, tun_task_tx, tun_task_response_rx)
|
||||
}
|
||||
|
||||
// Send outbound packets out on the wild internet
|
||||
async fn handle_tun_write(&mut self, data: TunTaskPayload) -> Result<(), TunDeviceError> {
|
||||
let (tag, packet) = data;
|
||||
let ParsedAddresses { src_addr, dst_addr } = parse_src_dst_address(&packet)?;
|
||||
log::debug!(
|
||||
"iface: write Packet({src_addr} -> {dst_addr}, {} bytes)",
|
||||
packet.len()
|
||||
);
|
||||
|
||||
// TODO: expire old entries
|
||||
#[allow(irrefutable_let_patterns)]
|
||||
if let RoutingMode::Nat(nat_table) = &mut self.routing_mode {
|
||||
nat_table.nat_table.insert(src_addr, tag);
|
||||
}
|
||||
|
||||
timeout(
|
||||
Duration::from_millis(TUN_WRITE_TIMEOUT_MS),
|
||||
self.tun.write_all(&packet),
|
||||
)
|
||||
.await
|
||||
.map_err(|_| TunDeviceError::TunWriteTimeout)?
|
||||
.map_err(|err| TunDeviceError::TunWriteError { source: err })
|
||||
}
|
||||
|
||||
// Receive reponse packets from the wild internet
|
||||
async fn handle_tun_read(&self, packet: &[u8]) -> Result<(), TunDeviceError> {
|
||||
let ParsedAddresses { src_addr, dst_addr } = parse_src_dst_address(packet)?;
|
||||
log::debug!(
|
||||
"iface: read Packet({src_addr} -> {dst_addr}, {} bytes)",
|
||||
packet.len(),
|
||||
);
|
||||
|
||||
// Route packet to the correct peer.
|
||||
|
||||
match self.routing_mode {
|
||||
// This is how wireguard does it, by consulting the AllowedIPs table.
|
||||
#[cfg(feature = "wireguard")]
|
||||
RoutingMode::AllowedIps(ref peers_by_ip) => {
|
||||
let peers = peers_by_ip.lock().await?;
|
||||
if let Some(peer_tx) = peers.longest_match(dst_addr).map(|(_, tx)| tx) {
|
||||
log::debug!("Forward packet to wg tunnel");
|
||||
return peer_tx
|
||||
.send(Event::Ip(packet.to_vec().into()))
|
||||
.await
|
||||
.map_err(|err| err.into());
|
||||
}
|
||||
}
|
||||
|
||||
// But we can also do it by consulting the NAT table.
|
||||
RoutingMode::Nat(ref nat_table) => {
|
||||
if let Some(tag) = nat_table.nat_table.get(&dst_addr) {
|
||||
log::debug!("Forward packet with NAT tag: {tag}");
|
||||
return self
|
||||
.tun_task_response_tx
|
||||
.try_send((*tag, packet.to_vec()))
|
||||
.map_err(|err| err.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log::info!("No peer found, packet dropped");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn run(mut self) {
|
||||
let mut buf = [0u8; 65535];
|
||||
|
||||
loop {
|
||||
tokio::select! {
|
||||
// Reading from the TUN device
|
||||
len = self.tun.read(&mut buf) => match len {
|
||||
Ok(len) => {
|
||||
let packet = &buf[..len];
|
||||
if let Err(err) = self.handle_tun_read(packet).await {
|
||||
log::error!("iface: handle_tun_read failed: {err}")
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
log::info!("iface: read error: {err}");
|
||||
// break;
|
||||
}
|
||||
},
|
||||
// Writing to the TUN device
|
||||
Some(data) = self.tun_task_rx.recv() => {
|
||||
if let Err(err) = self.handle_tun_write(data).await {
|
||||
log::error!("ifcae: handle_tun_write failed: {err}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// log::info!("TUN device shutting down");
|
||||
}
|
||||
|
||||
pub fn start(self) {
|
||||
tokio::spawn(async move { self.run().await });
|
||||
}
|
||||
}
|
||||
|
||||
struct ParsedAddresses {
|
||||
src_addr: IpAddr,
|
||||
dst_addr: IpAddr,
|
||||
}
|
||||
|
||||
fn parse_src_dst_address(packet: &[u8]) -> Result<ParsedAddresses, TunDeviceError> {
|
||||
let headers = SlicedPacket::from_ip(packet)?;
|
||||
match headers.ip {
|
||||
Some(InternetSlice::Ipv4(ip, _)) => Ok(ParsedAddresses {
|
||||
src_addr: ip.source_addr().into(),
|
||||
dst_addr: ip.destination_addr().into(),
|
||||
}),
|
||||
Some(InternetSlice::Ipv6(ip, _)) => Ok(ParsedAddresses {
|
||||
src_addr: ip.source_addr().into(),
|
||||
dst_addr: ip.destination_addr().into(),
|
||||
}),
|
||||
None => Err(TunDeviceError::UnableToParseAddressIpHeaderMissing),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
#![cfg_attr(not(target_os = "linux"), allow(dead_code))]
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
use tokio::sync::mpsc::{
|
||||
self,
|
||||
error::{SendError, SendTimeoutError, TrySendError},
|
||||
};
|
||||
|
||||
pub(crate) type TunTaskPayload = (u64, Vec<u8>);
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TunTaskTx(mpsc::Sender<TunTaskPayload>);
|
||||
pub(crate) struct TunTaskRx(mpsc::Receiver<TunTaskPayload>);
|
||||
|
||||
impl TunTaskTx {
|
||||
pub async fn send(&self, data: TunTaskPayload) -> Result<(), SendError<TunTaskPayload>> {
|
||||
self.0.send(data).await
|
||||
}
|
||||
|
||||
pub fn try_send(&self, data: TunTaskPayload) -> Result<(), TrySendError<TunTaskPayload>> {
|
||||
self.0.try_send(data)
|
||||
}
|
||||
}
|
||||
|
||||
impl TunTaskRx {
|
||||
pub(crate) async fn recv(&mut self) -> Option<TunTaskPayload> {
|
||||
self.0.recv().await
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn tun_task_channel() -> (TunTaskTx, TunTaskRx) {
|
||||
let (tun_task_tx, tun_task_rx) = tokio::sync::mpsc::channel(128);
|
||||
(TunTaskTx(tun_task_tx), TunTaskRx(tun_task_rx))
|
||||
}
|
||||
|
||||
const TUN_TASK_RESPONSE_SEND_TIMEOUT_MS: u64 = 1_000;
|
||||
|
||||
// Send responses back from the tun device back to the PacketRelayer
|
||||
pub(crate) struct TunTaskResponseTx(mpsc::Sender<TunTaskPayload>);
|
||||
pub struct TunTaskResponseRx(mpsc::Receiver<TunTaskPayload>);
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum TunTaskResponseSendError {
|
||||
#[error("failed to send tun response: {0}")]
|
||||
SendTimeoutError(#[from] SendTimeoutError<TunTaskPayload>),
|
||||
|
||||
#[error("failed to send tun response: {0}")]
|
||||
SendError(#[from] SendError<TunTaskPayload>),
|
||||
|
||||
#[error("failed to send tun response: {0}")]
|
||||
TrySendError(#[from] TrySendError<TunTaskPayload>),
|
||||
}
|
||||
|
||||
impl TunTaskResponseTx {
|
||||
#[allow(unused)]
|
||||
pub(crate) async fn send(&self, data: TunTaskPayload) -> Result<(), TunTaskResponseSendError> {
|
||||
Ok(self
|
||||
.0
|
||||
.send_timeout(
|
||||
data,
|
||||
Duration::from_millis(TUN_TASK_RESPONSE_SEND_TIMEOUT_MS),
|
||||
)
|
||||
.await?)
|
||||
}
|
||||
|
||||
pub(crate) fn try_send(&self, data: TunTaskPayload) -> Result<(), TunTaskResponseSendError> {
|
||||
Ok(self.0.try_send(data)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl TunTaskResponseRx {
|
||||
pub async fn recv(&mut self) -> Option<TunTaskPayload> {
|
||||
self.0.recv().await
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn tun_task_response_channel() -> (TunTaskResponseTx, TunTaskResponseRx) {
|
||||
let (tun_task_tx, tun_task_rx) = tokio::sync::mpsc::channel(128);
|
||||
(
|
||||
TunTaskResponseTx(tun_task_tx),
|
||||
TunTaskResponseRx(tun_task_rx),
|
||||
)
|
||||
}
|
||||
@@ -12,9 +12,14 @@ license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
base64 = { workspace = true }
|
||||
bytes = "1.5.0"
|
||||
dashmap = { workspace = true }
|
||||
ip_network = "0.4.1"
|
||||
ip_network_table = "0.2.0"
|
||||
log = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
thiserror = { workspace = true }
|
||||
tokio = { workspace = true, features = ["sync", "time"] }
|
||||
|
||||
nym-crypto = { path = "../crypto", features = ["asymmetric"] }
|
||||
|
||||
@@ -45,4 +50,4 @@ nym-crypto = { path = "../crypto", features = ["rand"]}
|
||||
default = ["verify"]
|
||||
openapi = ["utoipa", "serde_json"]
|
||||
# this is moved to a separate feature as we really need clients to import it (especially, *cough*, wasm)
|
||||
verify = ["hmac", "sha2"]
|
||||
verify = ["hmac", "sha2"]
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
pub mod error;
|
||||
pub mod public_key;
|
||||
pub mod registration;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub mod tun_common;
|
||||
|
||||
pub use error::Error;
|
||||
pub use public_key::PeerPublicKey;
|
||||
@@ -13,5 +15,3 @@ pub use registration::{
|
||||
|
||||
#[cfg(feature = "verify")]
|
||||
pub use registration::HmacSha256;
|
||||
|
||||
pub const WG_PORT: u16 = 51822;
|
||||
|
||||
@@ -6,6 +6,7 @@ use crate::PeerPublicKey;
|
||||
use base64::{engine::general_purpose, Engine};
|
||||
use dashmap::DashMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::net::IpAddr;
|
||||
use std::{fmt, ops::Deref, str::FromStr};
|
||||
|
||||
#[cfg(feature = "verify")]
|
||||
@@ -17,11 +18,13 @@ use sha2::Sha256;
|
||||
|
||||
pub type GatewayClientRegistry = DashMap<PeerPublicKey, GatewayClient>;
|
||||
pub type PendingRegistrations = DashMap<PeerPublicKey, Nonce>;
|
||||
pub type PrivateIPs = DashMap<IpAddr, Free>;
|
||||
|
||||
#[cfg(feature = "verify")]
|
||||
pub type HmacSha256 = Hmac<Sha256>;
|
||||
|
||||
pub type Nonce = u64;
|
||||
pub type Free = bool;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
#[serde(tag = "type", rename_all = "camelCase")]
|
||||
@@ -72,6 +75,9 @@ pub struct GatewayClient {
|
||||
#[cfg_attr(feature = "openapi", schema(value_type = String, format = Byte))]
|
||||
pub pub_key: PeerPublicKey,
|
||||
|
||||
/// Assigned private IP
|
||||
pub private_ip: IpAddr,
|
||||
|
||||
/// Sha256 hmac on the data (alongside the prior nonce)
|
||||
#[cfg_attr(feature = "openapi", schema(value_type = String, format = Byte))]
|
||||
pub mac: ClientMac,
|
||||
@@ -79,11 +85,15 @@ pub struct GatewayClient {
|
||||
|
||||
impl GatewayClient {
|
||||
#[cfg(feature = "verify")]
|
||||
pub fn new(local_secret: &PrivateKey, remote_public: PublicKey, nonce: u64) -> Self {
|
||||
pub fn new(
|
||||
local_secret: &PrivateKey,
|
||||
remote_public: PublicKey,
|
||||
private_ip: IpAddr,
|
||||
nonce: u64,
|
||||
) -> Self {
|
||||
// convert from 1.0 x25519-dalek private key into 2.0 x25519-dalek
|
||||
#[allow(clippy::expect_used)]
|
||||
let static_secret = boringtun::x25519::StaticSecret::try_from(local_secret.to_bytes())
|
||||
.expect("conversion between x25519 private keys is infallible");
|
||||
let static_secret = boringtun::x25519::StaticSecret::from(local_secret.to_bytes());
|
||||
let local_public: boringtun::x25519::PublicKey = (&static_secret).into();
|
||||
|
||||
let remote_public = boringtun::x25519::PublicKey::from(remote_public.to_bytes());
|
||||
@@ -96,10 +106,12 @@ impl GatewayClient {
|
||||
.expect("x25519 shared secret is always 32 bytes long");
|
||||
|
||||
mac.update(local_public.as_bytes());
|
||||
mac.update(private_ip.to_string().as_bytes());
|
||||
mac.update(&nonce.to_le_bytes());
|
||||
|
||||
GatewayClient {
|
||||
pub_key: PeerPublicKey::new(local_public),
|
||||
private_ip,
|
||||
mac: ClientMac(mac.finalize().into_bytes().to_vec()),
|
||||
}
|
||||
}
|
||||
@@ -110,8 +122,7 @@ impl GatewayClient {
|
||||
pub fn verify(&self, gateway_key: &PrivateKey, nonce: u64) -> Result<(), Error> {
|
||||
// convert from 1.0 x25519-dalek private key into 2.0 x25519-dalek
|
||||
#[allow(clippy::expect_used)]
|
||||
let static_secret = boringtun::x25519::StaticSecret::try_from(gateway_key.to_bytes())
|
||||
.expect("conversion between x25519 private keys is infallible");
|
||||
let static_secret = boringtun::x25519::StaticSecret::from(gateway_key.to_bytes());
|
||||
|
||||
let dh = static_secret.diffie_hellman(&self.pub_key);
|
||||
|
||||
@@ -121,6 +132,7 @@ impl GatewayClient {
|
||||
.expect("x25519 shared secret is always 32 bytes long");
|
||||
|
||||
mac.update(self.pub_key.as_bytes());
|
||||
mac.update(self.private_ip.to_string().as_bytes());
|
||||
mac.update(&nonce.to_le_bytes());
|
||||
|
||||
mac.verify_slice(&self.mac)
|
||||
@@ -209,6 +221,7 @@ mod tests {
|
||||
let client = GatewayClient::new(
|
||||
client_key_pair.private_key(),
|
||||
*gateway_key_pair.public_key(),
|
||||
"10.0.0.42".parse().unwrap(),
|
||||
nonce,
|
||||
);
|
||||
assert!(client.verify(gateway_key_pair.private_key(), nonce).is_ok())
|
||||
|
||||
+33
-15
@@ -1,4 +1,4 @@
|
||||
use std::net::SocketAddr;
|
||||
use std::{net::SocketAddr, time::Duration};
|
||||
|
||||
use boringtun::x25519;
|
||||
use dashmap::{
|
||||
@@ -7,26 +7,47 @@ use dashmap::{
|
||||
};
|
||||
use tokio::sync::mpsc::{self};
|
||||
|
||||
use crate::event::Event;
|
||||
use crate::tun_common::{event::Event, network_table::NetworkTable};
|
||||
|
||||
// Registered peers
|
||||
pub type PeersByIp = NetworkTable<PeerEventSender>;
|
||||
|
||||
// Channels that are used to communicate with the various tunnels
|
||||
#[derive(Clone)]
|
||||
pub struct PeerEventSender(mpsc::Sender<Event>);
|
||||
pub(crate) struct PeerEventReceiver(mpsc::Receiver<Event>);
|
||||
pub struct PeerEventReceiver(mpsc::Receiver<Event>);
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum PeerEventSenderError {
|
||||
#[error("send failed: timeout: {source}")]
|
||||
SendTimeoutError {
|
||||
#[from]
|
||||
source: mpsc::error::SendTimeoutError<Event>,
|
||||
},
|
||||
|
||||
#[error("send failed: {source}")]
|
||||
SendError {
|
||||
#[from]
|
||||
source: mpsc::error::SendError<Event>,
|
||||
},
|
||||
}
|
||||
|
||||
impl PeerEventSender {
|
||||
pub(crate) async fn send(&self, event: Event) -> Result<(), mpsc::error::SendError<Event>> {
|
||||
self.0.send(event).await
|
||||
pub async fn send(&self, event: Event) -> Result<(), PeerEventSenderError> {
|
||||
Ok(self
|
||||
.0
|
||||
.send_timeout(event, Duration::from_millis(1000))
|
||||
.await?)
|
||||
}
|
||||
}
|
||||
|
||||
impl PeerEventReceiver {
|
||||
pub(crate) async fn recv(&mut self) -> Option<Event> {
|
||||
pub async fn recv(&mut self) -> Option<Event> {
|
||||
self.0.recv().await
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn peer_event_channel() -> (PeerEventSender, PeerEventReceiver) {
|
||||
pub fn peer_event_channel() -> (PeerEventSender, PeerEventReceiver) {
|
||||
let (tx, rx) = mpsc::channel(16);
|
||||
(PeerEventSender(tx), PeerEventReceiver(rx))
|
||||
}
|
||||
@@ -35,20 +56,20 @@ pub(crate) type PeersByKey = DashMap<x25519::PublicKey, PeerEventSender>;
|
||||
pub(crate) type PeersByAddr = DashMap<SocketAddr, PeerEventSender>;
|
||||
|
||||
#[derive(Default)]
|
||||
pub(crate) struct ActivePeers {
|
||||
pub struct ActivePeers {
|
||||
active_peers: PeersByKey,
|
||||
active_peers_by_addr: PeersByAddr,
|
||||
}
|
||||
|
||||
impl ActivePeers {
|
||||
pub(crate) fn remove(&self, public_key: &x25519::PublicKey) {
|
||||
pub fn remove(&self, public_key: &x25519::PublicKey) {
|
||||
log::info!("Removing peer: {public_key:?}");
|
||||
self.active_peers.remove(public_key);
|
||||
log::warn!("TODO: remove from peers_by_ip?");
|
||||
log::warn!("TODO: remove from peers_by_addr");
|
||||
}
|
||||
|
||||
pub(crate) fn insert(
|
||||
pub fn insert(
|
||||
&self,
|
||||
public_key: x25519::PublicKey,
|
||||
addr: SocketAddr,
|
||||
@@ -58,17 +79,14 @@ impl ActivePeers {
|
||||
self.active_peers_by_addr.insert(addr, peer_tx);
|
||||
}
|
||||
|
||||
pub(crate) fn get_by_key_mut(
|
||||
pub fn get_by_key_mut(
|
||||
&self,
|
||||
public_key: &x25519::PublicKey,
|
||||
) -> Option<RefMut<'_, x25519::PublicKey, PeerEventSender>> {
|
||||
self.active_peers.get_mut(public_key)
|
||||
}
|
||||
|
||||
pub(crate) fn get_by_addr(
|
||||
&self,
|
||||
addr: &SocketAddr,
|
||||
) -> Option<Ref<'_, SocketAddr, PeerEventSender>> {
|
||||
pub fn get_by_addr(&self, addr: &SocketAddr) -> Option<Ref<'_, SocketAddr, PeerEventSender>> {
|
||||
self.active_peers_by_addr.get(addr)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
pub mod active_peers;
|
||||
pub mod event;
|
||||
pub mod network_table;
|
||||
+1
-1
@@ -9,7 +9,7 @@ pub struct NetworkTable<T> {
|
||||
}
|
||||
|
||||
impl<T> NetworkTable<T> {
|
||||
pub(crate) fn new() -> Self {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
ips: IpNetworkTable::new(),
|
||||
}
|
||||
@@ -13,20 +13,26 @@ license.workspace = true
|
||||
[dependencies]
|
||||
async-recursion = "1.0.4"
|
||||
base64 = "0.21.3"
|
||||
bincode = "1.3.3"
|
||||
# The latest version on crates.io at the time of writing this (6.0.0) has a
|
||||
# version mismatch with x25519-dalek/curve25519-dalek that is resolved in the
|
||||
# latest commit. So pick that for now.
|
||||
#boringtun = "0.6.0"
|
||||
boringtun = { workspace = true }
|
||||
bytes = "1.5.0"
|
||||
#defguard_wireguard_rs = { git = "https://github.com/DefGuard/wireguard-rs", rev = "d40df5c4e598918253682c42c4aa189d0ec2499a" }
|
||||
wireguard-control = { path = "../../../innernet/wireguard-control" }
|
||||
dashmap = "5.5.3"
|
||||
etherparse = "0.13.0"
|
||||
futures = "0.3.28"
|
||||
ip_network = "0.4.1"
|
||||
ip_network_table = "0.2.0"
|
||||
log.workspace = true
|
||||
nym-network-defaults = { path = "../network-defaults" }
|
||||
nym-task = { path = "../task" }
|
||||
nym-wireguard-types = { path = "../wireguard-types" }
|
||||
nym-sphinx = { path = "../nymsphinx" }
|
||||
nym-tun = { path = "../tun" , features = ["wireguard"] }
|
||||
rand.workspace = true
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
tap.workspace = true
|
||||
|
||||
+22
-54
@@ -3,15 +3,10 @@
|
||||
// #![warn(clippy::expect_used)]
|
||||
// #![warn(clippy::unwrap_used)]
|
||||
|
||||
mod active_peers;
|
||||
mod error;
|
||||
mod event;
|
||||
mod network_table;
|
||||
mod packet_relayer;
|
||||
mod platform;
|
||||
mod registered_peers;
|
||||
mod setup;
|
||||
mod tun_task_channel;
|
||||
pub mod setup;
|
||||
mod udp_listener;
|
||||
mod wg_tunnel;
|
||||
|
||||
@@ -20,59 +15,32 @@ use std::sync::Arc;
|
||||
|
||||
// Currently the module related to setting up the virtual network device is platform specific.
|
||||
#[cfg(target_os = "linux")]
|
||||
use platform::linux::tun_device;
|
||||
use nym_tun::tun_device;
|
||||
|
||||
use nym_network_defaults::{WG_PORT, WG_TUN_DEVICE_ADDRESS};
|
||||
use nym_tun::tun_task_channel;
|
||||
use setup::PRIVATE_KEY;
|
||||
use wireguard_control::{Backend, Device, DeviceUpdate, Key, KeyPair, PeerConfigBuilder};
|
||||
|
||||
/// Start wireguard UDP listener and TUN device
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// This function will return an error if either the UDP listener of the TUN device fails to start.
|
||||
#[cfg(target_os = "linux")]
|
||||
/// Start wireguard device
|
||||
pub async fn start_wireguard(
|
||||
task_client: nym_task::TaskClient,
|
||||
gateway_client_registry: Arc<GatewayClientRegistry>,
|
||||
mut task_client: nym_task::TaskClient,
|
||||
_gateway_client_registry: Arc<GatewayClientRegistry>,
|
||||
) -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
|
||||
// We can either index peers by their IP like standard wireguard
|
||||
let peers_by_ip = Arc::new(tokio::sync::Mutex::new(network_table::NetworkTable::new()));
|
||||
let peer = std::env::var("NYM_PEER_PUBLIC_KEY").expect("NYM_PEER_PUBLIC_KEY must be set");
|
||||
let peer = PeerConfigBuilder::new(&Key::from_base64(&peer).unwrap())
|
||||
.add_allowed_ip("10.1.0.2".parse()?, 32);
|
||||
DeviceUpdate::new()
|
||||
.set_keypair(KeyPair::from_private(
|
||||
Key::from_base64(PRIVATE_KEY).unwrap(),
|
||||
))
|
||||
.set_listen_port(WG_PORT)
|
||||
.add_peer(peer)
|
||||
.apply(&"wg0".parse().unwrap(), Backend::Kernel)
|
||||
.unwrap();
|
||||
|
||||
// ... or by their tunnel tag, which is a random number assigned to them
|
||||
let peers_by_tag = Arc::new(tokio::sync::Mutex::new(wg_tunnel::PeersByTag::new()));
|
||||
|
||||
// Start the tun device that is used to relay traffic outbound
|
||||
let (tun, tun_task_tx, tun_task_response_rx) = tun_device::TunDevice::new(peers_by_ip.clone());
|
||||
tun.start();
|
||||
|
||||
// If we want to have the tun device on a separate host, it's the tun_task and
|
||||
// tun_task_response channels that needs to be sent over the network to the host where the tun
|
||||
// device is running.
|
||||
|
||||
// The packet relayer's responsibility is to route packets between the correct tunnel and the
|
||||
// tun device. The tun device may or may not be on a separate host, which is why we can't do
|
||||
// this routing in the tun device itself.
|
||||
let (packet_relayer, packet_tx) = packet_relayer::PacketRelayer::new(
|
||||
tun_task_tx.clone(),
|
||||
tun_task_response_rx,
|
||||
peers_by_tag.clone(),
|
||||
);
|
||||
packet_relayer.start();
|
||||
|
||||
// Start the UDP listener that clients connect to
|
||||
let udp_listener = udp_listener::WgUdpListener::new(
|
||||
packet_tx,
|
||||
peers_by_ip,
|
||||
peers_by_tag,
|
||||
Arc::clone(&gateway_client_registry),
|
||||
)
|
||||
.await?;
|
||||
udp_listener.start(task_client);
|
||||
tokio::spawn(async move { task_client.recv().await });
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
pub async fn start_wireguard(
|
||||
_task_client: nym_task::TaskClient,
|
||||
_gateway_client_registry: Arc<GatewayClientRegistry>,
|
||||
) -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
|
||||
todo!("WireGuard is currently only supported on Linux")
|
||||
}
|
||||
|
||||
@@ -3,11 +3,9 @@ use std::{collections::HashMap, sync::Arc};
|
||||
use tap::TapFallible;
|
||||
use tokio::sync::mpsc::{self};
|
||||
|
||||
use crate::{
|
||||
active_peers::PeerEventSender,
|
||||
event::Event,
|
||||
tun_task_channel::{TunTaskResponseRx, TunTaskTx},
|
||||
};
|
||||
use crate::tun_task_channel::{TunTaskResponseRx, TunTaskTx};
|
||||
|
||||
use nym_wireguard_types::tun_common::{active_peers::PeerEventSender, event::Event};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PacketRelaySender(pub(crate) mpsc::Sender<(u64, Vec<u8>)>);
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
pub(crate) mod tun_device;
|
||||
@@ -1,192 +0,0 @@
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
net::{IpAddr, Ipv4Addr},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use etherparse::{InternetSlice, SlicedPacket};
|
||||
use tap::TapFallible;
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
|
||||
use crate::{
|
||||
event::Event,
|
||||
setup::{TUN_BASE_NAME, TUN_DEVICE_ADDRESS, TUN_DEVICE_NETMASK},
|
||||
tun_task_channel::{
|
||||
tun_task_channel, tun_task_response_channel, TunTaskPayload, TunTaskResponseRx,
|
||||
TunTaskResponseTx, TunTaskRx, TunTaskTx,
|
||||
},
|
||||
udp_listener::PeersByIp,
|
||||
};
|
||||
|
||||
fn setup_tokio_tun_device(name: &str, address: Ipv4Addr, netmask: Ipv4Addr) -> tokio_tun::Tun {
|
||||
log::info!("Creating TUN device with: address={address}, netmask={netmask}");
|
||||
tokio_tun::Tun::builder()
|
||||
.name(name)
|
||||
.tap(false)
|
||||
.packet_info(false)
|
||||
.mtu(1350)
|
||||
.up()
|
||||
.address(address)
|
||||
.netmask(netmask)
|
||||
.try_build()
|
||||
.expect("Failed to setup tun device, do you have permission?")
|
||||
}
|
||||
|
||||
pub struct TunDevice {
|
||||
// The TUN device that we read/write to, to send/receive packets
|
||||
tun: tokio_tun::Tun,
|
||||
|
||||
// Incoming data that we should send
|
||||
tun_task_rx: TunTaskRx,
|
||||
|
||||
// And when we get replies, this is where we should send it
|
||||
tun_task_response_tx: TunTaskResponseTx,
|
||||
|
||||
// The routing table, as how wireguard does it
|
||||
peers_by_ip: Arc<tokio::sync::Mutex<PeersByIp>>,
|
||||
|
||||
// This is an alternative to the routing table, where we just match outgoing source IP with
|
||||
// incoming destination IP.
|
||||
nat_table: HashMap<IpAddr, u64>,
|
||||
}
|
||||
|
||||
impl TunDevice {
|
||||
pub fn new(
|
||||
peers_by_ip: Arc<tokio::sync::Mutex<PeersByIp>>,
|
||||
) -> (Self, TunTaskTx, TunTaskResponseRx) {
|
||||
let tun = setup_tokio_tun_device(
|
||||
format!("{TUN_BASE_NAME}%d").as_str(),
|
||||
TUN_DEVICE_ADDRESS.parse().unwrap(),
|
||||
TUN_DEVICE_NETMASK.parse().unwrap(),
|
||||
);
|
||||
log::info!("Created TUN device: {}", tun.name());
|
||||
|
||||
// Channels to communicate with the other tasks
|
||||
let (tun_task_tx, tun_task_rx) = tun_task_channel();
|
||||
let (tun_task_response_tx, tun_task_response_rx) = tun_task_response_channel();
|
||||
|
||||
let tun_device = TunDevice {
|
||||
tun_task_rx,
|
||||
tun_task_response_tx,
|
||||
tun,
|
||||
peers_by_ip,
|
||||
nat_table: HashMap::new(),
|
||||
};
|
||||
|
||||
(tun_device, tun_task_tx, tun_task_response_rx)
|
||||
}
|
||||
|
||||
// Send outbound packets out on the wild internet
|
||||
async fn handle_tun_write(&mut self, data: TunTaskPayload) {
|
||||
let (tag, packet) = data;
|
||||
let Some(dst_addr) = boringtun::noise::Tunn::dst_address(&packet) else {
|
||||
log::error!("Unable to parse dst_address in packet that was supposed to be written to tun device");
|
||||
return;
|
||||
};
|
||||
let Some(src_addr) = parse_src_address(&packet) else {
|
||||
log::error!("Unable to parse src_address in packet that was supposed to be written to tun device");
|
||||
return;
|
||||
};
|
||||
log::info!(
|
||||
"iface: write Packet({src_addr} -> {dst_addr}, {} bytes)",
|
||||
packet.len()
|
||||
);
|
||||
|
||||
// TODO: expire old entries
|
||||
self.nat_table.insert(src_addr, tag);
|
||||
|
||||
self.tun
|
||||
.write_all(&packet)
|
||||
.await
|
||||
.tap_err(|err| {
|
||||
log::error!("iface: write error: {err}");
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
|
||||
// Receive reponse packets from the wild internet
|
||||
async fn handle_tun_read(&self, packet: &[u8]) {
|
||||
let Some(dst_addr) = boringtun::noise::Tunn::dst_address(packet) else {
|
||||
log::error!("Unable to parse dst_address in packet that was read from tun device");
|
||||
return;
|
||||
};
|
||||
let Some(src_addr) = parse_src_address(packet) else {
|
||||
log::error!("Unable to parse src_address in packet that was read from tun device");
|
||||
return;
|
||||
};
|
||||
log::info!(
|
||||
"iface: read Packet({src_addr} -> {dst_addr}, {} bytes)",
|
||||
packet.len(),
|
||||
);
|
||||
|
||||
// Route packet to the correct peer.
|
||||
|
||||
// This is how wireguard does it, by consulting the AllowedIPs table.
|
||||
if false {
|
||||
let peers = self.peers_by_ip.lock().await;
|
||||
if let Some(peer_tx) = peers.longest_match(dst_addr).map(|(_, tx)| tx) {
|
||||
log::info!("Forward packet to wg tunnel");
|
||||
peer_tx
|
||||
.send(Event::Ip(packet.to_vec().into()))
|
||||
.await
|
||||
.tap_err(|err| log::error!("{err}"))
|
||||
.ok();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// But we do it by consulting the NAT table.
|
||||
{
|
||||
if let Some(tag) = self.nat_table.get(&dst_addr) {
|
||||
log::info!("Forward packet to wg tunnel with tag: {tag}");
|
||||
self.tun_task_response_tx
|
||||
.send((*tag, packet.to_vec()))
|
||||
.await
|
||||
.tap_err(|err| log::error!("{err}"))
|
||||
.ok();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
log::info!("No peer found, packet dropped");
|
||||
}
|
||||
|
||||
pub async fn run(mut self) {
|
||||
let mut buf = [0u8; 1024];
|
||||
|
||||
loop {
|
||||
tokio::select! {
|
||||
// Reading from the TUN device
|
||||
len = self.tun.read(&mut buf) => match len {
|
||||
Ok(len) => {
|
||||
let packet = &buf[..len];
|
||||
self.handle_tun_read(packet).await;
|
||||
},
|
||||
Err(err) => {
|
||||
log::info!("iface: read error: {err}");
|
||||
break;
|
||||
}
|
||||
},
|
||||
// Writing to the TUN device
|
||||
Some(data) = self.tun_task_rx.recv() => {
|
||||
self.handle_tun_write(data).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
log::info!("TUN device shutting down");
|
||||
}
|
||||
|
||||
pub fn start(self) {
|
||||
tokio::spawn(async move { self.run().await });
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_src_address(packet: &[u8]) -> Option<IpAddr> {
|
||||
let headers = SlicedPacket::from_ip(packet)
|
||||
.tap_err(|err| log::error!("Unable to parse IP packet: {err:?}"))
|
||||
.ok()?;
|
||||
Some(match headers.ip? {
|
||||
InternetSlice::Ipv4(ip, _) => ip.source_addr().into(),
|
||||
InternetSlice::Ipv6(ip, _) => ip.source_addr().into(),
|
||||
})
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
#[cfg(target_os = "linux")]
|
||||
pub(crate) mod linux;
|
||||
@@ -7,22 +7,13 @@ use log::info;
|
||||
// The wireguard UDP listener
|
||||
pub const WG_ADDRESS: &str = "0.0.0.0";
|
||||
|
||||
// The interface used to route traffic
|
||||
pub const TUN_BASE_NAME: &str = "nymtun";
|
||||
pub const TUN_DEVICE_ADDRESS: &str = "10.0.0.1";
|
||||
pub const TUN_DEVICE_NETMASK: &str = "255.255.255.0";
|
||||
|
||||
// The private key of the listener
|
||||
// Corresponding public key: "WM8s8bYegwMa0TJ+xIwhk+dImk2IpDUKslDBCZPizlE="
|
||||
const PRIVATE_KEY: &str = "AEqXrLFT4qjYq3wmX0456iv94uM6nDj5ugp6Jedcflg=";
|
||||
|
||||
// The public keys of the registered peer (clients)
|
||||
// Corresponding private key: "ILeN6gEh6vJ3Ju8RJ3HVswz+sPgkcKtAYTqzQRhTtlo="
|
||||
const PEER: &str = "NCIhkgiqxFx1ckKl3Zuh595DzIFl8mxju1Vg995EZhI=";
|
||||
pub(crate) const PRIVATE_KEY: &str = "AEqXrLFT4qjYq3wmX0456iv94uM6nDj5ugp6Jedcflg=";
|
||||
|
||||
// The AllowedIPs for the connected peer, which is one a single IP and the same as the IP that the
|
||||
// peer has configured on their side.
|
||||
const ALLOWED_IPS: &str = "10.0.0.2";
|
||||
const ALLOWED_IPS: &str = "10.1.0.2";
|
||||
|
||||
fn decode_base64_key(base64_key: &str) -> [u8; 32] {
|
||||
general_purpose::STANDARD
|
||||
@@ -35,7 +26,7 @@ fn decode_base64_key(base64_key: &str) -> [u8; 32] {
|
||||
pub fn server_static_private_key() -> x25519::StaticSecret {
|
||||
// TODO: this is a temporary solution for development
|
||||
let static_private_bytes: [u8; 32] = decode_base64_key(PRIVATE_KEY);
|
||||
let static_private = x25519::StaticSecret::try_from(static_private_bytes).unwrap();
|
||||
let static_private = x25519::StaticSecret::from(static_private_bytes);
|
||||
let static_public = x25519::PublicKey::from(&static_private);
|
||||
info!(
|
||||
"wg public key: {}",
|
||||
@@ -46,8 +37,12 @@ pub fn server_static_private_key() -> x25519::StaticSecret {
|
||||
|
||||
pub fn peer_static_public_key() -> x25519::PublicKey {
|
||||
// A single static public key is used during development
|
||||
let peer_static_public_bytes: [u8; 32] = decode_base64_key(PEER);
|
||||
let peer_static_public = x25519::PublicKey::try_from(peer_static_public_bytes).unwrap();
|
||||
|
||||
// Read from NYM_PEER_PUBLIC_KEY env variable
|
||||
let peer = std::env::var("NYM_PEER_PUBLIC_KEY").expect("NYM_PEER_PUBLIC_KEY must be set");
|
||||
|
||||
let peer_static_public_bytes: [u8; 32] = decode_base64_key(&peer);
|
||||
let peer_static_public = x25519::PublicKey::from(peer_static_public_bytes);
|
||||
info!(
|
||||
"Adding wg peer public key: {}",
|
||||
general_purpose::STANDARD.encode(peer_static_public)
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
pub(crate) type TunTaskPayload = (u64, Vec<u8>);
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TunTaskTx(mpsc::Sender<TunTaskPayload>);
|
||||
pub(crate) struct TunTaskRx(mpsc::Receiver<TunTaskPayload>);
|
||||
|
||||
impl TunTaskTx {
|
||||
pub(crate) async fn send(
|
||||
&self,
|
||||
data: TunTaskPayload,
|
||||
) -> Result<(), tokio::sync::mpsc::error::SendError<TunTaskPayload>> {
|
||||
self.0.send(data).await
|
||||
}
|
||||
}
|
||||
|
||||
impl TunTaskRx {
|
||||
pub(crate) async fn recv(&mut self) -> Option<TunTaskPayload> {
|
||||
self.0.recv().await
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn tun_task_channel() -> (TunTaskTx, TunTaskRx) {
|
||||
let (tun_task_tx, tun_task_rx) = tokio::sync::mpsc::channel(16);
|
||||
(TunTaskTx(tun_task_tx), TunTaskRx(tun_task_rx))
|
||||
}
|
||||
|
||||
// Send responses back from the tun device back to the PacketRelayer
|
||||
pub(crate) struct TunTaskResponseTx(mpsc::Sender<TunTaskPayload>);
|
||||
pub struct TunTaskResponseRx(mpsc::Receiver<TunTaskPayload>);
|
||||
|
||||
impl TunTaskResponseTx {
|
||||
pub(crate) async fn send(
|
||||
&self,
|
||||
data: TunTaskPayload,
|
||||
) -> Result<(), tokio::sync::mpsc::error::SendError<TunTaskPayload>> {
|
||||
self.0.send(data).await
|
||||
}
|
||||
}
|
||||
|
||||
impl TunTaskResponseRx {
|
||||
pub(crate) async fn recv(&mut self) -> Option<TunTaskPayload> {
|
||||
self.0.recv().await
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn tun_task_response_channel() -> (TunTaskResponseTx, TunTaskResponseRx) {
|
||||
let (tun_task_tx, tun_task_rx) = tokio::sync::mpsc::channel(16);
|
||||
(
|
||||
TunTaskResponseTx(tun_task_tx),
|
||||
TunTaskResponseRx(tun_task_rx),
|
||||
)
|
||||
}
|
||||
@@ -6,16 +6,21 @@ use boringtun::{
|
||||
};
|
||||
use futures::StreamExt;
|
||||
use log::error;
|
||||
use nym_network_defaults::WG_PORT;
|
||||
use nym_task::TaskClient;
|
||||
use nym_wireguard_types::{registration::GatewayClientRegistry, PeerPublicKey, WG_PORT};
|
||||
use nym_wireguard_types::{
|
||||
registration::GatewayClientRegistry,
|
||||
tun_common::{
|
||||
active_peers::{ActivePeers, PeersByIp},
|
||||
event::Event,
|
||||
},
|
||||
PeerPublicKey,
|
||||
};
|
||||
use tap::TapFallible;
|
||||
use tokio::{net::UdpSocket, sync::Mutex};
|
||||
|
||||
use crate::{
|
||||
active_peers::{ActivePeers, PeerEventSender},
|
||||
error::WgError,
|
||||
event::Event,
|
||||
network_table::NetworkTable,
|
||||
packet_relayer::PacketRelaySender,
|
||||
registered_peers::{RegisteredPeer, RegisteredPeers},
|
||||
setup::{self, WG_ADDRESS},
|
||||
@@ -24,9 +29,6 @@ use crate::{
|
||||
|
||||
const MAX_PACKET: usize = 65535;
|
||||
|
||||
// Registered peers
|
||||
pub(crate) type PeersByIp = NetworkTable<PeerEventSender>;
|
||||
|
||||
async fn add_test_peer(registered_peers: &mut RegisteredPeers) {
|
||||
let peer_static_public = PeerPublicKey::new(setup::peer_static_public_key());
|
||||
let peer_index = 0;
|
||||
|
||||
@@ -7,18 +7,16 @@ use boringtun::{
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use log::{debug, error, info, warn};
|
||||
use nym_wireguard_types::tun_common::{
|
||||
active_peers::{peer_event_channel, PeerEventReceiver, PeerEventSender},
|
||||
event::Event,
|
||||
network_table::NetworkTable,
|
||||
};
|
||||
use rand::RngCore;
|
||||
use tap::TapFallible;
|
||||
use tokio::{net::UdpSocket, sync::broadcast, time::timeout};
|
||||
|
||||
use crate::{
|
||||
active_peers::{peer_event_channel, PeerEventReceiver, PeerEventSender},
|
||||
error::WgError,
|
||||
event::Event,
|
||||
network_table::NetworkTable,
|
||||
packet_relayer::PacketRelaySender,
|
||||
registered_peers::PeerIdx,
|
||||
};
|
||||
use crate::{error::WgError, packet_relayer::PacketRelaySender, registered_peers::PeerIdx};
|
||||
|
||||
const HANDSHAKE_MAX_RATE: u64 = 10;
|
||||
|
||||
|
||||
@@ -9,5 +9,15 @@ Each directory contains a readme with more information about running and contrib
|
||||
## 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.
|
||||
* `build_all_to_dist.sh` is used by the `ci-dev.yml` and `cd-dev.yml` scripts for building all mdbook projects and moving the rendered html to `../dist/` to be rsynced with various servers.
|
||||
* `post_process.sh` is a script called by the github CI and CD workflows to post process CSS/image/href links for serving several mdbooks from a subdirectory.
|
||||
|
||||
|
||||
### 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.
|
||||
|
||||
As a general approach, licensing is as follows this pattern:
|
||||
- applications and binaries are GPLv3
|
||||
- libraries and components are Apache 2.0 or MIT
|
||||
- documentation is Apache 2.0 or CC0-1.0
|
||||
|
||||
For accurate information, please check individual files.
|
||||
@@ -19,4 +19,6 @@ theme/
|
||||
theme
|
||||
theme/*
|
||||
|
||||
.idea
|
||||
.idea
|
||||
|
||||
notes
|
||||
@@ -18,14 +18,23 @@
|
||||
|
||||
# User Manuals
|
||||
|
||||
- [NymConnect Monero](tutorials/monero.md)
|
||||
- [NymConnect Matrix](tutorials/matrix.md)
|
||||
- [NymConnect Telegram](tutorials/telegram.md)
|
||||
- [NymConnect X Monero](tutorials/monero.md)
|
||||
- [NymConnect X Matrix](tutorials/matrix.md)
|
||||
- [NymConnect X Telegram](tutorials/telegram.md)
|
||||
- [NymConnect X Electrum](tutorials/electrum.md)
|
||||
- [NymConnect X Firo wallet](tutorials/firo.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](integrations/mixnet-integration.md)
|
||||
[//]: # (- [Mixnet Integration](integrations/mixnet-integration.md))
|
||||
- [Payment Integration](integrations/payment-integration.md)
|
||||
|
||||
# Tutorials
|
||||
@@ -40,15 +49,21 @@
|
||||
- [Preparing Your Service](tutorials/cosmos-service/service.md)
|
||||
- [Preparing Your Service pt2](tutorials/cosmos-service/service-src.md)
|
||||
- [Querying the Chain](tutorials/cosmos-service/querying.md)
|
||||
|
||||
- [Typescript](tutorials/typescript.md)
|
||||
- [Simple Service Provider](tutorials/simple-service-provider/simple-service-provider.md)
|
||||
- [Tutorial Overview](tutorials/simple-service-provider/overview.md)
|
||||
- [Preparing Your User Client Environment](tutorials/simple-service-provider/preparating-env.md)
|
||||
- [Building Your User Client](tutorials/simple-service-provider/user-client.md)
|
||||
- [Preparing Your Service Provider Environment](tutorials/simple-service-provider/preparating-env2.md)
|
||||
- [Building Your Service Provider](tutorials/simple-service-provider/service-provider.md)
|
||||
- [Sending a Message Through the Mixnet](tutorials/simple-service-provider/sending-message.md)
|
||||
- [[DEPRECATED] Simple Service Provider](tutorials/simple-service-provider/simple-service-provider.md)
|
||||
- [Tutorial Overview](tutorials/simple-service-provider/overview.md)
|
||||
- [Preparing Your User Client Environment](tutorials/simple-service-provider/preparating-env.md)
|
||||
- [Building Your User Client](tutorials/simple-service-provider/user-client.md)
|
||||
- [Preparing Your Service Provider Environment](tutorials/simple-service-provider/preparating-env2.md)
|
||||
- [Building Your Service Provider](tutorials/simple-service-provider/service-provider.md)
|
||||
- [Sending a Message Through the Mixnet](tutorials/simple-service-provider/sending-message.md)
|
||||
|
||||
# Shipyard Builders Hackathon 2023
|
||||
- [General Info & Resources](shipyard/general.md)
|
||||
- [Hackathon Challenges](shipyard/challenges-overview.md)
|
||||
- [A Note on Infrastructure](shipyard/infra.md)
|
||||
- [Submission Guidelines](shipyard/guidelines.md)
|
||||
|
||||
# Events
|
||||
|
||||
|
||||
+1
-3
@@ -1,8 +1,6 @@
|
||||
# Community Applications
|
||||
|
||||
We love seeing our developer community create applications using Nym. If you would like to share your application with the community, please submit a pull request to the `main` branch of the `nymtech/dev-portal` [repository](https://github.com/nymtech/dev-portal).
|
||||
|
||||
|
||||
If you would like to share your application here, please submit a pull request to the `main` branch of the `nymtech/dev-portal` [repository](https://github.com/nymtech/dev-portal).
|
||||
|
||||
## <img src='../images/profile_picture/pastenym_ntv_pp.png' style="float: right; width: 75px; height: 75px;">Pastenym
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
# Browser only
|
||||
With the Typescript SDK you can run a Nym client in a webworker - meaning you can connect to the mixnet through the browser without having to worry about any other code than your web framework.
|
||||
|
||||
- [NoTrustVerify](https://notrustverify.ch/) have set up an example application using [`mixFetch`](https://sdk.nymtech.net/examples/mix-fetch) to fetch crypto prices from CoinGecko over the mixnet.
|
||||
- [Website](https://notrustverify.github.io/mixfetch-examples/)
|
||||
- [Codebase](https://github.com/notrustverify/mixfetch-examples)
|
||||
|
||||
- There is a coconut-scheme based Credential Library playground [here](https://coco-demo.nymtech.net/). This is a WASM implementation of our Coconut libraries which generate raw Coconut credentials. Test it to create and re-randomize your own credentials. For more information on what is happening here check out the [Coconut docs](https://nymtech.net/docs/coconut.html).
|
||||
|
||||
- You can find a browser-based 'hello world' chat app [here](https://chat-demo.nymtech.net). Either open in two browser windows and send messages to yourself, or share with a friend and send messages to each other through the mixnet.
|
||||
@@ -0,0 +1,16 @@
|
||||
# Custom Services
|
||||
Custom services involve two pieces of code that communicate via the mixnet: a client, and a custom server/service. This custom service will most likely interact with the wider internet / a clearnet service on your behalf, with the mixnet between you and the service, acting as a privacy shield.
|
||||
|
||||
- PasteNym is a private pastebin alternative. It involves a browser-based frontend utilising the Typescript SDK and a Python-based backend service communicating with a standalone Nym Websocket Client. **If you're a Python developer, start here!**.
|
||||
- [Frontend codebase](https://github.com/notrustverify/pastenym)
|
||||
- [Backend codebase](https://github.com/notrustverify/pastenym-frontend)
|
||||
|
||||
- Nostr-Nym is another application written by [NoTrustVerify](https://notrustverify.ch/), standing between mixnet users and a Nostr server in order to protect their metadata from being revealed when gossiping. **Useful for Go and Python developers**.
|
||||
- [Codebase](https://github.com/notrustverify/nostr-nym)
|
||||
|
||||
- Spook and Nym-Ethtx are both examples of Ethereum transaction broadcasters utilising the mixnet, written in Rust. Since they were written before the release of the Rust SDK, they utilise standalone clients to communicate with the mixnet.
|
||||
- [Spook](https://github.com/EdenBlockVC/spook) (**Typescript**)
|
||||
- [Nym-Ethtx](https://github.com/noot/nym-ethtx) (**Rust**)
|
||||
|
||||
- NymDrive is an early proof of concept application for privacy-enhanced file storage on IPFS. **JS and CSS**, and a good example of packaging as an Electrum app.
|
||||
- [Codebase](https://github.com/saleel/nymdrive)
|
||||
@@ -0,0 +1,5 @@
|
||||
# Monorepo examples
|
||||
As well as these examples, there are a bunch of examples for each SDK in the Nym monorepo.
|
||||
|
||||
- [Rust SDK examples](https://github.com/nymtech/nym/tree/develop/sdk/rust/nym-sdk/examples)
|
||||
- [Typescript SDK examples](https://github.com/nymtech/nym/tree/develop/sdk/typescript/examples)
|
||||
@@ -0,0 +1,17 @@
|
||||
# Apps Using Network Requesters
|
||||
These applications utilise custom app logic in the user-facing apps in order to communicate using the mixnet as a transport layer, without having to rely on custom server-side logic. Instead, they utilise existing Nym infrastructure - [Network Requesters](https://nymtech.net/operators/nodes/network-requester-setup.html) - with a custom whitelist addition.
|
||||
|
||||
If you are sending 'normal' application traffic, and/or don't require and custom logic to be happening on the 'other side' of the mixnet, this is most likely the best option to take as a developer who wishes to privacy-enhance their application.
|
||||
|
||||
> Nym will soon be switching from a whitelist-based approach to a blocklist-based approach to filtering traffic. As such, it will soon be even easier for developers to utilise the mixnet, as they will not have to run their own NRs or have to add their domains to the whitelist
|
||||
|
||||
- DarkFi over Nym leverages Nym’s mixnet as a pluggable transport for DarkIRC, their p2p IRC variant. Users can anonymously connect to peers over the network, ensuring secure and private communication within the DarkFi ecosystem. Written in **Rust**.
|
||||
- [Docs](https://darkrenaissance.github.io/darkfi/clients/nym_outbound.html?highlight=nym#3--run)
|
||||
- [Github](https://github.com/darkrenaissance/darkfi/tree/master/doc)
|
||||
|
||||
- MiniBolt is a complete guide to building a Bitcoin & Lightning full node on a personal computer. It has the capacity to run network traffic (transactions and syncing) over the mixnet, so you can privately sync your node and not expose your home IP to the wider world when interacting with the rest of the network!
|
||||
- [Docs](https://v2.minibolt.info/bonus-guides/system/nym-mixnet#proxying-bitcoin-core)
|
||||
- [Codebase](https://github.com/minibolt-guide/minibolt)
|
||||
|
||||
- Email over Nym is a set of configuration options to set up a Network Requester to send and recieve emails over Nym, using something like Thunderbird.
|
||||
- [Codebase](https://github.com/dial0ut/nymstr-email)
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 101 KiB |
@@ -4,43 +4,11 @@ Discover the workings of Nym's privacy-enhancing mixnet infrastructure through t
|
||||
|
||||
<iframe width="700" height="400" src="https://www.youtube.com/embed/rnPpEsJS4FM" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
|
||||
|
||||
### Mixnet Infrastructure
|
||||
|
||||
There are few types of Nym infrastructure nodes:
|
||||
|
||||
#### Mix Nodes
|
||||
Mix nodes play a critical role in the Nym network by providing enhanced security and privacy to network content and metadata. They are part of the three-layer mixnet that ensures that communication remains anonymous and untraceable. Mix nodes receive `NYM` tokens as compensation for their quality of service, which is measured by the network validators.
|
||||
|
||||
Mix nodes anonymously relay encrypted Sphinx packets between each other, adding an extra layer of protection by reordering and delaying the packets before forwarding them to the intended recipient. Additionally, cover traffic is maintained through mix nodes sending Sphinx packets to other mix nodes, making it appear as if there is a constant flow of user messages and further protecting the privacy of legitimate data packets.
|
||||
|
||||
With the ability to hide, reorder and add a delay to network traffic, mix nodes make it difficult for attackers to perform time-based correlation attacks and deanonymize users. By consistently delivering high-quality service, mix nodes are rewarded with NYM tokens, reinforcing the integrity of the Nym network.
|
||||
|
||||
#### Gateways
|
||||
Gateways serve as the point of entry for user data into the mixnet, verifying that users have acquired sufficient NYM-based bandwidth credentials before allowing encrypted packets to be forwarded to mixnodes. They are also responsible for safeguarding against denial of service attacks and act as a message storage for users who may go offline.
|
||||
|
||||
Gateways receive bandwidth credentials from users, which are periodically redeemed for `NYM` tokens as payment for their services. Users have the flexibility to choose a single gateway, split traffic across multiple gateways, run their own gateways, or a combination of these options.
|
||||
|
||||
In addition, gateways also cache messages, functioning as an inbox for users who are offline. By providing secure, reliable access to the mixnet and ensuring that data remains protected, gateways play a crucial role in maintaining the integrity of the Nym network.
|
||||
|
||||
#### Validators
|
||||
Validators are essential to the security and integrity of the Nym network, tasked with several key responsibilities. They utilize proof-of-stake Sybil defense measures to secure the network and determine which nodes are included within it. Through their collaborative efforts, validators create Coconut threshold credentials which provide anonymous access to network data and resources.
|
||||
|
||||
Validators also play a critical role in maintaining the Nym Cosmos blockchain, a secure, public ledger that records network-wide information such as node public information and keys, network configuration parameters, CosmWasm smart contracts, and `NYM` and credential transactions.
|
||||
|
||||
#### Service Providers
|
||||
Service Providers are a crucial aspect of the Nym infrastructure that support the application layer of the Nym network. Any application built with Nym will require a Service Provider, which can be created by anyone. Service Providers run a piece of binary code that enables them to handle requests from Nym users or other services, and then make requests to external servers on behalf of the users.
|
||||
|
||||
For example, a Service Provider could receive a request to check a mail server and then forward the response to the user. The presence of Service Providers in the Nym network enhances its security and privacy, making it a reliable and robust platform for anonymous communication and data exchange.
|
||||
|
||||
### Where do I go from here? 💭
|
||||
|
||||
Maybe you would like to concentrate on building a application that uses the mixnet:
|
||||
For more in-depth information on the network architecture, head to the [Network Overview page](https://nymtech.net/docs/architecture/network-overview.html), and check out the [Operators book](https://nymtech.net/operators) if you want to run a node yourself.
|
||||
|
||||
* Explore the Tutorials section of the Developer Portal. Our in-depth tutorial on [Building a Simple Service Provider](../tutorials/simple-service-provider/simple-service-provider.md) give a good understanding of building User Clients and Service Providers in TypeScript, and how to configure Nym Websocket Clients for seamless communication with the mixnet.
|
||||
|
||||
* Get started with using the Nym Mixnet quickly and easily by exploring the [Quickstart](../quickstart/overview.md) options, such a NymConnect, proxying traffic through the Nym Socks5 client, or dive into integrating Nym into your existing application with the [Integrations](../integrations/integration-options.md) section.
|
||||
|
||||
Or perhaps you a developer that would like to run a infrastructure node such as a Gateway, Mix node or Network Requestor:
|
||||
* Check out the [Network Overview](https://nymtech.net/docs/architecture/network-overview.html) docs page.
|
||||
|
||||
* Take a look at our [Node Setup Guide](https://nymtech.net/operators/nodes/setup-guides.html) with our Nym Docs, containing setup guides for setting up you own infrastructure node.
|
||||
If you would like to concentrate on building an application that uses the mixnet:
|
||||
* Explore the [Quickstart](../quickstart/overview.md) options.
|
||||
* Check out examples of [Community Apps](../community-resources/community-applications-and-guides.md).
|
||||
* Run through the [Rust SDK](../tutorials/rust-sdk.md) or [Typescript](../tutorials/typescript.md) tutorials.
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
# Integration Options
|
||||
If you've already gone through the different [Quick Start](../quickstart/overview.md) options, you have seen the possibilities avaliable to you for quickly connecting existing application code to another Nym process.
|
||||
If you've already gone through the different [Quick Start](../quickstart/overview.md) options and had a look at the tutorials, you have seen the possibilities available to you for quickly connecting existing application code to another Nym process.
|
||||
|
||||
This section assumes you wish to integrate with Nym into your application code.
|
||||
Below are a resources that will be useful for either beginning to integrate mixnet functionality into existing application code or build a new app using Nym.
|
||||
|
||||
The [integrations FAQ](../faq/integrations-faq.md) has a list of common questions regarding integrating with Nym and Nyx, as well as commonly required links. _This is a good place to start to get an overall idea of the tools and software avaliable to you_.
|
||||
- **We suggest you begin with this [integration decision tree](https://sdk.nymtech.net/integrations)**. This will give you a better idea of what pieces of software (SDKs, standalone clients, service providers) your integration might involve, and what is currently possible to do with as little custom code as possible.
|
||||
|
||||
- The [integrations FAQ](../faq/integrations-faq.md) has a list of common questions regarding integrating with Nym and Nyx, as well as commonly required links.
|
||||
|
||||
- To get an idea of what is possible / has already been built, check the [community applications and resources](../community-resources/community-applications-and-guides.md) page, as well as the [developer tutorials codebase](https://github.com/nymtech/developer-tutorials).
|
||||
|
||||
> If you wish to integrate with the Nyx blockchain to use `NYM` for payments, start with the [payment integration](./payment-integration.md) page.
|
||||
|
||||
If you wish to integrate with Nym to use the mixnet for application traffic, start with the [mixnet integration](./mixnet-integration.md) page.
|
||||
|
||||
If you wish to integrate with the Nyx blockchain to use `NYM` for payments, start with the [payment integration](./payment-integration.md) page.
|
||||
|
||||
@@ -13,7 +13,7 @@ As outlined in the [clients overview documentation](https://nymtech.net/docs/cli
|
||||
#### Websocket client
|
||||
Your first option is the native websocket client. This is a compiled program that can run on Linux, Mac OS X, and Windows machines. It runs as a persistent process on a desktop or server machine. You can connect to it with any language that supports websockets.
|
||||
|
||||
You can see an example of how to connect to and manage interactions with this client in the [Simple Service Provider tutorial](../tutorials/simple-service-provider/simple-service-provider.md).
|
||||
[//]: # (You can see an example of how to connect to and manage interactions with this client in the [Simple Service Provider tutorial](../tutorials/simple-service-provider/simple-service-provider.md).)
|
||||
|
||||
#### Webassembly client
|
||||
If you’re working in JavaScript or Typescript in the browser, or building an edge computing app, you’ll likely want to choose the webassembly client.
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
# Licensing
|
||||
|
||||
Nym is Free Software released under the Apache License V2.
|
||||
Components that make up Nym as a system are licensed individually, so for accurate information, please check individual files.
|
||||
|
||||
All of the contributions of the Nym core developers are © Nym Technologies SA. If you are interested in talking to us about other licenses, please get in touch.
|
||||
As a general approach, licensing is as follows this pattern:
|
||||
- applications and binaries are GPLv3
|
||||
- libraries and components are Apache 2.0 or MIT
|
||||
- documentation is Apache 2.0 or CC0-1.0
|
||||
|
||||
Again, for accurate information, please check individual files.
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
# Hackathon Challenges
|
||||
There are a few different challenges to choose from, each with different approaches. It is also recommended to check out the _**Examples**_ directory above for inspiration.
|
||||
|
||||
## Tooling challenge
|
||||
The tooling challenge involves creating tooling for users, operators, or developers of Nym.
|
||||
|
||||
### Examples of user-centric tools:
|
||||
- Facilitate onboarding new users more easily to staking their Nym, and understanding the pros and cons, as well as finding a good node to stake on. Examples of tools like this:
|
||||
- [ExploreNym dashboard](https://explorenym.net/)
|
||||
|
||||
- Show information on a dashboard about the network. NOTE due to the amount of dashboards currently available, we expect a good justification for why / something to set this apart from existing ones e.g. it is presenting information that is not already presented, or it is presented in a different manner, such as a TUI or CLI app instead of a web dashboard - maybe an onion service, or no-JS site for those who do not wish to enable Javascript in their day-to-day browsing. Examples of tools like this:
|
||||
- [NTV's node dashboard](https://status.notrustverify.ch/d/CW3L7dVVk/nym-mixnet?orgId=1)
|
||||
- [IsNymUp dashboard](https://isnymup.com/)
|
||||
|
||||
### Examples of operator-centric tooling:
|
||||
- An APY calculator for determining different financial outcomes of running a node in different situations.
|
||||
|
||||
- Scripting for updating and maintaining nodes. Examples of tools like this:
|
||||
- [ExploreNym's bash scripts](https://github.com/ExploreNYM/bash-tool)
|
||||
|
||||
- Scripting for packaging node binaries for different OSes.
|
||||
|
||||
### Examples of developer-centric tooling:
|
||||
- Tooling for use in development: are there pain points you’ve found when developing apps with Nym that you have created scripts/hacks/workarounds for? Is there a pain point that you’ve thought ‘oh it would be great if I could just do X’? These are often the best places to start for building out developer tooling - if you’ve run into this issue, it's very likely someone else already has, or will!
|
||||
|
||||
- Interacting with one of the SDKs via FFI: perhaps you’re a Go developer who would love to have the functionality of one of the Nym SDKs. Building an FFI tool might be something that would make your life easier, and can be shared with other developers in your situation.
|
||||
|
||||
## Integrations challenge
|
||||
Integration options for Nym are currently relatively restrictive due to the manner in which Nym handles sending and receiving traffic (as unordered Sphinx packets). This challenge will involve (most likely) implementing custom logic for handling Nym traffic for an existing application.
|
||||
|
||||
There are several potential avenues developers can take here:
|
||||
- If your application (or the application you wish to modify) is written in either Javascript or Typescript, and relies on the `fetch` library to make API calls, then you can use its drop-in replacement: [`mixfetch`](). Perhaps you wish to interact with Coingecko, or a private search engine like Kagi without leaking your IP and metadata, or an RPC endpoint.
|
||||
- Example with [NTV’s privacy-preserving Coingecko API](https://github.com/notrustverify/mixfetch-examples)
|
||||
- [Mixfetch docs examples](https://github.com/nymtech/nym/tree/develop/sdk/typescript/examples)
|
||||
|
||||
- If you instead have an application that is able to use any of the SOCKS5, 4a, or 4 protocols (a rule of thumb: if it can communicate over Tor, it will) then you can experiment with using Nym as the transport layer.
|
||||
- For Rustaceans, check out our [socks5 rust sdk example](https://nymtech.net/docs/sdk/rust.html#socks-client-example).
|
||||
- For those of you who aren’t Crustaceans, then you will have to run the [Socks Client]() alongside your application as a separate process. _NOTE If you are taking this route, please make sure to include detailed documentation on how you expect users to do this, as well as including any process management tools, scripts, and configs (e.g. if you use systemd then include the configuration file for the client, as well as initialisation logic) that may streamline this process._
|
||||
- [NTV's PasteNym backend](https://github.com/notrustverify/pastenym) is a great example of an application with this architecture.
|
||||
|
||||
- Nym is not only useful for blockchain-related apps, but for anything that requires network level privacy! Email clients, messaging clients, and decentralised storage are all key elements of the privacy-enabled web. Several of these sorts of apps can be found in the [community apps page](../community-resources/community-applications-and-guides.md).
|
||||
|
||||
- There is currently a proof of concept using Rust Libp2p with Nym as a transport layer. Perhaps you can think of an app that uses Gossipsub for p2p communication could benefit from network-level privacy.
|
||||
- [GossipSub chat example](https://github.com/nymtech/nym/tree/develop/sdk/rust/nym-sdk/examples/libp2p_chat)
|
||||
- [Chainsafe's Lighthouse Nym PoC](https://github.com/ChainSafe/lighthouse/blob/nym/USE_NYM.md#usage)
|
||||
|
||||
- Alternatively if you know of an app that is written in Rust or TS and could benefit from using Nym, you could fork and modify it using the SDKs. Applications such as:
|
||||
- Magic Wormhole (has a [rust implementation](https://github.com/magic-wormhole/magic-wormhole.rs))
|
||||
- [Qual](https://github.com/qaul/qaul.net) (uses Rust Libp2p)
|
||||
- [Syncthing](https://github.com/syncthing/syncthing)
|
||||
|
||||
### MiniApp challenge
|
||||
Write an app, either using one of the SDKs or a standalone client (harder). Think of what you can ‘nymify’ e.g. a version of the [TorBirdy](https://support.torproject.org/glossary/torbirdy/) extension that uses Nym instead of Tor. This is very similar to the Integration challenge in terms of the different potential _architectures_ and approaches, but just for new applications.
|
||||
@@ -0,0 +1,16 @@
|
||||
# General Info & Resources
|
||||
Discussions and announcements will be taking place in the [builders channel on Matrix](https://matrix.to/#/#shipyardbuilders:nymtech.chat). This channel can be used for all discussions.
|
||||
|
||||
There will be daily office horse between 12-14:00 CET.
|
||||
|
||||
This is an open call and questions will be answered on a first come first serve basis.
|
||||
|
||||
The timetable can be found on the [Shipyard website](https://nymtech.net/learn/shipyard).
|
||||
|
||||
## Links
|
||||
- You can find **code examples**, **tutorials**, & **quickstart** information here, on the Developer Portal.
|
||||
- [Rust SDK docs](https://nymtech.net/docs/sdk/rust.html)
|
||||
- [Typescript SDK docs](https://sdk.nymtech.net)
|
||||
- [Platform docs](https://nymtech.net/docs)
|
||||
- [NoTrustVerify's Awesome Nym list](https://github.com/notrustverify/awesome-nym)
|
||||
- [Builders channel Matrix](https://matrix.to/#/#shipyardbuilders:nymtech.chat)
|
||||
@@ -0,0 +1,15 @@
|
||||
# Submission Guidelines
|
||||
We expect to see the following for submissions:
|
||||
- Working code demos hosted publicly (Gitlab, Github, some other git instance).
|
||||
- Quality > quantity here: we’d prefer to see a contained, working, and well documented Proof of Concept over a sprawling and messy app that does more but is poorly explained and presented. _The repo must be open source and able to be used and modified by others. The license is up to you._
|
||||
- If you already have existing apps / projects you are more than welcome to extend them, instead of starting from scratch - we will only be looking at the NEW additions to make this fair. If you are doing this, make sure to write a detailed account of what it is you;ve added to the existing project, preferably with the possibility to see the ‘old’ version as well as the new one.
|
||||
- Proper documentation:
|
||||
- If an app / tool:
|
||||
- How do you install and run the code? How is it to be used?
|
||||
- An overview of the application architecture: what is it doing? Is it relying on other services?
|
||||
- If a UI-based solution:
|
||||
- How to run it locally? We are happy to also accept staging deployments as part of the submission (e.g. via Vercel) but this does not replace being able to run it locally.
|
||||
- Please make sure that your application works on commonly reproducible system environments (e.g. if you’re developing on Artix Linux please check for the necessary dependencies for more common-place OSes such as Debian, or Arch). If you are developing on Windows please make sure that it works on non-Windows machines also. Where possible please try to include build and install instructions for a variety of OSes.
|
||||
|
||||
## How to submit?
|
||||
Please follow the instructions [here](https://github.com/nymtech/nym/discussions/4143).
|
||||
@@ -0,0 +1,12 @@
|
||||
# A Note on Infrastructure
|
||||
If you are writing an application that requires sending messages through the mixnet, then you will either be relying on existing infrastructure nodes (network requesters), or writing your own custom service (for example, the service written as part of the Rust SDK tutorial).
|
||||
|
||||
If you are relying on network requesters then chances are that the IPs or domains your app relies on will not already be on the whitelist. Ideally, you would [run your own,](https://nymtech.net/operators/nodes/network-requester-setup.html) but we will also run a few nodes in ‘open proxy’ mode and share the addresses so that you can use them when beginning to develop.
|
||||
|
||||
## Node Details:
|
||||
- NR1
|
||||
- Location: Singapore
|
||||
- Nym Address: `FDeWfd8q686PWLXJDCqNJTCbydTk1KSux5HVftimsPyx.9XyThN4yh92eTMuLp1NvWicRZob8Ei5xpba9dvcMLxcN@9Byd9VAtyYMnbVAcqdoQxJnq76XEg2dbxbiF5Aa5Jj9J`
|
||||
- NR2
|
||||
- Location: Frankfurt
|
||||
- Nym Address: `BNypKaGiGY8GNRN4gpV95GcaVS8n7CrHuoZNgQ2ezqv2.ACpaixzuaSzuMajVQj6aR7cbpbvp676tm21MiLbX1gni@678qVUJ21uwxZBhp3r56z7GRf6gMh3NYDHruTegPtgMf`
|
||||
@@ -29,7 +29,7 @@ cargo new nym-cosmos-service
|
||||
```
|
||||
[dependencies]
|
||||
clap = { version = "4.0", features = ["derive"] }
|
||||
cosmrs = "=0.14.0"
|
||||
cosmrs = "=0.15.0"
|
||||
tokio = { version = "1.24.1", features = ["rt-multi-thread", "macros"] }
|
||||
serde = "1.0.152"
|
||||
serde_json = "1.0.91"
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# Electrum Wallet NymConnect Integration
|
||||
|
||||
Electrum is one of the most favorite Bitcoin wallet for desktop users and it is used as a backend wallet for various crypto aplications in smart phones. Electrum was among the first integrations of Nym. This easy setup allows users to enhance privacy when managing the flagship of blochain cryptocurencies Bitcoin.
|
||||
|
||||
## How can I use Bitcoin over the Nym mixnet?
|
||||
|
||||
> Any syntax in `<>` brackets is a user’s unique variable. Exchange with a corresponding name without the `<>` brackets.
|
||||
|
||||
### NymConnect Installation
|
||||
|
||||
NymConnect application is for everyone who does not want to install and run `nym-socks5-client`. NymConnect is plug-and-play, fast and easy use. Electrum Bitcoin wallet, Monero wallet (desktop and CLI) and Matrix (Element app) connects through NymConnect automatically to the Mixnet.
|
||||
|
||||
1. [Download](https://nymtech.net/download/nymconnect) NymConnect
|
||||
2. On Linux and Mac, make executable by opening terminal in the same directory and run:
|
||||
|
||||
```sh
|
||||
chmod +x ./nym-connect_<VERSION>
|
||||
```
|
||||
|
||||
3. Start the application
|
||||
4. Click on `Connect` button to initialise the connection with the Mixnet
|
||||
5. Anytime you'll need to setup Host and Port in your applications, click on `IP` and `Port` to copy the values to clipboard
|
||||
6. In case you have problems such as `Gateway Issues`, try to reconnect or restart the application
|
||||
|
||||
### Electrum Bitcoin wallet via NymConnect
|
||||
|
||||
|
||||
To download Electrum visit the [official webpage](https://electrum.org/#download). To connect to the Mixnet follow these steps:
|
||||
|
||||
7. Start and connect [NymConnect](./electrum.md#nymconnect-installation) (or [`nym-socks5-client`](https://nymtech.net/docs/clients/socks5-client.html))
|
||||
2. Start your Electrum Bitcoin wallet
|
||||
3. Go to: *Tools* -> *Network* -> *Proxy*
|
||||
4. Set *Use proxy* to ✅, choose `SOCKS5` from the drop-down and add 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.
|
||||
|
||||

|
||||
@@ -0,0 +1,36 @@
|
||||
# Firo-Electrum Wallet NymConnect Integration
|
||||
|
||||
[Firo](https://github.com/firoorg/firo#firo) (formerly Zcoin) is a privacy focused, zk-proof based cryptocurrency. Now users can enjoy Firo with network privacy by Nym as Firo's fork of Electrum wallet was integrated to work behind the Mixnet. Read more about Firo on their [official webpage](https://firo.org/).
|
||||
|
||||
## How can I use Firo over the Nym Mixnet?
|
||||
|
||||
> Any syntax in `<>` brackets is a user’s unique variable. Exchange with a corresponding name without the `<>` brackets.
|
||||
|
||||
### NymConnect Installation
|
||||
|
||||
NymConnect application is for everyone who does not want to install and run `nym-socks5-client`. NymConnect is plug-and-play, fast and easy use. Electrum Bitcoin wallet, Monero wallet (desktop and CLI) and Matrix (Element app) connects through NymConnect automatically to the Mixnet.
|
||||
|
||||
1. [Download](https://nymtech.net/download/nymconnect) NymConnect
|
||||
2. On Linux and Mac, make executable by opening terminal in the same directory and run:
|
||||
|
||||
```sh
|
||||
chmod +x ./nym-connect_<VERSION>
|
||||
```
|
||||
|
||||
3. Start the application
|
||||
4. Click on `Connect` button to initialise the connection with the Mixnet
|
||||
5. Anytime you'll need to setup Host and Port in your applications, click on `IP` and `Port` to copy the values to clipboard
|
||||
6. In case you have problems such as `Gateway Issues`, try to reconnect or restart the application
|
||||
|
||||
### Firo Electrum wallet via NymConnect
|
||||
|
||||
|
||||
To download Firo Electrum wallet visit the [Firo's repository](https://github.com/firoorg/firo) or [Github release page](https://github.com/firoorg/electrum-firo/releases/tag/4.1.5.2). To connect to the Mixnet follow these steps:
|
||||
|
||||
7. Start and connect [NymConnect](./firo.md#nymconnect-installation) (or [`nym-socks5-client`](https://nymtech.net/docs/clients/socks5-client.html))
|
||||
8. Start your Firo Electrum wallet
|
||||
9. Go to: *Tools* -> *Network* -> *Proxy*
|
||||
10. Set *Use proxy* to ✅, choose `SOCKS5` from the drop-down and add the values from your NymConnect application
|
||||
11. Now your Firo Electrum wallet runs through the Mixnet and it will be connected only if your NymConnect or `nym-socks5-client` are connected.
|
||||
|
||||

|
||||
+7
@@ -1,5 +1,12 @@
|
||||
# Building a Simple Service Provider
|
||||
|
||||
```admonish warning
|
||||
This tutorial was written before the creation of the [Typescript SDK](https://sdk.nymtech.net), and involves running a Nym Client alongside your application processes, instead of relying on the SDK to integrate the Client process into your application logic.
|
||||
|
||||
As such, although this tutorial is still a valid way of approaching building on Nym, it is a little less streamlined than it could be.
|
||||
|
||||
A more streamlined rewrite of this tutorial will be coming soon.
|
||||
```
|
||||
This tutorial is the best place to start for developers new to Nym. You will learn how to build a minimum viable privacy-enabled application (PEApp) able to send and receive traffic via the mixnet.
|
||||
|
||||
This tutorial is less about building an immediately useful application, and more about beginning to understand:
|
||||
|
||||
@@ -16,7 +16,7 @@ Here’s how to configure Telegram with NymConnect:
|
||||
For more releases, check out [Github](https://github.com/nymtech/nym/tags). NymConnect is available for Linux, Windows, and MacOS.
|
||||
On Linux make sure NymConnect is executable. Opening a terminal in the same directory and run:
|
||||
```sh
|
||||
chmod +x ./<YOUR-NYM-CONNECT-VERSION>.AppImage
|
||||
chmod +x ./<VERSION>
|
||||
```
|
||||
2. **Start NymConnect**
|
||||
Telegram is added to NymConnect by default.
|
||||
|
||||
@@ -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.
|
||||
@@ -6,6 +6,9 @@ language = "en"
|
||||
multilingual = false # for the moment - ideally work on chinese, brazillian, spanish next
|
||||
src = "src"
|
||||
|
||||
[rust]
|
||||
edition = "2018"
|
||||
|
||||
#################
|
||||
# PREPROCESSORS #
|
||||
#################
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# Architecture
|
||||
- [Network Overview](architecture/network-overview.md)
|
||||
- [Mixnet Traffic Flow](architecture/traffic-flow.md)
|
||||
<!-- todo reintroduce this with themed images -->
|
||||
<!-- TODO reintroduce this with themed images -->
|
||||
<!-- - [Network Rewards](architecture/network-rewards.md) -->
|
||||
|
||||
# Binaries
|
||||
@@ -22,14 +22,31 @@
|
||||
|
||||
# Clients
|
||||
- [Clients Overview](clients/overview.md)
|
||||
- [Websocket](clients/websocket-client.md)
|
||||
- [Socks5](clients/socks5-client.md)
|
||||
- [Webassembly](clients/webassembly-client.md)
|
||||
- [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)
|
||||
- [Webassembly Client](clients/webassembly-client.md)
|
||||
- [Addressing System](clients/addressing-system.md)
|
||||
|
||||
# SDK
|
||||
- [Typescript SDK](sdk/typescript.md)
|
||||
- [Rust SDK](sdk/rust.md)
|
||||
- [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)
|
||||
|
||||
# Wallet
|
||||
- [Desktop Wallet](wallet/desktop-wallet.md)
|
||||
|
||||
@@ -5,7 +5,7 @@ When you send data across the internet, it can be recorded by a wide range of ob
|
||||
|
||||
Even if the content of a network request is encrypted, observers can still see that data was transmitted, its size, frequency of transmission, and gather metadata from unencrypted parts of the data (such as IP routing information). Adversaries may then combine all the leaked information to probabilistically de-anonymize users.
|
||||
|
||||
The Nym mixnet provides very strong security guarantees against this sort of surveillance. It _packetizes_ and _mixes_ together IP traffic from many users inside the _mixnet_.
|
||||
The Nym mixnet provides very strong security guarantees against this sort of surveillance. It _packetises_ and _mixes_ together IP traffic from many users inside the _mixnet_.
|
||||
|
||||
> If you're into comparisons, the Nym mixnet is conceptually similar to other systems such as Tor, but provides improved protections against end-to-end timing attacks which can de-anonymize users. When Tor was first fielded, in 2002, those kinds of attacks were regarded as science fiction. But the future is now here.
|
||||
|
||||
@@ -69,7 +69,7 @@ From your Nym client, your encrypted traffic is sent to:
|
||||
Whatever is on the 'other side' of the mixnet from your client, all traffic will travel this way through the mixnet. If you are sending traffic to a service external to Nym (such as a chat application's servers) then your traffic will be sent from the recieving Nym client to an application that will proxy it 'out' of the mixnet to these servers, shielding your metadata from them. P2P (peer-to-peer) applications, unlike the majority of apps, might want to keep all of their traffic entirely 'within' the mixnet, as they don't have to necessarily make outbound network requests to application servers. They would simply have their local application code communicate with their Nym clients, and not forward traffic anywhere 'outside' of the mixnet.
|
||||
|
||||
## Acks & Package Retransmission
|
||||
Whenever a hop is completed, the recieving node will send back an acknowledgement ('ack') so that the sending node knows that the packet was recieved. If it does not recieve an ack after sending, it will resend the packet, as it assumes that the packet was dropped for some reason. This is done under the hood by the binaries themselves, and is never something that developers and node operators have to worry about dealing with themselves.
|
||||
Whenever a hop is completed, the receiving node will send back an acknowledgement ('ack') so that the sending node knows that the packet was received. If it does not receive an ack after sending, it will resend the packet, as it assumes that the packet was dropped for some reason. This is done under the hood by the binaries themselves, and is never something that developers and node operators have to worry about dealing with themselves.
|
||||
|
||||
Packet retransmission means that 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. All nodes in the mixnet support packet retransmission.
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ You need to choose which one you want incorporate into your app. Which one you u
|
||||
### 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.md)_.
|
||||
_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.
|
||||
@@ -39,7 +39,7 @@ The `nym-socks5-client` is useful for allowing existing applications to use the
|
||||
|
||||
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.md)_.
|
||||
_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.
|
||||
|
||||
@@ -89,7 +89,7 @@ You can check the necessary parameters for the available commands by running:
|
||||
Before you can use the client, you need to initalise a new instance of it, which can be done with the following command:
|
||||
|
||||
```
|
||||
./nym-socks5-client init --id docs-example --provider Entztfv6Uaz2hpYHQJ6JKoaCTpDL5dja18SuQWVJAmmx.Cvhn9rBJw5Ay9wgHcbgCnVg89MPSV5s2muPV2YF1BXYu@Fo4f4SQLdoyoGkFae5TpVhRVoXCF8UiypLVGtGjujVPf
|
||||
./nym-socks5-client init --id docs-example --use-reply-surbs true --provider Entztfv6Uaz2hpYHQJ6JKoaCTpDL5dja18SuQWVJAmmx.Cvhn9rBJw5Ay9wgHcbgCnVg89MPSV5s2muPV2YF1BXYu@Fo4f4SQLdoyoGkFae5TpVhRVoXCF8UiypLVGtGjujVPf
|
||||
```
|
||||
|
||||
~~~admonish example collapsible=true title="Console output"
|
||||
@@ -100,6 +100,8 @@ Before you can use the client, you need to initalise a new instance of it, which
|
||||
|
||||
The `--id` in the example above is a local identifier so that you can name your clients and keep track of them on your local system; it is **never** transmitted over the network.
|
||||
|
||||
The `--use-reply-surbs` field denotes whether you wish to send [SURBs](../architecture/traffic-flow.md#private-replies-using-surbs) along with your request. It defaults to `false`, we are explicitly setting it as `true`. It defaults to `false` for compatibility with older versions of the [Network Requester](../nodes/network-requester.md).
|
||||
|
||||
The `--provider` field needs to be filled with the Nym address of a Network Requester that can make network requests on your behalf. If you don't want to [run your own](../nodes/network-requester.md) you can select one from the [mixnet explorer](https://explorer.nymtech.net/network-components/service-providers) by copying its `Client ID` and using this as the value of the `--provider` flag. Alternatively, you could use [this list](https://harbourmaster.nymtech.net/).
|
||||
|
||||
Since the nodes on this list are the infrastructure for [Nymconnect](https://nymtech.net/developers/quickstart/nymconnect-gui.html) they will support all apps on the [default whitelist](../nodes/network-requester.md#network-requester-whitelist): Keybase, Telegram, Electrum, Blockstream Green, and Helios.
|
||||
@@ -148,7 +150,7 @@ Alternatively, a custom host can be set in the `config.toml` file under the `soc
|
||||
|
||||
### Running the socks5 client
|
||||
|
||||
You can run the initalised client by doing this:
|
||||
You can run the initialised client by doing this:
|
||||
|
||||
```
|
||||
./nym-socks5-client run --id docs-example
|
||||
@@ -160,7 +162,7 @@ Create a service file for the socks5 client at `/etc/systemd/system/nym-socks5-c
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Nym Socks5 Client
|
||||
Description=Nym Socks5 Client
|
||||
StartLimitInterval=350
|
||||
StartLimitBurst=10
|
||||
|
||||
|
||||
@@ -2,13 +2,15 @@
|
||||
|
||||
The Nym webassembly client allows any webassembly-capable runtime to build and send Sphinx packets to the Nym network, for uses in edge computing and browser-based applications.
|
||||
|
||||
This is currently packaged and distributed for ease of use via the [Nym Typescript SDK library](../sdk/typescript.md).
|
||||
This is currently packaged and distributed for ease of use via the [Nym Typescript SDK library](../sdk/typescript.md). **We imagine most developers will use this client via the SDK for ease.**
|
||||
|
||||
The webassembly client allows for the easy creation of Sphinx packets from within mobile apps and browser-based client-side apps (including Electron or similar).
|
||||
|
||||
## Building apps with nym-client-wasm
|
||||
## Building apps with Webassembly Client
|
||||
|
||||
Check out the [examples section](../sdk/typescript.md#using-the-sdk) of the SDK docs for examples of simple application framework setups. There are also two example applications located in the `clients/webassembly` directory in the main Nym platform codebase. The `js-example` is a simple, bare-bones JavaScript app.
|
||||
Check out the [Typescript SDK docs](https://sdk.nymtech.net) for examples of usage.
|
||||
|
||||
There are also example applications located in the `clients/webassembly` directory in the main Nym platform codebase.
|
||||
|
||||
## Think about what you're sending!
|
||||
```admonish caution
|
||||
|
||||
@@ -7,208 +7,7 @@
|
||||
<!-- cmdrun ../../../../target/release/nym-client --version | grep "Build Version" | cut -b 21-26 -->
|
||||
```
|
||||
|
||||
## Client setup
|
||||
### Viewing command help
|
||||
You can run this client as a standalone process and pipe traffic into it to be sent through the mixnet. This is useful if you're building an application in a language other than Typescript or Rust and cannot utilise one of the SDKs.
|
||||
|
||||
You can check that your binaries are properly compiled with:
|
||||
You can find the code for this client [here](https://github.com/nymtech/nym/tree/develop/clients/native).
|
||||
|
||||
```
|
||||
./nym-client --help
|
||||
```
|
||||
|
||||
~~~admonish example collapsible=true title="Console output"
|
||||
```
|
||||
<!-- cmdrun ../../../../target/release/nym-client --help -->
|
||||
```
|
||||
~~~
|
||||
|
||||
The two most important commands you will issue to the client are:
|
||||
|
||||
* `init` - initalise a new client instance.
|
||||
* `run` - run a mixnet client process.
|
||||
|
||||
You can check the necessary parameters for the available commands by running:
|
||||
|
||||
```
|
||||
./nym-client <command> --help
|
||||
```
|
||||
|
||||
### Initialising your client
|
||||
|
||||
Before you can use the client, you need to initalise a new instance of it. Each instance of the client has its own public/private keypair, and connects to its own gateway node. Taken together, these 3 things (public/private keypair + gateway node identity key) make up an app's identity.
|
||||
|
||||
Initialising a new client instance can be done with the following command:
|
||||
|
||||
```
|
||||
./nym-client init --id example-client
|
||||
```
|
||||
|
||||
~~~admonish example collapsible=true title="Console output"
|
||||
```
|
||||
<!-- cmdrun ../../../../target/release/nym-client init --id example-client -->
|
||||
```
|
||||
~~~
|
||||
|
||||
The `--id` in the example above is a local identifier so that you can name your clients; it is **never** transmitted over the network.
|
||||
|
||||
There is an optional `--gateway` flag that you can use if you want to use a specific gateway. The supplied argument is the `Identity Key` of the gateway you wish to use, which can be found on the [mainnet Network Explorer](https://explorer.nymtech.net/network-components/gateways) or [Sandbox Testnet Explorer](https://sandbox-explorer.nymtech.net/network-components/gateways) depending on which network you are on.
|
||||
|
||||
Not passing this argument will randomly select a gateway for your client.
|
||||
|
||||
#### Choosing a Gateway
|
||||
By default - as in the example above - your client will choose a random gateway to connect to.
|
||||
|
||||
However, there are several options for choosing a gateway, if you do not want one that is randomly assigned to your client:
|
||||
* If you wish to connect to a specific gateway, you can specify this with the `--gateway` flag when running `init`.
|
||||
* You can also choose a gateway based on its location relative to your client. This can be done by appending the `--latency-based-routing` flag to your `init` command. This command means that to select a gateway, your client will:
|
||||
* fetch a list of all availiable gateways
|
||||
* send few ping messages to all of them, and measure response times.
|
||||
* create a weighted distribution to randomly choose one, favouring ones with lower latency.
|
||||
|
||||
> Note this doesn't mean that your client will pick the closest gateway to you, but it will be far more likely to connect to gateway with a 20ms ping rather than 200ms
|
||||
|
||||
### Running your client
|
||||
You can run the initalised client by doing this:
|
||||
|
||||
```
|
||||
./nym-client run --id example-client
|
||||
```
|
||||
|
||||
When you run the client, it immediately starts generating (fake) cover traffic and sending it to the mixnet.
|
||||
|
||||
When the client is first started, it will reach out to the Nym network's validators, and get a list of available Nym nodes (gateways, mixnodes, and validators). We call this list of nodes the network _topology_. The client does this so that it knows how to connect, register itself with the network, and know which mixnodes it can route Sphinx packets through.
|
||||
|
||||
### Configuring your client
|
||||
When you initalise a client instance, a configuration directory will be generated and stored in `$HOME_DIR/.nym/clients/<client-name>/`.
|
||||
|
||||
```
|
||||
tree $HOME/<user>/.nym/clients/example-client
|
||||
├── config
|
||||
│ └── config.toml
|
||||
└── data
|
||||
├── ack_key.pem
|
||||
├── gateway_shared.pem
|
||||
├── private_encryption.pem
|
||||
├── private_identity.pem
|
||||
├── public_encryption.pem
|
||||
└── public_identity.pem
|
||||
```
|
||||
|
||||
The `config.toml` file contains client configuration options, while the two `pem` files contain client key information.
|
||||
|
||||
The generated files contain the client name, public/private keypairs, and gateway address. The name `<client_id>` in the example above is just a local identifier so that you can name your clients.
|
||||
|
||||
#### Configuring your client for Docker
|
||||
By default, the native client listens to host `127.0.0.1`. However this can be an issue if you wish to run a client in a Dockerized environment, where it can be convenenient to listen on a different host such as `0.0.0.0`.
|
||||
|
||||
You can set this via the `--host` flag during either the `init` or `run` commands.
|
||||
|
||||
Alternatively, a custom host can be set in the `config.toml` file under the `socket` section. If you do this, remember to restart your client process.
|
||||
|
||||
## Using your client
|
||||
### Connecting to the local websocket
|
||||
The Nym native client exposes a websocket interface that your code connects to. To program your app, choose a websocket library for whatever language you're using. The **default** websocket port is `1977`, you can override that in the client config if you want.
|
||||
|
||||
The Nym monorepo includes websocket client example code for Rust, Go, Javacript, and Python, all of which can be found [here](https://github.com/nymtech/nym/tree/master/clients/native/examples).
|
||||
|
||||
> Rust users can run the examples with `cargo run --example <rust_file>.rs`, as the examples are not organised in the same way as the other examples, due to already being inside a Cargo project.
|
||||
|
||||
All of these code examples will do the following:
|
||||
* connect to a running websocket client on port `1977`
|
||||
* format a message to send in either JSON or Binary format. Nym messages have defined JSON formats.
|
||||
* send the message into the websocket. The native client packages the message into a Sphinx packet and sends it to the mixnet
|
||||
* wait for confirmation that the message hit the native client
|
||||
* wait to receive messages from other Nym apps
|
||||
|
||||
By varying the message content, you can easily build sophisticated service provider apps. For example, instead of printing the response received from the mixnet, your service provider might take some action on behalf of the user - perhaps initiating a network request, a blockchain transaction, or writing to a local data store.
|
||||
|
||||
> You can find an example of building both frontend and service provider code with the websocket client in the [Simple Service Provider Tutorial](https://nymtech.net/developers/tutorials/simple-service-provider/simple-service-provider.html) in the Developer Portal.
|
||||
|
||||
### Message Types
|
||||
There are a small number of messages that your application sends up the websocket to interact with the native client, as follows.
|
||||
|
||||
#### Sending text
|
||||
If you want to send text information through the mixnet, format a message like this one and poke it into the websocket:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "send",
|
||||
"message": "the message",
|
||||
"recipient": "71od3ZAupdCdxeFNg8sdonqfZTnZZy1E86WYKEjxD4kj@FWYoUrnKuXryysptnCZgUYRTauHq4FnEFu2QGn5LZWbm"
|
||||
}
|
||||
```
|
||||
|
||||
In some applications, e.g. where people are chatting with friends who they know, you might want to include unencrypted reply information in the message field. This provides an easy way for the receiving chat to then turn around and send a reply message:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "send",
|
||||
"message": {
|
||||
"sender": "198427b63ZAupdCdxeFNg8sdonqfZTnZZy1E86WYKEjxD4kj@FWYoUrnKuXryysptnCZgUYRTauHq4FnEFu2QGn5LZWbm",
|
||||
"chatMessage": "hi julia!"
|
||||
},
|
||||
"recipient": "71od3ZAupdCdxeFNg8sdonqfZTnZZy1E86WYKEjxD4kj@FWYoUrnKuXryysptnCZgUYRTauHq4FnEFu2QGn5LZWbm"
|
||||
}
|
||||
```
|
||||
|
||||
If that fits your security model, good. However, will probably be the case that you want to send **anonymous replies using Single Use Reply Blocks (SURBs)**.
|
||||
|
||||
You can read more about SURBs [here](../architecture/traffic-flow.md#private-replies-using-surbs) but in short they are ways for the receiver of this message to anonymously reply to you - the sender - without them having to know your nym address.
|
||||
|
||||
Your client will send along a number of `replySurbs` to the recipient of the message. These are pre-addressed Sphinx packets that the recipient can write to the payload of (i.e. write response data to), but not view the address. If the recipient is unable to fit the response data into the bucket of SURBs sent to it, it will use a SURB to request more SURBs be sent to it from your client.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "sendAnonymous",
|
||||
"message": "something you want to keep secret"
|
||||
"recipient": "71od3ZAupdCdxeFNg8sdonqfZTnZZy1E86WYKEjxD4kj@FWYoUrnKuXryysptnCZgUYRTauHq4FnEFu2QGn5LZWbm"
|
||||
"replySurbs": 100 // however many reply SURBs to send along with your message
|
||||
}
|
||||
```
|
||||
|
||||
Each bucket of replySURBs, when received as part of an incoming message, has a unique session identifier, which **only identifies the bucket of pre-addressed packets**. This is necessary to make sure that your app is replying to the correct people with the information meant for them! Constructing a reply with SURBs looks something like this (where `senderTag` was parsed from the incoming message)
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "reply",
|
||||
"message": "reply you also want to keep secret",
|
||||
"senderTag": "the sender tag you parsed from the incoming message"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### Sending binary data
|
||||
You can also send bytes instead of JSON. For that you have to send a binary websocket frame containing a binary encoded
|
||||
Nym [`ClientRequest`](https://github.com/nymtech/nym/blob/develop/clients/native/websocket-requests/src/requests.rs#L25) containing the same information.
|
||||
|
||||
As a response the `native-client` will send a `ServerResponse` to be decoded.
|
||||
|
||||
You can find examples of sending and receiving binary data in the Rust, Python and Go [code examples](https://github.com/nymtech/nym/tree/master/clients/native/examples), and an example project from the Nym community [BTC-BC](https://github.com/sgeisler/btcbc-rs/): Bitcoin transaction transmission via Nym, a client and service provider written in Rust.
|
||||
|
||||
#### Getting your own address
|
||||
Sometimes, when you start your app, it can be convenient to ask the native client to tell you what your own address is (from the saved configuration files). To do this, send:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "selfAddress"
|
||||
}
|
||||
```
|
||||
|
||||
You'll get back:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "selfAddress",
|
||||
"address": "the-address" // e.g. "71od3ZAupdCdxeFNg8sdonqfZTnZZy1E86WYKEjxD4kj@FWYoUrnKuXryysptnCZgUYRTauHq4FnEFu2QGn5LZWbm"
|
||||
}
|
||||
```
|
||||
|
||||
#### Error messages
|
||||
Errors from the app's client, or from the gateway, will be sent down the websocket to your code in the following format:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "error",
|
||||
"message": "string message"
|
||||
}
|
||||
```
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
# Configuration
|
||||
|
||||
## Default listening port
|
||||
The Nym native client exposes a websocket interface that your code connects to. To program your app, choose a websocket library for whatever language you're using. The **default** websocket port is `1977`, you can override that in the client config if you want.
|
||||
|
||||
You can either set this via the `--port` flag at `init` or `run`, or you can manually edit `~/.nym/clients/<CLIENT-ID>/config/config.toml`.
|
||||
|
||||
> Remember to restart your client if you change your listening port via editing your config file.
|
||||
|
||||
## Choosing a Gateway
|
||||
By default your client will choose a random gateway to connect to.
|
||||
|
||||
However, there are several options for choosing a gateway, if you do not want one that is randomly assigned to your client:
|
||||
* If you wish to connect to a specific gateway, you can specify this with the `--gateway` flag when running `init`.
|
||||
* You can also choose a gateway based on its location relative to your client. This can be done by appending the `--latency-based-routing` flag to your `init` command. This command means that to select a gateway, your client will:
|
||||
* fetch a list of all available gateways
|
||||
* send few ping messages to all of them, and measure response times.
|
||||
* create a weighted distribution to randomly choose one, favouring ones with lower latency.
|
||||
|
||||
> Note this doesn't mean that your client will pick the closest gateway to you, but it will be far more likely to connect to gateway with a 20ms ping rather than 200ms
|
||||
|
||||
## Configuring your client
|
||||
When you initalise a client instance, a configuration directory will be generated and stored in `$HOME_DIR/.nym/clients/<client-name>/`.
|
||||
|
||||
```
|
||||
tree $HOME/<user>/.nym/clients/example-client
|
||||
├── config
|
||||
│ └── config.toml
|
||||
└── data
|
||||
├── ack_key.pem
|
||||
├── gateway_shared.pem
|
||||
├── private_encryption.pem
|
||||
├── private_identity.pem
|
||||
├── public_encryption.pem
|
||||
└── public_identity.pem
|
||||
```
|
||||
|
||||
The `config.toml` file contains client configuration options, while the two `pem` files contain client key information.
|
||||
|
||||
The generated files contain the client name, public/private keypairs, and gateway address. The name `<client_id>` in the example above is just a local identifier so that you can name your clients.
|
||||
|
||||
### Configuring your client for Docker
|
||||
By default, the native client listens to host `127.0.0.1`. However this can be an issue if you wish to run a client in a Dockerized environment, where it can be convenenient to listen on a different host such as `0.0.0.0`.
|
||||
|
||||
You can set this via the `--host` flag during either the `init` or `run` commands.
|
||||
|
||||
Alternatively, a custom host can be set in the `config.toml` file under the `socket` section. If you do this, remember to restart your client process.
|
||||
@@ -0,0 +1,15 @@
|
||||
# Examples
|
||||
The Nym monorepo includes websocket client example code for Rust, Go, Javacript, and Python, all of which can be found [here](https://github.com/nymtech/nym/tree/master/clients/native/examples).
|
||||
|
||||
> Rust users can run the examples with `cargo run --example <rust_file>.rs`, as the examples are not organised in the same way as the other examples, due to already being inside a Cargo project.
|
||||
|
||||
All of these code examples will do the following:
|
||||
* connect to a running websocket client on port `1977`
|
||||
* format a message to send in either JSON or Binary format. Nym messages have defined JSON formats.
|
||||
* send the message into the websocket. The native client packages the message into a Sphinx packet and sends it to the mixnet
|
||||
* wait for confirmation that the message hit the native client
|
||||
* wait to receive messages from other Nym apps
|
||||
|
||||
By varying the message content, you can easily build sophisticated service provider apps. For example, instead of printing the response received from the mixnet, your service provider might take some action on behalf of the user - perhaps initiating a network request, a blockchain transaction, or writing to a local data store.
|
||||
|
||||
> You can find an example of building both frontend and service provider code with the websocket client in the [Simple Service Provider Tutorial](https://nymtech.net/developers/tutorials/simple-service-provider/simple-service-provider.html) in the Developer Portal.
|
||||
@@ -0,0 +1,59 @@
|
||||
# Setup & Run
|
||||
|
||||
## Viewing command help
|
||||
|
||||
You can check that your binaries are properly compiled with:
|
||||
|
||||
```
|
||||
./nym-client --help
|
||||
```
|
||||
|
||||
~~~admonish example collapsible=true title="Console output"
|
||||
```
|
||||
<!-- cmdrun ../../../../../target/release/nym-client --help -->
|
||||
```
|
||||
~~~
|
||||
|
||||
The two most important commands you will issue to the client are:
|
||||
|
||||
* `init` - initalise a new client instance.
|
||||
* `run` - run a mixnet client process.
|
||||
|
||||
You can check the necessary parameters for the available commands by running:
|
||||
|
||||
```
|
||||
./nym-client <command> --help
|
||||
```
|
||||
|
||||
## Initialising your client
|
||||
|
||||
Before you can use the client, you need to initalise a new instance of it. Each instance of the client has its own public/private keypair, and connects to its own gateway node. Taken together, these 3 things (public/private keypair + gateway node identity key) make up an app's identity.
|
||||
|
||||
Initialising a new client instance can be done with the following command:
|
||||
|
||||
```
|
||||
./nym-client init --id example-client
|
||||
```
|
||||
|
||||
~~~admonish example collapsible=true title="Console output"
|
||||
```
|
||||
<!-- cmdrun ../../../../../target/release/nym-client init --id example-client -->
|
||||
```
|
||||
~~~
|
||||
|
||||
The `--id` in the example above is a local identifier so that you can name your clients; it is **never** transmitted over the network.
|
||||
|
||||
There is an optional `--gateway` flag that you can use if you want to use a specific gateway. The supplied argument is the `Identity Key` of the gateway you wish to use, which can be found on the [mainnet Network Explorer](https://explorer.nymtech.net/network-components/gateways) or [Sandbox Testnet Explorer](https://sandbox-explorer.nymtech.net/network-components/gateways) depending on which network you are on.
|
||||
|
||||
Not passing this argument will randomly select a gateway for your client.
|
||||
|
||||
## Running your client
|
||||
You can run the initalised client by doing this:
|
||||
|
||||
```
|
||||
./nym-client run --id example-client
|
||||
```
|
||||
|
||||
When you run the client, it immediately starts generating (fake) cover traffic and sending it to the mixnet.
|
||||
|
||||
When the client is first started, it will reach out to the Nym network's validators, and get a list of available Nym nodes (gateways, mixnodes, and validators). We call this list of nodes the network _topology_. The client does this so that it knows how to connect, register itself with the network, and know which mixnodes it can route Sphinx packets through.
|
||||
@@ -0,0 +1,117 @@
|
||||
# Using Your Client
|
||||
The Nym native client exposes a websocket interface that your code connects to. The **default** websocket port is `1977`, you can override that in the client config if you want.
|
||||
|
||||
Once you have a websocket connection, interacting with the client involves piping messages down the socket and listening for incoming messages.
|
||||
|
||||
# Message Requests
|
||||
There are a number of message types that you can send up the websocket as defined [here](https://github.com/nymtech/nym/blob/develop/clients/native/websocket-requests/src/requests.rs):
|
||||
|
||||
```rust,noplayground
|
||||
{{#include ../../../../../clients/native/websocket-requests/src/requests.rs:55:97}}
|
||||
```
|
||||
|
||||
## Getting your own address
|
||||
When you start your app, it is best practice to ask the native client to tell you what your own address is (from the generated configuration files - see [here](../addressing-system.md) for more on Nym's addressing scheme). If you are running a service, you need to do this in order to know what address to give others. In a client-side piece of code you can also use this as a test to make sure your websocket connection is running smoothly. To do this, send:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "selfAddress"
|
||||
}
|
||||
```
|
||||
|
||||
You'll receive a response of the format:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "selfAddress",
|
||||
"address": "your address" // e.g. "71od3ZAupdCdxeFNg8sdonqfZTnZZy1E86WYKEjxD4kj@FWYoUrnKuXryysptnCZgUYRTauHq4FnEFu2QGn5LZWbm"
|
||||
}
|
||||
```
|
||||
|
||||
See [here](https://github.com/nymtech/nym/blob/93cc281abc2cc951023b51746fa6f2ead1f56c46/clients/native/examples/python-examples/websocket/textsend.py#L16C9-L16C9) for an example of this being used.
|
||||
|
||||
> Note that all the pieces of native client example code begin with printing the selfAddress. Examples exist for Rust, Go, Javascript, and Python.
|
||||
|
||||
## Sending text
|
||||
If you want to send text information through the mixnet, format a message like this one and poke it into the websocket:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "send",
|
||||
"message": "the message",
|
||||
"recipient": "71od3ZAupdCdxeFNg8sdonqfZTnZZy1E86WYKEjxD4kj@FWYoUrnKuXryysptnCZgUYRTauHq4FnEFu2QGn5LZWbm"
|
||||
}
|
||||
```
|
||||
|
||||
In some applications, e.g. where people are chatting with friends who they know, you might want to include unencrypted reply information in the message field. This provides an easy way for the receiving chat to then turn around and send a reply message:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "send",
|
||||
"message": {
|
||||
"sender": "198427b63ZAupdCdxeFNg8sdonqfZTnZZy1E86WYKEjxD4kj@FWYoUrnKuXryysptnCZgUYRTauHq4FnEFu2QGn5LZWbm",
|
||||
"chatMessage": "hi julia!"
|
||||
},
|
||||
"recipient": "71od3ZAupdCdxeFNg8sdonqfZTnZZy1E86WYKEjxD4kj@FWYoUrnKuXryysptnCZgUYRTauHq4FnEFu2QGn5LZWbm"
|
||||
}
|
||||
```
|
||||
|
||||
**If that fits your security model, good. However, will probably be the case that you want to send anonymous replies using Single Use Reply Blocks (SURBs)**.
|
||||
|
||||
You can read more about SURBs [here](../../architecture/traffic-flow.md#private-replies-using-surbs) but in short they are ways for the receiver of this message to anonymously reply to you - the sender - **without them having to know your client address**.
|
||||
|
||||
Your client will send along a number of `replySurbs` to the recipient of the message. These are pre-addressed Sphinx packets that the recipient can write to the payload of (i.e. write response data to), but not view the final destination of. If the recipient is unable to fit the response data into the bucket of SURBs sent to it, it will use a SURB to request more SURBs be sent to it from your client.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "sendAnonymous",
|
||||
"message": "something you want to keep secret",
|
||||
"recipient": "71od3ZAupdCdxeFNg8sdonqfZTnZZy1E86WYKEjxD4kj@FWYoUrnKuXryysptnCZgUYRTauHq4FnEFu2QGn5LZWbm",
|
||||
"replySurbs": 20 // however many reply SURBs to send along with your message
|
||||
}
|
||||
```
|
||||
|
||||
See ['Replying to SURB Messages'](#replying-to-surb-messages) below for an example of how to deal with incoming messages that have SURBs attached.
|
||||
|
||||
Deciding on the amount of SURBs to generate and send along with outgoing messages depends on the expected size of the reply. You might want to send a lot of SURBs in order to make sure you get your response as quickly as possible (but accept the minor additional latency when sending, as your client has to generate and encrypt the packets), or you might just send a few (e.g. 20) and then if your response requires more SURBs, send them along, accepting the additional latency in getting your response.
|
||||
|
||||
## Sending binary data
|
||||
You can also send bytes instead of JSON. For that you have to send a binary websocket frame containing a binary encoded
|
||||
Nym [`ClientRequest`](https://github.com/nymtech/nym/blob/develop/clients/native/websocket-requests/src/requests.rs#L25) containing the same information.
|
||||
|
||||
> As a response the `native-client` will send a `ServerResponse` to be decoded. See [Message Responses](#message-responses) below for more.
|
||||
|
||||
You can find examples of sending and receiving binary data in the [code examples](https://github.com/nymtech/nym/tree/master/clients/native/examples), and an example project from the Nym community [BTC-BC](https://github.com/sgeisler/btcbc-rs/): Bitcoin transaction transmission via Nym, a client and service provider written in Rust.
|
||||
|
||||
## Replying to SURB messages
|
||||
Each bucket of `replySURBs`, when received as part of an incoming message, has a unique session identifier, which **only identifies the bucket of pre-addressed packets**. This is necessary to make sure that your app is replying to the correct people with the information meant for them in a situation where multiple clients are sending requests to a single service.
|
||||
|
||||
Constructing a reply with SURBs looks something like this (where `senderTag` was parsed from the incoming message)
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "reply",
|
||||
"message": "reply you also want to keep secret",
|
||||
"senderTag": "the sender tag you parsed from the incoming message"
|
||||
}
|
||||
```
|
||||
|
||||
## Error messages
|
||||
Errors from the app's client, or from the gateway, will be sent down the websocket to your code in the following format:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "error",
|
||||
"message": "string message"
|
||||
}
|
||||
```
|
||||
|
||||
## LaneQueueLength
|
||||
This is currently only used in the [Socks Client](../socks5-client.md) to keep track of the number of Sphinx packets waiting to be sent to the mixnet via being slotted amongst cover traffic. As this value becomes larger, the client signals to the application it should slow down the speed with which it writes to the proxy. This is to stop situations arising whereby an app connected to the client appears as if it has sent (e.g.) a bunch of messages and is awaiting a reply, when they in fact have not been sent through the mixnet yet.
|
||||
|
||||
# Message Responses
|
||||
Responses to your messages are defined [here](https://github.com/nymtech/nym/blob/develop/clients/native/websocket-requests/src/responses.rs):
|
||||
|
||||
```rust,noplayground
|
||||
{{#include ../../../../../clients/native/websocket-requests/src/responses.rs:48:53}}
|
||||
```
|
||||
@@ -1,12 +1,12 @@
|
||||
# Introduction
|
||||
|
||||
This is Nym's technical documentation, containing information and setup guides about the various pieces of Nym software such as different mixnet infrastructure nodes, application clients, and existing applications like the desktop wallet and mixnet explorer.
|
||||
This is Nym's technical documentation, containing information and setup guides about the various pieces of Nym software such as different Mixnet infrastructure nodes, application clients, and existing applications like the desktop wallet and Mixnet explorer.
|
||||
|
||||
If you are new to Nym and want to learn about the mixnet, explore kickstart options and demos, learn how to integrate with the network, and follow developer tutorials check out the [Developer Portal](https://nymtech.net/developers/) where you can find also our [FAQ section](https://nymtech.net/developers/faq/general-faq.md).
|
||||
If you are new to Nym and want to learn about the Mixnet, explore kickstart options and demos, learn how to integrate with the network, and follow developer tutorials check out the [Developer Portal](https://nymtech.net/developers/) where you can find also our [FAQ section](https://nymtech.net/developers/faq/general-faq.html).
|
||||
|
||||
If you are looking for information and setup guides for the various pieces of Nym mixnet infrastructure (mix nodes, gateways and network requesters) and Nyx blockchain validators see the **new [Operators Guides](https://nymtech.net/operators)** book.
|
||||
If you are looking for information and setup guides for the various pieces of Nym Mixnet infrastructure (Mix Nodes, Gateways and Network Requesters) and Nyx blockchain validators see the **new [Operators Guides](https://nymtech.net/operators)** book.
|
||||
|
||||
If you're specically looking for TypeScript/JavaScript related information such as SDKs to build your own tools, step-by-step tutorials, live playgrounds and more - make sure to check out the **new [TS SDK Handbook](https://sdk.nymtech.net/)** !
|
||||
If you're specifically looking for TypeScript/JavaScript related information such as SDKs to build your own tools, step-by-step tutorials, live playgrounds and more - make sure to check out the **new [TS SDK Handbook](https://sdk.nymtech.net/)** !
|
||||
|
||||
## Popular pages
|
||||
**Network Architecture:**
|
||||
@@ -15,7 +15,7 @@ If you're specically looking for TypeScript/JavaScript related information such
|
||||
|
||||
**SDK examples:**
|
||||
* [Typescript SDK](https://sdk.nymtech.net/)
|
||||
* [Rust SDK](./sdk/rust.md)
|
||||
* [Rust SDK](sdk/rust/rust.md)
|
||||
|
||||
**Nyx**
|
||||
* [Interacting with the Nyx chain](./nyx/interacting-with-chain.md)
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
# Licensing
|
||||
|
||||
Nym is Free Software released under the Apache License V2.
|
||||
As a general approach, licensing is as follows this pattern:
|
||||
- applications and binaries are GPLv3
|
||||
- libraries and components are Apache 2.0 or MIT
|
||||
- documentation is Apache 2.0 or CC0-1.0
|
||||
|
||||
All of the contributions of the Nym core developers are © Nym Technologies SA. If you are interested in talking to us about other licenses, please get in touch.
|
||||
Again, for accurate information, please check individual files.
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
# Rust SDK
|
||||
The Rust SDK allows developers building applications in Rust to import and interact with Nym clients as they would any other dependency, instead of running the client as a seperate process on their machine. This makes both developing and running applications much easier, reducing complexity in the development process (not having to restart another client in a seperate console window/tab) and being able to have a single binary for other people to use.
|
||||
|
||||
Currently developers can use the Rust SDK to import either websocket client ([`nym-client`](../clients/websocket-client.md)) or [`socks-client`](../clients/socks5-client.md) functionality into their Rust code.
|
||||
|
||||
## Development status
|
||||
The SDK is still somewhat a work in progress: interfaces are fairly stable but still may change in subsequent releases.
|
||||
|
||||
The `nym-sdk` crate is **not yet availiable via [crates.io](https://crates.io)**. As such, in order to import the crate you must specify the Nym monorepo in your `Cargo.toml` file:
|
||||
|
||||
```toml
|
||||
nym-sdk = { git = "https://github.com/nymtech/nym" }
|
||||
```
|
||||
|
||||
In order to generate the crate docs run `cargo doc --open` from `nym/sdk/rust/nym-sdk/`
|
||||
|
||||
In the future the SDK will be made up of several components, each of which will allow developers to interact with different parts of Nym's infrastructure.
|
||||
|
||||
| Component | Functionality | Released |
|
||||
| --------- | ------------------------------------------------------------------------------------- | -------- |
|
||||
| Mixnet | Create / load clients & keypairs, subscribe to Mixnet events, send & receive messages | ✔️ |
|
||||
| Coconut | Create & verify Coconut credentials | 🛠️ |
|
||||
| Validator | Sign & broadcast Nyx blockchain transactions, query the blockchain | ❌ |
|
||||
|
||||
The `mixnet` component currently exposes the logic of two clients: the [websocket client](../clients/websocket-client.md), and the [socks](../clients/socks5-client.md) client.
|
||||
|
||||
The `coconut` component is currently being worked on. Right now it exposes logic allowing for the creation of coconut credentials on the Sandbox testnet.
|
||||
|
||||
## Websocket client examples
|
||||
> All the codeblocks below can be found in the `nym-sdk` [examples directory](https://github.com/nymtech/nym/tree/master/sdk/rust/nym-sdk/examples) in the monorepo. Just navigate to `nym/sdk/rust/nym-sdk/examples/` and run the files from there. If you wish to run these outside of the workspace - such as if you want to use one as the basis for your own project - then make sure to import the `sdk`, `tokio`, and `nym_bin_common` crates.
|
||||
|
||||
### Different message types
|
||||
There are two methods for sending messages through the mixnet using your client:
|
||||
* `send_plain_message()` is the most simple: pass the recipient address and the message you wish to send as a string (this was previously `send_str()`). This is a nicer-to-use wrapper around `send_message()`.
|
||||
* `send_message()` allows you to also define the amount of SURBs to send along with your message (which is sent as bytes).
|
||||
|
||||
### Simple example
|
||||
Lets look at a very simple example of how you can import and use the websocket client in a piece of Rust code (`examples/simple.rs`):
|
||||
|
||||
```rust,noplayground
|
||||
{{#include ../../../../sdk/rust/nym-sdk/examples/simple.rs}}
|
||||
```
|
||||
|
||||
Simply importing the `nym_sdk` crate into your project allows you to create a client and send traffic through the mixnet.
|
||||
|
||||
### Creating and storing keypairs
|
||||
The example above involves ephemeral keys - if we want to create and then maintain a client identity over time, our code becomes a little more complex as we need to create, store, and conditionally load these keys (`examples/builder_with_storage`):
|
||||
|
||||
```rust,noplayground
|
||||
{{#include ../../../../sdk/rust/nym-sdk/examples/builder_with_storage.rs}}
|
||||
```
|
||||
|
||||
As seen in the example above, the `mixnet::MixnetClientBuilder::new()` function handles checking for keys in a storage location, loading them if present, or creating them and storing them if not, making client key management very simple.
|
||||
|
||||
Assuming our client config is stored in `/tmp/mixnet-client`, the following files are generated:
|
||||
```
|
||||
$ tree /tmp/mixnet-client
|
||||
|
||||
mixnet-client
|
||||
├── ack_key.pem
|
||||
├── db.sqlite
|
||||
├── db.sqlite-shm
|
||||
├── db.sqlite-wal
|
||||
├── gateway_details.json
|
||||
├── gateway_shared.pem
|
||||
├── persistent_reply_store.sqlite
|
||||
├── private_encryption.pem
|
||||
├── private_identity.pem
|
||||
├── public_encryption.pem
|
||||
└── public_identity.pem
|
||||
|
||||
1 directory, 11 files
|
||||
```
|
||||
|
||||
### Manually handling storage
|
||||
If you're integrating mixnet functionality into an existing app and want to integrate saving client configs and keys into your existing storage logic, you can manually perform the actions taken automatically above (`examples/manually_handle_keys_and_config.rs`)
|
||||
|
||||
```rust,noplayground
|
||||
{{#include ../../../../sdk/rust/nym-sdk/examples/manually_handle_storage.rs}}
|
||||
```
|
||||
|
||||
### Anonymous replies with SURBs
|
||||
Both functions used to send messages through the mixnet (`send_message` and `send_plain_message`) send a pre-determined number of SURBs along with their messages by default.
|
||||
|
||||
The number of SURBs is set [here](https://github.com/nymtech/nym/blob/master/sdk/rust/nym-sdk/src/mixnet/client.rs#L33).
|
||||
|
||||
|
||||
```rust,noplayground
|
||||
{{#include ../../../../sdk/rust/nym-sdk/src/mixnet/client.rs:33}}
|
||||
```
|
||||
|
||||
You can read more about how SURBs function under the hood [here](../architecture/traffic-flow.md#private-replies-using-surbs).
|
||||
|
||||
In order to reply to an incoming message using SURBs, you can construct a `recipient` from the `sender_tag` sent along with the message you wish to reply to:
|
||||
|
||||
```rust,noplayground
|
||||
{{#include ../../../../sdk/rust/nym-sdk/examples/surb-reply.rs}}
|
||||
```
|
||||
|
||||
### Importing and using a custom network topology
|
||||
If you want to send traffic through a sub-set of nodes (for instance, ones you control, or a small test setup) when developing, debugging, or performing research, you will need to import these nodes as a custom network topology, instead of grabbing it from the [`Mainnet Nym-API`](https://validator.nymtech.net/api/swagger/index.html) (`examples/custom_topology_provider.rs`).
|
||||
|
||||
There are two ways to do this:
|
||||
|
||||
#### Import a custom Nym API endpoint
|
||||
If you are also running a Validator and Nym API for your network, you can specify that endpoint as such and interact with it as clients usually do (under the hood):
|
||||
|
||||
```rust,noplayground
|
||||
{{#include ../../../../sdk/rust/nym-sdk/examples/custom_topology_provider.rs}}
|
||||
```
|
||||
|
||||
#### Import a specific topology manually
|
||||
If you aren't running a Validator and Nym API, and just want to import a specific sub-set of mix nodes, you can simply overwrite the grabbed topology manually:
|
||||
|
||||
```rust,noplayground
|
||||
{{#include ../../../../sdk/rust/nym-sdk/examples/manually_overwrite_topology.rs}}
|
||||
```
|
||||
|
||||
### Send and receive in different tasks
|
||||
If you need to split the different actions of your client across different tasks, you can do so like this:
|
||||
|
||||
```rust, noplayground
|
||||
{{#include ../../../../sdk/rust/nym-sdk/examples/parallel_sending_and_receiving.rs}}
|
||||
```
|
||||
|
||||
## Socks client example
|
||||
There is also the option to embed the [`socks5-client`](../clients/socks5-client.md) into your app code (`examples/socks5.rs`):
|
||||
|
||||
```rust,noplayground
|
||||
{{#include ../../../../sdk/rust/nym-sdk/examples/socks5.rs}}
|
||||
```
|
||||
|
||||
```admonish info
|
||||
If you are looking at implementing Nym as a transport layer for a crypto wallet or desktop app, this is probably the best place to start.
|
||||
```
|
||||
|
||||
## Coconut credential generation
|
||||
The following code shows how you can use the SDK to create and use a [credential](../bandwidth-credentials.md) representing paid bandwidth on the Sandbox testnet.
|
||||
|
||||
```rust,noplayground
|
||||
{{#include ../../../../sdk/rust/nym-sdk/examples/bandwidth.rs}}
|
||||
```
|
||||
|
||||
You can read more about Coconut credentials (also referred to as `zk-Nym`) [here](../coconut.md).
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user