Compare commits

...

128 Commits

Author SHA1 Message Date
benedettadavico 6c5457468b Adding mixnode test 2023-11-20 07:41:25 +01:00
benedettadavico b615f5e75e Merge remote-tracking branch 'origin/develop' into benny/nym-api-tests-via-mixfetch 2023-11-20 06:48:51 +01:00
Bogdan-Ștefan Neacşu a5c1e4abf0 Expose the same pub key that's used for wg (#4157) 2023-11-17 13:04:22 +00:00
Jon Häggblad 3a1003c564 Create TaggedPacket (#4156)
* Create TaggedPacket

* Fix bug passing the correct data
2023-11-17 12:30:15 +01:00
Jon Häggblad 1cdd8f6c08 Rework error handling in tun device (#4146)
* Rework error handling in tun device

* Extract out timeout constants

* Experiment with timeouts

* Update error msg

* try_send in one direction as hotfix for deadlock

* Downgrade some log from info to debug

* Update comment

* rustfmt
2023-11-17 09:52:05 +01:00
Jon Häggblad 808e3f0562 Merge pull request #4154 from nymtech/jon/clippy
Fix clippy for latest rustc
2023-11-17 09:19:02 +01:00
Jon Häggblad f0dade3c5b Fix clippy in ephemera 2023-11-17 09:15:42 +01:00
Jon Häggblad 0a3c2b3cca Upgrade to safer-ffi 0.1.4 for clippy 2023-11-17 09:06:12 +01:00
Jon Häggblad ac66906980 IPR: add exit policy (#4127)
* Copy over request_filter

* Comment out stuff we don't need

* Delete unused allowed_hosts

* Delete unused code in request_filter

* Setup request filter

* Handle address checks

* rustfmt

* Tweak errors

* clippy

* allow dead code for non-linux

* inline log_msg

* Add ParsedPacket type
2023-11-16 14:13:13 +01:00
Gala afd9f823d8 Merge pull request #4151 from nymtech/feat/explorer-vpnsite-buttom
Feat/explorer vpnsite buttom
2023-11-16 13:08:06 +01:00
serinko d818448848 DOC: hotfix 2023-11-16 12:07:20 +00:00
Gala a9a1ba2847 please lint.. 2023-11-16 12:50:10 +01:00
Drazen Urch 2708c0ce10 Feature/deb package (#4153)
* Add debian scaffolding, allow specifying home_dir in env

* Run as nym user
2023-11-16 12:35:02 +01:00
Gala bb3e9b3d4e remove non used variable 2023-11-16 12:33:43 +01:00
Gala e624f42ad5 fixing build 2023-11-16 12:03:23 +01:00
mx 7da83397dd Merge pull request #4152 from nymtech/feature/docs/sort-info
DOCs: Operators - create tables to clarify Smoosh progress
2023-11-16 10:18:00 +00:00
serinko 26d0b4b159 create tables to clarify Smoosh progress 2023-11-16 11:12:40 +01:00
mx b74490dc50 Merge pull request #4150 from nymtech/feature/ts-sdk-fixes
adding SURBs info to mixfetch
2023-11-15 17:19:59 +00:00
Jędrzej Stuczyński 8113095ff5 remove needless borrow (#4149) 2023-11-15 16:34:32 +01:00
Gala 8339d6ab49 nymvpn link on footer 2023-11-15 16:20:14 +01:00
Gala f037b2ae68 adding nymvpn link to explorer 2023-11-15 15:58:31 +01:00
Zane Schepke 2a4c1d96a4 Update README.md 2023-11-15 09:37:21 -05:00
Lorexia ed04ddf1c4 adding SURBs info to mixfetch 2023-11-15 15:35:10 +01:00
Zane Schepke 34b5d66df6 Update README.md 2023-11-15 09:35:04 -05:00
Tommy Verrall 0a1a5c25f7 Merge pull request #4148 from nymtech/chore/add-update-cost-params
Add update cost params to the NYM-CLI
2023-11-15 13:58:07 +00:00
benedettadavico 4366aca21c Merge remote-tracking branch 'origin/develop' into benny/nym-api-tests-via-mixfetch 2023-11-15 14:00:26 +01:00
Jędrzej Stuczyński 6bdba7046f Bugfix/prerelease versionbump (#4145)
* prerelease updating rc suffix

* added post-run summary

* updated error message
2023-11-15 13:58:21 +01:00
Tommy Verrall 428d91a536 fmt 2023-11-15 12:37:01 +00:00
Tommy Verrall 88e0eaafcb update args to pass through correctly 2023-11-15 12:32:23 +00:00
Tommy Verrall dd19cabf15 adding the cost parameter update to the nym-cli 2023-11-15 12:30:02 +00:00
benedettadavico f9b8272691 Updating yarn install in root 2023-11-15 12:29:56 +01:00
benedettadavico ece15f7c7d Adding nym-node api test github action 2023-11-15 12:12:21 +01: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
benedettadavico 3762b4264c getting all the API tests to run through mixfetch 2023-11-14 15:36:03 +01:00
benedettadavico 1ba04a7eb1 Merge remote-tracking branch 'origin/develop' into benny/nym-api-tests-via-mixfetch 2023-11-14 15:29:09 +01: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
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
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
benedettadavico b14efb211c Getting all our nym-api tests to run via mixfetch 2023-11-10 17:43:44 +01: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
benedettadavico aabc4e41ba playing around 2023-11-09 12:37:18 +01:00
benedettadavico 8d9387d3ac Merge remote-tracking branch 'origin/develop' into feature/nym-node-api-tests 2023-11-09 11:22:22 +01:00
benedettadavico e8bc2c7a01 Merge remote-tracking branch 'origin/develop' into feature/nym-node-api-tests 2023-11-06 16:46:31 +01:00
benedettadavico 0486cd2e63 refactoring the utils 2023-10-24 11:16:06 +02:00
benedettadavico 604098844a node-api test updates 2023-10-23 10:59:03 +02:00
benedettadavico 65e35bd2b0 Initial step to adding nym-node functional tests 2023-10-19 12:52:46 +02:00
122 changed files with 6230 additions and 10387 deletions
+3
View File
@@ -24,6 +24,9 @@ jobs:
uses: actions/setup-node@v3
with:
node-version: 18.1.0
- name: Yarn install in root
run: cd ../../ && yarn install
- name: Install yarn
run: yarn install
@@ -0,0 +1,39 @@
name: ci-nym-node-api-tests
on:
workflow_dispatch:
push:
paths:
- "nym-node/**"
defaults:
run:
working-directory: nym-node/tests
jobs:
test:
name: nym-node tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install npm
run: npm install
- name: Node v18
uses: actions/setup-node@v3
with:
node-version: 18.1.0
- name: Yarn install in root
run: cd ../../ && yarn install
- name: Install yarn
run: yarn install
- name: Run yarn
run: yarn
- name: Run tests
run: yarn test:sandbox
working-directory: nym-node/tests
Generated
+14 -8
View File
@@ -2994,7 +2994,7 @@ dependencies = [
[[package]]
name = "extension-storage"
version = "1.2.4-rc.1"
version = "1.2.4-rc.2"
dependencies = [
"bip39",
"console_error_panic_hook",
@@ -5568,7 +5568,7 @@ dependencies = [
[[package]]
name = "mix-fetch-wasm"
version = "1.2.4-rc.1"
version = "1.2.4-rc.2"
dependencies = [
"async-trait",
"futures",
@@ -6270,7 +6270,7 @@ dependencies = [
[[package]]
name = "nym-client-wasm"
version = "1.2.4-rc.1"
version = "1.2.4-rc.2"
dependencies = [
"anyhow",
"futures",
@@ -6661,18 +6661,23 @@ dependencies = [
name = "nym-ip-packet-router"
version = "0.1.0"
dependencies = [
"bincode",
"bytes",
"etherparse",
"futures",
"log",
"nym-bin-common",
"nym-client-core",
"nym-config",
"nym-exit-policy",
"nym-network-requester",
"nym-sdk",
"nym-service-providers-common",
"nym-sphinx",
"nym-task",
"nym-wireguard",
"nym-wireguard-types",
"reqwest",
"serde",
"serde_json",
"tap",
@@ -6917,6 +6922,7 @@ dependencies = [
"nym-crypto",
"nym-node-requests",
"nym-task",
"nym-wireguard",
"nym-wireguard-types",
"rand 0.7.3",
"serde",
@@ -6972,7 +6978,7 @@ dependencies = [
[[package]]
name = "nym-node-tester-wasm"
version = "1.2.4-rc.1"
version = "1.2.4-rc.2"
dependencies = [
"futures",
"js-sys",
@@ -9439,9 +9445,9 @@ checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
[[package]]
name = "safer-ffi"
version = "0.1.3"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9c1d19b288ca9898cd421c7b105fb7269918a7f8e9253a991e228981ca421ad"
checksum = "395ace5aff9629c7268ca8255aceb945525b2cb644015f3caec5131a6a537c11"
dependencies = [
"inventory",
"libc",
@@ -9456,9 +9462,9 @@ dependencies = [
[[package]]
name = "safer_ffi-proc_macros"
version = "0.1.3"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2d7a04caa3ca2224f5ea4ddd850e2629c3b36b2b83621f87a8303bf41020110"
checksum = "9255504d5467bae9e07d58b8de446ba6739b29bf72e1fa35b2387e30d29dcbfe"
dependencies = [
"macro_rules_attribute",
"prettyplease",
+7 -1
View File
@@ -166,5 +166,11 @@ generate-typescript:
yarn types:lint:fix
run-api-tests:
cd nym-api/tests/functional_test && yarn test:qa
cd nym-api/tests && yarn test:sandbox
run-nym-node-tests:
cd nym-node/tests && yarn test:sandbox
run-all-api-tests:
cd nym-api/tests && yarn test:sandbox
cd nym-node/tests && yarn test:sandbox
@@ -15,4 +15,4 @@ prod:
mixnode_identity: 3pMCJswCyA19MGYWGDWT5fBk2M8ybSZGXttyAoNY5gBB
gateway_identity: 2BuMSfMW3zpeAjKXyKLhmY4QW1DXurrtSPEJ6CjX3SEh
log_level: error
time_zone: utc
time_zone: utc
@@ -1,18 +1,18 @@
import { readFileSync } from "fs";
import { TLogLevelName } from "tslog";
import YAML from "yaml";
import * as dotenv from 'dotenv';
import path from "path";
class ConfigHandler {
private static instance: ConfigHandler;
private validEnvironments = ["sandbox", "prod"];
private baseWorkingDirectory: string;
public commonConfig: { request_headers: object };
public environment: string;
public environmnetConfig: {
public environmentConfig: {
log_level: TLogLevelName;
time_zone: string;
api_base_url: string;
@@ -22,8 +22,21 @@ class ConfigHandler {
};
private constructor() {
this.baseWorkingDirectory = __dirname;
const environment = process.env.TEST_ENV || "sandbox" || "prod";
this.loadEnvironment(environment);
}
private loadEnvironment(environment: string): void {
this.loadEnvironmentVariables(environment);
this.setCommonConfig();
this.setEnvironmentConfig(process.env.TEST_ENV || "sandbox" || "prod");
this.setEnvironmentConfig(environment);
}
private loadEnvironmentVariables(environment: string): void {
const envFileName = `${environment}.env`;
const envFilePath = path.resolve(this.baseWorkingDirectory, `../${envFileName}`);
dotenv.config({ path: envFilePath });
}
public static getInstance(): ConfigHandler {
@@ -35,25 +48,27 @@ class ConfigHandler {
private setCommonConfig(): void {
try {
this.commonConfig = YAML.parse(
readFileSync("src/config/config.yaml", "utf8")
).common;
this.commonConfig = this.readConfigFile().common;
} catch (error) {
throw Error(`Error reading common config: (${error})`);
}
}
private setEnvironmentConfig(environment: string): void {
public setEnvironmentConfig(environment: string): void {
this.ensureEnvironmentIsValid(environment);
try {
this.environmnetConfig = YAML.parse(
readFileSync("src/config/config.yaml", "utf8")
)[environment];
this.environmentConfig = this.readConfigFile()[environment];
} catch (error) {
throw Error(`Error reading environment config: (${error})`);
}
}
private readConfigFile(): any {
return YAML.parse(
readFileSync(path.join(this.baseWorkingDirectory, "/config.yaml"), "utf8")
);
}
private ensureEnvironmentIsValid(environment: string): void {
if (this.validEnvironments.indexOf(environment) === -1) {
throw Error(`Config environment is not valid: "${environment}"`);
+4
View File
@@ -0,0 +1,4 @@
module.exports = {
ConfigHandler: require('./config/configHandler.ts'),
MixFetchClient: require('./restClient/MixFetchClient.ts')
};
@@ -0,0 +1,115 @@
import { createMixFetch } from "@nymproject/mix-fetch-node-commonjs";
import * as dotenv from 'dotenv';
import path from "path";
dotenv.config({ path: path.join(__dirname, '../.env') });;
export class MixFetchClient {
public static authToken: string;
private baseUrl: string;
constructor(baseUrl: string) {
this.baseUrl = baseUrl;
}
public async sendGet({
route,
}: any): Promise<any> {
const extra = {
hiddenGateways: [
{
owner: process.env.HIDDEN_GATEWAY_OWNER,
host: process.env.HIDDEN_GATEWAY_HOST,
explicitIp: process.env.HIDDEN_GATEWAY_EXPLICIT_IP,
identityKey: process.env.HIDDEN_GATEWAY_IDENTITY_KEY,
sphinxKey: process.env.HIDDEN_GATEWAY_SPHINX_KEY,
},
],
};
const mixFetchOptions = {
nymApiUrl: process.env.PREFERRED_VALIDATOR,
preferredGateway: process.env.PREFERRED_GATEWAY,
preferredNetworkRequester: process.env.PREFFERED_NETWORK_REQUESTER,
mixFetchOverride: {
requestTimeoutMs: 60_000,
},
forceTls: true,
extra,
};
const { mixFetch } = await createMixFetch(mixFetchOptions);
let args = {
method: "GET",
headers: {
"Content-Type": "application/json",
},
mode: "unsafe-ignore-cors"
};
try {
const response = await mixFetch(`${this.baseUrl}${route}`, args);
if (response.status == 200) {
const json = await response.json();
return json;
}
}
catch (error) {
console.log(error);
throw error;
}
};
public async sendPost({
route,
data,
}: any): Promise<any> {
const extra = {
hiddenGateways: [
{
owner: process.env.HIDDEN_GATEWAY_OWNER,
host: process.env.HIDDEN_GATEWAY_HOST,
explicitIp: process.env.HIDDEN_GATEWAY_EXPLICIT_IP,
identityKey: process.env.HIDDEN_GATEWAY_IDENTITY_KEY,
sphinxKey: process.env.HIDDEN_GATEWAY_SPHINX_KEY,
},
],
};
const mixFetchOptions = {
nymApiUrl: process.env.PREFERRED_VALIDATOR,
preferredGateway: process.env.PREFERRED_GATEWAY,
preferredNetworkRequester: process.env.PREFFERED_NETWORK_REQUESTER,
mixFetchOverride: {
requestTimeoutMs: 60_000,
},
forceTls: true,
extra,
};
const { mixFetch } = await createMixFetch(mixFetchOptions);
let args = {
method: "POST",
headers: {
"accept": "application/json",
"Content-Type": "application/json"
},
mode: "unsafe-ignore-cors",
body: JSON.stringify(data),
};
try {
const response = await mixFetch(`${this.baseUrl}${route}`, args);
if (response.status == 200) {
const json = await response.json();
return json;
}
}
catch (error) {
console.log(error);
throw error;
}
}
}
+8
View File
@@ -0,0 +1,8 @@
HIDDEN_GATEWAY_OWNER=n1ns3v70ul9gnl9l9fkyz8cyxfq75vjcmx8el0t3
HIDDEN_GATEWAY_EXPLICIT_IP=35.158.238.80
HIDDEN_GATEWAY_HOST=sandbox-gateway1.nymtech.net
HIDDEN_GATEWAY_SPHINX_KEY=BoXeUD7ERGmzRauMjJD3itVNnQiH42ncUb6kcVLrb3dy
HIDDEN_GATEWAY_IDENTITY_KEY=HjNEDJuotWV8VD4ufeA1jeheTnfNJ7Jorevp57hgaZua
PREFFERED_NETWORK_REQUESTER="AzGdJ4MU78Ex22NEWfeycbN7bt3PFZr1MtKstAdhfELG.GSxnKnvKPjjQm3FdtsgG5KyhP6adGbPHRmFWDH4XfUpP@HjNEDJuotWV8VD4ufeA1jeheTnfNJ7Jorevp57hgaZua"
PREFERRED_GATEWAY=HjNEDJuotWV8VD4ufeA1jeheTnfNJ7Jorevp57hgaZua
PREFERRED_VALIDATOR=https://sandbox-nym-api1.nymtech.net/api
@@ -4,6 +4,7 @@
use clap::{Args, Subcommand};
pub mod update_config;
pub mod update_cost_params;
pub mod vesting_update_config;
#[derive(Debug, Args)]
@@ -20,7 +21,5 @@ pub enum MixnetOperatorsMixnodeSettingsCommands {
/// Update mixnode configuration for a mixnode bonded with locked tokens
VestingUpdateConfig(vesting_update_config::Args),
/// Update mixnode cost parameters
UpdateCostParameters,
/// Update mixnode cost parameters for a mixnode bonded with locked tokens
VestingUpdateCostParameters,
UpdateCostParameters(update_cost_params::Args),
}
@@ -0,0 +1,48 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::context::SigningClient;
use clap::Parser;
use cosmwasm_std::Uint128;
use log::info;
use nym_mixnet_contract_common::{MixNodeCostParams, Percent};
use nym_validator_client::nyxd::contract_traits::MixnetSigningClient;
use nym_validator_client::nyxd::CosmWasmCoin;
#[derive(Debug, Parser)]
pub struct Args {
#[clap(
long,
help = "input your profit margin as follows; (so it would be 10, rather than 0.1)"
)]
pub profit_margin_percent: Option<u8>,
#[clap(
long,
help = "operating cost in current DENOMINATION (so it would be 'unym', rather than 'nym')"
)]
pub interval_operating_cost: Option<u128>,
}
pub async fn update_cost_params(args: Args, client: SigningClient) {
let denom = client.current_chain_details().mix_denom.base.as_str();
let cost_params = MixNodeCostParams {
profit_margin_percent: Percent::from_percentage_value(
args.profit_margin_percent.unwrap_or(10) as u64,
)
.unwrap(),
interval_operating_cost: CosmWasmCoin {
denom: denom.into(),
amount: Uint128::new(args.interval_operating_cost.unwrap_or(40_000_000)),
},
};
info!("Starting mixnode params updating!");
let res = client
.update_mixnode_cost_params(cost_params, None)
.await
.expect("failed to update cost params");
info!("Cost params result: {:?}", res)
}
+10 -2
View File
@@ -25,12 +25,20 @@ pub const DEFAULT_CONFIG_FILENAME: &str = "config.toml";
#[cfg(feature = "dirs")]
pub fn must_get_home() -> PathBuf {
dirs::home_dir().expect("Failed to evaluate $HOME value")
if let Some(home_dir) = std::env::var_os("NYM_HOME_DIR") {
home_dir.into()
} else {
dirs::home_dir().expect("Failed to evaluate $HOME value")
}
}
#[cfg(feature = "dirs")]
pub fn may_get_home() -> Option<PathBuf> {
dirs::home_dir()
if let Some(home_dir) = std::env::var_os("NYM_HOME_DIR") {
Some(home_dir.into())
} else {
dirs::home_dir()
}
}
pub trait NymConfigTemplate: Serialize {
+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())
}
}
+1 -1
View File
@@ -10,7 +10,7 @@ mod network_table;
mod packet_relayer;
mod platform;
mod registered_peers;
mod setup;
pub mod setup;
pub mod tun_task_channel;
mod udp_listener;
mod wg_tunnel;
+100 -55
View File
@@ -2,21 +2,64 @@ 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,
tun_task_channel::{
tun_task_channel, tun_task_response_channel, TunTaskPayload, TunTaskResponseRx,
TunTaskResponseTx, TunTaskRx, TunTaskTx,
TunTaskResponseSendError, TunTaskResponseTx, TunTaskRx, TunTaskTx,
},
udp_listener::PeersByIp,
};
const MUTEX_LOCK_TIMEOUT_MS: u64 = 200;
const TUN_WRITE_TIMEOUT_MS: u64 = 1000;
#[derive(thiserror::Error, Debug)]
pub enum TunDeviceError {
#[error("timeout writing to tun device, dropping packet")]
TunWriteTimeout,
#[error("error writing to tun device: {source}")]
TunWriteError { source: std::io::Error },
#[error("failed forwarding packet to peer: {source}")]
ForwardToPeerFailed {
#[from]
source: PeerEventSenderError,
},
#[error("failed to forward responding packet with tag: {source}")]
ForwardNatResponseFailed {
#[from]
source: TunTaskResponseSendError,
},
#[error("unable to parse 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.
@@ -74,6 +117,17 @@ 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(MUTEX_LOCK_TIMEOUT_MS),
self.peers_by_ip.as_ref().lock(),
)
.await
.map_err(|_| TunDeviceError::FailedToLockPeer)
}
}
pub struct NatInner {
nat_table: HashMap<IpAddr, u64>,
}
@@ -114,17 +168,13 @@ impl TunDevice {
}
// Send outbound packets out on the wild internet
async fn handle_tun_write(&mut self, data: TunTaskPayload) {
async fn handle_tun_write(&mut self, data: TunTaskPayload) -> Result<(), TunDeviceError> {
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!(
let dst_addr = boringtun::noise::Tunn::dst_address(&packet)
.ok_or_else(|| TunDeviceError::UnableToParseDstAdddress)?;
let src_addr = parse_src_address(&packet)?;
log::debug!(
"iface: write Packet({src_addr} -> {dst_addr}, {} bytes)",
packet.len()
);
@@ -134,26 +184,21 @@ impl TunDevice {
nat_table.nat_table.insert(src_addr, tag);
}
self.tun
.write_all(&packet)
.await
.tap_err(|err| {
log::error!("iface: write error: {err}");
})
.ok();
timeout(
Duration::from_millis(TUN_WRITE_TIMEOUT_MS),
self.tun.write_all(&packet),
)
.await
.map_err(|_| TunDeviceError::TunWriteTimeout)?
.map_err(|err| TunDeviceError::TunWriteError { source: err })
}
// Receive reponse packets from the wild internet
async fn handle_tun_read(&self, packet: &[u8]) {
let Some(dst_addr) = boringtun::noise::Tunn::dst_address(packet) else {
log::error!("Unable to parse dst_address in packet that was read from tun device");
return;
};
let Some(src_addr) = parse_src_address(packet) else {
log::error!("Unable to parse src_address in packet that was read from tun device");
return;
};
log::info!(
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::debug!(
"iface: read Packet({src_addr} -> {dst_addr}, {} bytes)",
packet.len(),
);
@@ -163,33 +208,30 @@ impl TunDevice {
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.peers_by_ip.as_ref().lock().await;
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");
peer_tx
log::debug!("Forward packet to wg tunnel");
return peer_tx
.send(Event::Ip(packet.to_vec().into()))
.await
.tap_err(|err| log::error!("{err}"))
.ok();
return;
.map_err(|err| err.into());
}
}
// But we can also do it by consulting the NAT table.
RoutingMode::Nat(ref nat_table) => {
if let Some(tag) = nat_table.nat_table.get(&dst_addr) {
log::info!("Forward packet with tag: {tag}");
self.tun_task_response_tx
.send((*tag, packet.to_vec()))
.await
.tap_err(|err| log::error!("{err}"))
.ok();
return;
log::debug!("Forward packet with NAT tag: {tag}");
return self
.tun_task_response_tx
.try_send((*tag, packet.to_vec()))
.map_err(|err| err.into());
}
}
}
log::info!("No peer found, packet dropped");
Ok(())
}
pub async fn run(mut self) {
@@ -201,20 +243,24 @@ impl TunDevice {
len = self.tun.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;
if let Err(err) = self.handle_tun_write(data).await {
log::error!("ifcae: handle_tun_write failed: {err}");
}
}
}
}
log::info!("TUN device shutting down");
// log::info!("TUN device shutting down");
}
pub fn start(self) {
@@ -222,12 +268,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),
}
}
+40 -12
View File
@@ -1,4 +1,9 @@
use tokio::sync::mpsc;
use std::time::Duration;
use tokio::sync::mpsc::{
self,
error::{SendError, SendTimeoutError, TrySendError},
};
pub(crate) type TunTaskPayload = (u64, Vec<u8>);
@@ -7,12 +12,13 @@ pub struct TunTaskTx(mpsc::Sender<TunTaskPayload>);
pub(crate) struct TunTaskRx(mpsc::Receiver<TunTaskPayload>);
impl TunTaskTx {
pub async fn send(
&self,
data: TunTaskPayload,
) -> Result<(), tokio::sync::mpsc::error::SendError<TunTaskPayload>> {
pub async fn send(&self, data: TunTaskPayload) -> Result<(), SendError<TunTaskPayload>> {
self.0.send(data).await
}
pub fn try_send(&self, data: TunTaskPayload) -> Result<(), TrySendError<TunTaskPayload>> {
self.0.try_send(data)
}
}
impl TunTaskRx {
@@ -22,20 +28,42 @@ impl TunTaskRx {
}
pub(crate) fn tun_task_channel() -> (TunTaskTx, TunTaskRx) {
let (tun_task_tx, tun_task_rx) = tokio::sync::mpsc::channel(16);
let (tun_task_tx, tun_task_rx) = tokio::sync::mpsc::channel(128);
(TunTaskTx(tun_task_tx), TunTaskRx(tun_task_rx))
}
const TUN_TASK_RESPONSE_SEND_TIMEOUT_MS: u64 = 1_000;
// Send responses back from the tun device back to the PacketRelayer
pub(crate) struct TunTaskResponseTx(mpsc::Sender<TunTaskPayload>);
pub struct TunTaskResponseRx(mpsc::Receiver<TunTaskPayload>);
#[derive(thiserror::Error, Debug)]
pub enum TunTaskResponseSendError {
#[error("failed to send tun response: {0}")]
SendTimeoutError(#[from] SendTimeoutError<TunTaskPayload>),
#[error("failed to send tun response: {0}")]
SendError(#[from] SendError<TunTaskPayload>),
#[error("failed to send tun response: {0}")]
TrySendError(#[from] TrySendError<TunTaskPayload>),
}
impl TunTaskResponseTx {
pub(crate) async fn send(
&self,
data: TunTaskPayload,
) -> Result<(), tokio::sync::mpsc::error::SendError<TunTaskPayload>> {
self.0.send(data).await
#[allow(unused)]
pub(crate) async fn send(&self, data: TunTaskPayload) -> Result<(), TunTaskResponseSendError> {
Ok(self
.0
.send_timeout(
data,
Duration::from_millis(TUN_TASK_RESPONSE_SEND_TIMEOUT_MS),
)
.await?)
}
pub(crate) fn try_send(&self, data: TunTaskPayload) -> Result<(), TunTaskResponseSendError> {
Ok(self.0.try_send(data)?)
}
}
@@ -46,7 +74,7 @@ impl TunTaskResponseRx {
}
pub(crate) fn tun_task_response_channel() -> (TunTaskResponseTx, TunTaskResponseRx) {
let (tun_task_tx, tun_task_rx) = tokio::sync::mpsc::channel(16);
let (tun_task_tx, tun_task_rx) = tokio::sync::mpsc::channel(128);
(
TunTaskResponseTx(tun_task_tx),
TunTaskResponseRx(tun_task_rx),
+2
View File
@@ -21,6 +21,8 @@
- [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
Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

@@ -10,3 +10,6 @@ We expect to see the following for submissions:
- 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,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)
@@ -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.
+4 -4
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:**
+1 -1
View File
@@ -5,7 +5,7 @@
# Binaries
- [Pre-built Binaries](binaries/pre-built-binaries.md)
- [Binary Initialisation and Configuration](binaries/init-and-config.md)
<!-- - [Binary Initialisation and Configuration](binaries/init-and-config.md) -->
- [Building from Source](binaries/building-nym.md)
<!-- - [Version Compatibility Table](binaries/version-compatiblity.md) -->
@@ -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.
+32 -26
View File
@@ -4,7 +4,8 @@
> -- Harry Halpin, Nym CEO
<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.
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,33 +15,36 @@ 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:
Project Smoosh will have four steps, please follow the table below to track the dynamic progress:
1. Combine the `gateway` and `network-requester` into one binary ✅
2. Create [Exit Gateway](../legal/exit-gateway.md): Take the gateway binary including 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 `mixnode`, `gateway` (entry and exit) and `network-requester`.
| **Step** | **Status** |
| :--- | :--- |
| **1.** Combine the `nym-gateway` and `nym-network-requester` into one binary | ✅ done |
| **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) | ✅ done |
| **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`. | 🛠️ in progress |
| **4.** Adjust reward scheme to incentivise and reward Exit Gateways as a part of `nym-node` binary, implementing [zkNym credentials](https://youtu.be/nLmdsZ1BsQg?t=1717). | 🛠️ in progress |
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)
These 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 Node (`nym-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.
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.
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?
### 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.
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?
@@ -48,15 +52,17 @@ The operators running Gateways would have to “open” their nodes to a wider r
### How will the Exit policy be implemented?
The progression of exit policy on Gateways will have three steps:
Follow the dynamic progress of exit policy implementation on Gateways below:
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.
| **Step** | **Status** |
| :--- | :--- |
| **1.** By default the [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt) filtering is disabled and the [`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. | ✅ done |
| **2.** The exit policy is part of the Gateway setup by default. To disable this exit policy, operators must use `--disable-exit-policy` flag. | 🛠️ in progress |
| **3.** The exit policy is the only option. The `allowed.list` is completely removed. | 🛠️ in progress |
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).
Keep in mind the table above only relates to changes happening on Gateways. For the Project Smoosh progress refer to the [table above](./smoosh-faq.md#what-are-the-changes). Whether Exit Gateway functionality will be optional or mandatory part of every active Nym Node depends on the chosen [design](./smoosh-faq.md#what-does-it-mean-for-nym-nodes-operators).
### Can I run a mix node only?
### 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.
@@ -68,7 +74,7 @@ For any specifics on Nym token economics and Nym Mixnet reward system, please re
### 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?
@@ -78,9 +84,9 @@ The token economics will stay the same as they are, same goes for the reward alg
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:
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.
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.
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 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.
I case we go with \#2, all nodes active in the epoch will be rewarded proportionally according their work.
@@ -88,21 +94,21 @@ In either way, Nym will share all the specifics beforehand.
### How will be the staking and inflation after project Smoosh?
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.
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).
+10 -11
View File
@@ -1,6 +1,6 @@
# Introduction
This is Nym's Operators guide, containing information and setup guides for the various pieces of Nym mixnet infrastructure (mix node, gateway and network requester) and Nyx blockchain validators.
This is Nym's Operators guide, containing information and setup guides for the various pieces of Nym Mixnet infrastructure (Mix Node, Gateway and Network Requester) and Nyx blockchain validators.
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/).
@@ -9,18 +9,17 @@ If you want to dive deeper into Nym's architecture, clients, nodes, and SDK exam
## Popular pages
**Binary Information**
* [Building Nym](./binaries/building-nym.md)
* [Pre-built Binaries](./binaries/pre-built-binaries.md)
* [Init & Configuration](./binaries/init-and-config.md)
* [Building Nym](binaries/building-nym.md)
* [Pre-built Binaries](binaries/pre-built-binaries.md)
**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)
* [Mix nodes](nodes/mix-node-setup.md)
* [Gateways](nodes/gateway-setup.md)
* [Network requesters](nodes/network-requester-setup.md)
* [Validators](nodes/validator-setup.md)
**Maintenance, troubleshooting and FAQ**
* [Maintenance](./nodes/maintenance.md)
* [Troubleshooting](./nodes/troubleshooting.md)
* [FAQ](./faq/mixnodes-faq.md)
* [Maintenance](nodes/maintenance.md)
* [Troubleshooting](nodes/troubleshooting.md)
* [FAQ](faq/mixnodes-faq.md)
@@ -8,7 +8,7 @@ This page is a part of Nym Community Legal Forum and its content is composed by
This document presents an initiative to further support Nyms mission of allowing privacy for everyone everywhere. This would be achieved with the support of Nym node operators operating Gateways and opening these to any online service. Such setup needs a **clear policy**, one which will remain the **same for all operators** running Nym nodes. The [proposed **Exit policy**](https://nymtech.net/.wellknown/network-requester/exit-policy.txt) is a combination of two existing safeguards: [Tor Null deny list](https://tornull.org/) and [Tor reduced policy](https://tornull.org/tor-reduced-reduced-exit-policy.php).
All the technical changes on the side of Nym nodes - ***Project Smoosh** - are described in the [FAQ section](../faq/smoosh-faq.md).
All the technical changes on the side of Nym nodes - ***Project Smoosh*** - are described in the [FAQ section](../faq/smoosh-faq.md).
```admonish warning
Nym core team cannot provide comprehensive legal advice across all jurisdictions. Knowledge and experience with the legalities are being built up with the help of our counsel and with you, the community of Nym node operators. We encourage Nym node operators to join the operator channels ([Element](https://matrix.to/#/#operators:nymtech.chat), [Discord](https://discord.com/invite/nym), [Telegram](https://t.me/nymchan_help_chat)) to share best practices and experiences.
@@ -17,13 +17,13 @@ Nym core team cannot provide comprehensive legal advice across all jurisdictions
## Summary
* This document outlines a plan to change Nym Gateways from operating with an allow to a deny list to enable broader uptake and usage of the Nym mixnet. It provides operators with an overview of the plan, pros and cons, legal as well as technical advice.
* This document outlines a plan to change Nym Gateways from operating with an allow to a deny list to enable broader uptake and usage of the Nym Mixnet. It provides operators with an overview of the plan, pros and cons, legal as well as technical advice.
* Nym is committed to ensuring privacy for all users, regardless of their location and for the broadest possible range of online services. In order to achieve this aim, the Nym mixnet needs to increase its usability across a broad range of apps and services.
* Nym is committed to ensuring privacy for all users, regardless of their location and for the broadest possible range of online services. In order to achieve this aim, the Nym Mixnet needs to increase its usability across a broad range of apps and services.
* Currently, Nym Gateway nodes only enable access to apps and services that are on an allow list that is maintained by the core team.
* To decentralise and enable privacy for a broader range of services, this initiative will have to transition from the current allow list to a deny list - [Exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt). In accordance with the [Tor Null 'deny' list](https://tornull.org/) and [Tor reduced policy](https://tornull.org/tor-reduced-reduced-exit-policy.php), which are two established safeguards.
* To decentralise and enable privacy for a broader range of services, this initiative will have to transition from the current allow list to a deny list - [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt). In accordance with the [Tor Null 'deny' list](https://tornull.org/) and [Tor reduced policy](https://tornull.org/tor-reduced-reduced-exit-policy.php), which are two established safeguards.
* This will enhance the usage and appeal of Nym products for end users. As a result, increased usage will ultimately lead to higher revenues for Nym operators.
@@ -40,7 +40,7 @@ Nym core team cannot provide comprehensive legal advice across all jurisdictions
To offer a better and more private everyday experience for its users, Nym would like them to use any online services they please, without limiting its access to a few messaging apps or crypto wallets.
To achieve this, operators running exit gateways would have to “open” their nodes to a wider range of online services, in a similar fashion to Tor exit relays following this [Exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt).
To achieve this, operators running Exit Gateways would have to “open” their nodes to a wider range of online services, in a similar fashion to Tor exit relays following this [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt).
## Pros and cons of the initiative
@@ -64,23 +64,23 @@ The new setup: Running nodes supporting traffic of any online service (with safe
| Operational | | - Higher operational overhead, such as dealing with DMCA / abuse complaints, managing the VPS provider questions, or helping the community to maintain the denylist <br>- Administrative overhead if running nodes as a company or an entity |
| Legal | | - Ideally requires to check legal environment with local privacy association or lawyer | Financial | - Higher revenue potential for operators due to the increase in network usage | - If not running VPS with an unlimited bandwidth plan, higher costs due to higher network usage |
## Exit gateways: New setup
## Exit Gateways: New setup
In our previous technical setup, network requesters acted as a proxy, and only made requests that match an allow list. That was a default IP based list of allowed domains stored at Nym page in a centralised fashion possibly re-defined by any Network requester operator.
In our previous technical setup, Network Requesters acted as a proxy, and only made requests that match an allow list. That was a default IP based list of allowed domains stored at Nym page in a centralised fashion possibly re-defined by any Network Requester operator.
This restricts the hosts that the NymConnect app can connect to and has the effect of selectively supporting messaging services (e.g. Telegram, Matrix) or crypto wallets (e.g. Electrum or Monero). Operators of network requesters can have confidence that the infrastructure they run only connects to a limited set of public internet hosts.
This restricts the hosts that the NymConnect app can connect to and has the effect of selectively supporting messaging services (e.g. Telegram, Matrix) or crypto wallets (e.g. Electrum or Monero). Operators of Network Requesters can have confidence that the infrastructure they run only connects to a limited set of public internet hosts.
The principal change in the new configuration is to make this short allow list more permissive. Nym's [Exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt) will restrict the hosts to which Nym Mixnet and Nym VPN users are permitted to connect. 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 Mixnet VPN and VPN clients (both wrapped in the same app).
The principal change in the new configuration is to make this short allow list more permissive. Nym's [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt) will restrict the hosts to which Nym Mixnet and Nym VPN users are permitted to connect. 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 Mixnet VPN and VPN clients (both wrapped in the same app).
As of now we the gateways will be defaulted to a combination of [Tor Null deny list](https://tornull.org/) (note: Not affiliated with Tor) - reproduction permitted under Creative Commons Attribution 3.0 United States License which is IP-based, e.g., `ExitPolicy reject 5.188.10.0/23:*` and [Tor reduced policy](https://tornull.org/tor-reduced-reduced-exit-policy.php). Whether we will stick with this list, do modifications or compile another one is still a subject of discussion. In all cases, this policy will remain the same for all the nodes, without any option to modify it by Nym node operators to secure stable and reliable service for the end users.
As of now we the Gateways will be defaulted to a combination of [Tor Null deny list](https://tornull.org/) (note: Not affiliated with Tor) - reproduction permitted under Creative Commons Attribution 3.0 United States License which is IP-based, e.g., `ExitPolicy reject 5.188.10.0/23:*` and [Tor reduced policy](https://tornull.org/tor-reduced-reduced-exit-policy.php). Whether we will stick with this list, do modifications or compile another one is still a subject of discussion. In all cases, this policy will remain the same for all the nodes, without any option to modify it by Nym node operators to secure stable and reliable service for the end users.
For exit relays on ports 80 and 443, the gateways will exhibit an HTML page resembling the one proposed by [Tor](https://gitlab.torproject.org/tpo/core/tor/-/raw/HEAD/contrib/operator-tools/tor-exit-notice.html). By doing so, the operator will be able to disclose details regarding their gateway, including the currently configured exit policy, all without the need for direct correspondence with regulatory or law enforcement agencies. It also makes the behaviour of exit gateways transparent and even computable (a possible feature would be to offer a machine readable form of the notice in JSON or YAML).
For exit relays on ports 80 and 443, the Gateways will exhibit an HTML page resembling the one proposed by [Tor](https://gitlab.torproject.org/tpo/core/tor/-/raw/HEAD/contrib/operator-tools/tor-exit-notice.html). By doing so, the operator will be able to disclose details regarding their Gateway, including the currently configured exit policy, all without the need for direct correspondence with regulatory or law enforcement agencies. It also makes the behavior of Exit Gateways transparent and even computable (a possible feature would be to offer a machine readable form of the notice in JSON or YAML).
We also recommend operators to check the technical advice from [Tor](https://community.torproject.org/relay/setup/exit/).
## Tor legal advice
Giving the legal similarity between Nym exit gateways and Tor exit relays, it is helpful to have a look in [Tor community Exit Guidelines](https://community.torproject.org/relay/community-resources/tor-exit-guidelines/). This chapter is an exert of tor page.
Giving the legal similarity between Nym Exit Gateways and Tor Exit Relays, it is helpful to have a look in [Tor community Exit Guidelines](https://community.torproject.org/relay/community-resources/tor-exit-guidelines/). This chapter is an exert of tor page.
Note that Tor states:
> This FAQ is for informational purposes only and does not constitute legal advice.
@@ -88,7 +88,7 @@ Note that Tor states:
*Check legal advice prior to running an exit relay*
* Understand the risks associated with running an exit relay; E.g., know legal paragraphs relevant in the country of operations:
- US [DMCA 512](https://www.law.cornell.edu/uscode/text/17/512); see [EFF's Legal FAQ for TOr Operators](https://community.torproject.org/relay/community-resources/eff-tor-legal-faq) (a very good and relevant read for other countries as well)
- US [DMCA 512](https://www.law.cornell.edu/uscode/text/17/512); see [EFF's Legal FAQ for Tor Operators](https://community.torproject.org/relay/community-resources/eff-tor-legal-faq) (a very good and relevant read for other countries as well)
- Germanys [TeleMedienGesetz 8](http://www.gesetze-im-internet.de/tmg/__8.html) and [15](http://www.gesetze-im-internet.de/tmg/__15.html)
- Netherlands: [Artikel 6:196c BW](http://wetten.overheid.nl/BWBR0005289/Boek6/Titel3/Afdeling4A/Artikel196c/)
- Austria: [E-Commerce-Gesetz 13](http://www.ris.bka.gv.at/Dokument.wxe?Abfrage=Bundesnormen&Dokumentnummer=NOR40025809)
@@ -96,7 +96,7 @@ Note that Tor states:
* Top 3 advice
- Have an abuse response letter
- Run relay from a location that is not home
- Read through the legal resources that Tor-supportive lawyers put together: https://www.eff.org/pages/legal-faq-tor-relay-operators or https://www.noisebridge.net/wiki/Noisebridge_Tor/FBI
- Read through the legal resources that Tor-supportive lawyers put together: [www.eff.org/pages/legal-faq-tor-relay-operators](https://www.eff.org/pages/legal-faq-tor-relay-operators) or [www.noisebridge.net/wiki/Noisebridge_Tor/FBI](https://www.noisebridge.net/wiki/Noisebridge_Tor/FBI)
* Consult a lawyer / local digital rights association / the EFF prior to operating an exit relay, especially in a place where exit relay operators have been harassed or not operating before. Note that Tor DOES NOT provide legal advice for specific countries. It only provides general advice (itself or in partnership), eventually skewed towards [US audiences](https://www.eff.org/pages/legal-faq-tor-relay-operators).
@@ -16,7 +16,7 @@ As a result of [Project Smoosh](../faq/smoosh-faq.md), the current version of `n
## Preliminary steps
Make sure you do the preparation listed in the [preliminary steps page](../preliminary-steps.md) before setting up your gateway.
Make sure you do the preparation listed in the [preliminary steps page](../preliminary-steps.md) before setting up your Gateway.
## Gateway setup
@@ -50,7 +50,7 @@ You can also check the various arguments required for individual commands with:
## Initialising your Gateway
As Nym developers build towards [Exit Gateway](../legal/exit-gateway.md) functionality, operators can now run their `nym-gateway` binary with in-build Network requester and include the our new [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt). Considering the plan to [*smoosh*](../faq/smoosh-faq.md) all the nodes into one binary and have wide opened Exit Gateways, we recommend this setup, instead of operating two separate binaries.
As Nym developers build towards [Exit Gateway](../legal/exit-gateway.md) functionality, operators can now run their `nym-gateway` binary with inbuilt Network Requester and include the our new [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt). Considering the plan to [*smoosh*](../faq/smoosh-faq.md) all the nodes into one binary and have wide opened Exit Gateways, we recommend this setup, instead of operating two separate binaries.
```admonish warning
Before you start an Exit Gateway, read our [Operators Legal Forum](../legal/exit-gateway.md) page and [*Project Smoosh FAQ*](../faq/smoosh-faq.md).
@@ -60,19 +60,21 @@ Before you start an Exit Gateway, read our [Operators Legal Forum](../legal/exit
There has been an ongoing development with dynamic upgrades. Follow the status of the Project Smoosh [changes](../faq/smoosh-faq.md#what-are-the-changes) and the progression state of exit policy [implementation](../faq/smoosh-faq.html#how-will-the-exit-policy-be-implemented) to be up to date with the current design.
```
**Note:** Due to the development towards Exit Gateway functionality the `--host` flag has been replaced with `--listening-address`, this is the IP address which is used for receiving sphinx packets and listening to client data. Another flag `--public-ips` is required; its a comma separated list of IPs that are announced to the `nym-api`, it is usually the address which is used for bonding.
### Initialising Exit Gateway
An operator can initialise the Exit Gateway functionality by adding Network requester with the new exit policy option:
An operator can initialise the Exit Gateway functionality by adding Network Requester with the new exit policy option:
```
./nym-gateway init --id <ID> --host $(curl -4 https://ifconfig.me) --with-network-requester --with-exit-policy true
./nym-gateway init --id <ID> --listening-address 0.0.0.0 --public-ips "$(curl -4 https://ifconfig.me)" --with-network-requester --with-exit-policy true
```
If we follow the previous example with `<ID>` chosen `superexitgateway`, adding the `--with-network-requester` and `--with-exit-policy` flags, the outcome will be:
~~~admonish example collapsible=true title="Console output"
```
<!-- cmdrun ../../../../target/release/nym-gateway init --id superexitgateway --host $(curl -4 https://ifconfig.me) --with-network-requester --with-exit-policy true -->
<!-- cmdrun ../../../../target/release/nym-gateway init --id superexitgateway --listening-address 0.0.0.0 --public-ips "$(curl -4 https://ifconfig.me)" --with-network-requester --with-exit-policy true -->
```
~~~
@@ -80,9 +82,9 @@ You can see that the printed information besides *identity* and *sphinx keys* al
Additionally
#### Add Network requester to an existing Gateway
#### Add Network Requester to an existing Gateway
If you already [upgraded](./maintenance.md#upgrading-your-node) your Gateway to the [latest version](./gateway-setup.md#current-version) and initialised without a Network requester, you can easily change its functionality to Exit Gateway with a command `setup-network-requester`.
If you already [upgraded](./maintenance.md#upgrading-your-node) your Gateway to the [latest version](./gateway-setup.md#current-version) and initialised without a Network Requester, you can easily change its functionality to Exit Gateway with a command `setup-network-requester`.
See the options:
@@ -102,7 +104,7 @@ To setup Exit Gateway functionality with our new [exit policy](https://nymtech.n
./nym-gateway setup-network-requester --enabled true --with-exit-policy true --id <ID>
```
Say we have a gateway with `<ID>` as `new-gateway`, originally initialised and ran without the Exit Gateway functionality. To change the setup, run:
Say we have a Gateway with `<ID>` as `new-gateway`, originally initialised and ran without the Exit Gateway functionality. To change the setup, run:
```
@@ -112,7 +114,7 @@ Say we have a gateway with `<ID>` as `new-gateway`, originally initialised and r
~~~admonish example collapsible=true title="Console output"
```
<!-- cmdrun rm -rf $HOME/.nym/gateways/new-gateway -->
<!-- cmdrun ../../../../target/release/nym-gateway init --id new-gateway --host $(curl -4 https://ifconfig.me) && ../../../../target/release/nym-gateway setup-network-requester --enabled true --with-exit-policy true --id new-gateway -->
<!-- cmdrun ../../../../target/release/nym-gateway init --id new-gateway --listening-address 0.0.0.0 --public-ips "$(curl -4 https://ifconfig.me)" && ../../../../target/release/nym-gateway setup-network-requester --enabled true --with-exit-policy true --id new-gateway -->
```
~~~
@@ -120,13 +122,13 @@ In case there are any unexpected problems, you can also change it manually by ed
```
[network_requester]
# Specifies whether network requester service is enabled in this process.
# Specifies whether Network Requester service is enabled in this process.
enabled = true
```
Save, exit and restart your gateway. Now you are an operator of post-smooshed Exit gateway.
Save, exit and restart your Gateway. Now you are an operator of post-smooshed Exit Gateway.
#### Enable Nym exit policy to an existing Gateway with Network requester functionality
#### Enable Nym exit policy to an existing Gateway with Network Requester functionality
In case you already added Network Requester functionality to your Gateway as described above but haven't enabled the [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt) there is an easy tweak to do so and turn your node into [Nym Exit Gateway](../faq/smoosh-faq.md#what-are-the-changes).
@@ -134,18 +136,18 @@ Open the config file stored at `.nym/gateways/<ID>/config/network_requester_conf
```sh
use_deprecated_allow_list = false
```
Save, exit and restart your gateway. Now you are an operator of post-smooshed Exit gateway.
Save, exit and restart your Gateway. Now you are an operator of post-smooshed Exit gateway.
```admonish info
All information about network requester part of your Exit Gateway is in `/home/user/.nym/gateways/<ID>/config/network_requester_config.toml`.
All information about Network Requester part of your Exit Gateway is in `/home/user/.nym/gateways/<ID>/config/network_requester_config.toml`.
```
For now you can run Gateway without Network requester or with and without the new exit policy. This will soon change as we inform in our [Project Smoosh FAQ](../faq/smoosh-faq.html#how-will-the-exit-policy-be-implemented).
For now you can run Gateway without Network Requester or with and without the new exit policy. This will soon change as we inform in our [Project Smoosh FAQ](../faq/smoosh-faq.html#how-will-the-exit-policy-be-implemented).
To read more about the configuration like whitelisted outbound requesters in `allowed.list` and other useful information, see the page [*Network requester whitelist*](network-requester-setup.md#using-your-network-requester).
To read more about the configuration like whitelisted outbound requesters in `allowed.list` and other useful information, see the page [*Network Requester whitelist*](network-requester-setup.md#using-your-network-requester).
#### Initialising Gateway without Network requester
#### Initialising Gateway without Network Requester
In case you don't want to run your Gateway with the Exit Gateway functionality, you still can run a simple Gateway.
@@ -161,42 +163,50 @@ To check available configuration options use:
```
~~~
The following command returns a gateway on your current IP with the `<ID>` of `simple-gateway`:
The following command returns a Gateway on your current IP with the `<ID>` of `simple-gateway`:
```
./nym-gateway init --id simple-gateway --host $(curl -4 https://ifconfig.me)
./nym-gateway init --id simple-gateway --listening-address 0.0.0.0 --public-ips "$(curl -4 https://ifconfig.me)"
```
~~~admonish example collapsible=true title="Console output"
```
<!-- cmdrun ../../../../target/release/nym-gateway init --id simple-gateway --host $(curl -4 https://ifconfig.me) -->
<!-- cmdrun ../../../../target/release/nym-gateway init --id simple-gateway --listening-address 0.0.0.0 --public-ips "$(curl -4 https://ifconfig.me)" -->
```
~~~
The `$(curl -4 https://ifconfig.me)` command above returns your IP automatically using an external service. Alternatively, you can enter your IP manually if you wish. If you do this, remember to enter your IP **without** any port information.
## Running your Gateway
### Bonding your gateway
The `run` command starts the Gateway:
```admonish info
Before you bond and re-run your Gateway, please make sure the [firewall configuration](./maintenance.md#configure-your-firewall) is setup so your gateway can be reached from the outside. You can also setup WSS on your Gateway, the steps are on the [Maintenance page](./maintenance.md#configure-your-firewall) below.
```
./nym-gateway run --id <ID>
```
#### Via the Desktop wallet
You can bond your gateway via the Desktop wallet.
## Bonding your Gateway
```admonish info
Before you bond your Gateway, please make sure the [firewall configuration](./maintenance.md#configure-your-firewall) is setup so your Gateway can be reached from the outside. You can also setup [WSS on your Gateway](./maintenance.md#run-web-secure-socket-wss-on-gateway) and [automate](./maintenance.md#vps-setup-and-automation) your Gateway to simplify the operation overhead. We highly recommend to run ny of these steps before bonding to prevent disruption of your Gateway's routing score later on.
```
### Via the Desktop wallet (recommended)
You can bond your Gateway via the Desktop wallet. Make sure your Gateway is running and follow the steps below:
1. Open your wallet, and head to the `Bonding` page, then select the node type `Gateway` and input your node details. Press `Next`.
2. Enter the `Amount`, `Operating cost` and press `Next`.
3. You will be asked to run a the `sign` command with your `gateway` - copy and paste the long signature as the value of `--contract-msg` and run it.
3. You will be asked to run a the `sign` command with your `gateway` - copy and paste the long signature `<PAYLOAD_GENERATED_BY_THE_WALLET>` and paste it as a value of `--contract-msg` in the following command:
```
./nym-gateway sign --id <YOUR_ID> --contract-msg <PAYLOAD_GENERATED_BY_THE_WALLET>
```
It will look something like this:
It will look something like this (as `<YOUR_ID>` we used `supergateway`):
~~~admonish example collapsible=true title="Console output"
```
@@ -209,40 +219,38 @@ It will look something like this:
|_| |_|\__, |_| |_| |_|
|___/
(nym-gateway - version v1.1.31)
(nym-gateway - version v1.1.<XX>)
>>> attempting to sign 2Mf8xYytgEeyJke9LA7TjhHoGQWNBEfgHZtTyy2krFJfGHSiqy7FLgTnauSkQepCZTqKN5Yfi34JQCuog9k6FGA2EjsdpNGAWHZiuUGDipyJ6UksNKRxnFKhYW7ri4MRduyZwbR98y5fQMLAwHne1Tjm9cXYCn8McfigNt77WAYwBk5bRRKmC34BJMmWcAxphcLES2v9RdSR68tkHSpy2C8STfdmAQs3tZg8bJS5Qa8pQdqx14TnfQAPLk3QYCynfUJvgcQTrg29aqCasceGRpKdQ3Tbn81MLXAGAs7JLBbiMEAhCezAr2kEN8kET1q54zXtKz6znTPgeTZoSbP8rzf4k2JKHZYWrHYF9JriXepuZTnyxAKAxvGFPBk8Z6KAQi33NRQkwd7MPyttatHna6kG9x7knffV6ebGzgRBf7NV27LurH8x4L1uUXwm1v1UYCA1WSBQ9Pp2JW69k5v5v7G9gBy8RUcZnMbeL26Qqb8WkuGcmuHhaFfoqSfV7PRHPpPT4M8uRqUyR4bjUtSJJM1yh6QSeZk9BEazzoJqPeYeGoiFDZ3LMj2jesbJweQR4caaYuRczK92UGSSqu9zBKmE45a
>>> decoding the message...
>>> message to sign: {"nonce":0,"algorithm":"ed25519","message_type":"gateway-bonding","content":{"sender":"n1ewmme88q22l8syvgshqma02jv0vqrug9zq9dy8","proxy":null,"funds":[{"denom":"unym","amount":"100000000"}],"data":{"gateway":{"host":"62.240.134.189","mix_port":1789,"clients_port":9000,"location":"62.240.134.189","sphinx_key":"FKbuN7mPdoCG9jA3CkAfXxC5X4rHhqeMVtmfRtJ3cFZd","identity_key":"3RoAhR8gEdfBETMjm2vbMFzKddxXDdE9ygBAnJHWqSzD","version":"1.1.13"}}}}
>>> The base58-encoded signature is:
2SPDjLjX4b6XEtkgG7yD8Znsb1xycL1edFvRK4JcVnPsM9k6HXEUUeVS6rswRiYxoj1bMgiRKyPDwiksiuyxu8Xi
```
~~~
* Copy the resulting signature:
```
>>> The base58-encoded signature is:
```sh
# >>> The base58-encoded signature is:
2SPDjLjX4b6XEtkgG7yD8Znsb1xycL1edFvRK4JcVnPsM9k6HXEUUeVS6rswRiYxoj1bMgiRKyPDwiksiuyxu8Xi
```
* And paste it into the wallet nodal, press `Next` and confirm the transaction.
![Paste Signature](../images/wallet-screenshots/wallet-gateway-sign.png)
![Paste Signature](../images/wallet-screenshots/wallet-gateway-sign.png)
*This image is just an example, copy-paste your own base58-encoded signature*
* Your gateway is now bonded.
* Your Gateway is now bonded.
> You are asked to `sign` a transaction on bonding so that the Mixnet smart contract is able to map your Nym address to your node. This allows us to create a nonce for each account and defend against replay attacks.
#### Via the CLI (power users)
If you want to bond your mix node via the CLI, then check out the [relevant section in the Nym CLI](https://nymtech.net/docs/tools/nym-cli.html#bond-a-mix-node) docs.
### Via the CLI (power users)
### Running your gateway
The `run` command starts the gateway:
If you want to bond your Gateway via the CLI, then check out the [relevant section in the Nym CLI](https://nymtech.net/docs/tools/nym-cli.html#bond-a-mix-node) docs.
```
./nym-gateway run --id <ID>
```
## Maintenance
For gateway upgrade, firewall setup, port configuration, API endpoints, VPS suggestions, automation and more, see the [maintenance page](./maintenance.md)
For Gateway upgrade, firewall setup, port configuration, API endpoints, VPS suggestions, automation, WSS setup and more, see the [maintenance page](./maintenance.md)
@@ -16,27 +16,38 @@ For example `./target/debug/nym-network-requester --no-banner build-info --outpu
## Upgrading your node
> The process is the similar for mix node, gateway and network requester. In the following steps we use a placeholder `<NODE>` in the commands, please change it for the type of node you want to upgrade. Any particularities for the given type of node are included.
> The process is the similar for Mix Node, Gateway and Network Requester. In the following steps we use a placeholder `<NODE>` in the commands, please change it for the type of node you want to upgrade. Any particularities for the given type of node are included.
Upgrading your node is a two-step process:
* Updating the binary and `~/.nym/<NODE>/<YOUR_ID>/config/config.toml` on your VPS
* Updating the node information in the [mixnet smart contract](https://nymtech.net/docs/nyx/mixnet-contract.html). **This is the information that is present on the [mixnet explorer](https://explorer.nymtech.net)**.
### Step 1: Upgrading your binary
Follow these steps to upgrade your mix node binary and update its config file:
* pause your mix node process.
* replace the existing binary with the newest binary (which you can either [compile yourself](https://nymtech.net/docs/binaries/building-nym.html) or grab from our [releases page](https://github.com/nymtech/nym/releases)).
* re-run `init` with the same values as you used initially. **This will just update the config file, it will not overwrite existing keys**.
* restart your mix node process with the new binary.
Follow these steps to upgrade your Node binary and update its config file:
* Pause your node process.
- if you see the terminal window with your node, press `ctrl + c`
- if you run it as `systemd` service, run: `systemctl stop nym-<NODE>.service`
* Replace the existing `<NODE>` binary with the newest binary (which you can either [compile yourself](https://nymtech.net/docs/binaries/building-nym.html) or grab from our [releases page](https://github.com/nymtech/nym/releases)).
* Re-run `init` with the same values as you used initially for your `<NODE>` ([Mix Node](./mix-node-setup.md#initialising-your-mix-node), [Gateway](./gateway-setup.md#initialising-your-gateway)) . **This will just update the config file, it will not overwrite existing keys**.
* Restart your node process with the new binary:
- if your node is not automitized, just `run` your `<NODE>` with `./nym-<NODE> run --id <ID>`. Here are exact guidelines for [Mix Node](./mix-node-setup.md#running-your-mix-node) and [Gateway](./gateway-setup.md#running-your-gateway).
- if you automatized your node via systemd (recommended) run:
```sh
systemctl daemon-reload # to pickup the new unit file
systemctl start nym-<NODE>.service
journalctl -f -u <NODE>.service # to monitor log of you node
```
> In case of a network requester this is all all, the following step is only for mix nodes and gateways.
If these steps are too difficult and you prefer to just run a script, you can use [ExploreNYM script](https://github.com/ExploreNYM/bash-tool) or one done by [Nym developers](https://gist.github.com/tommyv1987/4dca7cc175b70742c9ecb3d072eb8539).
> In case of a Network Requester this is all, the following step is only for Mix Nodes and Gateways.
### Step 2: Updating your node information in the smart contract
Follow these steps to update the information about your `<NODE>` which is publicly available from the [Nym API](https://validator.nymtech.net/api/swagger/index.html) and information displayed on the [mixnet explorer](https://explorer.nymtech.net).
Follow these steps to update the information about your `<NODE>` which is publicly available from the [`nym-api`](https://validator.nymtech.net/api/swagger/index.html) and information displayed on the [Mixnet explorer](https://explorer.nymtech.net).
You can either do this graphically via the Desktop Wallet, or the CLI.
### Updating node information via the Desktop Wallet
### Updating node information via the Desktop Wallet (recommended)
* Navigate to the `Bonding` page and click the `Node Settings` link in the top right corner:
![Bonding page](../images/wallet-screenshots/bonding.png)
@@ -53,9 +64,9 @@ If you want to bond your `<NODE>` via the CLI, then check out the [relevant sect
In the previous version of the network-requester, users were required to run a nym-client along side it to function. As of `v1.1.10`, the network-requester now has a nym client embedded into the binary, so it can run standalone.
If you are running an existing network requester registered with nym-connect, upgrading requires you move your old keys over to the new network requester configuration. We suggest following these instructions carefully to ensure a smooth transition.
If you are running an existing Network Requester registered with nym-connect, upgrading requires you move your old keys over to the new Network Requester configuration. We suggest following these instructions carefully to ensure a smooth transition.
Initiate the new network requester:
Initiate the new Network Requester:
```sh
nym-network-requester init --id <YOUR_ID>
@@ -184,13 +195,13 @@ exit 0
```
Although your gateway is Now ready to use its `wss_port`, your server may not be ready - the following commands will allow you to set up a properly configured firewall using `ufw`:
Although your Gateway is Now ready to use its `wss_port`, your server may not be ready - the following commands will allow you to set up a properly configured firewall using `ufw`:
```sh
ufw allow 9001/tcp
```
Lastly don't forget to restart your Gateway, now the API will render the WSS details for this gateway:
Lastly don't forget to restart your Gateway, now the API will render the WSS details for this Gateway:
### WSS on a new Gateway
@@ -203,7 +214,7 @@ Another flag `--public-ips` is required; it's a comma separated list of IPs t
If the operator wishes to run WSS, an optional `--hostname` flag is also required, that can be something like `mainnet-gateway2.nymtech.net`. Make sure to enable all necessary [ports](maintenance.md#configure-your-firewall) on the Gateway.
The gateway will then be accessible on something like: *http://85.159.211.99:8080/api/v1/swagger/index.html*
The Gateway will then be accessible on something like: *http://85.159.211.99:8080/api/v1/swagger/index.html*
Are you seeing something like: *this node attempted to announce an invalid public address: 0.0.0.0.*?
@@ -236,7 +247,7 @@ sudo ufw status
Finally open your `<NODE>` p2p port, as well as ports for ssh and ports for verloc and measurement pings:
```sh
# for mix node, gateway and network requester
# for Mix Node, Gateway and Network Requester
sudo ufw allow 1789,1790,8000,9000,9001,22/tcp
# In case of reverse proxy for the Gateway swagger page add:
@@ -257,7 +268,7 @@ For more information about your node's port configuration, check the [port refer
### Automating your node with nohup, tmux and systemd
Although its not totally necessary, it's useful to have the mix node automatically start at system boot time.
Although its not totally necessary, it's useful to have the Mix Node automatically start at system boot time.
#### nohup
@@ -287,7 +298,7 @@ In case it didn't work for your distribution, see how to build `tmux` from [vers
**Running tmux**
No when you installed tmux on your VPS, let's run a mix node on tmux, which allows you to detach your terminal and let your `<NODE>` run on its own on the VPS.
No when you installed tmux on your VPS, let's run a Mix Node on tmux, which allows you to detach your terminal and let your `<NODE>` run on its own on the VPS.
* Pause your `<NODE>`
* Start tmux with the command
@@ -310,7 +321,7 @@ tmux attach-session
Here's a systemd service file to do that:
##### For mix node
##### For Mix Node
```ini
[Unit]
@@ -354,7 +365,7 @@ WantedBy=multi-user.target
* Put the above file onto your system at `/etc/systemd/system/nym-gateway.service`.
##### For Network requester
##### For Network Requester
```ini
[Unit]
@@ -433,20 +444,20 @@ systemctl daemon-reload # to pickup the new unit file
```
```sh
# for mix node
# for Mix Node
systemctl enable nym-mixnode.service
# for gateway
# for Gateway
systemctl enable nym-gateway.service
```
Start your node:
```sh
# for mix node
# for Mix Node
service nym-mixnode start
# for gateway
# for Gateway
service nym-gateway start
```
@@ -477,7 +488,7 @@ This lets your operating system know it's ok to reload the service configuration
Linux machines limit how many open files a user is allowed to have. This is called a `ulimit`.
`ulimit` is 1024 by default on most systems. It needs to be set higher, because mix nodes make and receive a lot of connections to other nodes.
`ulimit` is 1024 by default on most systems. It needs to be set higher, because Mix Nodes make and receive a lot of connections to other nodes.
If you see errors such as:
@@ -491,12 +502,12 @@ This means that the operating system is preventing network connections from bein
> Replace `<NODE>` variable with `nym-mixnode`, `nym-gateway` or `nym-network-requester` according the node you running on your machine.
The ulimit setup is relevant for maintenance of nym mix node only.
The ulimit setup is relevant for maintenance of Nym Mix Node only.
Query the `ulimit` of your `<NODE>` with:
```sh
# for nym-mixnode, nym-gateway and nym-network requester:
# for nym-mixnode, nym-gateway and nym-network-requester:
grep -i "open files" /proc/$(ps -A -o pid,cmd|grep <NODE> | grep -v grep |head -n 1 | awk '{print $1}')/limits
# for nyx validator:
@@ -533,7 +544,7 @@ echo "DefaultLimitNOFILE=65535" >> /etc/systemd/system.conf
Reboot your machine and restart your node. When it comes back, use:
```sh
# for nym-mixnode, nym-gateway and nym-network requester:
# for nym-mixnode, nym-gateway and nym-network-requester:
cat /proc/$(pidof <NODE>)/limits | grep "Max open files"
# for validator
@@ -543,7 +554,7 @@ Make sure the limit has changed to 65535.
#### Set the ulimit on `non-systemd` based distributions
In case you chose tmux option for mix node automatization, see your `ulimit` list by running:
In case you chose tmux option for Mix Node automation, see your `ulimit` list by running:
```sh
ulimit -a
@@ -568,13 +579,13 @@ username hard nofile 4096
username soft nofile 4096
```
Then reboot your server and restart your mix node.
Then reboot your server and restart your Mix Node.
## Moving a node
In case of a need to move a node from one machine to another and avoiding to lose the delegation, here are few steps how to do it.
The following examples transfers a mix node (in case of other nodes, change the `mixnodes` in the command for the `<NODE>` of your desire.
The following examples transfers a Mix Node (in case of other nodes, change the `mixnodes` in the command for the `<NODE>` of your desire.
* Pause your node process.
@@ -587,7 +598,7 @@ Assuming both machines are remote VPS.
# in case none of the nym configs was created previously
mkdir ~/.nym
#in case no nym mix node was initialized previously
#in case no nym Mix Node was initialized previously
mkdir ~/.nym/mixnodes
```
* Move the node data (keys) and config file to the new machine by opening a local terminal (as that one's ssh key is authorized in both of the machines) and running:
@@ -614,29 +625,29 @@ ens4: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1460
The `ens4` interface has the IP `10.126.5.7`. But this isn't the public IP of the machine, it's the IP of the machine on Google's internal network. Google uses virtual routing, so the public IP of this machine is something else, maybe `36.68.243.18`.
`./nym-mixnode init --host 10.126.5.7`, initalises the mix node, but no packets will be routed because `10.126.5.7` is not on the public internet.
`./nym-mixnode init --host 10.126.5.7`, initalises the Mix Node, but no packets will be routed because `10.126.5.7` is not on the public internet.
Trying `nym-mixnode init --host 36.68.243.18`, you'll get back a startup error saying `AddrNotAvailable`. This is because the mix node doesn't know how to bind to a host that's not in the output of `ifconfig`.
Trying `nym-mixnode init --host 36.68.243.18`, you'll get back a startup error saying `AddrNotAvailable`. This is because the Mix Node doesn't know how to bind to a host that's not in the output of `ifconfig`.
The right thing to do in this situation is to init with a command:
```sh
./nym-mixnode init --host 10.126.5.7 --announce-host 36.68.243.18
```
This will bind the mix node to the available host `10.126.5.7`, but announce the mix node's public IP to the directory server as `36.68.243.18`. It's up to you as a node operator to ensure that your public and private IPs match up properly.
This will bind the Mix Node to the available host `10.126.5.7`, but announce the Mix Node's public IP to the directory server as `36.68.243.18`. It's up to you as a node operator to ensure that your public and private IPs match up properly.
To find the right IP configuration, contact your VPS provider for support.
## Nym API (previously 'Validator API') endpoints
Numerous API endpoints are documented on the Nym API (previously 'Validator API')'s [Swagger Documentation](https://validator.nymtech.net/api/swagger/index.html). There you can also try out various requests from your browser, and download the response from the API. Swagger will also show you what commands it is running, so that you can run these from an app or from your CLI if you prefer.
### Mix node Reward Estimation API endpoint
### Mix Node Reward Estimation API endpoint
The Reward Estimation API endpoint allows mix node operators to estimate the rewards they could earn for running a Nym mix node with a specific `MIX_ID`.
The Reward Estimation API endpoint allows Mix Node operators to estimate the rewards they could earn for running a Nym Mix Node with a specific `MIX_ID`.
> The `<MIX_ID>` can be found in the "Mix ID" column of the [Network Explorer](https://explorer.nymtech.net/network-components/mixnodes/active).
The endpoint is a particularly common for mix node operators as it can provide an estimate of potential earnings based on factors such as the amount of traffic routed through the mix node, the quality of the mix node's performance, and the overall demand for mixnodes in the network. This information can be useful for mix node operators in deciding whether or not to run a mix node and in optimizing its operations for maximum profitability.
The endpoint is a particularly common for Mix Node operators as it can provide an estimate of potential earnings based on factors such as the amount of traffic routed through the Mix Node, the quality of the Mix Node's performance, and the overall demand for Mix Nodes in the network. This information can be useful for Mix Node operators in deciding whether or not to run a Mix Node and in optimizing its operations for maximum profitability.
Using this API endpoint returns information about the Reward Estimation:
@@ -657,15 +668,15 @@ Query Response:
> The unit of value is measured in `uNYM`.
- `estimated_total_node_reward` - An estimate of the total amount of rewards that a particular mix node can expect to receive during the current epoch. This value is calculated by the Nym Validator based on a number of factors, including the current state of the network, the number of mix nodes currently active in the network, and the amount of network traffic being processed by the mix node.
- `estimated_total_node_reward` - An estimate of the total amount of rewards that a particular Mix Node can expect to receive during the current epoch. This value is calculated by the Nym Validator based on a number of factors, including the current state of the network, the number of Mix Nodes currently active in the network, and the amount of network traffic being processed by the Mix Node.
- `estimated_operator_reward` - An estimate of the amount of rewards that a particular mix node operator can expect to receive. This value is calculated by the Nym Validator based on a number of factors, including the amount of traffic being processed by the mix node, the quality of service provided by the mix node, and the operator's stake in the network.
- `estimated_operator_reward` - An estimate of the amount of rewards that a particular Mix Node operator can expect to receive. This value is calculated by the Nym Validator based on a number of factors, including the amount of traffic being processed by the Mix Node, the quality of service provided by the Mix Node, and the operator's stake in the network.
- `estimated_delegators_reward` - An estimate of the amount of rewards that mix node delegators can expect to receive individually. This value is calculated by the Nym Validator based on a number of factors, including the amount of traffic being processed by the mix node, the quality of service provided by the mix node, and the delegator's stake in the network.
- `estimated_delegators_reward` - An estimate of the amount of rewards that Mix Node delegators can expect to receive individually. This value is calculated by the Nym Validator based on a number of factors, including the amount of traffic being processed by the Mix Node, the quality of service provided by the Mix Node, and the delegator's stake in the network.
- `estimated_node_profit` - An estimate of the profit that a particular mix node operator can expect to earn. This value is calculated by subtracting the mix node operator's `operating_costs` from their `estimated_operator_reward` for the current epoch.
- `estimated_node_profit` - An estimate of the profit that a particular Mix node operator can expect to earn. This value is calculated by subtracting the Mix Node operator's `operating_costs` from their `estimated_operator_reward` for the current epoch.
- `estimated_operator_cost` - An estimate of the total cost that a particular mix node operator can expect to incur for their participation. This value is calculated by the Nym Validator based on a number of factors, including the cost of running a mix node, such as server hosting fees, and other expenses associated with operating the mix node.
- `estimated_operator_cost` - An estimate of the total cost that a particular Mix Node operator can expect to incur for their participation. This value is calculated by the Nym Validator based on a number of factors, including the cost of running a Mix Node, such as server hosting fees, and other expenses associated with operating the Mix Node.
### Validator: Installing and configuring nginx for HTTPS
#### Setup
@@ -785,7 +796,7 @@ go_memstats_gc_sys_bytes 1.3884192e+07
## Ports
All `<NODE>`-specific port configuration can be found in `$HOME/.nym/<NODE>/<YOUR_ID>/config/config.toml`. If you do edit any port configs, remember to restart your client and node processes.
### Mix node port reference
### Mix Node port reference
| Default port | Use |
| ------------ | ------------------------- |
| `1789` | Listen for Mixnet traffic |
@@ -800,7 +811,7 @@ All `<NODE>`-specific port configuration can be found in `$HOME/.nym/<NODE>/<YOU
| `9000` | Listen for Client traffic |
| `9001` | WSS |
### Network requester port reference
### Network Requester port reference
| Default port | Use |
|--------------|---------------------------|
@@ -1,6 +1,6 @@
# Mix Nodes
> The Nym mix node binary was built in the [building nym](../binaries/building-nym.md) section. If you haven't yet built Nym and want to run the code, go there first.
> The Nym Mix Node binary was built in the [building nym](../binaries/building-nym.md) section. If you haven't yet built Nym and want to run the code, go there first.
> Any syntax in `<>` brackets is a user's unique variable. Exchange with a corresponding name without the `<>` brackets.
@@ -13,11 +13,11 @@ The `nym-mix node` binary is currently one point version ahead of the rest of th
## Preliminary steps
Make sure you do the preparation listed in the [preliminary steps page](../preliminary-steps.md) before setting up your mix node.
Make sure you do the preparation listed in the [preliminary steps page](../preliminary-steps.md) before setting up your Mix Node.
## Mix node setup
Now that you have built the [codebase](../binaries/building-nym.md), set up your [wallet](https://nymtech.net/docs/wallet/desktop-wallet.html), and have a VPS with the `nym-mix node` binary, you can set up your mix node with the instructions below.
Now that you have built the [codebase](../binaries/building-nym.md), set up your [wallet](https://nymtech.net/docs/wallet/desktop-wallet.html), and have a VPS with the `nym-mix node` binary, you can set up your Mix Node with the instructions below.
To begin, move to `/target/release` directory from which you run the node commands:
@@ -49,7 +49,7 @@ You can also check the various arguments required for individual commands with:
> Adding `--no-banner` startup flag will prevent Nym banner being printed even if run in tty environment.
### Initialising your mix node
### Initialising your Mix Node
To check available configuration options for initializing your node use:
@@ -59,125 +59,30 @@ To check available configuration options for initializing your node use:
~~~admonish example collapsible=true title="Console output"
```
<!-- cmdrun ../../../../target/release/nym-mixnode init --help -->
<!-- cmdrun ../../../../target/release/nym-mixnode init --help -->
```
~~~
Initalise your mix node with the following command, replacing the value of `--id` with the moniker you wish to give your mix node. Your `--host` must be publicly routable on the internet in order to mix packets, and can be either an Ipv4 or IPv6 address. The `$(curl -4 https://ifconfig.me)` command returns your IP automatically using an external service. If you enter your IP address manually, enter it **without** any port information.
Initialise your Mix Node with the following command, replacing the value of `--id` with the moniker you wish to give your Mix Node. Your `--host` must be publicly routable on the internet in order to mix packets, and can be either an Ipv4 or IPv6 address. The `$(curl -4 https://ifconfig.me)` command returns your IP automatically using an external service. If you enter your IP address manually, enter it **without** any port information.
```
./nym-mixnode init --id <NODE_NAME> --host $(curl -4 https://ifconfig.me)
./nym-mixnode init --id <YOUR_ID> --host $(curl -4 https://ifconfig.me)
```
If `<YOUR_ID>` was `my-node`, the output shall look like like this:
<!---serinko: The automatized command did not work, printing the output manually--->
~~~admonish example collapsible=true title="Console output"
```
.nym-mixnode init --id <YOUR_ID> --host $(curl -4 https://ifconfig.me) --wallet-address <WALLET_ADDRESS>
Initialising mixnode <YOUR_ID>...
Saved mixnet identity and sphinx keypairs
2023-06-04T08:20:32.862Z INFO nym_config > Configuration file will be saved to "/home/<USER>/.nym/mixnodes/<YOUR_ID>/config/config.toml"
Saved configuration file to "/home/<USER>/.nym/mixnodes/<YOUR_ID>/config/config.toml"
Mixnode configuration completed.
_ __ _ _ _ __ ___
| '_ \| | | | '_ \ _ \
| | | | |_| | | | | | |
|_| |_|\__, |_| |_| |_|
|___/
(nym-mixnode - version v1.1.29)
Identity Key: DhmUYedPZvhP9MMwXdNpPaqCxxTQgjAg78s2nqtTTiNF","version":"v1.1.29"},"cost_params
Sphinx Key: CfZSy1jRfrfiVi9JYexjFWPqWkKoY72t7NdpWaq37K8Z
Host: 62.240.134.189 (bind address: 62.240.134.189)
Version: v1.1.29
Mix Port: 1789, Verloc port: 1790, Http Port: 8000
<!-- cmdrun ../../../../target/release/nym-mixnode init --id my-node --host $(curl -4 https://ifconfig.me) -->
```
~~~
> The `init` command will refuse to destroy existing mix node keys.
> The `init` command will refuse to destroy existing Mix Node keys.
During the `init` process you will have the option to change the `http_api`, `verloc` and `mixnode` ports from their default settings. If you wish to change these in the future you can edit their values in the `config.toml` file created by the initialization process, which is located at `~/.nym/mixnodes/<YOUR_ID>/`.
### Bonding your mix node
```admonish caution
From `v1.1.3`, if you unbond your mix node that means you are leaving the mixnet and you will lose all your delegations (permanently). You can join again with the same identity key, however, you will start with **no delegations**.
```
#### Bond via the Desktop wallet (recommended)
You can bond your mix node via the Desktop wallet.
* Open your wallet, and head to the `Bond` page, then select the node type `Mixnode` and input your node details. Press `Next`.
* Enter the `Amount`, `Operating cost` and `Profit margin` and press `Next`.
* You will be asked to run a the `sign` command with your `gateway` - copy and paste the long signature as the value of `--contract-msg` and run it.
```
./nym-mixnode sign --id <YOUR_ID> --contract-msg <PAYLOAD_GENERATED_BY_THE_WALLET>
```
It will look something like this:
~~~admonish example collapsible=true title="Console output"
```
./nym-mixnode sign --id upgrade_test --contract-msg 22Z9wt4PyiBCbMiErxj5bBa4VCCFsjNawZ1KnLyMeV9pMUQGyksRVANbXHjWndMUaXNRnAuEVJW6UCxpRJwZe788hDt4sicsrv7iAXRajEq19cWPVybbUqgeo76wbXbCbRdg1FvVKgYZGZZp8D72p5zWhKSBRD44qgCrqzfV1SkiFEhsvcLUvZATdLRocAUL75KmWivyRiQjCE1XYEWyRH9yvRYn4TymWwrKVDtEB63zhHjATN4QEi2E5qSrSbBcmmqatXsKakbgSbQoLsYygcHx7tkwbQ2HDYzeiKP1t16Rhcjn6Ftc2FuXUNnTcibk2LQ1hiqu3FAq31bHUbzn2wiaPfm4RgqTwGM4eqnjBofwR3251wQSxbYwKUYwGsrkweRcoPuEaovApR9R19oJ7GVG5BrKmFwZWX3XFVuECe8vt1x9MY7DbQ3xhAapsHhThUmzN6JPPU4qbQ3PdMt3YVWy6oRhap97ma2dPMBaidebfgLJizpRU3Yu7mtb6E8vgi5Xnehrgtd35gitoJqJUY5sB1p6TDPd6vk3MVU1zqusrke7Lvrud4xKfCLqp672Bj9eGb2wPwow643CpHuMkhigfSWsv9jDq13d75EGTEiprC2UmWTzCJWHrDH7ka68DZJ5XXAW67DBewu7KUm1jrJkNs55vS83SWwm5RjzQLVhscdtCH1Bamec6uZoFBNVzjs21o7ax2WHDghJpGMxFi6dmdMCZpqn618t4
_ __ _ _ _ __ ___
| '_ \| | | | '_ \ _ \
| | | | |_| | | | | | |
|_| |_|\__, |_| |_| |_|
|___/
(nym-mixnode - version v1.1.29)
>>> attempting to sign 22Z9wt4PyiBCbMiErxj5bBa4VCCFsjNawZ1KnLyMeV9pMUQGyksRVANbXHjWndMUaXNRnAuEVJW6UCxpRJwZe788hDt4sicsrv7iAXRajEq19cWPVybbUqgeo76wbXbCbRdg1FvVKgYZGZZp8D72p5zWhKSBRD44qgCrqzfV1SkiFEhsvcLUvZATdLRocAUL75KmWivyRiQjCE1XYEWyRH9yvRYn4TymWwrKVDtEB63zhHjATN4QEi2E5qSrSbBcmmqatXsKakbgSbQoLsYygcHx7tkwbQ2HDYzeiKP1t16Rhcjn6Ftc2FuXUNnTcibk2LQ1hiqu3FAq31bHUbzn2wiaPfm4RgqTwGM4eqnjBofwR3251wQSxbYwKUYwGsrkweRcoPuEaovApR9R19oJ7GVG5BrKmFwZWX3XFVuECe8vt1x9MY7DbQ3xhAapsHhThUmzN6JPPU4qbQ3PdMt3YVWy6oRhap97ma2dPMBaidebfgLJizpRU3Yu7mtb6E8vgi5Xnehrgtd35gitoJqJUY5sB1p6TDPd6vk3MVU1zqusrke7Lvrud4xKfCLqp672Bj9eGb2wPwow643CpHuMkhigfSWsv9jDq13d75EGTEiprC2UmWTzCJWHrDH7ka68DZJ5XXAW67DBewu7KUm1jrJkNs55vS83SWwm5RjzQLVhscdtCH1Bamec6uZoFBNVzjs21o7ax2WHDghJpGMxFi6dmdMCZpqn618t4
>>> decoding the message...
>>> message to sign: {"nonce":0,"algorithm":"ed25519","message_type":"mixnode-bonding","content":{"sender":"n1eufxdlgt0puwrwptgjfqne8pj4nhy2u5ft62uq","proxy":null,"funds":[{"denom":"unym","amount":"100000000"}],"data":{"mix_node":{"host":"62.240.134.189","mix_port":1789,"verloc_port":1790,"http_api_port":8000,"sphinx_key":"CfZSy1jRfrfiVi9JYexjFWPqWkKoY72t7NdpWaq37K8Z","identity_key":"DhmUYedPZvhP9MMwXdNpPaqCxxTQgjAg78s2nqtTTiNF","version":"1.1.14"},"cost_params":{"profit_margin_percent":"0.1","interval_operating_cost":{"denom":"unym","amount":"40000000"}}}}}
```
~~~
* Copy the resulting signature:
```
>>> The base58-encoded signature is:
2GbKcZVKFdpi3sR9xoJWzwPuGdj3bvd7yDtDYVoKfbTWdpjqAeU8KS5bSftD5giVLJC3gZiCg2kmEjNG5jkdjKUt
```
* And paste it into the wallet nodal, press `Next` and confirm the transaction.
![Paste Signature](../images/wallet-screenshots/wallet-sign.png)
* Your node will now be bonded and ready to mix at the beginning of the next epoch (at most 1 hour).
> You are asked to `sign` a transaction on bonding so that the mixnet smart contract is able to map your nym address to your node. This allows us to create a nonce for each account and defend against replay attacks.
#### Bond via the CLI (power users)
If you want to bond your mix node via the CLI, then check out the [relevant section in the Nym CLI](https://nymtech.net/docs/tools/nym-cli.html#bond-a-mix-node) docs.
### Running your mix node
Now you've bonded your mix node, run it with:
```
./nym-mixnode run --id <YOUR_ID>
```
If everything worked, you'll see your node running on the either the [Sandbox testnet network explorer](https://sandbox-explorer.nymtech.net) or the [mainnet network explorer](https://explorer.nymtech.net), depending on which network you're running.
Note that your node's public identity key is displayed during startup, you can use it to identify your node in the list.
Have a look at the saved configuration files in `$HOME/.nym/mixnodes/` to see more configuration options.
## Node Description (optional)
In order to easily identify your node via human-readable information later on in the development of the testnet when delegated staking is implemented, you can `describe` your mix node with the following command:
In order to easily identify your node via human-readable information later on, you can `describe` your Mix Node with the following command:
```
./nym-mixnode describe --id <YOUR_ID>
@@ -193,15 +98,85 @@ link = "https://nymtech.net"
location = "Giza, Egypt"
```
> Remember to restart your mix node process in order for the new description to be propagated.
> Remember to restart your `nym-mix-node` process in order for the new description to be propagated.
## Running your Mix Node
Run your Mix Node with:
```
./nym-mixnode run --id <YOUR_ID>
```
Have a look at the saved configuration files in `$HOME/.nym/mixnodes/` to see more configuration options.
## Bonding your Mix Node
```admonish caution
From `v1.1.3`, if you unbond your Mix Node that means you are leaving the mixnet and you will lose all your delegations (permanently). You can join again with the same identity key, however, you will start with **no delegations**.
```
To initialise, run and bond your Mix Node are the minimum steps to do in order for your Mix Node to work. However we recommend to do a few more steps before bonding. These steps will make it easier for you as a node operator on a long run as well as for others to possibly delegate Nym tokens to your Mix Node. These steps are:
- [Describe your Mix Node](./mix-node-setup.md#node-description-optional)
- [Configure your firewall](./maintenance.md#configure-your-firewall)
- [Automate your Mix Node](./maintenance.md#vps-setup-and-automation)
- Set the [ulimit](./maintenance.md#set-the-ulimit-via-systemd-service-file), in case you haven't automated with [systemd](./maintenance.md#set-the-ulimit-on-non-systemd-based-distributions)
### Bond via the Desktop wallet (recommended)
You can bond your Mix Node via the Desktop wallet.
* Open your wallet, and head to the `Bond` page, then select the node type `Mixnode` and input your node details. Press `Next`.
* Enter the `Amount`, `Operating cost` and `Profit margin` and press `Next`.
* You will be asked to run a the `sign` command with your `mixnode` - copy and paste the long signature as the value of `--contract-msg` and run it.
```
./nym-mixnode sign --id <YOUR_ID> --contract-msg <PAYLOAD_GENERATED_BY_THE_WALLET>
```
It will look something like this:
~~~admonish example collapsible=true title="Console output"
```
<!-- cmdrun ../../../../target/release/nym-mixnode init --id my-node --host $(curl -4 https://ifconfig.me) -->
<!-- cmdrun ../../../../target/release/nym-mixnode sign --id my-node --contract-msg 22Z9wt4PyiBCbMiErxj5bBa4VCCFsjNawZ1KnLyMeV9pMUQGyksRVANbXHjWndMUaXNRnAuEVJW6UCxpRJwZe788hDt4sicsrv7iAXRajEq19cWPVybbUqgeo76wbXbCbRdg1FvVKgYZGZZp8D72p5zWhKSBRD44qgCrqzfV1SkiFEhsvcLUvZATdLRocAUL75KmWivyRiQjCE1XYEWyRH9yvRYn4TymWwrKVDtEB63zhHjATN4QEi2E5qSrSbBcmmqatXsKakbgSbQoLsYygcHx7tkwbQ2HDYzeiKP1t16Rhcjn6Ftc2FuXUNnTcibk2LQ1hiqu3FAq31bHUbzn2wiaPfm4RgqTwGM4eqnjBofwR3251wQSxbYwKUYwGsrkweRcoPuEaovApR9R19oJ7GVG5BrKmFwZWX3XFVuECe8vt1x9MY7DbQ3xhAapsHhThUmzN6JPPU4qbQ3PdMt3YVWy6oRhap97ma2dPMBaidebfgLJizpRU3Yu7mtb6E8vgi5Xnehrgtd35gitoJqJUY5sB1p6TDPd6vk3MVU1zqusrke7Lvrud4xKfCLqp672Bj9eGb2wPwow643CpHuMkhigfSWsv9jDq13d75EGTEiprC2UmWTzCJWHrDH7ka68DZJ5XXAW67DBewu7KUm1jrJkNs55vS83SWwm5RjzQLVhscdtCH1Bamec6uZoFBNVzjs21o7ax2WHDghJpGMxFi6dmdMCZpqn618t4 -->
```
~~~
* Copy the resulting signature:
```sh
# >>> The base58-encoded signature is:
2bbDJSmSo9r9qdamTNygY297nQTVRyQaxXURuomVcRd7EvG9oEC8uW8fvZZYnDeeC9iWyG9mAbX2K8rWEAxZBro1
```
* And paste it into the wallet nodal, press `Next` and confirm the transaction.
![Paste Signature](../images/wallet-screenshots/wallet-sign.png)
*This image is just an example, copy-paste your own base58-encoded signature*
* Your node will now be bonded and ready to mix at the beginning of the next epoch (at most 1 hour).
> You are asked to `sign` a transaction on bonding so that the Mixnet smart contract is able to map your nym address to your node. This allows us to create a nonce for each account and defend against replay attacks.
If everything worked, you'll see your node running on the either the [Sandbox testnet network explorer](https://sandbox-explorer.nymtech.net) or the [mainnet network explorer](https://explorer.nymtech.net), depending on which network you're running.
Note that your node's public identity key is displayed during startup, you can use it to identify your node in the list.
### Bond via the CLI (power users)
If you want to bond your Mix Node via the CLI, then check out the [relevant section in the Nym CLI](https://nymtech.net/docs/tools/nym-cli.html#bond-a-mix-node) docs.
## Node Families
Node family involves setting up a group of mix nodes that work together to provide greater privacy and security for network communications. This is achieved by having the nodes in the family share information and routes, creating a decentralized network that makes it difficult for third parties to monitor or track communication traffic.
Node family involves setting up a group of Mix Nodes that work together to provide greater privacy and security for network communications. This is achieved by having the nodes in the family share information and routes, creating a decentralized network that makes it difficult for third parties to monitor or track communication traffic.
### Create a Node Family
To create a Node family, you will need to install and configure multiple mix nodes, and then use the CLI to link them together into a family. Once your Node family is up and running, you can use it to route your network traffic through a series of nodes, obscuring the original source and destination of the communication.
To create a Node family, you will need to install and configure multiple Mix Nodes, and then use the CLI to link them together into a family. Once your Node family is up and running, you can use it to route your network traffic through a series of nodes, obscuring the original source and destination of the communication.
You can use either `nym-cli` which can be downloaded from the [release page](https://github.com/nymtech/nym/releases) or compiling `nyxd`.
@@ -214,7 +189,8 @@ Change directory by `cd <PATH>/<TO>/<THE>/<RELEASE>` and run the following on th
~~~admonish example collapsible=true title="Console output"
```
<!-- cmdrun ../../../../target/release/nym-mixnode sign --id YOUR_ID --text "TEXT" -->
<!-- cmdrun ../../../../target/release/nym-mixnode init --id YOUR_ID --host $(curl -4 https://ifconfig.me) -->
<!-- cmdrun ../../../../target/release/nym-mixnode sign --id YOUR_ID --text "TEXT" -->
```
~~~
@@ -248,7 +224,8 @@ Change directory by `cd <PATH>/<TO>/<THE>/<RELEASE>` and run the following on th
~~~admonish example collapsible=true title="Console output"
```
<!-- cmdrun ../../../../target/release/nym-mixnode sign --id YOUR_ID --text "TEXT" -->
<!-- cmdrun ../../../../target/release/nym-mixnode init --id YOUR_ID --host $(curl -4 https://ifconfig.me) -->
<!-- cmdrun ../../../../target/release/nym-mixnode sign --id YOUR_ID --text "TEXT" -->
```
~~~
@@ -274,7 +251,7 @@ To get the node owner signature, use:
If wanting to leave, run the same initial command as above, followed by:
Using `nym-cli`:
<!---the sting under shall be changed to <NODE_ADDRESS>? --->
```
./nym-cli cosmwasm execute <WALLET_ADDRESS> '{"leave_family": {"signature": "<base58-encoded-signature>","family_head": "<TEXT>","owner_signautre": "<OWNER_IGNATURE_FROM_NODE_TO_LEAVE>"}}' --mnemonic <MNEMONIC_FROM_NODE_TO_LEAVE>
```
@@ -287,7 +264,7 @@ Using `nyxd`:
## Checking that your node is mixing correctly
### Network explorers
Once you've started your mix node and it connects to the validator, your node will automatically show up in the 'Mix nodes' section of either the Nym Network Explorers:
Once you've started your Mix Node and it connects to the validator, your node will automatically show up in the 'Mix Nodes' section of either the Nym Network Explorers:
- [Mainnet](https://explorer.nymtech.net/overview)
- [Sandbox testnet](https://sandbox-explorer.nymtech.net/)
@@ -301,9 +278,7 @@ There are also 2 community explorers which have been created by [Nodes Guru](htt
For more details see [Troubleshooting FAQ](../nodes/troubleshooting.md)
<!---Enter faq link to the information how to higher chances to become a part of an active set--->
## Maintenance
For mix node upgrade, firewall setup, port configuration, API endpoints, VPS suggestions, automation and more, see the [maintenance page](./maintenance.md)
For Mix Node upgrade, firewall setup, port configuration, API endpoints, VPS suggestions, automation and more, see the [maintenance page](./maintenance.md)
@@ -1,9 +1,9 @@
# Network Requesters
> The Nym network requester was built in the [building nym](../binaries/building-nym.md) section. If you haven't yet built Nym and want to run the code, go there first.
> Nym Network Requester was built in the [building nym](../binaries/building-nym.md) section. If you haven't yet built Nym and want to run the code, go there first.
```admonish info
As a result of [Project Smoosh](../faq/smoosh-faq.md), the current version of `nym-gateway` binary also contains `nym-network-requester` functionality which can be enabled [by the operator](./gateway-setup.md#initialising-gateway-with-network-requester). This combination is a basis of Nym exit gateway node - an essential piece in our new setup. Please read more in our [Project Smoosh FAQ](../faq/smoosh-faq.md) and [Exit Gateways Page](../legal/exit-gateway.md). We recommend operators begin to shift their setups to this new combined node, instead of operating two separate binaries.
As a result of [Project Smoosh](../faq/smoosh-faq.md), the current version of `nym-gateway` binary also contains `nym-network-requester` functionality which can be enabled [by the operator](./gateway-setup.md#initialising-gateway-with-network-requester). This combination is a basis of Nym Exit Gateway node - an essential piece in our new setup. Please read more in our [Project Smoosh FAQ](../faq/smoosh-faq.md) and [Exit Gateways Page](../legal/exit-gateway.md). We recommend operators begin to shift their setups to this new combined node, instead of operating two separate binaries.
```
> Any syntax in `<>` brackets is a user's unique variable. Exchange with a corresponding name without the `<>` brackets.
@@ -15,23 +15,23 @@ As a result of [Project Smoosh](../faq/smoosh-faq.md), the current version of `n
## Preliminary steps
Make sure you do the preparation listed in the [preliminary steps page](../preliminary-steps.md) before setting up your network requester.
Make sure you do the preparation listed in the [preliminary steps page](../preliminary-steps.md) before setting up your Network Requester.
## Network Requester Whitelist
If you have access to a server, you can run the network requester, which allows Nym users to send outbound requests from their local machine through the mixnet to a server, which then makes the request on their behalf, shielding them (and their metadata) from clearnet, untrusted and unknown infrastructure, such as email or message client servers.
If you have access to a server, you can run the Network Requester, which allows Nym users to send outbound requests from their local machine through the Mixnet to a server, which then makes the request on their behalf, shielding them (and their metadata) from clearnet, untrusted and unknown infrastructure, such as email or message client servers.
By default the network requester is **not** an open proxy (although it can be used as one). It uses a file called `allowed.list` (located in `~/.nym/service-providers/network-requester/<NETWORK-REQUESTER-ID>/`) as a whitelist for outbound requests.
By default the Network Requester is **not** an open proxy (although it can be used as one). It uses a file called `allowed.list` (located in `~/.nym/service-providers/network-requester/<NETWORK-REQUESTER-ID>/`) as a whitelist for outbound requests.
**Note:** If you run network requester as a part of the exit gateway (suggested setup) the `allowed.list` will be stored in `~/.nym/gateways/<ID>/data/network-requester-data/allowed.list`.
**Note:** If you run Network Requester as a part of the Exit Gateway (suggested setup) the `allowed.list` will be stored in `~/.nym/gateways/<ID>/data/network-requester-data/allowed.list`.
Any request to a URL which is not on this list will be blocked.
On startup, if this file is not present, the requester will grab the default whitelist from [Nym's default list](https://nymtech.net/.wellknown/network-requester/standard-allowed-list.txt) automatically.
This default whitelist is useful for knowing that the majority of Network requesters are able to support certain apps 'out of the box'.
This default whitelist is useful for knowing that the majority of Network Requesters are able to support certain apps 'out of the box'.
**Operators of a network requester are of course free to edit this file and add the URLs of services they wish to support to it!** You can find instructions below on adding your own URLs or IPs to this list.
**Operators of a Network Requester are of course free to edit this file and add the URLs of services they wish to support to it!** You can find instructions below on adding your own URLs or IPs to this list.
The domains and IPs on the default whitelist can be broken down by application as follows:
@@ -109,14 +109,14 @@ alephium.org
## Network Requester Directory
You can find a list of Network requesters running the default whitelist in the [explorer](https://explorer.nymtech.net/network-components/service-providers). This list comprises of the NRs running as infrastructure for NymConnect.
You can find a list of Network Requesters running the default whitelist in the [explorer](https://explorer.nymtech.net/network-components/service-providers). This list comprises of the NRs running as infrastructure for NymConnect.
> We are currently working on a smart-contract based solution more in line with how Mix nodes and Gateways announce themselves to the network.
> We are currently working on a smart-contract based solution more in line with how Mix Nodes and Gateways announce themselves to the network.
## Viewing command help
```admonish info
If you run your network requester as a part of your exit gateway according to the suggested setup, please skip this part of the page and read about [exit gateway setup](./gateway-setup.md#initialising-gateway-with-network-requester) instead.
If you run your Network Requester as a part of your Exit Gateway according to the suggested setup, please skip this part of the page and read about [Exit Gateway setup](./gateway-setup.md#initialising-gateway-with-network-requester) instead.
```
To begin, move to `/target/release` directory from which you run the node commands:
@@ -141,9 +141,9 @@ You can check the required parameters for available commands by running:
> Adding `--no-banner` startup flag will prevent Nym banner being printed even if run in tty environment.
## Initializing and running your network requester
## Initializing and running your Network Requester
The network-requester needs to be initialized before it can be run. This is required for the embedded nym-client to connect successfully to the mixnet. We want to specify an `<ID>` using the `--id` command and give it a value of your choice. The following command will achieve that:
The Network Requester needs to be initialized before it can be run. This is required for the embedded nym-client to connect successfully to the Mixnet. We want to specify an `<ID>` using the `--id` command and give it a value of your choice. The following command will achieve that:
```
./nym-network-requester init --id <YOUR_ID>
@@ -164,11 +164,11 @@ Now that we have initialized our network-requester, we can start it with the fol
./nym-network-requester run --id <YOUR_ID>
```
## Using your network requester
## Using your Network Requester
The next thing to do is use your requester, share its address with friends (or whoever you want to help privacy-enhance their app traffic). Is this safe to do? If it was an open proxy, this would be unsafe, because any Nym user could make network requests to any system on the internet.
To make things a bit less stressful for administrators, the Network Requester drops all incoming requests by default. In order for it to make requests, you need to add specific domains to the `allowed.list` file at `$HOME/.nym/service-providers/network-requester/allowed.list` or if network requester is ran as a part of [exit gateway](./gateway-setup.md#initialising-gateway-with-network-requester), the `allowed.list` will be stored in `~/.nym/gateways/<ID>/data/network-requester-data/allowed.list`
To make things a bit less stressful for administrators, the Network Requester drops all incoming requests by default. In order for it to make requests, you need to add specific domains to the `allowed.list` file at `$HOME/.nym/service-providers/network-requester/allowed.list` or if Network Requester is ran as a part of [Exit Gateway](./gateway-setup.md#initialising-gateway-with-network-requester), the `allowed.list` will be stored in `~/.nym/gateways/<ID>/data/network-requester-data/allowed.list`
### Global vs local allow lists
Your Network Requester will check for a domain against 2 lists before allowing traffic through for a particular domain or IP.
@@ -177,34 +177,34 @@ Your Network Requester will check for a domain against 2 lists before allowing t
* The second is the local `allowed.list` file.
### Supporting custom domains with your network requester
It is easy to add new domains and services to your network requester - simply find out which endpoints (both URLs and raw IP addresses are supported) you need to whitelist, and then add these endpoints to your `allowed.list`.
### Supporting custom domains with your Network Requester
It is easy to add new domains and services to your Network Requester - simply find out which endpoints (both URLs and raw IP addresses are supported) you need to whitelist, and then add these endpoints to your `allowed.list`.
> In order to keep things more organised, you can now use comments in the `allow.list` like the example at the top of this page.
How to go about this? Have a look in your nym-network-requester config directory:
How to go about this? Have a look in your `nym-network-requester` config directory:
```
# network requester binary
# nym-network-requester binary
ls -lt $HOME/.nym/service-providers/network-requester/*/data | grep "list"
# exit gateway binary
# nym-gateway binary
ls -lt $HOME/.nym/gateways/*/data/network-requester-data | grep "list"
# returns: allowed.list unknown.list
```
We already know that `allowed.list` is what lets requests go through. All unknown requests are logged to `unknown.list`. If you want to try using a new client type, just start the new application, point it at your local [socks client](https://nymtech.net/docs/clients/socks5-client.html) (configured to use your remote `nym-network-requester`), and keep copying URLs from `unknown.list` into `allowed.list` (it may take multiple tries until you get all of them, depending on the complexity of the application). Make sure to delete the copied ones in `unknown.list` and restart your exit gateway or standalone network requester.
We already know that `allowed.list` is what lets requests go through. All unknown requests are logged to `unknown.list`. If you want to try using a new client type, just start the new application, point it at your local [socks client](https://nymtech.net/docs/clients/socks5-client.html) (configured to use your remote `nym-network-requester`), and keep copying URLs from `unknown.list` into `allowed.list` (it may take multiple tries until you get all of them, depending on the complexity of the application). Make sure to delete the copied ones in `unknown.list` and restart your Exit Gateway or standalone Network Requester.
> If you are adding custom domains, please note that whilst they may appear in the logs of your network-requester as something like `api-0.core.keybaseapi.com:443`, you **only need** to include the main domain name, in this instance `keybaseapi.com`
### Running an open proxy
If you *really* want to run an open proxy, perhaps for testing purposes for your own use or among a small group of trusted friends, it is possible to do so. You can disable network checks by passing the flag `--open-proxy` flag when you run it. If you run in this configuration, you do so at your own risk.
If you *really* want to run an open proxy, perhaps for testing purposes for your own use or among a small group of trusted friends, it is possible to do so. You can disable Network checks by passing the flag `--open-proxy` flag when you run it. If you run in this configuration, you do so at your own risk.
## Testing your network requester
1. Make sure `nymtech.net` is in your `allowed.list` (remember to restart your network requester).
## Testing your Network Requester
1. Make sure `nymtech.net` is in your `allowed.list` (remember to restart your Network Requester).
2. Ensure that your network-requester is initialized and running.
2. Ensure that your `nym-network-requester` is initialized and running.
3. In another terminal window, run the following:
@@ -220,5 +220,5 @@ This command should return the following:
## Maintenance
For network requester upgrade (including an upgrade from `<v1.1.9` to `>= v1.1.10`), firewall setup, port configuration, API endpoints, VPS suggestions, automation and more, see the [maintenance page](./maintenance.md).
For Network Requester upgrade (including an upgrade from `<v1.1.9` to `>= v1.1.10`), firewall setup, port configuration, API endpoints, VPS suggestions, automation and more, see the [maintenance page](./maintenance.md).
@@ -3,7 +3,7 @@
To setup any type of Nym's node, start with building [Nym's platform](../binaries/building-nym.md) on the machine (VPS) where you want to run the node. Nodes will need to be bond to Nym's wallet, setup one [here](https://nymtech.net/docs/wallet/desktop-wallet.html).
This section contains setup guides for the following node types:
* [Mix node](./mix-node-setup.md)
* [Mix Node](./mix-node-setup.md)
* [Gateway](./gateway-setup.md)
* [Network Requester](./network-requester-setup.md)
* [Validator](./validator-setup.md)
@@ -78,7 +78,7 @@ Additional details can be obtained via various methods after you connect to your
##### Socket statistics with `ss`
```
sudo ss -s -t | grep 1789 # if you have specified a different port in your mix node config, change accordingly
sudo ss -s -t | grep 1789 # if you have specified a different port in your Mix Node config, change accordingly
```
This command should return a lot of data containing `ESTAB`. This command should work on every unix based system.
@@ -90,7 +90,7 @@ This command should return a lot of data containing `ESTAB`. This command should
lsof -v
# install if not installed
sudo apt install lsof
# run against mix node port
# run against nym-mix-node node port
sudo lsof -i TCP:1789 # if you have specified a different port in your mixnode config, change accordingly
```
@@ -110,7 +110,7 @@ nym-mixno 103349 root 57u IPv6 1333229976 0t0 TCP [2a03:b0c0:3:d0::ff3:
sudo journalctl -u nym-mixnode -o cat | grep "Since startup mixed"
```
If you have created `nym-mixnode.service` file (i.e. you are running your mix node via `systemd`) then this command shows you how many packets have you mixed so far, and should return a list of messages like this:
If you have created `nym-mixnode.service` file (i.e. you are running your Mix Node via `systemd`) then this command shows you how many packets have you mixed so far, and should return a list of messages like this:
```
2021-05-18T12:35:24.057Z INFO nym_mixnode::node::metrics > Since startup mixed 233639 packets!
@@ -140,7 +140,7 @@ For example `./target/debug/nym-network-requester --no-banner build-info --outpu
nmap -p 1789 <IP ADDRESS> -Pn
```
If your mix node is configured properly it should output something like this:
If your Mix Node is configured properly it should output something like this:
```
bob@desktop:~$ nmap -p 1789 95.296.134.220 -Pn
@@ -159,12 +159,12 @@ curl --location --request GET 'https://validator.nymtech.net/api/v1/mixnodes/'
Will return a list all nodes currently online.
You can query gateways by replacing `mixnodes` with `gateways` in the above command, and can query for the mixnodes and gateways on the Sandbox testnet by replacing `validator` with `sandbox-validator`.
You can query Gateways by replacing `nym-mixnodes` with `nym-gateways` in the above command, and can query for the Mix Nodes and Gateways on the Sandbox testnet by replacing `validator` with `sandbox-validator`.
#### Check with Network API
We currently have an API set up returning our metrics tests of the network. There are two endpoints to ping for information about your mix node, `report` and `history`. Find more information about this in the [Mixnodes metrics documentation](./maintenance.md#metrics--api-endpoints).
We currently have an API set up returning our metrics tests of the network. There are two endpoints to ping for information about your Mix Node, `report` and `history`. Find more information about this in the [Mixnodes metrics documentation](./maintenance.md#metrics--api-endpoints).
### Why is my node not mixing any packets?
@@ -172,24 +172,24 @@ If you are still unable to see your node on the dashboard, or your node is decla
- The firewall on your host machine is not configured properly. Checkout the [instructions](./maintenance.md#configure-your-firewall).
- You provided incorrect information when bonding your node.
- You are running your mix node from a VPS without IPv6 support.
- You did not use the `--announce-host` flag while running the mix node from your local machine behind NAT.
- You did not configure your router firewall while running the mix node from your local machine behind NAT, or you are lacking IPv6 support.
- Your mix node is not running at all, it has either exited / panicked or you closed the session without making the node persistent. Check out the [instructions](./maintenance.md#automating-your-node-with-tmux-and-systemd).
- You are running your Mix Node from a VPS without IPv6 support.
- You did not use the `--announce-host` flag while running the Mix Node from your local machine behind NAT.
- You did not configure your router firewall while running the Mix Node from your local machine behind NAT, or you are lacking IPv6 support.
- Your Mix Node is not running at all, it has either exited / panicked or you closed the session without making the node persistent. Check out the [instructions](./maintenance.md#automating-your-node-with-tmux-and-systemd).
```admonish caution
Your mix node **must speak both IPv4 and IPv6** in order to cooperate with other nodes and route traffic. This is a common reason behind many errors we are seeing among node operators, so check with your provider that your VPS is able to do this!
Your Mix Node **must speak both IPv4 and IPv6** in order to cooperate with other nodes and route traffic. This is a common reason behind many errors we are seeing among node operators, so check with your provider that your VPS is able to do this!
```
#### Incorrect bonding information
Check that you have provided the correct information when bonding your mix node in the web wallet interface. When in doubt, un-bond and then re-bond your node!
Check that you have provided the correct information when bonding your Mix Node in the web wallet interface. When in doubt, un-bond and then re-bond your node!
> All delegated stake will be lost when un-bonding! However the mix node must be operational in the first place for the delegation to have any effect.
> All delegated stake will be lost when un-bonding! However the Mix Node must be operational in the first place for the delegation to have any effect.
#### Missing `announce-host` flag
On certain cloud providers such as AWS and Google Cloud, you need to do some additional configuration of your firewall and use `--host` with your **local ip** and `--announce-host` with the **public ip** of your mix node host.
On certain cloud providers such as AWS and Google Cloud, you need to do some additional configuration of your firewall and use `--host` with your **local ip** and `--announce-host` with the **public ip** of your Mix Node host.
If the difference between the two is unclear, contact the help desk of your VPS provider.
@@ -222,15 +222,15 @@ bob@nym:~$ hostname -I
### Running on a local machine behind NAT with no fixed IP address
Your ISP has to be IPv6 ready if you want to run a mix node on your local machine. Sadly, in 2020, most of them are not and you won't get an IPv6 address by default from your ISP. Usually it is an extra paid service or they simply don't offer it.
Your ISP has to be IPv6 ready if you want to run a Mix Node on your local machine. Sadly, in 2020, most of them are not and you won't get an IPv6 address by default from your ISP. Usually it is an extra paid service or they simply don't offer it.
Before you begin, check if you have IPv6 [here](https://test-ipv6.cz/) or by running command explained in the [section above](./troubleshooting.md#no-ipv6-connectivity). If not, then don't waste your time to run a node which won't ever be able to mix any packet due to this limitation. Call your ISP and ask for IPv6, there is a plenty of it for everyone!
If all goes well and you have IPv6 available, then you will need to `init` the mix node with an extra flag, `--announce-host`. You will also need to edit your `config.toml` file each time your IPv4 address changes, that could be a few days or a few weeks. Check the your IPv4 in the [section above](./troubleshooting.md#no-ipv6-connectivity).
If all goes well and you have IPv6 available, then you will need to `init` the Mix Node with an extra flag, `--announce-host`. You will also need to edit your `config.toml` file each time your IPv4 address changes, that could be a few days or a few weeks. Check the your IPv4 in the [section above](./troubleshooting.md#no-ipv6-connectivity).
Additional configuration on your router might also be needed to allow traffic in and out to port 1789 and IPv6 support.
Here is a sample of the `init` command example to create the mix node config.
Here is a sample of the `init` command example to create the Mix Node config.
```
./nym-mixnode init --id <YOUR_ID> --host 0.0.0.0 --announce-host 85.160.12.13
@@ -244,7 +244,7 @@ Make sure you check if your node is really mixing. We are aiming to improve the
### Accidentally killing your node process on exiting session
When you close your current terminal session, you need to make sure you don't kill the mix node process! There are multiple ways on how to make it persistent even after exiting your ssh session, the easiest solution is to use `tmux` or `nohup`, and the more elegant solution is to run the node with `systemd`. Read the automation manual [here](./maintenance.md#automating-your-node-with-tmux-and-systemd).
When you close your current terminal session, you need to make sure you don't kill the Mix Node process! There are multiple ways on how to make it persistent even after exiting your ssh session, the easiest solution is to use `tmux` or `nohup`, and the more elegant solution is to run the node with `systemd`. Read the automation manual [here](./maintenance.md#automating-your-node-with-tmux-and-systemd).
### Common errors and warnings
@@ -266,14 +266,14 @@ Then you need to `--announce-host <PUBLIC_IP>` and `--host <LOCAL_IP>` on startu
Yes! Here is what you will need to do:
Assuming you would like to use port `1337` for your mix node, you need to open the new port (and close the old one):
Assuming you would like to use port `1337` for your Mix Node, you need to open the new port (and close the old one):
```
sudo ufw allow 1337
sudo ufw deny 1789
```
And then edit the mix node's config.
And then edit the Mix Node's config.
> If you want to change the port for an already running node, you need to stop the process before editing your config file.
@@ -287,25 +287,25 @@ nano ~/.nym/mixnodes/alice-node/config/config.toml
You will need to edit two parts of the file. `announce_address` and `listening_address` in the config.toml file. Simply replace `:1789` (the default port) with `:1337` (your new port) after your IP address.
Finally, restart your node. You should see if the mix node is using the port you have changed in the config.toml file right after you run the node.
Finally, restart your node. You should see if the Mix Node is using the port you have changed in the config.toml file right after you run the node.
### What is `verloc` and do I have to configure my mix node to implement it?
### What is `verloc` and do I have to configure my Mix Node to implement it?
`verloc` is short for _verifiable location_. Mixnodes and gateways now measure speed-of-light distances to each other, in an attempt to verify how far apart they are. In later releases, this will allow us to algorithmically verify node locations in a non-fake-able and trustworthy manner.
`verloc` is short for _verifiable location_. Mix Nodes and Gateways now measure speed-of-light distances to each other, in an attempt to verify how far apart they are. In later releases, this will allow us to algorithmically verify node locations in a non-fake-able and trustworthy manner.
You don't have to do any additional configuration for your node to implement this, it is a passive process that runs in the background of the mixnet from version `0.10.1` onward.
## Gateways & Network requesters
## Gateways & Network Requesters
### My gateway seems to be running but appears offline
### My Gateway seems to be running but appears offline
Check your [firewall](./maintenance.md#configure-your-firewall) is active and if the necessary ports are open / allowed.
### My exit gateway "is still not online..."
### My exit Gateway "is still not online..."
The Nyx chain epoch takes up to 60 min. To prevent the gateway getting blacklisted, it's important to run it right after the bonding process to return positive response our API testing it's routing score.
The Nyx chain epoch takes up to 60 min. To prevent the Gateway getting blacklisted, it's important to run it before and during the bonding process. In case it already got blacklisted run it for at several hours. During this time your node is tested by `nym-api` and every positive response picks up your Gateway's routing score.
You may want to disconnect the network requester and let it run as a gatewy alone for some time to regain better routing score and then areturn to the full [exit gateway finctionality](./gateway-setup.md#initialising-gateway-with-network-requester).
You may want to disconnect the Network Requester and let it run as a Gateway alone for some time to regain better routing score and then return to the full [Exit Gateway finctionality](./gateway-setup.md#initialising-gateway-with-network-requester).
## Validators
@@ -1,12 +1,12 @@
# Validators
> Nym has two main codebases:
> Nym has two main codebases:
> - the [Nym platform](https://github.com/nymtech/nym), written in Rust. This contains all of our code except for the validators.
> - the [Nym validators](https://github.com/nymtech/nyxd), written in Go.
> - the [Nym validators](https://github.com/nymtech/nyxd), written in Go & maintained as a no-modification fork of [wasmd](https://github.com/CosmWasm/wasmd)
The validator is built using [Cosmos SDK](https://cosmos.network) and [Tendermint](https://tendermint.com), with a [CosmWasm](https://cosmwasm.com) smart contract controlling the directory service, node bonding, and delegated mixnet staking.
The validator is a Go application which implements it's functionalities using [Cosmos SDK](https://v1.cosmos.network/sdk). The underlying state-replication engine is powered by [CometBFT](https://cometbft.com/), where the consensus mechanism is based on the [Tendermint Consensus Algorithm](https://arxiv.org/abs/1807.04938). Finally, a [CosmWasm](https://cosmwasm.com) smart contract module controls crucial mixnet functionalities like decentralised directory service, node bonding, and delegated mixnet staking.
> 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.
> We are currently running mainnet with a closed set of reputable validators. To ensure decentralisation of Nyx chain, we are working on a mechanism to onboard new validators to the network. To join the waitlist, please drop an email to `validators [at] nymtech.net` with details of your setup, experience and any other relevent information
## Building your validator
@@ -33,9 +33,9 @@ pacman -S git gcc jq
`Go` can be installed via the following commands (taken from the [Go Download and install page](https://go.dev/doc/install)):
```
# First remove any existing old Go installation and extract the archive you just downloaded into /usr/local:
# First remove any existing old Go installation and extract the archive you just downloaded into /usr/local:
# You may need to run the command as root or through sudo
rm -rf /usr/local/go && tar -C /usr/local -xzf go1.20.6.linux-amd64.tar.gz
rm -rf /usr/local/go && tar -C /usr/local -xzf go1.20.10.linux-amd64.tar.gz
# Add /usr/local/go/bin to the PATH environment variable
export PATH=$PATH:/usr/local/go/bin
@@ -47,16 +47,12 @@ Verify `Go` is installed with:
```
go version
# Should return something like:
go version go1.20.4 linux/amd64
go version go1.20.10 linux/amd64
```
### Download a precompiled validator binary
You can find pre-compiled binaries for Ubuntu `22.04` and `20.04` [here](https://github.com/nymtech/nyxd/releases).
```admonish caution title=""
There are seperate releases for Mainnet and the Sandbox testnet - make sure to download the correct binary to avoid `bech32Prefix` mismatches.
```
### Manually compiling your validator binary
The codebase for the Nyx validators can be found [here](https://github.com/nymtech/nyxd).
@@ -64,15 +60,13 @@ The validator binary can be compiled by running the following commands:
```
git clone https://github.com/nymtech/nyxd.git
cd nyxd
# Make sure to check releases for the latest version information
git checkout release/<NYXD_VERSION>
# Mainnet
# Build the binaries
make build
# Sandbox testnet
BECH32_PREFIX=nymt make build
```
At this point, you will have a copy of the `nyxd` binary in your `build/` directory. Test that it's compiled properly by running:
```
@@ -83,50 +77,49 @@ You should see a similar help menu printed to you:
~~~admonish example collapsible=true title="Console output"
```
Wasm Daemon (server)
Nyx Daemon (server)
Usage:
nyxd [command]
Available Commands:
add-genesis-account Add a genesis account to genesis.json
add-wasm-genesis-message Wasm genesis subcommands
collect-gentxs Collect genesis txs and output a genesis.json file
config Create or query an application CLI configuration file
debug Tool for helping with debugging your application
export Export state to JSON
gentx Generate a genesis tx carrying a self delegation
help Help about any command
init Initialize private validator, p2p, genesis, and application configuration files
keys Manage your application's keys
query Querying subcommands
rollback rollback cosmos-sdk and tendermint state by one height
start Run the full node
status Query remote node for status
tendermint Tendermint subcommands
tx Transactions subcommands
validate-genesis validates the genesis file at the default location or at the location passed as an arg
version Print the application binary version information
completion Generate the autocompletion script for the specified shell
config Create or query an application CLI configuration file
debug Tool for helping with debugging your application
export Export state to JSON
genesis Application's genesis-related subcommands
help Help about any command
init Initialize private validator, p2p, genesis, and application configuration files
keys Manage your application's keys
prune Prune app history states by keeping the recent heights and deleting old heights
query Querying subcommands
rollback rollback cosmos-sdk and tendermint state by one height
rosetta spin up a rosetta server
start Run the full node
status Query remote node for status
tendermint Tendermint subcommands
testnet subcommands for starting or configuring local testnets
tx Transactions subcommands
version Print the application binary version information
Flags:
-h, --help help for nyxd
--home string directory for config and data (default "/home/willow/.nyxd")
--home string directory for config and data
--log_format string The logging format (json|plain) (default "plain")
--log_level string The logging level (trace|debug|info|warn|error|fatal|panic) (default "info")
--trace print out full stack trace on errors
Use "nyxd [command] --help" for more information about a command.
```
~~~
### Linking `nyxd` to `libwasmvm.so`
`libwasmvm.so` is the wasm virtual machine which is needed to execute smart contracts in `v0.26.1`. This file is renamed in `libwasmvm.x86_64.so` in `v0.31.1`.
`libwasmvm.so` is the wasm virtual machine which is needed to execute smart contracts in `v0.26.1`. This file is renamed in `libwasmvm.x86_64.so` in `v0.31.1` and above.
If you downloaded your `nyxd` binary from Github, you will have seen this file when un-`tar`-ing the `.tar.gz` file from the releases page.
If you are seeing an error concerning this file when trying to run `nyxd`, then you need to move the `libwasmvm.so` file to correct location.
If you are seeing an error concerning this file when trying to run `nyxd`, then you need to move the `libwasmvm.x86_64.so` file to correct location.
Simply `cp` or `mv` that file to `/lib/x86_64-linux-gnu/` and re-run `nyxd`.
@@ -152,40 +145,39 @@ This should return the regular help menu:
~~~admonish example collapsible=true title="Console output"
```
Wasm Daemon (server)
Nyx Daemon (server)
Usage:
nyxd [command]
Available Commands:
add-genesis-account Add a genesis account to genesis.json
add-wasm-genesis-message Wasm genesis subcommands
collect-gentxs Collect genesis txs and output a genesis.json file
config Create or query an application CLI configuration file
debug Tool for helping with debugging your application
export Export state to JSON
gentx Generate a genesis tx carrying a self delegation
help Help about any command
init Initialize private validator, p2p, genesis, and application configuration files
keys Manage your application's keys
query Querying subcommands
rollback rollback cosmos-sdk and tendermint state by one height
start Run the full node
status Query remote node for status
tendermint Tendermint subcommands
tx Transactions subcommands
validate-genesis validates the genesis file at the default location or at the location passed as an arg
version Print the application binary version information
completion Generate the autocompletion script for the specified shell
config Create or query an application CLI configuration file
debug Tool for helping with debugging your application
export Export state to JSON
genesis Application's genesis-related subcommands
help Help about any command
init Initialize private validator, p2p, genesis, and application configuration files
keys Manage your application's keys
prune Prune app history states by keeping the recent heights and deleting old heights
query Querying subcommands
rollback rollback cosmos-sdk and tendermint state by one height
rosetta spin up a rosetta server
start Run the full node
status Query remote node for status
tendermint Tendermint subcommands
testnet subcommands for starting or configuring local testnets
tx Transactions subcommands
version Print the application binary version information
Flags:
-h, --help help for nyxd
--home string directory for config and data (default "/home/willow/.nyxd")
--home string directory for config and data
--log_format string The logging format (json|plain) (default "plain")
--log_level string The logging level (trace|debug|info|warn|error|fatal|panic) (default "info")
--trace print out full stack trace on errors
Use "nyxd [command] --help" for more information about a command.
```
~~~
@@ -224,7 +216,7 @@ You can use the following command to download them for the correct network:
wget -O $HOME/.nyxd/config/genesis.json https://nymtech.net/genesis/genesis.json
# Sandbox testnet
wget -O $HOME/.nyxd/config/genesis.json https://sandbox-validator1.nymtech.net/snapshots/genesis.json
wget -O $HOME/.nyxd/config/genesis.json https://sandbox-validator1.nymtech.net/snapshots/genesis.json | jq '.result.genesis'
```
### `config.toml` configuration
@@ -234,21 +226,18 @@ Edit the following config options in `$HOME/.nyxd/config/config.toml` to match t
```
# Mainnet
persistent_peers = "ee03a6777fb76a2efd0106c3769daaa064a3fcb5@51.79.21.187:26656"
create_empty_blocks = false
laddr = "tcp://0.0.0.0:26656"
```
```
# Sandbox testnet
cors_allowed_origins = ["*"]
persistent_peers = "8421c0a3d90d490e27e8061f2abcb1276c8358b6@sandbox-validator1.nymtech.net:26666"
create_empty_blocks = false
persistent_peers = "26f7782aff699457c8e6dd9a845e5054c9b0707e@sandbox-validator1.nymtech.net:26666"
laddr = "tcp://0.0.0.0:26656"
```
These affect the following:
These affect the following:
* `persistent_peers = "<PEER_ADDRESS>@<DOMAIN>.nymtech.net:26666"` allows your validator to start pulling blocks from other validators. **The main sandbox validator listens on `26666` instead of the default `26656` for debugging**. It is recommended you do not change your port from `26656`.
* `create_empty_blocks = false` will save space
* `laddr = "tcp://0.0.0.0:26656"` is in your p2p configuration options
Optionally, if you want to enable [Prometheus](https://prometheus.io/) metrics then the following must also match in the `config.toml`:
@@ -270,11 +259,11 @@ In the file `$HOME/nyxd/config/app.toml`, set the following values:
```
# Mainnet
minimum-gas-prices = "0.025unym,0.025unyx"
enable = true in the `[api]` section to get the API server running
```
```
# Sandbox Testnet
minimum-gas-prices = "0.025unymt,0.025unyxt"
minimum-gas-prices = "0.025unym,0.025unyx"
enable = true` in the `[api]` section to get the API server running
```
@@ -285,9 +274,13 @@ You'll need an admin account to be in charge of your validator. Set that up with
nyxd keys add nyxd-admin
```
This will add keys for your administrator account to your system's keychain and log your name, address, public key, and mnemonic. As the instructions say, remember to **write down your mnemonic**.
```admonish tip title="Key Backends"
Cosmos SDK offers multiple backends for securing your keys. Please refer to the Cosmos SDK [docs on available keyring backends](https://docs.cosmos.network/main/user/run-node/keyring#available-backends-for-the-keyring) to learn more
```
You can get the admin account's address with:
While using the default settings, this will add keys for your account to your system's keychain and log your name, address, public key, and mnemonic. As the instructions say, remember to **write down your mnemonic**.
You can get the current account address with:
```
nyxd keys show nyxd-admin -a
@@ -297,10 +290,6 @@ Type in your keychain **password**, not the mnemonic, when asked.
## Starting your validator
```admonish caution title=""
If you are running a Sandbox testnet validator, please skip the `validate-genesis` command: it will fail due to the size of the genesis file as this is a fork of an existing chain state.
```
Everything should now be ready to go. You've got the validator set up, all changes made in `config.toml` and `app.toml`, the Nym genesis file copied into place (replacing the initial auto-generated one). Now let's validate the whole setup:
```
@@ -313,7 +302,7 @@ If this check passes, you should receive the following output:
File at /path/to/genesis.json is a valid genesis file
```
> If this test did not pass, check that you have replaced the contents of `/<PATH-TO>/.nymd/config/genesis.json` with that of the correct genesis file.
> If this test did not pass, check that you have replaced the contents of `/<PATH-TO>/.nyxd/config/genesis.json` with that of the correct genesis file.
### Open firewall ports
@@ -323,14 +312,18 @@ Before starting the validator, we will need to open the firewall ports:
# if ufw is not already installed:
sudo apt install ufw
sudo ufw enable
sudo ufw allow 1317,26656,26660,22,80,443/tcp
# Customise according to your port bindings. This is only for reference
# 26656 : p2p gossip port
# 26660: If prometheus is enabled
# 22 : Default SSH port
sudo ufw allow 26656,26660,22
# to check everything worked
sudo ufw status
```
Ports `22`, `80`, and `443` are for ssh, http, and https connections respectively. The rest of the ports are documented [here](https://docs.cosmos.network/main/core/grpc_rest).
For more information about your validator's port configuration, check the [validator port reference table](./maintenance.md#ports) below.
For more information about your validator's port configuration, check the [validator port reference table](./maintenance.md#ports) below. These can be customised in `app.toml` and `config.toml` files.
> If you are planning to use [Cockpit](https://cockpit-project.org/) on your validator server then you will have defined a different `grpc` port in your `config.toml` above: remember to open this port as well.
@@ -376,8 +369,7 @@ Once your validator has synced and you have received tokens, you can join consen
```
# Mainnet
nyxd tx staking create-validator
--amount=10000000unyx
--fees=0unyx
--amount=<10000000unyx>
--pubkey=$(/home/<USER>/<PATH-TO>/nyxd/binaries/nyxd tendermint show-validator)
--moniker="<YOUR_VALIDATOR_NAME>"
--chain-id=nyx
@@ -387,14 +379,14 @@ nyxd tx staking create-validator
--min-self-delegation="1"
--gas="auto"
--gas-adjustment=1.15
--from="KEYRING_NAME"
--node https://rpc-1.nyx.nodes.guru:443
--gas-prices=0.025unyx
--from=<"KEYRING_NAME">
--node=https://rpc.nymtech.net:443
```
```
# Sandbox Testnet
nyxd tx staking create-validator
--amount=10000000unyxt
--fees=5000unyxt
--amount=<10000000unyx>
--pubkey=$(/home/<USER>/<PATH-TO>/nym/binaries/nyxd tendermint show-validator)
--moniker="<YOUR_VALIDATOR_NAME>"
--chain-id=sandbox
@@ -404,13 +396,13 @@ nyxd tx staking create-validator
--min-self-delegation="1"
--gas="auto"
--gas-adjustment=1.15
--from="KEYRING_NAME"
--gas-prices=0.025unyx
--from=<"KEYRING_NAME">
--node https://sandbox-validator1.nymtech.net:443
```
You'll need either `unyxt` tokens on Sandbox, or `unyx` tokens on mainnet to perform this command.
You'll need Nyx tokens on mainnet / sandbox to perform the above tasks.
> 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.
If you want to edit some details for your node you will use a command like this:
@@ -424,8 +416,8 @@ nyxd tx staking edit-validator
--identity="<YOUR_IDENTITY>"
--gas="auto"
--gas-adjustment=1.15
--gas-prices=0.025unyx
--from="KEYRING_NAME"
--fees 2000unyx
```
```
# Sandbox testnet
@@ -437,8 +429,8 @@ nyxd tx staking edit-validator
--identity="<YOUR_IDENTITY>"
--gas="auto"
--gas-adjustment=1.15
--gas-prices=0.025unyx
--from="KEYRING_NAME"
--fees 2000unyxt
```
With above command you can specify the `gpg` key last numbers (as used in `keybase`) as well as validator details and your email for security contact.
@@ -446,9 +438,6 @@ With above command you can specify the `gpg` key last numbers (as used in `keyba
### Automating your validator with systemd
You will most likely want to automate your validator restarting if your server reboots. Checkout the [maintenance page](./maintenance.md#systemd) with a quick tutorial.
### Installing and configuring nginx for HTTPS
If you want to set up a reverse proxying on the validator server to improve security and performance, using [nginx](https://www.nginx.com/resources/glossary/nginx/#:~:text=NGINX%20is%20open%20source%20software,%2C%20media%20streaming%2C%20and%20more.&text=In%20addition%20to%20its%20HTTP,%2C%20TCP%2C%20and%20UDP%20servers.), follow the manual on the [maintenance page](./maintenance.md#setup).
### Setting the ulimit
@@ -466,7 +455,7 @@ nyxd tx slashing unjail
--chain-id=nyx
--gas=auto
--gas-adjustment=1.4
--fees=7000unyx
--gas-prices=0.025unyx
```
```
# Sandbox Testnet
@@ -476,7 +465,7 @@ nyxd tx slashing unjail
--chain-id=sandbox
--gas=auto
--gas-adjustment=1.4
--fees=7000unyxt
--gas-prices=0.025unyx
```
### Upgrading your validator
@@ -496,7 +485,7 @@ If the `/dev/sda` partition is almost full, try pruning some of the `.gz` syslog
You can check your current balances with:
```
nymd query bank balances ${ADDRESS}
nyxd query bank balances ${ADDRESS}
```
For example, on the Sandbox testnet this would return:
@@ -504,7 +493,7 @@ For example, on the Sandbox testnet this would return:
```yaml
balances:
- amount: "919376"
denom: unymt
denom: unym
pagination:
next_key: null
total: "0"
@@ -516,22 +505,21 @@ You can, of course, stake back the available balance to your validator with the
```
# Mainnet
nyxd tx staking delegate VALOPERADDRESS AMOUNTunym
nyxd tx staking delegate VALOPERADDRESS AMOUNTunyx
--from="KEYRING_NAME"
--keyring-backend=os
--chain-id=nyx
--gas="auto"
--gas-adjustment=1.15
--fees 5000unyx
```
```
--gas-prices=0.025unyx
# Sandbox Testnet
nyxd tx staking delegate VALOPERADDRESS AMOUNTunymt
nyxd tx staking delegate VALOPERADDRESS AMOUNTunyx
--from="KEYRING_NAME"
--keyring-backend=os
--chain-id=sandbox
--gas="auto"
--gas-adjustment=1.15
--fees 5000unyxt
--gas-prices=0.025unyx
```
+3 -1
View File
@@ -580,7 +580,9 @@ mod test {
}
#[tokio::test]
#[should_panic]
#[should_panic(
expected = "Received committed block which isn't last produced block, this is a bug!"
)]
async fn test_on_committed_with_invalid_pending_block() {
let (mut manager, _) = block_manager_with_defaults();
+8 -2
View File
@@ -1,8 +1,11 @@
import * as React from 'react';
import React from 'react';
import Box from '@mui/material/Box';
import { Typography } from '@mui/material';
import MuiLink from '@mui/material/Link';
import { Link } from 'react-router-dom';
import Typography from '@mui/material/Typography';
import { Socials } from './Socials';
import { useIsMobile } from '../hooks/useIsMobile';
import { NymVpnIcon } from '../icons/NymVpn';
export const Footer: FCWithChildren = () => {
const isMobile = useIsMobile();
@@ -31,6 +34,9 @@ export const Footer: FCWithChildren = () => {
mb: 2,
}}
>
<MuiLink component={Link} to="http://nymvpn.com" target="_blank" underline="none" marginRight={1}>
<NymVpnIcon />
</MuiLink>
<Socials isFooter />
</Box>
)}
+4
View File
@@ -22,6 +22,7 @@ import { useMainContext } from '../context/main';
import { MobileDrawerClose } from '../icons/MobileDrawerClose';
import { Socials } from './Socials';
import { Footer } from './Footer';
import { NymVpnIcon } from '../icons/NymVpn';
import { DarkLightSwitchDesktop } from './Switch';
import { NavOptionType } from '../context/nav';
@@ -341,6 +342,9 @@ export const Nav: FCWithChildren = ({ children }) => {
alignItems: 'center',
}}
>
<MuiLink component={Link} to="http://nymvpn.com" target="_blank" underline="none" marginRight={1}>
<NymVpnIcon />
</MuiLink>
<Socials />
<DarkLightSwitchDesktop defaultChecked />
</Box>
+56
View File
@@ -0,0 +1,56 @@
import * as React from 'react';
interface DiscordIconProps {
size?: { width: number; height: number };
}
export const NymVpnIcon: FCWithChildren<DiscordIconProps> = ({ size }) => (
<svg width={size?.width} height={size?.height} viewBox="0 0 170 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M19.6118 0.128906H19.5405V0.187854V20.7961L10.7849 0.164277L10.773 0.128906H10.7255H5.75959H0.187819H0.128418V0.187854V23.8142V23.8732H0.187819H5.75959H5.81899V23.8142V3.17063L14.6103 23.8378L14.6222 23.8732H14.6697H19.6118H25.1717H25.2311V23.8142V0.187854V0.128906H25.1717H19.6118Z"
fill="white"
/>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M19.4121 0H25.3603V24H14.5297L14.4901 23.8819L5.94824 3.80121V24H0V0H10.8663L10.906 0.118132L19.4121 20.1621V0ZM19.5409 20.7951L10.7853 0.163225L10.7734 0.127854H0.128835V23.8721H5.81941V3.16958L14.6107 23.8368L14.6226 23.8721H25.2315V0.127854H19.5409V20.7951Z"
fill="white"
/>
<path
d="M89.8116 0.128906H79.1908H79.1314L79.1195 0.176068L73.6784 20.8904L68.2255 0.176068L68.2136 0.128906H68.1661H57.5215H57.4502V0.187854V23.8142V23.8732H57.5215H63.0814H63.1408V23.8142V3.33568L68.5225 23.826L68.5343 23.8732H68.5937H78.7394H78.7869L78.7988 23.826L84.1804 3.33568V23.8142V23.8732H84.2398H89.8116H89.871V23.8142V0.187854V0.128906H89.8116Z"
fill="white"
/>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M79.0312 0H90.0003V24H84.052V4.33208L78.9242 23.856L78.9238 23.8572L78.8879 24H68.4342L68.3982 23.8572L68.3979 23.856L63.27 4.33208V24H57.3218V0H68.3146L68.3505 0.142699L68.3509 0.144015L73.6787 20.383L78.9949 0.144015L78.9953 0.142765L79.0312 0ZM73.6788 20.8894L68.2259 0.175015L68.214 0.127854H57.4506V23.8721H63.1412V3.33463L68.5229 23.825L68.5348 23.8721H78.7873L78.7992 23.825L84.1809 3.33463V23.8721H89.8714V0.127854H79.1318L79.1199 0.175015L73.6788 20.8894Z"
fill="white"
/>
<path
d="M48.2909 0.128906H48.2553L48.2434 0.152487L41.4836 11.8124L34.6882 0.152487L34.6763 0.128906H34.6407H28.2135H28.0947L28.1541 0.223225L38.6205 18.2142V23.8142V23.8732H38.6799H44.2517H44.3111V23.8142V18.2142L54.7775 0.223225L54.8369 0.128906H54.7181H48.2909Z"
fill="white"
/>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M48.1757 0H55.0693L54.8879 0.288036L44.4399 18.2474V24H38.4917V18.2474L28.0437 0.288036L27.8623 0H34.756L34.8017 0.0907854L41.4833 11.5555L48.1299 0.0909153L48.1757 0ZM48.2434 0.151434L41.4836 11.8114L34.6882 0.151434L34.6763 0.127854H28.0948L28.1542 0.222173L38.6205 18.2131V23.8721H44.3111V18.2131L54.7775 0.222173L54.8369 0.127854H48.2553L48.2434 0.151434Z"
fill="white"
/>
<path
d="M169.238 0V24H166.422C166.006 24 165.654 23.9341 165.366 23.8023C165.088 23.6596 164.811 23.418 164.534 23.0776L153.542 8.76321C153.584 9.19149 153.611 9.60878 153.622 10.0151C153.643 10.4104 153.654 10.7838 153.654 11.1352V24H148.886V0H151.734C151.968 0 152.166 0.0109813 152.326 0.032944C152.486 0.0549066 152.63 0.0988326 152.758 0.164722C152.886 0.219629 153.008 0.30199 153.126 0.411805C153.243 0.521619 153.376 0.669869 153.526 0.856553L164.614 15.2697C164.56 14.8085 164.523 14.3638 164.502 13.9355C164.48 13.4962 164.47 13.0844 164.47 12.7001V0H169.238Z"
fill="#A8A6A6"
/>
<path
d="M134.206 11.7776C135.614 11.7776 136.627 11.4317 137.246 10.7399C137.865 10.048 138.174 9.08167 138.174 7.84077C138.174 7.29169 138.094 6.79204 137.934 6.3418C137.774 5.89156 137.529 5.50721 137.198 5.18874C136.878 4.8593 136.467 4.60673 135.966 4.43102C135.475 4.25532 134.889 4.16747 134.206 4.16747H131.39V11.7776H134.206ZM134.206 0C135.849 0 137.257 0.203157 138.43 0.609471C139.614 1.0048 140.585 1.55388 141.342 2.25669C142.11 2.95951 142.675 3.78861 143.038 4.74399C143.401 5.69938 143.582 6.73164 143.582 7.84077C143.582 9.03775 143.395 10.1359 143.022 11.1352C142.649 12.1345 142.078 12.9911 141.31 13.7049C140.542 14.4187 139.566 14.9787 138.382 15.385C137.209 15.7804 135.817 15.978 134.206 15.978H131.39V24H125.982V0H134.206Z"
fill="#A8A6A6"
/>
<path
d="M121.584 0L112.24 24H107.344L98 0H102.352C102.821 0 103.2 0.115305 103.488 0.345915C103.776 0.565545 103.995 0.851064 104.144 1.20247L108.656 14.0508C108.869 14.6108 109.077 15.2258 109.28 15.8957C109.483 16.5546 109.675 17.2464 109.856 17.9712C110.005 17.2464 110.171 16.5546 110.352 15.8957C110.544 15.2258 110.747 14.6108 110.96 14.0508L115.44 1.20247C115.557 0.894989 115.765 0.620452 116.064 0.378861C116.373 0.126287 116.752 0 117.2 0H121.584Z"
fill="#A8A6A6"
/>
</svg>
);
NymVpnIcon.defaultProps = {
size: { width: 80, height: 12 },
};
+2 -2
View File
@@ -229,14 +229,14 @@ impl<'a> HttpApiBuilder<'a> {
IpAddr::from(Ipv4Addr::new(10, 1, 0, 0)),
self.gateway_config.wireguard.private_network_prefix,
)?;
let wg_state = self.client_registry.map(|client_registry| {
let wg_state = self.client_registry.and_then(|client_registry| {
WireguardAppState::new(
self.sphinx_keypair,
client_registry,
Default::default(),
self.gateway_config.wireguard.bind_address.port(),
wireguard_private_network,
)
.ok()
});
let router = nym_node::http::NymNodeRouter::new(config, wg_state);
+5
View File
@@ -81,3 +81,8 @@ cpucycles = [
"opentelemetry",
"nym-bin-common/tracing",
]
[package.metadata.deb]
name = "nym-mixnode"
maintainer-scripts = "debian"
systemd-units = { enable = false }
+6
View File
@@ -0,0 +1,6 @@
#DEBHELPER#
useradd nym
mkdir -p /etc/nym
chown -R nym /etc/nym
su nym -c 'NYM_HOME_DIR=/etc/nym nym-mixnode init --host 0.0.0.0 --id nym-mixnode'
+11
View File
@@ -0,0 +1,11 @@
[Unit]
Description=Nym Mixnode
After=network-online.target
[Service]
ExecStart=/usr/bin/nym-mixnode run --id nym-mixnode
User=nym
Environment="NYM_HOME_DIR=/etc/nym"
[Install]
WantedBy=multi-user.target
@@ -1,5 +1,6 @@
import ContractCache from "../../src/endpoints/CirculatingSupply";
let contract: ContractCache;
jest.setTimeout(60000);
describe("Get circulating supply", (): void => {
beforeAll(async (): Promise<void> => {
@@ -1,6 +1,6 @@
import ContractCache from "../../src/endpoints/ContractCache";
let contract: ContractCache;
jest.setTimeout(60000);
describe("Get epoch info", (): void => {
beforeAll(async (): Promise<void> => {
@@ -1,6 +1,6 @@
import ContractCache from "../../../src/endpoints/ContractCache";
let contract: ContractCache;
jest.setTimeout(60000);
describe("Get gateway data", (): void => {
beforeAll(async (): Promise<void> => {
@@ -1,8 +1,9 @@
import ContractCache from "../../../src/endpoints/ContractCache";
import ConfigHandler from "../../../src/config/configHandler";
import ConfigHandler from "../../../../../common/api-test-utils/config/configHandler"
let contract: ContractCache;
let config: ConfigHandler;
jest.setTimeout(60000);
describe("Get mixnode data", (): void => {
beforeAll(async (): Promise<void> => {
@@ -1,5 +1,6 @@
import ContractCache from "../../src/endpoints/ContractCache";
let contract: ContractCache;
jest.setTimeout(60000);
describe("Get service provider info", (): void => {
beforeAll(async (): Promise<void> => {
@@ -1,5 +1,5 @@
import Status from "../../src/endpoints/Status";
import ConfigHandler from "../../src/config/configHandler";
import ConfigHandler from "../../../../common/api-test-utils/config/configHandler"
let status: Status;
let config: ConfigHandler;
@@ -29,7 +29,7 @@ describe("Get gateway data", (): void => {
});
it("Get a gateway history", async (): Promise<void> => {
const identity_key = config.environmnetConfig.gateway_identity;
const identity_key = config.environmentConfig.gateway_identity;
const response = await status.getGatewayHistory(identity_key);
if ("identity" in response) {
@@ -47,14 +47,14 @@ describe("Get gateway data", (): void => {
});
it("Get gateway core status count", async (): Promise<void> => {
const identity_key = config.environmnetConfig.gateway_identity;
const identity_key = config.environmentConfig.gateway_identity;
const response = await status.getGatewayCoreCount(identity_key);
expect(identity_key).toStrictEqual(response.identity);
expect(typeof response.count).toBe("number");
});
it("Get gateway average uptime", async (): Promise<void> => {
const identity_key = config.environmnetConfig.gateway_identity;
const identity_key = config.environmentConfig.gateway_identity;
const response = await status.getGatewayAverageUptime(identity_key);
if ("mix_id" in response) {
expect(identity_key).toStrictEqual(response.identity);
@@ -67,7 +67,7 @@ describe("Get gateway data", (): void => {
});
it("Get a gateway status report", async (): Promise<void> => {
const identity_key = config.environmnetConfig.gateway_identity;
const identity_key = config.environmentConfig.gateway_identity;
const response = await status.getGatewayStatusReport(identity_key);
if ("mix_id" in response) {
expect(identity_key).toStrictEqual(response.identity);
@@ -1,5 +1,5 @@
import Status from "../../src/endpoints/Status";
import ConfigHandler from "../../src/config/configHandler";
import ConfigHandler from "../../../../common/api-test-utils/config/configHandler"
let status: Status;
let config: ConfigHandler;
@@ -11,7 +11,7 @@ describe("Get mixnode data", (): void => {
});
it("Get a mixnode report", async (): Promise<void> => {
const identity_key = config.environmnetConfig.mix_id;
const identity_key = config.environmentConfig.mix_id;
const response = await status.getMixnodeStatusReport(identity_key);
if ("mix_id" in response) {
expect(typeof response.last_day).toBe("number");
@@ -22,7 +22,7 @@ describe("Get mixnode data", (): void => {
});
it("Get a mixnode stake saturation", async (): Promise<void> => {
const identity_key = config.environmnetConfig.mix_id;
const identity_key = config.environmentConfig.mix_id;
const response = await status.getMixnodeStakeSaturation(identity_key);
if ("saturation" in response) {
expect(typeof response.as_at).toBe("number");
@@ -34,7 +34,7 @@ describe("Get mixnode data", (): void => {
});
it("Get a mixnode average uptime", async (): Promise<void> => {
const identity_key = config.environmnetConfig.mix_id;
const identity_key = config.environmentConfig.mix_id;
const response = await status.getMixnodeAverageUptime(identity_key);
if ("mix_id" in response) {
expect(identity_key).toStrictEqual(response.mix_id);
@@ -45,7 +45,7 @@ describe("Get mixnode data", (): void => {
});
it("Get a mixnode history", async (): Promise<void> => {
const identity_key = config.environmnetConfig.mix_id;
const identity_key = config.environmentConfig.mix_id;
const response = await status.getMixnodeHistory(identity_key);
if ("mix_id" in response) {
response.history.forEach((x) => {
@@ -62,14 +62,14 @@ describe("Get mixnode data", (): void => {
});
it("Get a mixnode core count", async (): Promise<void> => {
const identity_key = config.environmnetConfig.mix_id;
const identity_key = config.environmentConfig.mix_id;
const response = await status.getMixnodeCoreCount(identity_key);
expect(identity_key).toStrictEqual(response.mix_id);
expect(typeof response.count).toBe("number");
});
it("Get a mixnode reward estimation", async (): Promise<void> => {
const identity_key = config.environmnetConfig.mix_id;
const identity_key = config.environmentConfig.mix_id;
const response = await status.getMixnodeRewardComputation(identity_key);
if ("estimation" in response) {
expect(response.reward_params.interval.sybil_resistance).toStrictEqual(
@@ -83,7 +83,7 @@ describe("Get mixnode data", (): void => {
});
it("Get a mixnode inclusion probability", async (): Promise<void> => {
const identity_key = config.environmnetConfig.mix_id;
const identity_key = config.environmentConfig.mix_id;
const response = await status.getMixnodeInclusionProbability(identity_key);
if ("mix_id" in response) {
expect(typeof response.in_active).toBe("string");
@@ -119,7 +119,7 @@ describe("Get mixnode data", (): void => {
});
it("Get a mixnode status", async (): Promise<void> => {
const identity_key = config.environmnetConfig.mix_id;
const identity_key = config.environmentConfig.mix_id;
const response = await status.getMixnodeStatus(identity_key);
const unfiltered_mixnodes_response = await status.getUnfilteredMixnodes();
const mixnode = unfiltered_mixnodes_response.find(
@@ -155,11 +155,11 @@ describe("Get mixnode data", (): void => {
});
it("with correct data", async (): Promise<void> => {
const mix_id = config.environmnetConfig.mix_id;
const mix_id = config.environmentConfig.mix_id;
const response = await status.sendMixnodeRewardEstimatedComputation(
mix_id
);
expect(typeof response.estimation.delegates).toBe("string");
expect(typeof response.estimation.total_node_reward).toBe("string");
});
});
});
-8534
View File
File diff suppressed because it is too large Load Diff
+4 -2
View File
@@ -1,7 +1,7 @@
{
"name": "validator-api-test-suite",
"name": "nym-api-test-suite",
"version": "1.0.0",
"description": "a basic validator-api suite to test the validator-api",
"description": "a test suite to test the nym-api using mixfetch",
"main": "dist/index.js",
"directories": {
"test": "test"
@@ -24,7 +24,9 @@
"npm": "8.x"
},
"dependencies": {
"@nymproject/mix-fetch-node-commonjs": "^1.2.4-rc.1",
"axios": "^0.27.2",
"dotenv": "^16.3.1",
"eslint": "^8.21.0",
"form-data": "4.0.0",
"json-stringify-safe": "5.0.1",
@@ -10,20 +10,20 @@ export default class ContractCache extends APIClient {
const response = await this.restClient.sendGet({
route: `circulating-supply`,
});
return response.data;
return response;
}
public async getTotalSupplyValue(): Promise<number> {
const response = await this.restClient.sendGet({
route: `circulating-supply/total-supply-value`,
});
return response.data;
return response;
}
public async getCirculatingSupplyValue(): Promise<number> {
const response = await this.restClient.sendGet({
route: `circulating-supply/circulating-supply-value`,
});
return response.data;
return response;
}
}
+13 -13
View File
@@ -18,7 +18,7 @@ export default class ContractCache extends APIClient {
const response = await this.restClient.sendGet({
route: `mixnodes`,
});
return response.data;
return response;
}
public async getMixnodesDetailed(): Promise<MixnodesDetailed[]> {
@@ -26,83 +26,83 @@ export default class ContractCache extends APIClient {
route: `mixnodes/detailed`,
});
return response.data;
return response;
}
public async getGateways(): Promise<AllGateways[]> {
const response = await this.restClient.sendGet({
route: `gateways`,
});
return response.data;
return response;
}
public async getActiveMixnodes(): Promise<AllMixnodes[]> {
const response = await this.restClient.sendGet({
route: `mixnodes/active`,
});
return response.data;
return response;
}
public async getActiveMixnodesDetailed(): Promise<MixnodesDetailed[]> {
const response = await this.restClient.sendGet({
route: `mixnodes/active/detailed`,
});
return response.data;
return response;
}
public async getRewardedMixnodes(): Promise<AllMixnodes[]> {
const response = await this.restClient.sendGet({
route: `mixnodes/rewarded`,
});
return response.data;
return response;
}
public async getRewardedMixnodesDetailed(): Promise<MixnodesDetailed[]> {
const response = await this.restClient.sendGet({
route: `mixnodes/rewarded/detailed`,
});
return response.data;
return response;
}
public async getBlacklistedMixnodes(): Promise<[]> {
const response = await this.restClient.sendGet({
route: `mixnodes/blacklisted`,
});
return response.data;
return response;
}
public async getBlacklistedGateways(): Promise<[]> {
const response = await this.restClient.sendGet({
route: `gateways/blacklisted`,
});
return response.data;
return response;
}
public async getEpochRewardParams(): Promise<EpochRewardParams> {
const response = await this.restClient.sendGet({
route: `epoch/reward_params`,
});
return response.data;
return response;
}
public async getCurrentEpoch(): Promise<CurrentEpoch> {
const response = await this.restClient.sendGet({
route: `epoch/current`,
});
return response.data;
return response;
}
public async getServiceProviders(): Promise<ServiceProviders> {
const response = await this.restClient.sendGet({
route: `services`,
});
return response.data;
return response;
}
public async getNymAddressNames(): Promise<NymAddressNames> {
const response = await this.restClient.sendGet({
route: `names`,
});
return response.data;
return response;
}
}
+3 -3
View File
@@ -10,20 +10,20 @@ export default class NetworkTypes extends APIClient {
const response = await this.restClient.sendGet({
route: `network/details`,
});
return response.data;
return response;
}
public async getNymContractInfo(): Promise<NymContracts> {
const response = await this.restClient.sendGet({
route: `network/nym-contracts`,
});
return response.data;
return response;
}
public async getNymContractDetailedInfo(): Promise<NymContractsDetailed> {
const response = await this.restClient.sendGet({
route: `network/nym-contracts-detailed`,
});
return response.data;
return response;
}
}
+20 -21
View File
@@ -26,7 +26,7 @@ export default class Status extends APIClient {
route: `/gateways/detailed`,
});
return response.data;
return response;
}
public async getUnfilteredGateways(): Promise<DetailedGateway[]> {
@@ -34,7 +34,7 @@ export default class Status extends APIClient {
route: `/gateways/detailed-unfiltered`,
});
return response.data;
return response;
}
public async getGatewayStatusReport(
@@ -44,7 +44,7 @@ export default class Status extends APIClient {
route: `/gateway/${identity_key}/report`,
});
return response.data;
return response;
}
public async getGatewayHistory(
@@ -54,7 +54,7 @@ export default class Status extends APIClient {
route: `/gateway/${identity_key}/history`,
});
return response.data;
return response;
}
public async getGatewayCoreCount(identity_key: string): Promise<CoreCount> {
@@ -62,7 +62,7 @@ export default class Status extends APIClient {
route: `/gateway/${identity_key}/core-status-count`,
});
return response.data;
return response;
}
public async getGatewayAverageUptime(
@@ -72,7 +72,7 @@ export default class Status extends APIClient {
route: `/gateway/${identity_key}/avg_uptime`,
});
return response.data;
return response;
}
// MIXNODES
@@ -84,7 +84,7 @@ export default class Status extends APIClient {
route: `/mixnode/${mix_id}/report`,
});
return response.data;
return response;
}
public async getMixnodeStakeSaturation(
@@ -94,7 +94,7 @@ export default class Status extends APIClient {
route: `/mixnode/${mix_id}/stake-saturation`,
});
return response.data;
return response;
}
public async getMixnodeCoreCount(mix_id: number): Promise<CoreCount> {
@@ -102,7 +102,7 @@ export default class Status extends APIClient {
route: `/mixnode/${mix_id}/core-status-count`,
});
return response.data;
return response;
}
public async getMixnodeRewardComputation(
@@ -112,7 +112,7 @@ export default class Status extends APIClient {
route: `/mixnode/${mix_id}/reward-estimation`,
});
return response.data;
return response;
}
public async sendMixnodeRewardEstimatedComputation(
@@ -132,8 +132,7 @@ export default class Status extends APIClient {
// profit_margin_percent: 10
},
});
return response.data;
return response;
}
public async getMixnodeHistory(
@@ -143,7 +142,7 @@ export default class Status extends APIClient {
route: `/mixnode/${mix_id}/history`,
});
return response.data;
return response;
}
public async getMixnodeAverageUptime(
@@ -153,7 +152,7 @@ export default class Status extends APIClient {
route: `/mixnode/${mix_id}/avg_uptime`,
});
return response.data;
return response;
}
public async getMixnodeInclusionProbability(
@@ -163,7 +162,7 @@ export default class Status extends APIClient {
route: `/mixnode/${mix_id}/inclusion-probability`,
});
return response.data;
return response;
}
public async getMixnodeStatus(mix_id: number): Promise<ActiveStatus> {
@@ -171,7 +170,7 @@ export default class Status extends APIClient {
route: `/mixnode/${mix_id}/status`,
});
return response.data;
return response;
}
public async getAllMixnodeInclusionProbability(): Promise<InclusionProbabilities> {
@@ -179,7 +178,7 @@ export default class Status extends APIClient {
route: `/mixnodes/inclusion_probability`,
});
return response.data;
return response;
}
public async getDetailedMixnodes(): Promise<DetailedMixnodes[]> {
@@ -187,7 +186,7 @@ export default class Status extends APIClient {
route: `/mixnodes/detailed`,
});
return response.data;
return response;
}
public async getDetailedRewardedMixnodes(): Promise<DetailedMixnodes[]> {
@@ -195,7 +194,7 @@ export default class Status extends APIClient {
route: `/mixnodes/rewarded/detailed`,
});
return response.data;
return response;
}
public async getUnfilteredMixnodes(): Promise<DetailedMixnodes[]> {
@@ -203,7 +202,7 @@ export default class Status extends APIClient {
route: `/mixnodes/detailed-unfiltered`,
});
return response.data;
return response;
}
public async getDetailedActiveMixnodes(): Promise<DetailedMixnodes[]> {
@@ -211,6 +210,6 @@ export default class Status extends APIClient {
route: `/mixnodes/active/detailed`,
});
return response.data;
return response;
}
}
@@ -1,12 +1,12 @@
import { Logger } from "tslog";
import ConfigHandler from "../../config/configHandler";
import { RestClient } from "../../restClient/RestClient";
import ConfigHandler from "../../../../../common/api-test-utils/config/configHandler";
import { MixFetchClient } from "../../../../../common/api-test-utils/restClient/MixFetchClient";
export abstract class APIClient {
protected constructor(serviceUrl: string) {
const baseUrl: string = this.config.environmnetConfig.api_base_url;
const baseUrl: string = this.config.environmentConfig.api_base_url;
this.url = baseUrl + serviceUrl;
this.restClient = new RestClient(this.url);
this.restClient = new MixFetchClient(this.url);
this.serviceName = this.constructor.toString().match(/\w+/g)[1];
this.log.info(`The Service URL for ${this.serviceName} is ${this.url}`);
}
@@ -16,15 +16,15 @@ export abstract class APIClient {
protected config = ConfigHandler.getInstance();
protected log: Logger = new Logger({
minLevel: this.config.environmnetConfig.log_level,
minLevel: this.config.environmentConfig.log_level,
dateTimeTimezone:
this.config.environmnetConfig.time_zone ||
this.config.environmentConfig.time_zone ||
Intl.DateTimeFormat().resolvedOptions().timeZone,
});
protected url: string;
public restClient: RestClient;
public restClient: MixFetchClient;
protected serviceName: string;
}
-243
View File
@@ -1,243 +0,0 @@
import axios, {
AxiosInstance,
AxiosRequestConfig,
AxiosResponse,
Method,
} from "axios";
import { Logger } from "tslog";
import { stringify } from "yaml";
import https from "https";
import ConfigHandler from "../config/configHandler";
const config = ConfigHandler.getInstance();
const log = new Logger({
minLevel: config.environmnetConfig.log_level,
dateTimeTimezone:
config.environmnetConfig.time_zone ||
Intl.DateTimeFormat().resolvedOptions().timeZone,
});
function isSet(property): boolean {
return property !== undefined && property !== null;
}
export class RestClient {
private static authToken: string;
private axiosInstance: AxiosInstance;
constructor(baseUrl: string) {
this.axiosInstance = axios.create({ baseURL: baseUrl });
}
private httpsAgent = new https.Agent({
rejectUnauthorized: false,
});
// Not returning an actual auth token for this example project.
// Just showing how it can be done!
static async getToken(requestHeaders: object) {
requestHeaders["Authorization"] = `asdf`;
}
public async callEndpoint({
route,
method,
authToken,
headers,
data,
additionalConfigs,
params,
}: IAxiosCallEndpointArgs): Promise<AxiosResponse> {
let response;
let responseLog = "Response: ";
let requestHeaders = headers;
// if headers are not passed in, use the default headers
if (requestHeaders == undefined) {
requestHeaders = { ...config.commonConfig.request_headers };
}
// if authToken is passed in, add it to the request headers
if (authToken !== undefined) {
requestHeaders = {
...requestHeaders,
...{
Authorization: `Bearer ${authToken}`,
},
};
}
// if we have not set the auth headers yet, set them
else if (!requestHeaders.Authorization) {
await RestClient.getToken(requestHeaders);
}
log.debug(
RestClient.prepareLogRecord({
route,
method,
headers: requestHeaders,
data,
additionalConfigs,
params,
})
);
await this.axiosInstance
.request({
url: route,
method,
data,
headers: requestHeaders,
httpsAgent: this.httpsAgent,
params,
...additionalConfigs,
})
.then((res) => {
response = res;
responseLog = `<Success> Status = ${res.status} ${res.statusText}`;
})
.catch((error) => {
response = error.response;
if (response === undefined)
responseLog = `<Error> Something wrong happened, did not get proper error from server! (${error.message})`;
else
responseLog = `<Error> Status = ${response.status} ${response.statusText}, ${error.message}`;
});
log.debug(responseLog);
return response;
}
public async sendPost({
route,
authToken,
data,
params,
headers,
additionalConfigs,
}: IAxiosHttpRequestArgs): Promise<any> {
return this.callEndpoint({
route,
method: "POST",
authToken,
data,
params,
headers,
additionalConfigs,
});
}
public async sendGet({
route,
authToken,
params,
headers,
additionalConfigs,
}: IAxiosHttpRequestArgs): Promise<any> {
return this.callEndpoint({
route,
method: "GET",
authToken,
params,
headers,
additionalConfigs,
});
}
public async sendDelete({
route,
authToken,
params,
headers,
additionalConfigs,
}: IAxiosHttpRequestArgs): Promise<any> {
return this.callEndpoint({
route,
method: "DELETE",
authToken,
params,
headers,
additionalConfigs,
});
}
public async sendPatch({
route,
authToken,
data,
headers,
additionalConfigs,
}: IAxiosHttpRequestArgs): Promise<any> {
return this.callEndpoint({
route,
method: "PATCH",
authToken,
data,
headers,
additionalConfigs,
});
}
public async sendPut({
route,
authToken,
data,
headers,
additionalConfigs,
}: IAxiosHttpRequestArgs): Promise<any> {
return this.callEndpoint({
route,
method: "PUT",
authToken,
data,
headers,
additionalConfigs,
});
}
private static prepareLogRecord({
route,
method,
headers,
data,
additionalConfigs,
params,
}: IAxiosCallEndpointArgs): string {
let logRecord = `Request: ${method} ${route}`;
if (isSet(headers))
logRecord = `${logRecord}\nHeaders: ${stringify(headers)}`;
if (isSet(params)) logRecord = `${logRecord}\nParams: ${stringify(params)}`;
if (isSet(additionalConfigs)) {
logRecord = `${logRecord}\nAdditional Configuration: ${stringify(
additionalConfigs
)}`;
}
if (isSet(data)) {
const jsonData = stringify(data);
// We don't want to log anything that isn't json data
logRecord = `${logRecord}\nData: ${
jsonData === undefined ? "Some data, not JSON!" : jsonData
}`;
}
return logRecord;
}
}
export interface IAxiosHttpRequestArgs {
route: string;
authToken?: string;
data?: object;
params?: object;
headers?: any;
additionalConfigs?: AxiosRequestConfig;
}
export interface IAxiosCallEndpointArgs extends IAxiosHttpRequestArgs {
method: Method;
}
+828 -862
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "extension-storage"
version = "1.2.4-rc.1"
version = "1.2.4-rc.2"
edition = "2021"
license = "Apache-2.0"
repository = "https://github.com/nymtech/nym"
+1
View File
@@ -50,6 +50,7 @@ nym-config = { path = "../common/config" }
nym-crypto = { path = "../common/crypto", features = ["asymmetric" ]}
nym-node-requests = { path = "nym-node-requests", default-features = false, features = ["openapi"]}
nym-task = { path = "../common/task" }
nym-wireguard = { path = "../common/wireguard" }
nym-wireguard-types = { path = "../common/wireguard-types", features = ["verify"] }
[dev-dependencies]
+6
View File
@@ -31,6 +31,12 @@ pub enum NymNodeError {
source: WireguardError,
},
#[error(transparent)]
KeyRecoveryError {
#[from]
source: nym_crypto::asymmetric::encryption::KeyRecoveryError,
},
#[error("unimplemented")]
Unimplemented,
}
@@ -31,10 +31,7 @@ async fn process_final_message(
}
};
if client
.verify(state.dh_keypair.private_key(), preshared_nonce)
.is_ok()
{
if client.verify(&state.private_key, preshared_nonce).is_ok() {
state.registration_in_progress.remove(&client.pub_key());
state.client_registry.insert(client.pub_key(), client);
@@ -104,7 +101,7 @@ pub(crate) async fn register_client(
// mark it as used, even though it's not final
*private_ip_ref = false;
let gateway_data = GatewayClient::new(
state.dh_keypair.private_key(),
&state.private_key,
remote_public,
*private_ip_ref.key(),
nonce,
@@ -8,8 +8,9 @@ use crate::wireguard::types::{GatewayClientRegistry, PendingRegistrations};
use axum::routing::{get, post};
use axum::Router;
use ipnetwork::IpNetwork;
use nym_crypto::asymmetric::encryption;
use nym_crypto::asymmetric::encryption::PrivateKey;
use nym_node_requests::routes::api::v1::gateway::client_interfaces::wireguard;
use nym_wireguard::setup;
use nym_wireguard_types::registration::PrivateIPs;
use std::sync::Arc;
@@ -24,15 +25,16 @@ pub struct WireguardAppState {
impl WireguardAppState {
pub fn new(
dh_keypair: Arc<encryption::KeyPair>,
client_registry: Arc<GatewayClientRegistry>,
registration_in_progress: Arc<PendingRegistrations>,
binding_port: u16,
private_ip_network: IpNetwork,
) -> Self {
WireguardAppState {
) -> Result<Self, crate::error::NymNodeError> {
Ok(WireguardAppState {
inner: Some(WireguardAppStateInner {
dh_keypair,
private_key: Arc::new(PrivateKey::from_bytes(
setup::server_static_private_key().as_ref(),
)?),
client_registry,
registration_in_progress,
binding_port,
@@ -40,7 +42,7 @@ impl WireguardAppState {
private_ip_network.iter().map(|ip| (ip, true)).collect(),
),
}),
}
})
}
// #[allow(dead_code)]
@@ -79,7 +81,7 @@ macro_rules! get_state {
#[derive(Clone)]
pub(crate) struct WireguardAppStateInner {
dh_keypair: Arc<encryption::KeyPair>,
private_key: Arc<PrivateKey>,
client_registry: Arc<GatewayClientRegistry>,
registration_in_progress: Arc<PendingRegistrations>,
binding_port: u16,
@@ -112,6 +114,7 @@ mod test {
PeerPublicKey,
};
use nym_node_requests::routes::api::v1::gateway::client_interfaces::wireguard;
use nym_wireguard::setup::server_static_private_key;
use nym_wireguard_types::registration::HmacSha256;
use std::net::IpAddr;
use std::str::FromStr;
@@ -130,8 +133,15 @@ mod test {
// 6. Gateway verifies mac digest and nonce, and stores client's public key and socket address and port
let mut rng = rand::thread_rng();
let gateway_private_key =
encryption::PrivateKey::from_bytes(server_static_private_key().as_bytes()).unwrap();
let gateway_public_key = encryption::PublicKey::from(&gateway_private_key);
let gateway_key_pair = encryption::KeyPair::new(&mut rng);
let gateway_key_pair = encryption::KeyPair::from_bytes(
&gateway_private_key.to_bytes(),
&gateway_public_key.to_bytes(),
)
.unwrap();
let client_key_pair = encryption::KeyPair::new(&mut rng);
let gateway_static_public =
@@ -158,7 +168,7 @@ mod test {
let state = WireguardAppState {
inner: Some(WireguardAppStateInner {
client_registry: Arc::clone(&client_registry),
dh_keypair: Arc::new(gateway_key_pair),
private_key: Arc::new(gateway_private_key),
registration_in_progress: Arc::clone(&registration_in_progress),
binding_port: 8080,
free_private_network_ips,
+32
View File
@@ -0,0 +1,32 @@
{
"root": true,
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended"
],
"parser": "@typescript-eslint/parser",
"plugins": [
"@typescript-eslint"
],
"rules": {
"import/extensions": "off",
"no-console": ["warn", { "allow": ["warn", "error"] }],
"import/prefer-default-export": "off",
"prettier/prettier": ["error"]
},
"overrides": [
{
"files": ["**/*.ts", "**/*.tsx"],
"rules": {
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-explicit-any": "off",
"no-shadow": "off",
"@typescript-eslint/no-shadow": ["error"]
}
}
]
}
+6
View File
@@ -0,0 +1,6 @@
node_modules
dist
coverage/
.DS_Store
.idea/
junit.xml
@@ -0,0 +1,71 @@
import Gateway from "../../src/endpoints/Gateways";
import { getGatewayIPAddresses } from "../../src/helpers/helper";
describe("Get gateway related info", (): void => {
let contract: Gateway;
let gatewayHosts: string[];
beforeAll(async (): Promise<void> => {
try {
gatewayHosts = await getGatewayIPAddresses();
} catch (error) {
throw new Error(`Error fetching gateway IP addresses: ${error.message}`);
}
});
beforeEach(async (): Promise<void> => {
// Testing only 3 nodes from the list
for (let i = 3; i < gatewayHosts.length; i++) {
console.log("currently trying gateway host", gatewayHosts[i]);
contract = new Gateway(gatewayHosts[i]);
}
});
// TODO this test is failing, it's incorrectly entering the else statement
it.skip("Get root gateway information", async (): Promise<void> => {
const response = await contract.getGatewayInformation();
console.log(response);
console.log(response.wireguard);
if (response.wireguard === null) {
console.log("This is the code I should be entering............");
expect(response.wireguard).toBeNull();
expect(typeof response.mixnet_websockets.ws_port).toBe("number");
expect(typeof response.mixnet_websockets.wss_port).toBe("number");
return;
} else {
console.log(
"This is wrong, I shouldn't be in the else statement.........",
);
console.log(response.wireguard);
expect(typeof response.wireguard.port).toBe("number");
expect(typeof response.wireguard.public_key).toBe("string");
expect(typeof response.mixnet_websockets.ws_port).toBe("number");
expect(typeof response.mixnet_websockets.wss_port).toBe("number");
}
});
it("Get client interfaces supported by gateway", async (): Promise<void> => {
const response = await contract.getGatewayClientInterfaces();
if (response.wireguard === null) {
expect(response.wireguard).toBeNull();
} else {
expect(typeof response.wireguard.port).toBe("number");
expect(typeof response.wireguard.public_key).toBe("string");
expect(typeof response.mixnet_websockets.ws_port).toBe("number");
expect(typeof response.mixnet_websockets.wss_port).toBe("number");
}
});
it("Get mixnet websocket info", async (): Promise<void> => {
const response = await contract.getMixnetWebsocketInfo();
expect(typeof response.ws_port).toBe("number");
expect(
typeof response.wss_port === "number" || response.wss_port === null,
).toBe(true);
});
// it("Get wireguard info", async (): Promise<void> => {
// const response = await contract.getWireguardInfo();
// expect(typeof response.port).toBe("number");
// expect(typeof response.public_key).toBe("string");
// });
});
@@ -0,0 +1,29 @@
import Mixnode from "../../src/endpoints/Mixnodes";
import { getMixnodeIPAddresses } from '../../src/helpers/helper';
describe("Get mixnode related info", (): void => {
let contract: Mixnode;
let mixnodeHosts: string[];
beforeAll(async (): Promise<void> => {
try {
mixnodeHosts = await getMixnodeIPAddresses();
console.log(mixnodeHosts)
} catch (error) {
throw new Error(`Error fetching mixnode IP addresses: ${error.message}`);
}
});
beforeEach(async (): Promise<void> => {
// Testing only 3 nodes from the list
for (let i = 3; i < mixnodeHosts.length; i++) {
console.log("currently trying mixnode host", mixnodeHosts[i])
contract = new Mixnode(mixnodeHosts[i]);
}
});
it("Get mixnode details", async (): Promise<void> => {
const response = await contract.getMixnodeInfo();
// This response is currently just empty {}, amend it when it changes
expect(response).toEqual({});
});
});
@@ -0,0 +1,57 @@
import Nodes from "../../src/endpoints/Node";
import { getGatewayIPAddresses } from "../../src/helpers/helper";
describe("Get Node information", (): void => {
let contract: Nodes;
let gatewayHosts: string[];
beforeAll(async (): Promise<void> => {
try {
gatewayHosts = await getGatewayIPAddresses();
// console.log(gatewayHosts);
} catch (error) {
throw new Error(`Error fetching gateway IP addresses: ${error.message}`);
}
});
beforeEach(async (): Promise<void> => {
for (let i = 0; i < gatewayHosts.length; i++) {
// console.log("currently trying gateway host", gatewayHosts[i]);
contract = new Nodes(gatewayHosts[i]);
}
});
it("Get build data for the binary running the API", async (): Promise<void> => {
const response = await contract.getBuildInformation();
expect(typeof response.binary_name).toBe("string");
expect(typeof response.build_timestamp).toBe("string");
expect(typeof response.build_version).toBe("string");
expect(typeof response.cargo_profile).toBe("string");
expect(typeof response.commit_branch).toBe("string");
expect(typeof response.commit_sha).toBe("string");
expect(typeof response.commit_timestamp).toBe("string");
expect(typeof response.rustc_channel).toBe("string");
expect(typeof response.rustc_version).toBe("string");
});
it("Get host information for the node", async (): Promise<void> => {
const response = await contract.getHostInformation();
response.data.ip_address.forEach((x) => {
expect(typeof x).toBe("string");
});
// expect(typeof response.data.hostname).toBe("string" || "null");
expect(
typeof response.data.hostname === "string" ||
response.data.hostname === null,
).toBe(true);
expect(typeof response.data.keys.ed25519).toBe("string");
expect(typeof response.data.keys.x25519).toBe("string");
expect(typeof response.signature).toBe("string");
});
it("Get roles supported by the node", async (): Promise<void> => {
const response = await contract.getSupportedRoles();
expect(typeof response.gateway_enabled).toBe("boolean");
expect(typeof response.mixnode_enabled).toBe("boolean");
expect(typeof response.network_requester_enabled).toBe("boolean");
});
});
+6
View File
@@ -0,0 +1,6 @@
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
reporters: ["default", "jest-junit"],
collectCoverageFrom: ["src/**/*.ts"],
};
+51
View File
@@ -0,0 +1,51 @@
{
"name": "nym-node-test-suite",
"version": "1.0.0",
"description": "a basic nym-node-api suite to test the nym-node-api using mixfetch",
"main": "dist/index.js",
"directories": {
"test": "test"
},
"scripts": {
"test:sandbox": "TEST_ENV=sandbox jest --forceExit --detectOpenHandles --passWithNoTests",
"test:prod": "TEST_ENV=prod jest --forceExit --detectOpenHandles --passWithNoTests",
"build": "tsc",
"lint": "eslint --fix --ext .js,.ts,.tsx .",
"lint:fix": "eslint src --fix",
"cleanup": "rm -rf node_modules; rm -rf dist; yarn install"
},
"author": "Nymtech",
"license": "MIT",
"files": [
"dist"
],
"engines": {
"node": "18.1.0",
"npm": "8.x"
},
"dependencies": {
"@nymproject/mix-fetch-node-commonjs": "^1.2.4-rc.1",
"eslint": "^8.51.0",
"form-data": "4.0.0",
"json-stringify-safe": "5.0.1",
"tslog": "../../node_modules/tslog",
"uuid": "8.3.2",
"yaml": "^2.2.2"
},
"devDependencies": {
"@types/jest": "^29.5.5",
"@types/node": "^20.8.4",
"@typescript-eslint/eslint-plugin": "^5.12.1",
"@typescript-eslint/parser": "^5.33.0",
"axios-mock-adapter": "^1.20.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.1",
"jest": "^28.1.3",
"jest-junit": "^14.0.0",
"prettier": "^3.0.3",
"process": "0.11.10",
"ts-jest": "28.0.7",
"typescript": "^4.7.4",
"uuidv4": "^6.2.12"
}
}
+40
View File
@@ -0,0 +1,40 @@
import {
ClientInterfaces,
MixnetWebsockets,
Wireguard,
} from "../types/GatewayTypes";
import { APIClient } from "./abstracts/APIClient";
export default class Gateway extends APIClient {
constructor(baseUrl: string) {
super(baseUrl, "/");
}
public async getGatewayInformation(): Promise<ClientInterfaces> {
const response = await this.restClient.sendGet({
route: `gateway`,
});
return response;
}
public async getGatewayClientInterfaces(): Promise<ClientInterfaces> {
const response = await this.restClient.sendGet({
route: `gateway/client-interfaces`,
});
return response;
}
public async getMixnetWebsocketInfo(): Promise<MixnetWebsockets> {
const response = await this.restClient.sendGet({
route: `gateway/client-interfaces/mixnet-websockets`,
});
return response;
}
public async getWireguardInfo(): Promise<Wireguard> {
const response = await this.restClient.sendGet({
route: `gateway/client-interfaces/wireguard`,
});
return response;
}
}
+15
View File
@@ -0,0 +1,15 @@
import { Mixnodes } from "../types/MixnodeTypes";
import { APIClient } from "./abstracts/APIClient";
export default class Mixnode extends APIClient {
constructor(baseUrl: string) {
super(baseUrl, "/");
}
public async getMixnodeInfo(): Promise<Mixnodes> {
const response = await this.restClient.sendGet({
route: `mixnode`,
});
return response;
}
}
+29
View File
@@ -0,0 +1,29 @@
import { BuildInformation, HostInformation, Roles } from "../types/NodeTypes";
import { APIClient } from "./abstracts/APIClient";
export default class Nodes extends APIClient {
constructor(baseUrl: string) {
super(baseUrl, "/");
}
public async getBuildInformation(): Promise<BuildInformation> {
const response = await this.restClient.sendGet({
route: `build-information`,
});
return response;
}
public async getHostInformation(): Promise<HostInformation> {
const response = await this.restClient.sendGet({
route: `host-information`,
});
return response;
}
public async getSupportedRoles(): Promise<Roles> {
const response = await this.restClient.sendGet({
route: `roles`,
});
return response;
}
}
@@ -0,0 +1,29 @@
import { Logger } from "tslog";
import ConfigHandler from "../../../../../common/api-test-utils/config/configHandler";
import { MixFetchClient } from "../../../../../common/api-test-utils/restClient/MixFetchClient";
export abstract class APIClient {
protected constructor(baseUrl: string, serviceUrl: string) {
this.url = baseUrl + serviceUrl;
this.restClient = new MixFetchClient(this.url);
this.serviceName = this.constructor.toString().match(/\w+/g)[1];
this.log.info(`The Service URL for ${this.serviceName} is ${this.url}`);
}
public createdItemIds: Set<string> = new Set();
protected config = ConfigHandler.getInstance();
protected log: Logger = new Logger({
minLevel: this.config.environmentConfig.log_level,
dateTimeTimezone:
this.config.environmentConfig.time_zone ||
Intl.DateTimeFormat().resolvedOptions().timeZone,
});
protected url: string;
public restClient: MixFetchClient;
protected serviceName: string;
}
+46
View File
@@ -0,0 +1,46 @@
import { APIClient } from "../../src/endpoints/abstracts/APIClient";
import ConfigHandler from "../../../../common/api-test-utils/config/configHandler";
const configHandler = ConfigHandler.getInstance();
let helper: Helper;
const apiBaseUrl = configHandler.environmentConfig.api_base_url;
export default class Helper extends APIClient {
constructor() {
super(apiBaseUrl, "");
}
}
export async function getGatewayIPAddresses(): Promise<string[]> {
helper = new Helper();
try {
const response = await helper.restClient.sendGet({
route: `/gateways`,
});
const hosts = response.map((item: { gateway: { host: string } }) => {
const host = item.gateway.host;
const apiUrl = `http://${host}:8080/api/v1`;
return apiUrl;
});
return hosts;
} catch (error) {
throw new Error(`Error fetching gateway IP addresses: ${error.message}`);
}
}
export async function getMixnodeIPAddresses(): Promise<string[]> {
helper = new Helper();
try {
const response = await helper.restClient.sendGet({
route: `/mixnodes`,
});
const hosts = response.map((item: { bond_information: { mix_node: { host: string } } } ) => {
const host = item.bond_information.mix_node.host;
const apiUrl = `http://${host}:8000/api/v1`;
return apiUrl;
});
return hosts;
} catch (error) {
throw new Error(`Error fetching mixnode IP addresses: ${error.message}`);
}
}
+14
View File
@@ -0,0 +1,14 @@
export interface ClientInterfaces {
mixnet_websockets: MixnetWebsockets;
wireguard: Wireguard;
}
export interface MixnetWebsockets {
ws_port: number | null;
wss_port: number | null;
}
export interface Wireguard {
port: number | null;
public_key: string;
}
+1
View File
@@ -0,0 +1 @@
export interface Mixnodes {}
+33
View File
@@ -0,0 +1,33 @@
export interface BuildInformation {
binary_name: string;
build_timestamp: string;
build_version: string;
cargo_profile: string;
commit_branch: string;
commit_sha: string;
commit_timestamp: string;
rustc_channel: string;
rustc_version: string;
}
export interface HostInformation {
data: Data;
signature: string;
}
export interface Data {
hostname: string | null;
ip_address: string[];
keys: Keys;
}
export interface Keys {
ed25519: string;
x25519: string;
}
export interface Roles {
gateway_enabled: boolean;
mixnode_enabled: boolean;
network_requester_enabled: boolean;
}
+26
View File
@@ -0,0 +1,26 @@
{
"compilerOptions": {
"removeComments": true,
"allowJs": true,
"preserveConstEnums": true,
"module": "commonjs",
"target": "ES2019",
"declaration": true,
"esModuleInterop": true,
"sourceMap": true,
"lib": ["esnext"],
"outDir": "dist",
"resolveJsonModule": true,
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"paths": {
"*": ["types/*"],
"common/api-test-utils": ["../../common/api-test-utils/index.ts"]
},
"baseUrl": "./",
"typeRoots": ["node_modules/@types"],
"alwaysStrict": true
},
"include": ["src/**/*", "tests/functional_test/*/*"],
"exclude": ["unit_test/**/*"]
}
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -13,7 +13,7 @@ This is the application UI layer for the next NymVPN clients.
Some system libraries are required depending on the host platform.
Follow the instructions for your specific OS [here](https://tauri.app/v1/guides/getting-started/prerequisites)
To install run
To install:
```
yarn
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@nymproject/nym-wallet-app",
"version": "1.2.12-rc.1",
"version": "1.2.12-rc.2",
"license": "MIT",
"main": "index.js",
"scripts": {
+5 -1
View File
@@ -51,6 +51,10 @@
"lerna": "^7.3.0",
"npm-run-all": "^4.1.5",
"@npmcli/node-gyp": "^3.0.0",
"node-gyp": "^9.3.1"
"node-gyp": "^9.3.1",
"tslog": "3.3.3",
"@nymproject/mix-fetch-node-commonjs": "^1.2.4-rc.1",
"fake-indexeddb": "^5.0.0",
"ws": "^8.14.2"
}
}
+1 -1
View File
@@ -28,7 +28,7 @@ tokio = { workspace = true, features = ["sync", "time"] }
log = "0.4.17"
rand = "0.7.3"
safer-ffi = { version = "0.1.0-rc1" }
safer-ffi = { version = "0.1.4" }
[target.'cfg(target_os="android")'.dependencies]
jni = { version = "0.21", default-features = false }
@@ -1,6 +1,6 @@
{
"name": "@nymproject/contract-clients",
"version": "1.2.4-rc.1",
"version": "1.2.4-rc.2",
"description": "A client for all Nym smart contracts",
"license": "Apache-2.0",
"author": "Nym Technologies SA",
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@nymproject/ts-sdk-docs",
"version": "1.2.4-rc.1",
"version": "1.2.4-rc.2",
"description": "Nym Typescript SDK Docs",
"license": "Apache-2.0",
"author": "Nym Technologies SA",
@@ -28,9 +28,9 @@
"@mui/icons-material": "^5.14.9",
"@mui/lab": "^5.0.0-alpha.145",
"@mui/material": "^5.14.8",
"@nymproject/contract-clients": ">=1.2.4-rc.1 || ^1",
"@nymproject/mix-fetch-full-fat": ">=1.2.4-rc.1 || ^1",
"@nymproject/sdk-full-fat": ">=1.2.4-rc.1 || ^1",
"@nymproject/contract-clients": ">=1.2.4-rc.2 || ^1",
"@nymproject/mix-fetch-full-fat": ">=1.2.4-rc.2 || ^1",
"@nymproject/sdk-full-fat": ">=1.2.4-rc.2 || ^1",
"chain-registry": "^1.19.0",
"cosmjs-types": "^0.8.0",
"next": "^13.4.19",
@@ -50,4 +50,4 @@
"typescript": "^4.9.3"
},
"private": false
}
}
@@ -16,6 +16,8 @@ in combination with their own configuration. If you are trying to access somethi
3. If you are using `mixFetch` in a web app with HTTPS you will need to use a gateway that has Secure Websockets to
avoid getting a [mixed content](https://developer.mozilla.org/en-US/docs/Web/Security/Mixed_content) error.
4. For now, mixfetch doesn't work with SURBS, altough this may change in the future.
Read [this article](https://blog.nymtech.net/mixfetch-like-the-fetch-api-but-via-the-mixnet-82acfd435c62) to learn more about mixFetch.
@@ -1,6 +1,6 @@
{
"name": "@nymproject/sdk-example-plain-html-parcel",
"version": "1.0.4-rc.1",
"version": "1.0.4-rc.2",
"description": "An example project that uses WASM and plain HTML bundled with Parcel v2",
"license": "Apache-2.0",
"scripts": {
@@ -1,6 +1,6 @@
{
"name": "@nymproject/sdk-example-plain-html",
"version": "1.0.4-rc.1",
"version": "1.0.4-rc.2",
"description": "An example project that uses WASM and plain HTML",
"license": "Apache-2.0",
"scripts": {
@@ -1,6 +1,6 @@
{
"name": "@nymproject/sdk-example-react-webpack-wasm",
"version": "1.0.4-rc.1",
"version": "1.0.4-rc.2",
"description": "An example project that uses WASM, React, Webpack, Typescript and the Nym theme + components library",
"license": "Apache-2.0",
"scripts": {
@@ -1,6 +1,6 @@
{
"name": "@nymproject/sdk-example-chrome-extension",
"version": "1.0.4-rc.1",
"version": "1.0.4-rc.2",
"description": "This is an example of how Nym can be used within the context of a Chrome extension.",
"license": "ISC",
"author": "",
@@ -1,6 +1,6 @@
{
"name": "@nymproject/sdk-example-firefox-extension",
"version": "1.0.4-rc.1",
"version": "1.0.4-rc.2",
"description": "This is an example of how Nym can be used within the context of a Firefox extension.",
"license": "ISC",
"author": "",
@@ -1,6 +1,6 @@
{
"name": "@nymproject/mix-fetch-example-parcel",
"version": "1.0.4-rc.1",
"version": "1.0.4-rc.2",
"license": "Apache-2.0",
"scripts": {
"build": "parcel build --no-cache --no-content-hash",
@@ -1,6 +1,6 @@
{
"name": "@nymproject/sdk-example-node-tester-plain-html-parcel",
"version": "1.0.4-rc.1",
"version": "1.0.4-rc.2",
"description": "An example project that uses WASM and plain HTML bundled with Parcel v2",
"license": "Apache-2.0",
"scripts": {
@@ -1,6 +1,6 @@
{
"name": "@nymproject/sdk-example-node-tester-plain-html",
"version": "1.0.4-rc.1",
"version": "1.0.4-rc.2",
"description": "An example project that uses WASM node tester and plain HTML",
"license": "Apache-2.0",
"scripts": {
@@ -1,6 +1,6 @@
{
"name": "@nymproject/sdk-example-node-tester-react",
"version": "1.0.4-rc.1",
"version": "1.0.4-rc.2",
"description": "An example project that uses WASM node tester and React",
"license": "Apache-2.0",
"scripts": {
@@ -1,6 +1,6 @@
{
"name": "@nymproject/mix-fetch-node",
"version": "1.2.4-rc.1",
"version": "1.2.4-rc.2",
"description": "This package is a drop-in replacement for `fetch` in NodeJS to send HTTP requests over the Nym Mixnet.",
"license": "Apache-2.0",
"author": "Nym Technologies SA",
@@ -28,7 +28,7 @@
"tsc": "tsc --noEmit true"
},
"dependencies": {
"@nymproject/mix-fetch-wasm-node": ">=1.2.4-rc.1 || ^1",
"@nymproject/mix-fetch-wasm-node": ">=1.2.4-rc.2 || ^1",
"comlink": "^4.3.1",
"fake-indexeddb": "^5.0.0",
"node-fetch": "^3.3.2",
@@ -68,4 +68,4 @@
},
"private": false,
"types": "./dist/cjs/index.d.ts"
}
}
@@ -1,6 +1,6 @@
{
"name": "@nymproject/mix-fetch-tester-webpack",
"version": "1.0.4-rc.1",
"version": "1.0.4-rc.2",
"license": "Apache-2.0",
"scripts": {
"build": "webpack build --progress --config webpack.prod.js",

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