Compare commits
50 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b6617eb34c | |||
| f43a2a1e42 | |||
| 4666e91820 | |||
| 7d0a25d570 | |||
| bb46235b54 | |||
| 70fa41c165 | |||
| 065d416305 | |||
| 3e93d2a250 | |||
| 8bc85191d5 | |||
| 102a8a0d8b | |||
| ae28a45915 | |||
| cffb8d98af | |||
| a40c2239d7 | |||
| 5a990a58ff | |||
| 2a1d37dd22 | |||
| be79042a23 | |||
| 7019dcc11f | |||
| bab842d277 | |||
| a374bca601 | |||
| d4d3041816 | |||
| 3acf521fc1 | |||
| 70766b6d3e | |||
| 437c66ad0b | |||
| 1afcfb0842 | |||
| 759e2fa2c5 | |||
| 489914fb42 | |||
| bca8992115 | |||
| f94d900d18 | |||
| dab55a12c7 | |||
| 82f722936f | |||
| 7f08020d4f | |||
| 579e41d57e | |||
| 06953298eb | |||
| 1d78f8747f | |||
| a6e9414cb8 | |||
| 23d7230d33 | |||
| 496f172070 | |||
| b617729873 | |||
| c5e1ea289c | |||
| 266c98a80e | |||
| 4540b3b41a | |||
| a9beb13189 | |||
| ebc30ec248 | |||
| 3cd9c6ad13 | |||
| b83d4e964b | |||
| bceb59a832 | |||
| 50a48603e3 | |||
| 1ae718c345 | |||
| 12c4450527 | |||
| 5bf34950ab |
@@ -1,9 +1,43 @@
|
||||
# Description
|
||||
|
||||
Closes: #XXXX
|
||||
<!-- Please include a summary of the change and which issue is fixed. Also include relevant motivation and context. List any dependencies that are required for this change. -->
|
||||
|
||||
<!-- If appropriate, insert relevant description here -->
|
||||
Fixes # (issue)
|
||||
|
||||
# Checklist:
|
||||
## Type of Change
|
||||
|
||||
- [ ] added a changelog entry to `CHANGELOG.md`
|
||||
Please delete options that are not relevant.
|
||||
|
||||
- [ ] Bug fix (non-breaking change which fixes an issue)
|
||||
- [ ] New feature (non-breaking change which adds functionality)
|
||||
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
||||
- [ ] Documentation update
|
||||
|
||||
## How Has This Been Tested?
|
||||
|
||||
<!-- Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration -->
|
||||
|
||||
- [ ] Test A
|
||||
- [ ] Test B
|
||||
|
||||
**Test Configuration**:
|
||||
* Component:
|
||||
* Chain:
|
||||
* Binaries:
|
||||
* SDK:
|
||||
|
||||
## Checklist:
|
||||
|
||||
- [ ] My code follows the style guidelines of this project
|
||||
- [ ] I have performed a self-review of my own code
|
||||
- [ ] I have commented my code, particularly in hard-to-understand areas
|
||||
- [ ] I have made corresponding changes to the documentation
|
||||
- [ ] My changes generate no new warnings
|
||||
- [ ] I have added tests that prove my fix is effective or that my feature works
|
||||
- [ ] New and existing unit tests pass locally with my changes
|
||||
- [ ] I have added a changelog entry to `CHANGELOG.md`
|
||||
- [ ] I have checked my code and corrected any misspellings
|
||||
|
||||
## Additional Notes
|
||||
|
||||
<!-- Any other notes (e.g. discussions, concerns, etc) you want to include -->
|
||||
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
- name: Install Rust stable
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
toolchain: 1.77
|
||||
target: wasm32-unknown-unknown
|
||||
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/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/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
|
||||
continue-on-error: true
|
||||
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
- uses: rlespinasse/github-slug-action@v3.x
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: 18.17
|
||||
- name: Install Rust stable
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
|
||||
@@ -4,6 +4,45 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
||||
|
||||
## [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)
|
||||
|
||||
- [fix] apply disable_poisson_rate from internal NR/IPR cfgs ([#4579])
|
||||
|
||||
Generated
+109
-220
@@ -43,19 +43,6 @@ dependencies = [
|
||||
"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]]
|
||||
name = "aes"
|
||||
version = "0.8.4"
|
||||
@@ -63,7 +50,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cipher 0.4.4",
|
||||
"cipher",
|
||||
"cpufeatures",
|
||||
]
|
||||
|
||||
@@ -74,9 +61,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1"
|
||||
dependencies = [
|
||||
"aead",
|
||||
"aes 0.8.4",
|
||||
"cipher 0.4.4",
|
||||
"ctr 0.9.2",
|
||||
"aes",
|
||||
"cipher",
|
||||
"ctr",
|
||||
"ghash",
|
||||
"subtle 2.5.0",
|
||||
]
|
||||
@@ -537,7 +524,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e141fb0f8be1c7b45887af94c88b182472b57c96b56773250ae00cd6a14a164"
|
||||
dependencies = [
|
||||
"bs58 0.5.1",
|
||||
"hmac 0.12.1",
|
||||
"hmac",
|
||||
"k256",
|
||||
"once_cell",
|
||||
"pbkdf2",
|
||||
@@ -599,7 +586,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330"
|
||||
dependencies = [
|
||||
"byte-tools",
|
||||
"crypto-mac 0.7.0",
|
||||
"crypto-mac",
|
||||
"digest 0.8.1",
|
||||
"opaque-debug 0.2.3",
|
||||
]
|
||||
@@ -827,7 +814,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cipher 0.4.4",
|
||||
"cipher",
|
||||
"cpufeatures",
|
||||
]
|
||||
|
||||
@@ -839,7 +826,7 @@ checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35"
|
||||
dependencies = [
|
||||
"aead",
|
||||
"chacha20",
|
||||
"cipher 0.4.4",
|
||||
"cipher",
|
||||
"poly1305",
|
||||
"zeroize",
|
||||
]
|
||||
@@ -886,15 +873,6 @@ dependencies = [
|
||||
"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]]
|
||||
name = "cipher"
|
||||
version = "0.4.4"
|
||||
@@ -1188,7 +1166,7 @@ dependencies = [
|
||||
"rand_core 0.6.4",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"signature 2.2.0",
|
||||
"signature",
|
||||
"subtle-encoding",
|
||||
"tendermint",
|
||||
"thiserror",
|
||||
@@ -1207,7 +1185,7 @@ dependencies = [
|
||||
"rand_core 0.6.4",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"signature 2.2.0",
|
||||
"signature",
|
||||
"subtle-encoding",
|
||||
"tendermint",
|
||||
"tendermint-rpc",
|
||||
@@ -1473,16 +1451,6 @@ dependencies = [
|
||||
"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]]
|
||||
name = "csv"
|
||||
version = "1.3.0"
|
||||
@@ -1504,22 +1472,13 @@ dependencies = [
|
||||
"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]]
|
||||
name = "ctr"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835"
|
||||
dependencies = [
|
||||
"cipher 0.4.4",
|
||||
"cipher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1571,7 +1530,6 @@ dependencies = [
|
||||
"byteorder",
|
||||
"digest 0.9.0",
|
||||
"rand_core 0.5.1",
|
||||
"serde",
|
||||
"subtle 2.5.0",
|
||||
"zeroize",
|
||||
]
|
||||
@@ -1585,9 +1543,11 @@ dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"curve25519-dalek-derive",
|
||||
"digest 0.10.7",
|
||||
"fiat-crypto",
|
||||
"platforms",
|
||||
"rustc_version 0.4.0",
|
||||
"serde",
|
||||
"subtle 2.5.0",
|
||||
"zeroize",
|
||||
]
|
||||
@@ -1804,8 +1764,9 @@ checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2"
|
||||
|
||||
[[package]]
|
||||
name = "defguard_wireguard_rs"
|
||||
version = "0.3.0"
|
||||
source = "git+https://github.com/neacsu/wireguard-rs.git?rev=c2cd0c1119f699f4bc43f5e6ffd6fc242caa42ed#c2cd0c1119f699f4bc43f5e6ffd6fc242caa42ed"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ba16f17698d4b389907310af018b0c3a80b025bba9c38d947cbc6dd70921743"
|
||||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"libc",
|
||||
@@ -1985,20 +1946,10 @@ dependencies = [
|
||||
"elliptic-curve",
|
||||
"rfc6979",
|
||||
"serdect",
|
||||
"signature 2.2.0",
|
||||
"signature",
|
||||
"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]]
|
||||
name = "ed25519"
|
||||
version = "2.2.3"
|
||||
@@ -2006,7 +1957,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53"
|
||||
dependencies = [
|
||||
"pkcs8",
|
||||
"signature 2.2.0",
|
||||
"serde",
|
||||
"signature",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2024,16 +1976,16 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ed25519-dalek"
|
||||
version = "1.0.1"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d"
|
||||
checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871"
|
||||
dependencies = [
|
||||
"curve25519-dalek 3.2.0",
|
||||
"ed25519 1.5.3",
|
||||
"rand 0.7.3",
|
||||
"curve25519-dalek 4.1.2",
|
||||
"ed25519",
|
||||
"rand_core 0.6.4",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
"sha2 0.9.9",
|
||||
"sha2 0.10.8",
|
||||
"subtle 2.5.0",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
@@ -2825,33 +2777,13 @@ dependencies = [
|
||||
"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]]
|
||||
name = "hkdf"
|
||||
version = "0.12.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7"
|
||||
dependencies = [
|
||||
"hmac 0.12.1",
|
||||
]
|
||||
|
||||
[[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",
|
||||
"hmac",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3409,7 +3341,7 @@ dependencies = [
|
||||
"elliptic-curve",
|
||||
"once_cell",
|
||||
"sha2 0.10.8",
|
||||
"signature 2.2.0",
|
||||
"signature",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3688,7 +3620,7 @@ dependencies = [
|
||||
"nym-ordered-buffer",
|
||||
"nym-service-providers-common",
|
||||
"nym-socks5-requests",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde-wasm-bindgen 0.6.5",
|
||||
"thiserror",
|
||||
@@ -3929,7 +3861,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-api"
|
||||
version = "1.1.37"
|
||||
version = "1.1.38"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -3966,11 +3898,9 @@ dependencies = [
|
||||
"nym-inclusion-probability",
|
||||
"nym-mixnet-contract-common",
|
||||
"nym-multisig-contract-common",
|
||||
"nym-name-service-common",
|
||||
"nym-node-requests",
|
||||
"nym-node-tester-utils",
|
||||
"nym-pemstore",
|
||||
"nym-service-provider-directory-common",
|
||||
"nym-sphinx",
|
||||
"nym-task",
|
||||
"nym-topology",
|
||||
@@ -3978,9 +3908,7 @@ dependencies = [
|
||||
"nym-vesting-contract-common",
|
||||
"okapi",
|
||||
"pin-project",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"rand_chacha 0.2.2",
|
||||
"rand_chacha 0.3.1",
|
||||
"reqwest 0.12.4",
|
||||
"rocket",
|
||||
@@ -4017,6 +3945,7 @@ dependencies = [
|
||||
"nym-node-requests",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tendermint",
|
||||
"time",
|
||||
"ts-rs",
|
||||
@@ -4045,7 +3974,7 @@ dependencies = [
|
||||
"nym-crypto",
|
||||
"nym-network-defaults",
|
||||
"nym-validator-client",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"thiserror",
|
||||
"url",
|
||||
"zeroize",
|
||||
@@ -4091,7 +4020,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-cli"
|
||||
version = "1.1.35"
|
||||
version = "1.1.36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64 0.13.1",
|
||||
@@ -4150,10 +4079,8 @@ dependencies = [
|
||||
"nym-id",
|
||||
"nym-mixnet-contract-common",
|
||||
"nym-multisig-contract-common",
|
||||
"nym-name-service-common",
|
||||
"nym-network-defaults",
|
||||
"nym-pemstore",
|
||||
"nym-service-provider-directory-common",
|
||||
"nym-sphinx",
|
||||
"nym-types",
|
||||
"nym-validator-client",
|
||||
@@ -4172,7 +4099,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-client"
|
||||
version = "1.1.34"
|
||||
version = "1.1.35"
|
||||
dependencies = [
|
||||
"bs58 0.5.1",
|
||||
"clap 4.5.4",
|
||||
@@ -4195,7 +4122,7 @@ dependencies = [
|
||||
"nym-task",
|
||||
"nym-topology",
|
||||
"nym-validator-client",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tap",
|
||||
@@ -4243,7 +4170,7 @@ dependencies = [
|
||||
"nym-task",
|
||||
"nym-topology",
|
||||
"nym-validator-client",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2 0.10.8",
|
||||
@@ -4323,7 +4250,7 @@ dependencies = [
|
||||
"nym-bin-common",
|
||||
"nym-node-tester-utils",
|
||||
"nym-node-tester-wasm",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde-wasm-bindgen 0.6.5",
|
||||
"serde_json",
|
||||
@@ -4466,7 +4393,7 @@ dependencies = [
|
||||
"nym-credentials-interface",
|
||||
"nym-crypto",
|
||||
"nym-validator-client",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"time",
|
||||
@@ -4487,25 +4414,25 @@ dependencies = [
|
||||
name = "nym-crypto"
|
||||
version = "0.4.0"
|
||||
dependencies = [
|
||||
"aes 0.8.4",
|
||||
"aes",
|
||||
"blake3",
|
||||
"bs58 0.5.1",
|
||||
"cipher 0.4.4",
|
||||
"ctr 0.9.2",
|
||||
"cipher",
|
||||
"ctr",
|
||||
"digest 0.10.7",
|
||||
"ed25519-dalek",
|
||||
"generic-array 0.14.7",
|
||||
"hkdf 0.12.4",
|
||||
"hmac 0.12.1",
|
||||
"hkdf",
|
||||
"hmac",
|
||||
"nym-pemstore",
|
||||
"nym-sphinx-types",
|
||||
"rand 0.7.3",
|
||||
"rand_chacha 0.2.2",
|
||||
"rand 0.8.5",
|
||||
"rand_chacha 0.3.1",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
"subtle-encoding",
|
||||
"thiserror",
|
||||
"x25519-dalek 1.1.1",
|
||||
"x25519-dalek",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
@@ -4627,7 +4554,7 @@ dependencies = [
|
||||
"nym-wireguard",
|
||||
"nym-wireguard-types",
|
||||
"once_cell",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sqlx",
|
||||
@@ -4660,7 +4587,7 @@ dependencies = [
|
||||
"nym-sphinx",
|
||||
"nym-task",
|
||||
"nym-validator-client",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"si-scale",
|
||||
"thiserror",
|
||||
@@ -4689,7 +4616,7 @@ dependencies = [
|
||||
"nym-crypto",
|
||||
"nym-pemstore",
|
||||
"nym-sphinx",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
@@ -4780,6 +4707,7 @@ dependencies = [
|
||||
"bincode",
|
||||
"bytes",
|
||||
"nym-bin-common",
|
||||
"nym-crypto",
|
||||
"nym-sphinx",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
@@ -4824,6 +4752,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"tap",
|
||||
"thiserror",
|
||||
"time",
|
||||
"tokio",
|
||||
"tokio-tun",
|
||||
"tokio-util",
|
||||
@@ -4917,7 +4846,7 @@ dependencies = [
|
||||
"nym-topology",
|
||||
"nym-types",
|
||||
"nym-validator-client",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sysinfo 0.27.8",
|
||||
@@ -4974,20 +4903,6 @@ dependencies = [
|
||||
"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]]
|
||||
name = "nym-network-defaults"
|
||||
version = "0.1.0"
|
||||
@@ -5005,7 +4920,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-network-requester"
|
||||
version = "1.1.35"
|
||||
version = "1.1.36"
|
||||
dependencies = [
|
||||
"addr",
|
||||
"anyhow",
|
||||
@@ -5039,7 +4954,7 @@ dependencies = [
|
||||
"nym-types",
|
||||
"pretty_env_logger",
|
||||
"publicsuffix",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"regex",
|
||||
"reqwest 0.12.4",
|
||||
"serde",
|
||||
@@ -5074,7 +4989,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-node"
|
||||
version = "1.1.1"
|
||||
version = "1.1.2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bip39",
|
||||
@@ -5100,8 +5015,9 @@ dependencies = [
|
||||
"nym-sphinx-addressing",
|
||||
"nym-task",
|
||||
"nym-types",
|
||||
"nym-wireguard",
|
||||
"nym-wireguard-types",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"semver 1.0.23",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -5120,11 +5036,12 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"axum 0.7.5",
|
||||
"axum-extra",
|
||||
"base64 0.21.7",
|
||||
"colored",
|
||||
"dashmap",
|
||||
"fastrand 2.1.0",
|
||||
"headers",
|
||||
"hmac 0.12.1",
|
||||
"hmac",
|
||||
"hyper 1.3.1",
|
||||
"ipnetwork 0.16.0",
|
||||
"nym-crypto",
|
||||
@@ -5134,7 +5051,7 @@ dependencies = [
|
||||
"nym-task",
|
||||
"nym-wireguard",
|
||||
"nym-wireguard-types",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"time",
|
||||
@@ -5144,7 +5061,7 @@ dependencies = [
|
||||
"tracing",
|
||||
"utoipa",
|
||||
"utoipa-swagger-ui",
|
||||
"x25519-dalek 2.0.1",
|
||||
"x25519-dalek",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5161,7 +5078,7 @@ dependencies = [
|
||||
"nym-exit-policy",
|
||||
"nym-http-api-client",
|
||||
"nym-wireguard-types",
|
||||
"rand_chacha 0.2.2",
|
||||
"rand_chacha 0.3.1",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -5182,7 +5099,7 @@ dependencies = [
|
||||
"nym-sphinx-params",
|
||||
"nym-task",
|
||||
"nym-topology",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
@@ -5197,7 +5114,7 @@ dependencies = [
|
||||
"futures",
|
||||
"js-sys",
|
||||
"nym-node-tester-utils",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde-wasm-bindgen 0.6.5",
|
||||
"thiserror",
|
||||
@@ -5252,11 +5169,11 @@ dependencies = [
|
||||
"chacha20",
|
||||
"chacha20poly1305",
|
||||
"criterion",
|
||||
"curve25519-dalek 3.2.0",
|
||||
"curve25519-dalek 4.1.2",
|
||||
"fastrand 1.9.0",
|
||||
"getrandom 0.2.15",
|
||||
"log",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"rayon",
|
||||
"sphinx-packet",
|
||||
"thiserror",
|
||||
@@ -5304,7 +5221,7 @@ dependencies = [
|
||||
"nym-validator-client",
|
||||
"parking_lot 0.12.2",
|
||||
"pretty_env_logger",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"reqwest 0.12.4",
|
||||
"tap",
|
||||
"thiserror",
|
||||
@@ -5315,19 +5232,6 @@ dependencies = [
|
||||
"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]]
|
||||
name = "nym-service-providers-common"
|
||||
version = "0.1.0"
|
||||
@@ -5347,7 +5251,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-socks5-client"
|
||||
version = "1.1.34"
|
||||
version = "1.1.35"
|
||||
dependencies = [
|
||||
"bs58 0.5.1",
|
||||
"clap 4.5.4",
|
||||
@@ -5366,7 +5270,7 @@ dependencies = [
|
||||
"nym-socks5-client-core",
|
||||
"nym-sphinx",
|
||||
"nym-topology",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tap",
|
||||
@@ -5399,7 +5303,7 @@ dependencies = [
|
||||
"nym-task",
|
||||
"nym-validator-client",
|
||||
"pin-project",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"reqwest 0.12.4",
|
||||
"schemars",
|
||||
"serde",
|
||||
@@ -5425,7 +5329,7 @@ dependencies = [
|
||||
"nym-credential-storage",
|
||||
"nym-crypto",
|
||||
"nym-socks5-client-core",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"safer-ffi",
|
||||
"serde",
|
||||
"tokio",
|
||||
@@ -5479,7 +5383,7 @@ dependencies = [
|
||||
"nym-sphinx-routing",
|
||||
"nym-sphinx-types",
|
||||
"nym-topology",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"rand_distr",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
@@ -5497,7 +5401,7 @@ dependencies = [
|
||||
"nym-sphinx-routing",
|
||||
"nym-sphinx-types",
|
||||
"nym-topology",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"zeroize",
|
||||
@@ -5509,7 +5413,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"nym-crypto",
|
||||
"nym-sphinx-types",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"thiserror",
|
||||
]
|
||||
@@ -5525,8 +5429,8 @@ dependencies = [
|
||||
"nym-sphinx-routing",
|
||||
"nym-sphinx-types",
|
||||
"nym-topology",
|
||||
"rand 0.7.3",
|
||||
"rand_chacha 0.2.2",
|
||||
"rand 0.8.5",
|
||||
"rand_chacha 0.3.1",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"wasm-bindgen",
|
||||
@@ -5540,7 +5444,7 @@ dependencies = [
|
||||
"nym-sphinx-addressing",
|
||||
"nym-sphinx-params",
|
||||
"nym-sphinx-types",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
@@ -5557,7 +5461,7 @@ dependencies = [
|
||||
"nym-sphinx-routing",
|
||||
"nym-sphinx-types",
|
||||
"nym-topology",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
@@ -5668,7 +5572,7 @@ dependencies = [
|
||||
"nym-sphinx-addressing",
|
||||
"nym-sphinx-routing",
|
||||
"nym-sphinx-types",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"semver 0.11.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -5698,7 +5602,7 @@ dependencies = [
|
||||
"cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)",
|
||||
"cosmwasm-std",
|
||||
"eyre",
|
||||
"hmac 0.12.1",
|
||||
"hmac",
|
||||
"itertools 0.11.0",
|
||||
"log",
|
||||
"nym-config",
|
||||
@@ -5716,7 +5620,7 @@ dependencies = [
|
||||
"thiserror",
|
||||
"ts-rs",
|
||||
"url",
|
||||
"x25519-dalek 2.0.1",
|
||||
"x25519-dalek",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5751,9 +5655,7 @@ dependencies = [
|
||||
"nym-http-api-client",
|
||||
"nym-mixnet-contract-common",
|
||||
"nym-multisig-contract-common",
|
||||
"nym-name-service-common",
|
||||
"nym-network-defaults",
|
||||
"nym-service-provider-directory-common",
|
||||
"nym-vesting-contract-common",
|
||||
"prost 0.12.4",
|
||||
"reqwest 0.12.4",
|
||||
@@ -5841,14 +5743,16 @@ name = "nym-wireguard"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"dashmap",
|
||||
"defguard_wireguard_rs",
|
||||
"ip_network",
|
||||
"log",
|
||||
"nym-crypto",
|
||||
"nym-network-defaults",
|
||||
"nym-task",
|
||||
"nym-wireguard-types",
|
||||
"tokio",
|
||||
"x25519-dalek 2.0.1",
|
||||
"x25519-dalek",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5857,21 +5761,23 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"dashmap",
|
||||
"hmac 0.12.1",
|
||||
"hmac",
|
||||
"log",
|
||||
"nym-config",
|
||||
"nym-crypto",
|
||||
"rand 0.7.3",
|
||||
"nym-network-defaults",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2 0.10.8",
|
||||
"thiserror",
|
||||
"utoipa",
|
||||
"x25519-dalek 2.0.1",
|
||||
"x25519-dalek",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nymvisor"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@@ -6190,7 +6096,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2"
|
||||
dependencies = [
|
||||
"digest 0.10.7",
|
||||
"hmac 0.12.1",
|
||||
"hmac",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6749,12 +6655,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rand_distr"
|
||||
version = "0.3.0"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c9e9532ada3929fb8b2e9dbe28d1e06c9b2cc65813f074fcb6bd5fbefeff9d56"
|
||||
checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7068,7 +6974,7 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2"
|
||||
dependencies = [
|
||||
"hmac 0.12.1",
|
||||
"hmac",
|
||||
"subtle 2.5.0",
|
||||
]
|
||||
|
||||
@@ -7860,12 +7766,6 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signature"
|
||||
version = "1.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c"
|
||||
|
||||
[[package]]
|
||||
name = "signature"
|
||||
version = "2.2.0"
|
||||
@@ -7936,25 +7836,26 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sphinx-packet"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc43eda802856ee82a7555c7b75ceb9e07451741c7a2f5f23d036020e01189d4"
|
||||
checksum = "dabeca95bf5fd0563d6be7ebcb1c6a9fcb135746a0ba9050c47dc68c8607e595"
|
||||
dependencies = [
|
||||
"aes 0.7.5",
|
||||
"aes",
|
||||
"arrayref",
|
||||
"blake2 0.8.1",
|
||||
"bs58 0.4.0",
|
||||
"bs58 0.5.1",
|
||||
"byteorder",
|
||||
"chacha",
|
||||
"curve25519-dalek 3.2.0",
|
||||
"digest 0.9.0",
|
||||
"hkdf 0.11.0",
|
||||
"hmac 0.11.0",
|
||||
"ctr",
|
||||
"curve25519-dalek 4.1.2",
|
||||
"digest 0.10.7",
|
||||
"hkdf",
|
||||
"hmac",
|
||||
"lioness",
|
||||
"log",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"rand_distr",
|
||||
"sha2 0.9.9",
|
||||
"sha2 0.10.8",
|
||||
"subtle 2.5.0",
|
||||
]
|
||||
|
||||
@@ -8345,7 +8246,7 @@ checksum = "15ab8f0a25d0d2ad49ac615da054d6a76aa6603ff95f7d18bafdd34450a1a04b"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"digest 0.10.7",
|
||||
"ed25519 2.2.3",
|
||||
"ed25519",
|
||||
"ed25519-consensus",
|
||||
"flex-error",
|
||||
"futures",
|
||||
@@ -8360,7 +8261,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"serde_repr",
|
||||
"sha2 0.10.8",
|
||||
"signature 2.2.0",
|
||||
"signature",
|
||||
"subtle 2.5.0",
|
||||
"subtle-encoding",
|
||||
"tendermint-proto",
|
||||
@@ -9496,7 +9397,7 @@ dependencies = [
|
||||
"nym-task",
|
||||
"nym-topology",
|
||||
"nym-validator-client",
|
||||
"rand 0.7.3",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde-wasm-bindgen 0.6.5",
|
||||
"thiserror",
|
||||
@@ -9952,18 +9853,6 @@ dependencies = [
|
||||
"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]]
|
||||
name = "x25519-dalek"
|
||||
version = "2.0.1"
|
||||
|
||||
+6
-8
@@ -39,8 +39,6 @@ members = [
|
||||
"common/cosmwasm-smart-contracts/group-contract",
|
||||
"common/cosmwasm-smart-contracts/mixnet-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/country-group",
|
||||
"common/credential-storage",
|
||||
@@ -172,7 +170,7 @@ bincode = "1.3.3"
|
||||
bip39 = { version = "2.0.0", features = ["zeroize"] }
|
||||
bitvec = "1.0.0"
|
||||
blake3 = "1.3.1"
|
||||
bs58 = "0.5.0"
|
||||
bs58 = "0.5.1"
|
||||
bytecodec = "0.4.15"
|
||||
bytes = "1.5.0"
|
||||
cargo_metadata = "0.18.1"
|
||||
@@ -195,13 +193,13 @@ criterion = "0.4"
|
||||
csv = "1.3.0"
|
||||
ctr = "0.9.1"
|
||||
cupid = "0.6.1"
|
||||
curve25519-dalek = "3.2"
|
||||
curve25519-dalek = "4.1"
|
||||
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"
|
||||
dotenvy = "0.15.6"
|
||||
ecdsa = "0.16"
|
||||
ed25519-dalek = "1.0"
|
||||
ed25519-dalek = "2.1"
|
||||
etherparse = "0.13.0"
|
||||
eyre = "0.6.9"
|
||||
flate2 = "1.0.28"
|
||||
@@ -247,7 +245,7 @@ rand = "0.8.5"
|
||||
rand-07 = "0.7.3"
|
||||
rand_chacha_02 = "0.2"
|
||||
rand_core = "0.6.3"
|
||||
rand_distr = "0.3"
|
||||
rand_distr = "0.4"
|
||||
rand_pcg = "0.3.1"
|
||||
rand_seeder = "0.2.3"
|
||||
rayon = "1.5.1"
|
||||
@@ -266,7 +264,7 @@ serde_repr = "0.1"
|
||||
serde_with = "3.4.0"
|
||||
serde_yaml = "0.9.25"
|
||||
si-scale = "0.2.2"
|
||||
sphinx-packet = "0.1.0"
|
||||
sphinx-packet = "0.1.1"
|
||||
sqlx = "0.6.3"
|
||||
strum = "0.25"
|
||||
subtle-encoding = "0.5"
|
||||
|
||||
@@ -134,7 +134,7 @@ clippy: sdk-wasm-lint
|
||||
# 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_OUT_DIR=contracts/target/wasm32-unknown-unknown/release
|
||||
|
||||
@@ -186,4 +186,4 @@ deb-gateway: build-nym-gateway
|
||||
deb-cli: build-nym-cli
|
||||
cargo deb -p nym-cli
|
||||
|
||||
deb: deb-mixnode deb-gateway deb-cli
|
||||
deb: deb-mixnode deb-gateway deb-cli
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
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>"]
|
||||
description = "Implementation of the Nym Client"
|
||||
edition = "2021"
|
||||
@@ -25,7 +25,7 @@ bs58 = { workspace = true }
|
||||
clap = { workspace = true, features = ["cargo", "derive"] }
|
||||
dirs = "4.0"
|
||||
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_json = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-socks5-client"
|
||||
version = "1.1.34"
|
||||
version = "1.1.35"
|
||||
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"
|
||||
edition = "2021"
|
||||
@@ -16,7 +16,7 @@ serde_json = { workspace = true }
|
||||
tap = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
tokio = { workspace = true, features = ["rt-multi-thread", "net", "signal"] }
|
||||
rand = "0.7.3"
|
||||
rand = { workspace = true }
|
||||
time = { workspace = true }
|
||||
url = { workspace = true }
|
||||
zeroize = { workspace = true }
|
||||
|
||||
@@ -9,7 +9,7 @@ license.workspace = true
|
||||
[dependencies]
|
||||
bip39 = { workspace = true }
|
||||
log = { workspace = true }
|
||||
rand = "0.7.3"
|
||||
rand = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
url = { workspace = true }
|
||||
zeroize = { workspace = true }
|
||||
|
||||
@@ -17,7 +17,7 @@ clap = { workspace = true, optional = true }
|
||||
futures = { workspace = true }
|
||||
humantime-serde = { workspace = true }
|
||||
log = { workspace = true }
|
||||
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
|
||||
rand = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json = { workspace = true }
|
||||
sha2 = "0.10.6"
|
||||
|
||||
@@ -14,7 +14,7 @@ futures = { workspace = true }
|
||||
log = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
url = { workspace = true }
|
||||
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
|
||||
rand = { workspace = true }
|
||||
tokio = { workspace = true, features = ["macros"] }
|
||||
si-scale = { workspace = true }
|
||||
time.workspace = true
|
||||
|
||||
@@ -220,9 +220,18 @@ impl<C, St> GatewayClient<C, St> {
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
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 {
|
||||
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));
|
||||
|
||||
@@ -23,6 +23,9 @@ pub enum GatewayClientError {
|
||||
#[error("There was a network error: {0}")]
|
||||
NetworkErrorWasm(#[from] JsError),
|
||||
|
||||
#[error("connection failed: {address}: {source}")]
|
||||
NetworkConnectionFailed { address: String, source: WsError },
|
||||
|
||||
#[error("Invalid URL: {0}")]
|
||||
InvalidURL(String),
|
||||
|
||||
|
||||
@@ -19,9 +19,7 @@ nym-mixnet-contract-common = { path = "../../cosmwasm-smart-contracts/mixnet-con
|
||||
nym-vesting-contract-common = { path = "../../cosmwasm-smart-contracts/vesting-contract" }
|
||||
nym-coconut-bandwidth-contract-common = { path = "../../cosmwasm-smart-contracts/coconut-bandwidth-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-service-provider-directory-common = { path = "../../cosmwasm-smart-contracts/service-provider-directory" }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json = { workspace = true }
|
||||
nym-http-api-client = { path = "../../../common/http-api-client"}
|
||||
@@ -86,14 +84,6 @@ name = "offline_signing"
|
||||
# (traits would need to be moved around and refactored themselves)
|
||||
required-features = ["http-client"]
|
||||
|
||||
[[example]]
|
||||
name = "query_service_provider_directory"
|
||||
required-features = ["http-client"]
|
||||
|
||||
[[example]]
|
||||
name = "query_name_service"
|
||||
required-features = ["http-client"]
|
||||
|
||||
[features]
|
||||
default = ["http-client"]
|
||||
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:#?}");
|
||||
}
|
||||
@@ -25,8 +25,6 @@ pub use nym_coconut_dkg_common::types::EpochId;
|
||||
use nym_http_api_client::{ApiClient, NO_PARAMS};
|
||||
use nym_mixnet_contract_common::mixnode::MixNodeDetails;
|
||||
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 routes;
|
||||
@@ -492,19 +490,6 @@ pub trait NymApiClientExt: ApiClient {
|
||||
)
|
||||
.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))]
|
||||
|
||||
@@ -40,4 +40,3 @@ pub const STAKE_SATURATION: &str = "stake-saturation";
|
||||
pub const INCLUSION_CHANCE: &str = "inclusion-probability";
|
||||
|
||||
pub const SERVICE_PROVIDERS: &str = "services";
|
||||
pub const REGISTERED_NAMES: &str = "names";
|
||||
|
||||
@@ -14,8 +14,6 @@ pub mod ephemera_query_client;
|
||||
pub mod group_query_client;
|
||||
pub mod mixnet_query_client;
|
||||
pub mod multisig_query_client;
|
||||
pub mod name_service_query_client;
|
||||
pub mod sp_directory_query_client;
|
||||
pub mod vesting_query_client;
|
||||
|
||||
// signing clients
|
||||
@@ -25,8 +23,6 @@ pub mod ephemera_signing_client;
|
||||
pub mod group_signing_client;
|
||||
pub mod mixnet_signing_client;
|
||||
pub mod multisig_signing_client;
|
||||
pub mod name_service_signing_client;
|
||||
pub mod sp_directory_signing_client;
|
||||
pub mod vesting_signing_client;
|
||||
|
||||
// re-export query traits
|
||||
@@ -38,8 +34,6 @@ pub use ephemera_query_client::{EphemeraQueryClient, PagedEphemeraQueryClient};
|
||||
pub use group_query_client::{GroupQueryClient, PagedGroupQueryClient};
|
||||
pub use mixnet_query_client::{MixnetQueryClient, PagedMixnetQueryClient};
|
||||
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};
|
||||
|
||||
// re-export signing traits
|
||||
@@ -49,8 +43,6 @@ pub use ephemera_signing_client::EphemeraSigningClient;
|
||||
pub use group_signing_client::GroupSigningClient;
|
||||
pub use mixnet_signing_client::MixnetSigningClient;
|
||||
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;
|
||||
|
||||
// helper for providing blanket implementation for query clients
|
||||
@@ -67,10 +59,6 @@ pub trait NymContractsProvider {
|
||||
|
||||
// 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)]
|
||||
@@ -84,9 +72,6 @@ pub struct TypedNymContracts {
|
||||
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 {
|
||||
@@ -122,14 +107,6 @@ impl TryFrom<NymContracts> for TypedNymContracts {
|
||||
.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()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
-144
@@ -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()
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
-138
@@ -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(),
|
||||
};
|
||||
}
|
||||
}
|
||||
-142
@@ -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(),
|
||||
};
|
||||
}
|
||||
}
|
||||
-148
@@ -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(),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -246,12 +246,6 @@ impl<C, S> NyxdClient<C, S> {
|
||||
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) {
|
||||
self.config.simulated_gas_multiplier = multiplier;
|
||||
}
|
||||
@@ -288,17 +282,6 @@ impl<C, S> NymContractsProvider for NyxdClient<C, S> {
|
||||
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
|
||||
|
||||
@@ -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-dkg-common = { path = "../cosmwasm-smart-contracts/coconut-dkg" }
|
||||
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-client-core = { path = "../../common/client-core" }
|
||||
nym-config = { path = "../../common/config" }
|
||||
|
||||
@@ -6,8 +6,6 @@ use clap::{Args, Subcommand};
|
||||
pub mod gateway;
|
||||
pub mod identity_key;
|
||||
pub mod mixnode;
|
||||
pub mod name;
|
||||
pub mod service;
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)]
|
||||
@@ -23,10 +21,6 @@ pub enum MixnetOperatorsCommands {
|
||||
Mixnode(mixnode::MixnetOperatorsMixnode),
|
||||
/// Manage your gateway
|
||||
Gateway(gateway::MixnetOperatorsGateway),
|
||||
/// Manage your service
|
||||
ServiceProvider(service::MixnetOperatorsService),
|
||||
/// Manage your registered name
|
||||
Name(name::MixnetOperatorsName),
|
||||
/// Sign messages using your private identity key
|
||||
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_mixnodes;
|
||||
pub mod query_all_names;
|
||||
pub mod query_all_service_providers;
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)]
|
||||
@@ -21,8 +19,4 @@ pub enum MixnetQueryCommands {
|
||||
Mixnodes(query_all_mixnodes::Args),
|
||||
/// Query gateways
|
||||
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),
|
||||
}
|
||||
}
|
||||
@@ -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}")
|
||||
}
|
||||
}
|
||||
@@ -23,5 +23,5 @@ nym-api-requests = { path = "../../nym-api/nym-api-requests" }
|
||||
nym-validator-client = { path = "../client-libs/validator-client", default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
rand = "0.7.3"
|
||||
rand = "0.8.5"
|
||||
|
||||
|
||||
@@ -17,10 +17,10 @@ generic-array = { workspace = true, optional = true }
|
||||
hkdf = { workspace = true, optional = true }
|
||||
hmac = { workspace = true, optional = true }
|
||||
cipher = { workspace = true, optional = true }
|
||||
x25519-dalek = { version = "1.1", optional = true }
|
||||
ed25519-dalek = { workspace = true, optional = true }
|
||||
rand = { version = "0.7.3", features = ["wasm-bindgen"], optional = true }
|
||||
serde_bytes = { workspace = true, optional = true }
|
||||
x25519-dalek = { version = "2.0", optional = true, features = ["static_secrets"]}
|
||||
ed25519-dalek = { version = "2.1", features = ["rand_core"], optional = true }
|
||||
rand = { 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" }
|
||||
subtle-encoding = { workspace = true, features = ["bech32-preview"] }
|
||||
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" }
|
||||
|
||||
[dev-dependencies]
|
||||
rand_chacha = "0.2"
|
||||
rand_chacha = "0.3"
|
||||
|
||||
[features]
|
||||
default = ["sphinx"]
|
||||
|
||||
@@ -56,7 +56,7 @@ pub struct KeyPair {
|
||||
impl KeyPair {
|
||||
#[cfg(feature = "rand")]
|
||||
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();
|
||||
|
||||
KeyPair {
|
||||
@@ -211,7 +211,7 @@ impl FromStr for PrivateKey {
|
||||
impl PrivateKey {
|
||||
#[cfg(feature = "rand")]
|
||||
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)
|
||||
}
|
||||
@@ -358,16 +358,23 @@ mod sphinx_key_conversion {
|
||||
let private = &keys.private_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 sphinx_private: nym_sphinx_types::PrivateKey = private.into();
|
||||
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 recovered_public = PublicKey::from(sphinx_public);
|
||||
assert_eq!(private_bytes, recovered_private.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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
pub use ed25519_dalek::ed25519::signature::Signature as SignatureTrait;
|
||||
pub use ed25519_dalek::SignatureError;
|
||||
use ed25519_dalek::{Signer, SigningKey};
|
||||
pub use ed25519_dalek::{Verifier, PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, SIGNATURE_LENGTH};
|
||||
use nym_pemstore::traits::{PemStorableKey, PemStorableKeyPair};
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
@@ -30,6 +30,9 @@ pub enum Ed25519RecoveryError {
|
||||
#[error(transparent)]
|
||||
MalformedBytes(#[from] SignatureError),
|
||||
|
||||
#[error(transparent)]
|
||||
BytesLengthError(#[from] std::array::TryFromSliceError),
|
||||
|
||||
#[error("the base58 representation of the public key was malformed - {source}")]
|
||||
MalformedPublicKeyString {
|
||||
#[source]
|
||||
@@ -64,11 +67,11 @@ pub struct KeyPair {
|
||||
impl KeyPair {
|
||||
#[cfg(feature = "rand")]
|
||||
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 {
|
||||
private_key: PrivateKey(ed25519_keypair.secret),
|
||||
public_key: PublicKey(ed25519_keypair.public),
|
||||
private_key: PrivateKey(ed25519_signing_key.to_bytes()),
|
||||
public_key: PublicKey(ed25519_signing_key.verifying_key()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +112,7 @@ impl PemStorableKeyPair for KeyPair {
|
||||
|
||||
/// ed25519 EdDSA Public Key
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub struct PublicKey(ed25519_dalek::PublicKey);
|
||||
pub struct PublicKey(ed25519_dalek::VerifyingKey);
|
||||
|
||||
impl Display for PublicKey {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
@@ -135,7 +138,9 @@ impl PublicKey {
|
||||
}
|
||||
|
||||
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 {
|
||||
@@ -189,7 +194,7 @@ impl<'d> Deserialize<'d> for PublicKey {
|
||||
where
|
||||
D: Deserializer<'d>,
|
||||
{
|
||||
Ok(PublicKey(ed25519_dalek::PublicKey::deserialize(
|
||||
Ok(PublicKey(ed25519_dalek::VerifyingKey::deserialize(
|
||||
deserializer,
|
||||
)?))
|
||||
}
|
||||
@@ -223,7 +228,7 @@ impl Display for PrivateKey {
|
||||
|
||||
impl<'a> From<&'a PrivateKey> for PublicKey {
|
||||
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 {
|
||||
#[cfg(feature = "rand")]
|
||||
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)
|
||||
}
|
||||
@@ -248,11 +253,11 @@ impl PrivateKey {
|
||||
}
|
||||
|
||||
pub fn to_bytes(&self) -> [u8; SECRET_KEY_LENGTH] {
|
||||
self.0.to_bytes()
|
||||
self.0
|
||||
}
|
||||
|
||||
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 {
|
||||
@@ -267,9 +272,8 @@ impl PrivateKey {
|
||||
}
|
||||
|
||||
pub fn sign<M: AsRef<[u8]>>(&self, message: M) -> Signature {
|
||||
let expanded_secret_key = ed25519_dalek::ExpandedSecretKey::from(&self.0);
|
||||
let public_key: PublicKey = self.into();
|
||||
let sig = expanded_secret_key.sign(message.as_ref(), &public_key.0);
|
||||
let signing_key: SigningKey = self.0.into();
|
||||
let sig = signing_key.sign(message.as_ref());
|
||||
Signature(sig)
|
||||
}
|
||||
|
||||
@@ -338,7 +342,9 @@ impl Signature {
|
||||
}
|
||||
|
||||
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()?,
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
|
||||
use crate::asymmetric::encryption;
|
||||
use crate::hkdf;
|
||||
#[cfg(feature = "rand")]
|
||||
use cipher::crypto_common::rand_core::{CryptoRng, RngCore};
|
||||
use cipher::{Key, KeyIvInit, StreamCipher};
|
||||
use digest::crypto_common::BlockSizeUser;
|
||||
use digest::Digest;
|
||||
#[cfg(feature = "rand")]
|
||||
use rand::{CryptoRng, RngCore};
|
||||
|
||||
/// Generate an ephemeral encryption keypair and perform diffie-hellman to establish
|
||||
/// shared key with the remote.
|
||||
|
||||
@@ -12,6 +12,7 @@ license.workspace = true
|
||||
bincode = { workspace = true }
|
||||
bytes = { workspace = true }
|
||||
nym-bin-common = { path = "../bin-common" }
|
||||
nym-crypto = { path = "../crypto" }
|
||||
nym-sphinx = { path = "../nymsphinx" }
|
||||
rand = "0.8.5"
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
pub mod request;
|
||||
pub mod response;
|
||||
|
||||
const VERSION: u8 = 6;
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
use nym_sphinx::addressing::clients::Recipient;
|
||||
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 {
|
||||
use rand::RngCore;
|
||||
@@ -26,7 +28,7 @@ impl IpPacketRequest {
|
||||
let request_id = generate_random();
|
||||
(
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketRequestData::StaticConnect(StaticConnectRequest {
|
||||
request_id,
|
||||
ips,
|
||||
@@ -49,7 +51,7 @@ impl IpPacketRequest {
|
||||
let request_id = generate_random();
|
||||
(
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketRequestData::DynamicConnect(DynamicConnectRequest {
|
||||
request_id,
|
||||
reply_to,
|
||||
@@ -66,7 +68,7 @@ impl IpPacketRequest {
|
||||
let request_id = generate_random();
|
||||
(
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketRequestData::Disconnect(DisconnectRequest {
|
||||
request_id,
|
||||
reply_to,
|
||||
@@ -78,7 +80,7 @@ impl IpPacketRequest {
|
||||
|
||||
pub fn new_data_request(ip_packets: bytes::Bytes) -> Self {
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketRequestData::Data(DataRequest { ip_packets }),
|
||||
}
|
||||
}
|
||||
@@ -87,7 +89,7 @@ impl IpPacketRequest {
|
||||
let request_id = generate_random();
|
||||
(
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketRequestData::Ping(PingRequest {
|
||||
request_id,
|
||||
reply_to,
|
||||
@@ -101,7 +103,7 @@ impl IpPacketRequest {
|
||||
let request_id = generate_random();
|
||||
(
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketRequestData::Health(HealthRequest {
|
||||
request_id,
|
||||
reply_to,
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
use nym_sphinx::addressing::clients::Recipient;
|
||||
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)]
|
||||
pub struct IpPacketResponse {
|
||||
@@ -12,7 +14,7 @@ pub struct IpPacketResponse {
|
||||
impl IpPacketResponse {
|
||||
pub fn new_static_connect_success(request_id: u64, reply_to: Recipient) -> Self {
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketResponseData::StaticConnect(StaticConnectResponse {
|
||||
request_id,
|
||||
reply_to,
|
||||
@@ -27,7 +29,7 @@ impl IpPacketResponse {
|
||||
reason: StaticConnectFailureReason,
|
||||
) -> Self {
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketResponseData::StaticConnect(StaticConnectResponse {
|
||||
request_id,
|
||||
reply_to,
|
||||
@@ -38,7 +40,7 @@ impl IpPacketResponse {
|
||||
|
||||
pub fn new_dynamic_connect_success(request_id: u64, reply_to: Recipient, ips: IpPair) -> Self {
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketResponseData::DynamicConnect(DynamicConnectResponse {
|
||||
request_id,
|
||||
reply_to,
|
||||
@@ -53,7 +55,7 @@ impl IpPacketResponse {
|
||||
reason: DynamicConnectFailureReason,
|
||||
) -> Self {
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketResponseData::DynamicConnect(DynamicConnectResponse {
|
||||
request_id,
|
||||
reply_to,
|
||||
@@ -64,7 +66,7 @@ impl IpPacketResponse {
|
||||
|
||||
pub fn new_disconnect_success(request_id: u64, reply_to: Recipient) -> Self {
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketResponseData::Disconnect(DisconnectResponse {
|
||||
request_id,
|
||||
reply_to,
|
||||
@@ -79,7 +81,7 @@ impl IpPacketResponse {
|
||||
reason: DisconnectFailureReason,
|
||||
) -> Self {
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketResponseData::Disconnect(DisconnectResponse {
|
||||
request_id,
|
||||
reply_to,
|
||||
@@ -93,7 +95,7 @@ impl IpPacketResponse {
|
||||
reason: UnrequestedDisconnectReason,
|
||||
) -> Self {
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketResponseData::UnrequestedDisconnect(UnrequestedDisconnect {
|
||||
reply_to,
|
||||
reason,
|
||||
@@ -103,7 +105,7 @@ impl IpPacketResponse {
|
||||
|
||||
pub fn new_ip_packet(ip_packet: bytes::Bytes) -> Self {
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketResponseData::Data(DataResponse { ip_packet }),
|
||||
}
|
||||
}
|
||||
@@ -115,7 +117,7 @@ impl IpPacketResponse {
|
||||
our_version: u8,
|
||||
) -> Self {
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketResponseData::Info(InfoResponse {
|
||||
request_id,
|
||||
reply_to,
|
||||
@@ -134,7 +136,7 @@ impl IpPacketResponse {
|
||||
level: InfoLevel,
|
||||
) -> Self {
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketResponseData::Info(InfoResponse {
|
||||
request_id: 0,
|
||||
reply_to,
|
||||
@@ -146,7 +148,7 @@ impl IpPacketResponse {
|
||||
|
||||
pub fn new_pong(request_id: u64, reply_to: Recipient) -> Self {
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketResponseData::Pong(PongResponse {
|
||||
request_id,
|
||||
reply_to,
|
||||
@@ -161,7 +163,7 @@ impl IpPacketResponse {
|
||||
routable: Option<bool>,
|
||||
) -> Self {
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketResponseData::Health(HealthResponse {
|
||||
request_id,
|
||||
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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,2 +1,6 @@
|
||||
pub mod conversion;
|
||||
pub mod request;
|
||||
pub mod response;
|
||||
pub mod signature;
|
||||
|
||||
const VERSION: u8 = 7;
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
use nym_crypto::asymmetric::identity;
|
||||
use nym_sphinx::addressing::clients::Recipient;
|
||||
use serde::{Deserialize, Serialize};
|
||||
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 {
|
||||
use rand::RngCore;
|
||||
@@ -27,7 +33,7 @@ impl IpPacketRequest {
|
||||
let request_id = generate_random();
|
||||
(
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketRequestData::StaticConnect(SignedStaticConnectRequest {
|
||||
request: StaticConnectRequest {
|
||||
request_id,
|
||||
@@ -54,7 +60,7 @@ impl IpPacketRequest {
|
||||
let request_id = generate_random();
|
||||
(
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketRequestData::DynamicConnect(SignedDynamicConnectRequest {
|
||||
request: DynamicConnectRequest {
|
||||
request_id,
|
||||
@@ -75,7 +81,7 @@ impl IpPacketRequest {
|
||||
let request_id = generate_random();
|
||||
(
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketRequestData::Disconnect(SignedDisconnectRequest {
|
||||
request: DisconnectRequest {
|
||||
request_id,
|
||||
@@ -91,7 +97,7 @@ impl IpPacketRequest {
|
||||
|
||||
pub fn new_data_request(ip_packets: bytes::Bytes) -> Self {
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketRequestData::Data(DataRequest { ip_packets }),
|
||||
}
|
||||
}
|
||||
@@ -100,7 +106,7 @@ impl IpPacketRequest {
|
||||
let request_id = generate_random();
|
||||
(
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketRequestData::Ping(PingRequest {
|
||||
request_id,
|
||||
reply_to,
|
||||
@@ -115,7 +121,7 @@ impl IpPacketRequest {
|
||||
let request_id = generate_random();
|
||||
(
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketRequestData::Health(HealthRequest {
|
||||
request_id,
|
||||
reply_to,
|
||||
@@ -173,19 +179,19 @@ pub enum 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 {
|
||||
IpPacketRequestData::StaticConnect(request) => {
|
||||
request.signature = Some(signature);
|
||||
request.signature.clone()
|
||||
request.signature
|
||||
}
|
||||
IpPacketRequestData::DynamicConnect(request) => {
|
||||
request.signature = Some(signature);
|
||||
request.signature.clone()
|
||||
request.signature
|
||||
}
|
||||
IpPacketRequestData::Disconnect(request) => {
|
||||
request.signature = Some(signature);
|
||||
request.signature.clone()
|
||||
request.signature
|
||||
}
|
||||
IpPacketRequestData::Data(_)
|
||||
| IpPacketRequestData::Ping(_)
|
||||
@@ -231,7 +237,30 @@ impl StaticConnectRequest {
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub struct SignedStaticConnectRequest {
|
||||
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
|
||||
@@ -269,7 +298,30 @@ impl DynamicConnectRequest {
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub struct SignedDynamicConnectRequest {
|
||||
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
|
||||
@@ -295,7 +347,30 @@ impl DisconnectRequest {
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub struct SignedDisconnectRequest {
|
||||
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.
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
use nym_sphinx::addressing::clients::Recipient;
|
||||
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)]
|
||||
pub struct IpPacketResponse {
|
||||
@@ -12,7 +14,7 @@ pub struct IpPacketResponse {
|
||||
impl IpPacketResponse {
|
||||
pub fn new_static_connect_success(request_id: u64, reply_to: Recipient) -> Self {
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketResponseData::StaticConnect(StaticConnectResponse {
|
||||
request_id,
|
||||
reply_to,
|
||||
@@ -27,7 +29,7 @@ impl IpPacketResponse {
|
||||
reason: StaticConnectFailureReason,
|
||||
) -> Self {
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketResponseData::StaticConnect(StaticConnectResponse {
|
||||
request_id,
|
||||
reply_to,
|
||||
@@ -38,7 +40,7 @@ impl IpPacketResponse {
|
||||
|
||||
pub fn new_dynamic_connect_success(request_id: u64, reply_to: Recipient, ips: IpPair) -> Self {
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketResponseData::DynamicConnect(DynamicConnectResponse {
|
||||
request_id,
|
||||
reply_to,
|
||||
@@ -53,7 +55,7 @@ impl IpPacketResponse {
|
||||
reason: DynamicConnectFailureReason,
|
||||
) -> Self {
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketResponseData::DynamicConnect(DynamicConnectResponse {
|
||||
request_id,
|
||||
reply_to,
|
||||
@@ -64,7 +66,7 @@ impl IpPacketResponse {
|
||||
|
||||
pub fn new_disconnect_success(request_id: u64, reply_to: Recipient) -> Self {
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketResponseData::Disconnect(DisconnectResponse {
|
||||
request_id,
|
||||
reply_to,
|
||||
@@ -79,7 +81,7 @@ impl IpPacketResponse {
|
||||
reason: DisconnectFailureReason,
|
||||
) -> Self {
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketResponseData::Disconnect(DisconnectResponse {
|
||||
request_id,
|
||||
reply_to,
|
||||
@@ -93,7 +95,7 @@ impl IpPacketResponse {
|
||||
reason: UnrequestedDisconnectReason,
|
||||
) -> Self {
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketResponseData::UnrequestedDisconnect(UnrequestedDisconnect {
|
||||
reply_to,
|
||||
reason,
|
||||
@@ -103,7 +105,7 @@ impl IpPacketResponse {
|
||||
|
||||
pub fn new_ip_packet(ip_packet: bytes::Bytes) -> Self {
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketResponseData::Data(DataResponse { ip_packet }),
|
||||
}
|
||||
}
|
||||
@@ -115,7 +117,7 @@ impl IpPacketResponse {
|
||||
our_version: u8,
|
||||
) -> Self {
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketResponseData::Info(InfoResponse {
|
||||
request_id,
|
||||
reply_to,
|
||||
@@ -134,7 +136,7 @@ impl IpPacketResponse {
|
||||
level: InfoLevel,
|
||||
) -> Self {
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketResponseData::Info(InfoResponse {
|
||||
request_id: 0,
|
||||
reply_to,
|
||||
@@ -146,7 +148,7 @@ impl IpPacketResponse {
|
||||
|
||||
pub fn new_pong(request_id: u64, reply_to: Recipient) -> Self {
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketResponseData::Pong(PongResponse {
|
||||
request_id,
|
||||
reply_to,
|
||||
@@ -161,7 +163,7 @@ impl IpPacketResponse {
|
||||
routable: Option<bool>,
|
||||
) -> Self {
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
version: VERSION,
|
||||
data: IpPacketResponseData::Health(HealthResponse {
|
||||
request_id,
|
||||
reply_to,
|
||||
@@ -275,6 +277,8 @@ pub enum StaticConnectFailureReason {
|
||||
RequestedIpAlreadyInUse,
|
||||
#[error("requested nym-address is already in use")]
|
||||
RequestedNymAddressAlreadyInUse,
|
||||
#[error("request timestamp is out of date")]
|
||||
OutOfDateTimestamp,
|
||||
#[error("{0}")]
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
futures = { workspace = true }
|
||||
rand = "0.7.3"
|
||||
rand = { workspace = true }
|
||||
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
|
||||
@@ -9,7 +9,7 @@ repository = { workspace = true }
|
||||
|
||||
[dependencies]
|
||||
log = { workspace = true }
|
||||
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
|
||||
rand = { workspace = true }
|
||||
rand_distr = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ license = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
|
||||
[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" }
|
||||
generic-array = { workspace = true, optional = true, features = ["serde"] }
|
||||
thiserror = { workspace = true }
|
||||
|
||||
@@ -14,5 +14,5 @@ serde = { workspace = true } # implementing serialization/deserialization for so
|
||||
thiserror = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
rand = "0.7"
|
||||
rand = "0.8.5"
|
||||
nym-crypto = { path = "../../crypto", features = ["rand"] }
|
||||
|
||||
@@ -8,7 +8,7 @@ license = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
|
||||
[dependencies]
|
||||
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
|
||||
rand = { workspace = true }
|
||||
bs58 = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
@@ -24,4 +24,4 @@ nym-topology = { path = "../../topology" }
|
||||
version = "0.2.83"
|
||||
|
||||
[dev-dependencies]
|
||||
rand_chacha = "0.2"
|
||||
rand_chacha = "0.3"
|
||||
|
||||
@@ -11,7 +11,7 @@ repository = { workspace = true }
|
||||
|
||||
[dependencies]
|
||||
log = { workspace = true }
|
||||
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
|
||||
rand = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
|
||||
nym-sphinx-addressing = { path = "../addressing" }
|
||||
|
||||
@@ -8,7 +8,7 @@ license = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
|
||||
[dependencies]
|
||||
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
|
||||
rand = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
|
||||
nym-crypto = { path = "../../crypto" }
|
||||
|
||||
@@ -15,7 +15,7 @@ pub use sphinx_packet::{
|
||||
self, DESTINATION_ADDRESS_LENGTH, IDENTIFIER_LENGTH, MAX_PATH_LENGTH, NODE_ADDRESS_LENGTH,
|
||||
PAYLOAD_KEY_SIZE,
|
||||
},
|
||||
crypto::{self, EphemeralSecret, PrivateKey, PublicKey, SharedSecret},
|
||||
crypto::{self, PrivateKey, PublicKey},
|
||||
header::{self, delays, delays::Delay, ProcessedHeader, SphinxHeader, HEADER_SIZE},
|
||||
packet::builder::DEFAULT_PAYLOAD_SIZE,
|
||||
payload::{Payload, PAYLOAD_OVERHEAD_SIZE},
|
||||
|
||||
@@ -12,7 +12,7 @@ dirs = "4.0"
|
||||
futures = { workspace = true }
|
||||
log = { workspace = true }
|
||||
pin-project = { workspace = true }
|
||||
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
|
||||
rand = { workspace = true }
|
||||
reqwest = { workspace = true }
|
||||
schemars = { workspace = true, features = ["preserve_order"] }
|
||||
serde = { workspace = true, features = ["derive"] } # for config serialization/deserialization
|
||||
|
||||
@@ -14,7 +14,7 @@ documentation = { workspace = true }
|
||||
[dependencies]
|
||||
bs58 = { workspace = true }
|
||||
log = { workspace = true }
|
||||
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
|
||||
rand = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
async-trait = { workspace = true, optional = true }
|
||||
semver = "0.11"
|
||||
|
||||
@@ -11,7 +11,7 @@ repository = "https://github.com/nymtech/nym"
|
||||
[dependencies]
|
||||
async-trait = { workspace = true }
|
||||
js-sys = { workspace = true }
|
||||
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
|
||||
rand = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde-wasm-bindgen = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
|
||||
@@ -17,7 +17,9 @@ log = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
thiserror = { workspace = true }
|
||||
|
||||
nym-config = { path = "../config" }
|
||||
nym-crypto = { path = "../crypto", features = ["asymmetric"] }
|
||||
nym-network-defaults = { path = "../network-defaults" }
|
||||
|
||||
# feature-specific dependencies:
|
||||
|
||||
@@ -32,7 +34,7 @@ serde_json = { workspace = true, optional = true }
|
||||
x25519-dalek = { version = "2.0.0", features = ["static_secrets"] }
|
||||
|
||||
[dev-dependencies]
|
||||
rand = "0.7.3"
|
||||
rand = "0.8.5"
|
||||
nym-crypto = { path = "../crypto", features = ["rand"]}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use std::net::{IpAddr, SocketAddr};
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
|
||||
pub struct Config {
|
||||
/// Socket address this node will use for binding its wireguard interface.
|
||||
/// default: `0.0.0.0:51822`
|
||||
pub bind_address: SocketAddr,
|
||||
|
||||
/// Private IP address of the wireguard gateway.
|
||||
/// default: `10.1.0.1`
|
||||
pub private_ip: IpAddr,
|
||||
|
||||
/// Port announced to external clients wishing to connect to the wireguard interface.
|
||||
/// Useful in the instances where the node is behind a proxy.
|
||||
pub announced_port: u16,
|
||||
|
||||
/// The prefix denoting the maximum number of the clients that can be connected via Wireguard.
|
||||
/// The maximum value for IPv4 is 32 and for IPv6 is 128
|
||||
pub private_network_prefix: u8,
|
||||
}
|
||||
@@ -32,4 +32,7 @@ pub enum Error {
|
||||
#[source]
|
||||
source: hmac::digest::MacError,
|
||||
},
|
||||
|
||||
#[error("peers can't be modified anymore")]
|
||||
PeerModifyStopped,
|
||||
}
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
pub mod config;
|
||||
pub mod error;
|
||||
pub mod public_key;
|
||||
pub mod registration;
|
||||
|
||||
pub use config::Config;
|
||||
pub use error::Error;
|
||||
pub use public_key::PeerPublicKey;
|
||||
pub use registration::{
|
||||
ClientMac, ClientMessage, ClientRegistrationResponse, GatewayClient, InitMessage, Nonce,
|
||||
ClientMac, ClientMessage, ClientRegistrationResponse, GatewayClient, GatewayClientRegistry,
|
||||
InitMessage, Nonce,
|
||||
};
|
||||
|
||||
#[cfg(feature = "verify")]
|
||||
|
||||
@@ -24,6 +24,10 @@ impl PeerPublicKey {
|
||||
pub fn as_bytes(&self) -> &[u8] {
|
||||
self.0.as_bytes()
|
||||
}
|
||||
|
||||
pub fn inner(&self) -> PublicKey {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for PeerPublicKey {
|
||||
|
||||
@@ -12,12 +12,12 @@ use std::{fmt, ops::Deref, str::FromStr};
|
||||
#[cfg(feature = "verify")]
|
||||
use hmac::{Hmac, Mac};
|
||||
#[cfg(feature = "verify")]
|
||||
use nym_crypto::asymmetric::encryption::{PrivateKey, PublicKey};
|
||||
use nym_crypto::asymmetric::encryption::PrivateKey;
|
||||
#[cfg(feature = "verify")]
|
||||
use sha2::Sha256;
|
||||
|
||||
pub type GatewayClientRegistry = DashMap<PeerPublicKey, GatewayClient>;
|
||||
pub type PendingRegistrations = DashMap<PeerPublicKey, Nonce>;
|
||||
pub type PendingRegistrations = DashMap<PeerPublicKey, RegistrationData>;
|
||||
pub type PrivateIPs = DashMap<IpAddr, Free>;
|
||||
|
||||
#[cfg(feature = "verify")]
|
||||
@@ -56,14 +56,16 @@ impl InitMessage {
|
||||
#[serde(tag = "type", rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
|
||||
pub enum ClientRegistrationResponse {
|
||||
PendingRegistration {
|
||||
nonce: u64,
|
||||
gateway_data: GatewayClient,
|
||||
wg_port: u16,
|
||||
},
|
||||
Registered {
|
||||
success: bool,
|
||||
},
|
||||
PendingRegistration(RegistrationData),
|
||||
Registered,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
|
||||
pub struct RegistrationData {
|
||||
pub nonce: u64,
|
||||
pub gateway_data: GatewayClient,
|
||||
pub wg_port: u16,
|
||||
}
|
||||
|
||||
/// Client that wants to register sends its PublicKey bytes mac digest encrypted with a DH shared secret.
|
||||
@@ -87,7 +89,7 @@ impl GatewayClient {
|
||||
#[cfg(feature = "verify")]
|
||||
pub fn new(
|
||||
local_secret: &PrivateKey,
|
||||
remote_public: PublicKey,
|
||||
remote_public: x25519_dalek::PublicKey,
|
||||
private_ip: IpAddr,
|
||||
nonce: u64,
|
||||
) -> Self {
|
||||
@@ -96,8 +98,6 @@ impl GatewayClient {
|
||||
let static_secret = x25519_dalek::StaticSecret::from(local_secret.to_bytes());
|
||||
let local_public: x25519_dalek::PublicKey = (&static_secret).into();
|
||||
|
||||
let remote_public = x25519_dalek::PublicKey::from(remote_public.to_bytes());
|
||||
|
||||
let dh = static_secret.diffie_hellman(&remote_public);
|
||||
|
||||
// TODO: change that to use our nym_crypto::hmac module instead
|
||||
@@ -220,7 +220,7 @@ mod tests {
|
||||
|
||||
let client = GatewayClient::new(
|
||||
client_key_pair.private_key(),
|
||||
*gateway_key_pair.public_key(),
|
||||
x25519_dalek::PublicKey::from(gateway_key_pair.public_key().to_bytes()),
|
||||
"10.0.0.42".parse().unwrap(),
|
||||
nonce,
|
||||
);
|
||||
|
||||
@@ -12,16 +12,16 @@ license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
base64 = "0.21.3"
|
||||
dashmap = { workspace = true }
|
||||
defguard_wireguard_rs = { workspace = true }
|
||||
# The latest version on crates.io at the time of writing this (6.0.0) has a
|
||||
# version mismatch with x25519-dalek/curve25519-dalek that is resolved in the
|
||||
# latest commit. So pick that for now.
|
||||
x25519-dalek = "2.0.0"
|
||||
ip_network = { workspace = true }
|
||||
log.workspace = true
|
||||
nym-crypto = { path = "../crypto", features = ["asymmetric"] }
|
||||
nym-network-defaults = { path = "../network-defaults" }
|
||||
nym-task = { path = "../task" }
|
||||
nym-wireguard-types = { path = "../wireguard-types" }
|
||||
tokio = { workspace = true, features = ["rt-multi-thread", "net", "io-util"] }
|
||||
|
||||
[target."cfg(target_os = \"linux\")".dependencies]
|
||||
defguard_wireguard_rs = { git = "https://github.com/neacsu/wireguard-rs.git", rev = "c2cd0c1119f699f4bc43f5e6ffd6fc242caa42ed" }
|
||||
|
||||
+126
-28
@@ -3,44 +3,142 @@
|
||||
// #![warn(clippy::expect_used)]
|
||||
// #![warn(clippy::unwrap_used)]
|
||||
|
||||
pub mod setup;
|
||||
use dashmap::DashMap;
|
||||
use defguard_wireguard_rs::{host::Peer, key::Key, net::IpAddrMask, WGApi};
|
||||
use nym_crypto::asymmetric::encryption::KeyPair;
|
||||
use nym_wireguard_types::{Config, Error, GatewayClient, GatewayClientRegistry};
|
||||
use peer_controller::PeerControlMessage;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::mpsc::{self, UnboundedReceiver};
|
||||
|
||||
const WG_TUN_NAME: &str = "nymwg";
|
||||
|
||||
pub mod peer_controller;
|
||||
|
||||
pub struct WgApiWrapper {
|
||||
inner: WGApi,
|
||||
}
|
||||
|
||||
impl WgApiWrapper {
|
||||
pub fn new(wg_api: WGApi) -> Self {
|
||||
WgApiWrapper { inner: wg_api }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for WgApiWrapper {
|
||||
fn drop(&mut self) {
|
||||
if let Err(e) = defguard_wireguard_rs::WireguardInterfaceApi::remove_interface(&self.inner)
|
||||
{
|
||||
log::error!("Could not remove the wireguard interface: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct WireguardGatewayData {
|
||||
config: Config,
|
||||
keypair: Arc<KeyPair>,
|
||||
client_registry: Arc<GatewayClientRegistry>,
|
||||
peer_tx: mpsc::UnboundedSender<PeerControlMessage>,
|
||||
}
|
||||
|
||||
impl WireguardGatewayData {
|
||||
pub fn new(
|
||||
config: Config,
|
||||
keypair: Arc<KeyPair>,
|
||||
) -> (Self, mpsc::UnboundedReceiver<PeerControlMessage>) {
|
||||
let (peer_tx, peer_rx) = mpsc::unbounded_channel();
|
||||
(
|
||||
WireguardGatewayData {
|
||||
config,
|
||||
keypair,
|
||||
client_registry: Arc::new(DashMap::default()),
|
||||
peer_tx,
|
||||
},
|
||||
peer_rx,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn config(&self) -> Config {
|
||||
self.config
|
||||
}
|
||||
|
||||
pub fn keypair(&self) -> &Arc<KeyPair> {
|
||||
&self.keypair
|
||||
}
|
||||
|
||||
pub fn client_registry(&self) -> &Arc<GatewayClientRegistry> {
|
||||
&self.client_registry
|
||||
}
|
||||
|
||||
pub fn add_peer(&self, client: &GatewayClient) -> Result<(), Error> {
|
||||
let mut peer = Peer::new(Key::new(client.pub_key.to_bytes()));
|
||||
peer.allowed_ips
|
||||
.push(IpAddrMask::new(client.private_ip, 32));
|
||||
let msg = PeerControlMessage::AddPeer(peer);
|
||||
self.peer_tx.send(msg).map_err(|_| Error::PeerModifyStopped)
|
||||
}
|
||||
|
||||
pub fn remove_peer(&self, client: &GatewayClient) -> Result<(), Error> {
|
||||
let key = Key::new(client.pub_key().to_bytes());
|
||||
let msg = PeerControlMessage::RemovePeer(key);
|
||||
self.peer_tx.send(msg).map_err(|_| Error::PeerModifyStopped)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WireguardData {
|
||||
pub inner: WireguardGatewayData,
|
||||
pub peer_rx: UnboundedReceiver<PeerControlMessage>,
|
||||
}
|
||||
|
||||
/// Start wireguard device
|
||||
#[cfg(target_os = "linux")]
|
||||
pub async fn start_wireguard(
|
||||
mut task_client: nym_task::TaskClient,
|
||||
_gateway_client_registry: std::sync::Arc<
|
||||
nym_wireguard_types::registration::GatewayClientRegistry,
|
||||
>,
|
||||
) -> Result<defguard_wireguard_rs::WGApi, Box<dyn std::error::Error + Send + Sync + 'static>> {
|
||||
use crate::setup::{peer_allowed_ips, peer_static_public_key, PRIVATE_KEY};
|
||||
use defguard_wireguard_rs::{
|
||||
host::Peer, key::Key, net::IpAddrMask, InterfaceConfiguration, WGApi, WireguardInterfaceApi,
|
||||
};
|
||||
use nym_network_defaults::{WG_PORT, WG_TUN_DEVICE_ADDRESS};
|
||||
task_client: nym_task::TaskClient,
|
||||
wireguard_data: WireguardData,
|
||||
) -> Result<std::sync::Arc<WgApiWrapper>, Box<dyn std::error::Error + Send + Sync + 'static>> {
|
||||
use base64::{prelude::BASE64_STANDARD, Engine};
|
||||
use defguard_wireguard_rs::{InterfaceConfiguration, WireguardInterfaceApi};
|
||||
use ip_network::IpNetwork;
|
||||
use peer_controller::PeerController;
|
||||
|
||||
let ifname = String::from("wg0");
|
||||
let wgapi = WGApi::new(ifname.clone(), false)?;
|
||||
wgapi.create_interface()?;
|
||||
let mut peers = vec![];
|
||||
for peer_client in wireguard_data.inner.client_registry().iter() {
|
||||
let mut peer = Peer::new(Key::new(peer_client.pub_key.to_bytes()));
|
||||
let peer_ip_mask = IpAddrMask::new(peer_client.private_ip, 32);
|
||||
peer.set_allowed_ips(vec![peer_ip_mask]);
|
||||
peers.push(peer);
|
||||
}
|
||||
|
||||
let ifname = String::from(WG_TUN_NAME);
|
||||
let wg_api = defguard_wireguard_rs::WGApi::new(ifname.clone(), false)?;
|
||||
wg_api.create_interface()?;
|
||||
let interface_config = InterfaceConfiguration {
|
||||
name: ifname.clone(),
|
||||
prvkey: PRIVATE_KEY.to_string(),
|
||||
address: WG_TUN_DEVICE_ADDRESS.to_string(),
|
||||
port: WG_PORT as u32,
|
||||
peers: vec![],
|
||||
prvkey: BASE64_STANDARD.encode(wireguard_data.inner.keypair().private_key().to_bytes()),
|
||||
address: wireguard_data.inner.config().private_ip.to_string(),
|
||||
port: wireguard_data.inner.config().announced_port as u32,
|
||||
peers,
|
||||
};
|
||||
wgapi.configure_interface(&interface_config)?;
|
||||
let peer = peer_static_public_key();
|
||||
let mut peer = Peer::new(Key::new(peer.to_bytes()));
|
||||
let peer_ip = peer_allowed_ips();
|
||||
let peer_ip_mask = IpAddrMask::new(peer_ip.network_address(), peer_ip.netmask());
|
||||
peer.set_allowed_ips(vec![peer_ip_mask]);
|
||||
wgapi.configure_peer(&peer)?;
|
||||
wgapi.configure_peer_routing(&[peer.clone()])?;
|
||||
wg_api.configure_interface(&interface_config)?;
|
||||
|
||||
tokio::spawn(async move { task_client.recv().await });
|
||||
// Use a dummy peer to create routing rule for the entire network space
|
||||
let mut catch_all_peer = Peer::new(Key::new([0; 32]));
|
||||
let network = IpNetwork::new_truncate(
|
||||
wireguard_data.inner.config().private_ip,
|
||||
wireguard_data.inner.config().private_network_prefix,
|
||||
)?;
|
||||
catch_all_peer.set_allowed_ips(vec![IpAddrMask::new(
|
||||
network.network_address(),
|
||||
network.netmask(),
|
||||
)]);
|
||||
wg_api.configure_peer_routing(&[catch_all_peer])?;
|
||||
|
||||
Ok(wgapi)
|
||||
let wg_api = std::sync::Arc::new(WgApiWrapper::new(wg_api));
|
||||
let mut controller = PeerController::new(wg_api.clone(), wireguard_data.peer_rx);
|
||||
tokio::spawn(async move { controller.run(task_client).await });
|
||||
|
||||
Ok(wg_api)
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use defguard_wireguard_rs::{host::Peer, key::Key, WireguardInterfaceApi};
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
use crate::WgApiWrapper;
|
||||
|
||||
pub enum PeerControlMessage {
|
||||
AddPeer(Peer),
|
||||
RemovePeer(Key),
|
||||
}
|
||||
|
||||
pub struct PeerController {
|
||||
peer_rx: mpsc::UnboundedReceiver<PeerControlMessage>,
|
||||
wg_api: Arc<WgApiWrapper>,
|
||||
}
|
||||
|
||||
impl PeerController {
|
||||
pub fn new(
|
||||
wg_api: Arc<WgApiWrapper>,
|
||||
peer_rx: mpsc::UnboundedReceiver<PeerControlMessage>,
|
||||
) -> Self {
|
||||
PeerController { wg_api, peer_rx }
|
||||
}
|
||||
|
||||
pub async fn run(&mut self, mut task_client: nym_task::TaskClient) {
|
||||
loop {
|
||||
tokio::select! {
|
||||
_ = task_client.recv() => {
|
||||
log::trace!("PeerController handler: Received shutdown");
|
||||
break;
|
||||
}
|
||||
msg = self.peer_rx.recv() => {
|
||||
match msg {
|
||||
Some(PeerControlMessage::AddPeer(peer)) => {
|
||||
if let Err(e) = self.wg_api.inner.configure_peer(&peer) {
|
||||
log::error!("Could not configure peer: {:?}", e);
|
||||
}
|
||||
}
|
||||
Some(PeerControlMessage::RemovePeer(peer_pubkey)) => {
|
||||
if let Err(e) = self.wg_api.inner.remove_peer(&peer_pubkey) {
|
||||
log::error!("Could not remove peer: {:?}", e);
|
||||
}
|
||||
}
|
||||
None => {
|
||||
log::trace!("PeerController [main loop]: stopping since channel closed");
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
use std::net::IpAddr;
|
||||
|
||||
use base64::{engine::general_purpose, Engine as _};
|
||||
use log::info;
|
||||
|
||||
// The wireguard UDP listener
|
||||
pub const WG_ADDRESS: &str = "0.0.0.0";
|
||||
|
||||
// The private key of the listener
|
||||
// Corresponding public key: "WM8s8bYegwMa0TJ+xIwhk+dImk2IpDUKslDBCZPizlE="
|
||||
pub(crate) const PRIVATE_KEY: &str = "AEqXrLFT4qjYq3wmX0456iv94uM6nDj5ugp6Jedcflg=";
|
||||
|
||||
// The AllowedIPs for the connected peer, which is one a single IP and the same as the IP that the
|
||||
// peer has configured on their side.
|
||||
const ALLOWED_IPS: &str = "10.1.0.2";
|
||||
|
||||
fn decode_base64_key(base64_key: &str) -> [u8; 32] {
|
||||
general_purpose::STANDARD
|
||||
.decode(base64_key)
|
||||
.unwrap()
|
||||
.try_into()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn server_static_private_key() -> x25519_dalek::StaticSecret {
|
||||
// TODO: this is a temporary solution for development
|
||||
let static_private_bytes: [u8; 32] = decode_base64_key(PRIVATE_KEY);
|
||||
let static_private = x25519_dalek::StaticSecret::from(static_private_bytes);
|
||||
let static_public = x25519_dalek::PublicKey::from(&static_private);
|
||||
info!(
|
||||
"wg public key: {}",
|
||||
general_purpose::STANDARD.encode(static_public)
|
||||
);
|
||||
static_private
|
||||
}
|
||||
|
||||
pub fn peer_static_public_key() -> x25519_dalek::PublicKey {
|
||||
// A single static public key is used during development
|
||||
|
||||
// Read from NYM_PEER_PUBLIC_KEY env variable
|
||||
let peer = std::env::var("NYM_PEER_PUBLIC_KEY").expect("NYM_PEER_PUBLIC_KEY must be set");
|
||||
|
||||
let peer_static_public_bytes: [u8; 32] = decode_base64_key(&peer);
|
||||
let peer_static_public = x25519_dalek::PublicKey::from(peer_static_public_bytes);
|
||||
info!(
|
||||
"Adding wg peer public key: {}",
|
||||
general_purpose::STANDARD.encode(peer_static_public)
|
||||
);
|
||||
peer_static_public
|
||||
}
|
||||
|
||||
pub fn peer_allowed_ips() -> ip_network::IpNetwork {
|
||||
let key: IpAddr = ALLOWED_IPS.parse().unwrap();
|
||||
let cidr = 32u8;
|
||||
ip_network::IpNetwork::new_truncate(key, cidr).unwrap()
|
||||
}
|
||||
Generated
+257
-550
File diff suppressed because it is too large
Load Diff
@@ -8,8 +8,6 @@ members = [
|
||||
"mixnet-vesting-integration-tests",
|
||||
"multisig/cw3-flex-multisig",
|
||||
"multisig/cw4-group",
|
||||
"name-service",
|
||||
"service-provider-directory",
|
||||
"vesting",
|
||||
]
|
||||
|
||||
|
||||
+1
-7
@@ -1,4 +1,4 @@
|
||||
schema: coconut-bandwidth-schema coconut-dkg-schema mixnet-schema name-service-schema service-provider-directory-schema vesting-schema multisig-schema group-schema
|
||||
schema: coconut-bandwidth-schema coconut-dkg-schema mixnet-schema vesting-schema multisig-schema group-schema
|
||||
|
||||
coconut-bandwidth-schema:
|
||||
$(MAKE) -C coconut-bandwidth generate-schema
|
||||
@@ -9,12 +9,6 @@ coconut-dkg-schema:
|
||||
mixnet-schema:
|
||||
$(MAKE) -C mixnet generate-schema
|
||||
|
||||
name-service-schema:
|
||||
$(MAKE) -C name-service generate-schema
|
||||
|
||||
service-provider-directory-schema:
|
||||
$(MAKE) -C service-provider-directory generate-schema
|
||||
|
||||
vesting-schema:
|
||||
$(MAKE) -C vesting generate-schema
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ cw-multi-test = { workspace = true }
|
||||
cw3-flex-multisig = { path = "../multisig/cw3-flex-multisig" }
|
||||
cw4-group = { path = "../multisig/cw4-group" }
|
||||
|
||||
rand_chacha = "0.2"
|
||||
rand_chacha = "0.3"
|
||||
|
||||
[[test]]
|
||||
name = "coconut-test"
|
||||
|
||||
@@ -25,7 +25,7 @@ nym-vesting-contract = { path = "../vesting" }
|
||||
nym-crypto = { path = "../../common/crypto", features = ["asymmetric", "rand"] }
|
||||
|
||||
# external dependencies
|
||||
rand_chacha = "0.2"
|
||||
rand_chacha = "0.3"
|
||||
|
||||
[[test]]
|
||||
name = "mixnet-vesting-test"
|
||||
|
||||
@@ -44,7 +44,7 @@ time = { version = "0.3", features = ["macros"] }
|
||||
semver = { workspace = true, default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
rand_chacha = "0.2"
|
||||
rand_chacha = "0.3"
|
||||
nym-crypto = { path = "../../common/crypto", features = ["asymmetric", "rand"] }
|
||||
|
||||
[build-dependencies]
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
[alias]
|
||||
wasm = "build --release --lib --target wasm32-unknown-unknown"
|
||||
unit-test = "test --lib"
|
||||
schema = "run --bin schema --features=schema-gen"
|
||||
@@ -33,7 +33,7 @@ cw-multi-test = { workspace = true }
|
||||
nym-crypto = { path = "../../common/crypto", features = ["asymmetric", "rand"] }
|
||||
nym-sphinx-addressing = { path = "../../common/nymsphinx/addressing" }
|
||||
rand = "0.8.5"
|
||||
rand_chacha = "0.2"
|
||||
rand_chacha = "0.3"
|
||||
rstest = "0.17.0"
|
||||
|
||||
[features]
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
generate-schema:
|
||||
cargo schema
|
||||
@@ -1,13 +0,0 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use vergen::{vergen, Config};
|
||||
|
||||
fn main() {
|
||||
let mut config = Config::default();
|
||||
if std::env::var("DOCS_RS").is_ok() {
|
||||
// If we don't have access to git information, such as in a docs.rs build, don't error
|
||||
*config.git_mut().skip_if_error_mut() = true;
|
||||
}
|
||||
vergen(config).expect("failed to extract build metadata");
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user