Compare commits

...

84 Commits

Author SHA1 Message Date
import this 8a786248fc update nymvpn cli page 2024-06-12 09:59:15 +00:00
import this 405d4653df [DOCs]: NC purge (#4645)
* update wallet desktop url

* purge nym connect docs

* update socks 5 client quickstart

* add api link - ready to merge

* remove allowlist from the integration faq

* syntax fix
2024-06-12 09:16:49 +00:00
Jędrzej Stuczyński 579527b480 Merge pull request #4648 from nymtech/bugfix/contracts-compat
bugfix: make sure nym-api can handle non-cw2 (or without detailed build info) compliant contracts
2024-06-11 19:04:32 +02:00
Jędrzej Stuczyński 70360196f0 bugfix: make sure nym-api can handle non-cw2 (or without detailed build info) compliant contracts 2024-06-11 17:38:24 +01:00
Tommy Verrall b777adeda6 Merge pull request #4639 from nymtech/jon/remove-pr-template
Remove old PR template
2024-06-11 16:25:23 +02:00
Jędrzej Stuczyński 6a6505c9d7 Merge pull request #4647 from nymtech/feature/toc-flag
introduced a flag to accept toc and exposed it via self-described API
2024-06-11 15:20:42 +02:00
Jędrzej Stuczyński b10119d339 Merge pull request #4646 from nymtech/jstuczyn-patch-1
bugfix: make sure to return an error on invalid public ip
2024-06-11 15:09:25 +02:00
Jędrzej Stuczyński 3a4bd4ffd6 introduced a flag to accept toc and exposed it via self-described API 2024-06-11 14:08:09 +01:00
Jędrzej Stuczyński 9769387730 bugfix: make sure to return an error on invalid public ip 2024-06-11 13:58:25 +01:00
Jędrzej Stuczyński 71747e3c82 Merge pull request #4630 from nymtech/feature/forbid-empty-ips
validate nym-node public ips on startup
2024-06-11 14:43:42 +02:00
Jędrzej Stuczyński 5cbbeee0d5 Merge pull request #4631 from nymtech/feature/standarise-contract-info
standarised ContractBuildInformation and added it to all contracts
2024-06-11 14:43:25 +02:00
Jędrzej Stuczyński f1486fb989 updated schema files 2024-06-11 12:22:38 +01:00
Jędrzej Stuczyński c50c30ae76 standarised ContractBuildInformation and added it to all contracts 2024-06-11 12:22:15 +01:00
Jędrzej Stuczyński 5745cb4d7a Merge pull request #4642 from nymtech/chore/purge-ephemera
Removed ephemera code
2024-06-11 13:15:04 +02:00
Jon Häggblad 00c978c864 Add ci check for PR having an assigned milestone (#4644)
* Add ci check for PR having an assigned milestone

* fix trigger
2024-06-11 12:58:25 +02:00
Tommy Verrall 9e4c58efdf Merge pull request #4640 from nymtech/feature/periodic_remove
Remove stale peers
2024-06-11 12:26:55 +02:00
Tommy Verrall 13e6fcaa85 Merge pull request #4635 from nymtech/feature/new-node-endpoints
Feature/new node endpoints
2024-06-11 12:26:30 +02:00
Tommy Verrall 9bd095ec18 Merge pull request #4638 from nymtech/dependabot/npm_and_yarn/testnet-faucet/braces-3.0.3
Bump braces from 3.0.2 to 3.0.3 in /testnet-faucet
2024-06-11 12:25:13 +02:00
Jędrzej Stuczyński 60d50ff17a fixed visibility of '--local' flag 2024-06-11 11:22:31 +01:00
Tommy Verrall 03f3f0285a Merge pull request #4624 from nymtech/jon/fix-cargo-warnings
Fix cargo warnings
2024-06-11 12:22:12 +02:00
Jędrzej Stuczyński 3e87063ab4 Removed ephemera code 2024-06-11 11:17:26 +01:00
Bogdan-Ștefan Neacşu a32cbd44b0 Remove stale peers 2024-06-11 10:05:38 +00:00
Jon Häggblad 962070a33c Remove old PR template 2024-06-11 12:04:24 +02:00
Jon Häggblad 55f11a5433 Disable profile settings for crate not included
Cargo is warning about

warning: profile package spec `nym-wasm-sdk` in profile `release` did not match any packages

Fix this by commenting out the profile settings for that crate as it's
currently not included  in the main workspace
2024-06-11 11:52:04 +02:00
Jon Häggblad 48332a1069 Fix cargo warnings about default-features for the main workspace
On every cargo command we have the set warnings:

warning: /home/jon/src/nym/nym/common/dkg/Cargo.toml: `default-features` is ignored for bls12_381, since `default-features` was not specified for `workspace.dependencies.bls12_381`, this could become a hard error in the future
warning: /home/jon/src/nym/nym/common/dkg/Cargo.toml: `default-features` is ignored for ff, since `default-features` was not specified for `workspace.dependencies.ff`, this could become a hard error in the future
warning: /home/jon/src/nym/nym/common/dkg/Cargo.toml: `default-features` is ignored for group, since `default-features` was not specified for `workspace.dependencies.group`, this could become a hard error in the future
warning: /home/jon/src/nym/nym/common/client-libs/validator-client/Cargo.toml: `default-features` is ignored for bip32, since `default-features` was not specified for `workspace.dependencies.bip32`, this could become a hard error in the future
warning: /home/jon/src/nym/nym/common/client-libs/validator-client/Cargo.toml: `default-features` is ignored for prost, since `default-features` was not specified for `workspace.dependencies.prost`, this could become a hard error in the future
warning: /home/jon/src/nym/nym/common/credentials-interface/Cargo.toml: `default-features` is ignored for bls12_381, since `default-features` was not specified for `workspace.dependencies.bls12_381`, this could become a hard error in the future
warning: /home/jon/src/nym/nym/common/credentials/Cargo.toml: `default-features` is ignored for bls12_381, since `default-features` was not specified for `workspace.dependencies.bls12_381`, this could become a hard error in the future
warning: /home/jon/src/nym/nym/common/nymcoconut/Cargo.toml: `default-features` is ignored for bls12_381, since `default-features` was not specified for `workspace.dependencies.bls12_381`, this could become a hard error in the future
warning: /home/jon/src/nym/nym/common/nymcoconut/Cargo.toml: `default-features` is ignored for ff, since `default-features` was not specified for `workspace.dependencies.ff`, this could become a hard error in the future
warning: /home/jon/src/nym/nym/common/nymcoconut/Cargo.toml: `default-features` is ignored for group, since `default-features` was not specified for `workspace.dependencies.group`, this could become a hard error in the future

This commit adds default-features = false to the workspace dependencies
to fix these. An alternative way would be to remove
`default-features = false`
in the crates, but I assume these were put there for a good reason. Also
we might have other crates outside of the main workspace that depends on
these crates having default features disabled.
2024-06-11 11:52:01 +02:00
Jon Häggblad f43a2a1e42 Merge pull request #4603 from nymtech/jon/purge-name-service-and-sp-dir-contracts
Purge name service and service provider directory contracts
2024-06-11 11:50:13 +02:00
dependabot[bot] 205c887686 Bump braces from 3.0.2 to 3.0.3 in /testnet-faucet
Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3.
- [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3)

---
updated-dependencies:
- dependency-name: braces
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-11 09:48:46 +00:00
Jon Häggblad 4666e91820 Merge pull request #4620 from nymtech/jon/ipr-read-both-v6-and-v7
Handle v6 and v7 requests in the IPR, but reply with v6
2024-06-11 11:48:00 +02:00
Tommy Verrall 7d0a25d570 Merge pull request #4619 from stefanopier/develop
fix typo
2024-06-11 11:06:27 +02:00
Bogdan-Ștefan Neacşu bb46235b54 Add generic wg private network routing (#4636) 2024-06-10 16:55:05 +03:00
Jędrzej Stuczyński 464041f9e1 ibid for nym-connect 2024-06-10 14:48:35 +01:00
Jędrzej Stuczyński 433748521c wasm fixes 2024-06-10 13:00:24 +01:00
Jędrzej Stuczyński 3cbcd001f4 clippy + test build issues 2024-06-10 11:36:57 +01:00
Jędrzej Stuczyński 282b27646f review comments 2024-06-10 11:19:27 +01:00
Jędrzej Stuczyński 5cc3ee32e9 fix test 2024-06-10 11:17:44 +01:00
Jędrzej Stuczyński f412f45b50 proper type conversions and client compat 2024-06-10 11:03:26 +01:00
Jędrzej Stuczyński 9c19452758 scaffolding of using new endpoints in the client 2024-06-10 10:11:07 +01:00
Jędrzej Stuczyński bf34d00478 new endpoints on nym-api side 2024-06-07 17:02:53 +01:00
Bogdan-Ștefan Neacşu 70fa41c165 Update kernel peers on peer modification (#4622)
* Include wireguard in gw config

* Support nym node first

* Create wg keypair

* Activate wg feature in gw dep

* Move key paths to separate structure

* Use client reg

* Generate and use own private key

* Rename network to ip for wg gw

* Propagate wireguard setup error message

* Remove logs

* Bump gateway version number

* Remove upgrade code

* Init wireguard on migration

* Upgrade code for nym-node too

* Wireguard paths upgrade

* Init wg keys on upgrade

* Simplify pub key translatations

* Fix clippy

* Undo comment change

* Fix tests

* Don't bump version just yet

* Remove redundant source attr

* Remove unused wg details

* Rename wg device

* Init for mixnode migration as well

* Add upgrade for gw wireguard deleted field

* Move interface removal to Drop trait impl

* Fix clippy

* Wgapi could be included on other platforms

* Handle peer control msgs

* Send add peer msg

* Handle double registration

* Fix deadlock

* Fix clippy

* More clippy

* Use same defguard

* Fix unit test

* Fix wasm build

* Move implementations from types to wireguard crate

* Fix linux
2024-06-07 14:02:47 +03:00
Jon Häggblad 065d416305 Update lock files after merging in develop 2024-06-07 12:46:46 +02:00
Jon Häggblad 3e93d2a250 Merge remote-tracking branch 'origin/develop' into jon/purge-name-service-and-sp-dir-contracts 2024-06-07 12:41:46 +02:00
Jon Häggblad 8bc85191d5 Replace Vec<u8> signature with strong type 2024-06-07 12:33:07 +02:00
Jędrzej Stuczyński 7d714a22f0 validate nym-node public ips on startup 2024-06-06 11:23:16 +01:00
Jędrzej Stuczyński 102a8a0d8b Merge pull request #4607 from nymtech/simon/sphinx_update
Update crypto and rand crates
2024-06-05 10:34:42 +01:00
Tommy Verrall ae28a45915 Merge pull request #4618 from vitorsantanna2/patch-1
Update isp-sheet.csv
2024-06-05 11:09:11 +02:00
import this cffb8d98af [DOCs/operators]: fix wireguard syntax (#4628)
* fix wireguard syntax

* simplify syntax

* clean
2024-06-03 14:16:30 +00:00
import this a40c2239d7 [DOCs/operators]: Routine update && Fix a probe syntax (#4627)
* update probe and simplify nym gw flow

* add gw troubleshooting
2024-06-03 07:45:27 +00:00
Jon Häggblad 5a990a58ff Extend the return error when connecting to gateway fails (#4626) 2024-05-31 19:18:31 +02:00
Simon Wicky 2a1d37dd22 update crypto and rand crates 2024-05-31 11:33:16 +01:00
Bogdan-Ștefan Neacşu be79042a23 Bump defguard wg (#4625) 2024-05-30 16:00:51 +02:00
Jon Häggblad 7019dcc11f Clean up parsing request 2024-05-28 22:26:13 +02:00
Jon Häggblad bab842d277 Move comment 2024-05-28 19:35:23 +02:00
Jon Häggblad a374bca601 Check timestamp 2024-05-28 15:10:45 +02:00
Jon Häggblad d4d3041816 Verify signature if present 2024-05-28 12:22:39 +02:00
Bogdan-Ștefan Neacşu 3acf521fc1 Refine wireguard on gateway side (#4615)
* Include wireguard in gw config

* Support nym node first

* Create wg keypair

* Activate wg feature in gw dep

* Move key paths to separate structure

* Use client reg

* Generate and use own private key

* Rename network to ip for wg gw

* Propagate wireguard setup error message

* Remove logs

* Bump gateway version number

* Remove upgrade code

* Init wireguard on migration

* Upgrade code for nym-node too

* Wireguard paths upgrade

* Init wg keys on upgrade

* Simplify pub key translatations

* Fix clippy

* Undo comment change

* Fix tests

* Don't bump version just yet

* Remove redundant source attr

* Remove unused wg details

* Rename wg device

* Init for mixnode migration as well

* Add upgrade for gw wireguard deleted field

* Move interface removal to Drop trait impl

* Fix clippy

* Wgapi could be included on other platforms
2024-05-28 11:52:14 +02:00
Jon Häggblad 70766b6d3e Handle v6 and v7 requests in the IPR, but reply with v6 2024-05-28 09:00:08 +02:00
Stefano Piermatteo 437c66ad0b fix typo 2024-05-24 20:18:06 +02:00
Vitor Santanna 1afcfb0842 Update isp-sheet.csv
Add Misaka and IsHosting VPS
2024-05-24 12:55:10 -03:00
benedetta davico 759e2fa2c5 Merge pull request #4617 from nymtech/master
Merge Master into Develop with the recent Ragusa changes
2024-05-24 14:06:57 +02:00
Tommy Verrall 489914fb42 Merge pull request #4608 from nymtech/release/2024.5-ragusa
Release 2024.5-ragusa into master - DO NO MERGE
2024-05-24 12:35:01 +01:00
import this bca8992115 [DOCs/operators]: 2024.5-ragusa updates (#4609)
* initialise changelog updates

* fix formatting

* finalise changelog

* change formating - PR ready for review

* review comments resolved
2024-05-23 16:49:17 +00:00
mx f94d900d18 update mixfetch docs (#4614)
* * added info on gateway habourmaster
* fixed broken examples with new infra addresses
* bump node version in ts sdk docs ci script

---------

Co-authored-by: mfahampshire <mfahampshire@pm.me>
2024-05-23 15:15:51 +00:00
Tommy Verrall dab55a12c7 update changelog 2024-05-23 16:26:09 +02:00
Tommy Verrall 82f722936f Merge branch 'release/2024.5-ragusa' of https://github.com/nymtech/nym into release/2024.5-ragusa 2024-05-23 16:09:07 +02:00
benedettadavico 7f08020d4f update changelog and bump versions 2024-05-23 16:08:37 +02:00
Tommy Verrall 579e41d57e Merge pull request #4613 from nymtech/bugfix/last_polled-backwards-compat
make sure 'OffsetDateTimeJsonSchemaWrapper' is serialised with legacy format
2024-05-23 15:00:38 +01:00
Jędrzej Stuczyński 06953298eb ibid for nym-connect 2024-05-23 12:10:41 +01:00
Jędrzej Stuczyński 1d78f8747f update wallet 'time' dep due to broken semver 2024-05-23 10:21:08 +01:00
Tommy Verrall a6e9414cb8 Update ci-contracts-upload-binaries.yml
use version 1.77 so it's compatible with ecash
2024-05-23 11:03:40 +02:00
Jędrzej Stuczyński 23d7230d33 make sure 'OffsetDateTimeJsonSchemaWrapper' is serialised with legacy format 2024-05-23 10:01:46 +01:00
benedettadavico 496f172070 update changelog and bump versions 2024-05-22 10:28:38 +02:00
Jon Häggblad b617729873 Remove from contract Makefile 2024-05-20 15:08:18 +02:00
Jon Häggblad c5e1ea289c nym-connect and nym-wallet lock files 2024-05-20 09:50:32 +02:00
Jon Häggblad 266c98a80e Don't upload in ci workflow 2024-05-20 09:48:48 +02:00
Jon Häggblad 4540b3b41a lock file for contracts 2024-05-20 09:43:07 +02:00
Jon Häggblad a9beb13189 Remove references in Makefile 2024-05-20 09:42:23 +02:00
Jon Häggblad ebc30ec248 Remove everywhere sp contract is used 2024-05-20 09:38:22 +02:00
Jon Häggblad 3cd9c6ad13 Remove nym-service-provider-directory-common 2024-05-20 09:27:40 +02:00
Jon Häggblad b83d4e964b Remove nym-service-provider-directory from workspace 2024-05-20 09:27:09 +02:00
Jon Häggblad bceb59a832 Remove nym-service-provider-directory 2024-05-20 09:26:14 +02:00
Jon Häggblad 50a48603e3 Remove everywhere name-service contract is used 2024-05-20 09:25:10 +02:00
Jon Häggblad 1ae718c345 Purge nym-name-service-common 2024-05-20 09:13:17 +02:00
Jon Häggblad 12c4450527 Remove nym-name-service from workspace 2024-05-20 09:12:06 +02:00
Jon Häggblad 5bf34950ab Delete nym-name-service contract 2024-05-20 09:11:25 +02:00
452 changed files with 4939 additions and 29366 deletions
-9
View File
@@ -1,9 +0,0 @@
# Description
Closes: #XXXX
<!-- If appropriate, insert relevant description here -->
# Checklist:
- [ ] added a changelog entry to `CHANGELOG.md`
@@ -35,7 +35,7 @@ jobs:
- name: Install Rust stable - name: Install Rust stable
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
with: with:
toolchain: stable toolchain: 1.77
target: wasm32-unknown-unknown target: wasm32-unknown-unknown
override: true override: true
@@ -58,8 +58,6 @@ jobs:
cp contracts/target/wasm32-unknown-unknown/release/nym_coconut_dkg.wasm $OUTPUT_DIR cp contracts/target/wasm32-unknown-unknown/release/nym_coconut_dkg.wasm $OUTPUT_DIR
cp contracts/target/wasm32-unknown-unknown/release/cw3_flex_multisig.wasm $OUTPUT_DIR cp contracts/target/wasm32-unknown-unknown/release/cw3_flex_multisig.wasm $OUTPUT_DIR
cp contracts/target/wasm32-unknown-unknown/release/cw4_group.wasm $OUTPUT_DIR cp contracts/target/wasm32-unknown-unknown/release/cw4_group.wasm $OUTPUT_DIR
cp contracts/target/wasm32-unknown-unknown/release/nym_service_provider_directory.wasm $OUTPUT_DIR
cp contracts/target/wasm32-unknown-unknown/release/nym_name_service.wasm $OUTPUT_DIR
- name: Deploy branch to CI www - name: Deploy branch to CI www
continue-on-error: true continue-on-error: true
+1 -1
View File
@@ -17,7 +17,7 @@ jobs:
- uses: rlespinasse/github-slug-action@v3.x - uses: rlespinasse/github-slug-action@v3.x
- uses: actions/setup-node@v3 - uses: actions/setup-node@v3
with: with:
node-version: 18 node-version: 18.17
- name: Install Rust stable - name: Install Rust stable
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
with: with:
+27
View File
@@ -0,0 +1,27 @@
name: pr-validation
on:
pull_request:
branches:
- develop
- 'release/**'
types:
- labeled
- unlabeled
- opened
- reopened
- synchronize
- edited
- milestoned
- demilestoned
env:
LABELS: ${{ join( github.event.pull_request.labels.*.name, ' ' ) }}
jobs:
check-milestone:
name: Check Milestone
runs-on: ubuntu-latest
steps:
- if: github.event.pull_request.milestone == null && contains( env.LABELS, 'no-milestone' ) == false
run: exit 1
+39
View File
@@ -4,6 +4,45 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
## [Unreleased] ## [Unreleased]
## [2024.5-ragusa] (2024-05-22)
- Feature/nym node api location ([#4605])
- Add optional signature to IPR request/response ([#4604])
- Feature/unstable tested nodes endpoint ([#4601])
- nym-api: make report/avg_uptime endpoints ignore blacklist ([#4599])
- removed blocking for coconut in the final epoch state ([#4598])
- allow using explicit admin address for issuing freepasses ([#4595])
- Use rfc3339 for last_polled in described nym-api endpoint ([#4591])
- Explicitly handle constraint unique violation when importing credential ([#4588])
- [bugfix] noop flag for nym-api for nymvisor compatibility ([#4586])
- Chore/additional helpers ([#4585])
- Feature/wasm coconut ([#4584])
- upgraded axum and related deps to the most recent version ([#4573])
- Feature/nyxd scraper pruning ([#4564])
- Run cargo autoinherit on the main workspace ([#4553])
- Add rustls-tls to reqwest in validator-client ([#4552])
- Feature/rewarder voucher issuance ([#4548])
- make sure 'OffsetDateTimeJsonSchemaWrapper' is serialised with legacy format ([#4613])
[#4613]: https://github.com/nymtech/nym/pull/4613
[#4605]: https://github.com/nymtech/nym/pull/4605
[#4604]: https://github.com/nymtech/nym/pull/4604
[#4601]: https://github.com/nymtech/nym/pull/4601
[#4599]: https://github.com/nymtech/nym/pull/4599
[#4598]: https://github.com/nymtech/nym/pull/4598
[#4595]: https://github.com/nymtech/nym/pull/4595
[#4591]: https://github.com/nymtech/nym/pull/4591
[#4588]: https://github.com/nymtech/nym/pull/4588
[#4586]: https://github.com/nymtech/nym/pull/4586
[#4585]: https://github.com/nymtech/nym/pull/4585
[#4584]: https://github.com/nymtech/nym/pull/4584
[#4573]: https://github.com/nymtech/nym/pull/4573
[#4564]: https://github.com/nymtech/nym/pull/4564
[#4553]: https://github.com/nymtech/nym/pull/4553
[#4552]: https://github.com/nymtech/nym/pull/4552
[#4548]: https://github.com/nymtech/nym/pull/4548
## [2024.4-nutella] (2024-05-08) ## [2024.4-nutella] (2024-05-08)
- [fix] apply disable_poisson_rate from internal NR/IPR cfgs ([#4579]) - [fix] apply disable_poisson_rate from internal NR/IPR cfgs ([#4579])
Generated
+117 -245
View File
@@ -43,19 +43,6 @@ dependencies = [
"generic-array 0.14.7", "generic-array 0.14.7",
] ]
[[package]]
name = "aes"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8"
dependencies = [
"cfg-if",
"cipher 0.3.0",
"cpufeatures",
"ctr 0.8.0",
"opaque-debug 0.3.1",
]
[[package]] [[package]]
name = "aes" name = "aes"
version = "0.8.4" version = "0.8.4"
@@ -63,7 +50,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cipher 0.4.4", "cipher",
"cpufeatures", "cpufeatures",
] ]
@@ -74,9 +61,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1"
dependencies = [ dependencies = [
"aead", "aead",
"aes 0.8.4", "aes",
"cipher 0.4.4", "cipher",
"ctr 0.9.2", "ctr",
"ghash", "ghash",
"subtle 2.5.0", "subtle 2.5.0",
] ]
@@ -537,10 +524,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e141fb0f8be1c7b45887af94c88b182472b57c96b56773250ae00cd6a14a164" checksum = "7e141fb0f8be1c7b45887af94c88b182472b57c96b56773250ae00cd6a14a164"
dependencies = [ dependencies = [
"bs58 0.5.1", "bs58 0.5.1",
"hmac 0.12.1", "hmac",
"k256", "k256",
"once_cell",
"pbkdf2",
"rand_core 0.6.4", "rand_core 0.6.4",
"ripemd", "ripemd",
"sha2 0.10.8", "sha2 0.10.8",
@@ -599,7 +584,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330" checksum = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330"
dependencies = [ dependencies = [
"byte-tools", "byte-tools",
"crypto-mac 0.7.0", "crypto-mac",
"digest 0.8.1", "digest 0.8.1",
"opaque-debug 0.2.3", "opaque-debug 0.2.3",
] ]
@@ -827,7 +812,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cipher 0.4.4", "cipher",
"cpufeatures", "cpufeatures",
] ]
@@ -839,7 +824,7 @@ checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35"
dependencies = [ dependencies = [
"aead", "aead",
"chacha20", "chacha20",
"cipher 0.4.4", "cipher",
"poly1305", "poly1305",
"zeroize", "zeroize",
] ]
@@ -886,15 +871,6 @@ dependencies = [
"half", "half",
] ]
[[package]]
name = "cipher"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7"
dependencies = [
"generic-array 0.14.7",
]
[[package]] [[package]]
name = "cipher" name = "cipher"
version = "0.4.4" version = "0.4.4"
@@ -1188,7 +1164,7 @@ dependencies = [
"rand_core 0.6.4", "rand_core 0.6.4",
"serde", "serde",
"serde_json", "serde_json",
"signature 2.2.0", "signature",
"subtle-encoding", "subtle-encoding",
"tendermint", "tendermint",
"thiserror", "thiserror",
@@ -1207,7 +1183,7 @@ dependencies = [
"rand_core 0.6.4", "rand_core 0.6.4",
"serde", "serde",
"serde_json", "serde_json",
"signature 2.2.0", "signature",
"subtle-encoding", "subtle-encoding",
"tendermint", "tendermint",
"tendermint-rpc", "tendermint-rpc",
@@ -1473,16 +1449,6 @@ dependencies = [
"subtle 1.0.0", "subtle 1.0.0",
] ]
[[package]]
name = "crypto-mac"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25fab6889090c8133f3deb8f73ba3c65a7f456f66436fc012a1b1e272b1e103e"
dependencies = [
"generic-array 0.14.7",
"subtle 2.5.0",
]
[[package]] [[package]]
name = "csv" name = "csv"
version = "1.3.0" version = "1.3.0"
@@ -1504,22 +1470,13 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "ctr"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea"
dependencies = [
"cipher 0.3.0",
]
[[package]] [[package]]
name = "ctr" name = "ctr"
version = "0.9.2" version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835"
dependencies = [ dependencies = [
"cipher 0.4.4", "cipher",
] ]
[[package]] [[package]]
@@ -1571,7 +1528,6 @@ dependencies = [
"byteorder", "byteorder",
"digest 0.9.0", "digest 0.9.0",
"rand_core 0.5.1", "rand_core 0.5.1",
"serde",
"subtle 2.5.0", "subtle 2.5.0",
"zeroize", "zeroize",
] ]
@@ -1585,9 +1541,11 @@ dependencies = [
"cfg-if", "cfg-if",
"cpufeatures", "cpufeatures",
"curve25519-dalek-derive", "curve25519-dalek-derive",
"digest 0.10.7",
"fiat-crypto", "fiat-crypto",
"platforms", "platforms",
"rustc_version 0.4.0", "rustc_version 0.4.0",
"serde",
"subtle 2.5.0", "subtle 2.5.0",
"zeroize", "zeroize",
] ]
@@ -1804,8 +1762,9 @@ checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2"
[[package]] [[package]]
name = "defguard_wireguard_rs" name = "defguard_wireguard_rs"
version = "0.3.0" version = "0.4.2"
source = "git+https://github.com/neacsu/wireguard-rs.git?rev=c2cd0c1119f699f4bc43f5e6ffd6fc242caa42ed#c2cd0c1119f699f4bc43f5e6ffd6fc242caa42ed" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ba16f17698d4b389907310af018b0c3a80b025bba9c38d947cbc6dd70921743"
dependencies = [ dependencies = [
"base64 0.21.7", "base64 0.21.7",
"libc", "libc",
@@ -1985,20 +1944,10 @@ dependencies = [
"elliptic-curve", "elliptic-curve",
"rfc6979", "rfc6979",
"serdect", "serdect",
"signature 2.2.0", "signature",
"spki", "spki",
] ]
[[package]]
name = "ed25519"
version = "1.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7"
dependencies = [
"serde",
"signature 1.6.4",
]
[[package]] [[package]]
name = "ed25519" name = "ed25519"
version = "2.2.3" version = "2.2.3"
@@ -2006,7 +1955,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53"
dependencies = [ dependencies = [
"pkcs8", "pkcs8",
"signature 2.2.0", "serde",
"signature",
] ]
[[package]] [[package]]
@@ -2024,16 +1974,16 @@ dependencies = [
[[package]] [[package]]
name = "ed25519-dalek" name = "ed25519-dalek"
version = "1.0.1" version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871"
dependencies = [ dependencies = [
"curve25519-dalek 3.2.0", "curve25519-dalek 4.1.2",
"ed25519 1.5.3", "ed25519",
"rand 0.7.3", "rand_core 0.6.4",
"serde", "serde",
"serde_bytes", "sha2 0.10.8",
"sha2 0.9.9", "subtle 2.5.0",
"zeroize", "zeroize",
] ]
@@ -2252,7 +2202,6 @@ version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449"
dependencies = [ dependencies = [
"bitvec",
"rand_core 0.6.4", "rand_core 0.6.4",
"subtle 2.5.0", "subtle 2.5.0",
] ]
@@ -2825,33 +2774,13 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "hkdf"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01706d578d5c281058480e673ae4086a9f4710d8df1ad80a5b03e39ece5f886b"
dependencies = [
"digest 0.9.0",
"hmac 0.11.0",
]
[[package]] [[package]]
name = "hkdf" name = "hkdf"
version = "0.12.4" version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7"
dependencies = [ dependencies = [
"hmac 0.12.1", "hmac",
]
[[package]]
name = "hmac"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b"
dependencies = [
"crypto-mac 0.11.0",
"digest 0.9.0",
] ]
[[package]] [[package]]
@@ -3409,7 +3338,7 @@ dependencies = [
"elliptic-curve", "elliptic-curve",
"once_cell", "once_cell",
"sha2 0.10.8", "sha2 0.10.8",
"signature 2.2.0", "signature",
] ]
[[package]] [[package]]
@@ -3688,7 +3617,7 @@ dependencies = [
"nym-ordered-buffer", "nym-ordered-buffer",
"nym-service-providers-common", "nym-service-providers-common",
"nym-socks5-requests", "nym-socks5-requests",
"rand 0.7.3", "rand 0.8.5",
"serde", "serde",
"serde-wasm-bindgen 0.6.5", "serde-wasm-bindgen 0.6.5",
"thiserror", "thiserror",
@@ -3929,7 +3858,7 @@ dependencies = [
[[package]] [[package]]
name = "nym-api" name = "nym-api"
version = "1.1.37" version = "1.1.38"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@@ -3966,11 +3895,9 @@ dependencies = [
"nym-inclusion-probability", "nym-inclusion-probability",
"nym-mixnet-contract-common", "nym-mixnet-contract-common",
"nym-multisig-contract-common", "nym-multisig-contract-common",
"nym-name-service-common",
"nym-node-requests", "nym-node-requests",
"nym-node-tester-utils", "nym-node-tester-utils",
"nym-pemstore", "nym-pemstore",
"nym-service-provider-directory-common",
"nym-sphinx", "nym-sphinx",
"nym-task", "nym-task",
"nym-topology", "nym-topology",
@@ -3978,9 +3905,7 @@ dependencies = [
"nym-vesting-contract-common", "nym-vesting-contract-common",
"okapi", "okapi",
"pin-project", "pin-project",
"rand 0.7.3",
"rand 0.8.5", "rand 0.8.5",
"rand_chacha 0.2.2",
"rand_chacha 0.3.1", "rand_chacha 0.3.1",
"reqwest 0.12.4", "reqwest 0.12.4",
"rocket", "rocket",
@@ -4015,8 +3940,10 @@ dependencies = [
"nym-crypto", "nym-crypto",
"nym-mixnet-contract-common", "nym-mixnet-contract-common",
"nym-node-requests", "nym-node-requests",
"rocket",
"schemars", "schemars",
"serde", "serde",
"serde_json",
"tendermint", "tendermint",
"time", "time",
"ts-rs", "ts-rs",
@@ -4045,7 +3972,7 @@ dependencies = [
"nym-crypto", "nym-crypto",
"nym-network-defaults", "nym-network-defaults",
"nym-validator-client", "nym-validator-client",
"rand 0.7.3", "rand 0.8.5",
"thiserror", "thiserror",
"url", "url",
"zeroize", "zeroize",
@@ -4091,7 +4018,7 @@ dependencies = [
[[package]] [[package]]
name = "nym-cli" name = "nym-cli"
version = "1.1.35" version = "1.1.36"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"base64 0.13.1", "base64 0.13.1",
@@ -4150,10 +4077,8 @@ dependencies = [
"nym-id", "nym-id",
"nym-mixnet-contract-common", "nym-mixnet-contract-common",
"nym-multisig-contract-common", "nym-multisig-contract-common",
"nym-name-service-common",
"nym-network-defaults", "nym-network-defaults",
"nym-pemstore", "nym-pemstore",
"nym-service-provider-directory-common",
"nym-sphinx", "nym-sphinx",
"nym-types", "nym-types",
"nym-validator-client", "nym-validator-client",
@@ -4172,7 +4097,7 @@ dependencies = [
[[package]] [[package]]
name = "nym-client" name = "nym-client"
version = "1.1.34" version = "1.1.35"
dependencies = [ dependencies = [
"bs58 0.5.1", "bs58 0.5.1",
"clap 4.5.4", "clap 4.5.4",
@@ -4195,7 +4120,7 @@ dependencies = [
"nym-task", "nym-task",
"nym-topology", "nym-topology",
"nym-validator-client", "nym-validator-client",
"rand 0.7.3", "rand 0.8.5",
"serde", "serde",
"serde_json", "serde_json",
"tap", "tap",
@@ -4243,7 +4168,7 @@ dependencies = [
"nym-task", "nym-task",
"nym-topology", "nym-topology",
"nym-validator-client", "nym-validator-client",
"rand 0.7.3", "rand 0.8.5",
"serde", "serde",
"serde_json", "serde_json",
"sha2 0.10.8", "sha2 0.10.8",
@@ -4323,7 +4248,7 @@ dependencies = [
"nym-bin-common", "nym-bin-common",
"nym-node-tester-utils", "nym-node-tester-utils",
"nym-node-tester-wasm", "nym-node-tester-wasm",
"rand 0.7.3", "rand 0.8.5",
"serde", "serde",
"serde-wasm-bindgen 0.6.5", "serde-wasm-bindgen 0.6.5",
"serde_json", "serde_json",
@@ -4412,10 +4337,12 @@ dependencies = [
"bs58 0.5.1", "bs58 0.5.1",
"cosmwasm-schema", "cosmwasm-schema",
"cosmwasm-std", "cosmwasm-std",
"cw-storage-plus",
"schemars", "schemars",
"serde", "serde",
"serde_json", "serde_json",
"thiserror", "thiserror",
"vergen",
] ]
[[package]] [[package]]
@@ -4466,7 +4393,7 @@ dependencies = [
"nym-credentials-interface", "nym-credentials-interface",
"nym-crypto", "nym-crypto",
"nym-validator-client", "nym-validator-client",
"rand 0.7.3", "rand 0.8.5",
"serde", "serde",
"thiserror", "thiserror",
"time", "time",
@@ -4487,25 +4414,25 @@ dependencies = [
name = "nym-crypto" name = "nym-crypto"
version = "0.4.0" version = "0.4.0"
dependencies = [ dependencies = [
"aes 0.8.4", "aes",
"blake3", "blake3",
"bs58 0.5.1", "bs58 0.5.1",
"cipher 0.4.4", "cipher",
"ctr 0.9.2", "ctr",
"digest 0.10.7", "digest 0.10.7",
"ed25519-dalek", "ed25519-dalek",
"generic-array 0.14.7", "generic-array 0.14.7",
"hkdf 0.12.4", "hkdf",
"hmac 0.12.1", "hmac",
"nym-pemstore", "nym-pemstore",
"nym-sphinx-types", "nym-sphinx-types",
"rand 0.7.3", "rand 0.8.5",
"rand_chacha 0.2.2", "rand_chacha 0.3.1",
"serde", "serde",
"serde_bytes", "serde_bytes",
"subtle-encoding", "subtle-encoding",
"thiserror", "thiserror",
"x25519-dalek 1.1.1", "x25519-dalek",
"zeroize", "zeroize",
] ]
@@ -4532,16 +4459,6 @@ dependencies = [
"zeroize", "zeroize",
] ]
[[package]]
name = "nym-ephemera-common"
version = "0.1.0"
dependencies = [
"cosmwasm-schema",
"cosmwasm-std",
"cw-utils",
"nym-contracts-common",
]
[[package]] [[package]]
name = "nym-execute" name = "nym-execute"
version = "0.1.0" version = "0.1.0"
@@ -4627,7 +4544,7 @@ dependencies = [
"nym-wireguard", "nym-wireguard",
"nym-wireguard-types", "nym-wireguard-types",
"once_cell", "once_cell",
"rand 0.7.3", "rand 0.8.5",
"serde", "serde",
"serde_json", "serde_json",
"sqlx", "sqlx",
@@ -4660,7 +4577,7 @@ dependencies = [
"nym-sphinx", "nym-sphinx",
"nym-task", "nym-task",
"nym-validator-client", "nym-validator-client",
"rand 0.7.3", "rand 0.8.5",
"serde", "serde",
"si-scale", "si-scale",
"thiserror", "thiserror",
@@ -4689,7 +4606,7 @@ dependencies = [
"nym-crypto", "nym-crypto",
"nym-pemstore", "nym-pemstore",
"nym-sphinx", "nym-sphinx",
"rand 0.7.3", "rand 0.8.5",
"serde", "serde",
"serde_json", "serde_json",
"thiserror", "thiserror",
@@ -4780,6 +4697,7 @@ dependencies = [
"bincode", "bincode",
"bytes", "bytes",
"nym-bin-common", "nym-bin-common",
"nym-crypto",
"nym-sphinx", "nym-sphinx",
"rand 0.8.5", "rand 0.8.5",
"serde", "serde",
@@ -4824,6 +4742,7 @@ dependencies = [
"serde_json", "serde_json",
"tap", "tap",
"thiserror", "thiserror",
"time",
"tokio", "tokio",
"tokio-tun", "tokio-tun",
"tokio-util", "tokio-util",
@@ -4917,7 +4836,7 @@ dependencies = [
"nym-topology", "nym-topology",
"nym-types", "nym-types",
"nym-validator-client", "nym-validator-client",
"rand 0.7.3", "rand 0.8.5",
"serde", "serde",
"serde_json", "serde_json",
"sysinfo 0.27.8", "sysinfo 0.27.8",
@@ -4974,20 +4893,6 @@ dependencies = [
"thiserror", "thiserror",
] ]
[[package]]
name = "nym-name-service-common"
version = "0.1.0"
dependencies = [
"cosmwasm-schema",
"cosmwasm-std",
"cw-controllers",
"cw-utils",
"cw2",
"nym-contracts-common",
"serde",
"thiserror",
]
[[package]] [[package]]
name = "nym-network-defaults" name = "nym-network-defaults"
version = "0.1.0" version = "0.1.0"
@@ -5005,7 +4910,7 @@ dependencies = [
[[package]] [[package]]
name = "nym-network-requester" name = "nym-network-requester"
version = "1.1.35" version = "1.1.36"
dependencies = [ dependencies = [
"addr", "addr",
"anyhow", "anyhow",
@@ -5039,7 +4944,7 @@ dependencies = [
"nym-types", "nym-types",
"pretty_env_logger", "pretty_env_logger",
"publicsuffix", "publicsuffix",
"rand 0.7.3", "rand 0.8.5",
"regex", "regex",
"reqwest 0.12.4", "reqwest 0.12.4",
"serde", "serde",
@@ -5074,7 +4979,7 @@ dependencies = [
[[package]] [[package]]
name = "nym-node" name = "nym-node"
version = "1.1.1" version = "1.1.2"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bip39", "bip39",
@@ -5100,8 +5005,9 @@ dependencies = [
"nym-sphinx-addressing", "nym-sphinx-addressing",
"nym-task", "nym-task",
"nym-types", "nym-types",
"nym-wireguard",
"nym-wireguard-types", "nym-wireguard-types",
"rand 0.7.3", "rand 0.8.5",
"semver 1.0.23", "semver 1.0.23",
"serde", "serde",
"serde_json", "serde_json",
@@ -5120,11 +5026,12 @@ version = "0.1.0"
dependencies = [ dependencies = [
"axum 0.7.5", "axum 0.7.5",
"axum-extra", "axum-extra",
"base64 0.21.7",
"colored", "colored",
"dashmap", "dashmap",
"fastrand 2.1.0", "fastrand 2.1.0",
"headers", "headers",
"hmac 0.12.1", "hmac",
"hyper 1.3.1", "hyper 1.3.1",
"ipnetwork 0.16.0", "ipnetwork 0.16.0",
"nym-crypto", "nym-crypto",
@@ -5134,7 +5041,7 @@ dependencies = [
"nym-task", "nym-task",
"nym-wireguard", "nym-wireguard",
"nym-wireguard-types", "nym-wireguard-types",
"rand 0.7.3", "rand 0.8.5",
"serde_json", "serde_json",
"thiserror", "thiserror",
"time", "time",
@@ -5144,7 +5051,7 @@ dependencies = [
"tracing", "tracing",
"utoipa", "utoipa",
"utoipa-swagger-ui", "utoipa-swagger-ui",
"x25519-dalek 2.0.1", "x25519-dalek",
] ]
[[package]] [[package]]
@@ -5161,7 +5068,7 @@ dependencies = [
"nym-exit-policy", "nym-exit-policy",
"nym-http-api-client", "nym-http-api-client",
"nym-wireguard-types", "nym-wireguard-types",
"rand_chacha 0.2.2", "rand_chacha 0.3.1",
"schemars", "schemars",
"serde", "serde",
"serde_json", "serde_json",
@@ -5182,7 +5089,7 @@ dependencies = [
"nym-sphinx-params", "nym-sphinx-params",
"nym-task", "nym-task",
"nym-topology", "nym-topology",
"rand 0.7.3", "rand 0.8.5",
"serde", "serde",
"serde_json", "serde_json",
"thiserror", "thiserror",
@@ -5197,7 +5104,7 @@ dependencies = [
"futures", "futures",
"js-sys", "js-sys",
"nym-node-tester-utils", "nym-node-tester-utils",
"rand 0.7.3", "rand 0.8.5",
"serde", "serde",
"serde-wasm-bindgen 0.6.5", "serde-wasm-bindgen 0.6.5",
"thiserror", "thiserror",
@@ -5252,11 +5159,11 @@ dependencies = [
"chacha20", "chacha20",
"chacha20poly1305", "chacha20poly1305",
"criterion", "criterion",
"curve25519-dalek 3.2.0", "curve25519-dalek 4.1.2",
"fastrand 1.9.0", "fastrand 1.9.0",
"getrandom 0.2.15", "getrandom 0.2.15",
"log", "log",
"rand 0.7.3", "rand 0.8.5",
"rayon", "rayon",
"sphinx-packet", "sphinx-packet",
"thiserror", "thiserror",
@@ -5304,7 +5211,7 @@ dependencies = [
"nym-validator-client", "nym-validator-client",
"parking_lot 0.12.2", "parking_lot 0.12.2",
"pretty_env_logger", "pretty_env_logger",
"rand 0.7.3", "rand 0.8.5",
"reqwest 0.12.4", "reqwest 0.12.4",
"tap", "tap",
"thiserror", "thiserror",
@@ -5315,19 +5222,6 @@ dependencies = [
"url", "url",
] ]
[[package]]
name = "nym-service-provider-directory-common"
version = "0.1.0"
dependencies = [
"cosmwasm-schema",
"cosmwasm-std",
"cw-controllers",
"cw-utils",
"cw2",
"nym-contracts-common",
"thiserror",
]
[[package]] [[package]]
name = "nym-service-providers-common" name = "nym-service-providers-common"
version = "0.1.0" version = "0.1.0"
@@ -5347,7 +5241,7 @@ dependencies = [
[[package]] [[package]]
name = "nym-socks5-client" name = "nym-socks5-client"
version = "1.1.34" version = "1.1.35"
dependencies = [ dependencies = [
"bs58 0.5.1", "bs58 0.5.1",
"clap 4.5.4", "clap 4.5.4",
@@ -5366,7 +5260,7 @@ dependencies = [
"nym-socks5-client-core", "nym-socks5-client-core",
"nym-sphinx", "nym-sphinx",
"nym-topology", "nym-topology",
"rand 0.7.3", "rand 0.8.5",
"serde", "serde",
"serde_json", "serde_json",
"tap", "tap",
@@ -5399,7 +5293,7 @@ dependencies = [
"nym-task", "nym-task",
"nym-validator-client", "nym-validator-client",
"pin-project", "pin-project",
"rand 0.7.3", "rand 0.8.5",
"reqwest 0.12.4", "reqwest 0.12.4",
"schemars", "schemars",
"serde", "serde",
@@ -5425,7 +5319,7 @@ dependencies = [
"nym-credential-storage", "nym-credential-storage",
"nym-crypto", "nym-crypto",
"nym-socks5-client-core", "nym-socks5-client-core",
"rand 0.7.3", "rand 0.8.5",
"safer-ffi", "safer-ffi",
"serde", "serde",
"tokio", "tokio",
@@ -5479,7 +5373,7 @@ dependencies = [
"nym-sphinx-routing", "nym-sphinx-routing",
"nym-sphinx-types", "nym-sphinx-types",
"nym-topology", "nym-topology",
"rand 0.7.3", "rand 0.8.5",
"rand_distr", "rand_distr",
"thiserror", "thiserror",
"tokio", "tokio",
@@ -5497,7 +5391,7 @@ dependencies = [
"nym-sphinx-routing", "nym-sphinx-routing",
"nym-sphinx-types", "nym-sphinx-types",
"nym-topology", "nym-topology",
"rand 0.7.3", "rand 0.8.5",
"serde", "serde",
"thiserror", "thiserror",
"zeroize", "zeroize",
@@ -5509,7 +5403,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"nym-crypto", "nym-crypto",
"nym-sphinx-types", "nym-sphinx-types",
"rand 0.7.3", "rand 0.8.5",
"serde", "serde",
"thiserror", "thiserror",
] ]
@@ -5525,8 +5419,8 @@ dependencies = [
"nym-sphinx-routing", "nym-sphinx-routing",
"nym-sphinx-types", "nym-sphinx-types",
"nym-topology", "nym-topology",
"rand 0.7.3", "rand 0.8.5",
"rand_chacha 0.2.2", "rand_chacha 0.3.1",
"serde", "serde",
"thiserror", "thiserror",
"wasm-bindgen", "wasm-bindgen",
@@ -5540,7 +5434,7 @@ dependencies = [
"nym-sphinx-addressing", "nym-sphinx-addressing",
"nym-sphinx-params", "nym-sphinx-params",
"nym-sphinx-types", "nym-sphinx-types",
"rand 0.7.3", "rand 0.8.5",
"thiserror", "thiserror",
] ]
@@ -5557,7 +5451,7 @@ dependencies = [
"nym-sphinx-routing", "nym-sphinx-routing",
"nym-sphinx-types", "nym-sphinx-types",
"nym-topology", "nym-topology",
"rand 0.7.3", "rand 0.8.5",
"thiserror", "thiserror",
] ]
@@ -5668,7 +5562,7 @@ dependencies = [
"nym-sphinx-addressing", "nym-sphinx-addressing",
"nym-sphinx-routing", "nym-sphinx-routing",
"nym-sphinx-types", "nym-sphinx-types",
"rand 0.7.3", "rand 0.8.5",
"semver 0.11.0", "semver 0.11.0",
"serde", "serde",
"serde_json", "serde_json",
@@ -5698,7 +5592,7 @@ dependencies = [
"cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)",
"cosmwasm-std", "cosmwasm-std",
"eyre", "eyre",
"hmac 0.12.1", "hmac",
"itertools 0.11.0", "itertools 0.11.0",
"log", "log",
"nym-config", "nym-config",
@@ -5716,7 +5610,7 @@ dependencies = [
"thiserror", "thiserror",
"ts-rs", "ts-rs",
"url", "url",
"x25519-dalek 2.0.1", "x25519-dalek",
] ]
[[package]] [[package]]
@@ -5746,14 +5640,11 @@ dependencies = [
"nym-coconut-dkg-common", "nym-coconut-dkg-common",
"nym-config", "nym-config",
"nym-contracts-common", "nym-contracts-common",
"nym-ephemera-common",
"nym-group-contract-common", "nym-group-contract-common",
"nym-http-api-client", "nym-http-api-client",
"nym-mixnet-contract-common", "nym-mixnet-contract-common",
"nym-multisig-contract-common", "nym-multisig-contract-common",
"nym-name-service-common",
"nym-network-defaults", "nym-network-defaults",
"nym-service-provider-directory-common",
"nym-vesting-contract-common", "nym-vesting-contract-common",
"prost 0.12.4", "prost 0.12.4",
"reqwest 0.12.4", "reqwest 0.12.4",
@@ -5841,14 +5732,17 @@ name = "nym-wireguard"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"base64 0.21.7", "base64 0.21.7",
"dashmap",
"defguard_wireguard_rs", "defguard_wireguard_rs",
"ip_network", "ip_network",
"log", "log",
"nym-crypto",
"nym-network-defaults", "nym-network-defaults",
"nym-task", "nym-task",
"nym-wireguard-types", "nym-wireguard-types",
"tokio", "tokio",
"x25519-dalek 2.0.1", "tokio-stream",
"x25519-dalek",
] ]
[[package]] [[package]]
@@ -5857,21 +5751,23 @@ version = "0.1.0"
dependencies = [ dependencies = [
"base64 0.21.7", "base64 0.21.7",
"dashmap", "dashmap",
"hmac 0.12.1", "hmac",
"log", "log",
"nym-config",
"nym-crypto", "nym-crypto",
"rand 0.7.3", "nym-network-defaults",
"rand 0.8.5",
"serde", "serde",
"serde_json", "serde_json",
"sha2 0.10.8", "sha2 0.10.8",
"thiserror", "thiserror",
"utoipa", "utoipa",
"x25519-dalek 2.0.1", "x25519-dalek",
] ]
[[package]] [[package]]
name = "nymvisor" name = "nymvisor"
version = "0.1.0" version = "0.1.1"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytes", "bytes",
@@ -6183,16 +6079,6 @@ version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "pbkdf2"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2"
dependencies = [
"digest 0.10.7",
"hmac 0.12.1",
]
[[package]] [[package]]
name = "pear" name = "pear"
version = "0.2.9" version = "0.2.9"
@@ -6749,12 +6635,12 @@ dependencies = [
[[package]] [[package]]
name = "rand_distr" name = "rand_distr"
version = "0.3.0" version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9e9532ada3929fb8b2e9dbe28d1e06c9b2cc65813f074fcb6bd5fbefeff9d56" checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31"
dependencies = [ dependencies = [
"num-traits", "num-traits",
"rand 0.7.3", "rand 0.8.5",
] ]
[[package]] [[package]]
@@ -7068,7 +6954,7 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2"
dependencies = [ dependencies = [
"hmac 0.12.1", "hmac",
"subtle 2.5.0", "subtle 2.5.0",
] ]
@@ -7860,12 +7746,6 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "signature"
version = "1.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c"
[[package]] [[package]]
name = "signature" name = "signature"
version = "2.2.0" version = "2.2.0"
@@ -7936,25 +7816,26 @@ dependencies = [
[[package]] [[package]]
name = "sphinx-packet" name = "sphinx-packet"
version = "0.1.0" version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc43eda802856ee82a7555c7b75ceb9e07451741c7a2f5f23d036020e01189d4" checksum = "dabeca95bf5fd0563d6be7ebcb1c6a9fcb135746a0ba9050c47dc68c8607e595"
dependencies = [ dependencies = [
"aes 0.7.5", "aes",
"arrayref", "arrayref",
"blake2 0.8.1", "blake2 0.8.1",
"bs58 0.4.0", "bs58 0.5.1",
"byteorder", "byteorder",
"chacha", "chacha",
"curve25519-dalek 3.2.0", "ctr",
"digest 0.9.0", "curve25519-dalek 4.1.2",
"hkdf 0.11.0", "digest 0.10.7",
"hmac 0.11.0", "hkdf",
"hmac",
"lioness", "lioness",
"log", "log",
"rand 0.7.3", "rand 0.8.5",
"rand_distr", "rand_distr",
"sha2 0.9.9", "sha2 0.10.8",
"subtle 2.5.0", "subtle 2.5.0",
] ]
@@ -8345,7 +8226,7 @@ checksum = "15ab8f0a25d0d2ad49ac615da054d6a76aa6603ff95f7d18bafdd34450a1a04b"
dependencies = [ dependencies = [
"bytes", "bytes",
"digest 0.10.7", "digest 0.10.7",
"ed25519 2.2.3", "ed25519",
"ed25519-consensus", "ed25519-consensus",
"flex-error", "flex-error",
"futures", "futures",
@@ -8360,7 +8241,7 @@ dependencies = [
"serde_json", "serde_json",
"serde_repr", "serde_repr",
"sha2 0.10.8", "sha2 0.10.8",
"signature 2.2.0", "signature",
"subtle 2.5.0", "subtle 2.5.0",
"subtle-encoding", "subtle-encoding",
"tendermint-proto", "tendermint-proto",
@@ -9334,11 +9215,14 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]] [[package]]
name = "vergen" name = "vergen"
version = "8.2.6" version = "8.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1290fd64cc4e7d3c9b07d7f333ce0ce0007253e32870e632624835cc80b83939" checksum = "e27d6bdd219887a9eadd19e1c34f32e47fa332301184935c6d9bca26f3cca525"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"cargo_metadata",
"cfg-if",
"regex",
"rustc_version 0.4.0", "rustc_version 0.4.0",
"rustversion", "rustversion",
"time", "time",
@@ -9496,7 +9380,7 @@ dependencies = [
"nym-task", "nym-task",
"nym-topology", "nym-topology",
"nym-validator-client", "nym-validator-client",
"rand 0.7.3", "rand 0.8.5",
"serde", "serde",
"serde-wasm-bindgen 0.6.5", "serde-wasm-bindgen 0.6.5",
"thiserror", "thiserror",
@@ -9952,18 +9836,6 @@ dependencies = [
"tap", "tap",
] ]
[[package]]
name = "x25519-dalek"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a0c105152107e3b96f6a00a65e86ce82d9b125230e1c4302940eca58ff71f4f"
dependencies = [
"curve25519-dalek 3.2.0",
"rand_core 0.5.1",
"serde",
"zeroize",
]
[[package]] [[package]]
name = "x25519-dalek" name = "x25519-dalek"
version = "2.0.1" version = "2.0.1"
+19 -19
View File
@@ -35,12 +35,9 @@ members = [
"common/cosmwasm-smart-contracts/coconut-bandwidth-contract", "common/cosmwasm-smart-contracts/coconut-bandwidth-contract",
"common/cosmwasm-smart-contracts/coconut-dkg", "common/cosmwasm-smart-contracts/coconut-dkg",
"common/cosmwasm-smart-contracts/contracts-common", "common/cosmwasm-smart-contracts/contracts-common",
# "common/cosmwasm-smart-contracts/ephemera",
"common/cosmwasm-smart-contracts/group-contract", "common/cosmwasm-smart-contracts/group-contract",
"common/cosmwasm-smart-contracts/mixnet-contract", "common/cosmwasm-smart-contracts/mixnet-contract",
"common/cosmwasm-smart-contracts/multisig-contract", "common/cosmwasm-smart-contracts/multisig-contract",
"common/cosmwasm-smart-contracts/name-service",
"common/cosmwasm-smart-contracts/service-provider-directory",
"common/cosmwasm-smart-contracts/vesting-contract", "common/cosmwasm-smart-contracts/vesting-contract",
"common/country-group", "common/country-group",
"common/credential-storage", "common/credential-storage",
@@ -119,7 +116,7 @@ members = [
"tools/nymvisor", "tools/nymvisor",
"tools/ts-rs-cli", "tools/ts-rs-cli",
"wasm/client", "wasm/client",
# "wasm/full-nym-wasm", # "wasm/full-nym-wasm", # If we uncomment this again, remember to also uncomment the profile settings below
"wasm/mix-fetch", "wasm/mix-fetch",
"wasm/node-tester", "wasm/node-tester",
"wasm/zknym-lib", "wasm/zknym-lib",
@@ -172,7 +169,7 @@ bincode = "1.3.3"
bip39 = { version = "2.0.0", features = ["zeroize"] } bip39 = { version = "2.0.0", features = ["zeroize"] }
bitvec = "1.0.0" bitvec = "1.0.0"
blake3 = "1.3.1" blake3 = "1.3.1"
bs58 = "0.5.0" bs58 = "0.5.1"
bytecodec = "0.4.15" bytecodec = "0.4.15"
bytes = "1.5.0" bytes = "1.5.0"
cargo_metadata = "0.18.1" cargo_metadata = "0.18.1"
@@ -195,13 +192,13 @@ criterion = "0.4"
csv = "1.3.0" csv = "1.3.0"
ctr = "0.9.1" ctr = "0.9.1"
cupid = "0.6.1" cupid = "0.6.1"
curve25519-dalek = "3.2" curve25519-dalek = "4.1"
dashmap = "5.5.3" dashmap = "5.5.3"
defguard_wireguard_rs = { git = "https://github.com/neacsu/wireguard-rs.git", rev = "c2cd0c1119f699f4bc43f5e6ffd6fc242caa42ed" } defguard_wireguard_rs = "0.4.2"
doc-comment = "0.3" doc-comment = "0.3"
dotenvy = "0.15.6" dotenvy = "0.15.6"
ecdsa = "0.16" ecdsa = "0.16"
ed25519-dalek = "1.0" ed25519-dalek = "2.1"
etherparse = "0.13.0" etherparse = "0.13.0"
eyre = "0.6.9" eyre = "0.6.9"
flate2 = "1.0.28" flate2 = "1.0.28"
@@ -247,7 +244,7 @@ rand = "0.8.5"
rand-07 = "0.7.3" rand-07 = "0.7.3"
rand_chacha_02 = "0.2" rand_chacha_02 = "0.2"
rand_core = "0.6.3" rand_core = "0.6.3"
rand_distr = "0.3" rand_distr = "0.4"
rand_pcg = "0.3.1" rand_pcg = "0.3.1"
rand_seeder = "0.2.3" rand_seeder = "0.2.3"
rayon = "1.5.1" rayon = "1.5.1"
@@ -266,7 +263,7 @@ serde_repr = "0.1"
serde_with = "3.4.0" serde_with = "3.4.0"
serde_yaml = "0.9.25" serde_yaml = "0.9.25"
si-scale = "0.2.2" si-scale = "0.2.2"
sphinx-packet = "0.1.0" sphinx-packet = "0.1.1"
sqlx = "0.6.3" sqlx = "0.6.3"
strum = "0.25" strum = "0.25"
subtle-encoding = "0.5" subtle-encoding = "0.5"
@@ -292,7 +289,7 @@ tungstenite = { version = "0.20.1", default-features = false }
url = "2.4" url = "2.4"
utoipa = "4.2.0" utoipa = "4.2.0"
utoipa-swagger-ui = "6.0.0" utoipa-swagger-ui = "6.0.0"
vergen = { version = "=8.2.6", default-features = false } vergen = { version = "=8.3.1", default-features = false }
walkdir = "2" walkdir = "2"
wasm-bindgen-test = "0.3.36" wasm-bindgen-test = "0.3.36"
zeroize = "1.6.0" zeroize = "1.6.0"
@@ -302,9 +299,9 @@ prometheus = { version = "0.13.0" }
# coconut/DKG related # coconut/DKG related
# unfortunately until https://github.com/zkcrypto/bls12_381/issues/10 is resolved, we have to rely on the fork # unfortunately until https://github.com/zkcrypto/bls12_381/issues/10 is resolved, we have to rely on the fork
# as we need to be able to serialize Gt so that we could create the lookup table for baby-step-giant-step algorithm # as we need to be able to serialize Gt so that we could create the lookup table for baby-step-giant-step algorithm
bls12_381 = { git = "https://github.com/jstuczyn/bls12_381", branch = "feature/gt-serialization-0.8.0" } bls12_381 = { git = "https://github.com/jstuczyn/bls12_381", default-features = false, branch = "feature/gt-serialization-0.8.0" }
group = "0.13.0" group = { version = "0.13.0", default-features = false }
ff = "0.13.0" ff = { version = "0.13.0", default-features = false }
# cosmwasm-related # cosmwasm-related
cosmwasm-derive = "=1.4.3" cosmwasm-derive = "=1.4.3"
@@ -323,14 +320,14 @@ cw4 = { version = "=1.1.2" }
cw-controllers = { version = "=1.1.0" } cw-controllers = { version = "=1.1.0" }
# cosmrs-related # cosmrs-related
bip32 = "0.5.1" bip32 = { version = "0.5.1", default-features = false }
# temporarily using a fork again (yay.) because we need staking and slashing support # temporarily using a fork again (yay.) because we need staking and slashing support
cosmrs = { git = "https://github.com/jstuczyn/cosmos-rust", branch = "nym-temp/all-validator-features" } cosmrs = { git = "https://github.com/jstuczyn/cosmos-rust", branch = "nym-temp/all-validator-features" }
#cosmrs = { git = "https://github.com/jstuczyn/cosmos-rust", branch = "nym-temp/all-validator-features" } # unfortuntely we need a fork by yours truly to get the staking support #cosmrs = { git = "https://github.com/jstuczyn/cosmos-rust", branch = "nym-temp/all-validator-features" } # unfortuntely we need a fork by yours truly to get the staking support
tendermint = "0.34" # same version as used by cosmrs tendermint = "0.34" # same version as used by cosmrs
tendermint-rpc = "0.34" # same version as used by cosmrs tendermint-rpc = "0.34" # same version as used by cosmrs
prost = "0.12" prost = { version = "0.12", default-features = false }
# wasm-related dependencies # wasm-related dependencies
gloo-utils = "0.2.0" gloo-utils = "0.2.0"
@@ -358,9 +355,12 @@ opt-level = 'z'
# lto = true # lto = true
opt-level = 'z' opt-level = 'z'
[profile.release.package.nym-wasm-sdk] # Commented out since the crate is also commented out from the inclusion in the
# lto = true # workspace above. We should uncomment this if we re-include it in the
opt-level = 'z' # workspace
#[profile.release.package.nym-wasm-sdk]
## lto = true
#opt-level = 'z'
[profile.release.package.mix-fetch-wasm] [profile.release.package.mix-fetch-wasm]
# lto = true # lto = true
+2 -2
View File
@@ -134,7 +134,7 @@ clippy: sdk-wasm-lint
# Build contracts ready for deploy # Build contracts ready for deploy
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
CONTRACTS=vesting_contract mixnet_contract nym_service_provider_directory nym_name_service CONTRACTS=vesting_contract mixnet_contract
CONTRACTS_WASM=$(addsuffix .wasm, $(CONTRACTS)) CONTRACTS_WASM=$(addsuffix .wasm, $(CONTRACTS))
CONTRACTS_OUT_DIR=contracts/target/wasm32-unknown-unknown/release CONTRACTS_OUT_DIR=contracts/target/wasm32-unknown-unknown/release
@@ -186,4 +186,4 @@ deb-gateway: build-nym-gateway
deb-cli: build-nym-cli deb-cli: build-nym-cli
cargo deb -p nym-cli cargo deb -p nym-cli
deb: deb-mixnode deb-gateway deb-cli deb: deb-mixnode deb-gateway deb-cli
+2 -2
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "nym-client" name = "nym-client"
version = "1.1.34" version = "1.1.35"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"] authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
description = "Implementation of the Nym Client" description = "Implementation of the Nym Client"
edition = "2021" edition = "2021"
@@ -25,7 +25,7 @@ bs58 = { workspace = true }
clap = { workspace = true, features = ["cargo", "derive"] } clap = { workspace = true, features = ["cargo", "derive"] }
dirs = "4.0" dirs = "4.0"
log = { workspace = true } # self explanatory log = { workspace = true } # self explanatory
rand = { version = "0.7.3", features = ["wasm-bindgen"] } # rng-related traits + some rng implementation to use rand = { workspace = true }
serde = { workspace = true, features = ["derive"] } # for config serialization/deserialization serde = { workspace = true, features = ["derive"] } # for config serialization/deserialization
serde_json = { workspace = true } serde_json = { workspace = true }
thiserror = { workspace = true } thiserror = { workspace = true }
+2 -2
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "nym-socks5-client" name = "nym-socks5-client"
version = "1.1.34" version = "1.1.35"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"] authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address" description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
edition = "2021" edition = "2021"
@@ -16,7 +16,7 @@ serde_json = { workspace = true }
tap = { workspace = true } tap = { workspace = true }
thiserror = { workspace = true } thiserror = { workspace = true }
tokio = { workspace = true, features = ["rt-multi-thread", "net", "signal"] } tokio = { workspace = true, features = ["rt-multi-thread", "net", "signal"] }
rand = "0.7.3" rand = { workspace = true }
time = { workspace = true } time = { workspace = true }
url = { workspace = true } url = { workspace = true }
zeroize = { workspace = true } zeroize = { workspace = true }
+1 -1
View File
@@ -9,7 +9,7 @@ license.workspace = true
[dependencies] [dependencies]
bip39 = { workspace = true } bip39 = { workspace = true }
log = { workspace = true } log = { workspace = true }
rand = "0.7.3" rand = { workspace = true }
thiserror = { workspace = true } thiserror = { workspace = true }
url = { workspace = true } url = { workspace = true }
zeroize = { workspace = true } zeroize = { workspace = true }
+1 -1
View File
@@ -17,7 +17,7 @@ clap = { workspace = true, optional = true }
futures = { workspace = true } futures = { workspace = true }
humantime-serde = { workspace = true } humantime-serde = { workspace = true }
log = { workspace = true } log = { workspace = true }
rand = { version = "0.7.3", features = ["wasm-bindgen"] } rand = { workspace = true }
serde = { workspace = true, features = ["derive"] } serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true } serde_json = { workspace = true }
sha2 = "0.10.6" sha2 = "0.10.6"
@@ -24,6 +24,11 @@ const DEFAULT_MESSAGE_STREAM_AVERAGE_DELAY: Duration = Duration::from_millis(20)
const DEFAULT_AVERAGE_PACKET_DELAY: Duration = Duration::from_millis(50); const DEFAULT_AVERAGE_PACKET_DELAY: Duration = Duration::from_millis(50);
const DEFAULT_TOPOLOGY_REFRESH_RATE: Duration = Duration::from_secs(5 * 60); // every 5min const DEFAULT_TOPOLOGY_REFRESH_RATE: Duration = Duration::from_secs(5 * 60); // every 5min
const DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT: Duration = Duration::from_millis(5_000); const DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT: Duration = Duration::from_millis(5_000);
// the same values as our current (10.06.24) blacklist
const DEFAULT_MIN_MIXNODE_PERFORMANCE: u8 = 50;
const DEFAULT_MIN_GATEWAY_PERFORMANCE: u8 = 50;
const DEFAULT_MAX_STARTUP_GATEWAY_WAITING_PERIOD: Duration = Duration::from_secs(70 * 60); // 70min -> full epoch (1h) + a bit of overhead const DEFAULT_MAX_STARTUP_GATEWAY_WAITING_PERIOD: Duration = Duration::from_secs(70 * 60); // 70min -> full epoch (1h) + a bit of overhead
// Set this to a high value for now, so that we don't risk sporadic timeouts that might cause // Set this to a high value for now, so that we don't risk sporadic timeouts that might cause
@@ -516,6 +521,14 @@ pub struct Topology {
/// Specifies the mixnode topology to be used for sending packets. /// Specifies the mixnode topology to be used for sending packets.
pub topology_structure: TopologyStructure, pub topology_structure: TopologyStructure,
/// Specifies a minimum performance of a mixnode that is used on route construction.
/// This setting is only applicable when `NymApi` topology is used.
pub minimum_mixnode_performance: u8,
/// Specifies a minimum performance of a gateway that is used on route construction.
/// This setting is only applicable when `NymApi` topology is used.
pub minimum_gateway_performance: u8,
} }
#[allow(clippy::large_enum_variant)] #[allow(clippy::large_enum_variant)]
@@ -550,6 +563,8 @@ impl Default for Topology {
disable_refreshing: false, disable_refreshing: false,
max_startup_gateway_waiting_period: DEFAULT_MAX_STARTUP_GATEWAY_WAITING_PERIOD, max_startup_gateway_waiting_period: DEFAULT_MAX_STARTUP_GATEWAY_WAITING_PERIOD,
topology_structure: TopologyStructure::default(), topology_structure: TopologyStructure::default(),
minimum_mixnode_performance: DEFAULT_MIN_MIXNODE_PERFORMANCE,
minimum_gateway_performance: DEFAULT_MIN_GATEWAY_PERFORMANCE,
} }
} }
} }
@@ -146,6 +146,7 @@ impl From<ConfigV5> for Config {
.topology .topology
.max_startup_gateway_waiting_period, .max_startup_gateway_waiting_period,
topology_structure: value.debug.topology.topology_structure.into(), topology_structure: value.debug.topology.topology_structure.into(),
..Default::default()
}, },
reply_surbs: ReplySurbs { reply_surbs: ReplySurbs {
minimum_reply_surb_storage_threshold: value minimum_reply_surb_storage_threshold: value
@@ -0,0 +1,18 @@
/*
* Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
* SPDX-License-Identifier: Apache-2.0
*/
CREATE TABLE remote_gateway_details_temp
(
gateway_id_bs58 TEXT NOT NULL UNIQUE PRIMARY KEY REFERENCES registered_gateway (gateway_id_bs58),
derived_aes128_ctr_blake3_hmac_keys_bs58 TEXT NOT NULL,
gateway_owner_address TEXT,
gateway_listener TEXT NOT NULL,
wg_tun_address TEXT
);
INSERT INTO remote_gateway_details_temp SELECT * FROM remote_gateway_details;
DROP TABLE remote_gateway_details;
ALTER TABLE remote_gateway_details_temp RENAME TO remote_gateway_details;
@@ -65,7 +65,7 @@ impl GatewayDetails {
pub fn new_remote( pub fn new_remote(
gateway_id: identity::PublicKey, gateway_id: identity::PublicKey,
derived_aes128_ctr_blake3_hmac_keys: Arc<SharedKeys>, derived_aes128_ctr_blake3_hmac_keys: Arc<SharedKeys>,
gateway_owner_address: AccountId, gateway_owner_address: Option<AccountId>,
gateway_listener: Url, gateway_listener: Url,
wg_tun_address: Option<Url>, wg_tun_address: Option<Url>,
) -> Self { ) -> Self {
@@ -170,7 +170,7 @@ pub struct RegisteredGateway {
pub struct RawRemoteGatewayDetails { pub struct RawRemoteGatewayDetails {
pub gateway_id_bs58: String, pub gateway_id_bs58: String,
pub derived_aes128_ctr_blake3_hmac_keys_bs58: String, pub derived_aes128_ctr_blake3_hmac_keys_bs58: String,
pub gateway_owner_address: String, pub gateway_owner_address: Option<String>,
pub gateway_listener: String, pub gateway_listener: String,
pub wg_tun_address: Option<String>, pub wg_tun_address: Option<String>,
} }
@@ -195,14 +195,19 @@ impl TryFrom<RawRemoteGatewayDetails> for RemoteGatewayDetails {
})?, })?,
); );
let gateway_owner_address = let gateway_owner_address = value
AccountId::from_str(&value.gateway_owner_address).map_err(|source| { .gateway_owner_address
BadGateway::MalformedGatewayOwnerAccountAddress { .as_ref()
gateway_id: value.gateway_id_bs58.clone(), .map(|raw_owner| {
raw_owner: value.gateway_owner_address.clone(), AccountId::from_str(raw_owner).map_err(|source| {
source, BadGateway::MalformedGatewayOwnerAccountAddress {
} gateway_id: value.gateway_id_bs58.clone(),
})?; raw_owner: raw_owner.clone(),
source,
}
})
})
.transpose()?;
let gateway_listener = Url::parse(&value.gateway_listener).map_err(|source| { let gateway_listener = Url::parse(&value.gateway_listener).map_err(|source| {
BadGateway::MalformedListener { BadGateway::MalformedListener {
@@ -241,7 +246,7 @@ impl<'a> From<&'a RemoteGatewayDetails> for RawRemoteGatewayDetails {
derived_aes128_ctr_blake3_hmac_keys_bs58: value derived_aes128_ctr_blake3_hmac_keys_bs58: value
.derived_aes128_ctr_blake3_hmac_keys .derived_aes128_ctr_blake3_hmac_keys
.to_base58_string(), .to_base58_string(),
gateway_owner_address: value.gateway_owner_address.to_string(), gateway_owner_address: value.gateway_owner_address.as_ref().map(|o| o.to_string()),
gateway_listener: value.gateway_listener.to_string(), gateway_listener: value.gateway_listener.to_string(),
wg_tun_address: value.wg_tun_address.as_ref().map(|addr| addr.to_string()), wg_tun_address: value.wg_tun_address.as_ref().map(|addr| addr.to_string()),
} }
@@ -256,7 +261,7 @@ pub struct RemoteGatewayDetails {
// the keys will be zeroized // the keys will be zeroized
pub derived_aes128_ctr_blake3_hmac_keys: Arc<SharedKeys>, pub derived_aes128_ctr_blake3_hmac_keys: Arc<SharedKeys>,
pub gateway_owner_address: AccountId, pub gateway_owner_address: Option<AccountId>,
pub gateway_listener: Url, pub gateway_listener: Url,
@@ -25,7 +25,7 @@ use crate::client::replies::reply_storage::{
}; };
use crate::client::topology_control::nym_api_provider::NymApiTopologyProvider; use crate::client::topology_control::nym_api_provider::NymApiTopologyProvider;
use crate::client::topology_control::{ use crate::client::topology_control::{
TopologyAccessor, TopologyRefresher, TopologyRefresherConfig, nym_api_provider, TopologyAccessor, TopologyRefresher, TopologyRefresherConfig,
}; };
use crate::config::{Config, DebugConfig}; use crate::config::{Config, DebugConfig};
use crate::error::ClientCoreError; use crate::error::ClientCoreError;
@@ -388,7 +388,10 @@ where
let cfg = GatewayConfig::new( let cfg = GatewayConfig::new(
details.gateway_id, details.gateway_id,
Some(details.gateway_owner_address.to_string()), details
.gateway_owner_address
.as_ref()
.map(|o| o.to_string()),
gateway_listener, gateway_listener,
); );
GatewayClient::new( GatewayClient::new(
@@ -462,12 +465,16 @@ where
fn setup_topology_provider( fn setup_topology_provider(
custom_provider: Option<Box<dyn TopologyProvider + Send + Sync>>, custom_provider: Option<Box<dyn TopologyProvider + Send + Sync>>,
provider_from_config: config::TopologyStructure, config_topology: config::Topology,
nym_api_urls: Vec<Url>, nym_api_urls: Vec<Url>,
) -> Box<dyn TopologyProvider + Send + Sync> { ) -> Box<dyn TopologyProvider + Send + Sync> {
// if no custom provider was ... provided ..., create one using nym-api // if no custom provider was ... provided ..., create one using nym-api
custom_provider.unwrap_or_else(|| match provider_from_config { custom_provider.unwrap_or_else(|| match config_topology.topology_structure {
config::TopologyStructure::NymApi => Box::new(NymApiTopologyProvider::new( config::TopologyStructure::NymApi => Box::new(NymApiTopologyProvider::new(
nym_api_provider::Config {
min_mixnode_performance: config_topology.minimum_mixnode_performance,
min_gateway_performance: config_topology.minimum_gateway_performance,
},
nym_api_urls, nym_api_urls,
env!("CARGO_PKG_VERSION").to_string(), env!("CARGO_PKG_VERSION").to_string(),
)), )),
@@ -680,7 +687,7 @@ where
let topology_provider = Self::setup_topology_provider( let topology_provider = Self::setup_topology_provider(
self.custom_topology_provider.take(), self.custom_topology_provider.take(),
self.config.debug.topology.topology_structure, self.config.debug.topology,
self.config.get_nym_api_endpoints(), self.config.get_nym_api_endpoints(),
); );
@@ -92,11 +92,11 @@ pub mod v1_1_33 {
message: format!("the stored gateway id was malformed: {err}"), message: format!("the stored gateway id was malformed: {err}"),
})?, })?,
derived_aes128_ctr_blake3_hmac_keys: Arc::new(gateway_shared_key), derived_aes128_ctr_blake3_hmac_keys: Arc::new(gateway_shared_key),
gateway_owner_address: gateway_owner.parse().map_err(|err| { gateway_owner_address: Some(gateway_owner.parse().map_err(|err| {
ClientCoreError::UpgradeFailure { ClientCoreError::UpgradeFailure {
message: format!("the stored gateway owner address was malformed: {err}"), message: format!("the stored gateway owner address was malformed: {err}"),
} }
})?, })?),
gateway_listener: gateway_listener.parse().map_err(|err| { gateway_listener: gateway_listener.parse().map_err(|err| {
ClientCoreError::UpgradeFailure { ClientCoreError::UpgradeFailure {
message: format!("the stored gateway listener address was malformed: {err}"), message: format!("the stored gateway listener address was malformed: {err}"),
@@ -2,14 +2,35 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
use async_trait::async_trait; use async_trait::async_trait;
use log::{error, warn}; use log::{debug, error, warn};
use nym_topology::provider_trait::TopologyProvider; use nym_topology::provider_trait::TopologyProvider;
use nym_topology::{nym_topology_from_detailed, NymTopology, NymTopologyError}; use nym_topology::{NymTopology, NymTopologyError};
use rand::prelude::SliceRandom; use rand::prelude::SliceRandom;
use rand::thread_rng; use rand::thread_rng;
use url::Url; use url::Url;
// the same values as our current (10.06.24) blacklist
pub const DEFAULT_MIN_MIXNODE_PERFORMANCE: u8 = 50;
pub const DEFAULT_MIN_GATEWAY_PERFORMANCE: u8 = 50;
pub(crate) struct Config {
pub(crate) min_mixnode_performance: u8,
pub(crate) min_gateway_performance: u8,
}
impl Default for Config {
fn default() -> Self {
// old values that decided on blacklist membership
Config {
min_mixnode_performance: DEFAULT_MIN_MIXNODE_PERFORMANCE,
min_gateway_performance: DEFAULT_MIN_GATEWAY_PERFORMANCE,
}
}
}
pub(crate) struct NymApiTopologyProvider { pub(crate) struct NymApiTopologyProvider {
config: Config,
validator_client: nym_validator_client::client::NymApiClient, validator_client: nym_validator_client::client::NymApiClient,
nym_api_urls: Vec<Url>, nym_api_urls: Vec<Url>,
@@ -18,10 +39,11 @@ pub(crate) struct NymApiTopologyProvider {
} }
impl NymApiTopologyProvider { impl NymApiTopologyProvider {
pub(crate) fn new(mut nym_api_urls: Vec<Url>, client_version: String) -> Self { pub(crate) fn new(config: Config, mut nym_api_urls: Vec<Url>, client_version: String) -> Self {
nym_api_urls.shuffle(&mut thread_rng()); nym_api_urls.shuffle(&mut thread_rng());
NymApiTopologyProvider { NymApiTopologyProvider {
config,
validator_client: nym_validator_client::client::NymApiClient::new( validator_client: nym_validator_client::client::NymApiClient::new(
nym_api_urls[0].clone(), nym_api_urls[0].clone(),
), ),
@@ -61,7 +83,11 @@ impl NymApiTopologyProvider {
} }
async fn get_current_compatible_topology(&mut self) -> Option<NymTopology> { async fn get_current_compatible_topology(&mut self) -> Option<NymTopology> {
let mixnodes = match self.validator_client.get_cached_active_mixnodes().await { let mixnodes = match self
.validator_client
.get_basic_mixnodes(Some(self.client_version.clone()))
.await
{
Err(err) => { Err(err) => {
error!("failed to get network mixnodes - {err}"); error!("failed to get network mixnodes - {err}");
return None; return None;
@@ -69,7 +95,11 @@ impl NymApiTopologyProvider {
Ok(mixes) => mixes, Ok(mixes) => mixes,
}; };
let gateways = match self.validator_client.get_cached_described_gateways().await { let gateways = match self
.validator_client
.get_basic_gateways(Some(self.client_version.clone()))
.await
{
Err(err) => { Err(err) => {
error!("failed to get network gateways - {err}"); error!("failed to get network gateways - {err}");
return None; return None;
@@ -77,8 +107,20 @@ impl NymApiTopologyProvider {
Ok(gateways) => gateways, Ok(gateways) => gateways,
}; };
let topology = nym_topology_from_detailed(mixnodes, gateways) debug!(
.filter_system_version(&self.client_version); "there are {} mixnodes and {} gateways in total (before performance filtering)",
mixnodes.len(),
gateways.len()
);
let topology = NymTopology::from_unordered(
mixnodes.iter().filter(|m| {
m.performance.round_to_integer() >= self.config.min_mixnode_performance
}),
gateways.iter().filter(|g| {
g.performance.round_to_integer() >= self.config.min_gateway_performance
}),
);
if let Err(err) = self.check_layer_distribution(&topology) { if let Err(err) = self.check_layer_distribution(&topology) {
warn!("The current filtered active topology has extremely skewed layer distribution. It cannot be used: {err}"); warn!("The current filtered active topology has extremely skewed layer distribution. It cannot be used: {err}");
+14 -8
View File
@@ -29,7 +29,7 @@ pub enum SelectedGateway {
Remote { Remote {
gateway_id: identity::PublicKey, gateway_id: identity::PublicKey,
gateway_owner_address: AccountId, gateway_owner_address: Option<AccountId>,
gateway_listener: Url, gateway_listener: Url,
@@ -84,13 +84,19 @@ impl SelectedGateway {
let wg_tun_address = wg_tun_address(wg_tun_ip_address, &node)?; let wg_tun_address = wg_tun_address(wg_tun_ip_address, &node)?;
let gateway_owner_address = AccountId::from_str(&node.owner).map_err(|source| { let gateway_owner_address = node
ClientCoreError::MalformedGatewayOwnerAccountAddress { .owner
gateway_id: node.identity_key.to_base58_string(), .as_ref()
raw_owner: node.owner, .map(|raw_owner| {
err: source.to_string(), AccountId::from_str(raw_owner).map_err(|source| {
} ClientCoreError::MalformedGatewayOwnerAccountAddress {
})?; gateway_id: node.identity_key.to_base58_string(),
raw_owner: raw_owner.clone(),
err: source.to_string(),
}
})
})
.transpose()?;
let gateway_listener = let gateway_listener =
Url::parse(&gateway_listener).map_err(|source| ClientCoreError::MalformedListener { Url::parse(&gateway_listener).map_err(|source| ClientCoreError::MalformedListener {
+1 -1
View File
@@ -14,7 +14,7 @@ futures = { workspace = true }
log = { workspace = true } log = { workspace = true }
thiserror = { workspace = true } thiserror = { workspace = true }
url = { workspace = true } url = { workspace = true }
rand = { version = "0.7.3", features = ["wasm-bindgen"] } rand = { workspace = true }
tokio = { workspace = true, features = ["macros"] } tokio = { workspace = true, features = ["macros"] }
si-scale = { workspace = true } si-scale = { workspace = true }
time.workspace = true time.workspace = true
@@ -220,9 +220,18 @@ impl<C, St> GatewayClient<C, St> {
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
pub async fn establish_connection(&mut self) -> Result<(), GatewayClientError> { pub async fn establish_connection(&mut self) -> Result<(), GatewayClientError> {
debug!(
"Attemting to establish connection to gateway at: {}",
self.gateway_address
);
let ws_stream = match connect_async(&self.gateway_address).await { let ws_stream = match connect_async(&self.gateway_address).await {
Ok((ws_stream, _)) => ws_stream, Ok((ws_stream, _)) => ws_stream,
Err(e) => return Err(GatewayClientError::NetworkError(e)), Err(error) => {
return Err(GatewayClientError::NetworkConnectionFailed {
address: self.gateway_address.clone(),
source: error,
})
}
}; };
self.connection = SocketState::Available(Box::new(ws_stream)); self.connection = SocketState::Available(Box::new(ws_stream));
@@ -23,6 +23,9 @@ pub enum GatewayClientError {
#[error("There was a network error: {0}")] #[error("There was a network error: {0}")]
NetworkErrorWasm(#[from] JsError), NetworkErrorWasm(#[from] JsError),
#[error("connection failed: {address}: {source}")]
NetworkConnectionFailed { address: String, source: WsError },
#[error("Invalid URL: {0}")] #[error("Invalid URL: {0}")]
InvalidURL(String), InvalidURL(String),
+1 -12
View File
@@ -14,17 +14,14 @@ colored = { workspace = true }
nym-coconut-dkg-common = { path = "../../cosmwasm-smart-contracts/coconut-dkg" } nym-coconut-dkg-common = { path = "../../cosmwasm-smart-contracts/coconut-dkg" }
nym-contracts-common = { path = "../../cosmwasm-smart-contracts/contracts-common" } nym-contracts-common = { path = "../../cosmwasm-smart-contracts/contracts-common" }
nym-ephemera-common = { path = "../../cosmwasm-smart-contracts/ephemera" }
nym-mixnet-contract-common = { path = "../../cosmwasm-smart-contracts/mixnet-contract" } nym-mixnet-contract-common = { path = "../../cosmwasm-smart-contracts/mixnet-contract" }
nym-vesting-contract-common = { path = "../../cosmwasm-smart-contracts/vesting-contract" } nym-vesting-contract-common = { path = "../../cosmwasm-smart-contracts/vesting-contract" }
nym-coconut-bandwidth-contract-common = { path = "../../cosmwasm-smart-contracts/coconut-bandwidth-contract" } nym-coconut-bandwidth-contract-common = { path = "../../cosmwasm-smart-contracts/coconut-bandwidth-contract" }
nym-multisig-contract-common = { path = "../../cosmwasm-smart-contracts/multisig-contract" } nym-multisig-contract-common = { path = "../../cosmwasm-smart-contracts/multisig-contract" }
nym-name-service-common = { path = "../../cosmwasm-smart-contracts/name-service" }
nym-group-contract-common = { path = "../../cosmwasm-smart-contracts/group-contract" } nym-group-contract-common = { path = "../../cosmwasm-smart-contracts/group-contract" }
nym-service-provider-directory-common = { path = "../../cosmwasm-smart-contracts/service-provider-directory" }
serde = { workspace = true, features = ["derive"] } serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true } serde_json = { workspace = true }
nym-http-api-client = { path = "../../../common/http-api-client"} nym-http-api-client = { path = "../../../common/http-api-client" }
thiserror = { workspace = true } thiserror = { workspace = true }
log = { workspace = true } log = { workspace = true }
url = { workspace = true, features = ["serde"] } url = { workspace = true, features = ["serde"] }
@@ -86,14 +83,6 @@ name = "offline_signing"
# (traits would need to be moved around and refactored themselves) # (traits would need to be moved around and refactored themselves)
required-features = ["http-client"] required-features = ["http-client"]
[[example]]
name = "query_service_provider_directory"
required-features = ["http-client"]
[[example]]
name = "query_name_service"
required-features = ["http-client"]
[features] [features]
default = ["http-client"] default = ["http-client"]
http-client = ["cosmrs/rpc"] http-client = ["cosmrs/rpc"]
@@ -1,37 +0,0 @@
use std::str::FromStr;
use cosmrs::AccountId;
use nym_name_service_common::Address;
use nym_network_defaults::{setup_env, NymNetworkDetails};
use nym_validator_client::nyxd::contract_traits::{
NameServiceQueryClient, PagedNameServiceQueryClient,
};
#[tokio::main]
async fn main() {
setup_env(Some("../../../envs/qa.env"));
let network_details = NymNetworkDetails::new_from_env();
let config =
nym_validator_client::Config::try_from_nym_network_details(&network_details).unwrap();
let client = nym_validator_client::Client::new_query(config).unwrap();
let config = client.nyxd.get_name_service_config().await.unwrap();
println!("config: {config:?}");
let names_paged = client.nyxd.get_names_paged(None, None).await.unwrap();
println!("names (paged): {names_paged:#?}");
let names = client.nyxd.get_all_names().await.unwrap();
println!("names: {names:#?}");
let owner = AccountId::from_str("n1hmf957kc7arcd39rl7xq8l0a4zyg7kxnv7su87").unwrap();
let names_by_owner = client.nyxd.get_names_by_owner(owner).await.unwrap();
println!("names (by owner): {names_by_owner:#?}");
let nym_address = Address::new("client_id.client_key@gateway_id").unwrap();
let names_by_address = client.nyxd.get_names_by_address(nym_address).await.unwrap();
println!("names (by address): {names_by_address:#?}");
let service_info = client.nyxd.get_name_entry(1).await;
println!("service info: {service_info:#?}");
}
@@ -1,45 +0,0 @@
use std::str::FromStr;
use cosmrs::AccountId;
use nym_network_defaults::{setup_env, NymNetworkDetails};
use nym_service_provider_directory_common::NymAddress;
use nym_validator_client::nyxd::contract_traits::{
PagedSpDirectoryQueryClient, SpDirectoryQueryClient,
};
#[tokio::main]
async fn main() {
setup_env(Some("../../../envs/qa.env"));
let network_details = NymNetworkDetails::new_from_env();
let config =
nym_validator_client::Config::try_from_nym_network_details(&network_details).unwrap();
let client = nym_validator_client::Client::new_query(config).unwrap();
let config = client.nyxd.get_service_config().await.unwrap();
println!("config: {config:?}");
let services_paged = client.nyxd.get_services_paged(None, None).await.unwrap();
println!("services (paged): {services_paged:#?}");
let services = client.nyxd.get_all_services().await.unwrap();
println!("services: {services:#?}");
let announcer = AccountId::from_str("n1hmf957kc7arcd39rl7xq8l0a4zyg7kxnv7su87").unwrap();
let services_by_announcer = client
.nyxd
.get_services_by_announcer(announcer)
.await
.unwrap();
println!("services (by announcer): {services_by_announcer:#?}");
let nym_address = NymAddress::new("foo.bar@gateway");
let services_by_nym_address = client
.nyxd
.get_services_by_nym_address(nym_address)
.await
.unwrap();
assert_eq!(services_by_announcer, services_by_nym_address);
let service_info = client.nyxd.get_service_info(1).await;
println!("service info: {service_info:#?}");
}
@@ -18,6 +18,7 @@ use nym_api_requests::models::{
GatewayCoreStatusResponse, MixnodeCoreStatusResponse, MixnodeStatusResponse, GatewayCoreStatusResponse, MixnodeCoreStatusResponse, MixnodeStatusResponse,
RewardEstimationResponse, StakeSaturationResponse, RewardEstimationResponse, StakeSaturationResponse,
}; };
use nym_api_requests::nym_nodes::SkimmedNode;
use nym_network_defaults::NymNetworkDetails; use nym_network_defaults::NymNetworkDetails;
use url::Url; use url::Url;
@@ -265,6 +266,28 @@ impl NymApiClient {
self.nym_api.change_base_url(new_endpoint); self.nym_api.change_base_url(new_endpoint);
} }
pub async fn get_basic_mixnodes(
&self,
semver_compatibility: Option<String>,
) -> Result<Vec<SkimmedNode>, ValidatorClientError> {
Ok(self
.nym_api
.get_basic_mixnodes(semver_compatibility)
.await?
.nodes)
}
pub async fn get_basic_gateways(
&self,
semver_compatibility: Option<String>,
) -> Result<Vec<SkimmedNode>, ValidatorClientError> {
Ok(self
.nym_api
.get_basic_gateways(semver_compatibility)
.await?
.nodes)
}
pub async fn get_cached_active_mixnodes( pub async fn get_cached_active_mixnodes(
&self, &self,
) -> Result<Vec<MixNodeDetails>, ValidatorClientError> { ) -> Result<Vec<MixNodeDetails>, ValidatorClientError> {
@@ -25,14 +25,13 @@ pub use nym_coconut_dkg_common::types::EpochId;
use nym_http_api_client::{ApiClient, NO_PARAMS}; use nym_http_api_client::{ApiClient, NO_PARAMS};
use nym_mixnet_contract_common::mixnode::MixNodeDetails; use nym_mixnet_contract_common::mixnode::MixNodeDetails;
use nym_mixnet_contract_common::{GatewayBond, IdentityKeyRef, MixId}; use nym_mixnet_contract_common::{GatewayBond, IdentityKeyRef, MixId};
use nym_name_service_common::response::NamesListResponse;
use nym_service_provider_directory_common::response::ServicesListResponse;
pub mod error; pub mod error;
pub mod routes; pub mod routes;
use nym_api_requests::coconut::models::FreePassNonceResponse; use nym_api_requests::coconut::models::FreePassNonceResponse;
use nym_api_requests::coconut::FreePassRequest; use nym_api_requests::coconut::FreePassRequest;
use nym_api_requests::nym_nodes::{CachedNodesResponse, SkimmedNode};
pub use nym_http_api_client::Client; pub use nym_http_api_client::Client;
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
@@ -97,6 +96,52 @@ pub trait NymApiClientExt: ApiClient {
.await .await
} }
async fn get_basic_mixnodes(
&self,
semver_compatibility: Option<String>,
) -> Result<CachedNodesResponse<SkimmedNode>, NymAPIError> {
let params = if let Some(semver_compatibility) = &semver_compatibility {
vec![("semver_compatibility", semver_compatibility.as_str())]
} else {
vec![]
};
self.get_json(
&[
routes::API_VERSION,
"unstable",
"nym-nodes",
"mixnodes",
"skimmed",
],
&params,
)
.await
}
async fn get_basic_gateways(
&self,
semver_compatibility: Option<String>,
) -> Result<CachedNodesResponse<SkimmedNode>, NymAPIError> {
let params = if let Some(semver_compatibility) = &semver_compatibility {
vec![("semver_compatibility", semver_compatibility.as_str())]
} else {
vec![]
};
self.get_json(
&[
routes::API_VERSION,
"unstable",
"nym-nodes",
"gateways",
"skimmed",
],
&params,
)
.await
}
async fn get_active_mixnodes(&self) -> Result<Vec<MixNodeDetails>, NymAPIError> { async fn get_active_mixnodes(&self) -> Result<Vec<MixNodeDetails>, NymAPIError> {
self.get_json( self.get_json(
&[routes::API_VERSION, routes::MIXNODES, routes::ACTIVE], &[routes::API_VERSION, routes::MIXNODES, routes::ACTIVE],
@@ -492,19 +537,6 @@ pub trait NymApiClientExt: ApiClient {
) )
.await .await
} }
async fn get_service_providers(&self) -> Result<ServicesListResponse, NymAPIError> {
log::trace!("Getting service providers");
self.get_json(&[routes::API_VERSION, routes::SERVICE_PROVIDERS], NO_PARAMS)
.await
}
//async fn get_registered_names(&self) -> Result<Vec<NameEntry>, NymAPIError> {
async fn get_registered_names(&self) -> Result<NamesListResponse, NymAPIError> {
log::trace!("Getting registered names");
self.get_json(&[routes::API_VERSION, routes::REGISTERED_NAMES], NO_PARAMS)
.await
}
} }
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
@@ -40,4 +40,3 @@ pub const STAKE_SATURATION: &str = "stake-saturation";
pub const INCLUSION_CHANCE: &str = "inclusion-probability"; pub const INCLUSION_CHANCE: &str = "inclusion-probability";
pub const SERVICE_PROVIDERS: &str = "services"; pub const SERVICE_PROVIDERS: &str = "services";
pub const REGISTERED_NAMES: &str = "names";
@@ -1,79 +0,0 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::collect_paged;
use crate::nyxd::contract_traits::NymContractsProvider;
use crate::nyxd::error::NyxdError;
use crate::nyxd::CosmWasmClient;
use async_trait::async_trait;
use nym_ephemera_common::msg::QueryMsg as EphemeraQueryMsg;
use nym_ephemera_common::peers::PagedPeerResponse;
use nym_ephemera_common::types::JsonPeerInfo;
use serde::Deserialize;
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
pub trait EphemeraQueryClient {
async fn query_ephemera_contract<T>(&self, query: EphemeraQueryMsg) -> Result<T, NyxdError>
where
for<'a> T: Deserialize<'a>;
async fn get_peers_paged(
&self,
start_after: Option<String>,
limit: Option<u32>,
) -> Result<PagedPeerResponse, NyxdError> {
let request = EphemeraQueryMsg::GetPeers { start_after, limit };
self.query_ephemera_contract(request).await
}
}
// extension trait to the query client to deal with the paged queries
// (it didn't feel appropriate to combine it with the existing trait
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
pub trait PagedEphemeraQueryClient: EphemeraQueryClient {
async fn get_all_ephemera_peers(&self) -> Result<Vec<JsonPeerInfo>, NyxdError> {
collect_paged!(self, get_peers_paged, peers)
}
}
#[async_trait]
impl<T> PagedEphemeraQueryClient for T where T: EphemeraQueryClient {}
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl<C> EphemeraQueryClient for C
where
C: CosmWasmClient + NymContractsProvider + Send + Sync,
{
async fn query_ephemera_contract<T>(&self, query: EphemeraQueryMsg) -> Result<T, NyxdError>
where
for<'a> T: Deserialize<'a>,
{
let ephemera_contract_address = &self
.ephemera_contract_address()
.ok_or_else(|| NyxdError::unavailable_contract_address("ephemera contract"))?;
self.query_contract_smart(ephemera_contract_address, &query)
.await
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::nyxd::contract_traits::tests::IgnoreValue;
// it's enough that this compiles and clippy is happy about it
#[allow(dead_code)]
fn all_query_variants_are_covered<C: EphemeraQueryClient + Send + Sync>(
client: C,
msg: EphemeraQueryMsg,
) {
match msg {
EphemeraQueryMsg::GetPeers { limit, start_after } => {
client.get_peers_paged(start_after, limit).ignore()
}
};
}
}
@@ -1,86 +0,0 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::nyxd::contract_traits::NymContractsProvider;
use crate::nyxd::cosmwasm_client::types::ExecuteResult;
use crate::nyxd::error::NyxdError;
use crate::nyxd::{Coin, Fee, SigningCosmWasmClient};
use crate::signing::signer::OfflineSigner;
use async_trait::async_trait;
use nym_ephemera_common::msg::ExecuteMsg as EphemeraExecuteMsg;
use nym_ephemera_common::types::JsonPeerInfo;
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
pub trait EphemeraSigningClient {
async fn execute_ephemera_contract(
&self,
fee: Option<Fee>,
msg: EphemeraExecuteMsg,
memo: String,
funds: Vec<Coin>,
) -> Result<ExecuteResult, NyxdError>;
async fn register_as_peer(
&self,
peer_info: JsonPeerInfo,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
let req = EphemeraExecuteMsg::RegisterPeer { peer_info };
self.execute_ephemera_contract(fee, req, "registering as peer".to_string(), vec![])
.await
}
}
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl<C> EphemeraSigningClient for C
where
C: SigningCosmWasmClient + NymContractsProvider + Sync,
NyxdError: From<<Self as OfflineSigner>::Error>,
{
async fn execute_ephemera_contract(
&self,
fee: Option<Fee>,
msg: EphemeraExecuteMsg,
memo: String,
funds: Vec<Coin>,
) -> Result<ExecuteResult, NyxdError> {
let ephemera_contract_address = self
.ephemera_contract_address()
.ok_or_else(|| NyxdError::unavailable_contract_address("ephemera contract"))?;
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier())));
let signer_address = &self.signer_addresses()?[0];
self.execute(
signer_address,
ephemera_contract_address,
&msg,
fee,
memo,
funds,
)
.await
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::nyxd::contract_traits::tests::IgnoreValue;
// it's enough that this compiles and clippy is happy about it
#[allow(dead_code)]
fn all_execute_variants_are_covered<C: EphemeraSigningClient + Send + Sync>(
client: C,
msg: EphemeraExecuteMsg,
) {
match msg {
EphemeraExecuteMsg::RegisterPeer { peer_info } => {
client.register_as_peer(peer_info, None).ignore()
}
};
}
}
@@ -10,23 +10,17 @@ use std::str::FromStr;
// query clients // query clients
pub mod coconut_bandwidth_query_client; pub mod coconut_bandwidth_query_client;
pub mod dkg_query_client; pub mod dkg_query_client;
pub mod ephemera_query_client;
pub mod group_query_client; pub mod group_query_client;
pub mod mixnet_query_client; pub mod mixnet_query_client;
pub mod multisig_query_client; pub mod multisig_query_client;
pub mod name_service_query_client;
pub mod sp_directory_query_client;
pub mod vesting_query_client; pub mod vesting_query_client;
// signing clients // signing clients
pub mod coconut_bandwidth_signing_client; pub mod coconut_bandwidth_signing_client;
pub mod dkg_signing_client; pub mod dkg_signing_client;
pub mod ephemera_signing_client;
pub mod group_signing_client; pub mod group_signing_client;
pub mod mixnet_signing_client; pub mod mixnet_signing_client;
pub mod multisig_signing_client; pub mod multisig_signing_client;
pub mod name_service_signing_client;
pub mod sp_directory_signing_client;
pub mod vesting_signing_client; pub mod vesting_signing_client;
// re-export query traits // re-export query traits
@@ -34,23 +28,17 @@ pub use coconut_bandwidth_query_client::{
CoconutBandwidthQueryClient, PagedCoconutBandwidthQueryClient, CoconutBandwidthQueryClient, PagedCoconutBandwidthQueryClient,
}; };
pub use dkg_query_client::{DkgQueryClient, PagedDkgQueryClient}; pub use dkg_query_client::{DkgQueryClient, PagedDkgQueryClient};
pub use ephemera_query_client::{EphemeraQueryClient, PagedEphemeraQueryClient};
pub use group_query_client::{GroupQueryClient, PagedGroupQueryClient}; pub use group_query_client::{GroupQueryClient, PagedGroupQueryClient};
pub use mixnet_query_client::{MixnetQueryClient, PagedMixnetQueryClient}; pub use mixnet_query_client::{MixnetQueryClient, PagedMixnetQueryClient};
pub use multisig_query_client::{MultisigQueryClient, PagedMultisigQueryClient}; pub use multisig_query_client::{MultisigQueryClient, PagedMultisigQueryClient};
pub use name_service_query_client::{NameServiceQueryClient, PagedNameServiceQueryClient};
pub use sp_directory_query_client::{PagedSpDirectoryQueryClient, SpDirectoryQueryClient};
pub use vesting_query_client::{PagedVestingQueryClient, VestingQueryClient}; pub use vesting_query_client::{PagedVestingQueryClient, VestingQueryClient};
// re-export signing traits // re-export signing traits
pub use coconut_bandwidth_signing_client::CoconutBandwidthSigningClient; pub use coconut_bandwidth_signing_client::CoconutBandwidthSigningClient;
pub use dkg_signing_client::DkgSigningClient; pub use dkg_signing_client::DkgSigningClient;
pub use ephemera_signing_client::EphemeraSigningClient;
pub use group_signing_client::GroupSigningClient; pub use group_signing_client::GroupSigningClient;
pub use mixnet_signing_client::MixnetSigningClient; pub use mixnet_signing_client::MixnetSigningClient;
pub use multisig_signing_client::MultisigSigningClient; pub use multisig_signing_client::MultisigSigningClient;
pub use name_service_signing_client::NameServiceSigningClient;
pub use sp_directory_signing_client::SpDirectorySigningClient;
pub use vesting_signing_client::VestingSigningClient; pub use vesting_signing_client::VestingSigningClient;
// helper for providing blanket implementation for query clients // helper for providing blanket implementation for query clients
@@ -64,13 +52,6 @@ pub trait NymContractsProvider {
fn dkg_contract_address(&self) -> Option<&AccountId>; fn dkg_contract_address(&self) -> Option<&AccountId>;
fn group_contract_address(&self) -> Option<&AccountId>; fn group_contract_address(&self) -> Option<&AccountId>;
fn multisig_contract_address(&self) -> Option<&AccountId>; fn multisig_contract_address(&self) -> Option<&AccountId>;
// ephemera-related
fn ephemera_contract_address(&self) -> Option<&AccountId>;
// SPs
fn name_service_contract_address(&self) -> Option<&AccountId>;
fn service_provider_contract_address(&self) -> Option<&AccountId>;
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@@ -82,11 +63,6 @@ pub struct TypedNymContracts {
pub group_contract_address: Option<AccountId>, pub group_contract_address: Option<AccountId>,
pub multisig_contract_address: Option<AccountId>, pub multisig_contract_address: Option<AccountId>,
pub coconut_dkg_contract_address: Option<AccountId>, pub coconut_dkg_contract_address: Option<AccountId>,
pub ephemera_contract_address: Option<AccountId>,
pub service_provider_directory_contract_address: Option<AccountId>,
pub name_service_contract_address: Option<AccountId>,
} }
impl TryFrom<NymContracts> for TypedNymContracts { impl TryFrom<NymContracts> for TypedNymContracts {
@@ -118,18 +94,6 @@ impl TryFrom<NymContracts> for TypedNymContracts {
.coconut_dkg_contract_address .coconut_dkg_contract_address
.map(|addr| addr.parse()) .map(|addr| addr.parse())
.transpose()?, .transpose()?,
ephemera_contract_address: value
.ephemera_contract_address
.map(|addr| addr.parse())
.transpose()?,
service_provider_directory_contract_address: value
.service_provider_directory_contract_address
.map(|addr| addr.parse())
.transpose()?,
name_service_contract_address: value
.name_service_contract_address
.map(|addr| addr.parse())
.transpose()?,
}) })
} }
} }
@@ -1,144 +0,0 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::collect_paged;
use crate::nyxd::contract_traits::NymContractsProvider;
use crate::nyxd::{error::NyxdError, CosmWasmClient};
use async_trait::async_trait;
use cosmrs::AccountId;
use nym_contracts_common::{signing::Nonce, ContractBuildInformation};
use nym_name_service_common::{
msg::QueryMsg as NameQueryMsg,
response::{ConfigResponse, NamesListResponse, PagedNamesListResponse},
Address, NameId, NymName, RegisteredName,
};
use serde::Deserialize;
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
pub trait NameServiceQueryClient {
async fn query_name_service_contract<T>(&self, query: NameQueryMsg) -> Result<T, NyxdError>
where
for<'a> T: Deserialize<'a>;
async fn get_name_service_config(&self) -> Result<ConfigResponse, NyxdError> {
self.query_name_service_contract(NameQueryMsg::Config {})
.await
}
async fn get_name_entry(&self, name_id: NameId) -> Result<RegisteredName, NyxdError> {
self.query_name_service_contract(NameQueryMsg::NameId { name_id })
.await
}
async fn get_names_paged(
&self,
start_after: Option<NameId>,
limit: Option<u32>,
) -> Result<PagedNamesListResponse, NyxdError> {
self.query_name_service_contract(NameQueryMsg::All { limit, start_after })
.await
}
async fn get_name_signing_nonce(&self, address: &AccountId) -> Result<Nonce, NyxdError> {
self.query_name_service_contract(NameQueryMsg::SigningNonce {
address: address.to_string(),
})
.await
}
async fn get_names_by_owner(&self, owner: AccountId) -> Result<NamesListResponse, NyxdError> {
self.query_name_service_contract(NameQueryMsg::ByOwner {
owner: owner.to_string(),
})
.await
}
async fn get_names_by_nym_name(&self, name: NymName) -> Result<NamesListResponse, NyxdError> {
self.query_name_service_contract(NameQueryMsg::ByName { name })
.await
}
async fn get_names_by_address(&self, address: Address) -> Result<NamesListResponse, NyxdError> {
self.query_name_service_contract(NameQueryMsg::ByAddress { address })
.await
}
async fn get_name_service_contract_version(
&self,
) -> Result<ContractBuildInformation, NyxdError> {
self.query_name_service_contract(NameQueryMsg::GetContractVersion {})
.await
}
async fn get_name_service_contract_cw2_version(
&self,
) -> Result<cw2::ContractVersion, NyxdError> {
self.query_name_service_contract(NameQueryMsg::GetCW2ContractVersion {})
.await
}
}
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
pub trait PagedNameServiceQueryClient: NameServiceQueryClient {
async fn get_all_names(&self) -> Result<Vec<RegisteredName>, NyxdError> {
collect_paged!(self, get_names_paged, names)
}
}
#[async_trait]
impl<T> PagedNameServiceQueryClient for T where T: NameServiceQueryClient {}
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl<C> NameServiceQueryClient for C
where
C: CosmWasmClient + NymContractsProvider + Send + Sync,
{
async fn query_name_service_contract<T>(&self, query: NameQueryMsg) -> Result<T, NyxdError>
where
for<'a> T: Deserialize<'a>,
{
let name_service_contract_address = &self
.name_service_contract_address()
.ok_or_else(|| NyxdError::unavailable_contract_address("name service contract"))?;
self.query_contract_smart(name_service_contract_address, &query)
.await
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::nyxd::contract_traits::tests::IgnoreValue;
// it's enough that this compiles and clippy is happy about it
#[allow(dead_code)]
fn all_query_variants_are_covered<C: NameServiceQueryClient + Send + Sync>(
client: C,
msg: NameQueryMsg,
) {
match msg {
NameQueryMsg::NameId { name_id } => client.get_name_entry(name_id).ignore(),
NameQueryMsg::ByOwner { owner } => {
client.get_names_by_owner(owner.parse().unwrap()).ignore()
}
NameQueryMsg::ByName { name } => client.get_names_by_nym_name(name).ignore(),
NameQueryMsg::ByAddress { address } => client.get_names_by_address(address).ignore(),
NameQueryMsg::All { limit, start_after } => {
client.get_names_paged(limit, start_after).ignore()
}
NameQueryMsg::SigningNonce { address } => client
.get_name_signing_nonce(&address.parse().unwrap())
.ignore(),
NameQueryMsg::Config {} => client.get_name_service_config().ignore(),
NameQueryMsg::GetContractVersion {} => {
client.get_name_service_contract_version().ignore()
}
NameQueryMsg::GetCW2ContractVersion {} => {
client.get_name_service_contract_cw2_version().ignore()
}
};
}
}
@@ -1,138 +0,0 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use async_trait::async_trait;
use nym_contracts_common::signing::MessageSignature;
use nym_name_service_common::{msg::ExecuteMsg as NameExecuteMsg, NameDetails, NameId, NymName};
use crate::nyxd::contract_traits::NymContractsProvider;
use crate::nyxd::{
coin::Coin, cosmwasm_client::types::ExecuteResult, error::NyxdError, Fee, SigningCosmWasmClient,
};
use crate::signing::signer::OfflineSigner;
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
pub trait NameServiceSigningClient {
async fn execute_name_service_contract(
&self,
fee: Option<Fee>,
msg: NameExecuteMsg,
funds: Vec<Coin>,
) -> Result<ExecuteResult, NyxdError>;
async fn register_name(
&self,
name: NameDetails,
owner_signature: MessageSignature,
deposit: Coin,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
self.execute_name_service_contract(
fee,
NameExecuteMsg::Register {
name,
owner_signature,
},
vec![deposit],
)
.await
}
async fn delete_name_by_id(
&self,
name_id: NameId,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
self.execute_name_service_contract(fee, NameExecuteMsg::DeleteId { name_id }, vec![])
.await
}
async fn delete_service_provider_by_name(
&self,
name: NymName,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
self.execute_name_service_contract(fee, NameExecuteMsg::DeleteName { name }, vec![])
.await
}
async fn update_deposit_required(
&self,
deposit_required: Coin,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
self.execute_name_service_contract(
fee,
NameExecuteMsg::UpdateDepositRequired {
deposit_required: deposit_required.into(),
},
vec![],
)
.await
}
}
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl<C> NameServiceSigningClient for C
where
C: SigningCosmWasmClient + NymContractsProvider + Sync,
NyxdError: From<<Self as OfflineSigner>::Error>,
{
async fn execute_name_service_contract(
&self,
fee: Option<Fee>,
msg: NameExecuteMsg,
funds: Vec<Coin>,
) -> Result<ExecuteResult, NyxdError> {
let name_service_contract_address = &self
.name_service_contract_address()
.ok_or_else(|| NyxdError::unavailable_contract_address("name service contract"))?;
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier())));
let memo = msg.default_memo();
let signer_address = &self.signer_addresses()?[0];
self.execute(
signer_address,
name_service_contract_address,
&msg,
fee,
memo,
funds,
)
.await
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::nyxd::contract_traits::tests::{mock_coin, IgnoreValue};
// it's enough that this compiles and clippy is happy about it
#[allow(dead_code)]
fn all_execute_variants_are_covered<C: NameServiceSigningClient + Send + Sync>(
client: C,
msg: NameExecuteMsg,
) {
match msg {
NameExecuteMsg::Register {
name,
owner_signature,
} => client
.register_name(name, owner_signature, mock_coin(), None)
.ignore(),
NameExecuteMsg::DeleteId { name_id } => {
client.delete_name_by_id(name_id, None).ignore()
}
NameExecuteMsg::DeleteName { name } => {
client.delete_service_provider_by_name(name, None).ignore()
}
NameExecuteMsg::UpdateDepositRequired { deposit_required } => client
.update_deposit_required(deposit_required.into(), None)
.ignore(),
};
}
}
@@ -1,142 +0,0 @@
use crate::collect_paged;
use async_trait::async_trait;
use cosmrs::AccountId;
use nym_contracts_common::{signing::Nonce, ContractBuildInformation};
use nym_service_provider_directory_common::{
msg::QueryMsg as SpQueryMsg,
response::{
ConfigResponse, PagedServicesListResponse, ServiceInfoResponse, ServicesListResponse,
},
NymAddress, Service, ServiceId,
};
use serde::Deserialize;
use crate::nyxd::contract_traits::NymContractsProvider;
use crate::nyxd::{error::NyxdError, CosmWasmClient};
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
pub trait SpDirectoryQueryClient {
async fn query_service_provider_contract<T>(&self, query: SpQueryMsg) -> Result<T, NyxdError>
where
for<'a> T: Deserialize<'a>;
async fn get_service_config(&self) -> Result<ConfigResponse, NyxdError> {
self.query_service_provider_contract(SpQueryMsg::Config {})
.await
}
async fn get_service_info(
&self,
service_id: ServiceId,
) -> Result<ServiceInfoResponse, NyxdError> {
self.query_service_provider_contract(SpQueryMsg::ServiceId { service_id })
.await
}
async fn get_services_paged(
&self,
start_after: Option<ServiceId>,
limit: Option<u32>,
) -> Result<PagedServicesListResponse, NyxdError> {
self.query_service_provider_contract(SpQueryMsg::All { limit, start_after })
.await
}
async fn get_services_by_announcer(
&self,
announcer: AccountId,
) -> Result<ServicesListResponse, NyxdError> {
self.query_service_provider_contract(SpQueryMsg::ByAnnouncer {
announcer: announcer.to_string(),
})
.await
}
async fn get_services_by_nym_address(
&self,
nym_address: NymAddress,
) -> Result<ServicesListResponse, NyxdError> {
self.query_service_provider_contract(SpQueryMsg::ByNymAddress { nym_address })
.await
}
async fn get_sp_contract_version(&self) -> Result<ContractBuildInformation, NyxdError> {
self.query_service_provider_contract(SpQueryMsg::GetContractVersion {})
.await
}
async fn get_sp_contract_cw2_version(&self) -> Result<cw2::ContractVersion, NyxdError> {
self.query_service_provider_contract(SpQueryMsg::GetCW2ContractVersion {})
.await
}
async fn get_service_signing_nonce(&self, address: &AccountId) -> Result<Nonce, NyxdError> {
self.query_service_provider_contract(SpQueryMsg::SigningNonce {
address: address.to_string(),
})
.await
}
}
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
pub trait PagedSpDirectoryQueryClient: SpDirectoryQueryClient {
async fn get_all_services(&self) -> Result<Vec<Service>, NyxdError> {
collect_paged!(self, get_services_paged, services)
}
}
#[async_trait]
impl<T> PagedSpDirectoryQueryClient for T where T: SpDirectoryQueryClient {}
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl<C> SpDirectoryQueryClient for C
where
C: CosmWasmClient + NymContractsProvider + Send + Sync,
{
async fn query_service_provider_contract<T>(&self, query: SpQueryMsg) -> Result<T, NyxdError>
where
for<'a> T: Deserialize<'a>,
{
let sp_directory_contract_address =
&self.service_provider_contract_address().ok_or_else(|| {
NyxdError::unavailable_contract_address("service provider directory contract")
})?;
self.query_contract_smart(sp_directory_contract_address, &query)
.await
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::nyxd::contract_traits::tests::IgnoreValue;
// it's enough that this compiles and clippy is happy about it
#[allow(dead_code)]
fn all_query_variants_are_covered<C: SpDirectoryQueryClient + Send + Sync>(
client: C,
msg: SpQueryMsg,
) {
match msg {
SpQueryMsg::ServiceId { service_id } => client.get_service_info(service_id).ignore(),
SpQueryMsg::ByAnnouncer { announcer } => client
.get_services_by_announcer(announcer.parse().unwrap())
.ignore(),
SpQueryMsg::ByNymAddress { nym_address } => {
client.get_services_by_nym_address(nym_address).ignore()
}
SpQueryMsg::All { limit, start_after } => {
client.get_services_paged(start_after, limit).ignore()
}
SpQueryMsg::SigningNonce { address } => client
.get_service_signing_nonce(&address.parse().unwrap())
.ignore(),
SpQueryMsg::Config {} => client.get_service_config().ignore(),
SpQueryMsg::GetContractVersion {} => client.get_sp_contract_version().ignore(),
SpQueryMsg::GetCW2ContractVersion {} => client.get_sp_contract_cw2_version().ignore(),
};
}
}
@@ -1,148 +0,0 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::nyxd::contract_traits::NymContractsProvider;
use crate::nyxd::{
coin::Coin, cosmwasm_client::types::ExecuteResult, error::NyxdError, Fee, SigningCosmWasmClient,
};
use crate::signing::signer::OfflineSigner;
use async_trait::async_trait;
use nym_contracts_common::signing::MessageSignature;
use nym_service_provider_directory_common::{
msg::ExecuteMsg as SpExecuteMsg, NymAddress, ServiceDetails, ServiceId,
};
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
pub trait SpDirectorySigningClient {
async fn execute_service_provider_directory_contract(
&self,
fee: Option<Fee>,
msg: SpExecuteMsg,
funds: Vec<Coin>,
) -> Result<ExecuteResult, NyxdError>;
async fn announce_service_provider(
&self,
service: ServiceDetails,
owner_signature: MessageSignature,
deposit: Coin,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
self.execute_service_provider_directory_contract(
fee,
SpExecuteMsg::Announce {
service,
owner_signature,
},
vec![deposit],
)
.await
}
async fn delete_service_provider_by_id(
&self,
service_id: ServiceId,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
self.execute_service_provider_directory_contract(
fee,
SpExecuteMsg::DeleteId { service_id },
vec![],
)
.await
}
async fn delete_service_provider_by_nym_address(
&self,
nym_address: NymAddress,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
self.execute_service_provider_directory_contract(
fee,
SpExecuteMsg::DeleteNymAddress { nym_address },
vec![],
)
.await
}
async fn update_deposit_required(
&self,
deposit_required: Coin,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
self.execute_service_provider_directory_contract(
fee,
SpExecuteMsg::UpdateDepositRequired {
deposit_required: deposit_required.into(),
},
vec![],
)
.await
}
}
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl<C> SpDirectorySigningClient for C
where
C: SigningCosmWasmClient + NymContractsProvider + Sync,
NyxdError: From<<Self as OfflineSigner>::Error>,
{
async fn execute_service_provider_directory_contract(
&self,
fee: Option<Fee>,
msg: SpExecuteMsg,
funds: Vec<Coin>,
) -> Result<ExecuteResult, NyxdError> {
let sp_directory_contract_address =
&self.service_provider_contract_address().ok_or_else(|| {
NyxdError::unavailable_contract_address("service provider directory contract")
})?;
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier())));
let memo = msg.default_memo();
let signer_address = &self.signer_addresses()?[0];
self.execute(
signer_address,
sp_directory_contract_address,
&msg,
fee,
memo,
funds,
)
.await
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::nyxd::contract_traits::tests::{mock_coin, IgnoreValue};
// it's enough that this compiles and clippy is happy about it
#[allow(dead_code)]
fn all_execute_variants_are_covered<C: SpDirectorySigningClient + Send + Sync>(
client: C,
msg: SpExecuteMsg,
) {
match msg {
SpExecuteMsg::Announce {
service,
owner_signature,
} => client
.announce_service_provider(service, owner_signature, mock_coin(), None)
.ignore(),
SpExecuteMsg::DeleteId { service_id } => client
.delete_service_provider_by_id(service_id, None)
.ignore(),
SpExecuteMsg::DeleteNymAddress { nym_address } => client
.delete_service_provider_by_nym_address(nym_address, None)
.ignore(),
SpExecuteMsg::UpdateDepositRequired { deposit_required } => client
.update_deposit_required(deposit_required.into(), None)
.ignore(),
};
}
}
@@ -140,6 +140,6 @@ mod tests {
let fee = &gas_price * gas_limit; let fee = &gas_price * gas_limit;
// the failing behaviour was result value of 3937 // the failing behaviour was result value of 3937
assert_eq!(fee.amount, 3938u64.into()); assert_eq!(fee.amount, 3938u128);
} }
} }
@@ -70,6 +70,8 @@ use crate::http_client;
use crate::{DirectSigningHttpRpcNyxdClient, QueryHttpRpcNyxdClient}; use crate::{DirectSigningHttpRpcNyxdClient, QueryHttpRpcNyxdClient};
#[cfg(feature = "http-client")] #[cfg(feature = "http-client")]
use cosmrs::rpc::{HttpClient, HttpClientUrl}; use cosmrs::rpc::{HttpClient, HttpClientUrl};
use nym_contracts_common::build_information::CONTRACT_BUILD_INFO_STORAGE_KEY;
use nym_contracts_common::ContractBuildInformation;
pub mod coin; pub mod coin;
pub mod contract_traits; pub mod contract_traits;
@@ -246,12 +248,6 @@ impl<C, S> NyxdClient<C, S> {
self.config.contracts.multisig_contract_address = Some(address); self.config.contracts.multisig_contract_address = Some(address);
} }
pub fn set_service_provider_contract_address(&mut self, address: AccountId) {
self.config
.contracts
.service_provider_directory_contract_address = Some(address);
}
pub fn set_simulated_gas_multiplier(&mut self, multiplier: f32) { pub fn set_simulated_gas_multiplier(&mut self, multiplier: f32) {
self.config.simulated_gas_multiplier = multiplier; self.config.simulated_gas_multiplier = multiplier;
} }
@@ -284,21 +280,6 @@ impl<C, S> NymContractsProvider for NyxdClient<C, S> {
fn multisig_contract_address(&self) -> Option<&AccountId> { fn multisig_contract_address(&self) -> Option<&AccountId> {
self.config.contracts.multisig_contract_address.as_ref() self.config.contracts.multisig_contract_address.as_ref()
} }
fn ephemera_contract_address(&self) -> Option<&AccountId> {
self.config.contracts.ephemera_contract_address.as_ref()
}
fn name_service_contract_address(&self) -> Option<&AccountId> {
self.config.contracts.name_service_contract_address.as_ref()
}
fn service_provider_contract_address(&self) -> Option<&AccountId> {
self.config
.contracts
.service_provider_directory_contract_address
.as_ref()
}
} }
// queries // queries
@@ -349,6 +330,33 @@ where
.await .await
.map(|block| block.block_id.hash) .map(|block| block.block_id.hash)
} }
pub async fn try_get_cw2_contract_version(
&self,
contract_address: &AccountId,
) -> Option<cw2::ContractVersion> {
let raw_info = self
.query_contract_raw(contract_address, b"contract_info".to_vec())
.await
.ok()?;
serde_json::from_slice(&raw_info).ok()
}
pub async fn try_get_contract_build_information(
&self,
contract_address: &AccountId,
) -> Option<ContractBuildInformation> {
let raw_info = self
.query_contract_raw(
contract_address,
CONTRACT_BUILD_INFO_STORAGE_KEY.as_bytes().to_vec(),
)
.await
.ok()?;
serde_json::from_slice(&raw_info).ok()
}
} }
// signing // signing
-2
View File
@@ -46,8 +46,6 @@ nym-vesting-contract-common = { path = "../cosmwasm-smart-contracts/vesting-cont
nym-coconut-bandwidth-contract-common = { path = "../cosmwasm-smart-contracts/coconut-bandwidth-contract" } nym-coconut-bandwidth-contract-common = { path = "../cosmwasm-smart-contracts/coconut-bandwidth-contract" }
nym-coconut-dkg-common = { path = "../cosmwasm-smart-contracts/coconut-dkg" } nym-coconut-dkg-common = { path = "../cosmwasm-smart-contracts/coconut-dkg" }
nym-multisig-contract-common = { path = "../cosmwasm-smart-contracts/multisig-contract" } nym-multisig-contract-common = { path = "../cosmwasm-smart-contracts/multisig-contract" }
nym-service-provider-directory-common = { path = "../cosmwasm-smart-contracts/service-provider-directory" }
nym-name-service-common = { path = "../cosmwasm-smart-contracts/name-service" }
nym-sphinx = { path = "../../common/nymsphinx" } nym-sphinx = { path = "../../common/nymsphinx" }
nym-client-core = { path = "../../common/client-core" } nym-client-core = { path = "../../common/client-core" }
nym-config = { path = "../../common/config" } nym-config = { path = "../../common/config" }
@@ -6,8 +6,6 @@ use clap::{Args, Subcommand};
pub mod gateway; pub mod gateway;
pub mod identity_key; pub mod identity_key;
pub mod mixnode; pub mod mixnode;
pub mod name;
pub mod service;
#[derive(Debug, Args)] #[derive(Debug, Args)]
#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)] #[clap(args_conflicts_with_subcommands = true, subcommand_required = true)]
@@ -23,10 +21,6 @@ pub enum MixnetOperatorsCommands {
Mixnode(mixnode::MixnetOperatorsMixnode), Mixnode(mixnode::MixnetOperatorsMixnode),
/// Manage your gateway /// Manage your gateway
Gateway(gateway::MixnetOperatorsGateway), Gateway(gateway::MixnetOperatorsGateway),
/// Manage your service
ServiceProvider(service::MixnetOperatorsService),
/// Manage your registered name
Name(name::MixnetOperatorsName),
/// Sign messages using your private identity key /// Sign messages using your private identity key
IdentityKey(identity_key::MixnetOperatorsIdentityKey), IdentityKey(identity_key::MixnetOperatorsIdentityKey),
} }
@@ -1,25 +0,0 @@
use clap::Parser;
use log::{error, info};
use nym_name_service_common::NameId;
use nym_validator_client::nyxd::{contract_traits::NameServiceSigningClient, error::NyxdError};
use tap::TapFallible;
use crate::context::SigningClient;
#[derive(Debug, Parser)]
pub struct Args {
#[clap(long)]
pub id: NameId,
}
pub async fn delete(args: Args, client: SigningClient) -> Result<(), NyxdError> {
info!("Deleting registered name alias with id {}", args.id);
let res = client
.delete_name_by_id(args.id, None)
.await
.tap_err(|err| error!("Failed to delete name: {err:#?}"))?;
info!("Deleted: {res:?}");
Ok(())
}
@@ -1,22 +0,0 @@
use clap::{Args, Subcommand};
pub mod delete;
pub mod register;
pub mod register_sign_payload;
#[derive(Debug, Args)]
#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)]
pub struct MixnetOperatorsName {
#[clap(subcommand)]
pub command: MixnetOperatorsNameCommands,
}
#[derive(Debug, Subcommand)]
pub enum MixnetOperatorsNameCommands {
/// Register a name alias for a nym address
Register(register::Args),
/// Delete name alias for a nym address
Delete(delete::Args),
/// Create base58-encoded payload required for producing valiid register signature.
CreateNameRegisterPayload(register_sign_payload::Args),
}
@@ -1,53 +0,0 @@
use clap::Parser;
use log::{error, info};
use nym_contracts_common::signing::MessageSignature;
use nym_name_service_common::{Address, Coin, NameDetails, NymName};
use nym_sphinx::addressing::clients::Recipient;
use nym_validator_client::nyxd::{contract_traits::NameServiceSigningClient, error::NyxdError};
use tap::TapFallible;
use crate::context::SigningClient;
#[derive(Debug, Parser)]
pub struct Args {
/// Name alias
#[clap(long)]
pub name: NymName,
/// Nym address that the alias is pointing to
#[clap(long)]
pub nym_address: Recipient,
#[clap(long)]
pub signature: MessageSignature,
/// Deposit to be made to the service provider directory, in curent DENOMINATION (e.g. 'unym')
#[clap(long)]
pub deposit: u128,
}
pub async fn register(args: Args, client: SigningClient) -> Result<(), NyxdError> {
info!(
"Registering name alias '{}' for nym address '{}'",
args.name, args.nym_address
);
let address = Address::new(&args.nym_address.to_string()).expect("invalid address");
let identity_key = address.client_id().to_string();
let name = NameDetails {
name: args.name,
address,
identity_key,
};
let denom = client.current_chain_details().mix_denom.base.as_str();
let deposit = Coin::new(args.deposit, denom);
let res = client
.register_name(name, args.signature, deposit.into(), None)
.await
.tap_err(|err| error!("Failed to register name: {err:#?}"))?;
info!("Registered name: {res:?}");
Ok(())
}
@@ -1,65 +0,0 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::{
context::SigningClient,
utils::{account_id_to_cw_addr, DataWrapper},
};
use clap::Parser;
use cosmwasm_std::Coin;
use nym_bin_common::output_format::OutputFormat;
use nym_name_service_common::{
signing_types::construct_name_register_sign_payload, Address, NymName,
};
use nym_sphinx::addressing::clients::Recipient;
use nym_validator_client::nyxd::{contract_traits::NameServiceQueryClient, error::NyxdError};
#[derive(Debug, Parser)]
pub struct Args {
// The name to register.
#[arg(long)]
pub name: NymName,
/// The nym address the name should point to.
#[arg(long)]
pub nym_address: Recipient,
#[arg(long)]
pub amount: u128,
#[arg(short, long, default_value_t = OutputFormat::default())]
output: OutputFormat,
}
pub async fn create_payload(args: Args, client: SigningClient) -> Result<(), NyxdError> {
let address = Address::new(&args.nym_address.to_string()).expect("invalid address");
let identity_key = address.client_id().to_string();
let name = nym_name_service_common::NameDetails {
name: args.name,
address,
identity_key,
};
let denom = client.current_chain_details().mix_denom.base.as_str();
let deposit = Coin::new(args.amount, denom);
let nonce = match client.get_name_signing_nonce(&client.address()).await {
Ok(nonce) => nonce,
Err(err) => {
eprint!(
"failed to query for the signing nonce of {}: {err}",
client.address()
);
return Err(err);
}
};
let address = account_id_to_cw_addr(&client.address());
let payload = construct_name_register_sign_payload(nonce, address, deposit, name);
let wrapper = DataWrapper::new(payload.to_base58_string().unwrap());
println!("{}", args.output.format(&wrapper));
Ok(())
}
@@ -1,45 +0,0 @@
use clap::Parser;
use log::info;
use nym_contracts_common::signing::MessageSignature;
use nym_service_provider_directory_common::{Coin, NymAddress, ServiceDetails, ServiceType};
use nym_validator_client::nyxd::contract_traits::SpDirectorySigningClient;
use crate::context::SigningClient;
#[derive(Debug, Parser)]
pub struct Args {
#[clap(long)]
pub nym_address: String,
#[clap(long)]
pub signature: MessageSignature,
/// Deposit to be made to the service provider directory, in curent DENOMINATION (e.g. 'unym')
#[clap(long)]
pub deposit: u128,
#[clap(long)]
pub identity_key: String,
}
pub async fn announce(args: Args, client: SigningClient) {
info!("Annoucing service provider");
let nym_address = NymAddress::Address(args.nym_address);
let service_type = ServiceType::NetworkRequester;
let service = ServiceDetails {
nym_address,
service_type,
identity_key: args.identity_key,
};
let denom = client.current_chain_details().mix_denom.base.as_str();
let deposit = Coin::new(args.deposit, denom);
let res = client
.announce_service_provider(service, args.signature, deposit.into(), None)
.await
.expect("Failed to announce service provider");
info!("Announced service provider: {res:?}");
}
@@ -1,61 +0,0 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::{
context::SigningClient,
utils::{account_id_to_cw_addr, DataWrapper},
};
use clap::Parser;
use cosmwasm_std::Coin;
use nym_bin_common::output_format::OutputFormat;
use nym_service_provider_directory_common::{
signing_types::construct_service_provider_announce_sign_payload, NymAddress,
ServiceType::NetworkRequester,
};
use nym_sphinx::addressing::clients::Recipient;
use nym_validator_client::nyxd::contract_traits::SpDirectoryQueryClient;
#[derive(Debug, Parser)]
pub struct Args {
#[clap(long)]
pub nym_address: Recipient,
#[clap(long)]
pub amount: u128,
#[clap(long)]
pub identity_key: String,
#[clap(short, long, default_value_t = OutputFormat::default())]
output: OutputFormat,
}
pub async fn create_payload(args: Args, client: SigningClient) {
let service = nym_service_provider_directory_common::ServiceDetails {
nym_address: NymAddress::new(&args.nym_address.to_string()),
service_type: NetworkRequester,
identity_key: args.identity_key,
};
let denom = client.current_chain_details().mix_denom.base.as_str();
let deposit = Coin::new(args.amount, denom);
let nonce = match client.get_service_signing_nonce(&client.address()).await {
Ok(nonce) => nonce,
Err(err) => {
eprint!(
"failed to query for the signing nonce of {}: {err}",
client.address()
);
return;
}
};
let address = account_id_to_cw_addr(&client.address());
let payload =
construct_service_provider_announce_sign_payload(nonce, address, deposit, service);
let wrapper = DataWrapper::new(payload.to_base58_string().unwrap());
println!("{}", args.output.format(&wrapper))
}
@@ -1,23 +0,0 @@
use clap::Parser;
use log::info;
use nym_service_provider_directory_common::ServiceId;
use nym_validator_client::nyxd::contract_traits::SpDirectorySigningClient;
use crate::context::SigningClient;
#[derive(Debug, Parser)]
pub struct Args {
#[clap(long)]
pub id: ServiceId,
}
pub async fn delete(args: Args, client: SigningClient) {
info!("Deleting service provider with id {}", args.id);
let res = client
.delete_service_provider_by_id(args.id, None)
.await
.expect("Failed to delete service provider");
info!("Deleted: {res:?}");
}
@@ -1,23 +0,0 @@
use clap::{Args, Subcommand};
pub mod announce;
pub mod announce_sign_payload;
pub mod delete;
#[derive(Debug, Args)]
#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)]
pub struct MixnetOperatorsService {
#[clap(subcommand)]
pub command: MixnetOperatorsServiceCommands,
}
#[allow(clippy::large_enum_variant)]
#[derive(Debug, Subcommand)]
pub enum MixnetOperatorsServiceCommands {
/// Announce service provider to the world
Announce(announce::Args),
/// Delete entry for service provider from the directory
Delete(delete::Args),
/// Create base58-encoded payload required for producing valid announce signature.
CreateServiceAnnounceSignPayload(announce_sign_payload::Args),
}
@@ -5,8 +5,6 @@ use clap::{Args, Subcommand};
pub mod query_all_gateways; pub mod query_all_gateways;
pub mod query_all_mixnodes; pub mod query_all_mixnodes;
pub mod query_all_names;
pub mod query_all_service_providers;
#[derive(Debug, Args)] #[derive(Debug, Args)]
#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)] #[clap(args_conflicts_with_subcommands = true, subcommand_required = true)]
@@ -21,8 +19,4 @@ pub enum MixnetQueryCommands {
Mixnodes(query_all_mixnodes::Args), Mixnodes(query_all_mixnodes::Args),
/// Query gateways /// Query gateways
Gateways(query_all_gateways::Args), Gateways(query_all_gateways::Args),
/// Query announced service-providers
ServiceProviders(query_all_service_providers::Args),
/// Query registed names
Names(query_all_names::Args),
} }
@@ -1,53 +0,0 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::context::QueryClientWithNyxd;
use crate::utils::show_error;
use clap::Parser;
use comfy_table::Table;
use nym_validator_client::client::NymApiClientExt;
use nym_validator_client::nym_api::error::NymAPIError;
#[derive(Debug, Parser)]
pub struct Args {
#[clap(value_parser)]
#[clap(help = "Optionally, the registered name to display")]
pub name: Option<String>,
}
pub async fn query(args: Args, client: &QueryClientWithNyxd) {
log::trace!("Querying all registered names");
match client.nym_api.get_registered_names().await {
Ok(res) => {
if let Some(name) = args.name {
let name = res.names.iter().find(|name_entry| {
name_entry.name.name.to_string().eq_ignore_ascii_case(&name)
});
println!(
"{}",
::serde_json::to_string_pretty(&name).expect("json formatting error")
);
} else {
let mut table = Table::new();
table.set_header(vec!["Name Id", "Owner", "Nym Address", "Name"]);
for name_entry in res.names {
table.add_row(vec![
name_entry.id.to_string(),
name_entry.owner.to_string(),
name_entry.name.address.to_string(),
name_entry.name.name.to_string(),
]);
}
println!("The registered names in the directory are:");
println!("{table}");
}
}
Err(NymAPIError::NotFound) => {
println!("nym-api reports no name endpoint available");
}
Err(e) => show_error(e),
}
}
@@ -1,55 +0,0 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::context::QueryClientWithNyxd;
use crate::utils::show_error;
use clap::Parser;
use comfy_table::Table;
use nym_validator_client::client::NymApiClientExt;
use nym_validator_client::nym_api::error::NymAPIError;
#[derive(Debug, Parser)]
pub struct Args {
#[clap(value_parser)]
#[clap(help = "Optionally, the service provider to display")]
pub nym_address: Option<String>,
}
pub async fn query(args: Args, client: &QueryClientWithNyxd) {
match client.nym_api.get_service_providers().await {
Ok(res) => {
if let Some(nym_address) = args.nym_address {
let service = res.services.iter().find(|service| {
service
.service
.nym_address
.to_string()
.eq_ignore_ascii_case(&nym_address)
});
println!(
"{}",
::serde_json::to_string_pretty(&service).expect("json formatting error")
);
} else {
let mut table = Table::new();
table.set_header(vec!["Service Id", "Announcer", "Type", "Nym Address"]);
for service in res.services {
table.add_row(vec![
service.service_id.to_string(),
service.announcer.to_string(),
service.service.service_type.to_string(),
service.service.nym_address.to_string(),
]);
}
println!("The service providers in the directory are:");
println!("{table}");
}
}
Err(NymAPIError::NotFound) => {
println!("nym-api reports no service provider endpoint available");
}
Err(e) => show_error(e),
}
}
@@ -11,9 +11,13 @@ repository = { workspace = true }
bs58 = { workspace = true } bs58 = { workspace = true }
cosmwasm-std = { workspace = true } cosmwasm-std = { workspace = true }
cosmwasm-schema = { workspace = true } cosmwasm-schema = { workspace = true }
cw-storage-plus = { workspace = true }
schemars = { workspace = true } schemars = { workspace = true }
serde = { workspace = true, features = ["derive"] } serde = { workspace = true, features = ["derive"] }
thiserror = { workspace = true } thiserror = { workspace = true }
[dev-dependencies] [dev-dependencies]
serde_json = { workspace = true } serde_json = { workspace = true }
[build-dependencies]
vergen = { version = "=8.3.1", features = ["build", "git", "gitcl", "rustc", "cargo"] }
@@ -0,0 +1,17 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use vergen::EmitBuilder;
fn main() {
EmitBuilder::builder()
.all_build()
.rustc_semver()
.git_branch()
.git_commit_timestamp()
.git_sha(false)
.cargo_debug()
.cargo_opt_level()
.emit()
.expect("failed to extract build metadata");
}
@@ -0,0 +1,85 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::ContractBuildInformation;
use cosmwasm_std::{StdResult, Storage};
use cw_storage_plus::Item;
pub const CONTRACT_BUILD_INFO_STORAGE_KEY: &str = "contract_build_info";
pub const CONTRACT_BUILD_INFO: Item<ContractBuildInformation> =
Item::new(CONTRACT_BUILD_INFO_STORAGE_KEY);
// important note. this MUST BE called inside the contract code itself and not any intermediate crate
// otherwise macro expansions will resolve to incorrect data
#[macro_export]
macro_rules! get_build_information {
() => {
$crate::types::ContractBuildInformation::new(
env!("CARGO_PKG_NAME"),
env!("CARGO_PKG_VERSION"),
)
};
}
pub fn set_state_build_information(
store: &mut dyn Storage,
build_info: ContractBuildInformation,
) -> StdResult<()> {
CONTRACT_BUILD_INFO.save(store, &build_info)
}
pub fn get_contract_build_information(store: &dyn Storage) -> StdResult<ContractBuildInformation> {
CONTRACT_BUILD_INFO.load(store)
}
#[macro_export]
macro_rules! set_build_information {
( $store:expr ) => {
$crate::build_information::set_state_build_information(
$store,
$crate::get_build_information!(),
)
};
}
#[cfg(test)]
mod tests {
use super::*;
use cosmwasm_std::testing::MockStorage;
#[test]
fn get_and_set_work() {
let mut store = MockStorage::new();
// error if not set
assert!(get_contract_build_information(&store).is_err());
// set and get
let contract_name = "nym-mixnet-contract";
let contract_version = "1.2.3";
let build_info = ContractBuildInformation::new(contract_name, contract_version);
set_state_build_information(&mut store, build_info).unwrap();
let loaded = get_contract_build_information(&store).unwrap();
let expected = ContractBuildInformation {
contract_name: contract_name.into(),
build_version: contract_version.into(),
build_timestamp: env!("VERGEN_BUILD_TIMESTAMP").to_string(),
commit_sha: option_env!("VERGEN_GIT_SHA")
.unwrap_or("UNKNOWN")
.to_string(),
commit_timestamp: option_env!("VERGEN_GIT_COMMIT_TIMESTAMP")
.unwrap_or("UNKNOWN")
.to_string(),
commit_branch: option_env!("VERGEN_GIT_BRANCH")
.unwrap_or("UNKNOWN")
.to_string(),
rustc_version: env!("VERGEN_RUSTC_SEMVER").to_string(),
cargo_debug: env!("VERGEN_CARGO_DEBUG").to_string(),
cargo_opt_level: env!("VERGEN_CARGO_OPT_LEVEL").to_string(),
};
assert_eq!(expected, loaded);
}
}
@@ -4,6 +4,7 @@
#![warn(clippy::expect_used)] #![warn(clippy::expect_used)]
#![warn(clippy::unwrap_used)] #![warn(clippy::unwrap_used)]
pub mod build_information;
pub mod dealings; pub mod dealings;
pub mod events; pub mod events;
pub mod signing; pub mod signing;
@@ -132,10 +132,18 @@ where
} }
} }
fn default_unknown() -> String {
"unknown".to_string()
}
// TODO: there's no reason this couldn't be used for proper binaries, but in that case // TODO: there's no reason this couldn't be used for proper binaries, but in that case
// perhaps the struct should get renamed and moved to a "more" common crate // perhaps the struct should get renamed and moved to a "more" common crate
#[cw_serde] #[cw_serde]
pub struct ContractBuildInformation { pub struct ContractBuildInformation {
/// Provides the name of the binary, i.e. the content of `CARGO_PKG_NAME` environmental variable.
#[serde(default = "default_unknown")]
pub contract_name: String,
// VERGEN_BUILD_TIMESTAMP // VERGEN_BUILD_TIMESTAMP
/// Provides the build timestamp, for example `2021-02-23T20:14:46.558472672+00:00`. /// Provides the build timestamp, for example `2021-02-23T20:14:46.558472672+00:00`.
pub build_timestamp: String, pub build_timestamp: String,
@@ -159,6 +167,38 @@ pub struct ContractBuildInformation {
// VERGEN_RUSTC_SEMVER // VERGEN_RUSTC_SEMVER
/// Provides the rustc version that was used for the build, for example `1.52.0-nightly`. /// Provides the rustc version that was used for the build, for example `1.52.0-nightly`.
pub rustc_version: String, pub rustc_version: String,
// VERGEN_CARGO_DEBUG
/// Provides the cargo debug mode that was used for the build.
#[serde(default = "default_unknown")]
pub cargo_debug: String,
// VERGEN_CARGO_OPT_LEVEL
/// Provides the opt value set by cargo during the build
#[serde(default = "default_unknown")]
pub cargo_opt_level: String,
}
impl ContractBuildInformation {
pub fn new(name: impl Into<String>, version: impl Into<String>) -> Self {
ContractBuildInformation {
contract_name: name.into(),
build_version: version.into(),
build_timestamp: env!("VERGEN_BUILD_TIMESTAMP").to_string(),
commit_sha: option_env!("VERGEN_GIT_SHA")
.unwrap_or("UNKNOWN")
.to_string(),
commit_timestamp: option_env!("VERGEN_GIT_COMMIT_TIMESTAMP")
.unwrap_or("UNKNOWN")
.to_string(),
commit_branch: option_env!("VERGEN_GIT_BRANCH")
.unwrap_or("UNKNOWN")
.to_string(),
rustc_version: env!("VERGEN_RUSTC_SEMVER").to_string(),
cargo_debug: env!("VERGEN_CARGO_DEBUG").to_string(),
cargo_opt_level: env!("VERGEN_CARGO_OPT_LEVEL").to_string(),
}
}
} }
#[cfg(test)] #[cfg(test)]
@@ -1,17 +0,0 @@
[package]
name = "nym-ephemera-common"
version = "0.1.0"
edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
cosmwasm-schema = { workspace = true }
cosmwasm-std = { workspace = true }
cw-utils = { workspace = true }
contracts-common = { path = "../contracts-common", package = "nym-contracts-common" }
[features]
schema = []
@@ -1,3 +0,0 @@
pub mod msg;
pub mod peers;
pub mod types;
@@ -1,33 +0,0 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
#[cfg(feature = "schema")]
use crate::peers::PagedPeerResponse;
use crate::types::JsonPeerInfo;
use cosmwasm_schema::cw_serde;
#[cfg(feature = "schema")]
use cosmwasm_schema::QueryResponses;
#[cw_serde]
pub struct InstantiateMsg {
pub group_addr: String,
pub mix_denom: String,
}
#[cw_serde]
pub enum ExecuteMsg {
RegisterPeer { peer_info: JsonPeerInfo },
}
#[cw_serde]
#[cfg_attr(feature = "schema", derive(QueryResponses))]
pub enum QueryMsg {
#[cfg_attr(feature = "schema", returns(PagedPeerResponse))]
GetPeers {
limit: Option<u32>,
start_after: Option<String>,
},
}
#[cw_serde]
pub struct MigrateMsg {}
@@ -1,25 +0,0 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::types::JsonPeerInfo;
use cosmwasm_schema::cw_serde;
use cosmwasm_std::Addr;
#[cw_serde]
pub struct PagedPeerResponse {
pub peers: Vec<JsonPeerInfo>,
pub per_page: usize,
/// Field indicating paging information for the following queries if the caller wishes to get further entries.
pub start_next_after: Option<Addr>,
}
impl PagedPeerResponse {
pub fn new(peers: Vec<JsonPeerInfo>, per_page: usize, start_next_after: Option<Addr>) -> Self {
PagedPeerResponse {
peers,
per_page,
start_next_after,
}
}
}
@@ -1,29 +0,0 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use cosmwasm_schema::cw_serde;
use cosmwasm_std::Addr;
#[cw_serde]
pub struct JsonPeerInfo {
/// The cosmos address of the peer, used in interacting with the chain.
pub cosmos_address: Addr,
/// The TCP/IP address of the peer.
/// Expected formats:
/// 1. `<IP>:<PORT>`
/// 2. `/ip4/<IP>/tcp/<PORT>` - this is the format used by libp2p multiaddr
pub ip_address: String,
///Serialized public key.
pub public_key: String,
}
impl JsonPeerInfo {
#[must_use]
pub fn new(cosmos_address: Addr, ip_address: String, public_key: String) -> Self {
Self {
cosmos_address,
ip_address,
public_key,
}
}
}
@@ -234,12 +234,6 @@ pub enum MixnetContractError {
#[error("the epoch is currently not in the 'epoch advancement' state. (the state is {current_state})")] #[error("the epoch is currently not in the 'epoch advancement' state. (the state is {current_state})")]
EpochNotInAdvancementState { current_state: EpochState }, EpochNotInAdvancementState { current_state: EpochState },
#[error("failed to parse {value} into a valid SemVer version: {error_message}")]
SemVerFailure {
value: String,
error_message: String,
},
#[error("failed to verify message signature: {source}")] #[error("failed to verify message signature: {source}")]
SignatureVerificationFailure { SignatureVerificationFailure {
#[from] #[from]
@@ -1,20 +0,0 @@
[package]
name = "nym-name-service-common"
version = "0.1.0"
edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
cosmwasm-schema = { workspace = true }
cosmwasm-std = { workspace = true }
cw2 = { workspace = true, optional = true }
cw-controllers = { workspace = true }
cw-utils = { workspace = true }
nym-contracts-common = { path = "../contracts-common", version = "0.5.0" }
serde = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }
[features]
schema = ["cw2"]
@@ -1,83 +0,0 @@
use cosmwasm_std::{Addr, StdError};
use cw_controllers::AdminError;
use nym_contracts_common::signing::verifier::ApiVerifierError;
use thiserror::Error;
use crate::{Address, NameId, NymName};
#[derive(Error, Debug, PartialEq)]
pub enum NameServiceError {
#[error("{0}")]
Std(#[from] StdError),
#[error("{0}")]
AdminError(#[from] AdminError),
#[error("name id entry not found: {name_id}")]
NotFound { name_id: NameId },
#[error("name entry not found: {name}")]
NameNotFound { name: NymName },
#[error("{sender} is not registrator of name")]
Unauthorized { sender: Addr },
#[error("deposit required to register a name")]
DepositRequired { source: cw_utils::PaymentError },
#[error("insufficiant deposit: {funds}, required: {deposit_required}")]
InsufficientDeposit {
funds: cosmwasm_std::Uint128,
deposit_required: cosmwasm_std::Uint128,
},
#[error("deposit too large: {funds}, required: {deposit_required}")]
TooLargeDeposit {
funds: cosmwasm_std::Uint128,
deposit_required: cosmwasm_std::Uint128,
},
#[error("reached the max number of names ({max_names}) for owner {owner}")]
ReachedMaxNamesForOwner { max_names: u32, owner: Addr },
#[error("reached the max number of names ({max_names}) for address {0}", address.to_string())]
ReachedMaxNamesForAddress { max_names: u32, address: Address },
#[error("failed to parse {value} into a valid SemVer version: {error_message}")]
SemVerFailure {
value: String,
error_message: String,
},
#[error("failed to recover ed25519 public key from its base58 representation: {0}")]
MalformedEd25519IdentityKey(String),
#[error("failed to recover ed25519 signature from its base58 representation: {0}")]
MalformedEd25519Signature(String),
#[error("provided ed25519 signature did not verify correctly")]
InvalidEd25519Signature,
#[error("failed to verify message signature: {source}")]
SignatureVerificationFailure {
#[from]
source: ApiVerifierError,
},
#[error("duplicate entries detected for name: {name}")]
DuplicateNames { name: NymName },
#[error("name already registered: {name}")]
NameAlreadyRegistered { name: NymName },
#[error("invalid nym address format: {0}")]
InvalidNymAddress(String),
#[error("client identity in nym address does not match the provided identity key")]
IdentityKeyMismatch {
address: Address,
identity_key: String,
},
}
pub type Result<T, E = NameServiceError> = std::result::Result<T, E>;
@@ -1,66 +0,0 @@
use cosmwasm_std::{Coin, Event};
use crate::RegisteredName;
pub enum NameEventType {
Register,
DeleteId,
DeleteName,
UpdateDepositRequired,
}
impl std::fmt::Display for NameEventType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
NameEventType::Register => write!(f, "register"),
NameEventType::DeleteId => write!(f, "delete_id"),
NameEventType::DeleteName => write!(f, "delete_name"),
NameEventType::UpdateDepositRequired => write!(f, "update_deposit_required"),
}
}
}
impl From<NameEventType> for String {
fn from(event_type: NameEventType) -> Self {
event_type.to_string()
}
}
pub const ACTION: &str = "action";
pub const NAME_ID: &str = "name_id";
pub const NAME: &str = "name";
pub const OWNER: &str = "owner";
pub const DEPOSIT_REQUIRED: &str = "deposit_required";
pub fn new_register_event(name: RegisteredName) -> Event {
Event::new(NameEventType::Register)
.add_attribute(ACTION, NameEventType::Register)
.add_attribute(NAME_ID, name.id.to_string())
.add_attribute(NAME, name.name.name.to_string())
.add_attribute(name.name.address.event_tag(), name.name.address.to_string())
.add_attribute(OWNER, name.owner.to_string())
}
pub fn new_delete_id_event(name: RegisteredName) -> Event {
Event::new(NameEventType::DeleteId)
.add_attribute(ACTION, NameEventType::DeleteId)
.add_attribute(NAME_ID, name.id.to_string())
.add_attribute(NAME, name.name.name.to_string())
.add_attribute(name.name.address.event_tag(), name.name.address.to_string())
}
pub fn new_delete_name_event(name: RegisteredName) -> Event {
Event::new(NameEventType::DeleteId)
.add_attribute(ACTION, NameEventType::DeleteName)
.add_attribute(NAME_ID, name.id.to_string())
.add_attribute(NAME, name.name.name.to_string())
.add_attribute(name.name.address.event_tag(), name.name.address.to_string())
}
pub fn new_update_deposit_required_event(deposit_required: Coin) -> Event {
Event::new(NameEventType::UpdateDepositRequired)
.add_attribute(ACTION, NameEventType::UpdateDepositRequired)
.add_attribute(DEPOSIT_REQUIRED, deposit_required.to_string())
}
@@ -1,11 +0,0 @@
pub mod error;
pub mod events;
pub mod msg;
pub mod response;
pub mod signing_types;
pub mod types;
// Re-export all types at the top-level
pub use types::*;
pub use cosmwasm_std::{Addr, Coin, Decimal, Fraction};
@@ -1,123 +0,0 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::{Address, NameDetails, NameId, NymName};
use cosmwasm_schema::cw_serde;
use cosmwasm_std::Coin;
use nym_contracts_common::signing::MessageSignature;
#[cfg(feature = "schema")]
use crate::{
response::{ConfigResponse, NamesListResponse, PagedNamesListResponse},
types::RegisteredName,
};
#[cfg(feature = "schema")]
use cosmwasm_schema::QueryResponses;
#[cfg(feature = "schema")]
use nym_contracts_common::{signing::Nonce, ContractBuildInformation};
#[cw_serde]
pub struct InstantiateMsg {
pub deposit_required: Coin,
}
impl InstantiateMsg {
pub fn new(deposit_required: Coin) -> Self {
Self { deposit_required }
}
}
#[cw_serde]
pub struct MigrateMsg {}
#[cw_serde]
pub enum ExecuteMsg {
/// Announcing a name pointing to a nym-address
Register {
name: NameDetails,
owner_signature: MessageSignature,
},
/// Delete a name entry by id
DeleteId { name_id: NameId },
/// Delete a name entry by name
DeleteName { name: NymName },
/// Change the deposit required for announcing a name
UpdateDepositRequired { deposit_required: Coin },
}
impl ExecuteMsg {
pub fn delete_id(name_id: NameId) -> Self {
ExecuteMsg::DeleteId { name_id }
}
pub fn default_memo(&self) -> String {
match self {
ExecuteMsg::Register {
name,
owner_signature: _,
} => {
format!("registering {} as name: {}", name.address, name.name)
}
ExecuteMsg::DeleteId { name_id } => {
format!("deleting name with id {name_id}")
}
ExecuteMsg::DeleteName { name } => {
format!("deleting name: {name}")
}
ExecuteMsg::UpdateDepositRequired { deposit_required } => {
format!("updating the deposit required to {deposit_required}")
}
}
}
}
#[cw_serde]
#[cfg_attr(feature = "schema", derive(QueryResponses))]
pub enum QueryMsg {
/// Query the name by it's assigned id
#[cfg_attr(feature = "schema", returns(RegisteredName))]
NameId { name_id: NameId },
/// Query the names by the registrator
#[cfg_attr(feature = "schema", returns(NamesListResponse))]
ByOwner { owner: String },
#[cfg_attr(feature = "schema", returns(RegisteredName))]
ByName { name: NymName },
#[cfg_attr(feature = "schema", returns(NamesListResponse))]
ByAddress { address: Address },
#[cfg_attr(feature = "schema", returns(PagedNamesListResponse))]
All {
limit: Option<u32>,
start_after: Option<NameId>,
},
#[cfg_attr(feature = "schema", returns(Nonce))]
SigningNonce { address: String },
#[cfg_attr(feature = "schema", returns(ConfigResponse))]
Config {},
/// Gets build information of this contract, such as the commit hash used for the build or rustc version.
#[cfg_attr(feature = "schema", returns(ContractBuildInformation))]
GetContractVersion {},
/// Gets the stored contract version information that's required by the CW2 spec interface for migrations.
#[serde(rename = "get_cw2_contract_version")]
#[cfg_attr(feature = "schema", returns(cw2::ContractVersion))]
GetCW2ContractVersion {},
}
impl QueryMsg {
pub fn all() -> QueryMsg {
QueryMsg::All {
limit: None,
start_after: None,
}
}
}
@@ -1,53 +0,0 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::{NameId, RegisteredName};
use cosmwasm_schema::cw_serde;
use cosmwasm_std::Coin;
#[cw_serde]
pub struct NamesListResponse {
pub names: Vec<RegisteredName>,
}
impl NamesListResponse {
pub fn new(names: Vec<RegisteredName>) -> NamesListResponse {
NamesListResponse { names }
}
}
impl From<&[RegisteredName]> for NamesListResponse {
fn from(names: &[RegisteredName]) -> Self {
NamesListResponse {
names: names.to_vec(),
}
}
}
#[cw_serde]
pub struct PagedNamesListResponse {
pub names: Vec<RegisteredName>,
pub per_page: usize,
/// Field indicating paging information for the following queries if the caller wishes to get further entries.
pub start_next_after: Option<NameId>,
}
impl PagedNamesListResponse {
pub fn new(
names: Vec<RegisteredName>,
per_page: usize,
start_next_after: Option<NameId>,
) -> PagedNamesListResponse {
PagedNamesListResponse {
names,
per_page,
start_next_after,
}
}
}
#[cw_serde]
pub struct ConfigResponse {
pub deposit_required: Coin,
}
@@ -1,32 +0,0 @@
use cosmwasm_std::{Addr, Coin};
use nym_contracts_common::signing::{
ContractMessageContent, MessageType, Nonce, SignableMessage, SigningPurpose,
};
use serde::Serialize;
use crate::NameDetails;
pub type SignableNameRegisterMsg = SignableMessage<ContractMessageContent<NameRegister>>;
#[derive(Serialize)]
pub struct NameRegister {
name: NameDetails,
}
impl SigningPurpose for NameRegister {
fn message_type() -> MessageType {
MessageType::new("name-register")
}
}
pub fn construct_name_register_sign_payload(
nonce: Nonce,
sender: Addr,
deposit: Coin,
name: NameDetails,
) -> SignableNameRegisterMsg {
let payload = NameRegister { name };
let proxy = None;
let content = ContractMessageContent::new(sender, proxy, vec![deposit], payload);
SignableMessage::new(nonce, content)
}
@@ -1,252 +0,0 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use cosmwasm_schema::cw_serde;
use cosmwasm_std::{Addr, Coin};
use nym_contracts_common::IdentityKey;
use std::{
fmt::{Display, Formatter},
str::FromStr,
};
use thiserror::Error;
use crate::error::{NameServiceError, Result};
/// The directory of names are indexed by [`NameId`].
pub type NameId = u32;
#[cw_serde]
pub struct RegisteredName {
/// Unique id assigned to the registerd name.
pub id: NameId,
/// The registerd name details.
pub name: NameDetails,
/// name owner.
pub owner: Addr,
/// Block height at which the name was added.
pub block_height: u64,
/// The deposit used to announce the name.
pub deposit: Coin,
}
impl RegisteredName {
// Shortcut for getting the actual name
pub fn entry(&self) -> &NymName {
&self.name.name
}
}
#[cw_serde]
pub struct NameDetails {
/// The name pointing to the nym address
pub name: NymName,
/// The address of the name alias.
pub address: Address,
/// The identity key of the registered name.
pub identity_key: IdentityKey,
}
/// String representation of a nym address, which is of the form
/// client_id.client_enc@gateway_id.
/// NOTE: entirely unvalidated.
#[cw_serde]
pub enum Address {
NymAddress(NymAddressInner),
// Possible extension:
//Gateway(String)
}
#[cw_serde]
pub struct NymAddressInner {
client_id: String,
client_enc: String,
gateway_id: String,
}
// ADDRESS . ENCRYPTION @ GATEWAY_ID
impl std::fmt::Display for NymAddressInner {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}.{}@{}",
self.client_id, self.client_enc, self.gateway_id
)
}
}
impl Address {
/// Create a new nym address.
pub fn new(address: &str) -> Result<Self> {
parse_nym_address(address)
.map(Self::NymAddress)
.ok_or_else(|| NameServiceError::InvalidNymAddress(address.to_string()))
}
pub fn client_id(&self) -> &str {
match self {
Address::NymAddress(address) => &address.client_id,
}
}
pub fn client_enc(&self) -> &str {
match self {
Address::NymAddress(address) => &address.client_enc,
}
}
pub fn gateway_id(&self) -> &str {
match self {
Address::NymAddress(address) => &address.gateway_id,
}
}
pub fn event_tag(&self) -> &str {
match self {
Address::NymAddress(_) => "nym_address",
//Address::Gateway(_) => "gatway_address",
}
}
}
impl Display for Address {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Address::NymAddress(address) => write!(f, "{}", address),
}
}
}
// A valid nym address is of the form client_id.client_enc@gateway_id
fn parse_nym_address(address: &str) -> Option<NymAddressInner> {
let parts: Vec<&str> = address.split('@').collect();
if parts.len() != 2 {
return None;
}
let client_part = parts[0];
let gateway_part = parts[1];
// The client part consists of two parts separated by a dot
let client_parts: Vec<&str> = client_part.split('.').collect();
if client_parts.len() != 2 {
return None;
}
// Check that the gateway part does not contain any dots
if gateway_part.contains('.') {
return None;
}
Some(NymAddressInner {
client_id: client_parts[0].to_string(),
client_enc: client_parts[1].to_string(),
gateway_id: gateway_part.to_string(),
})
}
/// Name stored and pointing a to a nym-address
#[cw_serde]
pub struct NymName(String);
#[derive(Debug, Error)]
pub enum NymNameError {
#[error("invalid name")]
InvalidName,
}
/// Defines what names are allowed
fn is_valid_name_char(c: char) -> bool {
// Normal lowercase letters
(c.is_alphabetic() && c.is_lowercase())
// or numbers
|| c.is_numeric()
// special case hyphen or underscore
|| c == '-' || c == '_'
}
impl NymName {
pub fn new(name: &str) -> Result<NymName, NymNameError> {
// We are a bit restrictive in which names we allow, to start out with. Consider relaxing
// this in the future.
if !name.chars().all(is_valid_name_char) {
return Err(NymNameError::InvalidName);
}
Ok(Self(name.to_string()))
}
pub fn as_str(&self) -> &str {
&self.0
}
}
impl FromStr for NymName {
type Err = NymNameError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Self::new(s)
}
}
impl Display for NymName {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
#[cfg(test)]
mod tests {
use super::NymName;
#[test]
fn parse_nym_name() {
// Test some valid cases
assert!(NymName::new("foo").is_ok());
assert!(NymName::new("foo-bar").is_ok());
assert!(NymName::new("foo-bar-123").is_ok());
assert!(NymName::new("foo_bar").is_ok());
assert!(NymName::new("foo_bar_123").is_ok());
// And now test all some invalid ones
assert!(NymName::new("Foo").is_err());
assert!(NymName::new("foo bar").is_err());
assert!(NymName::new("foo!bar").is_err());
assert!(NymName::new("foo#bar").is_err());
assert!(NymName::new("foo$bar").is_err());
assert!(NymName::new("foo%bar").is_err());
assert!(NymName::new("foo&bar").is_err());
assert!(NymName::new("foo'bar").is_err());
assert!(NymName::new("foo(bar").is_err());
assert!(NymName::new("foo)bar").is_err());
assert!(NymName::new("foo*bar").is_err());
assert!(NymName::new("foo+bar").is_err());
assert!(NymName::new("foo,bar").is_err());
assert!(NymName::new("foo.bar").is_err());
assert!(NymName::new("foo.bar").is_err());
assert!(NymName::new("foo/bar").is_err());
assert!(NymName::new("foo/bar").is_err());
assert!(NymName::new("foo:bar").is_err());
assert!(NymName::new("foo;bar").is_err());
assert!(NymName::new("foo<bar").is_err());
assert!(NymName::new("foo=bar").is_err());
assert!(NymName::new("foo>bar").is_err());
assert!(NymName::new("foo?bar").is_err());
assert!(NymName::new("foo@bar").is_err());
assert!(NymName::new("fooBar").is_err());
assert!(NymName::new("foo[bar").is_err());
assert!(NymName::new("foo\"bar").is_err());
assert!(NymName::new("foo\\bar").is_err());
assert!(NymName::new("foo]bar").is_err());
assert!(NymName::new("foo^bar").is_err());
assert!(NymName::new("foo`bar").is_err());
assert!(NymName::new("foo{bar").is_err());
assert!(NymName::new("foo|bar").is_err());
assert!(NymName::new("foo}bar").is_err());
assert!(NymName::new("foo~bar").is_err());
}
}
@@ -1,19 +0,0 @@
[package]
name = "nym-service-provider-directory-common"
version = "0.1.0"
edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
cosmwasm-schema = { workspace = true }
cosmwasm-std = { workspace = true }
cw2 = { workspace = true, optional = true }
cw-controllers = { workspace = true }
cw-utils = { workspace = true }
nym-contracts-common = { path = "../contracts-common", version = "0.5.0" }
thiserror = { workspace = true }
[features]
schema = ["cw2"]
@@ -1,68 +0,0 @@
use cosmwasm_std::{Addr, StdError};
use cw_controllers::AdminError;
use nym_contracts_common::signing::verifier::ApiVerifierError;
use thiserror::Error;
use crate::{NymAddress, ServiceId};
#[derive(Error, Debug, PartialEq)]
pub enum SpContractError {
#[error("{0}")]
Std(#[from] StdError),
#[error("{0}")]
AdminError(#[from] AdminError),
#[error("service not found: {service_id}")]
NotFound { service_id: ServiceId },
#[error("{sender} is not announcer of service")]
Unauthorized { sender: Addr },
#[error("deposit required to announce service")]
DepositRequired { source: cw_utils::PaymentError },
#[error("insufficiant deposit: {funds}, required: {deposit_required}")]
InsufficientDeposit {
funds: cosmwasm_std::Uint128,
deposit_required: cosmwasm_std::Uint128,
},
#[error("deposit too large: {funds}, required: {deposit_required}")]
TooLargeDeposit {
funds: cosmwasm_std::Uint128,
deposit_required: cosmwasm_std::Uint128,
},
#[error("reached the max number of providers ({max_providers}) for announcer {announcer}")]
ReachedMaxProvidersForAdmin { max_providers: u32, announcer: Addr },
#[error("reached the max number of aliases ({max_aliases}) for nym address {0}", nym_address.to_string())]
ReachedMaxAliasesForNymAddress {
max_aliases: u32,
nym_address: NymAddress,
},
#[error("failed to parse {value} into a valid SemVer version: {error_message}")]
SemVerFailure {
value: String,
error_message: String,
},
#[error("Failed to recover ed25519 public key from its base58 representation - {0}")]
MalformedEd25519IdentityKey(String),
#[error("Failed to recover ed25519 signature from its base58 representation - {0}")]
MalformedEd25519Signature(String),
#[error("Provided ed25519 signature did not verify correctly")]
InvalidEd25519Signature,
#[error("failed to verify message signature: {source}")]
SignatureVerificationFailure {
#[from]
source: ApiVerifierError,
},
}
pub type Result<T, E = SpContractError> = std::result::Result<T, E>;
@@ -1,58 +0,0 @@
use cosmwasm_std::{Coin, Event};
use crate::{Service, ServiceId};
pub enum ServiceProviderEventType {
Announce,
DeleteId,
DeleteNymAddress,
UpdateDepositRequired,
}
impl std::fmt::Display for ServiceProviderEventType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ServiceProviderEventType::Announce => write!(f, "announce"),
ServiceProviderEventType::DeleteId => write!(f, "delete_id"),
ServiceProviderEventType::DeleteNymAddress => write!(f, "delete_nym_address"),
ServiceProviderEventType::UpdateDepositRequired => write!(f, "update_deposit_required"),
}
}
}
impl From<ServiceProviderEventType> for String {
fn from(event_type: ServiceProviderEventType) -> Self {
event_type.to_string()
}
}
pub const ACTION: &str = "action";
pub const SERVICE_ID: &str = "service_id";
pub const SERVICE_TYPE: &str = "service_type";
pub const NYM_ADDRESS: &str = "nym_address";
pub const OWNER: &str = "owner";
pub const DEPOSIT_REQUIRED: &str = "deposit_required";
pub fn new_announce_event(service_id: ServiceId, service: Service) -> Event {
Event::new(ServiceProviderEventType::Announce)
.add_attribute(ACTION, ServiceProviderEventType::Announce)
.add_attribute(SERVICE_ID, service_id.to_string())
.add_attribute(SERVICE_TYPE, service.service.service_type.to_string())
.add_attribute(NYM_ADDRESS, service.service.nym_address.to_string())
.add_attribute(OWNER, service.announcer.to_string())
}
pub fn new_delete_id_event(service: Service) -> Event {
Event::new(ServiceProviderEventType::DeleteId)
.add_attribute(ACTION, ServiceProviderEventType::DeleteId)
.add_attribute(SERVICE_ID, service.service_id.to_string())
.add_attribute(NYM_ADDRESS, service.service.nym_address.to_string())
}
pub fn new_update_deposit_required_event(deposit_required: Coin) -> Event {
Event::new(ServiceProviderEventType::UpdateDepositRequired)
.add_attribute(ACTION, ServiceProviderEventType::UpdateDepositRequired)
.add_attribute(DEPOSIT_REQUIRED, deposit_required.to_string())
}
@@ -1,11 +0,0 @@
pub mod error;
pub mod events;
pub mod msg;
pub mod response;
pub mod signing_types;
pub mod types;
// Re-export all types at the top-level
pub use types::*;
pub use cosmwasm_std::{Addr, Coin, Decimal, Fraction};
@@ -1,118 +0,0 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::{NymAddress, ServiceDetails, ServiceId};
use cosmwasm_schema::cw_serde;
use cosmwasm_std::Coin;
use nym_contracts_common::signing::MessageSignature;
#[cfg(feature = "schema")]
use crate::{
response::{ConfigResponse, PagedServicesListResponse, ServicesListResponse},
types::Service,
};
#[cfg(feature = "schema")]
use cosmwasm_schema::QueryResponses;
#[cfg(feature = "schema")]
use nym_contracts_common::{signing::Nonce, ContractBuildInformation};
#[cw_serde]
pub struct InstantiateMsg {
pub deposit_required: Coin,
}
impl InstantiateMsg {
pub fn new(deposit_required: Coin) -> Self {
Self { deposit_required }
}
}
#[cw_serde]
pub struct MigrateMsg {}
#[cw_serde]
pub enum ExecuteMsg {
Announce {
service: ServiceDetails,
owner_signature: MessageSignature,
},
DeleteId {
service_id: ServiceId,
},
DeleteNymAddress {
nym_address: NymAddress,
},
UpdateDepositRequired {
deposit_required: Coin,
},
}
impl ExecuteMsg {
pub fn delete_id(service_id: ServiceId) -> Self {
ExecuteMsg::DeleteId { service_id }
}
pub fn default_memo(&self) -> String {
match self {
ExecuteMsg::Announce {
service,
owner_signature: _,
} => format!(
"announcing {} as type {}",
service.nym_address, service.service_type
),
ExecuteMsg::DeleteId { service_id } => {
format!("deleting service with service id {service_id}")
}
ExecuteMsg::DeleteNymAddress { nym_address } => {
format!("deleting service with nym address {nym_address}")
}
ExecuteMsg::UpdateDepositRequired { deposit_required } => {
format!("updating the deposit required to {deposit_required}")
}
}
}
}
#[cw_serde]
#[cfg_attr(feature = "schema", derive(QueryResponses))]
pub enum QueryMsg {
#[cfg_attr(feature = "schema", returns(Service))]
ServiceId { service_id: ServiceId },
#[cfg_attr(feature = "schema", returns(ServicesListResponse))]
ByAnnouncer { announcer: String },
#[cfg_attr(feature = "schema", returns(ServicesListResponse))]
ByNymAddress { nym_address: NymAddress },
#[cfg_attr(feature = "schema", returns(PagedServicesListResponse))]
All {
limit: Option<u32>,
start_after: Option<ServiceId>,
},
#[cfg_attr(feature = "schema", returns(Nonce))]
SigningNonce { address: String },
#[cfg_attr(feature = "schema", returns(ConfigResponse))]
Config {},
/// Gets build information of this contract, such as the commit hash used for the build or rustc version.
#[cfg_attr(feature = "schema", returns(ContractBuildInformation))]
GetContractVersion {},
/// Gets the stored contract version information that's required by the CW2 spec interface for migrations.
#[serde(rename = "get_cw2_contract_version")]
#[cfg_attr(feature = "schema", returns(cw2::ContractVersion))]
GetCW2ContractVersion {},
}
impl QueryMsg {
pub fn all() -> QueryMsg {
QueryMsg::All {
limit: None,
start_after: None,
}
}
}
@@ -1,59 +0,0 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::{Service, ServiceId};
use cosmwasm_schema::cw_serde;
use cosmwasm_std::Coin;
#[cw_serde]
pub struct ServiceInfoResponse {
pub service_id: ServiceId,
pub service: Option<Service>,
}
#[cw_serde]
pub struct ServicesListResponse {
pub services: Vec<Service>,
}
impl ServicesListResponse {
pub fn new(services: Vec<Service>) -> ServicesListResponse {
ServicesListResponse { services }
}
}
impl From<&[Service]> for ServicesListResponse {
fn from(services: &[Service]) -> Self {
Self {
services: services.to_vec(),
}
}
}
#[cw_serde]
pub struct PagedServicesListResponse {
pub services: Vec<Service>,
pub per_page: usize,
/// Field indicating paging information for the following queries if the caller wishes to get further entries.
pub start_next_after: Option<ServiceId>,
}
impl PagedServicesListResponse {
pub fn new(
services: Vec<Service>,
per_page: usize,
start_next_after: Option<ServiceId>,
) -> PagedServicesListResponse {
PagedServicesListResponse {
services,
per_page,
start_next_after,
}
}
}
#[cw_serde]
pub struct ConfigResponse {
pub deposit_required: Coin,
}
@@ -1,35 +0,0 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::ServiceDetails;
use cosmwasm_schema::cw_serde;
use cosmwasm_std::{Addr, Coin};
use nym_contracts_common::signing::{
ContractMessageContent, MessageType, Nonce, SignableMessage, SigningPurpose,
};
pub type SignableServiceProviderAnnounceMsg =
SignableMessage<ContractMessageContent<ServiceProviderAnnounce>>;
#[cw_serde]
pub struct ServiceProviderAnnounce {
service: ServiceDetails,
}
impl SigningPurpose for ServiceProviderAnnounce {
fn message_type() -> MessageType {
MessageType::new("service-provider-announce")
}
}
pub fn construct_service_provider_announce_sign_payload(
nonce: Nonce,
sender: Addr,
deposit: Coin,
service: ServiceDetails,
) -> SignableServiceProviderAnnounceMsg {
let payload = ServiceProviderAnnounce { service };
let proxy = None;
let content = ContractMessageContent::new(sender, proxy, vec![deposit], payload);
SignableMessage::new(nonce, content)
}
@@ -1,79 +0,0 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use cosmwasm_schema::cw_serde;
use cosmwasm_std::{Addr, Coin};
use nym_contracts_common::IdentityKey;
use std::fmt::{Display, Formatter};
/// The directory of services are indexed by [`ServiceId`].
pub type ServiceId = u32;
#[cw_serde]
pub struct Service {
/// Unique id assigned to the anounced service.
pub service_id: ServiceId,
/// The announced service.
pub service: ServiceDetails,
/// Address of the service owner.
pub announcer: Addr,
/// Block height at which the service was added.
pub block_height: u64,
/// The deposit used to announce the service.
pub deposit: Coin,
}
#[cw_serde]
pub struct ServiceDetails {
/// The address of the service.
pub nym_address: NymAddress,
/// The service type.
pub service_type: ServiceType,
/// The identity key of the service.
pub identity_key: IdentityKey,
}
/// The types of addresses supported.
#[cw_serde]
pub enum NymAddress {
/// String representation of a nym address, which is of the form
/// client_id.client_enc@gateway_id.
Address(String),
// String name that can looked up in the nym-name-service contract (once it exists)
//Name(String),
}
impl NymAddress {
/// Create a new nym address.
pub fn new(address: &str) -> Self {
Self::Address(address.to_string())
}
pub fn as_str(&self) -> &str {
match self {
NymAddress::Address(address) => address,
//NymAddress::Name(name) => name,
}
}
}
impl Display for NymAddress {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.as_str())
}
}
/// The type of services provider supported
#[cw_serde]
pub enum ServiceType {
NetworkRequester,
}
impl std::fmt::Display for ServiceType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let service_type = match self {
ServiceType::NetworkRequester => "network_requester",
};
write!(f, "{service_type}")
}
}
+1 -1
View File
@@ -23,5 +23,5 @@ nym-api-requests = { path = "../../nym-api/nym-api-requests" }
nym-validator-client = { path = "../client-libs/validator-client", default-features = false } nym-validator-client = { path = "../client-libs/validator-client", default-features = false }
[dev-dependencies] [dev-dependencies]
rand = "0.7.3" rand = "0.8.5"
+5 -5
View File
@@ -17,10 +17,10 @@ generic-array = { workspace = true, optional = true }
hkdf = { workspace = true, optional = true } hkdf = { workspace = true, optional = true }
hmac = { workspace = true, optional = true } hmac = { workspace = true, optional = true }
cipher = { workspace = true, optional = true } cipher = { workspace = true, optional = true }
x25519-dalek = { version = "1.1", optional = true } x25519-dalek = { version = "2.0", optional = true, features = ["static_secrets"]}
ed25519-dalek = { workspace = true, optional = true } ed25519-dalek = { version = "2.1", features = ["rand_core"], optional = true }
rand = { version = "0.7.3", features = ["wasm-bindgen"], optional = true } rand = { workspace = true, optional = true }
serde_bytes = { workspace = true, optional = true } serde_bytes = { version = "0.11.6", optional = true }
serde_crate = { version = "1.0", optional = true, default_features = false, features = ["derive"], package = "serde" } serde_crate = { version = "1.0", optional = true, default_features = false, features = ["derive"], package = "serde" }
subtle-encoding = { workspace = true, features = ["bech32-preview"] } subtle-encoding = { workspace = true, features = ["bech32-preview"] }
thiserror = { workspace = true } thiserror = { workspace = true }
@@ -31,7 +31,7 @@ nym-sphinx-types = { path = "../nymsphinx/types", version = "0.2.0", default-fea
nym-pemstore = { path = "../../common/pemstore", version = "0.3.0" } nym-pemstore = { path = "../../common/pemstore", version = "0.3.0" }
[dev-dependencies] [dev-dependencies]
rand_chacha = "0.2" rand_chacha = "0.3"
[features] [features]
default = ["sphinx"] default = ["sphinx"]
+11 -4
View File
@@ -56,7 +56,7 @@ pub struct KeyPair {
impl KeyPair { impl KeyPair {
#[cfg(feature = "rand")] #[cfg(feature = "rand")]
pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self { pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
let private_key = x25519_dalek::StaticSecret::new(rng); let private_key = x25519_dalek::StaticSecret::random_from_rng(rng);
let public_key = (&private_key).into(); let public_key = (&private_key).into();
KeyPair { KeyPair {
@@ -211,7 +211,7 @@ impl FromStr for PrivateKey {
impl PrivateKey { impl PrivateKey {
#[cfg(feature = "rand")] #[cfg(feature = "rand")]
pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self { pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
let x25519_secret = x25519_dalek::StaticSecret::new(rng); let x25519_secret = x25519_dalek::StaticSecret::random_from_rng(rng);
PrivateKey(x25519_secret) PrivateKey(x25519_secret)
} }
@@ -358,16 +358,23 @@ mod sphinx_key_conversion {
let private = &keys.private_key; let private = &keys.private_key;
let public = &keys.public_key; let public = &keys.public_key;
let private_bytes = private.to_bytes(); let dummy_remote = KeyPair::new(&mut rng);
let dh1 = private.diffie_hellman(&dummy_remote.public_key);
let public_bytes = public.to_bytes(); let public_bytes = public.to_bytes();
let sphinx_private: nym_sphinx_types::PrivateKey = private.into(); let sphinx_private: nym_sphinx_types::PrivateKey = private.into();
let recovered_private = PrivateKey::from(sphinx_private); let recovered_private = PrivateKey::from(sphinx_private);
let dh2 = recovered_private.diffie_hellman(&dummy_remote.public_key);
let sphinx_public: nym_sphinx_types::PublicKey = public.into(); let sphinx_public: nym_sphinx_types::PublicKey = public.into();
let recovered_public = PublicKey::from(sphinx_public); let recovered_public = PublicKey::from(sphinx_public);
assert_eq!(private_bytes, recovered_private.to_bytes());
assert_eq!(public_bytes, recovered_public.to_bytes()); assert_eq!(public_bytes, recovered_public.to_bytes());
// even though the byte representation of the private key changed, the resultant DH is the same
// which is what matters
assert_eq!(dh1, dh2);
} }
} }
+21 -15
View File
@@ -1,8 +1,8 @@
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net> // Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
pub use ed25519_dalek::ed25519::signature::Signature as SignatureTrait;
pub use ed25519_dalek::SignatureError; pub use ed25519_dalek::SignatureError;
use ed25519_dalek::{Signer, SigningKey};
pub use ed25519_dalek::{Verifier, PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, SIGNATURE_LENGTH}; pub use ed25519_dalek::{Verifier, PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, SIGNATURE_LENGTH};
use nym_pemstore::traits::{PemStorableKey, PemStorableKeyPair}; use nym_pemstore::traits::{PemStorableKey, PemStorableKeyPair};
use std::fmt::{self, Display, Formatter}; use std::fmt::{self, Display, Formatter};
@@ -30,6 +30,9 @@ pub enum Ed25519RecoveryError {
#[error(transparent)] #[error(transparent)]
MalformedBytes(#[from] SignatureError), MalformedBytes(#[from] SignatureError),
#[error(transparent)]
BytesLengthError(#[from] std::array::TryFromSliceError),
#[error("the base58 representation of the public key was malformed - {source}")] #[error("the base58 representation of the public key was malformed - {source}")]
MalformedPublicKeyString { MalformedPublicKeyString {
#[source] #[source]
@@ -64,11 +67,11 @@ pub struct KeyPair {
impl KeyPair { impl KeyPair {
#[cfg(feature = "rand")] #[cfg(feature = "rand")]
pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self { pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
let ed25519_keypair = ed25519_dalek::Keypair::generate(rng); let ed25519_signing_key = ed25519_dalek::SigningKey::generate(rng);
KeyPair { KeyPair {
private_key: PrivateKey(ed25519_keypair.secret), private_key: PrivateKey(ed25519_signing_key.to_bytes()),
public_key: PublicKey(ed25519_keypair.public), public_key: PublicKey(ed25519_signing_key.verifying_key()),
} }
} }
@@ -109,7 +112,7 @@ impl PemStorableKeyPair for KeyPair {
/// ed25519 EdDSA Public Key /// ed25519 EdDSA Public Key
#[derive(Debug, Copy, Clone, Eq, PartialEq)] #[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct PublicKey(ed25519_dalek::PublicKey); pub struct PublicKey(ed25519_dalek::VerifyingKey);
impl Display for PublicKey { impl Display for PublicKey {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
@@ -135,7 +138,9 @@ impl PublicKey {
} }
pub fn from_bytes(b: &[u8]) -> Result<Self, Ed25519RecoveryError> { pub fn from_bytes(b: &[u8]) -> Result<Self, Ed25519RecoveryError> {
Ok(PublicKey(ed25519_dalek::PublicKey::from_bytes(b)?)) Ok(PublicKey(ed25519_dalek::VerifyingKey::from_bytes(
b.try_into()?,
)?))
} }
pub fn to_base58_string(self) -> String { pub fn to_base58_string(self) -> String {
@@ -189,7 +194,7 @@ impl<'d> Deserialize<'d> for PublicKey {
where where
D: Deserializer<'d>, D: Deserializer<'d>,
{ {
Ok(PublicKey(ed25519_dalek::PublicKey::deserialize( Ok(PublicKey(ed25519_dalek::VerifyingKey::deserialize(
deserializer, deserializer,
)?)) )?))
} }
@@ -223,7 +228,7 @@ impl Display for PrivateKey {
impl<'a> From<&'a PrivateKey> for PublicKey { impl<'a> From<&'a PrivateKey> for PublicKey {
fn from(pk: &'a PrivateKey) -> Self { fn from(pk: &'a PrivateKey) -> Self {
PublicKey((&pk.0).into()) PublicKey(SigningKey::from_bytes(&pk.0).verifying_key())
} }
} }
@@ -238,7 +243,7 @@ impl FromStr for PrivateKey {
impl PrivateKey { impl PrivateKey {
#[cfg(feature = "rand")] #[cfg(feature = "rand")]
pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self { pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
let ed25519_secret = ed25519_dalek::SecretKey::generate(rng); let ed25519_secret = ed25519_dalek::SigningKey::generate(rng).to_bytes();
PrivateKey(ed25519_secret) PrivateKey(ed25519_secret)
} }
@@ -248,11 +253,11 @@ impl PrivateKey {
} }
pub fn to_bytes(&self) -> [u8; SECRET_KEY_LENGTH] { pub fn to_bytes(&self) -> [u8; SECRET_KEY_LENGTH] {
self.0.to_bytes() self.0
} }
pub fn from_bytes(b: &[u8]) -> Result<Self, Ed25519RecoveryError> { pub fn from_bytes(b: &[u8]) -> Result<Self, Ed25519RecoveryError> {
Ok(PrivateKey(ed25519_dalek::SecretKey::from_bytes(b)?)) Ok(PrivateKey(b.try_into()?))
} }
pub fn to_base58_string(&self) -> String { pub fn to_base58_string(&self) -> String {
@@ -267,9 +272,8 @@ impl PrivateKey {
} }
pub fn sign<M: AsRef<[u8]>>(&self, message: M) -> Signature { pub fn sign<M: AsRef<[u8]>>(&self, message: M) -> Signature {
let expanded_secret_key = ed25519_dalek::ExpandedSecretKey::from(&self.0); let signing_key: SigningKey = self.0.into();
let public_key: PublicKey = self.into(); let sig = signing_key.sign(message.as_ref());
let sig = expanded_secret_key.sign(message.as_ref(), &public_key.0);
Signature(sig) Signature(sig)
} }
@@ -338,7 +342,9 @@ impl Signature {
} }
pub fn from_bytes(bytes: &[u8]) -> Result<Self, Ed25519RecoveryError> { pub fn from_bytes(bytes: &[u8]) -> Result<Self, Ed25519RecoveryError> {
Ok(Signature(ed25519_dalek::Signature::from_bytes(bytes)?)) Ok(Signature(ed25519_dalek::Signature::from_bytes(
bytes.try_into()?,
)))
} }
} }
+2 -2
View File
@@ -3,11 +3,11 @@
use crate::asymmetric::encryption; use crate::asymmetric::encryption;
use crate::hkdf; use crate::hkdf;
#[cfg(feature = "rand")]
use cipher::crypto_common::rand_core::{CryptoRng, RngCore};
use cipher::{Key, KeyIvInit, StreamCipher}; use cipher::{Key, KeyIvInit, StreamCipher};
use digest::crypto_common::BlockSizeUser; use digest::crypto_common::BlockSizeUser;
use digest::Digest; use digest::Digest;
#[cfg(feature = "rand")]
use rand::{CryptoRng, RngCore};
/// Generate an ephemeral encryption keypair and perform diffie-hellman to establish /// Generate an ephemeral encryption keypair and perform diffie-hellman to establish
/// shared key with the remote. /// shared key with the remote.
+1
View File
@@ -12,6 +12,7 @@ license.workspace = true
bincode = { workspace = true } bincode = { workspace = true }
bytes = { workspace = true } bytes = { workspace = true }
nym-bin-common = { path = "../bin-common" } nym-bin-common = { path = "../bin-common" }
nym-crypto = { path = "../crypto" }
nym-sphinx = { path = "../nymsphinx" } nym-sphinx = { path = "../nymsphinx" }
rand = "0.8.5" rand = "0.8.5"
serde = { workspace = true, features = ["derive"] } serde = { workspace = true, features = ["derive"] }
+2
View File
@@ -1,2 +1,4 @@
pub mod request; pub mod request;
pub mod response; pub mod response;
const VERSION: u8 = 6;
+9 -7
View File
@@ -1,7 +1,9 @@
use nym_sphinx::addressing::clients::Recipient; use nym_sphinx::addressing::clients::Recipient;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{make_bincode_serializer, IpPair, CURRENT_VERSION}; use crate::{make_bincode_serializer, IpPair};
use super::VERSION;
fn generate_random() -> u64 { fn generate_random() -> u64 {
use rand::RngCore; use rand::RngCore;
@@ -26,7 +28,7 @@ impl IpPacketRequest {
let request_id = generate_random(); let request_id = generate_random();
( (
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketRequestData::StaticConnect(StaticConnectRequest { data: IpPacketRequestData::StaticConnect(StaticConnectRequest {
request_id, request_id,
ips, ips,
@@ -49,7 +51,7 @@ impl IpPacketRequest {
let request_id = generate_random(); let request_id = generate_random();
( (
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketRequestData::DynamicConnect(DynamicConnectRequest { data: IpPacketRequestData::DynamicConnect(DynamicConnectRequest {
request_id, request_id,
reply_to, reply_to,
@@ -66,7 +68,7 @@ impl IpPacketRequest {
let request_id = generate_random(); let request_id = generate_random();
( (
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketRequestData::Disconnect(DisconnectRequest { data: IpPacketRequestData::Disconnect(DisconnectRequest {
request_id, request_id,
reply_to, reply_to,
@@ -78,7 +80,7 @@ impl IpPacketRequest {
pub fn new_data_request(ip_packets: bytes::Bytes) -> Self { pub fn new_data_request(ip_packets: bytes::Bytes) -> Self {
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketRequestData::Data(DataRequest { ip_packets }), data: IpPacketRequestData::Data(DataRequest { ip_packets }),
} }
} }
@@ -87,7 +89,7 @@ impl IpPacketRequest {
let request_id = generate_random(); let request_id = generate_random();
( (
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketRequestData::Ping(PingRequest { data: IpPacketRequestData::Ping(PingRequest {
request_id, request_id,
reply_to, reply_to,
@@ -101,7 +103,7 @@ impl IpPacketRequest {
let request_id = generate_random(); let request_id = generate_random();
( (
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketRequestData::Health(HealthRequest { data: IpPacketRequestData::Health(HealthRequest {
request_id, request_id,
reply_to, reply_to,
+15 -13
View File
@@ -1,7 +1,9 @@
use nym_sphinx::addressing::clients::Recipient; use nym_sphinx::addressing::clients::Recipient;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{make_bincode_serializer, IpPair, CURRENT_VERSION}; use crate::{make_bincode_serializer, IpPair};
use super::VERSION;
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct IpPacketResponse { pub struct IpPacketResponse {
@@ -12,7 +14,7 @@ pub struct IpPacketResponse {
impl IpPacketResponse { impl IpPacketResponse {
pub fn new_static_connect_success(request_id: u64, reply_to: Recipient) -> Self { pub fn new_static_connect_success(request_id: u64, reply_to: Recipient) -> Self {
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketResponseData::StaticConnect(StaticConnectResponse { data: IpPacketResponseData::StaticConnect(StaticConnectResponse {
request_id, request_id,
reply_to, reply_to,
@@ -27,7 +29,7 @@ impl IpPacketResponse {
reason: StaticConnectFailureReason, reason: StaticConnectFailureReason,
) -> Self { ) -> Self {
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketResponseData::StaticConnect(StaticConnectResponse { data: IpPacketResponseData::StaticConnect(StaticConnectResponse {
request_id, request_id,
reply_to, reply_to,
@@ -38,7 +40,7 @@ impl IpPacketResponse {
pub fn new_dynamic_connect_success(request_id: u64, reply_to: Recipient, ips: IpPair) -> Self { pub fn new_dynamic_connect_success(request_id: u64, reply_to: Recipient, ips: IpPair) -> Self {
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketResponseData::DynamicConnect(DynamicConnectResponse { data: IpPacketResponseData::DynamicConnect(DynamicConnectResponse {
request_id, request_id,
reply_to, reply_to,
@@ -53,7 +55,7 @@ impl IpPacketResponse {
reason: DynamicConnectFailureReason, reason: DynamicConnectFailureReason,
) -> Self { ) -> Self {
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketResponseData::DynamicConnect(DynamicConnectResponse { data: IpPacketResponseData::DynamicConnect(DynamicConnectResponse {
request_id, request_id,
reply_to, reply_to,
@@ -64,7 +66,7 @@ impl IpPacketResponse {
pub fn new_disconnect_success(request_id: u64, reply_to: Recipient) -> Self { pub fn new_disconnect_success(request_id: u64, reply_to: Recipient) -> Self {
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketResponseData::Disconnect(DisconnectResponse { data: IpPacketResponseData::Disconnect(DisconnectResponse {
request_id, request_id,
reply_to, reply_to,
@@ -79,7 +81,7 @@ impl IpPacketResponse {
reason: DisconnectFailureReason, reason: DisconnectFailureReason,
) -> Self { ) -> Self {
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketResponseData::Disconnect(DisconnectResponse { data: IpPacketResponseData::Disconnect(DisconnectResponse {
request_id, request_id,
reply_to, reply_to,
@@ -93,7 +95,7 @@ impl IpPacketResponse {
reason: UnrequestedDisconnectReason, reason: UnrequestedDisconnectReason,
) -> Self { ) -> Self {
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketResponseData::UnrequestedDisconnect(UnrequestedDisconnect { data: IpPacketResponseData::UnrequestedDisconnect(UnrequestedDisconnect {
reply_to, reply_to,
reason, reason,
@@ -103,7 +105,7 @@ impl IpPacketResponse {
pub fn new_ip_packet(ip_packet: bytes::Bytes) -> Self { pub fn new_ip_packet(ip_packet: bytes::Bytes) -> Self {
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketResponseData::Data(DataResponse { ip_packet }), data: IpPacketResponseData::Data(DataResponse { ip_packet }),
} }
} }
@@ -115,7 +117,7 @@ impl IpPacketResponse {
our_version: u8, our_version: u8,
) -> Self { ) -> Self {
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketResponseData::Info(InfoResponse { data: IpPacketResponseData::Info(InfoResponse {
request_id, request_id,
reply_to, reply_to,
@@ -134,7 +136,7 @@ impl IpPacketResponse {
level: InfoLevel, level: InfoLevel,
) -> Self { ) -> Self {
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketResponseData::Info(InfoResponse { data: IpPacketResponseData::Info(InfoResponse {
request_id: 0, request_id: 0,
reply_to, reply_to,
@@ -146,7 +148,7 @@ impl IpPacketResponse {
pub fn new_pong(request_id: u64, reply_to: Recipient) -> Self { pub fn new_pong(request_id: u64, reply_to: Recipient) -> Self {
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketResponseData::Pong(PongResponse { data: IpPacketResponseData::Pong(PongResponse {
request_id, request_id,
reply_to, reply_to,
@@ -161,7 +163,7 @@ impl IpPacketResponse {
routable: Option<bool>, routable: Option<bool>,
) -> Self { ) -> Self {
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketResponseData::Health(HealthResponse { data: IpPacketResponseData::Health(HealthResponse {
request_id, request_id,
reply_to, reply_to,
@@ -0,0 +1,124 @@
use time::OffsetDateTime;
use crate::{v6, v7};
impl From<v6::request::IpPacketRequest> for v7::request::IpPacketRequest {
fn from(ip_packet_request: v6::request::IpPacketRequest) -> Self {
Self {
version: 7,
data: ip_packet_request.data.into(),
}
}
}
impl From<v6::request::IpPacketRequestData> for v7::request::IpPacketRequestData {
fn from(ip_packet_request_data: v6::request::IpPacketRequestData) -> Self {
match ip_packet_request_data {
v6::request::IpPacketRequestData::StaticConnect(r) => {
v7::request::IpPacketRequestData::StaticConnect(
v7::request::SignedStaticConnectRequest {
request: r.into(),
signature: None,
},
)
}
v6::request::IpPacketRequestData::DynamicConnect(r) => {
v7::request::IpPacketRequestData::DynamicConnect(
v7::request::SignedDynamicConnectRequest {
request: r.into(),
signature: None,
},
)
}
v6::request::IpPacketRequestData::Disconnect(r) => {
v7::request::IpPacketRequestData::Disconnect(v7::request::SignedDisconnectRequest {
request: r.into(),
signature: None,
})
}
v6::request::IpPacketRequestData::Data(r) => {
v7::request::IpPacketRequestData::Data(r.into())
}
v6::request::IpPacketRequestData::Ping(r) => {
v7::request::IpPacketRequestData::Ping(r.into())
}
v6::request::IpPacketRequestData::Health(r) => {
v7::request::IpPacketRequestData::Health(r.into())
}
}
}
}
impl From<v6::request::StaticConnectRequest> for v7::request::StaticConnectRequest {
fn from(static_connect_request: v6::request::StaticConnectRequest) -> Self {
Self {
request_id: static_connect_request.request_id,
ips: static_connect_request.ips,
reply_to: static_connect_request.reply_to,
reply_to_hops: static_connect_request.reply_to_hops,
reply_to_avg_mix_delays: static_connect_request.reply_to_avg_mix_delays,
buffer_timeout: static_connect_request.buffer_timeout,
timestamp: OffsetDateTime::now_utc(),
}
}
}
impl From<v6::request::DynamicConnectRequest> for v7::request::DynamicConnectRequest {
fn from(dynamic_connect_request: v6::request::DynamicConnectRequest) -> Self {
Self {
request_id: dynamic_connect_request.request_id,
reply_to: dynamic_connect_request.reply_to,
reply_to_hops: dynamic_connect_request.reply_to_hops,
reply_to_avg_mix_delays: dynamic_connect_request.reply_to_avg_mix_delays,
buffer_timeout: dynamic_connect_request.buffer_timeout,
timestamp: OffsetDateTime::now_utc(),
}
}
}
impl From<v6::request::DisconnectRequest> for v7::request::SignedDisconnectRequest {
fn from(disconnect_request: v6::request::DisconnectRequest) -> Self {
Self {
request: disconnect_request.into(),
signature: None,
}
}
}
impl From<v6::request::DisconnectRequest> for v7::request::DisconnectRequest {
fn from(disconnect_request: v6::request::DisconnectRequest) -> Self {
Self {
request_id: disconnect_request.request_id,
reply_to: disconnect_request.reply_to,
timestamp: OffsetDateTime::now_utc(),
}
}
}
impl From<v6::request::DataRequest> for v7::request::DataRequest {
fn from(data_request: v6::request::DataRequest) -> Self {
Self {
ip_packets: data_request.ip_packets,
}
}
}
impl From<v6::request::PingRequest> for v7::request::PingRequest {
fn from(ping_request: v6::request::PingRequest) -> Self {
Self {
request_id: ping_request.request_id,
reply_to: ping_request.reply_to,
timestamp: OffsetDateTime::now_utc(),
}
}
}
impl From<v6::request::HealthRequest> for v7::request::HealthRequest {
fn from(health_request: v6::request::HealthRequest) -> Self {
Self {
request_id: health_request.request_id,
reply_to: health_request.reply_to,
timestamp: OffsetDateTime::now_utc(),
}
}
}
+4
View File
@@ -1,2 +1,6 @@
pub mod conversion;
pub mod request; pub mod request;
pub mod response; pub mod response;
pub mod signature;
const VERSION: u8 = 7;
+89 -14
View File
@@ -1,8 +1,14 @@
use nym_crypto::asymmetric::identity;
use nym_sphinx::addressing::clients::Recipient; use nym_sphinx::addressing::clients::Recipient;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use time::OffsetDateTime; use time::OffsetDateTime;
use crate::{make_bincode_serializer, IpPair, CURRENT_VERSION}; use crate::{make_bincode_serializer, IpPair};
use super::{
signature::{SignatureError, SignedRequest},
VERSION,
};
fn generate_random() -> u64 { fn generate_random() -> u64 {
use rand::RngCore; use rand::RngCore;
@@ -27,7 +33,7 @@ impl IpPacketRequest {
let request_id = generate_random(); let request_id = generate_random();
( (
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketRequestData::StaticConnect(SignedStaticConnectRequest { data: IpPacketRequestData::StaticConnect(SignedStaticConnectRequest {
request: StaticConnectRequest { request: StaticConnectRequest {
request_id, request_id,
@@ -54,7 +60,7 @@ impl IpPacketRequest {
let request_id = generate_random(); let request_id = generate_random();
( (
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketRequestData::DynamicConnect(SignedDynamicConnectRequest { data: IpPacketRequestData::DynamicConnect(SignedDynamicConnectRequest {
request: DynamicConnectRequest { request: DynamicConnectRequest {
request_id, request_id,
@@ -75,7 +81,7 @@ impl IpPacketRequest {
let request_id = generate_random(); let request_id = generate_random();
( (
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketRequestData::Disconnect(SignedDisconnectRequest { data: IpPacketRequestData::Disconnect(SignedDisconnectRequest {
request: DisconnectRequest { request: DisconnectRequest {
request_id, request_id,
@@ -91,7 +97,7 @@ impl IpPacketRequest {
pub fn new_data_request(ip_packets: bytes::Bytes) -> Self { pub fn new_data_request(ip_packets: bytes::Bytes) -> Self {
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketRequestData::Data(DataRequest { ip_packets }), data: IpPacketRequestData::Data(DataRequest { ip_packets }),
} }
} }
@@ -100,7 +106,7 @@ impl IpPacketRequest {
let request_id = generate_random(); let request_id = generate_random();
( (
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketRequestData::Ping(PingRequest { data: IpPacketRequestData::Ping(PingRequest {
request_id, request_id,
reply_to, reply_to,
@@ -115,7 +121,7 @@ impl IpPacketRequest {
let request_id = generate_random(); let request_id = generate_random();
( (
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketRequestData::Health(HealthRequest { data: IpPacketRequestData::Health(HealthRequest {
request_id, request_id,
reply_to, reply_to,
@@ -173,19 +179,19 @@ pub enum IpPacketRequestData {
} }
impl IpPacketRequestData { impl IpPacketRequestData {
pub fn add_signature(&mut self, signature: Vec<u8>) -> Option<Vec<u8>> { pub fn add_signature(&mut self, signature: identity::Signature) -> Option<identity::Signature> {
match self { match self {
IpPacketRequestData::StaticConnect(request) => { IpPacketRequestData::StaticConnect(request) => {
request.signature = Some(signature); request.signature = Some(signature);
request.signature.clone() request.signature
} }
IpPacketRequestData::DynamicConnect(request) => { IpPacketRequestData::DynamicConnect(request) => {
request.signature = Some(signature); request.signature = Some(signature);
request.signature.clone() request.signature
} }
IpPacketRequestData::Disconnect(request) => { IpPacketRequestData::Disconnect(request) => {
request.signature = Some(signature); request.signature = Some(signature);
request.signature.clone() request.signature
} }
IpPacketRequestData::Data(_) IpPacketRequestData::Data(_)
| IpPacketRequestData::Ping(_) | IpPacketRequestData::Ping(_)
@@ -231,7 +237,30 @@ impl StaticConnectRequest {
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct SignedStaticConnectRequest { pub struct SignedStaticConnectRequest {
pub request: StaticConnectRequest, pub request: StaticConnectRequest,
pub signature: Option<Vec<u8>>, pub signature: Option<identity::Signature>,
}
impl SignedRequest for SignedStaticConnectRequest {
fn identity(&self) -> &identity::PublicKey {
self.request.reply_to.identity()
}
fn request(&self) -> Result<Vec<u8>, SignatureError> {
self.request
.to_bytes()
.map_err(|error| SignatureError::RequestSerializationError {
message: "failed to serialize request to binary".to_string(),
error,
})
}
fn signature(&self) -> Option<&identity::Signature> {
self.signature.as_ref()
}
fn timestamp(&self) -> OffsetDateTime {
self.request.timestamp
}
} }
// A dynamic connect request is when the client does not provide the internal IP address it will use // A dynamic connect request is when the client does not provide the internal IP address it will use
@@ -269,7 +298,30 @@ impl DynamicConnectRequest {
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct SignedDynamicConnectRequest { pub struct SignedDynamicConnectRequest {
pub request: DynamicConnectRequest, pub request: DynamicConnectRequest,
pub signature: Option<Vec<u8>>, pub signature: Option<identity::Signature>,
}
impl SignedRequest for SignedDynamicConnectRequest {
fn identity(&self) -> &identity::PublicKey {
self.request.reply_to.identity()
}
fn request(&self) -> Result<Vec<u8>, SignatureError> {
self.request
.to_bytes()
.map_err(|error| SignatureError::RequestSerializationError {
message: "failed to serialize request to binary".to_string(),
error,
})
}
fn signature(&self) -> Option<&identity::Signature> {
self.signature.as_ref()
}
fn timestamp(&self) -> OffsetDateTime {
self.request.timestamp
}
} }
// A disconnect request is when the client wants to disconnect from the ip packet router and free // A disconnect request is when the client wants to disconnect from the ip packet router and free
@@ -295,7 +347,30 @@ impl DisconnectRequest {
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct SignedDisconnectRequest { pub struct SignedDisconnectRequest {
pub request: DisconnectRequest, pub request: DisconnectRequest,
pub signature: Option<Vec<u8>>, pub signature: Option<identity::Signature>,
}
impl SignedRequest for SignedDisconnectRequest {
fn identity(&self) -> &identity::PublicKey {
self.request.reply_to.identity()
}
fn request(&self) -> Result<Vec<u8>, SignatureError> {
self.request
.to_bytes()
.map_err(|error| SignatureError::RequestSerializationError {
message: "failed to serialize request to binary".to_string(),
error,
})
}
fn signature(&self) -> Option<&identity::Signature> {
self.signature.as_ref()
}
fn timestamp(&self) -> OffsetDateTime {
self.request.timestamp
}
} }
// A data request is when the client wants to send an IP packet to a destination. // A data request is when the client wants to send an IP packet to a destination.
+17 -13
View File
@@ -1,7 +1,9 @@
use nym_sphinx::addressing::clients::Recipient; use nym_sphinx::addressing::clients::Recipient;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{make_bincode_serializer, IpPair, CURRENT_VERSION}; use crate::{make_bincode_serializer, IpPair};
use super::VERSION;
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct IpPacketResponse { pub struct IpPacketResponse {
@@ -12,7 +14,7 @@ pub struct IpPacketResponse {
impl IpPacketResponse { impl IpPacketResponse {
pub fn new_static_connect_success(request_id: u64, reply_to: Recipient) -> Self { pub fn new_static_connect_success(request_id: u64, reply_to: Recipient) -> Self {
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketResponseData::StaticConnect(StaticConnectResponse { data: IpPacketResponseData::StaticConnect(StaticConnectResponse {
request_id, request_id,
reply_to, reply_to,
@@ -27,7 +29,7 @@ impl IpPacketResponse {
reason: StaticConnectFailureReason, reason: StaticConnectFailureReason,
) -> Self { ) -> Self {
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketResponseData::StaticConnect(StaticConnectResponse { data: IpPacketResponseData::StaticConnect(StaticConnectResponse {
request_id, request_id,
reply_to, reply_to,
@@ -38,7 +40,7 @@ impl IpPacketResponse {
pub fn new_dynamic_connect_success(request_id: u64, reply_to: Recipient, ips: IpPair) -> Self { pub fn new_dynamic_connect_success(request_id: u64, reply_to: Recipient, ips: IpPair) -> Self {
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketResponseData::DynamicConnect(DynamicConnectResponse { data: IpPacketResponseData::DynamicConnect(DynamicConnectResponse {
request_id, request_id,
reply_to, reply_to,
@@ -53,7 +55,7 @@ impl IpPacketResponse {
reason: DynamicConnectFailureReason, reason: DynamicConnectFailureReason,
) -> Self { ) -> Self {
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketResponseData::DynamicConnect(DynamicConnectResponse { data: IpPacketResponseData::DynamicConnect(DynamicConnectResponse {
request_id, request_id,
reply_to, reply_to,
@@ -64,7 +66,7 @@ impl IpPacketResponse {
pub fn new_disconnect_success(request_id: u64, reply_to: Recipient) -> Self { pub fn new_disconnect_success(request_id: u64, reply_to: Recipient) -> Self {
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketResponseData::Disconnect(DisconnectResponse { data: IpPacketResponseData::Disconnect(DisconnectResponse {
request_id, request_id,
reply_to, reply_to,
@@ -79,7 +81,7 @@ impl IpPacketResponse {
reason: DisconnectFailureReason, reason: DisconnectFailureReason,
) -> Self { ) -> Self {
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketResponseData::Disconnect(DisconnectResponse { data: IpPacketResponseData::Disconnect(DisconnectResponse {
request_id, request_id,
reply_to, reply_to,
@@ -93,7 +95,7 @@ impl IpPacketResponse {
reason: UnrequestedDisconnectReason, reason: UnrequestedDisconnectReason,
) -> Self { ) -> Self {
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketResponseData::UnrequestedDisconnect(UnrequestedDisconnect { data: IpPacketResponseData::UnrequestedDisconnect(UnrequestedDisconnect {
reply_to, reply_to,
reason, reason,
@@ -103,7 +105,7 @@ impl IpPacketResponse {
pub fn new_ip_packet(ip_packet: bytes::Bytes) -> Self { pub fn new_ip_packet(ip_packet: bytes::Bytes) -> Self {
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketResponseData::Data(DataResponse { ip_packet }), data: IpPacketResponseData::Data(DataResponse { ip_packet }),
} }
} }
@@ -115,7 +117,7 @@ impl IpPacketResponse {
our_version: u8, our_version: u8,
) -> Self { ) -> Self {
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketResponseData::Info(InfoResponse { data: IpPacketResponseData::Info(InfoResponse {
request_id, request_id,
reply_to, reply_to,
@@ -134,7 +136,7 @@ impl IpPacketResponse {
level: InfoLevel, level: InfoLevel,
) -> Self { ) -> Self {
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketResponseData::Info(InfoResponse { data: IpPacketResponseData::Info(InfoResponse {
request_id: 0, request_id: 0,
reply_to, reply_to,
@@ -146,7 +148,7 @@ impl IpPacketResponse {
pub fn new_pong(request_id: u64, reply_to: Recipient) -> Self { pub fn new_pong(request_id: u64, reply_to: Recipient) -> Self {
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketResponseData::Pong(PongResponse { data: IpPacketResponseData::Pong(PongResponse {
request_id, request_id,
reply_to, reply_to,
@@ -161,7 +163,7 @@ impl IpPacketResponse {
routable: Option<bool>, routable: Option<bool>,
) -> Self { ) -> Self {
Self { Self {
version: CURRENT_VERSION, version: VERSION,
data: IpPacketResponseData::Health(HealthResponse { data: IpPacketResponseData::Health(HealthResponse {
request_id, request_id,
reply_to, reply_to,
@@ -275,6 +277,8 @@ pub enum StaticConnectFailureReason {
RequestedIpAlreadyInUse, RequestedIpAlreadyInUse,
#[error("requested nym-address is already in use")] #[error("requested nym-address is already in use")]
RequestedNymAddressAlreadyInUse, RequestedNymAddressAlreadyInUse,
#[error("request timestamp is out of date")]
OutOfDateTimestamp,
#[error("{0}")] #[error("{0}")]
Other(String), Other(String),
} }
@@ -0,0 +1,57 @@
use std::time::Duration;
use nym_crypto::asymmetric::identity;
// For reply protection, if a request is older than this, it will be rejected
const MAX_REQUEST_AGE: Duration = Duration::from_secs(10);
#[derive(thiserror::Error, Debug)]
pub enum SignatureError {
#[error("signature is missing")]
MissingSignature,
#[error("failed to serialize request to binary: {message}")]
RequestSerializationError {
message: String,
error: Box<bincode::ErrorKind>,
},
#[error("signature verification failed: request out of date")]
RequestOutOfDate,
#[error("signature verification failed")]
VerificationFailed {
message: String,
error: identity::SignatureError,
},
}
pub trait SignedRequest {
fn identity(&self) -> &identity::PublicKey;
fn request(&self) -> Result<Vec<u8>, SignatureError>;
fn signature(&self) -> Option<&identity::Signature>;
fn timestamp(&self) -> time::OffsetDateTime;
fn verify(&self) -> Result<(), SignatureError> {
if let Some(signature) = self.signature() {
// First check that the request is recent enough
if time::OffsetDateTime::now_utc() - self.timestamp() > MAX_REQUEST_AGE {
return Err(SignatureError::RequestOutOfDate);
}
let request_as_bytes = self.request()?;
self.identity()
.verify(request_as_bytes, signature)
.map_err(|error| SignatureError::VerificationFailed {
message: "signature verification failed".to_string(),
error,
})
} else {
Err(SignatureError::MissingSignature)
}
}
}
-9
View File
@@ -31,7 +31,6 @@ pub struct NymContracts {
pub group_contract_address: Option<String>, pub group_contract_address: Option<String>,
pub multisig_contract_address: Option<String>, pub multisig_contract_address: Option<String>,
pub coconut_dkg_contract_address: Option<String>, pub coconut_dkg_contract_address: Option<String>,
pub ephemera_contract_address: Option<String>,
pub service_provider_directory_contract_address: Option<String>, pub service_provider_directory_contract_address: Option<String>,
pub name_service_contract_address: Option<String>, pub name_service_contract_address: Option<String>,
} }
@@ -128,7 +127,6 @@ impl NymNetworkDetails {
.with_group_contract(get_optional_env(var_names::GROUP_CONTRACT_ADDRESS)) .with_group_contract(get_optional_env(var_names::GROUP_CONTRACT_ADDRESS))
.with_multisig_contract(get_optional_env(var_names::MULTISIG_CONTRACT_ADDRESS)) .with_multisig_contract(get_optional_env(var_names::MULTISIG_CONTRACT_ADDRESS))
.with_coconut_dkg_contract(get_optional_env(var_names::COCONUT_DKG_CONTRACT_ADDRESS)) .with_coconut_dkg_contract(get_optional_env(var_names::COCONUT_DKG_CONTRACT_ADDRESS))
.with_ephemera_contract(get_optional_env(var_names::EPHEMERA_CONTRACT_ADDRESS))
.with_service_provider_directory_contract(get_optional_env( .with_service_provider_directory_contract(get_optional_env(
var_names::SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS, var_names::SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS,
)) ))
@@ -161,7 +159,6 @@ impl NymNetworkDetails {
coconut_dkg_contract_address: parse_optional_str( coconut_dkg_contract_address: parse_optional_str(
mainnet::COCONUT_DKG_CONTRACT_ADDRESS, mainnet::COCONUT_DKG_CONTRACT_ADDRESS,
), ),
ephemera_contract_address: parse_optional_str(mainnet::EPHEMERA_CONTRACT_ADDRESS),
service_provider_directory_contract_address: None, service_provider_directory_contract_address: None,
name_service_contract_address: None, name_service_contract_address: None,
}, },
@@ -269,12 +266,6 @@ impl NymNetworkDetails {
self self
} }
#[must_use]
pub fn with_ephemera_contract<S: Into<String>>(mut self, contract: Option<S>) -> Self {
self.contracts.ephemera_contract_address = contract.map(Into::into);
self
}
#[must_use] #[must_use]
pub fn with_service_provider_directory_contract<S: Into<String>>( pub fn with_service_provider_directory_contract<S: Into<String>>(
mut self, mut self,
-9
View File
@@ -24,7 +24,6 @@ pub const MULTISIG_CONTRACT_ADDRESS: &str =
"n1txayqfz5g9qww3rlflpg025xd26m9payz96u54x4fe3s2ktz39xqk67gzx"; "n1txayqfz5g9qww3rlflpg025xd26m9payz96u54x4fe3s2ktz39xqk67gzx";
pub const COCONUT_DKG_CONTRACT_ADDRESS: &str = pub const COCONUT_DKG_CONTRACT_ADDRESS: &str =
"n19604yflqggs9mk2z26mqygq43q2kr3n932egxx630svywd5mpxjsztfpvx"; "n19604yflqggs9mk2z26mqygq43q2kr3n932egxx630svywd5mpxjsztfpvx";
pub const EPHEMERA_CONTRACT_ADDRESS: &str = "";
pub const REWARDING_VALIDATOR_ADDRESS: &str = "n10yyd98e2tuwu0f7ypz9dy3hhjw7v772q6287gy"; pub const REWARDING_VALIDATOR_ADDRESS: &str = "n10yyd98e2tuwu0f7ypz9dy3hhjw7v772q6287gy";
@@ -107,10 +106,6 @@ pub fn export_to_env() {
var_names::COCONUT_DKG_CONTRACT_ADDRESS, var_names::COCONUT_DKG_CONTRACT_ADDRESS,
COCONUT_DKG_CONTRACT_ADDRESS, COCONUT_DKG_CONTRACT_ADDRESS,
); );
set_var_to_default(
var_names::EPHEMERA_CONTRACT_ADDRESS,
EPHEMERA_CONTRACT_ADDRESS,
);
set_var_to_default( set_var_to_default(
var_names::REWARDING_VALIDATOR_ADDRESS, var_names::REWARDING_VALIDATOR_ADDRESS,
REWARDING_VALIDATOR_ADDRESS, REWARDING_VALIDATOR_ADDRESS,
@@ -156,10 +151,6 @@ pub fn export_to_env_if_not_set() {
var_names::COCONUT_DKG_CONTRACT_ADDRESS, var_names::COCONUT_DKG_CONTRACT_ADDRESS,
COCONUT_DKG_CONTRACT_ADDRESS, COCONUT_DKG_CONTRACT_ADDRESS,
); );
set_var_conditionally_to_default(
var_names::EPHEMERA_CONTRACT_ADDRESS,
EPHEMERA_CONTRACT_ADDRESS,
);
set_var_conditionally_to_default( set_var_conditionally_to_default(
var_names::REWARDING_VALIDATOR_ADDRESS, var_names::REWARDING_VALIDATOR_ADDRESS,
REWARDING_VALIDATOR_ADDRESS, REWARDING_VALIDATOR_ADDRESS,
-1
View File
@@ -18,7 +18,6 @@ pub const COCONUT_BANDWIDTH_CONTRACT_ADDRESS: &str = "COCONUT_BANDWIDTH_CONTRACT
pub const GROUP_CONTRACT_ADDRESS: &str = "GROUP_CONTRACT_ADDRESS"; pub const GROUP_CONTRACT_ADDRESS: &str = "GROUP_CONTRACT_ADDRESS";
pub const MULTISIG_CONTRACT_ADDRESS: &str = "MULTISIG_CONTRACT_ADDRESS"; pub const MULTISIG_CONTRACT_ADDRESS: &str = "MULTISIG_CONTRACT_ADDRESS";
pub const COCONUT_DKG_CONTRACT_ADDRESS: &str = "COCONUT_DKG_CONTRACT_ADDRESS"; pub const COCONUT_DKG_CONTRACT_ADDRESS: &str = "COCONUT_DKG_CONTRACT_ADDRESS";
pub const EPHEMERA_CONTRACT_ADDRESS: &str = "EPHEMERA_CONTRACT_ADDRESS";
pub const REWARDING_VALIDATOR_ADDRESS: &str = "REWARDING_VALIDATOR_ADDRESS"; pub const REWARDING_VALIDATOR_ADDRESS: &str = "REWARDING_VALIDATOR_ADDRESS";
pub const STATISTICS_SERVICE_DOMAIN_ADDRESS: &str = "STATISTICS_SERVICE_DOMAIN_ADDRESS"; pub const STATISTICS_SERVICE_DOMAIN_ADDRESS: &str = "STATISTICS_SERVICE_DOMAIN_ADDRESS";
pub const SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS: &str = pub const SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS: &str =
+1 -1
View File
@@ -8,7 +8,7 @@ license.workspace = true
[dependencies] [dependencies]
futures = { workspace = true } futures = { workspace = true }
rand = "0.7.3" rand = { workspace = true }
serde = { workspace = true } serde = { workspace = true }
serde_json = { workspace = true } serde_json = { workspace = true }
+2 -2
View File
@@ -41,7 +41,7 @@ impl<'a> From<&'a mix::Node> for TestableNode {
fn from(value: &'a mix::Node) -> Self { fn from(value: &'a mix::Node) -> Self {
TestableNode { TestableNode {
encoded_identity: value.identity_key.to_base58_string(), encoded_identity: value.identity_key.to_base58_string(),
owner: value.owner.clone(), owner: value.owner.as_ref().cloned().unwrap_or_default(),
typ: NodeType::Mixnode { typ: NodeType::Mixnode {
mix_id: value.mix_id, mix_id: value.mix_id,
}, },
@@ -53,7 +53,7 @@ impl<'a> From<&'a gateway::Node> for TestableNode {
fn from(value: &'a gateway::Node) -> Self { fn from(value: &'a gateway::Node) -> Self {
TestableNode { TestableNode {
encoded_identity: value.identity_key.to_base58_string(), encoded_identity: value.identity_key.to_base58_string(),
owner: value.owner.clone(), owner: value.owner.as_ref().cloned().unwrap_or_default(),
typ: NodeType::Gateway, typ: NodeType::Gateway,
} }
} }
+1 -1
View File
@@ -9,7 +9,7 @@ repository = { workspace = true }
[dependencies] [dependencies]
log = { workspace = true } log = { workspace = true }
rand = { version = "0.7.3", features = ["wasm-bindgen"] } rand = { workspace = true }
rand_distr = { workspace = true } rand_distr = { workspace = true }
thiserror = { workspace = true } thiserror = { workspace = true }
+1 -1
View File
@@ -8,7 +8,7 @@ license = { workspace = true }
repository = { workspace = true } repository = { workspace = true }
[dependencies] [dependencies]
rand = { version = "0.7.3", features = ["wasm-bindgen"] } rand = { workspace = true }
serde_crate = { version = "1.0", optional = true, default_features = false, features = ["derive"], package = "serde" } serde_crate = { version = "1.0", optional = true, default_features = false, features = ["derive"], package = "serde" }
generic-array = { workspace = true, optional = true, features = ["serde"] } generic-array = { workspace = true, optional = true, features = ["serde"] }
thiserror = { workspace = true } thiserror = { workspace = true }
+1 -1
View File
@@ -14,5 +14,5 @@ serde = { workspace = true } # implementing serialization/deserialization for so
thiserror = { workspace = true } thiserror = { workspace = true }
[dev-dependencies] [dev-dependencies]
rand = "0.7" rand = "0.8.5"
nym-crypto = { path = "../../crypto", features = ["rand"] } nym-crypto = { path = "../../crypto", features = ["rand"] }

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