Compare commits

..

299 Commits

Author SHA1 Message Date
Jon Häggblad 8cd9b99d72 wip 2023-11-16 11:22:05 +00:00
Jon Häggblad f7093cdc5a Rework error handling in tun device 2023-11-15 12:33:45 +00:00
mx 4ec08da36d Merge pull request #4144 from nymtech/hackathon-submission
linked to discussion fr submission
2023-11-15 09:15:30 +00:00
mfahampshire 16c59d95d3 linked to discussion fr submission 2023-11-15 10:00:27 +01:00
Jon Häggblad e6f76380f6 Add timeouts in tun handler (#4142) 2023-11-14 17:34:37 +01:00
serinko 6961ecae55 hotfix
Adding a white line to fix the re-appearing bug
2023-11-14 15:06:49 +00:00
serinko dd814c067c Merge pull request #4138 from nymtech/patch/docs/hotfix
DOCS hot-fix: Missed bugs, details, spellcheck etc
2023-11-14 14:37:10 +00:00
serinko 666d5945b9 add init to fix node family cmdrun output 2023-11-14 15:15:15 +01:00
serinko ecebf6e84c add cosmwasm time execution definition 2023-11-14 14:54:45 +01:00
serinko 4663d39505 fix naming 2023-11-14 14:31:39 +01:00
serinko 81a7d7b001 correct urls && fix naming 2023-11-14 14:28:13 +01:00
serinko 2c0a561cd5 change html syntax 2023-11-14 14:20:44 +01:00
Tommy Verrall d187d252fb Merge pull request #4132 from nymtech/dependabot/npm_and_yarn/axios-1.6.0
Bump axios from 1.5.1 to 1.6.0
2023-11-14 13:04:38 +00:00
Tommy Verrall 4026dc8eef Merge pull request #4133 from nymtech/dependabot/npm_and_yarn/nym-api/tests/axios-1.6.0
Bump axios from 0.27.2 to 1.6.0 in /nym-api/tests
2023-11-14 12:59:51 +00:00
Sachin Kamath c02453b2d1 docs: update staking denoms, outdated validator info and small improvements 2023-11-14 17:21:39 +05:30
Jędrzej Stuczyński f1a5a0ccd7 returning 'nil' for non-existing origin as opposed to an empty string (#4135)
* returning 'nil' for non-existing origin as opposed to an empty string

* version bump
2023-11-14 11:16:16 +00:00
mx f9a4ca5a22 Merge pull request #4124 from nymtech/nymtech/docs/feature/updates
Update documentation
2023-11-13 18:31:42 +00:00
serinko ee99843b51 correction point ordering - PR finished 2023-11-13 18:46:56 +01:00
serinko 05e349cf37 spell check 2023-11-13 17:44:33 +01:00
serinko 8d51cd1afd spell check 2023-11-13 17:40:30 +01:00
serinko a2fd78963c spell check 2023-11-13 17:39:03 +01:00
serinko 59d43e1acd spell check 2023-11-13 17:36:33 +01:00
serinko 354c529cea syntax edit 2023-11-13 17:35:33 +01:00
serinko 435a60aee9 syntax edit 2023-11-13 17:34:55 +01:00
serinko a1c9b9b4bb syntax edit 2023-11-13 17:33:54 +01:00
serinko 457d1e8615 syntax edit 2023-11-13 17:33:21 +01:00
serinko 05eb05643f correct link path 2023-11-13 15:53:54 +01:00
serinko 3d82f84e1d correct link path 2023-11-13 15:52:16 +01:00
serinko c7b3999dcf add command example 2023-11-13 15:51:42 +01:00
serinko 8336bb0009 comment a reduntand page 2023-11-13 15:48:14 +01:00
serinko 4cb0231acf add run binary steps 2023-11-13 15:47:27 +01:00
serinko 3715860a47 add donwload binary steps 2023-11-13 15:43:38 +01:00
serinko 5b2e4158bd change version variable 2023-11-13 15:37:36 +01:00
serinko 2ddd34f343 edit syntax 2023-11-13 15:00:19 +01:00
serinko 564cbadc6e edit gateway bonding 2023-11-13 14:58:31 +01:00
serinko 5a9920edb8 simplify bonding sequence 2023-11-13 14:48:41 +01:00
serinko 0e312f66ea make node upgrade steps more explicit 2023-11-13 14:46:26 +01:00
serinko 8ca2ef28e6 edit node upgrade steps and add auto scripts 2023-11-13 13:53:32 +01:00
serinko 0cd0139307 edit Network requester to Network Requester 2023-11-13 13:02:04 +01:00
serinko 0041b4a7a7 edit Mix node to Mix Node 2023-11-13 13:00:11 +01:00
serinko caa18f1661 edit Network requester to Network Requester 2023-11-13 12:58:35 +01:00
serinko 946ced541c edit Mix node to Mix Node 2023-11-13 12:57:03 +01:00
serinko fd0c4c2623 edit Network requester to Network Requester 2023-11-13 12:55:54 +01:00
serinko 9f57ea4309 edit Mix node to Mix Node 2023-11-13 12:54:59 +01:00
serinko 4c7a30a16d edit Mix node to Mix Node 2023-11-13 12:50:35 +01:00
serinko 8029136251 edit Network requester to Network Requester 2023-11-13 12:50:10 +01:00
serinko 2a3d898da1 edit gateway to Gateway 2023-11-13 12:48:07 +01:00
serinko 0dd1f3ac2b edit Network requester to Network Requester 2023-11-13 12:47:26 +01:00
serinko 2edd704e39 edit Mix node to Mix Node 2023-11-13 12:45:54 +01:00
serinko e936ba1d26 edit Mix node to Mix Node 2023-11-13 12:39:54 +01:00
serinko d6a9f4c549 syntax edit 2023-11-13 12:34:57 +01:00
Pierre Dommerc 2934d24e53 feat(vpn-ui): scaffold rust backend (#4073)
* scaffold app

* feat: local storage for app data & config
2023-11-13 12:33:58 +01:00
serinko aa65b96ef2 reorder Mix Node setup steps 2023-11-13 11:52:18 +01:00
serinko b5bb3f36bf add steps prior to bond 2023-11-13 11:46:08 +01:00
serinko 9f5c225cf9 edit Network requester to Network Requester 2023-11-13 11:32:16 +01:00
serinko f0864adfe6 mix node to Mix Node 2023-11-13 11:31:18 +01:00
serinko 532fea38d5 edit gateway to Gateway 2023-11-13 11:30:22 +01:00
serinko 83eb0cbf54 mix node to Mix Node 2023-11-13 11:29:35 +01:00
serinko 58e0330f4f mix node to Mix Node 2023-11-13 11:29:16 +01:00
Zane Schepke 11e01335c2 Update tauri.conf.json 2023-11-12 13:48:07 -05:00
dependabot[bot] aa8accfbf8 Bump axios from 0.27.2 to 1.6.0 in /nym-api/tests
Bumps [axios](https://github.com/axios/axios) from 0.27.2 to 1.6.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v0.27.2...v1.6.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-11 06:19:19 +00:00
dependabot[bot] efc83bdc1a Bump axios from 1.5.1 to 1.6.0
Bumps [axios](https://github.com/axios/axios) from 1.5.1 to 1.6.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.5.1...v1.6.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-10 17:28:32 +00:00
serinko f623a9967c unify naming convention network requester to Network requester 2023-11-09 18:13:54 +01:00
serinko 5395eebaef unify naming convention mixnode to Mix node 2023-11-09 18:13:18 +01:00
serinko 7ffe4dd1d8 unify naming convention gateway to Gateway 2023-11-09 18:12:23 +01:00
serinko 1d292d4688 unify naming convention 2023-11-09 18:09:09 +01:00
serinko dd04d4ea46 unify naming convention 2023-11-09 18:08:34 +01:00
serinko 3620cc9df0 unify naming convention gateway to Gateway 2023-11-09 18:08:00 +01:00
serinko b06d6ff412 unify naming convention gateway to Gateway 2023-11-09 17:57:51 +01:00
serinko 6088c835a3 unify naming convention mixnode to Mix node 2023-11-09 17:53:51 +01:00
serinko 9113658a42 unify naming convention 2023-11-09 17:34:00 +01:00
serinko d09503edf4 unify naming convention gateway to Gateway 2023-11-09 17:22:09 +01:00
serinko 09124dafac unify naming convention network requester to Network requester 2023-11-09 17:20:20 +01:00
serinko a2ede72798 unify naming convention network requester to Network requester 2023-11-09 17:16:55 +01:00
serinko 61296b58e9 unify naming convention mixnode to Mix node 2023-11-09 17:15:34 +01:00
serinko e3f3c5620d spell check 2023-11-09 17:06:26 +01:00
serinko c656b3968b add firo intro 2023-11-09 17:03:10 +01:00
serinko 41f9b9b340 rename gateway to Gateway 2023-11-09 14:56:15 +01:00
serinko 7d12b91bbd remove --host flag 2023-11-09 14:52:51 +01:00
serinko 2960a4c48e add --listening-address and --public-ips 2023-11-09 14:50:28 +01:00
serinko 4a84274055 rename gateway to Gateway 2023-11-09 14:43:27 +01:00
serinko c34d89165c syntax edit 2023-11-09 14:37:44 +01:00
serinko f1b0a60b34 syntax edit 2023-11-09 14:37:32 +01:00
serinko abef9c9768 add firo wallet setup 2023-11-09 14:34:28 +01:00
serinko c4b227f66e create firo setup screenshot 2023-11-09 14:31:50 +01:00
serinko 2389d7e62f add firo to SUMMARY.md 2023-11-09 14:23:40 +01:00
serinko f5e16cda5e initialise firo guide 2023-11-09 14:22:50 +01:00
serinko 7ea415c082 finish electrum guide 2023-11-09 14:21:17 +01:00
serinko 90bfeb3dd2 add electrum to SUMMARY.md 2023-11-09 14:15:25 +01:00
serinko f8666cec45 add NC install steps 2023-11-09 14:13:34 +01:00
serinko f6e5892de7 initialise electrum guide 2023-11-09 14:01:30 +01:00
Tommy Verrall 6d2d8ce149 Merge pull request #4118 from nymtech/feature/ts-sdk-fixes
Feature/ts sdk fixes
2023-11-09 12:12:06 +00:00
Bogdan-Ștefan Neacşu d38139be66 Add private ip assignment (#4089)
* Add private ip assignment

* Update wg IPs
2023-11-09 13:39:27 +02:00
Jon Häggblad 46d1ef7892 Disable poisson in ip-packet-router (#4123) 2023-11-09 12:16:33 +01:00
Jon Häggblad 72bad6bb38 Fix read packet buffer size (#4122) 2023-11-09 02:12:58 +01:00
Mark Sinclair 66fd484bd5 Update cd-docs.yml
Allow docs GH Action to run for all branches
2023-11-08 15:22:03 +00:00
mfahampshire a1328c96cf commit to trigger deploy 2023-11-08 16:02:02 +01:00
Jon Häggblad 18aa4707a4 wg: tun devices in wireguard and packet router are separate (#4121) 2023-11-08 15:16:00 +01:00
mx dadfc412f2 Merge pull request #4107 from nymtech/feature/websocket-client-usage-docs
Feature/websocket client usage docs
2023-11-08 08:48:12 +00:00
Jon Häggblad 3746975b14 Merge pull request #4110 from nymtech/jon/wireguard-changes
wireguard: config tweaks
2023-11-08 09:08:06 +01:00
Jon Häggblad 2c90229fce Set peer at runtime 2023-11-08 08:42:19 +01:00
Jon Häggblad b461645d3d Make MTU configurable at runtime 2023-11-08 08:42:19 +01:00
Jon Häggblad f7f8b9b898 wireguard: set MTU to 1420 2023-11-08 08:42:19 +01:00
Tommy Verrall 880d2d4edd Merge pull request #4119 from nymtech/tommy/publish-sdk-candidate
Update SDK - version bump to 1.2.4-rc.1
2023-11-07 17:37:03 +00:00
Tommy Verrall 7bc81a91c5 run the formatter 2023-11-07 17:47:43 +01:00
mfahampshire 4ce652af95 update mdbook admonish 2023-11-07 17:46:46 +01:00
Tommy Verrall 8142e5c84c update version bump to 1.2.4-rc.1
- includes fixes for parser body
- and errors associative with the encoded_payload_helper.rs
2023-11-07 17:38:46 +01:00
Lorexia 4efe712fc5 Merge branch 'develop' into feature/ts-sdk-fixes 2023-11-07 17:25:06 +01:00
Tommy Verrall 03f754cde4 Merge pull request #4102 from nymtech/chore/potential-fix-issue-3345
message checks around encoded payload helper
2023-11-07 15:37:49 +00:00
Jędrzej Stuczyński 8f53f095fb Change default http API timeout from 3s to 10s (#4117) 2023-11-07 15:35:02 +00:00
Tommy Verrall a0c667927c one last change 2023-11-07 16:21:59 +01:00
benedetta davico 0cc090038b Merge pull request #4116 from nymtech/master
Merge master to develop
2023-11-07 15:56:49 +01:00
benedetta davico af32fe4022 Merge pull request #4114 from nymtech/release/2023.4-galaxy
Release/2023.4 galaxy
2023-11-07 15:54:16 +01:00
mfahampshire eb2ac7630a first pass at ws client usage docs 2023-11-07 14:38:54 +01:00
Tommy Verrall 189fd0ece4 insert import 2023-11-07 13:20:25 +01:00
Tommy Verrall b6ccab79d2 pr comments
- update based on comments
2023-11-07 13:18:25 +01:00
Tommy Verrall 93cc281abc Merge pull request #4112 from nymtech/chore/fix-get-reader-errors
Fixing parseBody for Mixfetch
2023-11-07 11:51:27 +00:00
Tommy Verrall 1f83b6f4e8 Update request.go with PR comments 2023-11-07 12:38:06 +01:00
Lorexia 5a96ef4ffe Update mixnet docs 2023-11-07 12:20:35 +01:00
Lorexia dea3f7d4b3 Merge updates and update mixFetcha and mixnet examples 2023-11-07 11:54:01 +01:00
Tommy Verrall 40b2729a01 attempt fixing parseBody
- why?
when using the mixfetch SDK, i was encountering issues, when posting requests to specific endpoints. It was not parsing the response correctly with:

Error: panic:syscall/js: Value.Call: property getReader is not a function

By updating the above, i've tested this works on all variations of post and get request using mixfetch.

Locally I had to upgrade my version of go to 1.20
2023-11-07 11:19:57 +01:00
benedettadavico 91f383d5ac Bump mixnode version and update changelog 2023-11-07 07:58:27 +01:00
Jędrzej Stuczyński 268588daac Feature/tls mixnet client (#4103)
* adjusting ts mixnet client constructor

* added forceTls argument to 'ClientOptsSimple'

* more sdk types removed

* fixed import

* removed go debug code

* printing wasm blob version on load

* version bump

* temporarily removed 'nym/nym/wasm/full-nym-wasm'

* changed workspaces definition

* correctly setting initial rc.0 suffix

* updated crate versions

* reverted 'useWorkspaces' lerna option

* Fix up dependency versions

* Add dev mode toggle to SDK publish scripts

* Show location of WASM package

* Change dev mode and CI build order

* Bump package versions in SDK docs

* Remove two versions of `mix-fetch` from SDK docs and only use `-full-fat` version

* Remove old arguments for mixFetch and rename to bust cache

* Remove `nym-wasm-sdk` from linting

* Release v1.2.3 of Typescript SDK

* Force WSS on mixnet client

* Bump TS SDK to 1.2.4-rc.0

* Clean up lock file

* Update node-tester version to 1.2.3 in nym-wallet

---------

Co-authored-by: Mark Sinclair <mmsinclair@users.noreply.github.com>
2023-11-06 19:05:11 +00:00
Tommy Verrall c0aff70b37 Merge pull request #4108 from nymtech/develop
Adding docs to the release
2023-11-06 15:55:58 +00:00
mfahampshire 410ef85165 updating websocket send and receives 2023-11-06 16:52:22 +01:00
mx 4af376cb33 Merge pull request #4106 from nymtech/serinko/docs/quick-patch
Quick addon on Exit Gateway setup
2023-11-06 15:24:04 +00:00
serinko 66f012c70e add exit policy to existing NR 2023-11-06 16:18:13 +01:00
mfahampshire 198739a126 added websocket client examples page 2023-11-06 15:48:59 +01:00
mfahampshire 85a0a3d8b5 * created 'examples' file
* added default port to configuration file
2023-11-06 15:48:20 +01:00
mfahampshire 789525c35b remove ref to previous single page setup 2023-11-06 14:02:41 +01:00
mfahampshire 7ad5ff7770 * cmdrun path fixes
* rename file to setup+run
2023-11-06 14:01:20 +01:00
mfahampshire bf56696adc smol tweaks to readability 2023-11-06 13:57:55 +01:00
mfahampshire 193ea34efc turned single ws client page into stub for expanded directory structure 2023-11-06 13:57:40 +01:00
mfahampshire 9c0ca32033 expanded pages for ws client 2023-11-06 13:57:12 +01:00
mfahampshire 76e49476a6 updated clients section format: expanding websocket client 2023-11-06 13:56:58 +01:00
mfahampshire 6d30ede01e updated mdbookadmonish 2023-11-06 13:56:33 +01:00
mfahampshire 02459f5d53 added links + typo fixes 2023-11-06 12:51:37 +01:00
Lorexia 4c2c738bba Update versioning for sanity check 2023-11-03 14:04:24 +01:00
Jon Häggblad 9f2bff2d16 Merge pull request #4068 from nymtech/jon/ip-forwarder-tun-device
Create IpPacketRouter
2023-11-03 13:34:37 +01:00
Tommy Verrall ec8c67e67d Merge pull request #4098 from nymtech/release/ts-sdk-1.2.1
Release Typescript SDK 1.2.1
2023-11-03 11:55:58 +00:00
Tommy Verrall 41bbbed704 keep notes 2023-11-03 12:49:35 +01:00
Lorexia a7f9cb7db0 mimxnet client examples updates 2023-11-03 12:48:55 +01:00
Tommy Verrall 14961d231e - add checks around message lengths 2023-11-03 12:46:55 +01:00
mx 881602bd9b Merge pull request #4101 from nymtech/serinko/patch/docs
Update admonish
2023-11-03 10:37:39 +00:00
serinko ba48b71b23 install admonish to all books 2023-11-03 11:29:20 +01:00
Lorexia c1f2bf4f27 Update versioning and mixfetch docs 2023-11-03 11:02:07 +01:00
mfahampshire 43bd1ba419 updated mdbook admonish assets 2023-11-03 10:59:00 +01:00
Jon Häggblad 807e7e588f Remove expect on NYM_CLIENT_ADDR 2023-11-03 10:49:39 +01:00
mx 9d678b4f8a Merge pull request #4047 from nymtech/chore/sdk-docs-restructure
Chore/sdk docs restructure
2023-11-03 09:44:24 +00:00
Jon Häggblad 462c15887e Fix compilation on non-linux 2023-11-03 10:03:05 +01:00
Jon Häggblad 60b1c1208a NYM_CLIENT_ADDR 2023-11-03 09:31:17 +01:00
Jon Häggblad 756aca36ad Take RoutingMode as argument 2023-11-03 09:26:32 +01:00
Jon Häggblad 90c40b76f5 rustfmt 2023-11-03 09:26:32 +01:00
Jon Häggblad 71a409cc0d Add RoutingMode enum 2023-11-03 09:26:32 +01:00
Jon Häggblad 6beb77e464 rustfmt 2023-11-03 09:26:32 +01:00
Jon Häggblad 5f5ac4449c send back to mixnet 2023-11-03 09:26:32 +01:00
Jon Häggblad bb0fb71a21 Rename remaining places to ip packet router 2023-11-03 09:26:32 +01:00
Jon Häggblad 833a1b118e on_message 2023-11-03 09:26:25 +01:00
Jon Häggblad 22dbdf0cd2 Create IpForwarderService 2023-11-03 09:26:25 +01:00
Jon Häggblad 7e6a4c073f ci: cargo clean before clippy in nightly build 2023-11-03 09:00:27 +01:00
mfahampshire 50c994d2ed fixed addr 2023-11-03 00:19:33 +01:00
mfahampshire d151b907d1 added open proxies 2023-11-02 23:36:14 +01:00
Mark Sinclair 77aa58083d Fix lint error 2023-11-02 21:56:27 +00:00
Mark Sinclair 13aeca9c88 Fix lint error 2023-11-02 21:37:47 +00:00
Jon Häggblad 3689b6df1a Merge pull request #4092 from nymtech/jon/ci-win-runners
ci: switch to github runners for nightly windows builds
2023-11-02 21:40:54 +01:00
Mark Sinclair d64613006c Release Typescript SDK to version 1.2.1 2023-11-02 19:29:02 +00:00
Mark Sinclair 1582c13f62 Update SDK contract client 2023-11-02 19:26:09 +00:00
Mark Sinclair 554010b5cb Add NodeJS mixFetch to version bump tool 2023-11-02 19:17:35 +00:00
Sebastian Martinez 60912ff8ef Fix sdk publish action (#4088)
* fix: sdk publish script

The bash implementation used in the GitHub CI runner seems to have an
issue with incrementing a variable with `(( COUNTER++ ))` while `((
COUNTER=+1 ))` works fine.

* Add more sdk packages to workspace and normalize build sdk scripts

* Disable workspaces in npm publish sdk

Signed-off-by: Sebastian Martinez <me@sebastinez.dev>

* Continue publishing even when it fails

Signed-off-by: Sebastian Martinez <me@sebastinez.dev>

---------

Signed-off-by: Sebastian Martinez <me@sebastinez.dev>
2023-11-02 17:19:34 +00:00
mfahampshire a9c40e76dc revert previous 2023-11-02 17:17:06 +01:00
mfahampshire e9a0c6f8d0 added code example to helpers 2023-11-02 17:13:55 +01:00
mfahampshire bcfea21501 upgraded mdbook-admonish version 2023-11-02 17:13:37 +01:00
Jon Häggblad 52736881db Update Cargo.lock 2023-11-02 16:36:40 +01:00
Tommy Verrall c85ac8e54d Merge pull request #4095 from nymtech/fix-cd-docs-dev
Github actions: remove deployment to website-dev
2023-11-02 14:30:05 +00:00
Raphaël Walther c4be55e824 Github actions: remove deployment to website-dev 2023-11-02 14:52:30 +01:00
Tommy Verrall e62f5833e0 Merge pull request #4093 from nymtech/master
Master into develop
2023-11-02 13:50:21 +00:00
Lorexia d073442cfe Correct typo in docs 2023-11-02 14:45:44 +01:00
Tommy Verrall ba803943d8 Merge pull request #4094 from nymtech/fix-cd-docs
Github Actions: fix cd-docs
2023-11-02 13:27:36 +00:00
Raphaël Walther 6e9eb26e27 Github Actions: fix cd-docs 2023-11-02 14:07:45 +01:00
mfahampshire a4bb4ec6c5 first pass at helper messages 2023-11-02 13:19:54 +01:00
mfahampshire 72553623a7 first pass at troubleshooting doc 2023-11-02 13:10:05 +01:00
Lorexia 30165c10af Update contract client page 2023-11-02 13:05:34 +01:00
serinko caf33095d6 Merge pull request #4059 from nymtech/operators/smoosh-updates
OPERATORS: Finalize legal findings, Update smoosh + Exit GW, announce exit policy, update --host changes
2023-11-02 11:01:59 +00:00
serinko 0173bc748b add smoosh link to intro 2023-11-02 11:56:31 +01:00
Jon Häggblad b9088a8dda ci: switch nightly-nym-connect-desktop-build to windows-latest 2023-11-02 10:54:31 +01:00
Jon Häggblad 01605534f7 ci: change nightly-nym-wallet-build to windows-latest 2023-11-02 10:54:31 +01:00
mfahampshire 082886ab19 removed todo - checked dependency versioning 2023-11-02 10:35:57 +01:00
mfahampshire 9a592df4f0 updated import info 2023-11-02 10:26:07 +01:00
mfahampshire 2334109721 tweak 2023-11-02 10:25:37 +01:00
mfahampshire bc21fa3a7e fix broken imports 2023-11-02 10:25:10 +01:00
mfahampshire aa7dd1ecf9 admonish plugin upgrade 2023-11-02 10:24:46 +01:00
mfahampshire 6122817ab6 fixed broken link 2023-11-02 10:24:25 +01:00
mfahampshire c667bb91c7 tweak 2023-11-02 10:24:03 +01:00
serinko 9b93b30aed add reversed proxy ports 2023-11-02 10:01:01 +01:00
serinko 79d9ddd463 add correct cmdrun auto flow 2023-11-02 09:57:35 +01:00
serinko ca512ca1ad change phrasing 2023-11-02 09:10:13 +01:00
serinko 0f05f6e1ee change phrasing 2023-11-02 09:06:33 +01:00
serinko 06e656840a change syntax *binary* -> 2023-11-02 08:58:56 +01:00
serinko 48391d2252 remove ./ from SUMMARY.md 2023-11-02 08:56:13 +01:00
Jon Häggblad e5ef62d7e7 ci: switch nightly-build to github hosted windows-latest 2023-11-02 08:51:30 +01:00
Jon Häggblad 1a6334f548 ci: fix typo in workflow name 2023-11-02 08:38:26 +01:00
mfahampshire 8cf0b3adae first draft of expanded rust stuff 2023-11-01 21:01:47 +01:00
mfahampshire d0e51df59a new directory structure for rust SDK docs 2023-11-01 17:34:55 +01:00
serinko 50da1b1606 add wss host setup 2023-11-01 17:23:28 +01:00
Sebastian Martinez df010ef304 Update mix-fetch-node to rc.3
Signed-off-by: Sebastian Martinez <me@sebastinez.dev>
2023-11-01 16:41:50 +01:00
Sebastian Martinez 41caad4dbf Fix the getRandomValue crypto polyfill issue
Signed-off-by: Sebastian Martinez <me@sebastinez.dev>
2023-11-01 16:41:11 +01:00
mfahampshire 11e3836599 spellcheck + table format fix 2023-11-01 16:31:02 +01:00
Sebastian Martinez 4262e2e2f6 fix: adding some polyfills to nodejs-client and mix-fetch
During the merge of the nodejs-wasm-client there seems to be some
losses, this commit makes nodejs-client and the nodejs mix-fetch work
with the internal tools. Still looking into Tommys qa feedback.
2023-11-01 15:57:23 +01:00
serinko 610f7e88ca add example setup-network-requester 2023-11-01 14:44:51 +01:00
Jon Häggblad 05a39aa5f5 Merge pull request #4087 from nymtech/jon/ci-work
ci: tidy up a few more workflows
2023-11-01 13:36:47 +01:00
Sebastian Martinez 784ee5ace8 Revert "Add hack for working with old nym gateways"
This reverts commit 7129de4373.
To avoid breaking wss
2023-11-01 13:28:49 +01:00
serinko 73fe7ebec7 finish exit gateway setup 2023-11-01 12:00:16 +01:00
Jon Häggblad 7da2ce362d ci: create nightly-nym-connect-desktop-build 2023-11-01 11:55:56 +01:00
Jon Häggblad f28e0b529e ci: use macos-latest in nightly-build 2023-11-01 11:55:56 +01:00
Jon Häggblad 6e9a588c1a ci: nightly-build sed debug = false 2023-11-01 11:50:48 +01:00
Jon Häggblad f3442c6964 ci: sort out nightly wallet build 2023-11-01 11:50:48 +01:00
Jon Häggblad 241169140e ci: move nightly to ubuntu-20.04 2023-11-01 11:50:04 +01:00
Jon Häggblad 143036c2a2 ci: rename cd-docs 2023-11-01 11:50:04 +01:00
Jon Häggblad 043437a0c3 ci: rename to ci-binary-config-checker 2023-11-01 11:46:08 +01:00
Jędrzej Stuczyński 1370192823 print info on exit policy on embedded NR init (#4086) 2023-11-01 10:31:59 +00:00
serinko 07037341c5 change --host to -4 https://ifconfig.me 2023-11-01 11:06:44 +01:00
serinko 5406396c3c syntax fix 2023-11-01 11:00:43 +01:00
serinko bd50119152 change --host -> 146.70.170.3 2023-11-01 11:00:01 +01:00
serinko d941d92571 add --with-exit-policy flag 2023-11-01 10:58:41 +01:00
Sebastian Martinez 06a96fa74a Polishing nodejs-client and mix-fetch-node
Signed-off-by: Sebastian Martinez <me@sebastinez.dev>
2023-11-01 09:31:15 +01:00
Sebastian Martinez 7129de4373 Add hack for working with old nym gateways
Signed-off-by: Sebastian Martinez <me@sebastinez.dev>
2023-11-01 09:30:40 +01:00
Sebastian Martinez 14d0d5dcbb Add mix-fetch for nodejs 2023-11-01 09:30:40 +01:00
Sebastian Martinez 37958ccb4e Add nodejs wrapper for wasm sphynx client 2023-11-01 09:30:40 +01:00
Tommy Verrall 7e16920358 Merge pull request #4077 from nymtech/chore/unify-client-init
DRY up client cli
2023-11-01 08:26:02 +00:00
Tommy Verrall 5df5918176 Merge pull request #4083 from nymtech/release/2023.3-kinder
Release/2023.3 kinder
2023-11-01 08:24:05 +00:00
mfahampshire a10ebf342b tweak 2023-10-31 17:14:30 +01:00
serinko 0e906b1a3d try change ifconfig.me -> icanhazip.com 2023-10-31 17:11:57 +01:00
mfahampshire b072a080ae added shipyard info 2023-10-31 17:03:37 +01:00
serinko eb7305e31c add token economics paper info 2023-10-31 16:01:54 +01:00
mfahampshire 4b23cd94fd streamlined node types 2023-10-31 15:46:25 +01:00
mfahampshire 04fdc1dc60 streamline integrations files 2023-10-31 15:45:27 +01:00
mfahampshire 27810d473d added community examples 2023-10-31 15:45:00 +01:00
mfahampshire d1160350b2 added notepad to gitignore file 2023-10-31 15:44:39 +01:00
mfahampshire 5d8c5224ed added examples pages 2023-10-31 15:44:22 +01:00
Jon Häggblad e38b8fd419 Merge pull request #4064 from nymtech/jon/embedded-ip-forwarder-in-gateway
Run nym-ip-packet-router in gateway
2023-10-31 14:48:21 +01:00
Jon Häggblad 19a0fb3f38 Merge pull request #4079 from nymtech/jon/ci-maintenance
Tidy up some github workflows
2023-10-31 14:42:18 +01:00
benedetta davico ebe693e591 Update publish-nym-wallet-macos.yml 2023-10-31 14:37:57 +01:00
Jon Häggblad 6fbb6539ef ci: tidy ci-nym-vpn-ui-js 2023-10-31 14:36:07 +01:00
Jon Häggblad 199817bed0 ci: more iterate on ci-nym-vpn-ui-rust 2023-10-31 14:31:12 +01:00
Jon Häggblad 5ce2e21abc ci: iterate on ci-nym-vpn-ui-rust 2023-10-31 14:26:09 +01:00
Jędrzej Stuczyński f2383b5cb0 replaced '--disable-sign-ext' with '--signext-lowering' when running wasm-opt (#3896)
* replaced '--disable-sign-ext' with '--signext-lowering' when running wasm-opt + updated wasm-opt

* updated wasm-opt used in CI
2023-10-31 12:39:25 +00:00
Jon Häggblad 99c972e880 Set name to ci-nym-api-tests 2023-10-31 11:49:04 +01:00
Jon Häggblad b169b6b438 ci: add workflow_dispatch to ci-nym-vpn-ui-rust 2023-10-31 11:48:20 +01:00
serinko 47d0c0ffa2 add exit policy implementation steps 2023-10-31 11:37:57 +01:00
Jon Häggblad 3307e7e0fc rustfmt 2023-10-31 10:38:30 +01:00
Jon Häggblad 70d0aabbc1 Big chunk of search replace to the new name 2023-10-31 10:37:46 +01:00
serinko b83e756650 syntax fix 2023-10-31 10:37:41 +01:00
serinko b10aa52eca add exit policy implementation steps 2023-10-31 10:35:30 +01:00
serinko 9e33454dc2 add exit policy implementation steps 2023-10-31 10:34:31 +01:00
Jon Häggblad a088d64d57 Fix missed rename in template 2023-10-31 10:21:01 +01:00
Jon Häggblad 7c5183700e Rename to ip-packet-router directory 2023-10-31 10:14:58 +01:00
Jon Häggblad 00ca4d2afa Rename to nym-ip-packet-router 2023-10-31 10:13:10 +01:00
Jon Häggblad cf234ecf82 Update files to reflect new filename 2023-10-31 09:58:08 +01:00
Jon Häggblad b48dc0b38a Rename to old_config_v1_1_31.rs 2023-10-31 09:53:28 +01:00
Raphaël Walther 0294febd63 Merge pull request #4076 from nymtech/feature/update-security-page
Update security disclosure process
2023-10-30 18:34:07 +01:00
Jędrzej Stuczyński 5fcaacc39a wasm lock 2023-10-30 17:16:08 +00:00
Jędrzej Stuczyński 30000126d1 Incorporate basic nym-node HTTP API (with swagger) to mixnodes (#4075)
* basic nym-node router

* loading legacy routes

* dead code

* config migrations
2023-10-30 17:12:13 +00:00
Jędrzej Stuczyński 00179d563b removed the contracicting flag 2023-10-30 17:06:36 +00:00
Jędrzej Stuczyński 4a4b0ab7e0 putting no cover and fastmode to common args 2023-10-30 16:59:40 +00:00
Jędrzej Stuczyński b3c7801f73 moved to different submodule 2023-10-30 16:30:12 +00:00
Jędrzej Stuczyński 4716d278ce combine client run args 2023-10-30 16:26:37 +00:00
Jędrzej Stuczyński f6f2cd7e17 unified native, socks5, NR client inits 2023-10-30 16:14:18 +00:00
Raphaël Walther 2084095773 Update security disclosure process 2023-10-30 16:42:40 +01:00
Jon Häggblad aa02f33add No need to show setup-ip-forwarder just yet 2023-10-30 15:01:47 +01:00
Jędrzej Stuczyński da9d743f39 [mixnode] replace rocket with axum (#4071)
* axum-equivalent mixnode http api routes

* replaced all rocket routes with axum equivalents

* removed '_axum' suffix from the routes
2023-10-30 12:55:42 +00:00
Jon Häggblad 49cf33f6d7 Proper config backwards compatibility 2023-10-30 11:11:38 +01:00
Jon Häggblad 65d93b2b18 Remove hack 2023-10-30 11:11:38 +01:00
Jon Häggblad a17d36fd89 Fix test compilation 2023-10-30 11:11:38 +01:00
Jon Häggblad d33967f60c rustfmt 2023-10-30 11:11:38 +01:00
Jon Häggblad cfef1f8325 config handling 2023-10-30 11:11:38 +01:00
Jon Häggblad 8270204c7e Run embedded ip-forwarder in gateway 2023-10-30 11:11:38 +01:00
serinko 9d1adf9884 fix based on feedback 2023-10-26 16:56:43 +02:00
serinko 49dcc7e894 syntax fix 2023-10-26 14:37:30 +02:00
serinko 3fdd89035b add page license 2023-10-26 13:07:07 +02:00
serinko 1aad2a3a7a syntax fix 2023-10-26 13:04:56 +02:00
serinko fa3277e18b syntax fix 2023-10-26 12:59:40 +02:00
serinko 3d5a3ad958 add regions to SUMMARY.md 2023-10-26 12:58:29 +02:00
serinko 722486ca68 add regions to SUMMARY.md 2023-10-26 12:57:31 +02:00
serinko 96d1861955 add legal findings switzerland 2023-10-26 12:51:30 +02:00
serinko f9e5a1159d create legal region pages - us, swiss 2023-10-26 12:37:15 +02:00
serinko 4e994f2b92 update exit policy info 2023-10-26 12:32:53 +02:00
serinko a65da367a3 correction based on feedback 2023-10-26 11:55:59 +02:00
serinko e61281e25e correction based on feedback 2023-10-26 11:54:51 +02:00
serinko 0ff512f373 update smoosh faq - two options 2023-10-26 11:22:23 +02:00
serinko d47f7afbf6 update smoosh faq - two options 2023-10-26 11:17:13 +02:00
serinko 0d21f2f39d initialise operators update branch 2023-10-26 10:39:11 +02:00
mfahampshire 15af551139 smol reword 2023-10-24 15:03:58 +02:00
mfahampshire 0347a2bd89 added deprecation warning 2023-10-24 14:51:15 +02:00
mfahampshire b26f70eb6a stripped down + added new links 2023-10-24 14:51:05 +02:00
mfahampshire bd10b17272 update plugin 2023-10-24 14:50:53 +02:00
mfahampshire 7b3a8d5bcd added new examples pages 2023-10-24 14:50:40 +02:00
mfahampshire 0e1548db72 added new pages to summary 2023-10-24 14:50:24 +02:00
mfahampshire 2806931ca1 added new pages 2023-10-24 14:50:03 +02:00
mfahampshire 50e03d08bf added info on post_process.sh 2023-10-24 13:18:32 +02:00
309 changed files with 15531 additions and 2859 deletions
+2 -27
View File
@@ -1,9 +1,8 @@
name: CD docs
name: cd-docs
on:
workflow_dispatch:
push:
branches: master
paths:
- 'documentation/docs/**'
@@ -26,7 +25,7 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace --release --all
args: --workspace --release
- name: Install mdbook
run: (test -x $HOME/.cargo/bin/mdbook || cargo install --vers "^0.4.33" mdbook)
- name: Install mdbook plugins
@@ -39,30 +38,6 @@ jobs:
run: cd documentation && ./build_all_to_dist.sh
continue-on-error: false
- name: Deploy branch master to dev
continue-on-error: true
uses: easingthemes/ssh-deploy@main
env:
SSH_PRIVATE_KEY: ${{ secrets.CD_WWW_SSH_PRIVATE_KEY }}
ARGS: "-rltgoDzvO --delete"
SOURCE: "dist/docs/"
REMOTE_HOST: ${{ secrets.CD_WWW_REMOTE_HOST_DEV }}
REMOTE_USER: ${{ secrets.CD_WWW_REMOTE_USER }}
TARGET: ${{ secrets.CD_WWW_REMOTE_TARGET }}/
EXCLUDE: "/node_modules/"
- name: Deploy branch master to prod
if: github.ref == 'refs/heads/master'
uses: easingthemes/ssh-deploy@main
env:
SSH_PRIVATE_KEY: ${{ secrets.CD_WWW_SSH_PRIVATE_KEY }}
ARGS: "-rltgoDzvO --delete"
SOURCE: "dist/docs/"
REMOTE_HOST: ${{ secrets.CD_WWW_REMOTE_HOST_PROD }}
REMOTE_USER: ${{ secrets.CD_WWW_REMOTE_USER }}
TARGET: ${{ secrets.CD_WWW_REMOTE_TARGET }}/
EXCLUDE: "/node_modules/"
- name: Post process
run: cd documentation && ./post_process.sh
continue-on-error: false
@@ -1,4 +1,4 @@
name: Run config checks on all binaries
name: ci-binary-config-checker
on:
workflow_dispatch:
@@ -35,14 +35,14 @@ jobs:
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
toolchain: 1.69.0
toolchain: stable
target: wasm32-unknown-unknown
override: true
- name: Install wasm-opt
uses: ./.github/actions/install-wasm-opt
with:
version: '112'
version: '114'
- name: Build release contracts
run: make contracts
+1 -1
View File
@@ -26,7 +26,7 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace --release --all
args: --workspace --release
- name: Install mdbook
run: (test -x $HOME/.cargo/bin/mdbook || cargo install --vers "^0.4.35" mdbook)
- name: Install mdbook plugins
+3 -3
View File
@@ -1,4 +1,4 @@
name: CI for Nym API Tests
name: ci-nym-api-tests
on:
workflow_dispatch:
@@ -16,10 +16,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install npm
run: npm install
- name: Node v18
uses: actions/setup-node@v3
with:
@@ -33,6 +33,12 @@ jobs:
override: true
components: rustfmt, clippy
- name: Check formatting
uses: actions-rs/cargo@v1
with:
command: fmt
args: --manifest-path nym-connect/desktop/Cargo.toml --all -- --check
- name: Build all binaries
uses: actions-rs/cargo@v1
with:
@@ -45,12 +51,6 @@ jobs:
command: test
args: --manifest-path nym-connect/desktop/Cargo.toml --workspace
- name: Check formatting
uses: actions-rs/cargo@v1
with:
command: fmt
args: --manifest-path nym-connect/desktop/Cargo.toml --all -- --check
- uses: actions-rs/clippy-check@v1
name: Clippy checks
continue-on-error: true
+2 -6
View File
@@ -1,11 +1,7 @@
name: ci-nym-vpn-ui-js
on:
push:
paths:
- 'nym-vpn/ui/src/**'
- 'nym-vpn/ui/package.json'
- 'nym-vpn/ui/index.html'
workflow_dispatch:
pull_request:
paths:
- 'nym-vpn/ui/src/**'
@@ -14,7 +10,7 @@ on:
jobs:
check:
runs-on: [ self-hosted, custom-linux ]
runs-on: custom-linux
steps:
- name: Checkout
uses: actions/checkout@v4
+14 -15
View File
@@ -1,16 +1,14 @@
name: ci-nym-vpn-ui-rust
on:
push:
paths:
- 'nym-vpn/ui/src-tauri/**'
workflow_dispatch:
pull_request:
paths:
- 'nym-vpn/ui/src-tauri/**'
jobs:
build:
runs-on: [self-hosted, custom-linux]
runs-on: custom-linux
env:
CARGO_TERM_COLOR: always
CARGOTOML_PATH: ./nym-vpn/ui/src-tauri/Cargo.toml
@@ -31,18 +29,19 @@ jobs:
components: rustfmt, clippy
- name: Prepare build
working-directory: nym-vpn/ui/
run: mkdir dist
run: mkdir nym-vpn/ui/dist
- name: Check build
working-directory: nym-vpn/ui/src-tauri
run: cargo build --release --lib --features custom-protocol
- name: Build
uses: actions-rs/cargo@v1
with:
command: build
args: --manifest-path ${{ env.CARGOTOML_PATH }} --lib --features custom-protocol
# - name: Run all tests
# uses: actions-rs/cargo@v1
# with:
# command: test
# args: --manifest-path ${{ env.CARGOTOML_PATH }} --workspace
# args: --manifest-path ${{ env.CARGOTOML_PATH }}
- name: Check formatting
uses: actions-rs/cargo@v1
@@ -50,15 +49,15 @@ jobs:
command: fmt
args: --manifest-path ${{ env.CARGOTOML_PATH }} --all -- --check
- uses: actions-rs/clippy-check@v1
name: Clippy checks
- name: Annotate with clippy checks
uses: actions-rs/clippy-check@v1
continue-on-error: true
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --manifest-path ${{ env.CARGOTOML_PATH }} --workspace --all-features
args: --manifest-path ${{ env.CARGOTOML_PATH }} --all-features
- name: Run clippy
- name: Clippy
uses: actions-rs/cargo@v1
with:
command: clippy
args: --manifest-path ${{ env.CARGOTOML_PATH }} --workspace --all-features -- -D warnings
args: --manifest-path ${{ env.CARGOTOML_PATH }} --all-features --all-targets -- -D warnings
+33 -8
View File
@@ -4,26 +4,26 @@ on:
workflow_dispatch:
schedule:
- cron: '14 1 * * *'
jobs:
build:
strategy:
fail-fast: false
matrix:
rust: [stable, beta]
os: [custom-linux, windows10, custom-runner-mac-m1]
os: [ubuntu-20.04, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
env:
CARGO_TERM_COLOR: always
continue-on-error: true
steps:
- name: Install Dependencies (Linux)
run: sudo apt-get update && sudo apt-get install -y build-essential curl wget libssl-dev libudev-dev squashfs-tools protobuf-compiler
continue-on-error: true
if: matrix.os == 'custom-linux'
- name: Check out repository code
uses: actions/checkout@v3
- name: Install Dependencies (Linux)
run: sudo apt-get update && sudo apt-get install -y build-essential curl wget libssl-dev libudev-dev squashfs-tools protobuf-compiler
if: matrix.os == 'ubuntu-20.04'
- name: Install Rust toolchain
uses: actions-rs/toolchain@v1
with:
@@ -32,6 +32,12 @@ jobs:
override: true
components: rustfmt, clippy
- name: Install Protoc
uses: arduino/setup-protoc@v2
if: matrix.os == 'macos-latest' || matrix.os == 'windows-latest'
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Check formatting
uses: actions-rs/cargo@v1
with:
@@ -42,13 +48,27 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace
args: --release --workspace
- name: Build examples
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace --examples
args: --release --workspace --examples
# 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
@@ -62,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:
@@ -0,0 +1,92 @@
name: nightly-nym-connect-desktop-build
on:
workflow_dispatch:
schedule:
- cron: '14 1 * * *'
jobs:
build:
strategy:
fail-fast: false
matrix:
os: [ubuntu-20.04, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
env:
CARGO_TERM_COLOR: always
MANIFEST_PATH: --manifest-path nym-connect/desktop/Cargo.toml
continue-on-error: true
steps:
- name: Check out repository code
uses: actions/checkout@v3
- name: Install Dependencies (Linux)
run: sudo apt-get update && sudo apt-get install -y libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev squashfs-tools
if: matrix.os == 'ubuntu-20.04'
- name: Install rust toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
components: rustfmt, clippy
- name: Check formatting
uses: actions-rs/cargo@v1
with:
command: fmt
args: ${{ env.MANIFEST_PATH }} --all -- --check
- name: Build
uses: actions-rs/cargo@v1
with:
command: build
args: ${{ env.MANIFEST_PATH }} --release --workspace
- name: Unit tests
uses: actions-rs/cargo@v1
with:
command: test
args: ${{ env.MANIFEST_PATH }} --workspace
- name: Clippy
uses: actions-rs/cargo@v1
with:
command: clippy
args: ${{ env.MANIFEST_PATH }} --workspace --all-targets -- -D warnings
notification:
needs: build
runs-on: custom-linux
steps:
- name: Collect jobs status
uses: technote-space/workflow-conclusion-action@v2
- name: Check out repository code
uses: actions/checkout@v3
- name: install npm
uses: actions/setup-node@v3
if: env.WORKFLOW_CONCLUSION == 'failure'
with:
node-version: 18
- name: Matrix - Node Install
if: env.WORKFLOW_CONCLUSION == 'failure'
run: npm install
working-directory: .github/workflows/support-files
- name: Matrix - Send Notification
if: env.WORKFLOW_CONCLUSION == 'failure'
env:
NYM_NOTIFICATION_KIND: nightly
NYM_PROJECT_NAME: "nym-connect-desktop-nightly-build"
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
GIT_BRANCH: "${GITHUB_REF##*/}"
IS_SUCCESS: "${{ env.WORKFLOW_CONCLUSION == 'success' }}"
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM_NIGHTLY }}"
MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}"
MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}"
MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}"
uses: docker://keybaseio/client:stable-node
with:
args: .github/workflows/support-files/notifications/entry_point.sh
+8 -22
View File
@@ -5,27 +5,24 @@ on:
schedule:
- cron: '14 1 * * *'
defaults:
run:
working-directory: nym-wallet
jobs:
build:
strategy:
fail-fast: false
matrix:
os: [custom-ubuntu-20.04, macos-latest, windows10]
os: [ubuntu-20.04, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
env:
CARGO_TERM_COLOR: always
MANIFEST_PATH: --manifest-path nym-wallet/Cargo.toml
continue-on-error: true
steps:
- name: Check out repository code
uses: actions/checkout@v3
- name: Install Dependencies (Linux)
run: sudo apt-get update && sudo apt-get install -y libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev libudev-dev squashfs-tools protobuf-compiler
if: matrix.os == 'custom-ubuntu-20.04'
run: sudo apt-get update && sudo apt-get install -y libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev squashfs-tools
if: matrix.os == 'ubuntu-20.04'
- name: Install rust toolchain
uses: actions-rs/toolchain@v1
@@ -35,40 +32,29 @@ jobs:
override: true
components: rustfmt, clippy
- name: Install Protoc
uses: arduino/setup-protoc@v2
if: matrix.os == 'macos-latest'
- name: Check formatting
uses: actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check
args: ${{ env.MANIFEST_PATH }} --all -- --check
- name: Build
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace
args: ${{ env.MANIFEST_PATH }} --release --workspace
- name: Unit tests
uses: actions-rs/cargo@v1
with:
command: test
args: --workspace
- name: Annotate with clippy warnings
uses: actions-rs/clippy-check@v1
continue-on-error: true
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --workspace
args: ${{ env.MANIFEST_PATH }} --workspace
- name: Clippy
uses: actions-rs/cargo@v1
with:
command: clippy
args: --workspace --all-targets -- -D warnings
args: ${{ env.MANIFEST_PATH }} --workspace --all-targets -- -D warnings
notification:
needs: build
+2 -2
View File
@@ -14,13 +14,13 @@ jobs:
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
toolchain: 1.69.0
toolchain: stable
target: wasm32-unknown-unknown
override: true
components: rustfmt, clippy
- name: Install wasm-opt
run: cargo install --version 0.112.0 wasm-opt
run: cargo install --version 0.114.0 wasm-opt
- name: Build release contracts
run: make contracts
@@ -39,6 +39,7 @@ jobs:
env:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
run: |
# create variables
@@ -73,6 +74,7 @@ jobs:
ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_IDENTITY_ID }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
+11 -1
View File
@@ -12,7 +12,7 @@ jobs:
uses: actions/setup-node@v3
with:
node-version: 18
registry-url: 'https://registry.npmjs.org'
registry-url: "https://registry.npmjs.org"
- name: Setup yarn
run: npm install -g yarn
@@ -28,6 +28,16 @@ jobs:
- name: Install wasm-opt
run: cargo install wasm-opt
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: "1.20"
- name: Install TinyGo
uses: acifani/setup-tinygo@v1
with:
tinygo-version: "0.27.0"
- name: Install dependencies
run: yarn
+14
View File
@@ -4,6 +4,18 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
## [Unreleased]
## [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])
[#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
## [2023.3-kinder] (2023-10-31)
- suppress error output ([#4056])
@@ -15,6 +27,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 +38,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
+59 -42
View File
@@ -1158,7 +1158,7 @@ checksum = "f769ab9e8c1652d78dd0b3ec59cdaa1e2bcb3b6b39f6681b256abcdbe101cc14"
dependencies = [
"anyhow",
"cargo_metadata",
"clap 4.4.6",
"clap 4.4.7",
"concolor-control",
"crates-index",
"dirs-next",
@@ -1393,9 +1393,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.4.6"
version = "4.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956"
checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b"
dependencies = [
"clap_builder",
"clap_derive",
@@ -1403,13 +1403,13 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.4.6"
version = "4.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45"
checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663"
dependencies = [
"anstream",
"anstyle",
"clap_lex 0.5.1",
"clap_lex 0.6.0",
"strsim",
"terminal_size",
]
@@ -1420,7 +1420,7 @@ version = "4.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3ae8ba90b9d8b007efe66e55e48fb936272f5ca00349b5b0e89877520d35ea7"
dependencies = [
"clap 4.4.6",
"clap 4.4.7",
]
[[package]]
@@ -1429,15 +1429,15 @@ version = "4.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29bdbe21a263b628f83fcbeac86a4416a1d588c7669dd41473bc4149e4e7d2f1"
dependencies = [
"clap 4.4.6",
"clap 4.4.7",
"clap_complete",
]
[[package]]
name = "clap_derive"
version = "4.4.2"
version = "4.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873"
checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442"
dependencies = [
"heck 0.4.1",
"proc-macro2",
@@ -1456,9 +1456,9 @@ dependencies = [
[[package]]
name = "clap_lex"
version = "0.5.1"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961"
checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1"
[[package]]
name = "cloudabi"
@@ -2871,7 +2871,7 @@ dependencies = [
"bytes",
"cfg-if",
"chrono",
"clap 4.4.6",
"clap 4.4.7",
"config",
"digest 0.10.7",
"dirs 5.0.1",
@@ -2941,7 +2941,7 @@ name = "explorer-api"
version = "1.1.31"
dependencies = [
"chrono",
"clap 4.4.6",
"clap 4.4.7",
"dotenvy",
"humantime-serde",
"isocountry",
@@ -2994,7 +2994,7 @@ dependencies = [
[[package]]
name = "extension-storage"
version = "1.2.0"
version = "1.2.4-rc.2"
dependencies = [
"bip39",
"console_error_panic_hook",
@@ -4282,6 +4282,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"
@@ -5559,12 +5568,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",
@@ -5961,7 +5971,7 @@ dependencies = [
"bs58 0.4.0",
"cfg-if",
"chrono",
"clap 4.4.6",
"clap 4.4.7",
"console-subscriber",
"cosmwasm-std",
"cw-utils",
@@ -6066,7 +6076,7 @@ name = "nym-bin-common"
version = "0.6.0"
dependencies = [
"atty",
"clap 4.4.6",
"clap 4.4.7",
"clap_complete",
"clap_complete_fig",
"log",
@@ -6107,7 +6117,7 @@ dependencies = [
"base64 0.13.1",
"bip39",
"bs58 0.4.0",
"clap 4.4.6",
"clap 4.4.7",
"clap_complete",
"clap_complete_fig",
"dotenvy",
@@ -6132,7 +6142,7 @@ dependencies = [
"bip39",
"bs58 0.4.0",
"cfg-if",
"clap 4.4.6",
"clap 4.4.7",
"comfy-table",
"cosmrs",
"cosmwasm-std",
@@ -6176,7 +6186,7 @@ dependencies = [
name = "nym-client"
version = "1.1.31"
dependencies = [
"clap 4.4.6",
"clap 4.4.7",
"dirs 4.0.0",
"futures",
"lazy_static",
@@ -6215,6 +6225,7 @@ dependencies = [
"async-trait",
"base64 0.21.4",
"cfg-if",
"clap 4.4.7",
"dashmap",
"dirs 4.0.0",
"futures",
@@ -6259,11 +6270,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",
@@ -6523,7 +6535,7 @@ dependencies = [
"atty",
"bip39",
"bs58 0.4.0",
"clap 4.4.6",
"clap 4.4.7",
"colored",
"dashmap",
"dirs 4.0.0",
@@ -6531,6 +6543,7 @@ dependencies = [
"futures",
"humantime-serde",
"hyper",
"ipnetwork 0.16.0",
"lazy_static",
"log",
"nym-api-requests",
@@ -6540,6 +6553,7 @@ dependencies = [
"nym-credentials",
"nym-crypto",
"nym-gateway-requests",
"nym-ip-packet-router",
"nym-mixnet-client",
"nym-mixnode-common",
"nym-network-defaults",
@@ -6644,19 +6658,27 @@ dependencies = [
]
[[package]]
name = "nym-ip-forwarder"
name = "nym-ip-packet-router"
version = "0.1.0"
dependencies = [
"etherparse",
"futures",
"log",
"nym-bin-common",
"nym-client-core",
"nym-config",
"nym-sdk",
"nym-service-providers-common",
"nym-sphinx",
"nym-task",
"nym-wireguard",
"nym-wireguard-types",
"serde",
"serde_json",
"tap",
"thiserror",
"tokio",
"url",
]
[[package]]
@@ -6694,12 +6716,13 @@ dependencies = [
[[package]]
name = "nym-mixnode"
version = "1.1.32"
version = "1.1.33"
dependencies = [
"anyhow",
"axum",
"bs58 0.4.0",
"cfg-if",
"clap 4.4.6",
"clap 4.4.7",
"colored",
"cpu-cycles",
"cupid",
@@ -6714,6 +6737,7 @@ dependencies = [
"nym-crypto",
"nym-mixnet-client",
"nym-mixnode-common",
"nym-node",
"nym-nonexhaustive-delayqueue",
"nym-pemstore",
"nym-sphinx",
@@ -6726,10 +6750,10 @@ dependencies = [
"opentelemetry",
"pretty_env_logger",
"rand 0.7.3",
"rocket",
"serde",
"serde_json",
"sysinfo",
"thiserror",
"tokio",
"tokio-util",
"toml 0.5.11",
@@ -6818,7 +6842,7 @@ dependencies = [
"async-file-watcher",
"async-trait",
"bs58 0.4.0",
"clap 4.4.6",
"clap 4.4.7",
"dirs 4.0.0",
"futures",
"humantime-serde",
@@ -6887,6 +6911,7 @@ dependencies = [
"fastrand 2.0.1",
"hmac 0.12.1",
"hyper",
"ipnetwork 0.16.0",
"mime",
"nym-config",
"nym-crypto",
@@ -6947,7 +6972,7 @@ dependencies = [
[[package]]
name = "nym-node-tester-wasm"
version = "1.2.0"
version = "1.2.4-rc.2"
dependencies = [
"futures",
"js-sys",
@@ -6980,7 +7005,7 @@ name = "nym-nr-query"
version = "0.1.0"
dependencies = [
"anyhow",
"clap 4.4.6",
"clap 4.4.7",
"log",
"nym-bin-common",
"nym-network-defaults",
@@ -7105,7 +7130,7 @@ dependencies = [
name = "nym-socks5-client"
version = "1.1.31"
dependencies = [
"clap 4.4.6",
"clap 4.4.7",
"lazy_static",
"log",
"nym-bin-common",
@@ -7547,15 +7572,6 @@ 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"
@@ -7577,6 +7593,7 @@ dependencies = [
"tap",
"thiserror",
"tokio",
"tokio-stream",
"tokio-tun",
]
@@ -9532,7 +9549,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"cargo-edit",
"clap 4.4.6",
"clap 4.4.7",
"semver 1.0.20",
"serde",
"serde_json",
@@ -10294,7 +10311,7 @@ name = "ssl-inject"
version = "0.1.0"
dependencies = [
"anyhow",
"clap 4.4.6",
"clap 4.4.7",
"hex",
"tokio",
]
+3 -2
View File
@@ -90,7 +90,7 @@ members = [
"sdk/lib/socks5-listener",
"sdk/rust/nym-sdk",
"service-providers/common",
"service-providers/ip-forwarder",
"service-providers/ip-packet-router",
"service-providers/network-requester",
"service-providers/network-statistics",
"nym-api",
@@ -105,7 +105,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",
]
@@ -138,6 +138,7 @@ axum = "0.6.20"
base64 = "0.21.4"
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"
+3 -7
View File
@@ -93,10 +93,6 @@ $(eval $(call add_cargo_workspace,contracts,contracts,--lib --target wasm32-unkn
$(eval $(call add_cargo_workspace,wallet,nym-wallet))
$(eval $(call add_cargo_workspace,connect,nym-connect/desktop))
# OVERRIDE: wasm-opt fails if the binary has been built with the latest rustc.
# Pin to the last working version.
contracts_BUILD_RELEASE_TOOLCHAIN := +1.69.0
# -----------------------------------------------------------------------------
# SDK
# -----------------------------------------------------------------------------
@@ -108,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:
@@ -118,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
@@ -144,7 +140,7 @@ contracts: build-release-contracts wasm-opt-contracts
wasm-opt-contracts:
for contract in $(CONTRACTS_WASM); do \
wasm-opt --disable-sign-ext -Os $(CONTRACTS_OUT_DIR)/$$contract -o $(CONTRACTS_OUT_DIR)/$$contract; \
wasm-opt --signext-lowering -Os $(CONTRACTS_OUT_DIR)/$$contract -o $(CONTRACTS_OUT_DIR)/$$contract; \
done
# Consider adding 's' to make plural consistent (beware: used in github workflow)
+85 -3
View File
@@ -1,8 +1,90 @@
Critical bug or security issue 💥
If you're here because you're trying to figure out how to notify us of a security issue, go to Discord or Matrix, and alert the core engineers:
If you're here because you're trying to figure out how to notify us of a security issue, send us a PGP encrypted email to:
Jedrzej Stuczynski, discord: "Jedrzej | Nym#5666" , matrix: @jstuczyn:nymtech.chat
Mark Sinclair | discord: marknym#8088 , matrix: @mark:nymtech.chat
```
security@nymte.ch
```
Encrypted with our public key which is available below in plain text and also on keyservers:
```
pub rsa4096 2023-10-30 [SC] [expire : 2026-10-29]
24B2592E801A5AAA8666C8BA7C3C727F05090550
uid [ ultime ] Security Nym Technologies <security@nymte.ch>
sub rsa4096 2023-10-30 [E] [expire : 2026-10-29]
```
The fingerprint of the key is on the second line above.
If you need to chat __urgently__ to our team for a __critical__ security issue:
go to Matrix, and alert the core engineers with a private direct message:
Jedrzej Stuczynski @jstuczyn:nymtech.chat
Mark Sinclair @mark:nymtech.chat
Raphaël Walther @raphael:nymtech.chat
Please avoid opening public issues on GitHub that contain information about a potential security vulnerability as this makes it difficult to reduce the impact and harm of valid security issues.
If you don't know what Matrix is, you can follow this documentation to create an account on this federation of instant messaging servers:
[Matrix for Instant Messaging](https://matrix.org/docs/chat_basics/matrix-for-im/)
```
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBGU/XpcBEAC+ykz0yxn8FferjEBooptXlOH/v/28aa0Nv8DfImTgj9BNY5cR
UdLk+Wa3CSXQVE7PIsi0egEjAMfyxPEywbvPlgklW4XAKDVUCf3gxpQNN47VuVgV
VwrN0VBurhhIKoEw9daO6A0P44+6nmXGIfUulCr4fMxYq82SOooog/j5w0/LfITu
rQXxVABLkXHGN/NGf4BE52QI/ppeXWoshlNVU1wdZIIYWwte+9ukikWpN+LYfJUR
ybtyCjQ4Gdf8ap1GmkKHmAru24wbUuFsBWGVgHsXAwYlKxyiNGR9YwgAxmFk6vNf
1PqKGO3i4erx5X/+mzylzNbFlCqFuksZRyUSDZvQ8fxkm8ra1zWbO38eOTp8Vhgg
SKfRTzOKeZYURZicJPxmEIfA88U4tx+YWJ54YWT/gERZkjIJL5mzIuY9UulVvKUM
vMFUIzBMHOPXH16036zGyFMC1esRd2qqil4b9KtLgCOkrD1VgpjcveoA0VyMJCN6
LmKTrVjwjjDMxby+d49BolRWGnCofXozXwvNQx+CYv8M2WPErTpyYoofYFtpqr7A
fIufc/e0+um3zoGIbHejrhsbuH9Qf+MKsI+Ng93bdDtjeHz6MEgAlsTm0qeizYpj
IyKZIObPmfvrAm08hFZ8JnGk+XuooF36XWbJYjCCy0bOyMw1r7ZG99TcSwARAQAB
tC1TZWN1cml0eSBOeW0gVGVjaG5vbG9naWVzIDxzZWN1cml0eUBueW10ZS5jaD6J
AlQEEwEKAD4WIQQkslkugBpaqoZmyLp8PHJ/BQkFUAUCZT9elwIbAwUJBaOagAUL
CQgHAwUVCgkICwUWAgMBAAIeAQIXgAAKCRB8PHJ/BQkFUL7dD/9zO73uI5VR+SWx
PFmJW+9QsPiQbVRvGwNZurctmQ2s2Pe0vHRELFeqD5oYvSx2Lequ3Ir+zn/C3kDM
kNs40obSL6jCBiLPkxEY0JqzPM9jZr7EjvlibWV3f6DxooRIqEyfN57I3OBGlqZE
0Mx7sQuCcgau8C70DF952QhKUwXC2cmpmDKHVEEoio1xGSD4dQhGapCB32RQGtna
OGfAO9celNMvSq0Lp+aJxeACmWFY5T4/y79JPcT5vSs/yEIRmaH/fn2piwaFBsIq
gHJJMxO3740P1hF8j7KWUoUofuFaEALHBpEpjWTOj8ej1wmFlu+5F+jSVoc781Wb
ZZXu04cOBXnGTogzSxMpBe9TtLb28zd6WzFotC25KTI3pngMzXsQGLJLOwvoZKiS
LFjPRjg1rwobmB3Q3J2W5GYSveia0CDsZGP+g87GVVf/oD2Djpa68xyVYwIYeA6T
3DNdS77qHiRuGiS4kWXyVjDqOICboR4uCvt09zlkBuLDdTWqWYARUvZjtjs4w/Ol
rdrBI3A88ti8fRldYaNpu17ME1ilpN44yKoJtqiWc3Tisk8eYLfx6c7FQF3PrRva
mr7FZvhFsYML5CeNFHTEzN6Y3jjKN/60DvCfodWnWFK47Txkl8UAXGY2W9B0fWqQ
wUVr8uLuMyyMiKbeoufi7rGOj6AMErkCDQRlP16XARAA8FGmD5J3tM1BOM1niJxZ
JTdCauzEtxEoBL0RuqGBkR8U29sRM6DwuzjU7PwscFnBaGyU+eU73GwGkH3ozFfF
tllYhQrhP/kkN+0rEO5Xi+nR+4JCFRqrf3nJXAAPfiksURMp8er1dUOY2/e1ZSoL
tS+nzUivV8CfE+pgj/5YtGwPC+KYHLATkKkMELCrbW4UO06VWOqQsvr6kivXuJQQ
LdEAMpBlADmXFG45DmPKQzsBWUgvTwyGy3LX0nys8cgpex9BH8hhr01QmGyP469s
N3cNrtFuu8U6RAsiCD/8mlBuD3EQEU5SF0lc7kCICAZk+wElmXnimEi0TOYsbz6k
90lteicX70rA9GNeyI76H+VSOYvWpkRwaJAgUdzrAM1o9SHASq+cZ6nD85OZioQk
DWM6+Q+sf2oen0qJnnGmUr93kJIC0PIdgrXRrtiNfeRa1Z/H0LmREyyEMoFiVivn
z1vVk85Oq6Sf3ltUwvmDzuuJOtsp2Qp6+x6Snn/yKauI4uf4Cf/wKUch4r6Bwgg5
Dw49ky7lwlnALio4GIVoGLpLef93wWoDmp4Klyh3ZPf2nB0U91u3bHRUo7m+D7QJ
98cyKtqLLzjg7szGf60pIWNWRsadYQT3bSncynqknAjOV3BCvx6/ivsnpj//QjYR
HtviUAcQ1DBB6UC6q23FIs0AEQEAAYkCPAQYAQoAJhYhBCSyWS6AGlqqhmbIunw8
cn8FCQVQBQJlP16XAhsMBQkFo5qAAAoJEHw8cn8FCQVQzukP/iLxjOxT+UpPR//c
prDVSLkP4pF5bmw36U07jvqpS+/KTXsxiiQleffRabOpNLcd+K1ueavyt9nnIwHH
tHS9kM9A7DBw3LnpEbXki46QDCCI6niGijlLOEeAWqnocwMNTT05wVVgCtO3DQP2
MoSCcqHpXDChvOyr5d5xjYLVJhlctIMSomcVzGryjknPu0Yj/TkC/4c+m86ZWQUD
HqMHQIuiEenvb62/F4c5OJIRZPEn70wdddkgJuJU3eHdHrnuhCkjCC93GQGbGj03
Zqos6699y6hmPeD3U5IUv8ujwZYVCCuDm8gJfrp3R6WLfeZeK9WmTVBpCzsDg3fV
hSwmOk6pp8DAq1/Dev3yRkFggCEyGK6c9b+a0CRBncl8e5Q0QQIzNiS/uExQP3h+
ELJs3P0MLP+6FWhNUry09n3lnWkr1hY+v1M0GAxbfdv/tsCN1Pq/VQEz+CTqXqya
ftWldOHWw6Hh+gtwxcHjG4MBOrO5oICQ3lh2hGwQ58cDgZYSK/OGgJ9BggFl1CcM
0uGC0/TRCI1zt/4y+7efSZQMZkHo7VC/3MFbp2hcNejpW+BxVuwKTunFvWK3TLhq
sSlQ5yyhqchooepsFHq9bosKFjLJC01uprBv1rinoNduOy43FbyS7JPRRspANN0R
iC2pMbWdE0ZTQaFq6tPIg058pjqi
=nqgX
-----END PGP PUBLIC KEY BLOCK-----
```
+2 -2
View File
@@ -20,7 +20,7 @@ futures = { workspace = true } # bunch of futures stuff, however, now that I thi
# and the single instance of abortable we have should really be refactored anyway
url = { workspace = true }
clap = { version = "4.0", features = ["cargo", "derive"] }
clap = { workspace = true, features = ["cargo", "derive"] }
dirs = "4.0"
lazy_static = "1.4.0"
log = { workspace = true } # self explanatory
@@ -36,7 +36,7 @@ tokio-tungstenite = { workspace = true }
## internal
nym-bandwidth-controller = { path = "../../common/bandwidth-controller" }
nym-bin-common = { path = "../../common/bin-common", features = ["output_format"] }
nym-client-core = { path = "../../common/client-core", features = ["fs-surb-storage"] }
nym-client-core = { path = "../../common/client-core", features = ["fs-surb-storage", "cli"] }
nym-coconut-interface = { path = "../../common/coconut-interface" }
nym-config = { path = "../../common/config" }
nym-credential-storage = { path = "../../common/credential-storage" }
+20
View File
@@ -4,6 +4,8 @@
use crate::client::config::persistence::ClientPaths;
use crate::client::config::template::CONFIG_TEMPLATE;
use nym_bin_common::logging::LoggingSettings;
use nym_client_core::cli_helpers::client_init::ClientConfig;
use nym_client_core::config::disk_persistence::CommonClientPaths;
use nym_config::defaults::DEFAULT_WEBSOCKET_LISTENING_PORT;
use nym_config::{
must_get_home, read_config_from_toml_file, save_formatted_config_to_file, NymConfigTemplate,
@@ -72,6 +74,24 @@ impl NymConfigTemplate for Config {
}
}
impl ClientConfig for Config {
fn common_paths(&self) -> &CommonClientPaths {
&self.storage_paths.common_paths
}
fn core_config(&self) -> &BaseClientConfig {
&self.base
}
fn default_store_location(&self) -> PathBuf {
self.default_location()
}
fn save_to<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
save_formatted_config_to_file(self, path)
}
}
impl Config {
pub fn new<S: AsRef<str>>(id: S) -> Self {
Config {
+55 -160
View File
@@ -12,55 +12,49 @@ use crate::{
};
use clap::Args;
use nym_bin_common::output_format::OutputFormat;
use nym_client_core::client::base_client::storage::gateway_details::OnDiskGatewayDetails;
use nym_client_core::client::key_manager::persistence::OnDiskKeys;
use nym_client_core::config::GatewayEndpointConfig;
use nym_client_core::error::ClientCoreError;
use nym_client_core::init::helpers::current_gateways;
use nym_client_core::init::types::{GatewayDetails, GatewaySelectionSpecification, GatewaySetup};
use nym_crypto::asymmetric::identity;
use nym_sphinx::addressing::clients::Recipient;
use nym_topology::NymTopology;
use nym_client_core::cli_helpers::client_init::{
initialise_client, CommonClientInitArgs, InitResultsWithConfig, InitialisableClient,
};
use serde::Serialize;
use std::fmt::Display;
use std::fs;
use std::net::IpAddr;
use std::path::PathBuf;
use std::{fs, io};
use tap::TapFallible;
struct NativeClientInit;
impl InitialisableClient for NativeClientInit {
const NAME: &'static str = "native";
type Error = ClientError;
type InitArgs = Init;
type Config = Config;
fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error> {
try_upgrade_config(id)
}
fn initialise_storage_paths(id: &str) -> Result<(), Self::Error> {
fs::create_dir_all(default_data_directory(id))?;
fs::create_dir_all(default_config_directory(id))?;
Ok(())
}
fn default_config_path(id: &str) -> PathBuf {
default_config_filepath(id)
}
fn construct_config(init_args: &Self::InitArgs) -> Self::Config {
override_config(
Config::new(&init_args.common_args.id),
OverrideConfig::from(init_args.clone()),
)
}
}
#[derive(Args, Clone)]
pub(crate) struct Init {
/// Id of the nym-mixnet-client we want to create config for.
#[clap(long)]
id: String,
/// Id of the gateway we are going to connect to.
#[clap(long)]
gateway: Option<identity::PublicKey>,
/// Specifies whether the new gateway should be determined based by latency as opposed to being chosen
/// uniformly.
#[clap(long, conflicts_with = "gateway")]
latency_based_selection: bool,
/// Force register gateway. WARNING: this will overwrite any existing keys for the given id,
/// potentially causing loss of access.
#[clap(long)]
force_register_gateway: bool,
/// Comma separated list of rest endpoints of the nyxd validators
#[clap(long, alias = "nyxd_validators", value_delimiter = ',', hide = true)]
nyxd_urls: Option<Vec<url::Url>>,
/// Comma separated list of rest endpoints of the API validators
#[clap(
long,
alias = "api_validators",
value_delimiter = ',',
group = "network"
)]
// the alias here is included for backwards compatibility (1.1.4 and before)
nym_apis: Option<Vec<url::Url>>,
#[command(flatten)]
common_args: CommonClientInitArgs,
/// Whether to not start the websocket
#[clap(long)]
@@ -74,40 +68,28 @@ pub(crate) struct Init {
#[clap(long)]
host: Option<IpAddr>,
/// Path to .json file containing custom network specification.
#[clap(long, group = "network", hide = true)]
custom_mixnet: Option<PathBuf>,
/// Mostly debug-related option to increase default traffic rate so that you would not need to
/// modify config post init
#[clap(long, hide = true)]
fastmode: bool,
/// Disable loop cover traffic and the Poisson rate limiter (for debugging only)
#[clap(long, hide = true)]
no_cover: bool,
/// Set this client to work in a enabled credentials mode that would attempt to use gateway
/// with bandwidth credential requirement.
#[clap(long, hide = true)]
enabled_credentials_mode: Option<bool>,
#[clap(short, long, default_value_t = OutputFormat::default())]
output: OutputFormat,
}
impl AsRef<CommonClientInitArgs> for Init {
fn as_ref(&self) -> &CommonClientInitArgs {
&self.common_args
}
}
impl From<Init> for OverrideConfig {
fn from(init_config: Init) -> Self {
OverrideConfig {
nym_apis: init_config.nym_apis,
nym_apis: init_config.common_args.nym_apis,
disable_socket: init_config.disable_socket,
port: init_config.port,
host: init_config.host,
fastmode: init_config.fastmode,
no_cover: init_config.no_cover,
fastmode: init_config.common_args.fastmode,
no_cover: init_config.common_args.no_cover,
nyxd_urls: init_config.nyxd_urls,
enabled_credentials_mode: init_config.enabled_credentials_mode,
nyxd_urls: init_config.common_args.nyxd_urls,
enabled_credentials_mode: init_config.common_args.enabled_credentials_mode,
}
}
}
@@ -121,15 +103,11 @@ pub struct InitResults {
}
impl InitResults {
fn new(config: &Config, address: &Recipient, gateway: &GatewayEndpointConfig) -> Self {
fn new(res: InitResultsWithConfig<Config>) -> Self {
Self {
client_core: nym_client_core::init::types::InitResults::new(
&config.base,
address,
gateway,
),
client_listening_port: config.socket.listening_port,
client_address: address.to_string(),
client_address: res.init_results.address.to_string(),
client_core: res.init_results,
client_listening_port: res.config.socket.listening_port,
}
}
}
@@ -142,97 +120,14 @@ impl Display for InitResults {
}
}
fn init_paths(id: &str) -> io::Result<()> {
fs::create_dir_all(default_data_directory(id))?;
fs::create_dir_all(default_config_directory(id))
}
pub(crate) async fn execute(args: Init) -> Result<(), ClientError> {
eprintln!("Initialising client...");
let id = &args.id;
let output = args.output;
let res = initialise_client::<NativeClientInit>(args).await?;
let already_init = if default_config_filepath(id).exists() {
// in case we're using old config, try to upgrade it
// (if we're using the current version, it's a no-op)
try_upgrade_config(id)?;
eprintln!("Client \"{id}\" was already initialised before");
true
} else {
init_paths(id)?;
false
};
// Usually you only register with the gateway on the first init, however you can force
// re-registering if wanted.
let user_wants_force_register = args.force_register_gateway;
if user_wants_force_register {
eprintln!("Instructed to force registering gateway. This will overwrite keys!");
}
// If the client was already initialized, don't generate new keys and don't re-register with
// the gateway (because this would create a new shared key).
// Unless the user really wants to.
let register_gateway = !already_init || user_wants_force_register;
// Attempt to use a user-provided gateway, if possible
let user_chosen_gateway_id = args.gateway;
let selection_spec = GatewaySelectionSpecification::new(
user_chosen_gateway_id.map(|id| id.to_base58_string()),
Some(args.latency_based_selection),
false,
);
// Load and potentially override config
let config = override_config(Config::new(id), OverrideConfig::from(args.clone()));
// Setup gateway by either registering a new one, or creating a new config from the selected
// one but with keys kept, or reusing the gateway configuration.
let key_store = OnDiskKeys::new(config.storage_paths.common_paths.keys.clone());
let details_store =
OnDiskGatewayDetails::new(&config.storage_paths.common_paths.gateway_details);
let available_gateways = if let Some(hardcoded_topology) = args
.custom_mixnet
.map(NymTopology::new_from_file)
.transpose()?
{
// hardcoded_topology
hardcoded_topology.get_gateways()
} else {
let mut rng = rand::thread_rng();
current_gateways(&mut rng, &config.base.client.nym_api_urls).await?
};
let gateway_setup = GatewaySetup::New {
specification: selection_spec,
available_gateways,
overwrite_data: register_gateway,
};
let init_details =
nym_client_core::init::setup_gateway(gateway_setup, &key_store, &details_store)
.await
.tap_err(|err| eprintln!("Failed to setup gateway\nError: {err}"))?;
let config_save_location = config.default_location();
config.save_to_default_location().tap_err(|_| {
log::error!("Failed to save the config file");
})?;
eprintln!(
"Saved configuration file to {}",
config_save_location.display()
);
let address = init_details.client_address()?;
eprintln!("Client configuration completed.\n");
let GatewayDetails::Configured(gateway_details) = init_details.gateway_details else {
return Err(ClientCoreError::UnexpectedPersistedCustomGatewayDetails)?;
};
let init_results = InitResults::new(&config, &address, &gateway_details);
println!("{}", args.output.format(&init_results));
let init_results = InitResults::new(res);
println!("{}", output.format(&init_results));
Ok(())
}
+11 -50
View File
@@ -10,35 +10,14 @@ use crate::{
use clap::Args;
use log::*;
use nym_bin_common::version_checker::is_minor_version_compatible;
use nym_crypto::asymmetric::identity;
use nym_client_core::cli_helpers::client_run::CommonClientRunArgs;
use std::error::Error;
use std::net::IpAddr;
use std::path::PathBuf;
#[derive(Args, Clone)]
pub(crate) struct Run {
/// Id of the nym-mixnet-client we want to run.
#[clap(long)]
id: String,
/// Comma separated list of rest endpoints of the nyxd validators
#[clap(long, alias = "nyxd_validators", value_delimiter = ',', hide = true)]
nyxd_urls: Option<Vec<url::Url>>,
/// Comma separated list of rest endpoints of the API validators
#[clap(
long,
alias = "api_validators",
value_delimiter = ',',
group = "network"
)]
// the alias here is included for backwards compatibility (1.1.4 and before)
nym_apis: Option<Vec<url::Url>>,
/// Id of the gateway we want to connect to. If overridden, it is user's responsibility to
/// ensure prior registration happened
#[clap(long)]
gateway: Option<identity::PublicKey>,
#[command(flatten)]
common_args: CommonClientRunArgs,
/// Whether to not start the websocket
#[clap(long)]
@@ -51,37 +30,19 @@ pub(crate) struct Run {
/// Ip for the socket (if applicable) to listen for requests.
#[clap(long)]
host: Option<IpAddr>,
/// Path to .json file containing custom network specification.
#[clap(long, group = "network", hide = true)]
custom_mixnet: Option<PathBuf>,
/// Mostly debug-related option to increase default traffic rate so that you would not need to
/// modify config post init
#[clap(long, hide = true)]
fastmode: bool,
/// Disable loop cover traffic and the Poisson rate limiter (for debugging only)
#[clap(long, hide = true)]
no_cover: bool,
/// Set this client to work in a enabled credentials mode that would attempt to use gateway
/// with bandwidth credential requirement.
#[clap(long, hide = true)]
enabled_credentials_mode: Option<bool>,
}
impl From<Run> for OverrideConfig {
fn from(run_config: Run) -> Self {
OverrideConfig {
nym_apis: run_config.nym_apis,
nym_apis: run_config.common_args.nym_apis,
disable_socket: run_config.disable_socket,
port: run_config.port,
host: run_config.host,
fastmode: run_config.fastmode,
no_cover: run_config.no_cover,
nyxd_urls: run_config.nyxd_urls,
enabled_credentials_mode: run_config.enabled_credentials_mode,
fastmode: run_config.common_args.fastmode,
no_cover: run_config.common_args.no_cover,
nyxd_urls: run_config.common_args.nyxd_urls,
enabled_credentials_mode: run_config.common_args.enabled_credentials_mode,
}
}
}
@@ -106,9 +67,9 @@ fn version_check(cfg: &Config) -> bool {
}
pub(crate) async fn execute(args: Run) -> Result<(), Box<dyn Error + Send + Sync>> {
eprintln!("Starting client {}...", args.id);
eprintln!("Starting client {}...", args.common_args.id);
let mut config = try_load_current_config(&args.id)?;
let mut config = try_load_current_config(&args.common_args.id)?;
config = override_config(config, OverrideConfig::from(args.clone()));
if !version_check(&config) {
@@ -116,7 +77,7 @@ pub(crate) async fn execute(args: Run) -> Result<(), Box<dyn Error + Send + Sync
return Err(Box::new(ClientError::FailedLocalVersionCheck));
}
SocketClient::new(config, args.custom_mixnet)
SocketClient::new(config, args.common_args.custom_mixnet)
.run_socket_forever()
.await
}
+2 -2
View File
@@ -7,7 +7,7 @@ edition = "2021"
rust-version = "1.56"
[dependencies]
clap = { version = "4.0", features = ["cargo", "derive"] }
clap = { workspace = true, features = ["cargo", "derive"] }
lazy_static = "1.4.0"
log = { workspace = true }
pretty_env_logger = "0.4"
@@ -21,7 +21,7 @@ url = { workspace = true }
# internal
nym-bin-common = { path = "../../common/bin-common", features = ["output_format"] }
nym-client-core = { path = "../../common/client-core", features = ["fs-surb-storage"] }
nym-client-core = { path = "../../common/client-core", features = ["fs-surb-storage", "cli"] }
nym-coconut-interface = { path = "../../common/coconut-interface" }
nym-config = { path = "../../common/config" }
nym-credentials = { path = "../../common/credentials" }
+55 -163
View File
@@ -11,27 +11,50 @@ use crate::{
};
use clap::Args;
use nym_bin_common::output_format::OutputFormat;
use nym_client_core::client::base_client::storage::gateway_details::OnDiskGatewayDetails;
use nym_client_core::client::key_manager::persistence::OnDiskKeys;
use nym_client_core::config::GatewayEndpointConfig;
use nym_client_core::error::ClientCoreError;
use nym_client_core::init::helpers::current_gateways;
use nym_client_core::init::types::{GatewayDetails, GatewaySelectionSpecification, GatewaySetup};
use nym_crypto::asymmetric::identity;
use nym_client_core::cli_helpers::client_init::{
initialise_client, CommonClientInitArgs, InitResultsWithConfig, InitialisableClient,
};
use nym_sphinx::addressing::clients::Recipient;
use nym_topology::NymTopology;
use serde::Serialize;
use std::fmt::Display;
use std::fs;
use std::net::{IpAddr, SocketAddr};
use std::path::PathBuf;
use std::{fs, io};
use tap::TapFallible;
struct Socks5ClientInit;
impl InitialisableClient for Socks5ClientInit {
const NAME: &'static str = "socks5";
type Error = Socks5ClientError;
type InitArgs = Init;
type Config = Config;
fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error> {
try_upgrade_config(id)
}
fn initialise_storage_paths(id: &str) -> Result<(), Self::Error> {
fs::create_dir_all(default_data_directory(id))?;
fs::create_dir_all(default_config_directory(id))?;
Ok(())
}
fn default_config_path(id: &str) -> PathBuf {
default_config_filepath(id)
}
fn construct_config(init_args: &Self::InitArgs) -> Self::Config {
override_config(
Config::new(&init_args.common_args.id, &init_args.provider.to_string()),
OverrideConfig::from(init_args.clone()),
)
}
}
#[derive(Args, Clone)]
pub(crate) struct Init {
/// Id of the nym-mixnet-client we want to create config for.
#[clap(long)]
id: String,
#[command(flatten)]
common_args: CommonClientInitArgs,
/// Address of the socks5 provider to send messages to.
#[clap(long)]
@@ -46,34 +69,6 @@ pub(crate) struct Init {
#[clap(long, alias = "use_anonymous_sender_tag")]
use_reply_surbs: Option<bool>,
/// Id of the gateway we are going to connect to.
#[clap(long)]
gateway: Option<identity::PublicKey>,
/// Specifies whether the new gateway should be determined based by latency as opposed to being chosen
/// uniformly.
#[clap(long, conflicts_with = "gateway")]
latency_based_selection: bool,
/// Force register gateway. WARNING: this will overwrite any existing keys for the given id,
/// potentially causing loss of access.
#[clap(long)]
force_register_gateway: bool,
/// Comma separated list of rest endpoints of the nyxd validators
#[clap(long, alias = "nyxd_validators", value_delimiter = ',', hide = true)]
nyxd_urls: Option<Vec<url::Url>>,
/// Comma separated list of rest endpoints of the API validators
#[clap(
long,
alias = "api_validators",
value_delimiter = ',',
group = "network"
)]
// the alias here is included for backwards compatibility (1.1.4 and before)
nym_apis: Option<Vec<url::Url>>,
/// Port for the socket to listen on in all subsequent runs
#[clap(short, long)]
port: Option<u16>,
@@ -82,41 +77,29 @@ pub(crate) struct Init {
#[clap(long)]
host: Option<IpAddr>,
/// Path to .json file containing custom network specification.
#[clap(long, group = "network", hide = true)]
custom_mixnet: Option<PathBuf>,
/// Mostly debug-related option to increase default traffic rate so that you would not need to
/// modify config post init
#[clap(long, hide = true)]
fastmode: bool,
/// Disable loop cover traffic and the Poisson rate limiter (for debugging only)
#[clap(long, hide = true)]
no_cover: bool,
/// Set this client to work in a enabled credentials mode that would attempt to use gateway
/// with bandwidth credential requirement.
#[clap(long, hide = true)]
enabled_credentials_mode: Option<bool>,
#[clap(short, long, default_value_t = OutputFormat::default())]
output: OutputFormat,
}
impl AsRef<CommonClientInitArgs> for Init {
fn as_ref(&self) -> &CommonClientInitArgs {
&self.common_args
}
}
impl From<Init> for OverrideConfig {
fn from(init_config: Init) -> Self {
OverrideConfig {
nym_apis: init_config.nym_apis,
nym_apis: init_config.common_args.nym_apis,
ip: init_config.host,
port: init_config.port,
use_anonymous_replies: init_config.use_reply_surbs,
fastmode: init_config.fastmode,
no_cover: init_config.no_cover,
fastmode: init_config.common_args.fastmode,
no_cover: init_config.common_args.no_cover,
geo_routing: None,
medium_toggle: false,
nyxd_urls: init_config.nyxd_urls,
enabled_credentials_mode: init_config.enabled_credentials_mode,
nyxd_urls: init_config.common_args.nyxd_urls,
enabled_credentials_mode: init_config.common_args.enabled_credentials_mode,
outfox: false,
}
}
@@ -131,15 +114,11 @@ pub struct InitResults {
}
impl InitResults {
fn new(config: &Config, address: &Recipient, gateway: &GatewayEndpointConfig) -> Self {
fn new(res: InitResultsWithConfig<Config>) -> Self {
Self {
client_core: nym_client_core::init::types::InitResults::new(
&config.core.base,
address,
gateway,
),
socks5_listening_address: config.core.socks5.bind_adddress,
client_address: address.to_string(),
client_address: res.init_results.address.to_string(),
client_core: res.init_results,
socks5_listening_address: res.config.core.socks5.bind_adddress,
}
}
}
@@ -156,101 +135,14 @@ impl Display for InitResults {
}
}
fn init_paths(id: &str) -> io::Result<()> {
fs::create_dir_all(default_data_directory(id))?;
fs::create_dir_all(default_config_directory(id))
}
pub(crate) async fn execute(args: Init) -> Result<(), Socks5ClientError> {
eprintln!("Initialising client...");
let id = &args.id;
let provider_address = &args.provider;
let output = args.output;
let res = initialise_client::<Socks5ClientInit>(args).await?;
let already_init = if default_config_filepath(id).exists() {
// in case we're using old config, try to upgrade it
// (if we're using the current version, it's a no-op)
try_upgrade_config(id)?;
eprintln!("SOCKS5 client \"{id}\" was already initialised before");
true
} else {
init_paths(id)?;
false
};
// Usually you only register with the gateway on the first init, however you can force
// re-registering if wanted.
let user_wants_force_register = args.force_register_gateway;
if user_wants_force_register {
eprintln!("Instructed to force registering gateway. This might overwrite keys!");
}
// If the client was already initialized, don't generate new keys and don't re-register with
// the gateway (because this would create a new shared key).
// Unless the user really wants to.
let register_gateway = !already_init || user_wants_force_register;
// Attempt to use a user-provided gateway, if possible
let user_chosen_gateway_id = args.gateway;
let selection_spec = GatewaySelectionSpecification::new(
user_chosen_gateway_id.map(|id| id.to_base58_string()),
Some(args.latency_based_selection),
false,
);
// Load and potentially override config
let config = override_config(
Config::new(id, &provider_address.to_string()),
OverrideConfig::from(args.clone()),
);
// Setup gateway by either registering a new one, or creating a new config from the selected
// one but with keys kept, or reusing the gateway configuration.
let key_store = OnDiskKeys::new(config.storage_paths.common_paths.keys.clone());
let details_store =
OnDiskGatewayDetails::new(&config.storage_paths.common_paths.gateway_details);
let available_gateways = if let Some(hardcoded_topology) = args
.custom_mixnet
.map(NymTopology::new_from_file)
.transpose()?
{
// hardcoded_topology
hardcoded_topology.get_gateways()
} else {
let mut rng = rand::thread_rng();
current_gateways(&mut rng, &config.core.base.client.nym_api_urls).await?
};
let gateway_setup = GatewaySetup::New {
specification: selection_spec,
available_gateways,
overwrite_data: register_gateway,
};
let init_details =
nym_client_core::init::setup_gateway(gateway_setup, &key_store, &details_store)
.await
.tap_err(|err| eprintln!("Failed to setup gateway\nError: {err}"))?;
// TODO: ask the service provider we specified for its interface version and set it in the config
let config_save_location = config.default_location();
config.save_to_default_location().tap_err(|_| {
log::error!("Failed to save the config file");
})?;
eprintln!(
"Saved configuration file to {}",
config_save_location.display()
);
let address = init_details.client_address()?;
let GatewayDetails::Configured(gateway_details) = init_details.gateway_details else {
return Err(ClientCoreError::UnexpectedPersistedCustomGatewayDetails)?;
};
let init_results = InitResults::new(&config, &address, &gateway_details);
println!("{}", args.output.format(&init_results));
let init_results = InitResults::new(res);
println!("{}", output.format(&init_results));
Ok(())
}
+11 -44
View File
@@ -10,19 +10,17 @@ use crate::{
use clap::Args;
use log::*;
use nym_bin_common::version_checker::is_minor_version_compatible;
use nym_client_core::cli_helpers::client_run::CommonClientRunArgs;
use nym_client_core::client::base_client::storage::OnDiskPersistent;
use nym_client_core::client::topology_control::geo_aware_provider::CountryGroup;
use nym_crypto::asymmetric::identity;
use nym_socks5_client_core::NymClient;
use nym_sphinx::addressing::clients::Recipient;
use std::net::IpAddr;
use std::path::PathBuf;
#[derive(Args, Clone)]
pub(crate) struct Run {
/// Id of the nym-mixnet-client we want to run.
#[clap(long)]
id: String,
#[command(flatten)]
common_args: CommonClientRunArgs,
/// Specifies whether this client is going to use an anonymous sender tag for communication with the service provider.
/// While this is going to hide its actual address information, it will make the actual communication
@@ -37,19 +35,6 @@ pub(crate) struct Run {
#[clap(long)]
provider: Option<Recipient>,
/// Id of the gateway we want to connect to. If overridden, it is user's responsibility to
/// ensure prior registration happened
#[clap(long)]
gateway: Option<identity::PublicKey>,
/// Comma separated list of rest endpoints of the nyxd validators
#[clap(long, alias = "nyxd_validators", value_delimiter = ',', hide = true)]
nyxd_urls: Option<Vec<url::Url>>,
/// Comma separated list of rest endpoints of the Nym APIs
#[clap(long, value_delimiter = ',', group = "network")]
nym_apis: Option<Vec<url::Url>>,
/// Port for the socket to listen on
#[clap(short, long)]
port: Option<u16>,
@@ -58,19 +43,6 @@ pub(crate) struct Run {
#[clap(long)]
host: Option<IpAddr>,
/// Path to .json file containing custom network specification.
#[clap(long, group = "network", group = "routing", hide = true)]
custom_mixnet: Option<PathBuf>,
/// Mostly debug-related option to increase default traffic rate so that you would not need to
/// modify config post init
#[clap(long, hide = true)]
fastmode: bool,
/// Disable loop cover traffic and the Poisson rate limiter (for debugging only)
#[clap(long, hide = true)]
no_cover: bool,
/// Set geo-aware mixnode selection when sending mixnet traffic, for experiments only.
#[clap(long, hide = true, value_parser = validate_country_group, group="routing")]
geo_routing: Option<CountryGroup>,
@@ -80,11 +52,6 @@ pub(crate) struct Run {
#[clap(long, hide = true)]
medium_toggle: bool,
/// Set this client to work in a enabled credentials mode that would attempt to use gateway
/// with bandwidth credential requirement.
#[clap(long, hide = true)]
enabled_credentials_mode: Option<bool>,
#[clap(long, hide = true, action)]
outfox: bool,
}
@@ -92,16 +59,16 @@ pub(crate) struct Run {
impl From<Run> for OverrideConfig {
fn from(run_config: Run) -> Self {
OverrideConfig {
nym_apis: run_config.nym_apis,
nym_apis: run_config.common_args.nym_apis,
ip: run_config.host,
port: run_config.port,
use_anonymous_replies: run_config.use_anonymous_replies,
fastmode: run_config.fastmode,
no_cover: run_config.no_cover,
fastmode: run_config.common_args.fastmode,
no_cover: run_config.common_args.no_cover,
geo_routing: run_config.geo_routing,
medium_toggle: run_config.medium_toggle,
nyxd_urls: run_config.nyxd_urls,
enabled_credentials_mode: run_config.enabled_credentials_mode,
nyxd_urls: run_config.common_args.nyxd_urls,
enabled_credentials_mode: run_config.common_args.enabled_credentials_mode,
outfox: run_config.outfox,
}
}
@@ -136,9 +103,9 @@ fn version_check(cfg: &Config) -> bool {
}
pub(crate) async fn execute(args: Run) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
eprintln!("Starting client {}...", args.id);
eprintln!("Starting client {}...", args.common_args.id);
let mut config = try_load_current_config(&args.id)?;
let mut config = try_load_current_config(&args.common_args.id)?;
config = override_config(config, OverrideConfig::from(args.clone()));
if !version_check(&config) {
@@ -149,7 +116,7 @@ pub(crate) async fn execute(args: Run) -> Result<(), Box<dyn std::error::Error +
let storage =
OnDiskPersistent::from_paths(config.storage_paths.common_paths, &config.core.base.debug)
.await?;
NymClient::new(config.core, storage, args.custom_mixnet)
NymClient::new(config.core, storage, args.common_args.custom_mixnet)
.run_forever()
.await
}
+20
View File
@@ -3,6 +3,8 @@
use crate::config::template::CONFIG_TEMPLATE;
use nym_bin_common::logging::LoggingSettings;
use nym_client_core::cli_helpers::client_init::ClientConfig;
use nym_client_core::config::disk_persistence::CommonClientPaths;
use nym_config::{
must_get_home, read_config_from_toml_file, save_formatted_config_to_file, NymConfigTemplate,
DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILENAME, DEFAULT_DATA_DIR, NYM_DIR,
@@ -69,6 +71,24 @@ impl NymConfigTemplate for Config {
}
}
impl ClientConfig for Config {
fn common_paths(&self) -> &CommonClientPaths {
&self.storage_paths.common_paths
}
fn core_config(&self) -> &BaseClientConfig {
&self.core.base
}
fn default_store_location(&self) -> PathBuf {
self.default_location()
}
fn save_to<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
save_formatted_config_to_file(self, path)
}
}
impl Config {
pub fn new<S: AsRef<str>>(id: S, provider_mix_address: S) -> Self {
Config {
+1 -1
View File
@@ -9,7 +9,7 @@ repository = { workspace = true }
[dependencies]
atty = "0.2"
clap = { version = "4.0", features = ["derive"] }
clap = { workspace = true, features = ["derive"] }
clap_complete = "4.0"
clap_complete_fig = "4.0"
log = { workspace = true }
+2
View File
@@ -11,6 +11,7 @@ rust-version = "1.66"
async-trait = { workspace = true }
base64 = "0.21.2"
cfg-if = "1.0.0"
clap = { workspace = true, optional = true }
dashmap = { workspace = true }
dirs = "4.0"
futures = { workspace = true }
@@ -92,6 +93,7 @@ sqlx = { version = "0.6.2", features = ["runtime-tokio-rustls", "sqlite", "macro
[features]
default = []
cli = ["clap"]
fs-surb-storage = ["sqlx"]
wasm = ["nym-gateway-client/wasm"]
@@ -0,0 +1,210 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::config::disk_persistence::CommonClientPaths;
use crate::error::ClientCoreError;
use crate::{
client::{
base_client::storage::gateway_details::OnDiskGatewayDetails,
key_manager::persistence::OnDiskKeys,
},
init::types::{GatewayDetails, GatewaySelectionSpecification, GatewaySetup, InitResults},
};
use log::info;
use nym_crypto::asymmetric::identity;
use nym_topology::NymTopology;
use std::path::{Path, PathBuf};
pub trait InitialisableClient {
const NAME: &'static str;
type Error: From<ClientCoreError>;
type InitArgs: AsRef<CommonClientInitArgs>;
type Config: ClientConfig;
fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error>;
fn initialise_storage_paths(id: &str) -> Result<(), Self::Error>;
fn default_config_path(id: &str) -> PathBuf;
fn construct_config(init_args: &Self::InitArgs) -> Self::Config;
}
pub trait ClientConfig {
fn common_paths(&self) -> &CommonClientPaths;
fn core_config(&self) -> &crate::config::Config;
fn default_store_location(&self) -> PathBuf;
fn save_to<P: AsRef<Path>>(&self, path: P) -> std::io::Result<()>;
}
#[cfg_attr(feature = "cli", derive(clap::Args))]
#[derive(Debug, Clone)]
pub struct CommonClientInitArgs {
/// Id of client we want to create config for.
#[cfg_attr(feature = "cli", clap(long))]
pub id: String,
/// Id of the gateway we are going to connect to.
#[cfg_attr(feature = "cli", clap(long))]
pub gateway: Option<identity::PublicKey>,
/// Specifies whether the new gateway should be determined based by latency as opposed to being chosen
/// uniformly.
#[cfg_attr(feature = "cli", clap(long, conflicts_with = "gateway"))]
pub latency_based_selection: bool,
/// Force register gateway. WARNING: this will overwrite any existing keys for the given id,
/// potentially causing loss of access.
#[cfg_attr(feature = "cli", clap(long))]
pub force_register_gateway: bool,
/// Comma separated list of rest endpoints of the nyxd validators
#[cfg_attr(
feature = "cli",
clap(long, alias = "nyxd_validators", value_delimiter = ',', hide = true)
)]
pub nyxd_urls: Option<Vec<url::Url>>,
/// Comma separated list of rest endpoints of the API validators
#[cfg_attr(
feature = "cli",
clap(
long,
alias = "api_validators",
value_delimiter = ',',
group = "network"
)
)]
pub nym_apis: Option<Vec<url::Url>>,
/// Path to .json file containing custom network specification.
#[cfg_attr(feature = "cli", clap(long, group = "network", hide = true))]
pub custom_mixnet: Option<PathBuf>,
/// Set this client to work in a enabled credentials mode that would attempt to use gateway
/// with bandwidth credential requirement.
#[cfg_attr(feature = "cli", clap(long, hide = true))]
pub enabled_credentials_mode: Option<bool>,
/// Mostly debug-related option to increase default traffic rate so that you would not need to
/// modify config post init
#[cfg_attr(feature = "cli", clap(long, hide = true))]
pub fastmode: bool,
/// Disable loop cover traffic and the Poisson rate limiter (for debugging only)
#[cfg_attr(feature = "cli", clap(long, hide = true))]
pub no_cover: bool,
}
pub struct InitResultsWithConfig<T> {
pub config: T,
pub init_results: InitResults,
}
pub async fn initialise_client<C>(
init_args: C::InitArgs,
) -> Result<InitResultsWithConfig<C::Config>, C::Error>
where
C: InitialisableClient,
{
info!("initialising {} client", C::NAME);
let common_args = init_args.as_ref();
let id = &common_args.id;
let already_init = if C::default_config_path(id).exists() {
// in case we're using old config, try to upgrade it
// (if we're using the current version, it's a no-op)
C::try_upgrade_outdated_config(id)?;
eprintln!("{} client \"{id}\" was already initialised before", C::NAME);
true
} else {
C::initialise_storage_paths(id)?;
false
};
// Usually you only register with the gateway on the first init, however you can force
// re-registering if wanted.
let user_wants_force_register = common_args.force_register_gateway;
if user_wants_force_register {
eprintln!("Instructed to force registering gateway. This might overwrite keys!");
}
// If the client was already initialized, don't generate new keys and don't re-register with
// the gateway (because this would create a new shared key).
// Unless the user really wants to.
let register_gateway = !already_init || user_wants_force_register;
// Attempt to use a user-provided gateway, if possible
let user_chosen_gateway_id = common_args.gateway;
let selection_spec = GatewaySelectionSpecification::new(
user_chosen_gateway_id.map(|id| id.to_base58_string()),
Some(common_args.latency_based_selection),
false,
);
// Load and potentially override config
let config = C::construct_config(&init_args);
let paths = config.common_paths();
let core = config.core_config();
// Setup gateway by either registering a new one, or creating a new config from the selected
// one but with keys kept, or reusing the gateway configuration.
let key_store = OnDiskKeys::new(paths.keys.clone());
let details_store = OnDiskGatewayDetails::new(&paths.gateway_details);
let available_gateways = if let Some(custom_mixnet) = common_args.custom_mixnet.as_ref() {
let hardcoded_topology = NymTopology::new_from_file(custom_mixnet).map_err(|source| {
ClientCoreError::CustomTopologyLoadFailure {
file_path: custom_mixnet.clone(),
source,
}
})?;
hardcoded_topology.get_gateways()
} else {
let mut rng = rand::thread_rng();
crate::init::helpers::current_gateways(&mut rng, &core.client.nym_api_urls).await?
};
let gateway_setup = GatewaySetup::New {
specification: selection_spec,
available_gateways,
overwrite_data: register_gateway,
};
let init_details =
crate::init::setup_gateway(gateway_setup, &key_store, &details_store).await?;
// TODO: ask the service provider we specified for its interface version and set it in the config
let config_save_location = config.default_store_location();
if let Err(err) = config.save_to(&config_save_location) {
return Err(ClientCoreError::ConfigSaveFailure {
typ: C::NAME.to_string(),
id: id.to_string(),
path: config_save_location,
source: err,
}
.into());
}
eprintln!(
"Saved configuration file to {}",
config_save_location.display()
);
let address = init_details.client_address()?;
let GatewayDetails::Configured(gateway_details) = init_details.gateway_details else {
return Err(ClientCoreError::UnexpectedPersistedCustomGatewayDetails)?;
};
let init_results = InitResults::new(config.core_config(), address, &gateway_details);
Ok(InitResultsWithConfig {
config,
init_results,
})
}
@@ -0,0 +1,59 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use nym_crypto::asymmetric::identity;
use std::path::PathBuf;
#[cfg_attr(feature = "cli", derive(clap::Args))]
#[derive(Debug, Clone)]
pub struct CommonClientRunArgs {
/// Id of client we want to create config for.
#[cfg_attr(feature = "cli", clap(long))]
pub id: String,
/// Id of the gateway we want to connect to. If overridden, it is user's responsibility to
/// ensure prior registration happened
#[cfg_attr(feature = "cli", clap(long))]
pub gateway: Option<identity::PublicKey>,
/// Comma separated list of rest endpoints of the nyxd validators
#[cfg_attr(
feature = "cli",
clap(long, alias = "nyxd_validators", value_delimiter = ',', hide = true)
)]
pub nyxd_urls: Option<Vec<url::Url>>,
/// Comma separated list of rest endpoints of the API validators
#[cfg_attr(
feature = "cli",
clap(
long,
alias = "api_validators",
value_delimiter = ',',
group = "network"
)
)]
pub nym_apis: Option<Vec<url::Url>>,
/// Path to .json file containing custom network specification.
#[cfg_attr(feature = "cli", clap(long, group = "network", hide = true))]
pub custom_mixnet: Option<PathBuf>,
/// Set this client to work in a enabled credentials mode that would attempt to use gateway
/// with bandwidth credential requirement.
#[cfg_attr(feature = "cli", clap(long, hide = true))]
pub enabled_credentials_mode: Option<bool>,
/// Mostly debug-related option to increase default traffic rate so that you would not need to
/// modify config post init
// note: we removed the 'conflicts_with = medium_toggle', but that's fine since NR
// has defined the conflict on that field itself
#[cfg_attr(feature = "cli", clap(long, hide = true))]
pub fastmode: bool,
/// Disable loop cover traffic and the Poisson rate limiter (for debugging only)
// note: we removed the 'conflicts_with = medium_toggle', but that's fine since NR
// has defined the conflict on that field itself
#[cfg_attr(feature = "cli", clap(long, hide = true))]
pub no_cover: bool,
}
@@ -0,0 +1,5 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
pub mod client_init;
pub mod client_run;
+21
View File
@@ -8,6 +8,7 @@ use nym_topology::gateway::GatewayConversionError;
use nym_topology::NymTopologyError;
use nym_validator_client::ValidatorClientError;
use std::error::Error;
use std::path::PathBuf;
#[derive(thiserror::Error, Debug)]
pub enum ClientCoreError {
@@ -132,6 +133,26 @@ pub enum ClientCoreError {
#[error("the specified gateway '{gateway}' does not support the wss protocol")]
UnsupportedWssProtocol { gateway: String },
#[error(
"failed to load custom topology using path '{}'. detailed message: {source}", file_path.display()
)]
CustomTopologyLoadFailure {
file_path: PathBuf,
#[source]
source: std::io::Error,
},
#[error(
"failed to save config file for client-{typ} id {id} using path '{}'. detailed message: {source}", path.display()
)]
ConfigSaveFailure {
typ: String,
id: String,
path: PathBuf,
#[source]
source: std::io::Error,
},
}
/// Set of messages that the client can send to listeners via the task manager
+9 -7
View File
@@ -296,16 +296,17 @@ impl<T> GatewaySetup<T> {
/// Struct describing the results of the client initialization procedure.
#[derive(Debug, Serialize)]
pub struct InitResults {
version: String,
id: String,
identity_key: String,
encryption_key: String,
gateway_id: String,
gateway_listener: String,
pub version: String,
pub id: String,
pub identity_key: String,
pub encryption_key: String,
pub gateway_id: String,
pub gateway_listener: String,
pub address: Recipient,
}
impl InitResults {
pub fn new(config: &Config, address: &Recipient, gateway: &GatewayEndpointConfig) -> Self {
pub fn new(config: &Config, address: Recipient, gateway: &GatewayEndpointConfig) -> Self {
Self {
version: config.client.version.clone(),
id: config.client.id.clone(),
@@ -313,6 +314,7 @@ impl InitResults {
encryption_key: address.encryption_key().to_base58_string(),
gateway_id: gateway.gateway_id.clone(),
gateway_listener: gateway.gateway_listener.clone(),
address,
}
}
}
+2
View File
@@ -1,5 +1,7 @@
use std::future::Future;
#[cfg(not(target_arch = "wasm32"))]
pub mod cli_helpers;
pub mod client;
pub mod config;
pub mod error;
+1 -1
View File
@@ -11,7 +11,7 @@ bip39 = { workspace = true }
bs58 = "0.4"
comfy-table = "6.0.0"
cfg-if = "1.0.0"
clap = { version = "4.0", features = ["derive"] }
clap = { workspace = true, features = ["derive"] }
cw-utils = { workspace = true }
handlebars = "3.0.1"
humantime-serde = "1.0"
+1 -1
View File
@@ -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)];
@@ -9,11 +9,12 @@ use std::sync::Arc;
use std::time::Duration;
use tokio::sync::RwLock;
#[derive(Clone, Default)]
pub struct AtomicVerlocResult {
inner: Arc<RwLock<VerlocResult>>,
}
#[derive(Debug, Clone, Serialize)]
#[derive(Debug, Clone, Serialize, Default)]
pub struct VerlocResult {
total_tested: usize,
#[serde(with = "humantime_serde")]
@@ -35,13 +36,6 @@ impl AtomicVerlocResult {
}
}
// this could have also been achieved with a normal #[derive(Clone)] but I prefer to be explicit about it
pub(crate) fn clone_data_pointer(&self) -> Self {
AtomicVerlocResult {
inner: Arc::clone(&self.inner),
}
}
pub(crate) async fn reset_results(&self, new_tested: usize) {
let mut write_permit = self.inner.write().await;
write_permit.total_tested = new_tested;
+1 -1
View File
@@ -226,7 +226,7 @@ impl VerlocMeasurer {
}
pub fn get_verloc_results_pointer(&self) -> AtomicVerlocResult {
self.results.clone_data_pointer()
self.results.clone()
}
fn start_listening(&self) -> JoinHandle<()> {
+27
View File
@@ -119,6 +119,7 @@ pub struct GatewayNetworkRequesterDetails {
pub encryption_key: String,
pub open_proxy: bool,
pub exit_policy: bool,
pub enabled_statistics: bool,
// just a convenience wrapper around all the keys
@@ -140,9 +141,35 @@ impl fmt::Display for GatewayNetworkRequesterDetails {
writeln!(f, "\taddress: {}", self.address)?;
writeln!(f, "\tuses open proxy: {}", self.open_proxy)?;
writeln!(f, "\tuses exit policy: {}", self.exit_policy)?;
writeln!(f, "\tsends statistics: {}", self.enabled_statistics)?;
writeln!(f, "\tallow list path: {}", self.allow_list_path)?;
writeln!(f, "\tunknown list path: {}", self.unknown_list_path)
}
}
#[derive(Serialize, Deserialize)]
pub struct GatewayIpPacketRouterDetails {
pub enabled: bool,
pub identity_key: String,
pub encryption_key: String,
// just a convenience wrapper around all the keys
pub address: String,
pub config_path: String,
}
impl fmt::Display for GatewayIpPacketRouterDetails {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "IP packet router:")?;
writeln!(f, "\tenabled: {}", self.enabled)?;
writeln!(f, "\tconfig path: {}", self.config_path)?;
writeln!(f, "\tidentity key: {}", self.identity_key)?;
writeln!(f, "\tencryption key: {}", self.encryption_key)?;
writeln!(f, "\taddress: {}", self.address)
}
}
+16 -1
View File
@@ -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,7 +85,12 @@ 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())
@@ -96,10 +107,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()),
}
}
@@ -121,6 +134,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 +223,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())
+1
View File
@@ -32,6 +32,7 @@ serde = { workspace = true, features = ["derive"] }
tap.workspace = true
thiserror.workspace = true
tokio = { workspace = true, features = ["rt-multi-thread", "net", "io-util"] }
tokio-stream = { version = "0.1.11" }
[target.'cfg(target_os = "linux")'.dependencies]
tokio-tun = "0.9.0"
+24 -4
View File
@@ -1,11 +1,14 @@
use std::net::SocketAddr;
use std::{net::SocketAddr, time::Duration};
use boringtun::x25519;
use dashmap::{
mapref::one::{Ref, RefMut},
DashMap,
};
use tokio::sync::mpsc::{self};
use tokio::{
sync::mpsc::{self},
time::{error::Elapsed, timeout},
};
use crate::event::Event;
@@ -14,9 +17,26 @@ use crate::event::Event;
pub struct PeerEventSender(mpsc::Sender<Event>);
pub(crate) struct PeerEventReceiver(mpsc::Receiver<Event>);
#[derive(thiserror::Error, Debug)]
pub enum PeerEventSenderError {
#[error("timeout")]
Timeout {
#[from]
source: Elapsed,
},
#[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(crate) async fn send(&self, event: Event) -> Result<(), PeerEventSenderError> {
timeout(Duration::from_millis(1000), self.0.send(event))
.await?
.map_err(|err| err.into())
}
}
+19 -6
View File
@@ -11,7 +11,7 @@ mod packet_relayer;
mod platform;
mod registered_peers;
mod setup;
mod tun_task_channel;
pub mod tun_task_channel;
mod udp_listener;
mod wg_tunnel;
@@ -20,7 +20,7 @@ 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;
pub use platform::linux::tun_device;
/// Start wireguard UDP listener and TUN device
///
@@ -32,16 +32,29 @@ pub async fn start_wireguard(
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
// TODO: make this configurable
// We can optionally index peers by their IP like standard wireguard. If we don't then we do
// plain NAT where we match incoming destination IP with outgoing source IP.
let peers_by_ip = Arc::new(tokio::sync::Mutex::new(network_table::NetworkTable::new()));
// ... 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()));
// Alternative 1:
let routing_mode = tun_device::RoutingMode::new_allowed_ips(peers_by_ip.clone());
// Alternative 2:
//let routing_mode = tun_device::RoutingMode::new_nat();
// 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());
let config = tun_device::TunDeviceConfig {
base_name: setup::TUN_BASE_NAME.to_string(),
ip: setup::TUN_DEVICE_ADDRESS.parse().unwrap(),
netmask: setup::TUN_DEVICE_NETMASK.parse().unwrap(),
};
let (tun, tun_task_tx, tun_task_response_rx) = tun_device::TunDevice::new(routing_mode, config);
tun.start();
// We also index peers by a tag
let peers_by_tag = Arc::new(tokio::sync::Mutex::new(wg_tunnel::PeersByTag::new()));
// 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.
+1 -1
View File
@@ -1 +1 @@
pub(crate) mod tun_device;
pub mod tun_device;
+198 -88
View File
@@ -2,29 +2,73 @@ use std::{
collections::HashMap,
net::{IpAddr, Ipv4Addr},
sync::Arc,
time::Duration,
};
use etherparse::{InternetSlice, SlicedPacket};
use tap::TapFallible;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::{
io::{AsyncReadExt, AsyncWriteExt},
time::timeout,
};
use crate::{
active_peers::PeerEventSenderError,
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,
TunTaskResponseSendError, TunTaskResponseTx, TunTaskRx, TunTaskTx,
},
udp_listener::PeersByIp,
};
#[derive(thiserror::Error, Debug)]
pub enum TunDeviceError {
#[error("iface: timeout writing to tun device, dropping packet")]
TunWriteTimeout,
#[error("iface: failed forwarding packet to peer: {source}")]
ForwardToPeerFailed {
#[from]
source: PeerEventSenderError,
},
#[error("iface: failed to forward responding packet with tag: {source}")]
ForwardNatResponseFailed {
#[from]
source: TunTaskResponseSendError,
},
#[error("iface: error writing to tun device: {source}")]
TunWriteError { source: std::io::Error },
#[error("unable to parse destination address from packet")]
UnableToParseDstAdddress,
#[error("unable to parse source address from packet")]
UnableToParseSrcAddress {
#[from]
source: etherparse::ReadError,
},
#[error("unable to parse source address from packet: ip header missing")]
UnableToParseSrcAddressIpHeaderMissing,
#[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(1350)
.mtu(mtu)
.up()
.address(address)
.netmask(netmask)
@@ -34,31 +78,73 @@ fn setup_tokio_tun_device(name: &str, address: Ipv4Addr, netmask: Ipv4Addr) -> t
pub struct TunDevice {
// The TUN device that we read/write to, to send/receive packets
tun: tokio_tun::Tun,
tun: Option<tokio_tun::Tun>,
// Incoming data that we should send
tun_task_rx: TunTaskRx,
tun_task_rx: Option<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
peers_by_ip: Arc<tokio::sync::Mutex<PeersByIp>>,
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(),
})
}
pub fn new_allowed_ips(peers_by_ip: Arc<tokio::sync::Mutex<PeersByIp>>) -> Self {
RoutingMode::AllowedIps(AllowedIpsInner { peers_by_ip })
}
}
pub struct AllowedIpsInner {
peers_by_ip: Arc<tokio::sync::Mutex<PeersByIp>>,
}
impl AllowedIpsInner {
async fn lock(&self) -> Result<tokio::sync::MutexGuard<PeersByIp>, TunDeviceError> {
timeout(Duration::from_millis(200), 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(
peers_by_ip: Arc<tokio::sync::Mutex<PeersByIp>>,
routing_mode: RoutingMode,
config: TunDeviceConfig,
) -> (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(),
);
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
@@ -66,54 +152,45 @@ impl TunDevice {
let (tun_task_response_tx, tun_task_response_rx) = tun_task_response_channel();
let tun_device = TunDevice {
tun_task_rx,
tun_task_rx: Some(tun_task_rx),
tun_task_response_tx,
tun,
peers_by_ip,
nat_table: HashMap::new(),
tun: Some(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) {
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()
);
async fn handle_tun_write(&mut self, data: TunTaskPayload) -> Result<(), TunDeviceError> {
{
let (tag, ref packet) = data;
let dst_addr = boringtun::noise::Tunn::dst_address(packet)
.ok_or_else(|| TunDeviceError::UnableToParseDstAdddress)?;
// TODO: expire old entries
self.nat_table.insert(src_addr, tag);
let src_addr = parse_src_address(packet)?;
log::info!(
"iface: write Packet({src_addr} -> {dst_addr}, {} bytes)",
packet.len()
);
self.tun
.write_all(&packet)
.await
.tap_err(|err| {
log::error!("iface: write error: {err}");
})
.ok();
// TODO: expire old entries
if let RoutingMode::Nat(nat_table) = &mut self.routing_mode {
nat_table.nat_table.insert(src_addr, tag);
}
}
// timeout(Duration::from_millis(1000), self.tun.write_all(&data.1))
// .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]) {
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;
};
async fn handle_tun_read(&self, packet: &[u8]) -> Result<(), TunDeviceError> {
let dst_addr = boringtun::noise::Tunn::dst_address(packet)
.ok_or(TunDeviceError::UnableToParseDstAdddress)?;
let src_addr = parse_src_address(packet)?;
log::info!(
"iface: read Packet({src_addr} -> {dst_addr}, {} bytes)",
packet.len(),
@@ -121,59 +198,93 @@ impl TunDevice {
// 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;
match self.routing_mode {
// This is how wireguard does it, by consulting the AllowedIPs table.
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::info!("Forward packet to wg tunnel");
return peer_tx
.send(Event::Ip(packet.to_vec().into()))
.await
.map_err(|err| err.into());
}
}
}
// 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;
// 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::info!("Forward packet with NAT tag: {tag}");
return self
.tun_task_response_tx
.send((*tag, packet.to_vec()))
.await
.map_err(|err| err.into());
}
}
}
log::info!("No peer found, packet dropped");
Ok(())
}
pub async fn run(mut self) {
let mut buf = [0u8; 1024];
let mut buf = [0u8; 65535];
let tun_task_rx_stream =
tokio_stream::wrappers::ReceiverStream::new(self.tun_task_rx.take().unwrap().0);
use futures::StreamExt;
let tun_task_rx_stream = tun_task_rx_stream.map(|data| {
//{
// let (tag, ref packet) = data;
// let dst_addr = boringtun::noise::Tunn::dst_address(packet).unwrap();
// // .ok_or_else(|| TunDeviceError::UnableToParseDstAdddress)?;
// let src_addr = parse_src_address(packet).unwrap();
// log::info!(
// "iface: write Packet({src_addr} -> {dst_addr}, {} bytes)",
// packet.len()
// );
// // TODO: expire old entries
// // if let RoutingMode::Nat(nat_table) = &mut self.routing_mode {
// // nat_table.nat_table.insert(src_addr, tag);
// // }
//}
// data.1
4
});
let (mut tun_read, tun_write) = tokio::io::split(self.tun);
loop {
tokio::select! {
// Reading from the TUN device
len = self.tun.read(&mut buf) => match len {
// len = self.tun.read(&mut buf) => match len {
len = tun_read.read(&mut buf) => match len {
Ok(len) => {
let packet = &buf[..len];
self.handle_tun_read(packet).await;
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;
// break;
}
},
// Writing to the TUN device
Some(data) = self.tun_task_rx.recv() => {
self.handle_tun_write(data).await;
}
//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}");
// }
//}
// res = self.tun.send_all(&mut tun_task_rx_stream) => {
// log::error!("finished");
// }
}
}
log::info!("TUN device shutting down");
// log::info!("TUN device shutting down");
}
pub fn start(self) {
@@ -181,12 +292,11 @@ impl TunDevice {
}
}
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(),
})
fn parse_src_address(packet: &[u8]) -> Result<IpAddr, TunDeviceError> {
let headers = SlicedPacket::from_ip(packet)?;
match headers.ip {
Some(InternetSlice::Ipv4(ip, _)) => Ok(ip.source_addr().into()),
Some(InternetSlice::Ipv6(ip, _)) => Ok(ip.source_addr().into()),
None => Err(TunDeviceError::UnableToParseSrcAddressIpHeaderMissing),
}
}
+8 -8
View File
@@ -8,21 +8,17 @@ use log::info;
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_BASE_NAME: &str = "nymwg";
pub const TUN_DEVICE_ADDRESS: &str = "10.1.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=";
// 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
@@ -46,7 +42,11 @@ 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);
// 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::try_from(peer_static_public_bytes).unwrap();
info!(
"Adding wg peer public key: {}",
+24 -9
View File
@@ -1,13 +1,20 @@
use tokio::sync::mpsc;
use std::time::Duration;
use tokio::{
sync::mpsc::{self, error::SendError},
time::{error::Elapsed, timeout},
};
pub(crate) type TunTaskPayload = (u64, Vec<u8>);
#[derive(Clone)]
pub struct TunTaskTx(mpsc::Sender<TunTaskPayload>);
pub(crate) struct TunTaskRx(mpsc::Receiver<TunTaskPayload>);
pub(crate) struct TunTaskRx(pub(crate) mpsc::Receiver<TunTaskPayload>);
pub(crate) struct TunTaskRxStream(pub(crate) tokio_stream::wrappers::ReceiverStream<TunTaskPayload>);
impl TunTaskTx {
pub(crate) async fn send(
pub async fn send(
&self,
data: TunTaskPayload,
) -> Result<(), tokio::sync::mpsc::error::SendError<TunTaskPayload>> {
@@ -30,17 +37,25 @@ pub(crate) fn tun_task_channel() -> (TunTaskTx, TunTaskRx) {
pub(crate) struct TunTaskResponseTx(mpsc::Sender<TunTaskPayload>);
pub struct TunTaskResponseRx(mpsc::Receiver<TunTaskPayload>);
#[derive(thiserror::Error, Debug)]
pub enum TunTaskResponseSendError {
#[error("failed to send: timeout")]
Timeout(#[from] Elapsed),
#[error("failed to send: {0}")]
SendError(#[from] SendError<TunTaskPayload>),
}
impl TunTaskResponseTx {
pub(crate) async fn send(
&self,
data: TunTaskPayload,
) -> Result<(), tokio::sync::mpsc::error::SendError<TunTaskPayload>> {
self.0.send(data).await
pub(crate) async fn send(&self, data: TunTaskPayload) -> Result<(), TunTaskResponseSendError> {
timeout(Duration::from_millis(1000), self.0.send(data))
.await?
.map_err(|err| err.into())
}
}
impl TunTaskResponseRx {
pub(crate) async fn recv(&mut self) -> Option<TunTaskPayload> {
pub async fn recv(&mut self) -> Option<TunTaskPayload> {
self.0.recv().await
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
opt: wasm
wasm-opt --disable-sign-ext -Os ../target/wasm32-unknown-unknown/release/mixnet_contract.wasm -o ../target/wasm32-unknown-unknown/release/mixnet_contract.wasm
wasm-opt --signext-lowering -Os ../target/wasm32-unknown-unknown/release/mixnet_contract.wasm -o ../target/wasm32-unknown-unknown/release/mixnet_contract.wasm
wasm:
RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown
+1 -2
View File
@@ -9,5 +9,4 @@ 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.
+3 -1
View File
@@ -19,4 +19,6 @@ theme/
theme
theme/*
.idea
.idea
notes
+26 -11
View File
@@ -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]&#40;integrations/mixnet-integration.md&#41;)
- [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,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 Nyms 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]&#40;../tutorials/simple-service-provider/simple-service-provider.md&#41;.)
#### Webassembly client
If youre working in JavaScript or Typescript in the browser, or building an edge computing app, youll likely want to choose the webassembly client.
@@ -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 youve found when developing apps with Nym that you have created scripts/hacks/workarounds for? Is there a pain point that youve 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 youve run into this issue, it's very likely someone else already has, or will!
- Interacting with one of the SDKs via FFI: perhaps youre 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 [NTVs 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 arent 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: wed 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 youre 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`
@@ -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 users 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.
![Electrum Bitcoin wallet setup](../images/electrum_tutorial/electrum.gif)
@@ -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 users 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.
![Firo Electrum wallet setup](../images/firo_tutorial/firo.png)
@@ -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 @@ Heres 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.
+3
View File
@@ -6,6 +6,9 @@ language = "en"
multilingual = false # for the moment - ideally work on chinese, brazillian, spanish next
src = "src"
[rust]
edition = "2018"
#################
# PREPROCESSORS #
#################
+22 -5
View File
@@ -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.
+2 -2
View File
@@ -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.
@@ -160,7 +160,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}}
```
+5 -5
View File
@@ -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)
-144
View File
@@ -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).
@@ -0,0 +1,12 @@
# Examples
All the following examples 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 with:
```sh
cargo run --example <NAME_OF_FILE>
```
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.
An example `Cargo.toml` file can be found [here](examples/cargo.md).
@@ -0,0 +1,35 @@
# Example Cargo File
This file imports the basic requirements for running these pieces of example code, and can be used as the basis for your own cargo project.
```toml
[package]
name = "your_app"
version = "x.y.z"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
# Async runtime
tokio = { version = "1.24.1", features = ["rt-multi-thread", "macros"] }
# Used for (de)serialising incoming and outgoing messages
serde = "1.0.152"
serde_json = "1.0.91"
# Nym clients, addressing, etc
nym-sdk = { git = "https://github.com/nymtech/nym", branch = "master" }
nym-sphinx-addressing = { git = "https://github.com/nymtech/nym", branch = "master" }
nym-bin-common = { git = "https://github.com/nymtech/nym", branch = "master" }
nym-sphinx-anonymous-replies = { git = "https://github.com/nymtech/nym", branch = "master" }
# Additional dependencies if you're interacting with Nyx or another Cosmos SDK blockchain
cosmrs = "=0.14.0"
nym-validator-client = { git = "https://github.com/nymtech/nym", branch = "master" }
# If you're building an app with a client and server / serivce this might be a useful structure for your repo
[[bin]]
name = "client"
path = "bin/client.rs"
[[bin]]
name = "service"
path = "bin/service.rs"
```
@@ -0,0 +1,9 @@
# 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).
@@ -0,0 +1,18 @@
# 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}}
```
@@ -0,0 +1,28 @@
# Key Creation and Use
The previous example 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
```
@@ -0,0 +1,8 @@
# Simple Send
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`).
Simply importing the `nym_sdk` crate into your project allows you to create a client and send traffic through the mixnet.
```rust,noplayground
{{#include ../../../../../../sdk/rust/nym-sdk/examples/simple.rs}}
```
@@ -0,0 +1,10 @@
# Socks Proxy
There is also the option to embed the [`socks5-client`](../../../clients/socks5-client.md) into your app code (`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 if they can speak SOCKS5, 4a, or 4.
```
```rust,noplayground
{{#include ../../../../../../sdk/rust/nym-sdk/examples/socks5.rs}}
```
@@ -0,0 +1,6 @@
# 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}}
```
@@ -0,0 +1,6 @@
# Manually Handled 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}}
```
@@ -0,0 +1,16 @@
# Anonymous Replies with SURBs (Single Use Reply Blocks)
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}}
```
@@ -0,0 +1,70 @@
# Message Helpers
## Handling incoming messages
As seen in the [Chain querier tutorial](https://github.com/nymtech/developer-tutorials/blob/0130ee5a61cd6801bdcfc84608b2a520b5392714/rust/chain-query-service/) when listening out for a response to a sent message (e.g. if you have sent a request to a service, and are awaiting the response) you will want to await [non-empty messages (if you don't know why, read the info on this here)](troubleshooting.md#client-receives-empty-messages-when-listening-for-response). This can be done with something like the helper functions [here](https://github.com/nymtech/developer-tutorials/blob/0130ee5a61cd6801bdcfc84608b2a520b5392714/rust/chain-query-service/src/lib.rs#L71):
```rust
use nym_sdk::mixnet::ReconstructedMessage;
pub async fn wait_for_non_empty_message(
client: &mut MixnetClient,
) -> anyhow::Result<ReconstructedMessage> {
while let Some(mut new_message) = client.wait_for_messages().await {
if !new_message.is_empty() {
return Ok(new_message.pop().unwrap());
}
}
bail!("did not receive any non-empty message")
}
pub fn handle_response(message: ReconstructedMessage) -> anyhow::Result<ResponseTypes> {
ResponseTypes::try_deserialize(message.message)
}
// Note here that the only difference between handling a request and a response
// is that a request will have a sender_tag to parse.
//
// This is used for anonymous replies with SURBs.
pub fn handle_request(
message: ReconstructedMessage,
) -> anyhow::Result<(RequestTypes, Option<AnonymousSenderTag>)> {
let request = RequestTypes::try_deserialize(message.message)?;
Ok((request, message.sender_tag))
}
```
The above helper functions are used as such by the client in tutorial example: it sends a message to the service (what the message is isn't important - just that your client has sent a message _somewhere_ and you are awaiting a response), waits for a _non_empty_ message, then handles it (then logs it - but you can do whatever you want, parse it, etc):
```rust
// [snip]
// Send serialised request to service via mixnet what is await-ed here is
// placing the message in the client's message queue, NOT the sending itself.
let _ = client
.send_message(sp_address, message.serialize(), Default::default())
.await;
// Await a non-empty message
let received = wait_for_non_empty_message(client).await?;
// Handle the response received (the non-empty message awaited above)
let sp_response = handle_response(received)?;
// Match JSON -> ResponseType
let res = match sp_response {
crate::ResponseTypes::Balance(response) => {
println!("{:#?}", response);
response.balance
}
};
// [snip]
```
([repo code on Github here](https://github.com/nymtech/developer-tutorials/blob/0130ee5a61cd6801bdcfc84608b2a520b5392714/rust/chain-query-service/src/client.rs#L19))
## Iterating over incoming messages
It is recommended to use `nym_client.next().await` over `nym_client.wait_for_messages().await` as the latter will return one message at a time which will probably be easier to deal with. See the [parallel send and receive example](https://github.com/nymtech/nym/blob/2993e85c7a17bd5b68171751a48b731b2394ee03/sdk/rust/nym-sdk/examples/parallel_sending_and_receiving.rs#L23-L25) for an example.
## Remember to disconnect your client
You should always **manually disconnect your client** with `client.disconnect().await` as seen in the code examples. This is important as your client is writing to a local DB and dealing with SURB storage.
@@ -0,0 +1,5 @@
# Message Types
[//]: # (TODO expand! )
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).
+48
View File
@@ -0,0 +1,48 @@
# 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 separate 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 separate 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.
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 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.
### Development status
The SDK is still somewhat a work in progress: interfaces are fairly stable but still may change in subsequent releases.
### Installation
The `nym-sdk` crate is **not yet available 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" }
```
By default the above command will import the current `HEAD` of the default branch, which in our case is `develop`. Assuming instead you wish to pull in another branch (e.g. `master` or a particular release) you can specify this like so:
```toml
# importing HEAD of master branch
nym-sdk = { git = "https://github.com/nymtech/nym", branch = "master" }
# importing HEAD of the third release of 2023, codename 'kinder'
nym-sdk = { git = "https://github.com/nymtech/nym", branch = "release/2023.3-kinder" }
```
You can also define a particular git commit to use as your import like so:
```toml
nym-sdk = { git = "https://github.com/nymtech/nym", rev = "85a7ec9f02ca8262d47eebb6c3b19d832341b55d" }
```
Since the `HEAD` of `master` is always the most recent release, we recommend developers use that for their imports, unless they have a reason to pull in a specific historic version of the code.
### Generate Crate Docs
In order to generate the crate docs run `cargo doc --open` from `nym/sdk/rust/nym-sdk/`
@@ -0,0 +1,115 @@
# Troubleshooting
Below are several common issues or questions you may have.
If you come across something that isn't explained here, [PRs are welcome](https://github.com/nymtech/nym/issues/new/choose).
## Verbose `task client is being dropped` logging
### On client shutdown (expected)
If this is happening at the end of your code when disconnecting your client, this is fine; we just have a verbose client! When calling `client.disconnect().await` this is simply informing you that the client is shutting down.
On client shutdown / disconnect this is to be expected - this can be seen in many of the code examples as well. We use the [`nym_bin_common::logging`](https://github.com/nymtech/nym/blob/develop/common/bin-common/src/logging/mod.rs) import to set logging in our example code. This defaults to `INFO` level.
If you wish to quickly lower the verbosity of your client process logs when developing you can prepend your command with `RUST_LOG=<LOGGING_LEVEL>`.
If you want to run the `builder.rs` example with only `WARN` level logging and below:
```sh
cargo run --example builder
```
Becomes:
```sh
RUST_LOG=warn cargo run --example builder
```
You can also make the logging _more_ verbose with:
```sh
RUST_LOG=debug cargo run --example builder
```
### Not on client shutdown (unexpected)
If this is happening unexpectedly then you might be shutting your client process down too early. See the [accidentally killing your client process](#accidentally-killing-your-client-process-too-early) below for possible explanations and how to fix this issue.
[//]: # (TODO note on poisson dance and not immediately killing client process)
## Accidentally killing your client process too early
If you are seeing either of the following errors when trying to run a client, specifically sending a message, then you may be accidentally killing your client process.
```sh
2023-11-02T10:31:03.930Z INFO TaskClient-BaseNymClient-real_traffic_controller-ack_control-action_controller > the task client is getting dropped
2023-11-02T10:31:04.625Z INFO TaskClient-BaseNymClient-received_messages_buffer-request_receiver > the task client is getting dropped
2023-11-02T10:31:04.626Z DEBUG nym_client_core::client::real_messages_control::acknowledgement_control::input_message_listener > InputMessageListener: Exiting
2023-11-02T10:31:04.626Z INFO TaskClient-BaseNymClient-real_traffic_controller-ack_control-input_message_listener > the task client is getting dropped
2023-11-02T10:31:04.626Z INFO TaskClient-BaseNymClient-real_traffic_controller-reply_control > the task client is getting dropped
2023-11-02T10:31:04.626Z DEBUG nym_client_core::client::real_messages_control > The reply controller has finished execution!
2023-11-02T10:31:04.626Z DEBUG nym_client_core::client::real_messages_control::acknowledgement_control > The input listener has finished execution!
2023-11-02T10:31:04.626Z INFO nym_task::manager > All registered tasks succesfully shutdown
```
```sh
2023-11-02T11:22:08.408Z ERROR TaskClient-BaseNymClient-topology_refresher > Assuming this means we should shutdown...
2023-11-02T11:22:08.408Z ERROR TaskClient-BaseNymClient-mix_traffic_controller > Polling shutdown failed: channel closed
2023-11-02T11:22:08.408Z INFO TaskClient-BaseNymClient-gateway_transceiver-child > the task client is getting dropped
2023-11-02T11:22:08.408Z ERROR TaskClient-BaseNymClient-mix_traffic_controller > Assuming this means we should shutdown...
thread 'tokio-runtime-worker' panicked at 'action control task has died: TrySendError { kind: Disconnected }', /home/.local/share/cargo/git/checkouts/nym-fbd2f6ea2e760da9/a800cba/common/client-core/src/client/real_messages_control/message_handler.rs:634:14
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
2023-11-02T11:22:08.477Z INFO TaskClient-BaseNymClient-real_traffic_controller-ack_control-input_message_listener > the task client is getting dropped
2023-11-02T11:22:08.477Z ERROR TaskClient-BaseNymClient-real_traffic_controller-ack_control-input_message_listener > Polling shutdown failed: channel closed
2023-11-02T11:22:08.477Z ERROR TaskClient-BaseNymClient-real_traffic_controller-ack_control-input_message_listener > Assuming this means we should shutdown...
```
Using the following piece of code as an example:
```rust
use nym_sdk::mixnet::{MixnetClient, MixnetMessageSender, Recipient};
use clap::Parser;
#[derive(Debug, Clone, Parser)]
enum Opts {
Client {
recipient: Recipient
}
}
#[tokio::main]
async fn main() {
let opts: Opts = Parser::parse();
nym_bin_common::logging::setup_logging();
let mut nym_client = MixnetClient::connect_new().await.expect("Could not build Nym client");
match opts {
Opts::Client { recipient } => {
nym_client.send_plain_message(recipient, "some message string").await.expect("send failed");
}
}
}
```
This is a simplified snippet of code for sending a simple hardcoded message with the following command:
```sh
cargo run client <RECIPIENT_NYM_ADDRESS>
```
You might assume that `send`-ing your message would _just work_ as `nym_client.send_plain_message()` is an async function; you might expect that the client will block until the message is actually sent into the mixnet, then shutdown.
However, this is not true.
**This will only block until the message is put into client's internal queue**. Therefore in the above example, the client is being shut down before the message is _actually sent to the mixnet_; after being placed in the client's internal queue, there is still work to be done under the hood, such as route encrypting the message and placing it amongst the stream of cover traffic.
The simple solution? Make sure the program/client stays active, either by calling `sleep`, or listening out for new messages. As sending a one-shot message without listening out for a response is likely not what you'll be doing, then you will be then awaiting a response (see the [message helpers page](message-helpers.md) for an example of this).
Furthermore, you should always **manually disconnect your client** with `client.disconnect().await` as seen in the code examples. This is important as your client is writing to a local DB and dealing with SURB storage.
## Client receives empty messages when listening for response
If you are sending out a message, it makes sense for your client to then listen out for incoming messages; this would probably be the reply you get from the service you've sent a message to.
You might however be receiving messages without data attached to them / empty payloads. This is most likely because your client is receiving a message containing a [SURB request](https://nymtech.net/docs/architecture/traffic-flow.html#private-replies-using-surbs) - a SURB requesting more SURB packets to be sent to the service, in order for them to have enough packets (with a big enough overall payload) to split the entire response to your initial request across.
Whether the `data` of a SURB request being empty is a feature or a bug is to be decided - there is some discussion surrounding whether we can use SURB requests to send additional data to streamline the process of sending large replies across the mixnet.
You can find a few helper functions [here](message-helpers.md) to help deal with this issue in the meantime.
> If you can think of a more succinct or different way of handling this do reach out - we're happy to hear other opinions
+17 -14
View File
@@ -3,30 +3,33 @@
- [Introduction](introduction.md)
# Binaries
- [Pre-built Binaries](./binaries/pre-built-binaries.md)
- [Binary Initialisation and Configuration](./binaries/init-and-config.md)
- [Building from Source](./binaries/building-nym.md)
- [Pre-built Binaries](binaries/pre-built-binaries.md)
<!-- - [Binary Initialisation and Configuration](binaries/init-and-config.md) -->
- [Building from Source](binaries/building-nym.md)
<!-- - [Version Compatibility Table](binaries/version-compatiblity.md) -->
# Operators Guides
- [Mixnet Nodes Setup](./nodes/setup-guides.md)
- [Preliminary Steps](./preliminary-steps.md)
- [Mix Node](./nodes/mix-node-setup.md)
- [Gateway](./nodes/gateway-setup.md)
- [Network Requester](./nodes/network-requester-setup.md)
- [Nyx Validator Setup](./nodes/validator-setup.md)
- [Maintenance](./nodes/maintenance.md)
- [Troubleshooting](./nodes/troubleshooting.md)
- [Mixnet Nodes Setup](nodes/setup-guides.md)
- [Preliminary Steps](preliminary-steps.md)
- [Mix Node](nodes/mix-node-setup.md)
- [Gateway](nodes/gateway-setup.md)
- [Network Requester](nodes/network-requester-setup.md)
- [Nyx Validator Setup](nodes/validator-setup.md)
- [Maintenance](nodes/maintenance.md)
- [Troubleshooting](nodes/troubleshooting.md)
# FAQ
- [Mix Nodes](./faq/mixnodes-faq.md)
- [Project Smoosh](./faq/smoosh-faq.md)
- [Mix Nodes](faq/mixnodes-faq.md)
- [Project Smoosh](faq/smoosh-faq.md)
# Legal Forum
- [Exit Gateway](./legal/exit-gateway.md)
- [Exit Gateway](legal/exit-gateway.md)
- [Switzerland](legal/swiss.md)
- [United States](legal/united-states.md)
---
# Misc.
@@ -4,3 +4,31 @@ The [Github releases page](https://github.com/nymtech/nym/releases) has pre-buil
If the pre-built binaries don't work or are unavailable for your system, you will need to build the platform yourself.
## Setup Binaries
> Any syntax in `<>` brackets is a users unique variable. Exchange with a corresponding name without the `<>` brackets.
### Download Binary
1. Open [Github releases page](https://github.com/nymtech/nym/releases) and right click on the binary you want
2. Select `Copy Link`
3. Open your VPS terminal in a directory where you want to download Nym binaries.
4. Download binary by running `wget <BINARY_LINK>` where `<BINARY_LINK>` shall be in your clipboard from point \# 2.
### Make Executable
5. Run command:
```sh
chmod +x <BINARY>
# for example: chmod +x nym-mixnode
```
### Run Binary
Now you can use your binary, initialise and run your Nym Node. Follow the guide according to the type of your binary.
**Node setup and usage guides:**
* [Mix nodes](../nodes/mix-node-setup.md)
* [Gateways](../nodes/gateway-setup.md)
* [Network requesters](../nodes/network-requester-setup.md)
* [Validators](../nodes/validator-setup.md)
+18 -10
View File
@@ -1,20 +1,20 @@
# Frequently Asked Questions
## Mixnet nodes
## Nym Nodes
### What determines the rewards when running a mix node?
### What determines the rewards when running a Mix Node?
The stake required for a mix node to achieve maximum rewards is called mix node saturation point. This is calculated from the staking supply (all circulating supply + part of unlocked tokens). The target level of staking is to have 50% of the staking supply locked in mix nodes.
The stake required for a Mix Node to achieve maximum rewards is called Mix Node saturation point. This is calculated from the staking supply (all circulating supply + part of unlocked tokens). The target level of staking is to have 50% of the staking supply locked in Mix Nodes.
The node stake saturation point, which we denote by Nsat, is given by the stake supply, target level of staking divided by the number of rewarded (active) nodes.
This design ensures the nodes aim to have a same size of stake (reputation) which can be done by delegation staking, as well as it ensures that there is a decentralization of staking as any higher level of staked tokens per node results in worse rewards. On the contrary, the more mix nodes are active, the lower is Nsat. The equilibrium is reached when the staked tokens are delegated equally across the active mix-nodes and that's our basis for this incentive system.
This design ensures the nodes aim to have a same size of stake (reputation) which can be done by delegation staking, as well as it ensures that there is a decentralization of staking as any higher level of staked tokens per node results in worse rewards. On the contrary, the more Mix Nodes are active, the lower is Nsat. The equilibrium is reached when the staked tokens are delegated equally across the active mix-nodes and that's our basis for this incentive system.
For more detailed calculation, read our blog post [Nym Token Economics update](https://blog.nymtech.net/nym-token-economics-update-fedff0ed5267). More info on staking can be found [here](https://blog.nymtech.net/staking-in-nym-introducing-mainnet-mixmining-f9bb1cbc7c36). And [here](https://blog.nymtech.net/want-to-stake-in-nym-here-is-how-to-choose-a-mix-node-to-delegate-nym-to-c3b862add165) is more info on how to choose a mix node for delegation. And finally an [update](https://blog.nymtech.net/quarterly-token-economic-parameter-update-b2862948710f) on token economics from July 2023.
For more detailed calculation, read our blog post [Nym Token Economics update](https://blog.nymtech.net/nym-token-economics-update-fedff0ed5267). More info on staking can be found [here](https://blog.nymtech.net/staking-in-nym-introducing-mainnet-mixmining-f9bb1cbc7c36). And [here](https://blog.nymtech.net/want-to-stake-in-nym-here-is-how-to-choose-a-mix-node-to-delegate-nym-to-c3b862add165) is more info on how to choose a Mix Node for delegation. And finally an [update](https://blog.nymtech.net/quarterly-token-economic-parameter-update-b2862948710f) on token economics from July 2023.
### Which VPS providers would you recommend?
Consider in which jurisdiction you reside and where do you want to run a mix node. Do you want to pay by crypto or not and what are the other important particularities for your case? We always recommend operators to try to choose smaller and decentralised VPS providers over the most known ones controlling a majority of the internet. We receive some good feedback on these: Linode, Ghandi, Flokinet and Exoscale. Do your own research and share with the community.
Consider in which jurisdiction you reside and where do you want to run a Mix Node. Do you want to pay by crypto or not and what are the other important particularities for your case? We always recommend operators to try to choose smaller and decentralised VPS providers over the most known ones controlling a majority of the internet. We receive some good feedback on these: Linode, Ghandi, Flokinet and Exoscale. Do your own research and share with the community.
<!---### Why is a mix node setup on a self-hosted machine so tricky?--->
@@ -22,17 +22,17 @@ Consider in which jurisdiction you reside and where do you want to run a mix nod
The sizes are shown in the configs [here](https://github.com/nymtech/nym/blob/1ba6444e722e7757f1175a296bed6e31e25b8db8/common/nymsphinx/params/src/packet_sizes.rs#L12) (default is the one clients use, the others are for research purposes, not to be used in production as this would fragment the anonymity set). More info can be found [here](https://github.com/nymtech/nym/blob/4844ac953a12b29fa27688609ec193f1d560c996/common/nymsphinx/anonymous-replies/src/reply_surb.rs#L80).
### Why a mix node and a gateway cannot be bond to the same wallet?
### Why a Mix Node and a Gateway cannot be bonded with the same wallet?
Because of the way the smart contract works we keep it one-node one-address at the moment.
### Which nodes are the most needed to be setup to strengthen Nym infrastructure and which ones bring rewards?
Right now only mix nodes are rewarded. We're working on gateway and service payments. Gateways are the weak link right now due mostly to lack of incentivisation. Services like Network Requesters are obviously the most necessary for people to start using the platform, and we're working on smart contracts to allow for people to start advertising them the same way they do mix nodes.
Right now only Mix Nodes are rewarded. We're working on Gateway and service payments. Gateways are the weak link right now due mostly to lack of incentivisation. Services like Network Requesters are obviously the most necessary for people to start using the platform, and we're working on smart contracts to allow for people to start advertising them the same way they do Mix Nodes.
### Are mixnodes whitelisted?
### Are Mix Nodes whitelisted?
Nope, anyone can run a mix node. Purely reliant on the node's reputation (self stake + delegations) & routing score.
Nope, anyone can run a Mix Node. Purely reliant on the node's reputation (self stake + delegations) & routing score.
## Validators and tokens
@@ -44,6 +44,14 @@ Nope, anyone can run a mix node. Purely reliant on the node's reputation (self s
### What's the difference between NYM and NYX?
--->
### Why some Nyx blockchain operations take one hour and others are instant?
This is based on the definition in [Nym's CosmWasm](https://github.com/nymtech/nym/tree/develop/common/cosmwasm-smart-contracts) smart contracts code.
Whatever is defined as [a pending epoch event](https://github.com/nymtech/nym/blob/b07627d57e075b6de35b4b1a84927578c3172811/common/cosmwasm-smart-contracts/mixnet-contract/src/pending_events.rs#L35-L103) will get resolved at the end of the current epoch.
And whatever is defined as [a pending interval event](https://github.com/nymtech/nym/blob/b07627d57e075b6de35b4b1a84927578c3172811/common/cosmwasm-smart-contracts/mixnet-contract/src/pending_events.rs#L145-L172) will get resolved at the end of the current interval.
### Can I run a validator?
We are currently working towards building up a closed set of reputable validators. You can ask us for coins to get in, but please don't be offended if we say no - validators are part of our system's core security and we are starting out with people we already know or who have a solid reputation.
+49 -20
View File
@@ -2,9 +2,10 @@
> We aim on purpose to make minimal changes to reward scheme and software. We're just 'smooshing' together stuff we already debugged and know works.
> -- Harry Halpin, Nym CEO
<p></p>
This page refer to the changes which are planned to take place over Q3 and Q4 2023. As this is a transition period in the beginning (Q3 2023) the [Mix Nodes FAQ page](./mixnodes-faq.md) holds more answers to the current setup as project Smoosh refers to the eventual setup. As project Smoosh gets progressively implemented the answers on this page will become to be more relevant to the current state and eventually this FAQ page will be merged with the still relevant parts of the main Mix Nodes FAQ page.
<br>
This page refer to the changes which are planned to take place over Q3 and Q4 2023. As this is a transition period in the beginning (Q3 2023) the [Mix Nodes FAQ page](mixnodes-faq.md) holds more answers to the current setup as project Smoosh refers to the eventual setup. As project Smoosh gets progressively implemented the answers on this page will become to be more relevant to the current state and eventually this FAQ page will be merged with the still relevant parts of the main Mix Nodes FAQ page.
If any questions are not answered or it's not clear for you in which stage project Smoosh is right now, please reach out in Node Operators [Matrix room](https://matrix.to/#/#operators:nymtech.chat).
@@ -14,67 +15,95 @@ If any questions are not answered or it's not clear for you in which stage proje
As we shared in our blog post article [*What does it take to build the wolds most powerful VPN*](https://blog.nymtech.net/what-does-it-take-to-build-the-worlds-most-powerful-vpn-d351a76ec4e6), project Smoosh is:
> A nick-name by CTO Dave Hrycyszyn and Chief Scientist Claudia Diaz for the work they are currently doing to “smoosh” Nym nodes so that the same operator can serve alternately as mix node, gateway or VPN node. This requires careful calibration of the Nym token economics, for example, only nodes with the highest reputation for good quality service will be in the VPN set and have the chance to earn higher rewards.
> A nick-name by CTO Dave Hrycyszyn and Chief Scientist Claudia Diaz for the work they are currently doing to “smoosh” Nym Nodes so that the same operator can serve alternately as Mix Node, Gateway or VPN node. This requires careful calibration of the Nym token economics, for example, only nodes with the highest reputation for good quality service will be in the VPN set and have the chance to earn higher rewards.
> By simplifying the components, adding VPN features and supporting new node operators, the aim is to widen the geographical coverage of nodes and have significant redundancy, meaning plenty of operators to be able to meet demand. This requires strong token economic incentives as well as training and support for new node operators.
## Technical Questions
### What are the changes?
Project smoosh will have three steps:
1. Combine the `gateway` and `network-requester`.
2. Combine all the nodes in the Nym Mixnet into one binary, that is `mixnode`, `gateway` (entry and exit) and `network-requester`.
3. Make a selection button (command/argument/flag) for operators to choose whether they want their node to provide all or just some of the functions nodes have in the Nym Mixnet. Not everyone will be able/want to run an exit `gateway` for example.
1. Combine the `nym-gateway` and `nym-network-requester` into one binary ✅
2. Create [Exit Gateway](../legal/exit-gateway.md): Take the `nym-gateway` binary including `nym-network-requester` combined in \#1 and switch from [`allowed.list`](https://nymtech.net/.wellknown/network-requester/standard-allowed-list.txt) to a new [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt) ✅
3. Combine all the nodes in the Nym Mixnet into one binary, that is `nym-mixnode`, `nym-gateway` (entry and exit) and `nym-network-requester`.
These three steps will be staggered over time - period of several months, and will be implemented one by one with enough time to take in feedback and fix bugs in between.
Generally, the software will be the same, just instead of multiple binaries, there will be one Nym Mixnet node binary. Delegations will remain on as they are now, per our token economics (staking, saturation etc)
### What does it mean for Nym nodes operators?
We are exploring two potential methods for implementing binary functionality in practice and will provide information in advance. The options are:
1. Make a selection button (command/argument/flag) for operators to choose whether they want their node to provide all or just some of the functions nodes have in the Nym Mixnet. Nodes functioning as Exit Gateways (in that epoch) will then have bigger rewards due to their larger risk exposure and overhead work with the setup.
2. All nodes will be required to have the Exit Gateway functionality. All nodes are rewarded the same as now, and the difference is that a node sometimes (some epochs) may be performing as Exit Gateway sometimes as Mix node or Entry Gateway adjusted according the network demand by an algorithm.
### Where can I read more about the Exit Gateway setup?
We created an [entire page](../legal/exit-gateway.md) about the technical and legal questions around Exit Gateway.
### What is the change from allow list to deny list?
The operators running `gateways` would have to “open” their nodes to a wider range of online services, in a similar fashion to Tor exit relays. The main change will be to expand the original short allow list to a more permissive setup. An exit policy will constrain the hosts that the users of the Nym VPN and Mixnet can connect to. This will be done in an effort to protect the operators, as Gateways will act both as SOCKS5 Network Requesters, and exit nodes for IP traffic from Nym VPN and Mixnet clients.
The operators running Gateways would have to “open” their nodes to a wider range of online services, in a similar fashion to Tor exit relays. The main change will be to expand the original short [`allowed.list`](https://nymtech.net/.wellknown/network-requester/standard-allowed-list.txt) to a more permissive setup. An [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt) will constrain the hosts that the users of the Nym VPN and Mixnet can connect to. This will be done in an effort to protect the operators, as Gateways will act both as SOCKS5 Network Requesters, and exit nodes for IP traffic from Nym VPN and Mixnet clients.
### Can I run a mix node only?
### How will the Exit policy be implemented?
Yes, to run a mix node only is an option. However it will be less rewarded as nodes providing option for `gateway` - meaning the *new smooshed gateway* (previously `gateway` and `network requester`) - due to the work and risk the operators have in comparison to running a `mixnode` only.
The progression of exit policy on Gateways will have three steps:
1. By default the [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt) filtering will be disabled and the current [`allowed.list`](https://nymtech.net/.wellknown/network-requester/standard-allowed-list.txt) filtering is going to continue be used. This is to prevent operators getting surprised by upgrading their Gateways (or Network Requesters) and suddenly be widely open to the internet. To enable the new exit policy, operators must use `--with-exit-policy` flag or modify the `config.toml` file. ✅
2. Relatively soon the exit policy will be part of the Gateway setup by default. To disable this exit policy, operators must use `--disable-exit-policy` flag.
3. Further down the line, it will be the only option. Then the `allowed.list` will be completely removed.
Keep in mind this only relates to changes happening on Gateway and Network Requester side. Whether this will be optional or mandatory depends on the chosen [design](./smoosh-faq.md#what-does-it-mean-for-nym-nodes-operators).
### Can I run a Mix Node only?
It depends which [design](./smoosh-faq.md#what-does-it-mean-for-nym-nodes-operators) will ultimately be used. In case of the first - yes. In case of the second option, all the nodes will be setup with Exit Gateway functionality turned on.
## Token Economics & Rewards
```admonish info
For any specifics on Nym token economics and Nym Mixnet reward system, please read the [Nym token economics paper](https://nymtech.net/nym-cryptoecon-paper.pdf).
```
### What are the incentives for the node operator?
In the original setup there were no incentives to run a `network-requester`. After the transition all the users will buy multiple tickets of zkNyms credentials and use those as [anonymous e-cash](https://arxiv.org/abs/2303.08221) to pay for their data traffic ([`Nym API`](https://github.com/nymtech/nym/tree/master/nym-api) will do the do cryptographical checks to prevent double-spending). All collected fees get distributed to all active nodes proportionally to their work by the end of each epoch.
In the original setup there were no incentives to run a `nym-network-requester` binary. After the transition all the users will buy multiple tickets of zkNyms credentials and use those as [anonymous e-cash](https://arxiv.org/abs/2303.08221) to pay for their data traffic ([`Nym API`](https://github.com/nymtech/nym/tree/master/nym-api) will do the do cryptographical checks to prevent double-spending). All collected fees get distributed to all active nodes proportionally to their work by the end of each epoch.
### How does this change the token economics?
The token economics will stay the same as they are, same goes for the reward algorithm. In practice the distribution of rewards will benefit more the operators who run open gateways.
The token economics will stay the same as they are, same goes for the reward algorithm.
### How are the rewards distributed?
As each operator can choose what roles their nodes provide, the nodes which work as open gateways will have higher rewards because they are the most important to keep up and stable. Besides that the operators of gateways may be exposed to more complication and possible legal risks.
This depends on [design](./smoosh-faq.md#what-does-it-mean-for-nym-nodes-operators) chosen. In case of \#1, it will look like this:
The nodes which are initialized to run as mix nodes and gateways will be chosen to be on top of the active set before the ones working only as a mix node.
As each operator can choose what roles their nodes provide, the nodes which work as open Gateways will have higher rewards because they are the most important to keep up and stable. Besides that the operators of Gateways may be exposed to more complication and possible legal risks.
We are considering to turn off the rewards for non-open gateways to incentivize operators to run the open ones. Mix nodes on 'standby' will not be rewarded (as they are not being used).
The nodes which are initialized to run as Mix Nodes and Gateways will be chosen to be on top of the active set before the ones working only as a Mix Node.
The more roles an operator will allow their node to provide the bigger reward ratio which will have huge performance benefits for the end-users.
I case we go with \#2, all nodes active in the epoch will be rewarded proportionally according their work.
In either way, Nym will share all the specifics beforehand.
### How will be the staking and inflation after project Smoosh?
We must run tests to see how many users pay. We may need to keep inflation on if not enough people pay to keep high quality gateways on in the early stage of the transition. That would mean keeping staking on for gateways. Staking will always be on for mix nodes.
Nym will run tests to count how much payment comes from the users of the Mixnet and if that covers the reward payments. If not, we may need to keep inflation on to secure incentives for high quality Gateways in the early stage of the transition.
### When project smooth will be launched, it would be the mixmining pool that will pay for the gateway rewards based on amount of traffic routed ?
### When project smooth will be launched, it would be the mixmining pool that will pay for the Gateway rewards based on amount of traffic routed ?
Yes, the same pool. Nym's aim is to do minimal modifications. The only real modification on the smart contract side will be to get into top X of 'active set' operators will need to have open gateway function enabled.
Yes, the same pool. Nym's aim is to do minimal modifications. The only real modification on the smart contract side will be to get into top X of 'active set' operators will need to have open Gateway function enabled.
### What does this mean for the current delegators?
From an operator standpoint, it shall just be a standard Nym upgrade, a new option to run the gateway software on your node. Delegators should not have to re-delegate.
From an operator standpoint, it shall just be a standard Nym upgrade, a new option to run the Gateway software on your node. Delegators should not have to re-delegate.
## Legal Questions
### Are there any legal concerns for the operators?
So far the general line is that running a gateway is not illegal (unless you are in Iran, China, and a few other places) and due to encryption/mixing less risky than running a normal VPN node. For mix nodes, it's very safe as they have "no idea" what packets they are mixing.
So far the general line is that running a Gateway is not illegal (unless you are in Iran, China, and a few other places) and due to encryption/mixing less risky than running a normal VPN node. For Mix Nodes, it's very safe as they have "no idea" what packets they are mixing.
There are several legal questions and analysis to be made for different jurisdictions. To be able to share resources and findings between the operators themselves we created a [Community Legal Forum](../legal/exit-gateway.md).

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