From 44fa52a7a76741bbc5f22219b0efd795f93fecd5 Mon Sep 17 00:00:00 2001 From: pierre Date: Thu, 27 Jul 2023 11:08:24 +0200 Subject: [PATCH 01/46] ci: fix release strapi actions --- .github/workflows/nym-connect-publish-macos.yml | 4 ++-- .github/workflows/nym-connect-publish-ubuntu.yml | 5 +++-- .github/workflows/nym-connect-publish-windows10.yml | 4 ++-- .github/workflows/nym-wallet-publish-macos.yml | 4 ++-- .github/workflows/nym-wallet-publish-ubuntu.yml | 4 ++-- .github/workflows/nym-wallet-publish-windows10.yml | 4 ++-- 6 files changed, 13 insertions(+), 12 deletions(-) diff --git a/.github/workflows/nym-connect-publish-macos.yml b/.github/workflows/nym-connect-publish-macos.yml index 45dac7e87a..a4176eb285 100644 --- a/.github/workflows/nym-connect-publish-macos.yml +++ b/.github/workflows/nym-connect-publish-macos.yml @@ -19,7 +19,7 @@ jobs: outputs: release_id: ${{ steps.create-release.outputs.id }} - release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }} + release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].published_at }} version: ${{ steps.release-info.outputs.version }} filename: ${{ steps.release-info.outputs.filename }} file_hash: ${{ steps.release-info.outputs.file_hash }} @@ -118,7 +118,7 @@ jobs: ref=${{ github.ref_name }} semver="${ref##nym-connect-}" && semver="${semver##v}" echo "version=${semver}" >> "$GITHUB_OUTPUT" - echo "filename=nym-connect_${version}_x64_en-US.msi" >> "$GITHUB_OUTPUT" + echo "filename=nym-connect_${semver}_x64_en-US.msi" >> "$GITHUB_OUTPUT" echo "file_hash=${{ hashFiles('nym-connect/desktop/target/release/bundle/dmg/nym-connect_*_x64.dmg') }}" >> "$GITHUB_OUTPUT" push-release-data: diff --git a/.github/workflows/nym-connect-publish-ubuntu.yml b/.github/workflows/nym-connect-publish-ubuntu.yml index cc5e1f3f00..caec73b10a 100644 --- a/.github/workflows/nym-connect-publish-ubuntu.yml +++ b/.github/workflows/nym-connect-publish-ubuntu.yml @@ -19,7 +19,7 @@ jobs: outputs: release_id: ${{ steps.create-release.outputs.id }} - release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }} + release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].published_at }} version: ${{ steps.release-info.outputs.version }} filename: ${{ steps.release-info.outputs.filename }} file_hash: ${{ steps.release-info.outputs.file_hash }} @@ -85,8 +85,9 @@ jobs: ref=${{ github.ref_name }} semver="${ref##nym-connect-}" && semver="${semver##v}" echo "version=${semver}" >> "$GITHUB_OUTPUT" - echo "filename=nym-connect_${version}_amd64.AppImage" >> "$GITHUB_OUTPUT" + echo "filename=nym-connect_${semver}_amd64.AppImage" >> "$GITHUB_OUTPUT" echo "file_hash=${{ hashFiles('nym-connect/desktop/target/release/bundle/appimage/nym-connect_*_amd64.AppImage') }}" >> "$GITHUB_OUTPUT" + push-release-data: if: ${{ (startsWith(github.ref, 'refs/tags/nym-connect-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }} uses: ./.github/workflows/push-release-data.yml diff --git a/.github/workflows/nym-connect-publish-windows10.yml b/.github/workflows/nym-connect-publish-windows10.yml index 1b4b1be2cc..aeb04dc872 100644 --- a/.github/workflows/nym-connect-publish-windows10.yml +++ b/.github/workflows/nym-connect-publish-windows10.yml @@ -19,7 +19,7 @@ jobs: outputs: release_id: ${{ steps.create-release.outputs.id }} - release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }} + release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].published_at }} version: ${{ steps.release-info.outputs.version }} filename: ${{ steps.release-info.outputs.filename }} file_hash: ${{ steps.release-info.outputs.file_hash }} @@ -104,7 +104,7 @@ jobs: ref=${{ github.ref_name }} semver="${ref##nym-connect-}" && semver="${semver##v}" echo "version=${semver}" >> "$GITHUB_OUTPUT" - echo "filename=nym-connect_${version}_x64_en-US.msi" >> "$GITHUB_OUTPUT" + echo "filename=nym-connect_${semver}_x64_en-US.msi" >> "$GITHUB_OUTPUT" echo "file_hash=${{ hashFiles('nym-connect/desktop/target/release/bundle/msi/nym-connect_*_x64_en-US.msi') }}" >> "$GITHUB_OUTPUT" push-release-data: diff --git a/.github/workflows/nym-wallet-publish-macos.yml b/.github/workflows/nym-wallet-publish-macos.yml index 408a3b7406..5db06a8f52 100644 --- a/.github/workflows/nym-wallet-publish-macos.yml +++ b/.github/workflows/nym-wallet-publish-macos.yml @@ -19,7 +19,7 @@ jobs: outputs: release_id: ${{ steps.create-release.outputs.id }} - release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }} + release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].published_at }} version: ${{ steps.release-info.outputs.version }} filename: ${{ steps.release-info.outputs.filename }} file_hash: ${{ steps.release-info.outputs.file_hash }} @@ -106,7 +106,7 @@ jobs: ref=${{ github.ref_name }} semver="${ref##nym-wallet-}" && semver="${semver##v}" echo "version=${semver}" >> "$GITHUB_OUTPUT" - echo "filename=nym-wallet_${version}_x64.dmg" >> "$GITHUB_OUTPUT" + echo "filename=nym-wallet_${semver}_x64.dmg" >> "$GITHUB_OUTPUT" echo "file_hash=${{ hashFiles('nym-wallet/target/release/bundle/dmg/nym-wallet_*_x64.dmg') }}" >> "$GITHUB_OUTPUT" push-release-data: diff --git a/.github/workflows/nym-wallet-publish-ubuntu.yml b/.github/workflows/nym-wallet-publish-ubuntu.yml index 9e9ee904cd..52887950fa 100644 --- a/.github/workflows/nym-wallet-publish-ubuntu.yml +++ b/.github/workflows/nym-wallet-publish-ubuntu.yml @@ -19,7 +19,7 @@ jobs: outputs: release_id: ${{ steps.create-release.outputs.id }} - release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }} + release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].published_at }} version: ${{ steps.release-info.outputs.version }} filename: ${{ steps.release-info.outputs.filename }} file_hash: ${{ steps.release-info.outputs.file_hash }} @@ -83,7 +83,7 @@ jobs: ref=${{ github.ref_name }} semver="${ref##nym-wallet-}" && semver="${semver##v}" echo "version=${semver}" >> "$GITHUB_OUTPUT" - echo "filename=nym-wallet_${version}_amd64.AppImage" >> "$GITHUB_OUTPUT" + echo "filename=nym-wallet_${semver}_amd64.AppImage" >> "$GITHUB_OUTPUT" echo "file_hash=${{ hashFiles('nym-wallet/target/release/bundle/appimage/nym-wallet_*_amd64.AppImage') }}" >> "$GITHUB_OUTPUT" push-release-data: diff --git a/.github/workflows/nym-wallet-publish-windows10.yml b/.github/workflows/nym-wallet-publish-windows10.yml index 56a332a75d..a7be3e4a37 100644 --- a/.github/workflows/nym-wallet-publish-windows10.yml +++ b/.github/workflows/nym-wallet-publish-windows10.yml @@ -19,7 +19,7 @@ jobs: outputs: release_id: ${{ steps.create-release.outputs.id }} - release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }} + release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].published_at }} version: ${{ steps.release-info.outputs.version }} filename: ${{ steps.release-info.outputs.filename }} file_hash: ${{ steps.release-info.outputs.file_hash }} @@ -103,7 +103,7 @@ jobs: ref=${{ github.ref_name }} semver="${ref##nym-wallet-}" && semver="${semver##v}" echo "version=${semver}" >> "$GITHUB_OUTPUT" - echo "filename=nym-wallet_${version}_x64_en-US.msi" >> "$GITHUB_OUTPUT" + echo "filename=nym-wallet_${semver}_x64_en-US.msi" >> "$GITHUB_OUTPUT" echo "file_hash=${{ hashFiles('nym-wallet/target/release/bundle/msi/nym-wallet_*_x64_en-US.msi') }}" >> "$GITHUB_OUTPUT" push-release-data: From aedacf6c6544c4c59d337ef1575dc08af3030ab8 Mon Sep 17 00:00:00 2001 From: pierre Date: Thu, 27 Jul 2023 11:08:24 +0200 Subject: [PATCH 02/46] ci: fix release strapi actions --- .github/workflows/nym-connect-publish-macos.yml | 4 ++-- .github/workflows/nym-connect-publish-ubuntu.yml | 5 +++-- .github/workflows/nym-connect-publish-windows10.yml | 4 ++-- .github/workflows/nym-wallet-publish-macos.yml | 4 ++-- .github/workflows/nym-wallet-publish-ubuntu.yml | 4 ++-- .github/workflows/nym-wallet-publish-windows10.yml | 4 ++-- 6 files changed, 13 insertions(+), 12 deletions(-) diff --git a/.github/workflows/nym-connect-publish-macos.yml b/.github/workflows/nym-connect-publish-macos.yml index 45dac7e87a..a4176eb285 100644 --- a/.github/workflows/nym-connect-publish-macos.yml +++ b/.github/workflows/nym-connect-publish-macos.yml @@ -19,7 +19,7 @@ jobs: outputs: release_id: ${{ steps.create-release.outputs.id }} - release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }} + release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].published_at }} version: ${{ steps.release-info.outputs.version }} filename: ${{ steps.release-info.outputs.filename }} file_hash: ${{ steps.release-info.outputs.file_hash }} @@ -118,7 +118,7 @@ jobs: ref=${{ github.ref_name }} semver="${ref##nym-connect-}" && semver="${semver##v}" echo "version=${semver}" >> "$GITHUB_OUTPUT" - echo "filename=nym-connect_${version}_x64_en-US.msi" >> "$GITHUB_OUTPUT" + echo "filename=nym-connect_${semver}_x64_en-US.msi" >> "$GITHUB_OUTPUT" echo "file_hash=${{ hashFiles('nym-connect/desktop/target/release/bundle/dmg/nym-connect_*_x64.dmg') }}" >> "$GITHUB_OUTPUT" push-release-data: diff --git a/.github/workflows/nym-connect-publish-ubuntu.yml b/.github/workflows/nym-connect-publish-ubuntu.yml index cc5e1f3f00..caec73b10a 100644 --- a/.github/workflows/nym-connect-publish-ubuntu.yml +++ b/.github/workflows/nym-connect-publish-ubuntu.yml @@ -19,7 +19,7 @@ jobs: outputs: release_id: ${{ steps.create-release.outputs.id }} - release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }} + release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].published_at }} version: ${{ steps.release-info.outputs.version }} filename: ${{ steps.release-info.outputs.filename }} file_hash: ${{ steps.release-info.outputs.file_hash }} @@ -85,8 +85,9 @@ jobs: ref=${{ github.ref_name }} semver="${ref##nym-connect-}" && semver="${semver##v}" echo "version=${semver}" >> "$GITHUB_OUTPUT" - echo "filename=nym-connect_${version}_amd64.AppImage" >> "$GITHUB_OUTPUT" + echo "filename=nym-connect_${semver}_amd64.AppImage" >> "$GITHUB_OUTPUT" echo "file_hash=${{ hashFiles('nym-connect/desktop/target/release/bundle/appimage/nym-connect_*_amd64.AppImage') }}" >> "$GITHUB_OUTPUT" + push-release-data: if: ${{ (startsWith(github.ref, 'refs/tags/nym-connect-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }} uses: ./.github/workflows/push-release-data.yml diff --git a/.github/workflows/nym-connect-publish-windows10.yml b/.github/workflows/nym-connect-publish-windows10.yml index 1b4b1be2cc..aeb04dc872 100644 --- a/.github/workflows/nym-connect-publish-windows10.yml +++ b/.github/workflows/nym-connect-publish-windows10.yml @@ -19,7 +19,7 @@ jobs: outputs: release_id: ${{ steps.create-release.outputs.id }} - release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }} + release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].published_at }} version: ${{ steps.release-info.outputs.version }} filename: ${{ steps.release-info.outputs.filename }} file_hash: ${{ steps.release-info.outputs.file_hash }} @@ -104,7 +104,7 @@ jobs: ref=${{ github.ref_name }} semver="${ref##nym-connect-}" && semver="${semver##v}" echo "version=${semver}" >> "$GITHUB_OUTPUT" - echo "filename=nym-connect_${version}_x64_en-US.msi" >> "$GITHUB_OUTPUT" + echo "filename=nym-connect_${semver}_x64_en-US.msi" >> "$GITHUB_OUTPUT" echo "file_hash=${{ hashFiles('nym-connect/desktop/target/release/bundle/msi/nym-connect_*_x64_en-US.msi') }}" >> "$GITHUB_OUTPUT" push-release-data: diff --git a/.github/workflows/nym-wallet-publish-macos.yml b/.github/workflows/nym-wallet-publish-macos.yml index 408a3b7406..5db06a8f52 100644 --- a/.github/workflows/nym-wallet-publish-macos.yml +++ b/.github/workflows/nym-wallet-publish-macos.yml @@ -19,7 +19,7 @@ jobs: outputs: release_id: ${{ steps.create-release.outputs.id }} - release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }} + release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].published_at }} version: ${{ steps.release-info.outputs.version }} filename: ${{ steps.release-info.outputs.filename }} file_hash: ${{ steps.release-info.outputs.file_hash }} @@ -106,7 +106,7 @@ jobs: ref=${{ github.ref_name }} semver="${ref##nym-wallet-}" && semver="${semver##v}" echo "version=${semver}" >> "$GITHUB_OUTPUT" - echo "filename=nym-wallet_${version}_x64.dmg" >> "$GITHUB_OUTPUT" + echo "filename=nym-wallet_${semver}_x64.dmg" >> "$GITHUB_OUTPUT" echo "file_hash=${{ hashFiles('nym-wallet/target/release/bundle/dmg/nym-wallet_*_x64.dmg') }}" >> "$GITHUB_OUTPUT" push-release-data: diff --git a/.github/workflows/nym-wallet-publish-ubuntu.yml b/.github/workflows/nym-wallet-publish-ubuntu.yml index 9e9ee904cd..52887950fa 100644 --- a/.github/workflows/nym-wallet-publish-ubuntu.yml +++ b/.github/workflows/nym-wallet-publish-ubuntu.yml @@ -19,7 +19,7 @@ jobs: outputs: release_id: ${{ steps.create-release.outputs.id }} - release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }} + release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].published_at }} version: ${{ steps.release-info.outputs.version }} filename: ${{ steps.release-info.outputs.filename }} file_hash: ${{ steps.release-info.outputs.file_hash }} @@ -83,7 +83,7 @@ jobs: ref=${{ github.ref_name }} semver="${ref##nym-wallet-}" && semver="${semver##v}" echo "version=${semver}" >> "$GITHUB_OUTPUT" - echo "filename=nym-wallet_${version}_amd64.AppImage" >> "$GITHUB_OUTPUT" + echo "filename=nym-wallet_${semver}_amd64.AppImage" >> "$GITHUB_OUTPUT" echo "file_hash=${{ hashFiles('nym-wallet/target/release/bundle/appimage/nym-wallet_*_amd64.AppImage') }}" >> "$GITHUB_OUTPUT" push-release-data: diff --git a/.github/workflows/nym-wallet-publish-windows10.yml b/.github/workflows/nym-wallet-publish-windows10.yml index 56a332a75d..a7be3e4a37 100644 --- a/.github/workflows/nym-wallet-publish-windows10.yml +++ b/.github/workflows/nym-wallet-publish-windows10.yml @@ -19,7 +19,7 @@ jobs: outputs: release_id: ${{ steps.create-release.outputs.id }} - release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }} + release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].published_at }} version: ${{ steps.release-info.outputs.version }} filename: ${{ steps.release-info.outputs.filename }} file_hash: ${{ steps.release-info.outputs.file_hash }} @@ -103,7 +103,7 @@ jobs: ref=${{ github.ref_name }} semver="${ref##nym-wallet-}" && semver="${semver##v}" echo "version=${semver}" >> "$GITHUB_OUTPUT" - echo "filename=nym-wallet_${version}_x64_en-US.msi" >> "$GITHUB_OUTPUT" + echo "filename=nym-wallet_${semver}_x64_en-US.msi" >> "$GITHUB_OUTPUT" echo "file_hash=${{ hashFiles('nym-wallet/target/release/bundle/msi/nym-wallet_*_x64_en-US.msi') }}" >> "$GITHUB_OUTPUT" push-release-data: From a47899aa77a5c1bee423cf7951c72d94bc5b4db5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogdan-=C8=98tefan=20Neac=C5=9Fu?= Date: Thu, 27 Jul 2023 12:18:08 +0300 Subject: [PATCH 03/46] Apply fix from feature/ephemera to develop too (#3698) --- common/crypto/Cargo.toml | 4 +- .../crypto/src/asymmetric/encryption/mod.rs | 6 + common/crypto/src/asymmetric/identity/mod.rs | 2 + common/nymsphinx/acknowledgements/Cargo.toml | 2 +- common/nymsphinx/addressing/Cargo.toml | 2 +- common/nymsphinx/forwarding/Cargo.toml | 2 +- common/nymsphinx/params/Cargo.toml | 4 + common/nymsphinx/params/src/packet_sizes.rs | 43 +- common/nymsphinx/routing/Cargo.toml | 4 +- common/nymsphinx/types/Cargo.toml | 8 +- common/nymsphinx/types/src/lib.rs | 28 ++ common/topology/Cargo.toml | 4 +- common/topology/src/error.rs | 1 + contracts/Cargo.lock | 448 +----------------- nym-connect/desktop/Cargo.lock | 2 - nym-wallet/Cargo.lock | 137 +----- 16 files changed, 112 insertions(+), 585 deletions(-) diff --git a/common/crypto/Cargo.toml b/common/crypto/Cargo.toml index c6521d9056..27702da016 100644 --- a/common/crypto/Cargo.toml +++ b/common/crypto/Cargo.toml @@ -27,7 +27,7 @@ thiserror = "1.0.37" zeroize = { workspace = true, optional = true, features = ["zeroize_derive"] } # internal -nym-sphinx-types = { path = "../nymsphinx/types", version = "0.2.0" } +nym-sphinx-types = { path = "../nymsphinx/types", version = "0.2.0", default-features = false } nym-pemstore = { path = "../../common/pemstore", version = "0.3.0" } [dev-dependencies] @@ -38,3 +38,5 @@ serde = ["serde_crate", "serde_bytes", "ed25519-dalek/serde", "x25519-dalek/serd asymmetric = ["x25519-dalek", "ed25519-dalek", "zeroize"] hashing = ["blake3", "digest", "hkdf", "hmac", "generic-array"] symmetric = ["aes", "ctr", "cipher", "generic-array"] +sphinx = ["nym-sphinx-types/sphinx"] +outfox = ["nym-sphinx-types/outfox"] diff --git a/common/crypto/src/asymmetric/encryption/mod.rs b/common/crypto/src/asymmetric/encryption/mod.rs index 5052e785a0..6c45d41d60 100644 --- a/common/crypto/src/asymmetric/encryption/mod.rs +++ b/common/crypto/src/asymmetric/encryption/mod.rs @@ -273,36 +273,42 @@ impl PemStorableKey for PrivateKey { } // compatibility with sphinx keys: +#[cfg(feature = "sphinx")] impl From for nym_sphinx_types::PublicKey { fn from(key: PublicKey) -> Self { nym_sphinx_types::PublicKey::from(key.to_bytes()) } } +#[cfg(feature = "sphinx")] impl<'a> From<&'a PublicKey> for nym_sphinx_types::PublicKey { fn from(key: &'a PublicKey) -> Self { nym_sphinx_types::PublicKey::from((*key).to_bytes()) } } +#[cfg(feature = "sphinx")] impl From for PublicKey { fn from(pub_key: nym_sphinx_types::PublicKey) -> Self { Self(x25519_dalek::PublicKey::from(*pub_key.as_bytes())) } } +#[cfg(feature = "sphinx")] impl From for nym_sphinx_types::PrivateKey { fn from(key: PrivateKey) -> Self { nym_sphinx_types::PrivateKey::from(key.to_bytes()) } } +#[cfg(feature = "sphinx")] impl<'a> From<&'a PrivateKey> for nym_sphinx_types::PrivateKey { fn from(key: &'a PrivateKey) -> Self { nym_sphinx_types::PrivateKey::from(key.to_bytes()) } } +#[cfg(feature = "sphinx")] impl From for PrivateKey { fn from(private_key: nym_sphinx_types::PrivateKey) -> Self { let private_key_bytes = private_key.to_bytes(); diff --git a/common/crypto/src/asymmetric/identity/mod.rs b/common/crypto/src/asymmetric/identity/mod.rs index c552206da3..efe11acf4f 100644 --- a/common/crypto/src/asymmetric/identity/mod.rs +++ b/common/crypto/src/asymmetric/identity/mod.rs @@ -5,6 +5,7 @@ pub use ed25519_dalek::ed25519::signature::Signature as SignatureTrait; pub use ed25519_dalek::SignatureError; pub use ed25519_dalek::{Verifier, PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, SIGNATURE_LENGTH}; use nym_pemstore::traits::{PemStorableKey, PemStorableKeyPair}; +#[cfg(feature = "sphinx")] use nym_sphinx_types::{DestinationAddressBytes, DESTINATION_ADDRESS_LENGTH}; use std::fmt::{self, Display, Formatter}; use std::str::FromStr; @@ -113,6 +114,7 @@ impl Display for PublicKey { } impl PublicKey { + #[cfg(feature = "sphinx")] pub fn derive_destination_address(&self) -> DestinationAddressBytes { let mut temporary_address = [0u8; DESTINATION_ADDRESS_LENGTH]; let public_key_bytes = self.to_bytes(); diff --git a/common/nymsphinx/acknowledgements/Cargo.toml b/common/nymsphinx/acknowledgements/Cargo.toml index 95b3d8b30c..da9977d1f3 100644 --- a/common/nymsphinx/acknowledgements/Cargo.toml +++ b/common/nymsphinx/acknowledgements/Cargo.toml @@ -19,7 +19,7 @@ nym-pemstore = { path = "../../pemstore" } nym-sphinx-addressing = { path = "../addressing" } nym-sphinx-params = { path = "../params" } nym-sphinx-routing = { path = "../routing" } -nym-sphinx-types = { path = "../types" } +nym-sphinx-types = { path = "../types", features = ["sphinx"] } nym-topology = { path = "../../topology" } [features] diff --git a/common/nymsphinx/addressing/Cargo.toml b/common/nymsphinx/addressing/Cargo.toml index f9c646e04b..c6bc2856e3 100644 --- a/common/nymsphinx/addressing/Cargo.toml +++ b/common/nymsphinx/addressing/Cargo.toml @@ -9,7 +9,7 @@ repository = { workspace = true } [dependencies] nym-crypto = { path = "../../crypto", features = ["asymmetric"] } # all addresses are expressed in terms on their crypto keys -nym-sphinx-types = { path = "../types" } # we need to be able to refer to some types defined inside sphinx crate +nym-sphinx-types = { path = "../types", features = ["sphinx"] } # we need to be able to refer to some types defined inside sphinx crate serde = "1.0" # implementing serialization/deserialization for some types, like `Recipient` thiserror = "1.0.37" diff --git a/common/nymsphinx/forwarding/Cargo.toml b/common/nymsphinx/forwarding/Cargo.toml index 6509098398..4060cbf076 100644 --- a/common/nymsphinx/forwarding/Cargo.toml +++ b/common/nymsphinx/forwarding/Cargo.toml @@ -10,6 +10,6 @@ repository = { workspace = true } [dependencies] nym-sphinx-addressing = { path = "../addressing" } nym-sphinx-params = { path = "../params" } -nym-sphinx-types = { path = "../types" } +nym-sphinx-types = { path = "../types", features = ["sphinx", "outfox"] } nym-outfox = { path = "../../../nym-outfox" } thiserror = "1" diff --git a/common/nymsphinx/params/Cargo.toml b/common/nymsphinx/params/Cargo.toml index bc9b40b9a8..57872bb0ca 100644 --- a/common/nymsphinx/params/Cargo.toml +++ b/common/nymsphinx/params/Cargo.toml @@ -13,3 +13,7 @@ serde = { workspace = true, features = ["derive"] } nym-crypto = { path = "../../crypto", features = ["hashing", "symmetric"] } nym-sphinx-types = { path = "../types" } + +[features] +sphinx = ["nym-crypto/sphinx", "nym-sphinx-types/outfox"] +outfox = ["nym-crypto/outfox", "nym-sphinx-types/outfox"] diff --git a/common/nymsphinx/params/src/packet_sizes.rs b/common/nymsphinx/params/src/packet_sizes.rs index a6613f3024..58d9681efc 100644 --- a/common/nymsphinx/params/src/packet_sizes.rs +++ b/common/nymsphinx/params/src/packet_sizes.rs @@ -1,11 +1,11 @@ // Copyright 2021-2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::{PacketType, FRAG_ID_LEN}; -use nym_sphinx_types::header::HEADER_SIZE; -use nym_sphinx_types::{ - MIN_PACKET_SIZE, MIX_PARAMS_LEN, OUTFOX_PACKET_OVERHEAD, PAYLOAD_OVERHEAD_SIZE, -}; +use crate::PacketType; +#[cfg(feature = "sphinx")] +use nym_sphinx_types::{header::HEADER_SIZE, PAYLOAD_OVERHEAD_SIZE}; +#[cfg(feature = "outfox")] +use nym_sphinx_types::{MIN_PACKET_SIZE, MIX_PARAMS_LEN, OUTFOX_PACKET_OVERHEAD}; use serde::{Deserialize, Serialize}; use std::cmp::Ordering; use std::convert::TryFrom; @@ -14,6 +14,7 @@ use std::str::FromStr; use thiserror::Error; // each sphinx packet contains mandatory header and payload padding + markers +#[cfg(feature = "sphinx")] const SPHINX_PACKET_OVERHEAD: usize = HEADER_SIZE + PAYLOAD_OVERHEAD_SIZE; // it's up to the smart people to figure those values out : ) @@ -22,15 +23,23 @@ const SPHINX_PACKET_OVERHEAD: usize = HEADER_SIZE + PAYLOAD_OVERHEAD_SIZE; // TODO: I'm not entirely sure if we can easily extract `::NonceSize` // into a const usize before relevant stuff is stabilised in rust... +#[cfg(feature = "sphinx")] const ACK_IV_SIZE: usize = 16; -const ACK_PACKET_SIZE: usize = ACK_IV_SIZE + FRAG_ID_LEN + SPHINX_PACKET_OVERHEAD; +#[cfg(feature = "sphinx")] +const ACK_PACKET_SIZE: usize = ACK_IV_SIZE + crate::FRAG_ID_LEN + SPHINX_PACKET_OVERHEAD; +#[cfg(feature = "sphinx")] const REGULAR_PACKET_SIZE: usize = 2 * 1024 + SPHINX_PACKET_OVERHEAD; +#[cfg(feature = "sphinx")] const EXTENDED_PACKET_SIZE_8: usize = 8 * 1024 + SPHINX_PACKET_OVERHEAD; +#[cfg(feature = "sphinx")] const EXTENDED_PACKET_SIZE_16: usize = 16 * 1024 + SPHINX_PACKET_OVERHEAD; +#[cfg(feature = "sphinx")] const EXTENDED_PACKET_SIZE_32: usize = 32 * 1024 + SPHINX_PACKET_OVERHEAD; +#[cfg(feature = "outfox")] const OUTFOX_ACK_PACKET_SIZE: usize = MIN_PACKET_SIZE + OUTFOX_PACKET_OVERHEAD; +#[cfg(feature = "outfox")] const OUTFOX_REGULAR_PACKET_SIZE: usize = 2 * 1024 + OUTFOX_PACKET_OVERHEAD; #[derive(Debug, Error)] @@ -153,38 +162,55 @@ impl TryFrom for PacketSize { impl PacketSize { pub const fn size(self) -> usize { + #[allow(unreachable_patterns)] match self { + #[cfg(feature = "sphinx")] PacketSize::RegularPacket => REGULAR_PACKET_SIZE, + #[cfg(feature = "sphinx")] PacketSize::AckPacket => ACK_PACKET_SIZE, + #[cfg(feature = "sphinx")] PacketSize::ExtendedPacket8 => EXTENDED_PACKET_SIZE_8, + #[cfg(feature = "sphinx")] PacketSize::ExtendedPacket16 => EXTENDED_PACKET_SIZE_16, + #[cfg(feature = "sphinx")] PacketSize::ExtendedPacket32 => EXTENDED_PACKET_SIZE_32, + #[cfg(feature = "outfox")] PacketSize::OutfoxRegularPacket => OUTFOX_REGULAR_PACKET_SIZE, + #[cfg(feature = "outfox")] PacketSize::OutfoxAckPacket => OUTFOX_ACK_PACKET_SIZE, + _ => 0, } } pub const fn header_size(&self) -> usize { + #[allow(unreachable_patterns)] match self { + #[cfg(feature = "sphinx")] PacketSize::RegularPacket | PacketSize::AckPacket | PacketSize::ExtendedPacket8 | PacketSize::ExtendedPacket16 | PacketSize::ExtendedPacket32 => HEADER_SIZE, + #[cfg(feature = "outfox")] PacketSize::OutfoxRegularPacket | PacketSize::OutfoxAckPacket => MIX_PARAMS_LEN, + _ => 0, } } pub const fn payload_overhead(&self) -> usize { + #[allow(unreachable_patterns)] match self { + #[cfg(feature = "sphinx")] PacketSize::RegularPacket | PacketSize::AckPacket | PacketSize::ExtendedPacket8 | PacketSize::ExtendedPacket16 | PacketSize::ExtendedPacket32 => PAYLOAD_OVERHEAD_SIZE, + #[cfg(feature = "outfox")] PacketSize::OutfoxRegularPacket | PacketSize::OutfoxAckPacket => { OUTFOX_PACKET_OVERHEAD - MIX_PARAMS_LEN // Mix params are calculated into the total overhead so we take them out here } + _ => 0, } } @@ -242,11 +268,16 @@ impl PacketSize { plaintext_size: usize, packet_type: PacketType, ) -> Result { + #[allow(unreachable_patterns)] let overhead = match packet_type { + #[cfg(feature = "sphinx")] PacketType::Mix => SPHINX_PACKET_OVERHEAD, #[allow(deprecated)] + #[cfg(feature = "sphinx")] PacketType::Vpn => SPHINX_PACKET_OVERHEAD, + #[cfg(feature = "outfox")] PacketType::Outfox => OUTFOX_PACKET_OVERHEAD, + _ => 0, }; let packet_size = plaintext_size + overhead; Self::get_type(packet_size) diff --git a/common/nymsphinx/routing/Cargo.toml b/common/nymsphinx/routing/Cargo.toml index c0f7cf7628..37b8d5a4dc 100644 --- a/common/nymsphinx/routing/Cargo.toml +++ b/common/nymsphinx/routing/Cargo.toml @@ -11,4 +11,6 @@ repository = { workspace = true } thiserror = { workspace = true } nym-sphinx-addressing = { path = "../addressing" } -nym-sphinx-types = { path = "../types" } \ No newline at end of file +nym-sphinx-types = { path = "../types", features = ["sphinx"] } + +[features] \ No newline at end of file diff --git a/common/nymsphinx/types/Cargo.toml b/common/nymsphinx/types/Cargo.toml index 2c52ef03d9..0569ef1406 100644 --- a/common/nymsphinx/types/Cargo.toml +++ b/common/nymsphinx/types/Cargo.toml @@ -8,6 +8,10 @@ license = { workspace = true } repository = { workspace = true } [dependencies] -sphinx-packet = { version = "0.1.0" } -nym-outfox = { path = "../../../nym-outfox" } +sphinx-packet = { version = "0.1.0", optional = true } +nym-outfox = { path = "../../../nym-outfox", optional = true } thiserror = "1" + +[features] +sphinx = ["sphinx-packet"] +outfox = ["nym-outfox"] diff --git a/common/nymsphinx/types/src/lib.rs b/common/nymsphinx/types/src/lib.rs index bd3063f939..d75060e9b0 100644 --- a/common/nymsphinx/types/src/lib.rs +++ b/common/nymsphinx/types/src/lib.rs @@ -1,12 +1,15 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +#[cfg(feature = "outfox")] pub use nym_outfox::{ constants::MIN_PACKET_SIZE, constants::MIX_PARAMS_LEN, constants::OUTFOX_PACKET_OVERHEAD, error::OutfoxError, }; // re-exporting types and constants available in sphinx +#[cfg(feature = "outfox")] use nym_outfox::packet::{OutfoxPacket, OutfoxProcessedPacket}; +#[cfg(feature = "sphinx")] pub use sphinx_packet::{ constants::{ self, DESTINATION_ADDRESS_LENGTH, IDENTIFIER_LENGTH, MAX_PATH_LENGTH, NODE_ADDRESS_LENGTH, @@ -20,6 +23,7 @@ pub use sphinx_packet::{ surb::{SURBMaterial, SURB}, Error as SphinxError, ProcessedPacket, }; +#[cfg(feature = "sphinx")] use sphinx_packet::{SphinxPacket, SphinxPacketBuilder}; use std::{array::TryFromSliceError, fmt}; use thiserror::Error; @@ -27,9 +31,11 @@ use thiserror::Error; #[derive(Error, Debug)] pub enum NymPacketError { #[error("Sphinx error: {0}")] + #[cfg(feature = "sphinx")] Sphinx(#[from] sphinx_packet::Error), #[error("Outfox error: {0}")] + #[cfg(feature = "outfox")] Outfox(#[from] nym_outfox::error::OutfoxError), #[error("{0}")] @@ -38,31 +44,40 @@ pub enum NymPacketError { #[allow(clippy::large_enum_variant)] pub enum NymPacket { + #[cfg(feature = "sphinx")] Sphinx(SphinxPacket), + #[cfg(feature = "outfox")] Outfox(OutfoxPacket), } pub enum NymProcessedPacket { + #[cfg(feature = "sphinx")] Sphinx(ProcessedPacket), + #[cfg(feature = "outfox")] Outfox(OutfoxProcessedPacket), } impl fmt::Debug for NymPacket { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + #[allow(unreachable_patterns)] match &self { + #[cfg(feature = "sphinx")] NymPacket::Sphinx(packet) => f .debug_struct("NymPacket::Sphinx") .field("len", &packet.len()) .finish(), + #[cfg(feature = "outfox")] NymPacket::Outfox(packet) => f .debug_struct("NymPacket::Outfox") .field("len", &packet.len()) .finish(), + _ => write!(f, ""), } } } impl NymPacket { + #[cfg(feature = "sphinx")] pub fn sphinx_build>( size: usize, message: M, @@ -76,10 +91,12 @@ impl NymPacket { .build_packet(message, route, destination, delays)?, )) } + #[cfg(feature = "sphinx")] pub fn sphinx_from_bytes(bytes: &[u8]) -> Result { Ok(NymPacket::Sphinx(SphinxPacket::from_bytes(bytes)?)) } + #[cfg(feature = "outfox")] pub fn outfox_build>( payload: M, route: &[Node], @@ -94,14 +111,19 @@ impl NymPacket { )?)) } + #[cfg(feature = "outfox")] pub fn outfox_from_bytes(bytes: &[u8]) -> Result { Ok(NymPacket::Outfox(OutfoxPacket::try_from(bytes)?)) } pub fn len(&self) -> usize { + #[allow(unreachable_patterns)] match self { + #[cfg(feature = "sphinx")] NymPacket::Sphinx(packet) => packet.len(), + #[cfg(feature = "outfox")] NymPacket::Outfox(packet) => packet.len(), + _ => 0, } } @@ -110,12 +132,17 @@ impl NymPacket { } pub fn to_bytes(&self) -> Result, NymPacketError> { + #[allow(unreachable_patterns)] match self { + #[cfg(feature = "sphinx")] NymPacket::Sphinx(packet) => Ok(packet.to_bytes()), + #[cfg(feature = "outfox")] NymPacket::Outfox(packet) => Ok(packet.to_bytes()?), + _ => Ok(vec![]), } } + #[cfg(feature = "sphinx")] pub fn process( self, node_secret_key: &PrivateKey, @@ -124,6 +151,7 @@ impl NymPacket { NymPacket::Sphinx(packet) => { Ok(NymProcessedPacket::Sphinx(packet.process(node_secret_key)?)) } + #[cfg(feature = "outfox")] NymPacket::Outfox(mut packet) => { let next_address = packet.decode_next_layer(node_secret_key)?; Ok(NymProcessedPacket::Outfox(OutfoxProcessedPacket::new( diff --git a/common/topology/Cargo.toml b/common/topology/Cargo.toml index 1d41a93ee4..bfe2c98573 100644 --- a/common/topology/Cargo.toml +++ b/common/topology/Cargo.toml @@ -19,10 +19,10 @@ thiserror = "1.0.37" async-trait = { workspace = true, optional = true } ## internal -nym-crypto = { path = "../crypto" } +nym-crypto = { path = "../crypto", features = ["sphinx", "outfox"] } nym-mixnet-contract-common = { path = "../cosmwasm-smart-contracts/mixnet-contract" } nym-sphinx-addressing = { path = "../nymsphinx/addressing" } -nym-sphinx-types = { path = "../nymsphinx/types" } +nym-sphinx-types = { path = "../nymsphinx/types", features = ["sphinx", "outfox"] } nym-sphinx-routing = { path = "../nymsphinx/routing" } nym-bin-common = { path = "../bin-common" } diff --git a/common/topology/src/error.rs b/common/topology/src/error.rs index bb36b42886..3f2523576f 100644 --- a/common/topology/src/error.rs +++ b/common/topology/src/error.rs @@ -41,6 +41,7 @@ pub enum NymTopologyError { PayloadBuilder, #[error("Outfox: {0}")] + #[cfg(feature = "outfox")] Outfox(#[from] nym_sphinx_types::OutfoxError), #[error("{0}")] diff --git a/contracts/Cargo.lock b/contracts/Cargo.lock index 0c3efd0a24..3d719dd6dc 100644 --- a/contracts/Cargo.lock +++ b/contracts/Cargo.lock @@ -2,29 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "aead" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" -dependencies = [ - "crypto-common", - "generic-array 0.14.6", -] - -[[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", - "opaque-debug 0.3.0", -] - [[package]] name = "ahash" version = "0.7.6" @@ -42,18 +19,6 @@ version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" -[[package]] -name = "arrayref" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" - -[[package]] -name = "arrayvec" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" - [[package]] name = "autocfg" version = "1.1.0" @@ -90,39 +55,13 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "blake2" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330" -dependencies = [ - "byte-tools", - "crypto-mac 0.7.0", - "digest 0.8.1", - "opaque-debug 0.2.3", -] - -[[package]] -name = "blake3" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "199c42ab6972d92c9f8995f086273d25c42fc0f7b2a1fcefba465c1352d25ba5" -dependencies = [ - "arrayref", - "arrayvec", - "cc", - "cfg-if", - "constant_time_eq", - "digest 0.10.7", -] - [[package]] name = "block-buffer" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "generic-array 0.14.6", + "generic-array", ] [[package]] @@ -131,7 +70,7 @@ version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "generic-array 0.14.6", + "generic-array", ] [[package]] @@ -146,12 +85,6 @@ version = "3.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b1ce199063694f33ffb7dd4e0ee620741495c32833cde5aa08f02a0bf96f0c8" -[[package]] -name = "byte-tools" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" - [[package]] name = "byteorder" version = "1.4.3" @@ -179,60 +112,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "chacha" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddf3c081b5fba1e5615640aae998e0fbd10c24cbd897ee39ed754a77601a4862" -dependencies = [ - "byteorder", - "keystream", -] - -[[package]] -name = "chacha20" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" -dependencies = [ - "cfg-if", - "cipher 0.4.4", - "cpufeatures", -] - -[[package]] -name = "chacha20poly1305" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" -dependencies = [ - "aead", - "chacha20", - "cipher 0.4.4", - "poly1305", - "zeroize", -] - -[[package]] -name = "cipher" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" -dependencies = [ - "generic-array 0.14.6", -] - -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", - "zeroize", -] - [[package]] name = "coconut-test" version = "0.1.0" @@ -264,12 +143,6 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" -[[package]] -name = "constant_time_eq" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" - [[package]] name = "cosmwasm-crypto" version = "1.2.5" @@ -355,49 +228,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crossbeam-channel" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" -dependencies = [ - "cfg-if", -] - [[package]] name = "crunchy" version = "0.2.2" @@ -410,9 +240,9 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ - "generic-array 0.14.6", + "generic-array", "rand_core 0.6.4", - "subtle 2.4.1", + "subtle", "zeroize", ] @@ -422,40 +252,10 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "generic-array 0.14.6", - "rand_core 0.6.4", + "generic-array", "typenum", ] -[[package]] -name = "crypto-mac" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" -dependencies = [ - "generic-array 0.12.4", - "subtle 1.0.0", -] - -[[package]] -name = "crypto-mac" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" -dependencies = [ - "generic-array 0.14.6", - "subtle 2.4.1", -] - -[[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 = "curve25519-dalek" version = "3.2.0" @@ -465,7 +265,7 @@ dependencies = [ "byteorder", "digest 0.9.0", "rand_core 0.5.1", - "subtle 2.4.1", + "subtle", "zeroize", ] @@ -676,22 +476,13 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "digest" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" -dependencies = [ - "generic-array 0.12.4", -] - [[package]] name = "digest" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array 0.14.6", + "generic-array", ] [[package]] @@ -702,7 +493,7 @@ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", "crypto-common", - "subtle 2.4.1", + "subtle", ] [[package]] @@ -778,12 +569,12 @@ dependencies = [ "der", "digest 0.10.7", "ff", - "generic-array 0.14.6", + "generic-array", "group", "pkcs8", "rand_core 0.6.4", "sec1", - "subtle 2.4.1", + "subtle", "zeroize", ] @@ -844,7 +635,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" dependencies = [ "rand_core 0.6.4", - "subtle 2.4.1", + "subtle", ] [[package]] @@ -963,15 +754,6 @@ dependencies = [ "slab", ] -[[package]] -name = "generic-array" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" -dependencies = [ - "typenum", -] - [[package]] name = "generic-array" version = "0.14.6" @@ -1002,10 +784,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", - "js-sys", "libc", "wasi 0.11.0+wasi-snapshot-preview1", - "wasm-bindgen", ] [[package]] @@ -1041,7 +821,7 @@ checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" dependencies = [ "ff", "rand_core 0.6.4", - "subtle 2.4.1", + "subtle", ] [[package]] @@ -1065,26 +845,6 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[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 = "hmac" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" -dependencies = [ - "crypto-mac 0.11.1", - "digest 0.9.0", -] - [[package]] name = "hmac" version = "0.12.1" @@ -1120,15 +880,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "generic-array 0.14.6", -] - [[package]] name = "instant" version = "0.1.12" @@ -1194,12 +945,6 @@ dependencies = [ "sha2 0.10.6", ] -[[package]] -name = "keystream" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33070833c9ee02266356de0c43f723152bd38bd96ddf52c82b3af10c9138b28" - [[package]] name = "lazy_static" version = "1.4.0" @@ -1224,12 +969,6 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "libm" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" - [[package]] name = "libz-sys" version = "1.1.8" @@ -1248,18 +987,6 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" -[[package]] -name = "lioness" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae926706ba42c425c9457121178330d75e273df2e82e28b758faf3de3a9acb9" -dependencies = [ - "arrayref", - "blake2", - "chacha", - "keystream", -] - [[package]] name = "log" version = "0.4.17" @@ -1275,15 +1002,6 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - [[package]] name = "mixnet-vesting-integration-tests" version = "0.1.0" @@ -1300,26 +1018,6 @@ dependencies = [ "rand_chacha 0.2.2", ] -[[package]] -name = "num-traits" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" -dependencies = [ - "autocfg", - "libm", -] - -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - [[package]] name = "nym-coconut-bandwidth" version = "0.1.0" @@ -1507,23 +1205,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "nym-outfox" -version = "0.1.0" -dependencies = [ - "blake3", - "chacha20", - "chacha20poly1305", - "curve25519-dalek", - "getrandom 0.2.10", - "log", - "rand 0.7.3", - "rayon", - "sphinx-packet", - "thiserror", - "zeroize", -] - [[package]] name = "nym-pemstore" version = "0.3.0" @@ -1571,8 +1252,6 @@ dependencies = [ name = "nym-sphinx-types" version = "0.2.0" dependencies = [ - "nym-outfox", - "sphinx-packet", "thiserror", ] @@ -1616,12 +1295,6 @@ version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" -[[package]] -name = "opaque-debug" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" - [[package]] name = "opaque-debug" version = "0.3.0" @@ -1673,17 +1346,6 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" -[[package]] -name = "poly1305" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" -dependencies = [ - "cpufeatures", - "opaque-debug 0.3.0", - "universal-hash", -] - [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1823,16 +1485,6 @@ dependencies = [ "getrandom 0.2.10", ] -[[package]] -name = "rand_distr" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e9532ada3929fb8b2e9dbe28d1e06c9b2cc65813f074fcb6bd5fbefeff9d56" -dependencies = [ - "num-traits", - "rand 0.7.3", -] - [[package]] name = "rand_hc" version = "0.2.0" @@ -1842,28 +1494,6 @@ dependencies = [ "rand_core 0.5.1", ] -[[package]] -name = "rayon" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "num_cpus", -] - [[package]] name = "redox_syscall" version = "0.3.5" @@ -1895,7 +1525,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ "crypto-bigint", - "hmac 0.12.1", + "hmac", "zeroize", ] @@ -1996,12 +1626,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - [[package]] name = "sec1" version = "0.3.0" @@ -2010,9 +1634,9 @@ checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ "base16ct", "der", - "generic-array 0.14.6", + "generic-array", "pkcs8", - "subtle 2.4.1", + "subtle", "zeroize", ] @@ -2103,7 +1727,7 @@ dependencies = [ "cfg-if", "cpufeatures", "digest 0.9.0", - "opaque-debug 0.3.0", + "opaque-debug", ] [[package]] @@ -2136,30 +1760,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "sphinx-packet" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc43eda802856ee82a7555c7b75ceb9e07451741c7a2f5f23d036020e01189d4" -dependencies = [ - "aes", - "arrayref", - "blake2", - "bs58", - "byteorder", - "chacha", - "curve25519-dalek", - "digest 0.9.0", - "hkdf", - "hmac 0.11.0", - "lioness", - "log", - "rand 0.7.3", - "rand_distr", - "sha2 0.9.9", - "subtle 2.4.1", -] - [[package]] name = "spki" version = "0.6.0" @@ -2176,12 +1776,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "subtle" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" - [[package]] name = "subtle" version = "2.4.1" @@ -2333,16 +1927,6 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "universal-hash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" -dependencies = [ - "crypto-common", - "subtle 2.4.1", -] - [[package]] name = "url" version = "2.3.1" diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 6287fadf38..c7bb0c20a6 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -4179,8 +4179,6 @@ dependencies = [ name = "nym-sphinx-types" version = "0.2.0" dependencies = [ - "nym-outfox", - "sphinx-packet", "thiserror", ] diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index 2da872c4fc..5768438108 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -120,12 +120,6 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" -[[package]] -name = "arrayvec" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" - [[package]] name = "async-trait" version = "0.1.64" @@ -301,20 +295,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "blake3" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "199c42ab6972d92c9f8995f086273d25c42fc0f7b2a1fcefba465c1352d25ba5" -dependencies = [ - "arrayref", - "arrayvec", - "cc", - "cfg-if", - "constant_time_eq", - "digest 0.10.7", -] - [[package]] name = "block" version = "0.1.6" @@ -525,30 +505,6 @@ dependencies = [ "keystream", ] -[[package]] -name = "chacha20" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" -dependencies = [ - "cfg-if", - "cipher 0.4.4", - "cpufeatures", -] - -[[package]] -name = "chacha20poly1305" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" -dependencies = [ - "aead", - "chacha20", - "cipher 0.4.4", - "poly1305", - "zeroize", -] - [[package]] name = "cipher" version = "0.3.0" @@ -566,7 +522,6 @@ checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ "crypto-common", "inout", - "zeroize", ] [[package]] @@ -700,12 +655,6 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" -[[package]] -name = "constant_time_eq" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" - [[package]] name = "convert_case" version = "0.4.0" @@ -879,30 +828,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "crossbeam-deque" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset 0.9.0", - "scopeguard", -] - [[package]] name = "crossbeam-utils" version = "0.8.14" @@ -1640,7 +1565,7 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e1c54951450cbd39f3dbcf1005ac413b49487dabf18a720ad2383eccfeffb92" dependencies = [ - "memoffset 0.6.5", + "memoffset", "rustc_version 0.3.3", ] @@ -2915,15 +2840,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - [[package]] name = "mime" version = "0.3.16" @@ -3328,23 +3244,6 @@ dependencies = [ "url", ] -[[package]] -name = "nym-outfox" -version = "0.1.0" -dependencies = [ - "blake3", - "chacha20", - "chacha20poly1305", - "curve25519-dalek", - "getrandom 0.2.10", - "log", - "rand 0.7.3", - "rayon", - "sphinx-packet", - "thiserror", - "zeroize", -] - [[package]] name = "nym-pemstore" version = "0.3.0" @@ -3369,7 +3268,6 @@ dependencies = [ name = "nym-sphinx-types" version = "0.2.0" dependencies = [ - "nym-outfox", "sphinx-packet", "thiserror", ] @@ -4074,17 +3972,6 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "poly1305" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" -dependencies = [ - "cpufeatures", - "opaque-debug 0.3.0", - "universal-hash", -] - [[package]] name = "polyval" version = "0.6.0" @@ -4336,28 +4223,6 @@ dependencies = [ "cty", ] -[[package]] -name = "rayon" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "num_cpus", -] - [[package]] name = "redox_syscall" version = "0.2.16" From 67435e9cdf261f03fb9edb50fa06647117012624 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 27 Jul 2023 10:20:07 +0100 Subject: [PATCH 04/46] Feature/simplify cli parsing (#3699) * added a global flag to disable the printed out banner inside tty * added a 'build-info' command to our binaries * added binary name to BinaryBuildInformation * clippy --- clients/native/src/commands/build_info.rs | 16 +++ clients/native/src/commands/mod.rs | 22 +++-- clients/native/src/main.rs | 11 ++- clients/socks5/src/commands/build_info.rs | 16 +++ clients/socks5/src/commands/mod.rs | 22 +++-- clients/socks5/src/main.rs | 11 ++- .../bin-common/src/build_information/mod.rs | 99 +++++++++++++------ gateway/src/commands/build_info.rs | 16 +++ gateway/src/commands/mod.rs | 5 + gateway/src/main.rs | 17 ++-- mixnode/src/commands/build_info.rs | 16 +++ mixnode/src/commands/mod.rs | 5 + mixnode/src/main.rs | 22 +++-- nym-api/src/support/cli/mod.rs | 5 +- .../network-requester/src/cli/build_info.rs | 16 +++ .../network-requester/src/cli/mod.rs | 22 +++-- .../network-requester/src/core.rs | 4 +- .../network-requester/src/main.rs | 8 +- 18 files changed, 254 insertions(+), 79 deletions(-) create mode 100644 clients/native/src/commands/build_info.rs create mode 100644 clients/socks5/src/commands/build_info.rs create mode 100644 gateway/src/commands/build_info.rs create mode 100644 mixnode/src/commands/build_info.rs create mode 100644 service-providers/network-requester/src/cli/build_info.rs diff --git a/clients/native/src/commands/build_info.rs b/clients/native/src/commands/build_info.rs new file mode 100644 index 0000000000..e3385bb933 --- /dev/null +++ b/clients/native/src/commands/build_info.rs @@ -0,0 +1,16 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::Args; +use nym_bin_common::bin_info_owned; +use nym_bin_common::output_format::OutputFormat; + +#[derive(Args)] +pub(crate) struct BuildInfo { + #[clap(short, long, default_value_t = OutputFormat::default())] + output: OutputFormat, +} + +pub(crate) fn execute(args: BuildInfo) { + println!("{}", args.output.format(&bin_info_owned!())) +} diff --git a/clients/native/src/commands/mod.rs b/clients/native/src/commands/mod.rs index 08c4f9592d..6badc58748 100644 --- a/clients/native/src/commands/mod.rs +++ b/clients/native/src/commands/mod.rs @@ -10,7 +10,7 @@ use clap::CommandFactory; use clap::{Parser, Subcommand}; use lazy_static::lazy_static; use log::{error, info}; -use nym_bin_common::build_information::BinaryBuildInformation; +use nym_bin_common::bin_info; use nym_bin_common::completions::{fig_generate, ArgShell}; use nym_client_core::client::base_client::storage::gateway_details::{ OnDiskGatewayDetails, PersistedGatewayDetails, @@ -22,12 +22,12 @@ use nym_config::OptionalSet; use std::error::Error; use std::net::IpAddr; +pub(crate) mod build_info; pub(crate) mod init; pub(crate) mod run; lazy_static! { - pub static ref PRETTY_BUILD_INFORMATION: String = - BinaryBuildInformation::new(env!("CARGO_PKG_VERSION")).pretty_print(); + pub static ref PRETTY_BUILD_INFORMATION: String = bin_info!().pretty_print(); } // Helper for passing LONG_VERSION to clap @@ -42,6 +42,10 @@ pub(crate) struct Cli { #[clap(short, long)] pub(crate) config_env_file: Option, + /// Flag used for disabling the printed banner in tty. + #[clap(long)] + pub(crate) no_banner: bool, + #[clap(subcommand)] command: Commands, } @@ -54,6 +58,9 @@ pub(crate) enum Commands { /// Run the Nym client with provided configuration client optionally overriding set parameters Run(run::Run), + /// Show build information of this binary + BuildInfo(build_info::BuildInfo), + /// Generate shell completions Completions(ArgShell), @@ -73,12 +80,13 @@ pub(crate) struct OverrideConfig { enabled_credentials_mode: Option, } -pub(crate) async fn execute(args: &Cli) -> Result<(), Box> { +pub(crate) async fn execute(args: Cli) -> Result<(), Box> { let bin_name = "nym-native-client"; - match &args.command { - Commands::Init(m) => init::execute(m).await?, - Commands::Run(m) => run::execute(m).await?, + match args.command { + Commands::Init(m) => init::execute(&m).await?, + Commands::Run(m) => run::execute(&m).await?, + Commands::BuildInfo(m) => build_info::execute(m), Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name), Commands::GenerateFigSpec => fig_generate(&mut Cli::command(), bin_name), } diff --git a/clients/native/src/main.rs b/clients/native/src/main.rs index cc862b2a88..cf3203b1e3 100644 --- a/clients/native/src/main.rs +++ b/clients/native/src/main.rs @@ -14,10 +14,13 @@ pub mod websocket; #[tokio::main] async fn main() -> Result<(), Box> { - setup_logging(); - maybe_print_banner(crate_name!(), crate_version!()); - let args = commands::Cli::parse(); setup_env(args.config_env_file.as_ref()); - commands::execute(&args).await + + if !args.no_banner { + maybe_print_banner(crate_name!(), crate_version!()); + } + setup_logging(); + + commands::execute(args).await } diff --git a/clients/socks5/src/commands/build_info.rs b/clients/socks5/src/commands/build_info.rs new file mode 100644 index 0000000000..e3385bb933 --- /dev/null +++ b/clients/socks5/src/commands/build_info.rs @@ -0,0 +1,16 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::Args; +use nym_bin_common::bin_info_owned; +use nym_bin_common::output_format::OutputFormat; + +#[derive(Args)] +pub(crate) struct BuildInfo { + #[clap(short, long, default_value_t = OutputFormat::default())] + output: OutputFormat, +} + +pub(crate) fn execute(args: BuildInfo) { + println!("{}", args.output.format(&bin_info_owned!())) +} diff --git a/clients/socks5/src/commands/mod.rs b/clients/socks5/src/commands/mod.rs index 2b5fe425b6..5ef887a3a2 100644 --- a/clients/socks5/src/commands/mod.rs +++ b/clients/socks5/src/commands/mod.rs @@ -10,7 +10,7 @@ use clap::CommandFactory; use clap::{Parser, Subcommand}; use lazy_static::lazy_static; use log::{error, info}; -use nym_bin_common::build_information::BinaryBuildInformation; +use nym_bin_common::bin_info; use nym_bin_common::completions::{fig_generate, ArgShell}; use nym_client_core::client::base_client::storage::gateway_details::{ OnDiskGatewayDetails, PersistedGatewayDetails, @@ -22,12 +22,12 @@ use nym_config::OptionalSet; use nym_sphinx::params::{PacketSize, PacketType}; use std::error::Error; +pub(crate) mod build_info; pub mod init; pub(crate) mod run; lazy_static! { - pub static ref PRETTY_BUILD_INFORMATION: String = - BinaryBuildInformation::new(env!("CARGO_PKG_VERSION")).pretty_print(); + pub static ref PRETTY_BUILD_INFORMATION: String = bin_info!().pretty_print(); } // Helper for passing LONG_VERSION to clap @@ -42,6 +42,10 @@ pub(crate) struct Cli { #[clap(short, long)] pub(crate) config_env_file: Option, + /// Flag used for disabling the printed banner in tty. + #[clap(long)] + pub(crate) no_banner: bool, + #[clap(subcommand)] command: Commands, } @@ -54,6 +58,9 @@ pub(crate) enum Commands { /// Run the Nym client with provided configuration client optionally overriding set parameters Run(run::Run), + /// Show build information of this binary + BuildInfo(build_info::BuildInfo), + /// Generate shell completions Completions(ArgShell), @@ -74,12 +81,13 @@ pub(crate) struct OverrideConfig { outfox: bool, } -pub(crate) async fn execute(args: &Cli) -> Result<(), Box> { +pub(crate) async fn execute(args: Cli) -> Result<(), Box> { let bin_name = "nym-socks5-client"; - match &args.command { - Commands::Init(m) => init::execute(m).await?, - Commands::Run(m) => run::execute(m).await?, + match args.command { + Commands::Init(m) => init::execute(&m).await?, + Commands::Run(m) => run::execute(&m).await?, + Commands::BuildInfo(m) => build_info::execute(m), Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name), Commands::GenerateFigSpec => fig_generate(&mut Cli::command(), bin_name), } diff --git a/clients/socks5/src/main.rs b/clients/socks5/src/main.rs index b592c62817..8e6d899652 100644 --- a/clients/socks5/src/main.rs +++ b/clients/socks5/src/main.rs @@ -13,10 +13,13 @@ pub mod error; #[tokio::main] async fn main() -> Result<(), Box> { - setup_logging(); - maybe_print_banner(crate_name!(), crate_version!()); - let args = commands::Cli::parse(); setup_env(args.config_env_file.as_ref()); - commands::execute(&args).await + + if !args.no_banner { + maybe_print_banner(crate_name!(), crate_version!()); + } + setup_logging(); + + commands::execute(args).await } diff --git a/common/bin-common/src/build_information/mod.rs b/common/bin-common/src/build_information/mod.rs index d4fa7dd5c6..064f8a60fa 100644 --- a/common/bin-common/src/build_information/mod.rs +++ b/common/bin-common/src/build_information/mod.rs @@ -5,9 +5,13 @@ // and be used by our smart contracts use serde::{Deserialize, Serialize}; +use std::fmt::{Display, Formatter}; #[derive(Debug)] pub struct BinaryBuildInformation { + /// Provides the name of the binary, i.e. the content of `CARGO_PKG_NAME` environmental variable. + pub binary_name: &'static str, + // VERGEN_BUILD_TIMESTAMP /// Provides the build timestamp, for example `2021-02-23T20:14:46.558472672+00:00`. pub build_timestamp: &'static str, @@ -43,8 +47,9 @@ pub struct BinaryBuildInformation { impl BinaryBuildInformation { // explicitly require the build_version to be passed as it's binary specific - pub const fn new(build_version: &'static str) -> Self { + pub const fn new(binary_name: &'static str, build_version: &'static str) -> Self { BinaryBuildInformation { + binary_name, build_timestamp: env!("VERGEN_BUILD_TIMESTAMP"), build_version, commit_sha: env!("VERGEN_GIT_SHA"), @@ -58,6 +63,7 @@ impl BinaryBuildInformation { pub fn to_owned(&self) -> BinaryBuildInformationOwned { BinaryBuildInformationOwned { + binary_name: self.binary_name.to_owned(), build_timestamp: self.build_timestamp.to_owned(), build_version: self.build_version.to_owned(), commit_sha: self.commit_sha.to_owned(), @@ -70,39 +76,15 @@ impl BinaryBuildInformation { } pub fn pretty_print(&self) -> String { - format!( - r#" -{:<20}{} -{:<20}{} -{:<20}{} -{:<20}{} -{:<20}{} -{:<20}{} -{:<20}{} -{:<20}{} -"#, - "Build Timestamp:", - self.build_timestamp, - "Build Version:", - self.build_version, - "Commit SHA:", - self.commit_sha, - "Commit Date:", - self.commit_timestamp, - "Commit Branch:", - self.commit_branch, - "rustc Version:", - self.rustc_version, - "rustc Channel:", - self.rustc_channel, - "cargo Profile:", - self.cargo_profile, - ) + self.to_owned().to_string() } } #[derive(Clone, Debug, Serialize, Deserialize)] pub struct BinaryBuildInformationOwned { + /// Provides the name of the binary, i.e. the content of `CARGO_PKG_NAME` environmental variable. + pub binary_name: String, + // VERGEN_BUILD_TIMESTAMP /// Provides the build timestamp, for example `2021-02-23T20:14:46.558472672+00:00`. pub build_timestamp: String, @@ -135,3 +117,62 @@ pub struct BinaryBuildInformationOwned { /// Provides the cargo profile that was used for the build, for example `debug`. pub cargo_profile: String, } + +impl Display for BinaryBuildInformationOwned { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!( + f, + r#" +{:<20}{} +{:<20}{} +{:<20}{} +{:<20}{} +{:<20}{} +{:<20}{} +{:<20}{} +{:<20}{} +{:<20}{} +"#, + "Binary Name:", + self.binary_name, + "Build Timestamp:", + self.build_timestamp, + "Build Version:", + self.build_version, + "Commit SHA:", + self.commit_sha, + "Commit Date:", + self.commit_timestamp, + "Commit Branch:", + self.commit_branch, + "rustc Version:", + self.rustc_version, + "rustc Channel:", + self.rustc_channel, + "cargo Profile:", + self.cargo_profile, + ) + } +} + +// since this macro will get expanded at the callsite, it will pull in correct binary version +#[macro_export] +macro_rules! bin_info { + () => { + $crate::build_information::BinaryBuildInformation::new( + env!("CARGO_PKG_NAME"), + env!("CARGO_PKG_VERSION"), + ) + }; +} + +#[macro_export] +macro_rules! bin_info_owned { + () => { + $crate::build_information::BinaryBuildInformation::new( + env!("CARGO_PKG_NAME"), + env!("CARGO_PKG_VERSION"), + ) + .to_owned() + }; +} diff --git a/gateway/src/commands/build_info.rs b/gateway/src/commands/build_info.rs new file mode 100644 index 0000000000..e3385bb933 --- /dev/null +++ b/gateway/src/commands/build_info.rs @@ -0,0 +1,16 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::Args; +use nym_bin_common::bin_info_owned; +use nym_bin_common::output_format::OutputFormat; + +#[derive(Args)] +pub(crate) struct BuildInfo { + #[clap(short, long, default_value_t = OutputFormat::default())] + output: OutputFormat, +} + +pub(crate) fn execute(args: BuildInfo) { + println!("{}", args.output.format(&bin_info_owned!())) +} diff --git a/gateway/src/commands/mod.rs b/gateway/src/commands/mod.rs index 15775ec757..ed70c8b203 100644 --- a/gateway/src/commands/mod.rs +++ b/gateway/src/commands/mod.rs @@ -18,6 +18,7 @@ use std::error::Error; use std::net::IpAddr; use std::path::PathBuf; +pub(crate) mod build_info; pub(crate) mod init; pub(crate) mod node_details; pub(crate) mod run; @@ -37,6 +38,9 @@ pub(crate) enum Commands { /// Sign text to prove ownership of this mixnode Sign(sign::Sign), + /// Show build information of this binary + BuildInfo(build_info::BuildInfo), + /// Generate shell completions Completions(ArgShell), @@ -67,6 +71,7 @@ pub(crate) async fn execute(args: Cli) -> Result<(), Box node_details::execute(m).await?, Commands::Run(m) => run::execute(m).await?, Commands::Sign(m) => sign::execute(m)?, + Commands::BuildInfo(m) => build_info::execute(m), Commands::Completions(s) => s.generate(&mut crate::Cli::command(), bin_name), Commands::GenerateFigSpec => fig_generate(&mut crate::Cli::command(), bin_name), } diff --git a/gateway/src/main.rs b/gateway/src/main.rs index 9ea8eb679d..5290037266 100644 --- a/gateway/src/main.rs +++ b/gateway/src/main.rs @@ -5,7 +5,7 @@ use clap::{crate_name, crate_version, Parser}; use colored::Colorize; use lazy_static::lazy_static; use log::error; -use nym_bin_common::build_information::BinaryBuildInformation; +use nym_bin_common::bin_info; use nym_bin_common::logging::{maybe_print_banner, setup_logging}; use nym_bin_common::output_format::OutputFormat; use nym_network_defaults::setup_env; @@ -18,8 +18,7 @@ mod node; pub(crate) mod support; lazy_static! { - pub static ref PRETTY_BUILD_INFORMATION: String = - BinaryBuildInformation::new(env!("CARGO_PKG_VERSION")).pretty_print(); + pub static ref PRETTY_BUILD_INFORMATION: String = bin_info!().pretty_print(); } // Helper for passing LONG_VERSION to clap @@ -34,18 +33,24 @@ struct Cli { #[clap(short, long)] pub(crate) config_env_file: Option, + /// Flag used for disabling the printed banner in tty. + #[clap(long)] + pub(crate) no_banner: bool, + #[clap(subcommand)] command: commands::Commands, } #[tokio::main] async fn main() -> Result<(), Box> { - setup_logging(); - maybe_print_banner(crate_name!(), crate_version!()); - let args = Cli::parse(); setup_env(args.config_env_file.as_ref()); + if !args.no_banner { + maybe_print_banner(crate_name!(), crate_version!()); + } + setup_logging(); + commands::execute(args).await.map_err(|err| { if atty::is(atty::Stream::Stdout) { let error_message = format!("{err}").red(); diff --git a/mixnode/src/commands/build_info.rs b/mixnode/src/commands/build_info.rs new file mode 100644 index 0000000000..e3385bb933 --- /dev/null +++ b/mixnode/src/commands/build_info.rs @@ -0,0 +1,16 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::Args; +use nym_bin_common::bin_info_owned; +use nym_bin_common::output_format::OutputFormat; + +#[derive(Args)] +pub(crate) struct BuildInfo { + #[clap(short, long, default_value_t = OutputFormat::default())] + output: OutputFormat, +} + +pub(crate) fn execute(args: BuildInfo) { + println!("{}", args.output.format(&bin_info_owned!())) +} diff --git a/mixnode/src/commands/mod.rs b/mixnode/src/commands/mod.rs index b8c8f84894..e79df8e2ab 100644 --- a/mixnode/src/commands/mod.rs +++ b/mixnode/src/commands/mod.rs @@ -15,6 +15,7 @@ use nym_crypto::bech32_address_validation; use std::net::IpAddr; use std::process; +mod build_info; mod describe; mod init; mod node_details; @@ -38,6 +39,9 @@ pub(crate) enum Commands { /// Show details of this mixnode NodeDetails(node_details::NodeDetails), + /// Show build information of this binary + BuildInfo(build_info::BuildInfo), + /// Generate shell completions Completions(ArgShell), @@ -64,6 +68,7 @@ pub(crate) async fn execute(args: Cli) -> anyhow::Result<()> { Commands::Run(m) => run::execute(&m).await?, Commands::Sign(m) => sign::execute(&m)?, Commands::NodeDetails(m) => node_details::execute(&m)?, + Commands::BuildInfo(m) => build_info::execute(m), Commands::Completions(s) => s.generate(&mut crate::Cli::command(), bin_name), Commands::GenerateFigSpec => fig_generate(&mut crate::Cli::command(), bin_name), } diff --git a/mixnode/src/main.rs b/mixnode/src/main.rs index 5681e02cc7..bdda653edf 100644 --- a/mixnode/src/main.rs +++ b/mixnode/src/main.rs @@ -7,7 +7,8 @@ extern crate rocket; use ::nym_config::defaults::setup_env; use clap::{crate_name, crate_version, Parser}; use lazy_static::lazy_static; -use nym_bin_common::build_information::BinaryBuildInformation; +use nym_bin_common::bin_info; + #[allow(unused_imports)] use nym_bin_common::logging::{maybe_print_banner, setup_logging}; #[cfg(feature = "cpucycles")] @@ -16,13 +17,13 @@ use nym_bin_common::setup_tracing; use nym_mixnode_common::measure; #[cfg(feature = "cpucycles")] use tracing::instrument; + mod commands; mod config; mod node; lazy_static! { - pub static ref PRETTY_BUILD_INFORMATION: String = - BinaryBuildInformation::new(env!("CARGO_PKG_VERSION")).pretty_print(); + pub static ref PRETTY_BUILD_INFORMATION: String = bin_info!().pretty_print(); } // Helper for passing LONG_VERSION to clap @@ -37,6 +38,10 @@ struct Cli { #[clap(short, long)] pub(crate) config_env_file: Option, + /// Flag used for disabling the printed banner in tty. + #[clap(long)] + pub(crate) no_banner: bool, + #[clap(subcommand)] command: commands::Commands, } @@ -49,6 +54,13 @@ fn test_function() { #[tokio::main] async fn main() -> anyhow::Result<()> { + let args = Cli::parse(); + setup_env(args.config_env_file.as_ref()); + + if !args.no_banner { + maybe_print_banner(crate_name!(), crate_version!()); + } + cfg_if::cfg_if! { if #[cfg(feature = "cpucycles")] { setup_tracing!("mixnode"); @@ -59,10 +71,6 @@ async fn main() -> anyhow::Result<()> { } } - maybe_print_banner(crate_name!(), crate_version!()); - - let args = Cli::parse(); - setup_env(args.config_env_file.as_ref()); commands::execute(args).await?; cfg_if::cfg_if! { diff --git a/nym-api/src/support/cli/mod.rs b/nym-api/src/support/cli/mod.rs index 1bcc518ad4..e638d29c09 100644 --- a/nym-api/src/support/cli/mod.rs +++ b/nym-api/src/support/cli/mod.rs @@ -8,14 +8,13 @@ use ::nym_config::defaults::var_names::{MIXNET_CONTRACT_ADDRESS, VESTING_CONTRAC use anyhow::Result; use clap::Parser; use lazy_static::lazy_static; -use nym_bin_common::build_information::BinaryBuildInformation; +use nym_bin_common::bin_info; use nym_config::defaults::var_names::NYXD; use nym_config::OptionalSet; use nym_validator_client::nyxd; lazy_static! { - pub static ref PRETTY_BUILD_INFORMATION: String = - BinaryBuildInformation::new(env!("CARGO_PKG_VERSION")).pretty_print(); + pub static ref PRETTY_BUILD_INFORMATION: String = bin_info!().pretty_print(); } // Helper for passing LONG_VERSION to clap diff --git a/service-providers/network-requester/src/cli/build_info.rs b/service-providers/network-requester/src/cli/build_info.rs new file mode 100644 index 0000000000..e3385bb933 --- /dev/null +++ b/service-providers/network-requester/src/cli/build_info.rs @@ -0,0 +1,16 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::Args; +use nym_bin_common::bin_info_owned; +use nym_bin_common::output_format::OutputFormat; + +#[derive(Args)] +pub(crate) struct BuildInfo { + #[clap(short, long, default_value_t = OutputFormat::default())] + output: OutputFormat, +} + +pub(crate) fn execute(args: BuildInfo) { + println!("{}", args.output.format(&bin_info_owned!())) +} diff --git a/service-providers/network-requester/src/cli/mod.rs b/service-providers/network-requester/src/cli/mod.rs index e6a34432df..80dd4751a5 100644 --- a/service-providers/network-requester/src/cli/mod.rs +++ b/service-providers/network-requester/src/cli/mod.rs @@ -10,7 +10,7 @@ use crate::{ }; use clap::{CommandFactory, Parser, Subcommand}; use log::{error, info}; -use nym_bin_common::build_information::BinaryBuildInformation; +use nym_bin_common::bin_info; use nym_bin_common::completions::{fig_generate, ArgShell}; use nym_bin_common::version_checker; use nym_client_core::client::base_client::storage::gateway_details::{ @@ -21,13 +21,13 @@ use nym_client_core::config::GatewayEndpointConfig; use nym_client_core::error::ClientCoreError; use nym_sphinx::params::PacketSize; +mod build_info; mod init; mod run; mod sign; lazy_static::lazy_static! { - pub static ref PRETTY_BUILD_INFORMATION: String = - BinaryBuildInformation::new(env!("CARGO_PKG_VERSION")).pretty_print(); + pub static ref PRETTY_BUILD_INFORMATION: String = bin_info!().pretty_print(); } // Helper for passing LONG_VERSION to clap @@ -42,6 +42,10 @@ pub(crate) struct Cli { #[clap(short, long)] pub(crate) config_env_file: Option, + /// Flag used for disabling the printed banner in tty. + #[clap(long)] + pub(crate) no_banner: bool, + #[clap(subcommand)] command: Commands, } @@ -59,6 +63,9 @@ pub(crate) enum Commands { /// Sign to prove ownership of this network requester Sign(sign::Sign), + /// Show build information of this binary + BuildInfo(build_info::BuildInfo), + /// Generate shell completions Completions(ArgShell), @@ -119,10 +126,11 @@ pub(crate) fn override_config(config: Config, args: OverrideConfig) -> Config { pub(crate) async fn execute(args: Cli) -> Result<(), NetworkRequesterError> { let bin_name = "nym-network-requester"; - match &args.command { - Commands::Init(m) => init::execute(m).await?, - Commands::Run(m) => run::execute(m).await?, - Commands::Sign(m) => sign::execute(m).await?, + match args.command { + Commands::Init(m) => init::execute(&m).await?, + Commands::Run(m) => run::execute(&m).await?, + Commands::Sign(m) => sign::execute(&m).await?, + Commands::BuildInfo(m) => build_info::execute(m), Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name), Commands::GenerateFigSpec => fig_generate(&mut Cli::command(), bin_name), } diff --git a/service-providers/network-requester/src/core.rs b/service-providers/network-requester/src/core.rs index b60bc30f41..92ab7af231 100644 --- a/service-providers/network-requester/src/core.rs +++ b/service-providers/network-requester/src/core.rs @@ -13,7 +13,7 @@ use crate::{reply, socks5}; use async_trait::async_trait; use futures::channel::mpsc; use log::warn; -use nym_bin_common::build_information::BinaryBuildInformation; +use nym_bin_common::bin_info_owned; use nym_client_core::config::disk_persistence::CommonClientPaths; use nym_network_defaults::NymNetworkDetails; use nym_service_providers_common::interface::{ @@ -101,7 +101,7 @@ impl ServiceProvider for NRServiceProvider { ) -> Result { Ok(BinaryInformation { binary_name: env!("CARGO_PKG_NAME").to_string(), - build_information: BinaryBuildInformation::new(env!("CARGO_PKG_VERSION")).to_owned(), + build_information: bin_info_owned!(), }) } diff --git a/service-providers/network-requester/src/main.rs b/service-providers/network-requester/src/main.rs index 696cb41c21..89ac717d37 100644 --- a/service-providers/network-requester/src/main.rs +++ b/service-providers/network-requester/src/main.rs @@ -18,11 +18,13 @@ mod statistics; #[tokio::main] async fn main() -> Result<(), NetworkRequesterError> { - setup_logging(); - maybe_print_banner(crate_name!(), crate_version!()); - let args = cli::Cli::parse(); setup_env(args.config_env_file.as_ref()); + if !args.no_banner { + maybe_print_banner(crate_name!(), crate_version!()); + } + setup_logging(); + cli::execute(args).await } From 0bfc1be1d594ecfb7970e0ad54571e1b1111a6a3 Mon Sep 17 00:00:00 2001 From: pierre Date: Thu, 27 Jul 2023 11:42:02 +0200 Subject: [PATCH 05/46] ci: fix release strapi actions --- .github/workflows/nym-connect-publish-macos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nym-connect-publish-macos.yml b/.github/workflows/nym-connect-publish-macos.yml index a4176eb285..827676f4d3 100644 --- a/.github/workflows/nym-connect-publish-macos.yml +++ b/.github/workflows/nym-connect-publish-macos.yml @@ -118,7 +118,7 @@ jobs: ref=${{ github.ref_name }} semver="${ref##nym-connect-}" && semver="${semver##v}" echo "version=${semver}" >> "$GITHUB_OUTPUT" - echo "filename=nym-connect_${semver}_x64_en-US.msi" >> "$GITHUB_OUTPUT" + echo "filename=nym-connect_${semver}_x64.dmg " >> "$GITHUB_OUTPUT" echo "file_hash=${{ hashFiles('nym-connect/desktop/target/release/bundle/dmg/nym-connect_*_x64.dmg') }}" >> "$GITHUB_OUTPUT" push-release-data: From 6e5f6bf0dfc0bce07e7f4e29ad1dea56d6ee677f Mon Sep 17 00:00:00 2001 From: pierre Date: Thu, 27 Jul 2023 11:42:02 +0200 Subject: [PATCH 06/46] ci: fix release strapi actions --- .github/workflows/nym-connect-publish-macos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nym-connect-publish-macos.yml b/.github/workflows/nym-connect-publish-macos.yml index a4176eb285..827676f4d3 100644 --- a/.github/workflows/nym-connect-publish-macos.yml +++ b/.github/workflows/nym-connect-publish-macos.yml @@ -118,7 +118,7 @@ jobs: ref=${{ github.ref_name }} semver="${ref##nym-connect-}" && semver="${semver##v}" echo "version=${semver}" >> "$GITHUB_OUTPUT" - echo "filename=nym-connect_${semver}_x64_en-US.msi" >> "$GITHUB_OUTPUT" + echo "filename=nym-connect_${semver}_x64.dmg " >> "$GITHUB_OUTPUT" echo "file_hash=${{ hashFiles('nym-connect/desktop/target/release/bundle/dmg/nym-connect_*_x64.dmg') }}" >> "$GITHUB_OUTPUT" push-release-data: From 19736b1204d78d0f877fc8d1729a1b9ea8432910 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogdan-=C8=98tefan=20Neac=C5=9Fu?= Date: Thu, 27 Jul 2023 13:25:34 +0300 Subject: [PATCH 07/46] Fix develop after bad automerge (#3712) --- common/nymsphinx/params/src/packet_sizes.rs | 39 +-- nym-connect/desktop/Cargo.lock | 15 +- nym-wallet/Cargo.lock | 291 ++++---------------- 3 files changed, 56 insertions(+), 289 deletions(-) diff --git a/common/nymsphinx/params/src/packet_sizes.rs b/common/nymsphinx/params/src/packet_sizes.rs index 58d9681efc..ecae71993d 100644 --- a/common/nymsphinx/params/src/packet_sizes.rs +++ b/common/nymsphinx/params/src/packet_sizes.rs @@ -2,10 +2,10 @@ // SPDX-License-Identifier: Apache-2.0 use crate::PacketType; -#[cfg(feature = "sphinx")] -use nym_sphinx_types::{header::HEADER_SIZE, PAYLOAD_OVERHEAD_SIZE}; -#[cfg(feature = "outfox")] -use nym_sphinx_types::{MIN_PACKET_SIZE, MIX_PARAMS_LEN, OUTFOX_PACKET_OVERHEAD}; +use nym_sphinx_types::{ + header::HEADER_SIZE, MIN_PACKET_SIZE, MIX_PARAMS_LEN, OUTFOX_PACKET_OVERHEAD, + PAYLOAD_OVERHEAD_SIZE, +}; use serde::{Deserialize, Serialize}; use std::cmp::Ordering; use std::convert::TryFrom; @@ -14,7 +14,6 @@ use std::str::FromStr; use thiserror::Error; // each sphinx packet contains mandatory header and payload padding + markers -#[cfg(feature = "sphinx")] const SPHINX_PACKET_OVERHEAD: usize = HEADER_SIZE + PAYLOAD_OVERHEAD_SIZE; // it's up to the smart people to figure those values out : ) @@ -23,23 +22,16 @@ const SPHINX_PACKET_OVERHEAD: usize = HEADER_SIZE + PAYLOAD_OVERHEAD_SIZE; // TODO: I'm not entirely sure if we can easily extract `::NonceSize` // into a const usize before relevant stuff is stabilised in rust... -#[cfg(feature = "sphinx")] + const ACK_IV_SIZE: usize = 16; -#[cfg(feature = "sphinx")] const ACK_PACKET_SIZE: usize = ACK_IV_SIZE + crate::FRAG_ID_LEN + SPHINX_PACKET_OVERHEAD; -#[cfg(feature = "sphinx")] const REGULAR_PACKET_SIZE: usize = 2 * 1024 + SPHINX_PACKET_OVERHEAD; -#[cfg(feature = "sphinx")] const EXTENDED_PACKET_SIZE_8: usize = 8 * 1024 + SPHINX_PACKET_OVERHEAD; -#[cfg(feature = "sphinx")] const EXTENDED_PACKET_SIZE_16: usize = 16 * 1024 + SPHINX_PACKET_OVERHEAD; -#[cfg(feature = "sphinx")] const EXTENDED_PACKET_SIZE_32: usize = 32 * 1024 + SPHINX_PACKET_OVERHEAD; -#[cfg(feature = "outfox")] const OUTFOX_ACK_PACKET_SIZE: usize = MIN_PACKET_SIZE + OUTFOX_PACKET_OVERHEAD; -#[cfg(feature = "outfox")] const OUTFOX_REGULAR_PACKET_SIZE: usize = 2 * 1024 + OUTFOX_PACKET_OVERHEAD; #[derive(Debug, Error)] @@ -162,55 +154,39 @@ impl TryFrom for PacketSize { impl PacketSize { pub const fn size(self) -> usize { - #[allow(unreachable_patterns)] match self { - #[cfg(feature = "sphinx")] PacketSize::RegularPacket => REGULAR_PACKET_SIZE, - #[cfg(feature = "sphinx")] PacketSize::AckPacket => ACK_PACKET_SIZE, - #[cfg(feature = "sphinx")] PacketSize::ExtendedPacket8 => EXTENDED_PACKET_SIZE_8, - #[cfg(feature = "sphinx")] PacketSize::ExtendedPacket16 => EXTENDED_PACKET_SIZE_16, - #[cfg(feature = "sphinx")] PacketSize::ExtendedPacket32 => EXTENDED_PACKET_SIZE_32, - #[cfg(feature = "outfox")] PacketSize::OutfoxRegularPacket => OUTFOX_REGULAR_PACKET_SIZE, - #[cfg(feature = "outfox")] PacketSize::OutfoxAckPacket => OUTFOX_ACK_PACKET_SIZE, - _ => 0, } } pub const fn header_size(&self) -> usize { - #[allow(unreachable_patterns)] match self { - #[cfg(feature = "sphinx")] PacketSize::RegularPacket | PacketSize::AckPacket | PacketSize::ExtendedPacket8 | PacketSize::ExtendedPacket16 | PacketSize::ExtendedPacket32 => HEADER_SIZE, - #[cfg(feature = "outfox")] PacketSize::OutfoxRegularPacket | PacketSize::OutfoxAckPacket => MIX_PARAMS_LEN, - _ => 0, } } pub const fn payload_overhead(&self) -> usize { #[allow(unreachable_patterns)] match self { - #[cfg(feature = "sphinx")] PacketSize::RegularPacket | PacketSize::AckPacket | PacketSize::ExtendedPacket8 | PacketSize::ExtendedPacket16 | PacketSize::ExtendedPacket32 => PAYLOAD_OVERHEAD_SIZE, - #[cfg(feature = "outfox")] PacketSize::OutfoxRegularPacket | PacketSize::OutfoxAckPacket => { OUTFOX_PACKET_OVERHEAD - MIX_PARAMS_LEN // Mix params are calculated into the total overhead so we take them out here } - _ => 0, } } @@ -268,16 +244,11 @@ impl PacketSize { plaintext_size: usize, packet_type: PacketType, ) -> Result { - #[allow(unreachable_patterns)] let overhead = match packet_type { - #[cfg(feature = "sphinx")] PacketType::Mix => SPHINX_PACKET_OVERHEAD, #[allow(deprecated)] - #[cfg(feature = "sphinx")] PacketType::Vpn => SPHINX_PACKET_OVERHEAD, - #[cfg(feature = "outfox")] PacketType::Outfox => OUTFOX_PACKET_OVERHEAD, - _ => 0, }; let packet_size = plaintext_size + overhead; Self::get_type(packet_size) diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index c7bb0c20a6..1b9ca04b31 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -2596,17 +2596,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "hostname" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" -dependencies = [ - "libc", - "match_cfg", - "winapi", -] - [[package]] name = "html5ever" version = "0.25.2" @@ -3669,7 +3658,7 @@ dependencies = [ [[package]] name = "nym-connect" -version = "1.1.13" +version = "1.1.15" dependencies = [ "anyhow", "bip39", @@ -4179,6 +4168,8 @@ dependencies = [ name = "nym-sphinx-types" version = "0.2.0" dependencies = [ + "nym-outfox", + "sphinx-packet", "thiserror", ] diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index 5768438108..050930055a 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -21,20 +21,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" dependencies = [ "crypto-common", - "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.0", + "generic-array", ] [[package]] @@ -44,7 +31,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" dependencies = [ "cfg-if", - "cipher 0.4.4", + "cipher", "cpufeatures", ] @@ -55,11 +42,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82e1366e0c69c9f927b1fa5ce2c7bf9eafc8f9268c0b9800729e8b267612447c" dependencies = [ "aead", - "aes 0.8.2", - "cipher 0.4.4", - "ctr 0.9.2", + "aes", + "cipher", + "ctr", "ghash", - "subtle 2.4.1", + "subtle", ] [[package]] @@ -110,16 +97,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95c2fcf79ad1932ac6269a738109997a83c227c09b75842ae564dc8ede6a861c" dependencies = [ "base64ct", - "blake2 0.10.6", + "blake2", "password-hash", ] -[[package]] -name = "arrayref" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" - [[package]] name = "async-trait" version = "0.1.64" @@ -225,14 +206,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e141fb0f8be1c7b45887af94c88b182472b57c96b56773250ae00cd6a14a164" dependencies = [ "bs58 0.5.0", - "hmac 0.12.1", + "hmac", "k256 0.13.1", "once_cell", "pbkdf2", "rand_core 0.6.4", "ripemd", "sha2 0.10.6", - "subtle 2.4.1", + "subtle", "zeroize", ] @@ -274,18 +255,6 @@ dependencies = [ "wyz", ] -[[package]] -name = "blake2" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330" -dependencies = [ - "byte-tools", - "crypto-mac 0.7.0", - "digest 0.8.1", - "opaque-debug 0.2.3", -] - [[package]] name = "blake2" version = "0.10.6" @@ -307,7 +276,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "generic-array 0.14.7", + "generic-array", ] [[package]] @@ -316,7 +285,7 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" dependencies = [ - "generic-array 0.14.7", + "generic-array", ] [[package]] @@ -329,7 +298,7 @@ dependencies = [ "group 0.11.0", "pairing", "rand_core 0.6.4", - "subtle 2.4.1", + "subtle", "zeroize", ] @@ -385,12 +354,6 @@ version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" -[[package]] -name = "byte-tools" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" - [[package]] name = "bytemuck" version = "1.13.0" @@ -495,25 +458,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "chacha" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddf3c081b5fba1e5615640aae998e0fbd10c24cbd897ee39ed754a77601a4862" -dependencies = [ - "byteorder", - "keystream", -] - -[[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" @@ -849,9 +793,9 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ - "generic-array 0.14.7", + "generic-array", "rand_core 0.6.4", - "subtle 2.4.1", + "subtle", "zeroize", ] @@ -861,9 +805,9 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15" dependencies = [ - "generic-array 0.14.7", + "generic-array", "rand_core 0.6.4", - "subtle 2.4.1", + "subtle", "zeroize", ] @@ -873,31 +817,11 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "generic-array 0.14.7", + "generic-array", "rand_core 0.6.4", "typenum", ] -[[package]] -name = "crypto-mac" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" -dependencies = [ - "generic-array 0.12.4", - "subtle 1.0.0", -] - -[[package]] -name = "crypto-mac" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" -dependencies = [ - "generic-array 0.14.7", - "subtle 2.4.1", -] - [[package]] name = "cssparser" version = "0.27.2" @@ -944,22 +868,13 @@ dependencies = [ "syn 1.0.107", ] -[[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]] @@ -977,7 +892,7 @@ dependencies = [ "byteorder", "digest 0.9.0", "rand_core 0.5.1", - "subtle 2.4.1", + "subtle", "zeroize", ] @@ -1168,22 +1083,13 @@ dependencies = [ "syn 1.0.107", ] -[[package]] -name = "digest" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" -dependencies = [ - "generic-array 0.12.4", -] - [[package]] name = "digest" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array 0.14.7", + "generic-array", ] [[package]] @@ -1195,7 +1101,7 @@ dependencies = [ "block-buffer 0.10.3", "const-oid", "crypto-common", - "subtle 2.4.1", + "subtle", ] [[package]] @@ -1403,12 +1309,12 @@ dependencies = [ "der 0.6.1", "digest 0.10.7", "ff 0.12.1", - "generic-array 0.14.7", + "generic-array", "group 0.12.1", "pkcs8 0.9.0", "rand_core 0.6.4", "sec1 0.3.0", - "subtle 2.4.1", + "subtle", "zeroize", ] @@ -1422,12 +1328,12 @@ dependencies = [ "crypto-bigint 0.5.2", "digest 0.10.7", "ff 0.13.0", - "generic-array 0.14.7", + "generic-array", "group 0.13.0", "pkcs8 0.10.2", "rand_core 0.6.4", "sec1 0.7.3", - "subtle 2.4.1", + "subtle", "zeroize", ] @@ -1536,7 +1442,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "131655483be284720a17d74ff97592b8e76576dc25563148601df2d7c9080924" dependencies = [ "rand_core 0.6.4", - "subtle 2.4.1", + "subtle", ] [[package]] @@ -1546,7 +1452,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" dependencies = [ "rand_core 0.6.4", - "subtle 2.4.1", + "subtle", ] [[package]] @@ -1556,7 +1462,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "rand_core 0.6.4", - "subtle 2.4.1", + "subtle", ] [[package]] @@ -1836,15 +1742,6 @@ dependencies = [ "windows 0.39.0", ] -[[package]] -name = "generic-array" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" -dependencies = [ - "typenum", -] - [[package]] name = "generic-array" version = "0.14.7" @@ -1900,7 +1797,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" dependencies = [ - "opaque-debug 0.3.0", + "opaque-debug", "polyval", ] @@ -2031,7 +1928,7 @@ dependencies = [ "byteorder", "ff 0.11.1", "rand_core 0.6.4", - "subtle 2.4.1", + "subtle", ] [[package]] @@ -2042,7 +1939,7 @@ checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" dependencies = [ "ff 0.12.1", "rand_core 0.6.4", - "subtle 2.4.1", + "subtle", ] [[package]] @@ -2053,7 +1950,7 @@ checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff 0.13.0", "rand_core 0.6.4", - "subtle 2.4.1", + "subtle", ] [[package]] @@ -2229,26 +2126,6 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" -[[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 = "hmac" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" -dependencies = [ - "crypto-mac 0.11.1", - "digest 0.9.0", -] - [[package]] name = "hmac" version = "0.12.1" @@ -2500,7 +2377,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" dependencies = [ - "generic-array 0.14.7", + "generic-array", ] [[package]] @@ -2659,12 +2536,6 @@ dependencies = [ "signature 2.1.0", ] -[[package]] -name = "keystream" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33070833c9ee02266356de0c43f723152bd38bd96ddf52c82b3af10c9138b28" - [[package]] name = "kuchiki" version = "0.8.1" @@ -2701,12 +2572,6 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "libm" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" - [[package]] name = "libz-sys" version = "1.1.8" @@ -2734,18 +2599,6 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" -[[package]] -name = "lioness" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae926706ba42c425c9457121178330d75e273df2e82e28b758faf3de3a9acb9" -dependencies = [ - "arrayref", - "blake2 0.8.1", - "chacha", - "keystream", -] - [[package]] name = "lock_api" version = "0.4.9" @@ -2989,7 +2842,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ "autocfg", - "libm", ] [[package]] @@ -3268,7 +3120,6 @@ dependencies = [ name = "nym-sphinx-types" version = "0.2.0" dependencies = [ - "sphinx-packet", "thiserror", ] @@ -3278,7 +3129,7 @@ version = "0.1.0" dependencies = [ "aes-gcm", "argon2", - "generic-array 0.14.7", + "generic-array", "getrandom 0.2.10", "rand 0.8.5", "serde", @@ -3517,12 +3368,6 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" -[[package]] -name = "opaque-debug" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" - [[package]] name = "opaque-debug" version = "0.3.0" @@ -3677,7 +3522,7 @@ checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" dependencies = [ "base64ct", "rand_core 0.6.4", - "subtle 2.4.1", + "subtle", ] [[package]] @@ -3699,7 +3544,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ "digest 0.10.7", - "hmac 0.12.1", + "hmac", ] [[package]] @@ -3980,7 +3825,7 @@ checksum = "7ef234e08c11dfcb2e56f79fd70f6f2eb7f025c0ce2333e82f4f0518ecad30c6" dependencies = [ "cfg-if", "cpufeatures", - "opaque-debug 0.3.0", + "opaque-debug", "universal-hash", ] @@ -4186,16 +4031,6 @@ dependencies = [ "getrandom 0.2.10", ] -[[package]] -name = "rand_distr" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e9532ada3929fb8b2e9dbe28d1e06c9b2cc65813f074fcb6bd5fbefeff9d56" -dependencies = [ - "num-traits", - "rand 0.7.3", -] - [[package]] name = "rand_hc" version = "0.2.0" @@ -4322,7 +4157,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ "crypto-bigint 0.4.9", - "hmac 0.12.1", + "hmac", "zeroize", ] @@ -4332,8 +4167,8 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "hmac 0.12.1", - "subtle 2.4.1", + "hmac", + "subtle", ] [[package]] @@ -4532,9 +4367,9 @@ checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ "base16ct 0.1.1", "der 0.6.1", - "generic-array 0.14.7", + "generic-array", "pkcs8 0.9.0", - "subtle 2.4.1", + "subtle", "zeroize", ] @@ -4546,9 +4381,9 @@ checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct 0.2.0", "der 0.7.7", - "generic-array 0.14.7", + "generic-array", "pkcs8 0.10.2", - "subtle 2.4.1", + "subtle", "zeroize", ] @@ -4798,7 +4633,7 @@ dependencies = [ "cfg-if", "cpufeatures", "digest 0.9.0", - "opaque-debug 0.3.0", + "opaque-debug", ] [[package]] @@ -4909,30 +4744,6 @@ dependencies = [ "system-deps 5.0.0", ] -[[package]] -name = "sphinx-packet" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc43eda802856ee82a7555c7b75ceb9e07451741c7a2f5f23d036020e01189d4" -dependencies = [ - "aes 0.7.5", - "arrayref", - "blake2 0.8.1", - "bs58 0.4.0", - "byteorder", - "chacha", - "curve25519-dalek", - "digest 0.9.0", - "hkdf", - "hmac 0.11.0", - "lioness", - "log", - "rand 0.7.3", - "rand_distr", - "sha2 0.9.9", - "subtle 2.4.1", -] - [[package]] name = "spin" version = "0.5.2" @@ -5034,12 +4845,6 @@ dependencies = [ "syn 1.0.107", ] -[[package]] -name = "subtle" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" - [[package]] name = "subtle" version = "2.4.1" @@ -5399,7 +5204,7 @@ dependencies = [ "serde_repr", "sha2 0.10.6", "signature 2.1.0", - "subtle 2.4.1", + "subtle", "subtle-encoding", "tendermint-proto", "time", @@ -5459,7 +5264,7 @@ dependencies = [ "serde", "serde_bytes", "serde_json", - "subtle 2.4.1", + "subtle", "subtle-encoding", "tendermint", "tendermint-config", @@ -5869,7 +5674,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d3160b73c9a19f7e2939a2fdad446c57c1bbbbf4d919d3213ff1267a580d8b5" dependencies = [ "crypto-common", - "subtle 2.4.1", + "subtle", ] [[package]] From ac8afe133fae9362636c2af0ddfdc6b2ca78c929 Mon Sep 17 00:00:00 2001 From: pierre Date: Thu, 27 Jul 2023 15:53:48 +0200 Subject: [PATCH 08/46] fix(nc-desktop): typo --- .../desktop/src/pages/menu/settings/PrivacyLevelSettings.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nym-connect/desktop/src/pages/menu/settings/PrivacyLevelSettings.tsx b/nym-connect/desktop/src/pages/menu/settings/PrivacyLevelSettings.tsx index 5c2241b4d0..a97e7fdfdf 100644 --- a/nym-connect/desktop/src/pages/menu/settings/PrivacyLevelSettings.tsx +++ b/nym-connect/desktop/src/pages/menu/settings/PrivacyLevelSettings.tsx @@ -37,8 +37,8 @@ export const PrivacyLevelSettings = () => { label="Enable" /> - By activating this option, the connection speed will be relatively faster in exchange of relaxing some - protections + By activating this option, the connection speed will be relatively faster in exchange for relaxing some + privacy protections From 5964f104c5ba699bda1a8e753741c01bbf7ea05c Mon Sep 17 00:00:00 2001 From: pierre Date: Thu, 27 Jul 2023 15:53:48 +0200 Subject: [PATCH 09/46] fix(nc-desktop): typo --- .../desktop/src/pages/menu/settings/PrivacyLevelSettings.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nym-connect/desktop/src/pages/menu/settings/PrivacyLevelSettings.tsx b/nym-connect/desktop/src/pages/menu/settings/PrivacyLevelSettings.tsx index 5c2241b4d0..a97e7fdfdf 100644 --- a/nym-connect/desktop/src/pages/menu/settings/PrivacyLevelSettings.tsx +++ b/nym-connect/desktop/src/pages/menu/settings/PrivacyLevelSettings.tsx @@ -37,8 +37,8 @@ export const PrivacyLevelSettings = () => { label="Enable" /> - By activating this option, the connection speed will be relatively faster in exchange of relaxing some - protections + By activating this option, the connection speed will be relatively faster in exchange for relaxing some + privacy protections From 5fbccc34066bc9437779f613245e93d8859a54c0 Mon Sep 17 00:00:00 2001 From: pierre Date: Thu, 27 Jul 2023 19:11:33 +0200 Subject: [PATCH 10/46] build(nc-android): moving build config to kotlin --- nym-connect/native/android/app/build.gradle | 127 ----------------- .../native/android/app/build.gradle.kts | 131 ++++++++++++++++++ nym-connect/native/android/build.gradle | 6 - nym-connect/native/android/build.gradle.kts | 6 + .../{settings.gradle => settings.gradle.kts} | 4 +- 5 files changed, 140 insertions(+), 134 deletions(-) delete mode 100644 nym-connect/native/android/app/build.gradle create mode 100644 nym-connect/native/android/app/build.gradle.kts delete mode 100644 nym-connect/native/android/build.gradle create mode 100644 nym-connect/native/android/build.gradle.kts rename nym-connect/native/android/{settings.gradle => settings.gradle.kts} (94%) diff --git a/nym-connect/native/android/app/build.gradle b/nym-connect/native/android/app/build.gradle deleted file mode 100644 index 72ba890287..0000000000 --- a/nym-connect/native/android/app/build.gradle +++ /dev/null @@ -1,127 +0,0 @@ -plugins { - id 'com.android.application' - id 'org.jetbrains.kotlin.android' - id 'org.jetbrains.kotlin.plugin.serialization' version '1.8.21' - id 'io.sentry.android.gradle' version '3.11.0' -} - -android { - namespace 'net.nymtech.nyms5' - compileSdk 33 - - defaultConfig { - applicationId "net.nymtech.nyms5" - minSdk 24 - targetSdk 33 - versionCode 1 - versionName "1.0" - - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - vectorDrawables { - useSupportLibrary true - } - } - - buildTypes { - release { - minifyEnabled true - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } - } - - flavorDimensions "abi" - productFlavors { - universal { - dimension "abi" - ndk { - abiFilters "arm64-v8a", "armeabi-v7a", "x86_64", "x86" - } - } - arch64 { - dimension "abi" - ndk { - abiFilters "arm64-v8a", "x86_64" - } - } - arm64 { - dimension "abi" - ndk { - abiFilters "arm64-v8a" - } - } - arm { - dimension "abi" - ndk { - abiFilters "armeabi-v7a" - } - } - x86_64 { - dimension "abi" - ndk { - abiFilters "x86_64" - } - } - x86 { - dimension "abi" - ndk { - abiFilters "x86" - } - } - } - -// splits { -// abi { -// enable true -// reset() -// include "x86_64", "arm64-v8a" -// universalApk true -// } -// } - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = '1.8' - } - buildFeatures { - compose true - } - composeOptions { - kotlinCompilerExtensionVersion '1.4.6' - } - packagingOptions { - resources { - excludes += '/META-INF/{AL2.0,LGPL2.1}' - } - } -} - -dependencies { - implementation 'androidx.core:core-ktx:1.10.1' - implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1' - implementation 'androidx.activity:activity-compose:1.7.2' - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4' - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4' - implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0' - implementation platform('androidx.compose:compose-bom:2022.10.00') - implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1' - implementation 'androidx.navigation:navigation-compose:2.6.0' - implementation 'androidx.compose.runtime:runtime-livedata' - implementation 'androidx.compose.ui:ui' - implementation 'androidx.compose.ui:ui-graphics' - implementation 'androidx.compose.ui:ui-tooling-preview' - implementation 'androidx.compose.material3:material3' - implementation 'androidx.work:work-runtime-ktx:2.8.1' - implementation 'androidx.datastore:datastore-preferences:1.0.0' - testImplementation 'junit:junit:4.13.2' - androidTestImplementation 'androidx.test.ext:junit:1.1.3' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' - androidTestImplementation platform('androidx.compose:compose-bom:2022.10.00') - androidTestImplementation 'androidx.compose.ui:ui-test-junit4' - debugImplementation 'androidx.compose.ui:ui-tooling' - debugImplementation 'androidx.compose.ui:ui-test-manifest' - implementation 'com.github.kittinunf.fuel:fuel:2.3.1' - implementation 'io.sentry:sentry-android:6.24.0' -} diff --git a/nym-connect/native/android/app/build.gradle.kts b/nym-connect/native/android/app/build.gradle.kts new file mode 100644 index 0000000000..b33dd6d715 --- /dev/null +++ b/nym-connect/native/android/app/build.gradle.kts @@ -0,0 +1,131 @@ +plugins { + id("com.android.application") + id("org.jetbrains.kotlin.android") + id("org.jetbrains.kotlin.plugin.serialization") version "1.8.21" + id("io.sentry.android.gradle") version "3.11.0" +} + +android { + namespace = "net.nymtech.nyms5" + compileSdk = 33 + + defaultConfig { + applicationId = "net.nymtech.nyms5" + minSdk = 24 + targetSdk = 33 + versionCode = 1 + versionName = "1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + vectorDrawables { + useSupportLibrary = true + } + } + + buildTypes { + release { + isMinifyEnabled = true + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + + flavorDimensions += "abi" + productFlavors { + create("universal") { + dimension = "abi" + ndk { + abiFilters += listOf("arm64-v8a", "armeabi-v7a", "x86_64", "x86") + } + } + create("arch64") { + dimension = "abi" + ndk { + abiFilters += listOf("arm64-v8a", "x86_64") + } + } + create("arm64") { + dimension = "abi" + ndk { + abiFilters += "arm64-v8a" + } + } + create("arm") { + dimension = "abi" + ndk { + abiFilters += "armeabi-v7a" + } + } + create("x86_64") { + dimension = "abi" + ndk { + abiFilters += "x86_64" + } + } + create("x86") { + dimension = "abi" + ndk { + abiFilters += "x86" + } + } + } + +// splits { +// abi { +// enable true +// reset() +// include "x86_64", "arm64-v8a" +// universalApk true +// } +// } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = "1.8" + } + buildFeatures { + compose = true + } + composeOptions { + kotlinCompilerExtensionVersion = "1.4.6" + } + packaging { + resources { + excludes += "/META-INF/{AL2.0,LGPL2.1}" + } + } +} + +dependencies { + + implementation("androidx.core:core-ktx:1.10.1") + implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.1") + implementation("androidx.activity:activity-compose:1.7.2") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4") + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0") + implementation(platform("androidx.compose:compose-bom:2022.10.00")) + implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1") + implementation("androidx.navigation:navigation-compose:2.6.0") + implementation("androidx.compose.runtime:runtime-livedata") + implementation("androidx.compose.ui:ui") + implementation("androidx.compose.ui:ui-graphics") + implementation("androidx.compose.ui:ui-tooling-preview") + implementation("androidx.compose.material3:material3") + implementation("androidx.work:work-runtime-ktx:2.8.1") + implementation("androidx.datastore:datastore-preferences:1.0.0") + testImplementation("junit:junit:4.13.2") + androidTestImplementation("androidx.test.ext:junit:1.1.3") + androidTestImplementation("androidx.test.espresso:espresso-core:3.4.0") + androidTestImplementation(platform("androidx.compose:compose-bom:2022.10.00")) + androidTestImplementation("androidx.compose.ui:ui-test-junit4") + debugImplementation("androidx.compose.ui:ui-tooling") + debugImplementation("androidx.compose.ui:ui-test-manifest") + implementation("com.github.kittinunf.fuel:fuel:2.3.1") + implementation("io.sentry:sentry-android:6.24.0") +} diff --git a/nym-connect/native/android/build.gradle b/nym-connect/native/android/build.gradle deleted file mode 100644 index fd3d478923..0000000000 --- a/nym-connect/native/android/build.gradle +++ /dev/null @@ -1,6 +0,0 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. -plugins { - id 'com.android.application' version '8.0.2' apply false - id 'com.android.library' version '8.0.2' apply false - id 'org.jetbrains.kotlin.android' version '1.8.20' apply false -} \ No newline at end of file diff --git a/nym-connect/native/android/build.gradle.kts b/nym-connect/native/android/build.gradle.kts new file mode 100644 index 0000000000..6cb6871c9e --- /dev/null +++ b/nym-connect/native/android/build.gradle.kts @@ -0,0 +1,6 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +plugins { + id("com.android.application") version "8.1.0" apply false + id("com.android.library") version "8.1.0" apply false + id("org.jetbrains.kotlin.android") version "1.8.20" apply false +} \ No newline at end of file diff --git a/nym-connect/native/android/settings.gradle b/nym-connect/native/android/settings.gradle.kts similarity index 94% rename from nym-connect/native/android/settings.gradle rename to nym-connect/native/android/settings.gradle.kts index 0bf8eaecd3..267005beeb 100644 --- a/nym-connect/native/android/settings.gradle +++ b/nym-connect/native/android/settings.gradle.kts @@ -12,5 +12,7 @@ dependencyResolutionManagement { mavenCentral() } } + rootProject.name = "nyms5" -include ':app' +include(":app") + \ No newline at end of file From 7b71775e08ad30fb13454493135026b3f70db629 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Fri, 28 Jul 2023 14:48:33 +0200 Subject: [PATCH 11/46] Add geo-aware mixnet topology provider (#3713) * WIP: initial work * wupwup * WIP: experiments * Move topology provider and requests to own crate * Make sure we use the new crate everywhere * Sort Cargo.toml * Extract out some functions in geo_aware_provider * rustfmt * Add CountryGroup type * Assign unknown as well * wipwip * Add command line flag to socks5-client * Use geo-aware mixnode selection in nym-connect when in medium mode * rustfmt * clippy * Fix nym-connect build * wasm fix * Spelling --- Cargo.lock | 20 ++ Cargo.toml | 13 +- clients/socks5/src/commands/init.rs | 1 + clients/socks5/src/commands/mod.rs | 15 +- clients/socks5/src/commands/run.rs | 13 + clients/webassembly/Cargo.lock | 13 + clients/webassembly/src/client/config.rs | 1 + common/client-core/Cargo.toml | 10 +- .../client-core/src/client/base_client/mod.rs | 15 +- .../topology_control/geo_aware_provider.rs | 319 ++++++++++++++++++ .../src/client/topology_control/mod.rs | 1 + common/client-core/src/config/mod.rs | 22 +- .../src/config/old_config_v1_1_20_2.rs | 1 + .../mixnet-contract/src/mixnode.rs | 4 + common/socks5-client-core/Cargo.toml | 13 +- common/socks5-client-core/src/lib.rs | 1 + explorer-api/Cargo.toml | 17 +- explorer-api/explorer-api-requests/Cargo.toml | 12 + explorer-api/explorer-api-requests/src/lib.rs | 44 +++ .../src/country_statistics/geolocate.rs | 4 +- explorer-api/src/geo_ip/location.rs | 12 + explorer-api/src/mix_node/http.rs | 3 +- explorer-api/src/mix_node/mod.rs | 2 +- explorer-api/src/mix_node/models.rs | 38 +-- explorer-api/src/mix_nodes/http.rs | 2 +- explorer-api/src/mix_nodes/location.rs | 23 +- explorer-api/src/mix_nodes/models.rs | 4 +- nym-connect/desktop/Cargo.lock | 39 ++- nym-connect/desktop/src-tauri/src/tasks.rs | 26 +- .../src/allowed_hosts/hosts.rs | 1 - 30 files changed, 574 insertions(+), 115 deletions(-) create mode 100644 common/client-core/src/client/topology_control/geo_aware_provider.rs create mode 100644 explorer-api/explorer-api-requests/Cargo.toml create mode 100644 explorer-api/explorer-api-requests/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index d576e05c0c..f7ba594a47 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1907,6 +1907,7 @@ dependencies = [ "maxminddb", "nym-bin-common", "nym-contracts-common", + "nym-explorer-api-requests", "nym-mixnet-contract-common", "nym-network-defaults", "nym-task", @@ -3783,6 +3784,7 @@ dependencies = [ "nym-config", "nym-credential-storage", "nym-crypto", + "nym-explorer-api-requests", "nym-gateway-client", "nym-gateway-requests", "nym-network-defaults", @@ -3793,6 +3795,7 @@ dependencies = [ "nym-topology", "nym-validator-client", "rand 0.7.3", + "reqwest", "serde", "serde_json", "sha2 0.10.6", @@ -4005,6 +4008,18 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "nym-explorer-api-requests" +version = "0.1.0" +dependencies = [ + "nym-contracts-common", + "nym-mixnet-contract-common", + "nym-validator-client", + "schemars", + "serde", + "ts-rs", +] + [[package]] name = "nym-gateway" version = "1.1.23" @@ -4520,7 +4535,9 @@ dependencies = [ "nym-bandwidth-controller", "nym-client-core", "nym-config", + "nym-contracts-common", "nym-credential-storage", + "nym-mixnet-contract-common", "nym-network-defaults", "nym-service-providers-common", "nym-socks5-proxy-helpers", @@ -4530,10 +4547,13 @@ dependencies = [ "nym-validator-client", "pin-project", "rand 0.7.3", + "reqwest", + "schemars", "serde", "tap", "thiserror", "tokio", + "url", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index fd137c6bdf..2b2fad2698 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -74,6 +74,7 @@ members = [ "common/types", "common/wasm-utils", "explorer-api", + "explorer-api/explorer-api-requests", "gateway", "gateway/gateway-requests", "integrations/bity", @@ -117,31 +118,31 @@ anyhow = "1.0.71" async-trait = "0.1.64" bip39 = { version = "2.0.0", features = ["zeroize"] } cfg-if = "1.0.0" +cosmrs = "=0.14.0" cosmwasm-derive = "=1.2.5" cosmwasm-schema = "=1.2.5" cosmwasm-std = "=1.2.5" cosmwasm-storage = "=1.2.5" -cosmrs = "=0.14.0" -# same version as used by cosmrs -tendermint-rpc = "=0.32" -cw-utils = "=1.0.1" +cw-controllers = { version = "=1.0.1" } cw-storage-plus = "=1.0.1" +cw-utils = "=1.0.1" cw2 = { version = "=1.0.1" } cw3 = { version = "=1.0.1" } cw3-fixed-multisig = { version = "=1.0.1" } cw4 = { version = "=1.0.1" } -cw-controllers = { version = "=1.0.1" } dotenvy = "0.15.6" generic-array = "0.14.7" -k256 = "0.13" getrandom = "0.2.10" +k256 = "0.13" lazy_static = "1.4.0" log = "0.4" once_cell = "1.7.2" rand = "0.8.5" +reqwest = "0.11.18" serde = "1.0.152" serde_json = "1.0.91" tap = "1.0.1" +tendermint-rpc = "=0.32" # same version as used by cosmrs thiserror = "1.0.38" tokio = "1.24.1" url = "2.2" diff --git a/clients/socks5/src/commands/init.rs b/clients/socks5/src/commands/init.rs index 76337b84ac..ef370c54b8 100644 --- a/clients/socks5/src/commands/init.rs +++ b/clients/socks5/src/commands/init.rs @@ -94,6 +94,7 @@ impl From for OverrideConfig { use_anonymous_replies: init_config.use_reply_surbs, fastmode: init_config.fastmode, no_cover: init_config.no_cover, + geo_routing: None, medium_toggle: false, nyxd_urls: init_config.nyxd_urls, enabled_credentials_mode: init_config.enabled_credentials_mode, diff --git a/clients/socks5/src/commands/mod.rs b/clients/socks5/src/commands/mod.rs index 2b5fe425b6..12b4523330 100644 --- a/clients/socks5/src/commands/mod.rs +++ b/clients/socks5/src/commands/mod.rs @@ -16,7 +16,8 @@ use nym_client_core::client::base_client::storage::gateway_details::{ OnDiskGatewayDetails, PersistedGatewayDetails, }; use nym_client_core::client::key_manager::persistence::OnDiskKeys; -use nym_client_core::config::GatewayEndpointConfig; +use nym_client_core::client::topology_control::geo_aware_provider::CountryGroup; +use nym_client_core::config::{GatewayEndpointConfig, TopologyStructure}; use nym_client_core::error::ClientCoreError; use nym_config::OptionalSet; use nym_sphinx::params::{PacketSize, PacketType}; @@ -68,6 +69,7 @@ pub(crate) struct OverrideConfig { use_anonymous_replies: Option, fastmode: bool, no_cover: bool, + geo_routing: Option, medium_toggle: bool, nyxd_urls: Option>, enabled_credentials_mode: Option, @@ -91,6 +93,13 @@ pub(crate) fn override_config(config: Config, args: OverrideConfig) -> Config { let secondary_packet_size = args.medium_toggle.then_some(PacketSize::ExtendedPacket16); let no_per_hop_delays = args.medium_toggle; + let topology_structure = if args.medium_toggle || args.geo_routing.is_some() { + // TODO: rethink the default group. I just picked one for now. + TopologyStructure::GeoAware(args.geo_routing.unwrap_or(CountryGroup::Europe)) + } else { + TopologyStructure::default() + }; + let packet_type = if args.outfox { PacketType::Outfox } else { @@ -114,6 +123,10 @@ pub(crate) fn override_config(config: Config, args: OverrideConfig) -> Config { // NOTE: see comment above about the order of the other disble cover traffic config .with_base(BaseClientConfig::with_disabled_cover_traffic, args.no_cover) .with_base(BaseClientConfig::with_packet_type, packet_type) + .with_base( + BaseClientConfig::with_topology_structure, + topology_structure, + ) .with_optional(Config::with_anonymous_replies, args.use_anonymous_replies) .with_optional(Config::with_port, args.port) .with_optional_base_custom_env( diff --git a/clients/socks5/src/commands/run.rs b/clients/socks5/src/commands/run.rs index 5d54038c06..8dd289e2bf 100644 --- a/clients/socks5/src/commands/run.rs +++ b/clients/socks5/src/commands/run.rs @@ -11,6 +11,7 @@ use clap::Args; use log::*; use nym_bin_common::version_checker::is_minor_version_compatible; use nym_client_core::client::base_client::storage::OnDiskPersistent; +use nym_client_core::client::topology_control::geo_aware_provider::CountryGroup; use nym_crypto::asymmetric::identity; use nym_socks5_client_core::NymClient; use nym_sphinx::addressing::clients::Recipient; @@ -60,6 +61,10 @@ pub(crate) struct Run { #[clap(long, hide = true)] no_cover: bool, + /// Set geo-aware mixnode selection when sending mixnet traffic, for experiments only. + #[clap(long, hide = true, value_parser = validate_country_group)] + geo_routing: Option, + /// Enable medium mixnet traffic, for experiments only. /// This includes things like disabling cover traffic, no per hop delays, etc. #[clap(long, hide = true)] @@ -82,6 +87,7 @@ impl From for OverrideConfig { use_anonymous_replies: run_config.use_anonymous_replies, fastmode: run_config.fastmode, no_cover: run_config.no_cover, + geo_routing: run_config.geo_routing, medium_toggle: run_config.medium_toggle, nyxd_urls: run_config.nyxd_urls, enabled_credentials_mode: run_config.enabled_credentials_mode, @@ -90,6 +96,13 @@ impl From for OverrideConfig { } } +fn validate_country_group(s: &str) -> Result { + match s.parse() { + Ok(cg) => Ok(cg), + Err(_) => Err(format!("failed to parse country group: {}", s)), + } +} + // this only checks compatibility between config the binary. It does not take into consideration // network version. It might do so in the future. fn version_check(cfg: &Config) -> bool { diff --git a/clients/webassembly/Cargo.lock b/clients/webassembly/Cargo.lock index f0733eac1b..c6410d881c 100644 --- a/clients/webassembly/Cargo.lock +++ b/clients/webassembly/Cargo.lock @@ -2477,6 +2477,7 @@ dependencies = [ "nym-config", "nym-credential-storage", "nym-crypto", + "nym-explorer-api-requests", "nym-gateway-client", "nym-gateway-requests", "nym-network-defaults", @@ -2487,6 +2488,7 @@ dependencies = [ "nym-topology", "nym-validator-client", "rand 0.7.3", + "reqwest", "serde", "serde_json", "sha2 0.10.6", @@ -2692,6 +2694,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "nym-explorer-api-requests" +version = "0.1.0" +dependencies = [ + "nym-contracts-common", + "nym-mixnet-contract-common", + "nym-validator-client", + "schemars", + "serde", +] + [[package]] name = "nym-gateway-client" version = "0.1.0" diff --git a/clients/webassembly/src/client/config.rs b/clients/webassembly/src/client/config.rs index 07d9ab5f5f..f63d1456ac 100644 --- a/clients/webassembly/src/client/config.rs +++ b/clients/webassembly/src/client/config.rs @@ -246,6 +246,7 @@ impl From for ConfigTopology { topology.topology_resolution_timeout_ms, ), disable_refreshing: topology.disable_refreshing, + topology_structure: Default::default(), } } } diff --git a/common/client-core/Cargo.toml b/common/client-core/Cargo.toml index d5ae32dbd2..e63d6e0ff7 100644 --- a/common/client-core/Cargo.toml +++ b/common/client-core/Cargo.toml @@ -10,27 +10,29 @@ rust-version = "1.66" [dependencies] async-trait = { workspace = true } base64 = "0.21.2" -dirs = "4.0" dashmap = "5.4.0" +dirs = "4.0" futures = "0.3" humantime-serde = "1.0" log = { workspace = true } rand = { version = "0.7.3", features = ["wasm-bindgen"] } +reqwest = { workspace = true } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } sha2 = "0.10.6" tap = "1.0.1" thiserror = "1.0.34" -url = { version ="2.2", features = ["serde"] } -tungstenite = { version = "0.13.0", default-features = false } -tokio = { version = "1.24.1", features = ["macros"]} time = "0.3.17" +tokio = { version = "1.24.1", features = ["macros"]} +tungstenite = { version = "0.13.0", default-features = false } +url = { version ="2.2", features = ["serde"] } zeroize = { workspace = true } # internal nym-bandwidth-controller = { path = "../bandwidth-controller" } nym-config = { path = "../config" } nym-crypto = { path = "../crypto" } +nym-explorer-api-requests = { path = "../../explorer-api/explorer-api-requests" } nym-gateway-client = { path = "../client-libs/gateway-client" } #gateway-client = { path = "../../common/client-libs/gateway-client", default-features = false, features = ["wasm", "coconut"] } nym-gateway-requests = { path = "../../gateway/gateway-requests" } diff --git a/common/client-core/src/client/base_client/mod.rs b/common/client-core/src/client/base_client/mod.rs index aecb7eb5c1..a934793953 100644 --- a/common/client-core/src/client/base_client/mod.rs +++ b/common/client-core/src/client/base_client/mod.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use super::received_buffer::ReceivedBufferMessage; +use super::topology_control::geo_aware_provider::GeoAwareTopologyProvider; use crate::client::base_client::storage::MixnetClientStorage; use crate::client::cover_traffic_stream::LoopCoverTrafficStream; use crate::client::inbound_messages::{InputMessage, InputMessageReceiver, InputMessageSender}; @@ -339,14 +340,20 @@ where fn setup_topology_provider( custom_provider: Option>, + provider_from_config: config::TopologyStructure, nym_api_urls: Vec, ) -> Box { // if no custom provider was ... provided ..., create one using nym-api - custom_provider.unwrap_or_else(|| { - Box::new(NymApiTopologyProvider::new( + custom_provider.unwrap_or_else(|| match provider_from_config { + config::TopologyStructure::NymApi => Box::new(NymApiTopologyProvider::new( nym_api_urls, env!("CARGO_PKG_VERSION").to_string(), - )) + )), + config::TopologyStructure::GeoAware(group) => Box::new(GeoAwareTopologyProvider::new( + nym_api_urls, + env!("CARGO_PKG_VERSION").to_string(), + group, + )), }) } @@ -521,8 +528,10 @@ where let topology_provider = Self::setup_topology_provider( self.custom_topology_provider.take(), + self.config.debug.topology.topology_structure, self.config.get_nym_api_endpoints(), ); + Self::start_topology_refresher( topology_provider, self.config.debug.topology, diff --git a/common/client-core/src/client/topology_control/geo_aware_provider.rs b/common/client-core/src/client/topology_control/geo_aware_provider.rs new file mode 100644 index 0000000000..268f6612e0 --- /dev/null +++ b/common/client-core/src/client/topology_control/geo_aware_provider.rs @@ -0,0 +1,319 @@ +use std::{collections::HashMap, fmt}; + +use log::{debug, error, info}; +use nym_explorer_api_requests::PrettyDetailedMixNodeBond; +use nym_topology::{ + nym_topology_from_detailed, + provider_trait::{async_trait, TopologyProvider}, + NymTopology, +}; +use nym_validator_client::client::MixId; +use rand::{prelude::SliceRandom, thread_rng}; +use serde::{Deserialize, Serialize}; +use url::Url; + +const MIN_NODES_PER_LAYER: usize = 1; +const EXPLORER_API_MIXNODES_URL: &str = "https://explorer.nymtech.net/api/v1/mix-nodes"; + +// TODO: create a explorer-api-client +async fn fetch_mixnodes_from_explorer_api() -> Option> { + reqwest::get(EXPLORER_API_MIXNODES_URL) + .await + .ok()? + .json::>() + .await + .ok() +} + +#[derive(Copy, Clone, Hash, PartialEq, Eq, Serialize, Deserialize, Debug)] +pub enum CountryGroup { + Europe, + NorthAmerica, + SouthAmerica, + Oceania, + Asia, + Africa, + Unknown, +} + +impl CountryGroup { + // We map contry codes into group, which initially are continent codes to a first approximation, + // but we do it manually to reserve the right to tweak this distribution for our purposes. + fn new(country_code: &str) -> Self { + let country_code = country_code.to_uppercase(); + use CountryGroup::*; + match country_code.as_ref() { + // Europe + "AT" => Europe, + "BG" => Europe, + "CH" => Europe, + "CY" => Europe, + "CZ" => Europe, + "DE" => Europe, + "DK" => Europe, + "ES" => Europe, + "FI" => Europe, + "FR" => Europe, + "GB" => Europe, + "GR" => Europe, + "IE" => Europe, + "IT" => Europe, + "LT" => Europe, + "LU" => Europe, + "LV" => Europe, + "MD" => Europe, + "MT" => Europe, + "NL" => Europe, + "NO" => Europe, + "PL" => Europe, + "RO" => Europe, + "SE" => Europe, + "SK" => Europe, + "TR" => Europe, + "UA" => Europe, + + // North America + "CA" => NorthAmerica, + "MX" => NorthAmerica, + "US" => NorthAmerica, + + // South America + "AR" => SouthAmerica, + "BR" => SouthAmerica, + "CL" => SouthAmerica, + "CO" => SouthAmerica, + "CR" => SouthAmerica, + "GT" => SouthAmerica, + + // Oceania + "AU" => Oceania, + + // Asia + "AM" => Asia, + "BH" => Asia, + "CN" => Asia, + "GE" => Asia, + "HK" => Asia, + "ID" => Asia, + "IL" => Asia, + "IN" => Asia, + "JP" => Asia, + "KH" => Asia, + "KR" => Asia, + "KZ" => Asia, + "MY" => Asia, + "RU" => Asia, + "SG" => Asia, + "TH" => Asia, + "VN" => Asia, + + // Africa + "SC" => Africa, + "UG" => Africa, + "ZA" => Africa, + + // And group level codes work too + "EU" => Europe, + "NA" => NorthAmerica, + "SA" => SouthAmerica, + "OC" => Oceania, + "AS" => Asia, + "AF" => Africa, + + // And some aliases + "EUROPE" => Europe, + "NORTHAMERICA" => NorthAmerica, + "SOUTHAMERICA" => SouthAmerica, + "OCEANIA" => Oceania, + "ASIA" => Asia, + "AFRICA" => Africa, + + _ => { + info!("Unknown country code: {}", country_code); + Unknown + } + } + } +} + +impl fmt::Display for CountryGroup { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use CountryGroup::*; + match self { + Europe => write!(f, "EU"), + NorthAmerica => write!(f, "NA"), + SouthAmerica => write!(f, "SA"), + Oceania => write!(f, "OC"), + Asia => write!(f, "AS"), + Africa => write!(f, "AF"), + Unknown => write!(f, "Unknown"), + } + } +} + +impl std::str::FromStr for CountryGroup { + type Err = (); + + fn from_str(s: &str) -> Result { + let group = CountryGroup::new(s); + if group == CountryGroup::Unknown { + Err(()) + } else { + Ok(group) + } + } +} + +impl CountryGroup { + #[allow(unused)] + fn known(self) -> Option { + use CountryGroup::*; + match self { + Europe | NorthAmerica | SouthAmerica | Oceania | Asia | Africa => Some(self), + Unknown => None, + } + } +} + +fn group_mixnodes_by_country_code( + mixnodes: Vec, +) -> HashMap> { + mixnodes + .into_iter() + .fold(HashMap::>::new(), |mut acc, m| { + if let Some(ref location) = m.location { + let country_code = location.two_letter_iso_country_code.clone(); + let group_code = CountryGroup::new(country_code.as_str()); + let mixnodes = acc.entry(group_code).or_insert_with(Vec::new); + mixnodes.push(m.mix_id); + } + acc + }) +} + +fn log_mixnode_distribution(mixnodes: &HashMap>) { + let mixnode_distribution = mixnodes + .iter() + .map(|(k, v)| format!("{}: {}", k, v.len())) + .collect::>() + .join(", "); + debug!("Mixnode distribution - {}", mixnode_distribution); +} + +fn check_layer_integrity(topology: NymTopology) -> Result<(), ()> { + let mixes = topology.mixes(); + if mixes.keys().len() < 3 { + error!("Layer is missing in topology!"); + return Err(()); + } + for (layer, mixnodes) in mixes { + debug!("Layer {:?} has {} mixnodes", layer, mixnodes.len()); + if mixnodes.len() < MIN_NODES_PER_LAYER { + error!( + "There are only {} mixnodes in layer {:?}", + mixnodes.len(), + layer + ); + return Err(()); + } + } + Ok(()) +} + +pub struct GeoAwareTopologyProvider { + validator_client: nym_validator_client::client::NymApiClient, + filter_on: CountryGroup, + client_version: String, +} + +impl GeoAwareTopologyProvider { + pub fn new( + mut nym_api_urls: Vec, + client_version: String, + filter_on: CountryGroup, + ) -> GeoAwareTopologyProvider { + log::info!( + "Creating geo-aware topology provider with filter on {:?}", + filter_on + ); + nym_api_urls.shuffle(&mut thread_rng()); + + GeoAwareTopologyProvider { + validator_client: nym_validator_client::client::NymApiClient::new( + nym_api_urls[0].clone(), + ), + filter_on, + client_version, + } + } + + async fn get_topology(&self) -> Option { + let mixnodes = match self.validator_client.get_cached_active_mixnodes().await { + Err(err) => { + error!("failed to get network mixnodes - {err}"); + return None; + } + Ok(mixes) => mixes, + }; + + let gateways = match self.validator_client.get_cached_gateways().await { + Err(err) => { + error!("failed to get network gateways - {err}"); + return None; + } + Ok(gateways) => gateways, + }; + + // Also fetch mixnodes cached by explorer-api, with the purpose of getting their + // geolocation. + debug!("Fetching mixnodes from explorer-api..."); + let Some(mixnodes_from_explorer_api) = fetch_mixnodes_from_explorer_api().await else { + error!("failed to get mixnodes from explorer-api"); + return None; + }; + + // Partition mixnodes_from_explorer_api according to the value of + // two_letter_iso_country_code. + // NOTE: we construct the full distribution here, but only use the one we're interested in. + // The reason we this instead of a straight filter is that this opens up the possibility to + // complement a small grouping with mixnodes from adjecent countries. + let mixnode_distribution = group_mixnodes_by_country_code(mixnodes_from_explorer_api); + log_mixnode_distribution(&mixnode_distribution); + + let Some(filtered_mixnode_ids) = mixnode_distribution.get(&self.filter_on) else { + error!("no mixnodes found for: {}", self.filter_on); + return None; + }; + + let mixnodes = mixnodes + .into_iter() + .filter(|m| filtered_mixnode_ids.contains(&m.mix_id())) + .collect::>(); + + let topology = nym_topology_from_detailed(mixnodes, gateways) + .filter_system_version(&self.client_version); + + // TODO: return real error type + check_layer_integrity(topology.clone()).ok()?; + + Some(topology) + } +} + +#[cfg(not(target_arch = "wasm32"))] +#[async_trait] +impl TopologyProvider for GeoAwareTopologyProvider { + // this will be manually refreshed on a timer specified inside mixnet client config + async fn get_new_topology(&mut self) -> Option { + self.get_topology().await + } +} + +#[cfg(target_arch = "wasm32")] +#[async_trait(?Send)] +impl TopologyProvider for GeoAwareTopologyProvider { + // this will be manually refreshed on a timer specified inside mixnet client config + async fn get_new_topology(&mut self) -> Option { + self.get_topology().await + } +} diff --git a/common/client-core/src/client/topology_control/mod.rs b/common/client-core/src/client/topology_control/mod.rs index 0fef523b1e..ed426dde50 100644 --- a/common/client-core/src/client/topology_control/mod.rs +++ b/common/client-core/src/client/topology_control/mod.rs @@ -10,6 +10,7 @@ use nym_topology::NymTopologyError; use std::time::Duration; mod accessor; +pub mod geo_aware_provider; pub(crate) mod nym_api_provider; // TODO: move it to config later diff --git a/common/client-core/src/config/mod.rs b/common/client-core/src/config/mod.rs index e8f08adfaa..465c227e19 100644 --- a/common/client-core/src/config/mod.rs +++ b/common/client-core/src/config/mod.rs @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize}; use std::time::Duration; use url::Url; -use crate::error::ClientCoreError; +use crate::{client::topology_control::geo_aware_provider::CountryGroup, error::ClientCoreError}; #[cfg(target_arch = "wasm32")] use wasm_bindgen::prelude::*; @@ -158,6 +158,15 @@ impl Config { self } + pub fn with_topology_structure(mut self, topology_structure: TopologyStructure) -> Self { + self.set_topology_structure(topology_structure); + self + } + + pub fn set_topology_structure(&mut self, topology_structure: TopologyStructure) { + self.debug.topology.topology_structure = topology_structure; + } + pub fn with_no_per_hop_delays(mut self, no_per_hop_delays: bool) -> Self { if no_per_hop_delays { self.set_no_per_hop_delays() @@ -466,6 +475,16 @@ pub struct Topology { /// the first valid instance. /// Supersedes `topology_refresh_rate_ms`. pub disable_refreshing: bool, + + /// Specifies the mixnode topology to be used for sending packets. + pub topology_structure: TopologyStructure, +} + +#[derive(Default, Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] +pub enum TopologyStructure { + #[default] + NymApi, + GeoAware(CountryGroup), } impl Default for Topology { @@ -474,6 +493,7 @@ impl Default for Topology { topology_refresh_rate: DEFAULT_TOPOLOGY_REFRESH_RATE, topology_resolution_timeout: DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT, disable_refreshing: false, + topology_structure: TopologyStructure::default(), } } } diff --git a/common/client-core/src/config/old_config_v1_1_20_2.rs b/common/client-core/src/config/old_config_v1_1_20_2.rs index ed0cd0356a..a097b55f2a 100644 --- a/common/client-core/src/config/old_config_v1_1_20_2.rs +++ b/common/client-core/src/config/old_config_v1_1_20_2.rs @@ -267,6 +267,7 @@ impl From for Topology { topology_refresh_rate: value.topology_refresh_rate, topology_resolution_timeout: value.topology_resolution_timeout, disable_refreshing: value.disable_refreshing, + topology_structure: Default::default(), } } } diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs index 69f1a89209..c29077c3b6 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs @@ -58,6 +58,10 @@ impl MixNodeDetails { self.bond_information.mix_id } + pub fn layer(&self) -> Layer { + self.bond_information.layer + } + pub fn is_unbonding(&self) -> bool { self.bond_information.is_unbonding } diff --git a/common/socks5-client-core/Cargo.toml b/common/socks5-client-core/Cargo.toml index 9ca792f8b1..2e1aa52b32 100644 --- a/common/socks5-client-core/Cargo.toml +++ b/common/socks5-client-core/Cargo.toml @@ -7,22 +7,27 @@ edition = "2021" [dependencies] dirs = "4.0" +futures = "0.3" log = { workspace = true } pin-project = "1.0" rand = { version = "0.7.3", features = ["wasm-bindgen"] } +reqwest = "0.11.4" +schemars = { version = "0.8", features = ["preserve_order"] } serde = { workspace = true, features = ["derive"] } # for config serialization/deserialization -thiserror = "1.0.34" tap = "1.0.1" +thiserror = "1.0.34" tokio = { version = "1.24.1", features = ["rt-multi-thread", "net", "signal"] } -futures = "0.3" +url = "2.2" -nym-client-core = { path = "../client-core", features = ["fs-surb-storage"] } nym-bandwidth-controller = { path = "../../common/bandwidth-controller" } +nym-client-core = { path = "../client-core", features = ["fs-surb-storage"] } nym-config = { path = "../config" } +nym-contracts-common = { path = "../cosmwasm-smart-contracts/contracts-common" } nym-credential-storage = { path = "../credential-storage" } +nym-mixnet-contract-common = { path = "../cosmwasm-smart-contracts/mixnet-contract" } nym-network-defaults = { path = "../network-defaults" } -nym-socks5-proxy-helpers = { path = "../socks5/proxy-helpers" } nym-service-providers-common = { path = "../../service-providers/common" } +nym-socks5-proxy-helpers = { path = "../socks5/proxy-helpers" } nym-socks5-requests = { path = "../socks5/requests" } nym-sphinx = { path = "../nymsphinx" } nym-task = { path = "../task" } diff --git a/common/socks5-client-core/src/lib.rs b/common/socks5-client-core/src/lib.rs index 2070eeaf71..74d27b69ed 100644 --- a/common/socks5-client-core/src/lib.rs +++ b/common/socks5-client-core/src/lib.rs @@ -24,6 +24,7 @@ use nym_credential_storage::storage::Storage as CredentialStorage; use nym_sphinx::addressing::clients::Recipient; use nym_sphinx::params::PacketType; use nym_task::{TaskClient, TaskManager}; + use std::error::Error; pub mod config; diff --git a/explorer-api/Cargo.toml b/explorer-api/Cargo.toml index 5e1dec9f48..c4c7b345bc 100644 --- a/explorer-api/Cargo.toml +++ b/explorer-api/Cargo.toml @@ -8,12 +8,17 @@ edition = "2021" [dependencies] chrono = { version = "0.4.19", features = ["serde"] } clap = { version = "4.0", features = ["cargo", "derive"] } +dotenvy = "0.15.6" humantime-serde = "1.0" isocountry = "0.3.2" itertools = "0.10.3" log = { workspace = true } +maxminddb = "0.23.0" okapi = { version = "0.7.0-rc.1", features = ["impl_json_schema"] } pretty_env_logger = "0.4.0" +rand = "0.8.5" +rand_pcg = "0.3.1" +rand_seeder = "0.2.3" reqwest = "0.11.4" rocket = { version = "0.5.0-rc.2", features = ["json"] } rocket_cors = { git="https://github.com/lawliet89/rocket_cors", rev="dfd3662c49e2f6fc37df35091cb94d82f7fb5915" } @@ -23,15 +28,11 @@ serde = "1.0.126" serde_json = "1.0.66" thiserror = "1.0.29" tokio = {version = "1.21.2", features = ["full"] } -maxminddb = "0.23.0" -dotenvy = "0.15.6" -rand = "0.8.5" -rand_seeder = "0.2.3" -rand_pcg = "0.3.1" -nym-mixnet-contract-common = { path = "../common/cosmwasm-smart-contracts/mixnet-contract" } -nym-contracts-common = { path = "../common/cosmwasm-smart-contracts/contracts-common" } -nym-network-defaults = { path = "../common/network-defaults" } nym-bin-common = { path = "../common/bin-common"} +nym-contracts-common = { path = "../common/cosmwasm-smart-contracts/contracts-common" } +nym-explorer-api-requests = { path = "explorer-api-requests" } +nym-mixnet-contract-common = { path = "../common/cosmwasm-smart-contracts/mixnet-contract" } +nym-network-defaults = { path = "../common/network-defaults" } nym-task = { path = "../common/task" } nym-validator-client = { path = "../common/client-libs/validator-client", features=["http-client"] } diff --git a/explorer-api/explorer-api-requests/Cargo.toml b/explorer-api/explorer-api-requests/Cargo.toml new file mode 100644 index 0000000000..93c8faaada --- /dev/null +++ b/explorer-api/explorer-api-requests/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "nym-explorer-api-requests" +version = "0.1.0" +edition = "2021" + +[dependencies] +nym-contracts-common = { path = "../../common/cosmwasm-smart-contracts/contracts-common" } +nym-mixnet-contract-common = { path = "../../common/cosmwasm-smart-contracts/mixnet-contract" } +nym-validator-client = { path = "../../common/client-libs/validator-client" } +schemars = { version = "0.8", features = ["preserve_order"] } +serde = { version = "1.0", features = ["derive"] } +ts-rs = { version = "6.1.2", optional = true } diff --git a/explorer-api/explorer-api-requests/src/lib.rs b/explorer-api/explorer-api-requests/src/lib.rs new file mode 100644 index 0000000000..bfcafa2860 --- /dev/null +++ b/explorer-api/explorer-api-requests/src/lib.rs @@ -0,0 +1,44 @@ +use nym_contracts_common::Percent; +use nym_mixnet_contract_common::{Addr, Coin, Layer, MixId, MixNode}; +use nym_validator_client::models::NodePerformance; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)] +#[serde(rename_all = "snake_case")] +pub enum MixnodeStatus { + Active, // in both the active set and the rewarded set + Standby, // only in the rewarded set + Inactive, // in neither the rewarded set nor the active set +} + +#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] +pub struct PrettyDetailedMixNodeBond { + pub mix_id: MixId, + pub location: Option, + pub status: MixnodeStatus, + pub pledge_amount: Coin, + pub total_delegation: Coin, + pub owner: Addr, + pub layer: Layer, + pub mix_node: MixNode, + pub stake_saturation: f32, + pub uncapped_saturation: f32, + pub avg_uptime: u8, + pub node_performance: NodePerformance, + pub estimated_operator_apy: f64, + pub estimated_delegators_apy: f64, + pub operating_cost: Coin, + pub profit_margin_percent: Percent, + pub family_id: Option, + pub blacklisted: bool, +} + +#[derive(Clone, Debug, JsonSchema, Serialize, Deserialize)] +pub struct Location { + pub two_letter_iso_country_code: String, + pub three_letter_iso_country_code: String, + pub country_name: String, + pub latitude: Option, + pub longitude: Option, +} diff --git a/explorer-api/src/country_statistics/geolocate.rs b/explorer-api/src/country_statistics/geolocate.rs index 8158c6e65e..a80ebc28e4 100644 --- a/explorer-api/src/country_statistics/geolocate.rs +++ b/explorer-api/src/country_statistics/geolocate.rs @@ -1,9 +1,9 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::mix_nodes::location::Location; use crate::state::ExplorerApiStateContext; use log::{info, warn}; +use nym_explorer_api_requests::Location; use nym_task::TaskClient; pub(crate) struct GeoLocateTask { @@ -64,7 +64,7 @@ impl GeoLocateTask { ) { Ok(opt) => match opt { Some(location) => { - let location = Location::new(location); + let location: Location = location.into(); trace!( "{} mix nodes already located. Ip {} is located in {:#?}", diff --git a/explorer-api/src/geo_ip/location.rs b/explorer-api/src/geo_ip/location.rs index adbdb6cef3..fdb8584938 100644 --- a/explorer-api/src/geo_ip/location.rs +++ b/explorer-api/src/geo_ip/location.rs @@ -42,6 +42,18 @@ pub(crate) struct Location { pub(crate) longitude: Option, } +impl From for nym_explorer_api_requests::Location { + fn from(location: Location) -> Self { + nym_explorer_api_requests::Location { + country_name: location.name, + two_letter_iso_country_code: location.iso_alpha2, + three_letter_iso_country_code: location.iso_alpha3, + latitude: location.latitude, + longitude: location.longitude, + } + } +} + impl GeoIp { pub fn new() -> Self { let db_path = std::env::var("GEOIP_DB_PATH").unwrap_or_else(|e| { diff --git a/explorer-api/src/mix_node/http.rs b/explorer-api/src/mix_node/http.rs index 137c6250ed..e00ed8ff82 100644 --- a/explorer-api/src/mix_node/http.rs +++ b/explorer-api/src/mix_node/http.rs @@ -6,9 +6,10 @@ use crate::mix_node::delegations::{ }; use crate::mix_node::econ_stats::retrieve_mixnode_econ_stats; use crate::mix_node::models::{ - EconomicDynamicsStats, NodeDescription, NodeStats, PrettyDetailedMixNodeBond, SummedDelegations, + EconomicDynamicsStats, NodeDescription, NodeStats, SummedDelegations, }; use crate::state::ExplorerApiStateContext; +use nym_explorer_api_requests::PrettyDetailedMixNodeBond; use nym_mixnet_contract_common::{Delegation, MixId}; use reqwest::Error as ReqwestError; use rocket::response::status::NotFound; diff --git a/explorer-api/src/mix_node/mod.rs b/explorer-api/src/mix_node/mod.rs index 88c3b1cd71..dac365c71d 100644 --- a/explorer-api/src/mix_node/mod.rs +++ b/explorer-api/src/mix_node/mod.rs @@ -1,4 +1,4 @@ pub(crate) mod delegations; pub(crate) mod econ_stats; pub(crate) mod http; -pub(crate) mod models; +pub mod models; diff --git a/explorer-api/src/mix_node/models.rs b/explorer-api/src/mix_node/models.rs index 94ae6558d0..4adfa6dd86 100644 --- a/explorer-api/src/mix_node/models.rs +++ b/explorer-api/src/mix_node/models.rs @@ -2,49 +2,15 @@ // SPDX-License-Identifier: Apache-2.0 use crate::cache::Cache; -use crate::mix_nodes::location::Location; -use nym_contracts_common::Percent; use nym_mixnet_contract_common::Delegation; -use nym_mixnet_contract_common::{Addr, Coin, Layer, MixId, MixNode}; -use nym_validator_client::models::{NodePerformance, SelectionChance}; +use nym_mixnet_contract_common::{Addr, Coin, MixId}; +use nym_validator_client::models::SelectionChance; use serde::Deserialize; use serde::Serialize; use std::sync::Arc; use std::time::SystemTime; use tokio::sync::RwLock; -#[derive(Clone, Debug, Serialize, JsonSchema, PartialEq)] -#[serde(rename_all = "snake_case")] -pub(crate) enum MixnodeStatus { - Active, // in both the active set and the rewarded set - Standby, // only in the rewarded set - Inactive, // in neither the rewarded set nor the active set -} - -#[derive(Clone, Debug, Serialize, JsonSchema)] -pub(crate) struct PrettyDetailedMixNodeBond { - // I leave this to @MS to refactor this type as a lot of things here are redundant thanks to - // the existence of `MixNodeDetails` - pub mix_id: MixId, - pub location: Option, - pub status: MixnodeStatus, - pub pledge_amount: Coin, - pub total_delegation: Coin, - pub owner: Addr, - pub layer: Layer, - pub mix_node: MixNode, - pub stake_saturation: f32, - pub uncapped_saturation: f32, - pub avg_uptime: u8, - pub node_performance: NodePerformance, - pub estimated_operator_apy: f64, - pub estimated_delegators_apy: f64, - pub operating_cost: Coin, - pub profit_margin_percent: Percent, - pub family_id: Option, - pub blacklisted: bool, -} - #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, JsonSchema)] pub struct SummedDelegations { pub owner: Addr, diff --git a/explorer-api/src/mix_nodes/http.rs b/explorer-api/src/mix_nodes/http.rs index ef5570e455..a36843b66f 100644 --- a/explorer-api/src/mix_nodes/http.rs +++ b/explorer-api/src/mix_nodes/http.rs @@ -1,6 +1,6 @@ -use crate::mix_node::models::{MixnodeStatus, PrettyDetailedMixNodeBond}; use crate::mix_nodes::models::{MixNodeActiveSetSummary, MixNodeSummary}; use crate::state::ExplorerApiStateContext; +use nym_explorer_api_requests::{MixnodeStatus, PrettyDetailedMixNodeBond}; use rocket::serde::json::Json; use rocket::{Route, State}; use rocket_okapi::okapi::openapi3::OpenApi; diff --git a/explorer-api/src/mix_nodes/location.rs b/explorer-api/src/mix_nodes/location.rs index b876cdc792..4908564697 100644 --- a/explorer-api/src/mix_nodes/location.rs +++ b/explorer-api/src/mix_nodes/location.rs @@ -1,7 +1,7 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::geo_ip::location; +use nym_explorer_api_requests::Location; use nym_mixnet_contract_common::MixId; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -31,27 +31,6 @@ pub(crate) struct LocationCacheItem { pub(crate) valid_until: SystemTime, } -#[derive(Clone, Debug, JsonSchema, Serialize, Deserialize)] -pub(crate) struct Location { - pub(crate) two_letter_iso_country_code: String, - pub(crate) three_letter_iso_country_code: String, - pub(crate) country_name: String, - pub(crate) latitude: Option, - pub(crate) longitude: Option, -} - -impl Location { - pub(crate) fn new(location: location::Location) -> Self { - Location { - country_name: location.name, - two_letter_iso_country_code: location.iso_alpha2, - three_letter_iso_country_code: location.iso_alpha3, - latitude: location.latitude, - longitude: location.longitude, - } - } -} - impl LocationCacheItem { pub(crate) fn new_from_location(location: Option) -> Self { LocationCacheItem { diff --git a/explorer-api/src/mix_nodes/models.rs b/explorer-api/src/mix_nodes/models.rs index bfead42c8c..b107bb2168 100644 --- a/explorer-api/src/mix_nodes/models.rs +++ b/explorer-api/src/mix_nodes/models.rs @@ -5,6 +5,7 @@ use std::collections::{HashMap, HashSet}; use std::sync::Arc; use std::time::{Duration, SystemTime}; +use nym_explorer_api_requests::{Location, MixnodeStatus, PrettyDetailedMixNodeBond}; use nym_mixnet_contract_common::rewarding::helpers::truncate_reward; use nym_mixnet_contract_common::MixId; use serde::Serialize; @@ -14,8 +15,7 @@ use crate::helpers::best_effort_small_dec_to_f64; use nym_validator_client::models::MixNodeBondAnnotated; use super::utils::family_numerical_id; -use crate::mix_node::models::{MixnodeStatus, PrettyDetailedMixNodeBond}; -use crate::mix_nodes::location::{Location, LocationCache, LocationCacheItem}; +use crate::mix_nodes::location::{LocationCache, LocationCacheItem}; use crate::mix_nodes::CACHE_ENTRY_TTL; #[derive(Clone, Debug, Serialize, JsonSchema)] diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 6287fadf38..3f657d5852 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -284,8 +284,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" dependencies = [ "bitcoin_hashes", - "rand 0.7.3", - "rand_core 0.5.1", + "rand 0.8.5", + "rand_core 0.6.4", "serde", "unicode-normalization", "zeroize", @@ -2596,17 +2596,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "hostname" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" -dependencies = [ - "libc", - "match_cfg", - "winapi", -] - [[package]] name = "html5ever" version = "0.25.2" @@ -3572,6 +3561,7 @@ dependencies = [ "nym-config", "nym-credential-storage", "nym-crypto", + "nym-explorer-api-requests", "nym-gateway-client", "nym-gateway-requests", "nym-network-defaults", @@ -3582,6 +3572,7 @@ dependencies = [ "nym-topology", "nym-validator-client", "rand 0.7.3", + "reqwest", "serde", "serde_json", "sha2 0.10.6", @@ -3669,7 +3660,7 @@ dependencies = [ [[package]] name = "nym-connect" -version = "1.1.13" +version = "1.1.15" dependencies = [ "anyhow", "bip39", @@ -3794,6 +3785,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "nym-explorer-api-requests" +version = "0.1.0" +dependencies = [ + "nym-contracts-common", + "nym-mixnet-contract-common", + "nym-validator-client", + "schemars", + "serde", +] + [[package]] name = "nym-gateway-client" version = "0.1.0" @@ -3995,7 +3997,9 @@ dependencies = [ "nym-bandwidth-controller", "nym-client-core", "nym-config", + "nym-contracts-common", "nym-credential-storage", + "nym-mixnet-contract-common", "nym-network-defaults", "nym-service-providers-common", "nym-socks5-proxy-helpers", @@ -4005,10 +4009,13 @@ dependencies = [ "nym-validator-client", "pin-project", "rand 0.7.3", + "reqwest", + "schemars", "serde", "tap", "thiserror", "tokio", + "url", ] [[package]] @@ -5155,9 +5162,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "reqwest" -version = "0.11.15" +version = "0.11.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ba30cc2c0cd02af1222ed216ba659cdb2f879dfe3181852fe7c50b1d0005949" +checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" dependencies = [ "base64 0.21.2", "bytes", diff --git a/nym-connect/desktop/src-tauri/src/tasks.rs b/nym-connect/desktop/src-tauri/src/tasks.rs index 8c69b1be7e..06b0809c2f 100644 --- a/nym-connect/desktop/src-tauri/src/tasks.rs +++ b/nym-connect/desktop/src-tauri/src/tasks.rs @@ -1,17 +1,23 @@ use futures::{channel::mpsc, StreamExt}; -use nym_client_core::client::base_client::storage::gateway_details::GatewayDetailsStore; -use nym_client_core::client::base_client::storage::{MixnetClientStorage, OnDiskPersistent}; -use nym_client_core::{config::GatewayEndpointConfig, error::ClientCoreStatusMessage}; -use nym_socks5_client_core::NymClient as Socks5NymClient; -use nym_socks5_client_core::Socks5ControlMessageSender; +use nym_client_core::{ + client::{ + base_client::storage::{ + gateway_details::GatewayDetailsStore, MixnetClientStorage, OnDiskPersistent, + }, + topology_control::geo_aware_provider::CountryGroup, + }, + config::{GatewayEndpointConfig, TopologyStructure}, + error::ClientCoreStatusMessage, +}; +use nym_socks5_client_core::{NymClient as Socks5NymClient, Socks5ControlMessageSender}; use nym_sphinx::params::PacketSize; use nym_task::manager::TaskStatus; use std::sync::Arc; use tap::TapFallible; use tokio::sync::RwLock; -use crate::config::{Config, PrivacyLevel}; use crate::{ + config::{Config, PrivacyLevel}, error::Result, events::{self, emit_event, emit_status_event}, models::{ConnectionStatusKind, ConnectivityTestResult}, @@ -46,6 +52,14 @@ fn override_config_from_env(config: &mut Config, privacy_level: &PrivacyLevel) { log::warn!("Disabling per-hop delay"); config.core.base.set_no_per_hop_delays(); + + // TODO: selectable in the UI + let default_country_group = CountryGroup::Europe; + log::warn!("Using geo-aware mixnode selection: {default_country_group}"); + config + .core + .base + .set_topology_structure(TopologyStructure::GeoAware(default_country_group)); } } diff --git a/service-providers/network-requester/src/allowed_hosts/hosts.rs b/service-providers/network-requester/src/allowed_hosts/hosts.rs index 5c48369d0d..11aa3dd276 100644 --- a/service-providers/network-requester/src/allowed_hosts/hosts.rs +++ b/service-providers/network-requester/src/allowed_hosts/hosts.rs @@ -136,7 +136,6 @@ impl HostsStore { }) .map(Host::from) .collect(); - dbg!(&hosts); Ok(hosts) } } From 97956afdf642c5ea6fedefc8406d94f50dfc6fe2 Mon Sep 17 00:00:00 2001 From: mfahampshire Date: Tue, 1 Aug 2023 10:33:34 +0200 Subject: [PATCH 12/46] removed old wallet address flag again --- documentation/docs/src/nodes/mix-node-setup.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/documentation/docs/src/nodes/mix-node-setup.md b/documentation/docs/src/nodes/mix-node-setup.md index 2f93797e1e..4635aa56ac 100644 --- a/documentation/docs/src/nodes/mix-node-setup.md +++ b/documentation/docs/src/nodes/mix-node-setup.md @@ -84,15 +84,15 @@ To check available configuration options for initializing your node use: ``` ~~~ -Initalise your mixnode with the following command, replacing the value of `--id` with the moniker you wish to give your mixnode, and the `--wallet-address` with the Nym address you created earlier. Your `--host` must be publicly routable on the internet in order to mix packets, and can be either an Ipv4 or IPv6 address. The `$(curl ifconfig.me)` command returns your IP automatically using an external service. If you enter your IP address manually, enter it **without** any port information. +Initalise your mixnode with the following command, replacing the value of `--id` with the moniker you wish to give your mixnode. Your `--host` must be publicly routable on the internet in order to mix packets, and can be either an Ipv4 or IPv6 address. The `$(curl ifconfig.me)` command returns your IP automatically using an external service. If you enter your IP address manually, enter it **without** any port information. ``` -./nym-mixnode init --id winston-smithnode --host $(curl ifconfig.me) --wallet-address n1eufxdlgt0puwrwptgjfqne8pj4nhy2u5ft62uq +./nym-mixnode init --id winston-smithnode --host $(curl ifconfig.me) ``` ~~~admonish example collapsible=true title="Console output" ``` - + ``` ~~~ From 15a6af49f092a86a095299ffcfdbac02118030f3 Mon Sep 17 00:00:00 2001 From: Lorexia Date: Tue, 25 Jul 2023 12:54:38 +0200 Subject: [PATCH 13/46] Add updates to community list projects --- .../community-applications-and-guides.md | 8 ++++++++ .../src/images/profile_picture/nymgraph_pp.png | Bin 0 -> 8489 bytes 2 files changed, 8 insertions(+) create mode 100644 documentation/dev-portal/src/images/profile_picture/nymgraph_pp.png diff --git a/documentation/dev-portal/src/community-resources/community-applications-and-guides.md b/documentation/dev-portal/src/community-resources/community-applications-and-guides.md index ba00922658..90e0801e80 100644 --- a/documentation/dev-portal/src/community-resources/community-applications-and-guides.md +++ b/documentation/dev-portal/src/community-resources/community-applications-and-guides.md @@ -93,6 +93,14 @@ We love seeing our developer community create applications using Nym. If you wou +## NymGraph + +> NymGraph is a graphical chat client for Nym running on Ubuntu and Debian. Test it to chat over the Nym network! +* [Github](https://github.com/Tyz3/nymgraph) + + + +

# Community Guides diff --git a/documentation/dev-portal/src/images/profile_picture/nymgraph_pp.png b/documentation/dev-portal/src/images/profile_picture/nymgraph_pp.png new file mode 100644 index 0000000000000000000000000000000000000000..411dbec6e01e27f9f960c521d4cdc453f874326b GIT binary patch literal 8489 zcmYLvdpr}~|Nj|d=xvG68!JjAp^`9ROSh#+7s@SBxle3!zbuq)=*`?pU>})J+^bs>-9RX*You{=e*AA?Di>(qmmK|5&!^6!m&fA z0T3b!K4PMtU zblcD5B$$_Zcz~( zp@sgH@4kx@@evXGGeW<+3&qSt(S-dsdi-(~qSw}M^1SnPhf6SQ5d_VF%!L6nMZs4y>nHq*Xy6MdafU@n<;`vmFV_qyNq}0tzRT1 zsLw#DvTy7P4so^)p6Cl~a}ckxx?NSY9f3zFX%8e1(X)m#&Rvp>zx&dB@63VCVpu0r zMETG6gfsqMo+A5>4P2)Q?_dA2?{t;JIs^2kz^r5;A1?xwsdKb3~!SZ zlC;l1%=~rPQx1tKQ5jTnqw(cXnr|SJl&|t6z@xUJ1r6Gv-a)5&$^jV^XZrkL+jR*k za^a_2{3NR4o3XR(oEX*mml7gKjMtuFxecS42JG7Q2bL3F&5^XIq-~6p;V01#M+XO{ zGxuiogzYYc(-++6g(8zaQyZBrp&t4r8mbF;`x=@Pqoub33gK7`T~Hv2^dnxF%_T@viNGL?C_w}{thsJqIb z#om7F>f2H1x~0s7(6^yRoz3Tw7%@W}8{)5m5;Kw_iy4ATF|;VPhF)c~5s3LZjf_M` zD=B}&u|Cl6^IdBid@t!yZw4Rp8+tDzhW+XJ)*<=+>{S#^E@1n&NiC7cI7W=U&Mf`h zl&y%z+@4uFyC?^;mfk1%$-2p?J8vM9wMRsK2M})RD0L}viOKL1gh3ru!gUa@{6|2V zeBY=!RP!~-57!mix-t;$ecpfkt#si~Y9(Q>90_-{+H$XUgidtEo@^Hzm9F^ZVUS!= zi^d<-Q*jNE9k^0+i)=9rf;yU)42eGsP^`& zXJDTKshlv`pj2neNa#(eO?lmOf_GkjSX(#io#78qh*|%@l3%5mob-TIWYNl1TP#l% zW9$sm-c(&2bM3{HXT2~3-oN|Hl9U0T|B`*e_I?=aO2@qrMgQGI=}Cf z!8+cl;H17oD5be$3if6XRov${RQrLG!+qGyD+im(_vqgW`3llJe0{i3)z;{^!*4S# znvU?|XwML2jhGWT9ZctTOCuv=2T>d?$WAQGb$U%^pbJ?`hF2W&?TnrppY z`NwN@O-4V|vZfM?L^vvt=~hL{OFJ~pQ!b#>!Bzr)^cPg}%yZySY9L}%xN+iYOKG)A zK*F$D!h*FhRdq{ZFFR6}+#y4%Zp})mEK~ryg5IuFFpF~B>1)r+|=HJC`^kl9y`Pq$0|tqsS}PAHAvJ2 z_u6y`mD%&-D$Mtw>TWU;?)BQ(=*uvJT^L!51Zx44q~!z4@gvEPOw`DfMi{xKpwIzr zE{2`oMB0+DLfj76|Ma)CE9`V`DP^Q8HWIACe7*R2d{eSn8~ly_qC)5wXO9$r-8ljV zLbUgqB0`)skQjbb?-c=d19evV{`A{4mtU!h4FdWpgUM$yJqf_=#YNXo&8)rqV#G62g{kL$5l^f00!>DU4N4&CFqeMCP1KI@{#L~$`%Qo0 zGVF1^K#lB-2K&F)tn4ylL6oE@V%R+>@W_ItG6HZN;@CGzumQgXooKxJ|2l7B@iD2w zz)GD5DQ;nra5_Qbyzbgu2NWs#$(NSHe=g1CpJPM3*Kio949_^JZq`z0yf*9n#KMfO z%paNmu>H8!t#BLNZdj%OrmtEOmf$ATciO8l+M*Rvm#w7!cT!f4S6wu*IMqn77D3@Z zxvJIOZmv8y{#1k4|7l-vplp-(R zsaXGAP7JV<7QVV_X0U+^Oq+5QeAx^4GQ&Fb<-`5B!8il+4swl zQV1p&!~r|saxzbb%(+vM2zTX7B$%HtXl7B=B8i%-WGQu9#K0+g*R8z$XW}d_LUIGI zj*7NJEV?2oNB3-qCx>#*(b5x9KHOc2w;yMpP12H3}E7Cup~9vrPP1iXJOxRzZxT3wfV^-;j#J7eXW zJlWf-Z*IPLYCj;qYj+6h_vB|~Lp7$L@n`6Ob@-3*FW*P}XkZE&B zzcFyS`@4MKO&UiA&O>d?)8kpRxA_dV83HGL?c<(eOiW`hVP{{zD0p_wj)S<}qeey_ z1fbIY;kz=&d~qyF1yGHHFMdMYPE#Y7*VqB-eBM4@)dnG8K=tTT{_vAVl7hc!JJH8F zc4t=-X4)2DTv7va4kNitI8}(=uC0LOp`SxQa?^-IY0_YzP+>K*t5K9Y*1dSe{)`aV zSHJubM)={rE(ze4XdA__A0CBtGy)?nxck}}b@CGupdNXu$9pFdE?=VqaKaAzzQ6dQ zX2Bzd*#N4jr+xmuoxJ1UnTIyPEh^w-`bRxAUe(|_kaz5{qj=~4iD%e^B0#BIhvqAV z4dk3_)qU0laH8fiT8h5@A8zRa4R6HA= zpqZr$Sk5*%K|Ozy38E%0fF?ZOb0B1$VAL^T!Q>+B=u4S*w_!CDlK`$E1Zn*8-f zsc@DiV5vlX#7&4XRlB~Y=>VEtoVjqR8bs>}z@a8`uKRB$YfFm)>^H6nV|O>)-v)}2 z0P8gxv&~+W$*uvB>>~_)q-smU~omg~bbB7RLMg>R$k$-11_h+VX1v=qyXJ zx$f<9&=qQTtu9#_-l81PSPmTkMNS}x@=06}Ep;PE44~5Nq9&{XmEP^fp(Ot4pI1`l zEp=jmlV>L}zch04$G4Te%|?7QDAb!e?lPgyOZe-#A*k!5e?HF_b?6Tk23}m-*it`M zMrOtWJYRgExXK;$QV#9zCpcwgiJvE3h8)KK3l!>VmUm+D3&j+820ci!^UR@fel!#T z;8j~;oxz&Z+5_s^=pFWg_|(LYGNl2v`oh>!!Z|f^nCCip@c0mQ@F>8_rjcID0;h<+ zUPm7ZL0q+{Hg&=dpE&ag#ZVa^Q6Zuy}tEepNMQ$Sgkrje~31$U2tej*%<-q)xf9k9n)CdL=oT?XAX5$<^hnW#nXPS2yia;&o`3M zhXB~uzMwD>@<;T0k_IHfZX_G?MF7j7`dnn2;#L6CM#oPI)*2DoLd(wdEFD!N8=FIl z^VQ|Z3~>y=k*eJfszcVD>zSDpA>j7B&n~h}vlg=Q2OHJ^qAk{Vm-(neJ|tiTR;NU^ zMMGd0PY9U0WMEKepMSNV7YFkaY8Y>{Egm7XzG zB-tV}7G4U0j?v485JN~n(N2y+1L|=M3^oo#Ij;k5#?4j<=H>`+if%42Cuz+zF=pl! z2)(r>41kg~FQn3hfg7Gx5d$Z4oXi#mc@IONB_0A0;Zgul32JO)n+DvOgEN%2R}`Y5 z9?Zh865y2Ke>^D#trde7!X~_suLYMt^nbYj+x=gv|8xsNP(Z~#$1;Y=7uCa9Y5Srx zobcIPL$W5oeO+6Jf20*!vAA{u8m^IGUj1Bq#2*E1rN}NV0Ge3z#|mie9;gK?l15q& zgQ0pd{_3aO0&{lirCaoxLEls!hSNy^>iB_Os0?pt)KcgLw7@&1V$6SXAT({zZSbpO zE3YwG2+*)D0(p<1c-m>x&|gb>1ixVa-=F=a6S_@TT{eLEZ$F^xg!)&z4`i&|S2eYj znAW#n1p~{2%R&^pKELW>C5YF{5N&}_mLIeO;_1WVk>XqqY+~qt$Ms7QxDE-`}$U8LJ_qYt?a9w?CxF3=v?GL`y%ZzD=+^clCRg zJeL2hQ~;oUaZ_d8=6F{QT%d-NB7(gXLidbD+6}=pbo3~GZ1daR=NYLYF3Q<4gSiy)=oYIVBZRSO$R6!gSBFU6%y&ocRVoE&b0vY>wAY zw-CU^E;^UacZ*$(ZBPCiIJsIA>6A#~X}U8Ij&-tI318b6CPrPr<1YpHnn1LvDD>geS@S9`8~D z%Mg04(Acy5a}VBzxI6sCJUqEVdWK`|k1GC-PydJjUc|>w{(G#!C9lYFtE3FkI7h66 z0J*nOYdee==H@lzI?KNM^Q|L^c2~p!3vcJX1A0`M_nYlMM}&x!hx9i3dnT;B{Q7$3 zVwU86)!f>Z%Nu~BPcGe{XK?jtcDo30TAe5<{R8>t(ER`u1n-#WcuwQ^y9@dZNT>{K@qmKfhI$JL_ zC&FczZv?chM&6GcP#N_bpaY4IGDI`BRTxcZ5z8!&HzA@=X^2Ul@G zX1Ta$Gou(U=YoU)rX)qQ$A%SD3sWyW%be>y8zAAZx&0-GV@u(_Q$~@DYX(Aqmrz~W z-WSPG>iWei76I6SAx6PY!(%L2vn(CJLWFo{R*O0qmW7P!iUQkj#4R>SO1pRx?a)!) zWec6%A*}aL5-oi{>;^20_#8?PhTK4JR|Ia^QTy8Pk;MHOf4Lk-fsz&%_lHCzS7n_X zpm}?f3Tc`me2NpmDIUOhU;|h*&4+;^pl5(~@>4WTHwWgp^BrR}O`Yd@YrnJioz#ya z7K!bFt#R`7nEkfMwtvwekNql_6f4GTaDF3bnQwbSiWSG6!2;UB*wi+dZ_C}4_KAlF z+H|U@jN2Gl&0 z#1=sbaxuwyd=m7?HVotb;=Go^D(cHb<#(cDXm zYD0(vCscU;nDU`HeEC@x`WOHl*3X5~vc0@_^>@k~5mfJ&PbZWQX+|;*ad-DA!=?Eo zP5)rYUfvzNSG5q}2kq3dDjko4PQI5IIvs`tozvMR(KJt72e*++26Y~rkDHyH$~(N} zUEP8-;5i$WsQuX+B7PEufX{UNM|33Px>bOpT>+?Tu`T}G^Nyw|T9XTKDYn@ZyenT8 z1mg3{Y~=+-6;Dl5I?OhfRpo2S0q*9)R;EGZ$0#C#ct9T~_fv-bggw-Nw zGK`k?aD3P6JW`T4D7lzlup`LAH8b08WTy;pqjz4kntAv*E}Y%vD;R!%2D=n^PCcq^ zmJC?OGlGeXS-j07;>Pw*2%O!@;}x%||FbYLD{qCvr>ZSX^vl1!4N&g#HN}9A@jaU# zOOrEmg{jXd^A(2pg|56x%bENnKz+8-Q@T8YVcnQ~m`?E_v0>sY#JM0I&r`3>kf>&czql_j1oUX%ND7iCFu|Y)~ zxTRgJ3=Jxz+3Aem^gSj7(q60Fk`KH&DGM+D3k2=wNT76Lv>*9hL5A5iH#DpXl-`*g z;Ar#qpCe{%z8wAxUIwyqRfT;brC|Mt8L|qKtdM|-lTwjHj+OqM!~#&LV^Jc(%s9;5 z-Rxs61pLSK)opEt{^cvcYkCZ!&kmNKn6N^5+39as;(F9ZQG=Dn^>82ixc7NmGJk2w zH$xnFX^p&Vx9)U0SbiNwNTTYHYLm4v=$!xe|3-ro<{q%TX`$bje2-#)mozDCk2(*H zp)5RtCBQp|0q@0`jfc3g5W%G0TZZ_ql03!6hI%keVBN+7DUuj7;|RAOT6%!* z<4jz(w|lXzPYnSgzGz7qIUg+F_I2Gd1e}^GLxwWnC`DRyAOwwD0$$jFGXC2M%Z+QD zXe$(OhULa_fpn~(0n3cz0M{yxEyGY&3#Gx?5g%v9-+yX}ZnvOO_=J8s63G6fzztQ) zOgELKcWm*-cj$Rss|v4Y1H}^7g>ME)lipu$Db0q^=_KAuP_mN*3b3-*P4@GF1=DCo z_B)-_@DppZGRGgoSCm&C;F|J!LNHXO=t4(WbLeTPhQXoMxt8{=3az?iSwmx^EownN zu%0U{FKY89nz8k(d?)l16|;P@^>afsdpR?Sd}5 ztTFD=QhNHUyuB&f928bGd_nE8(U4)jgZX{dWs|3sFBHJ@FWR%s4-=n9#)(FAcU#m6 z6)LD-uzQ{CY5woU`?a>>ppR#>r)#qsS!<{e2@06maSK{Fr0+5w+R9Q$w3 zT#^baV+Ax{281KyN*_<|optBl_zVng#kA)7WhR-iihSAJ#uBts|B0_sWH00K6MR@< zKa0jUwbf7Ve?kG3&O2jhEO4Hz<&-GH$WA_C7o34NMQN{B~I?~-7- zeQ;6>1*rpi9a0J_<3=Z(WMQ94_i0Evh&}`b;d-y%g0HGoT9ZrPTQS_})XS=a@O9K~ zi0Dguv?ce7drFM7FM21!<2iBn?(QLB;t?;QI zyZGlH9;ueU2C3>%rDx)3@DBp*g8u?ILNVHj_7`L`eaml^t1gtCg3{l|R~_!v3Ma81 z*=;^v#Z3uRydW(_#w~9xkWZ{CgKyw+K2Xr)k-n{y$!6{Q3Lb1uuGea2lYF4AeG0+V zIS~`l6GUSzXK#(ZXhld$Z*nwkCWu!xOv%{2^r6^`Ol#sS!=ziBp7>QvuPTOTp!hZ(b{aG10V#z(cQM-x#V%g{S&n?%> kelEbb4*4v#YdcoAP*-IP4!+)L22BHm!xo1a2c07SA6;5Yn*aa+ literal 0 HcmV?d00001 From a344cda9160b24ef8ce767725604fdbcd2b47bd0 Mon Sep 17 00:00:00 2001 From: mfahampshire Date: Tue, 1 Aug 2023 10:33:34 +0200 Subject: [PATCH 14/46] removed old wallet address flag again --- documentation/docs/src/nodes/mix-node-setup.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/documentation/docs/src/nodes/mix-node-setup.md b/documentation/docs/src/nodes/mix-node-setup.md index 2f93797e1e..4635aa56ac 100644 --- a/documentation/docs/src/nodes/mix-node-setup.md +++ b/documentation/docs/src/nodes/mix-node-setup.md @@ -84,15 +84,15 @@ To check available configuration options for initializing your node use: ``` ~~~ -Initalise your mixnode with the following command, replacing the value of `--id` with the moniker you wish to give your mixnode, and the `--wallet-address` with the Nym address you created earlier. Your `--host` must be publicly routable on the internet in order to mix packets, and can be either an Ipv4 or IPv6 address. The `$(curl ifconfig.me)` command returns your IP automatically using an external service. If you enter your IP address manually, enter it **without** any port information. +Initalise your mixnode with the following command, replacing the value of `--id` with the moniker you wish to give your mixnode. Your `--host` must be publicly routable on the internet in order to mix packets, and can be either an Ipv4 or IPv6 address. The `$(curl ifconfig.me)` command returns your IP automatically using an external service. If you enter your IP address manually, enter it **without** any port information. ``` -./nym-mixnode init --id winston-smithnode --host $(curl ifconfig.me) --wallet-address n1eufxdlgt0puwrwptgjfqne8pj4nhy2u5ft62uq +./nym-mixnode init --id winston-smithnode --host $(curl ifconfig.me) ``` ~~~admonish example collapsible=true title="Console output" ``` - + ``` ~~~ From c7147ebfb25228fcdfd32ddfccddbba4ba476dfd Mon Sep 17 00:00:00 2001 From: Lorexia Date: Tue, 25 Jul 2023 12:54:38 +0200 Subject: [PATCH 15/46] Add updates to community list projects --- .../community-applications-and-guides.md | 8 ++++++++ .../src/images/profile_picture/nymgraph_pp.png | Bin 0 -> 8489 bytes 2 files changed, 8 insertions(+) create mode 100644 documentation/dev-portal/src/images/profile_picture/nymgraph_pp.png diff --git a/documentation/dev-portal/src/community-resources/community-applications-and-guides.md b/documentation/dev-portal/src/community-resources/community-applications-and-guides.md index ba00922658..90e0801e80 100644 --- a/documentation/dev-portal/src/community-resources/community-applications-and-guides.md +++ b/documentation/dev-portal/src/community-resources/community-applications-and-guides.md @@ -93,6 +93,14 @@ We love seeing our developer community create applications using Nym. If you wou +## NymGraph + +> NymGraph is a graphical chat client for Nym running on Ubuntu and Debian. Test it to chat over the Nym network! +* [Github](https://github.com/Tyz3/nymgraph) + + + +

# Community Guides diff --git a/documentation/dev-portal/src/images/profile_picture/nymgraph_pp.png b/documentation/dev-portal/src/images/profile_picture/nymgraph_pp.png new file mode 100644 index 0000000000000000000000000000000000000000..411dbec6e01e27f9f960c521d4cdc453f874326b GIT binary patch literal 8489 zcmYLvdpr}~|Nj|d=xvG68!JjAp^`9ROSh#+7s@SBxle3!zbuq)=*`?pU>})J+^bs>-9RX*You{=e*AA?Di>(qmmK|5&!^6!m&fA z0T3b!K4PMtU zblcD5B$$_Zcz~( zp@sgH@4kx@@evXGGeW<+3&qSt(S-dsdi-(~qSw}M^1SnPhf6SQ5d_VF%!L6nMZs4y>nHq*Xy6MdafU@n<;`vmFV_qyNq}0tzRT1 zsLw#DvTy7P4so^)p6Cl~a}ckxx?NSY9f3zFX%8e1(X)m#&Rvp>zx&dB@63VCVpu0r zMETG6gfsqMo+A5>4P2)Q?_dA2?{t;JIs^2kz^r5;A1?xwsdKb3~!SZ zlC;l1%=~rPQx1tKQ5jTnqw(cXnr|SJl&|t6z@xUJ1r6Gv-a)5&$^jV^XZrkL+jR*k za^a_2{3NR4o3XR(oEX*mml7gKjMtuFxecS42JG7Q2bL3F&5^XIq-~6p;V01#M+XO{ zGxuiogzYYc(-++6g(8zaQyZBrp&t4r8mbF;`x=@Pqoub33gK7`T~Hv2^dnxF%_T@viNGL?C_w}{thsJqIb z#om7F>f2H1x~0s7(6^yRoz3Tw7%@W}8{)5m5;Kw_iy4ATF|;VPhF)c~5s3LZjf_M` zD=B}&u|Cl6^IdBid@t!yZw4Rp8+tDzhW+XJ)*<=+>{S#^E@1n&NiC7cI7W=U&Mf`h zl&y%z+@4uFyC?^;mfk1%$-2p?J8vM9wMRsK2M})RD0L}viOKL1gh3ru!gUa@{6|2V zeBY=!RP!~-57!mix-t;$ecpfkt#si~Y9(Q>90_-{+H$XUgidtEo@^Hzm9F^ZVUS!= zi^d<-Q*jNE9k^0+i)=9rf;yU)42eGsP^`& zXJDTKshlv`pj2neNa#(eO?lmOf_GkjSX(#io#78qh*|%@l3%5mob-TIWYNl1TP#l% zW9$sm-c(&2bM3{HXT2~3-oN|Hl9U0T|B`*e_I?=aO2@qrMgQGI=}Cf z!8+cl;H17oD5be$3if6XRov${RQrLG!+qGyD+im(_vqgW`3llJe0{i3)z;{^!*4S# znvU?|XwML2jhGWT9ZctTOCuv=2T>d?$WAQGb$U%^pbJ?`hF2W&?TnrppY z`NwN@O-4V|vZfM?L^vvt=~hL{OFJ~pQ!b#>!Bzr)^cPg}%yZySY9L}%xN+iYOKG)A zK*F$D!h*FhRdq{ZFFR6}+#y4%Zp})mEK~ryg5IuFFpF~B>1)r+|=HJC`^kl9y`Pq$0|tqsS}PAHAvJ2 z_u6y`mD%&-D$Mtw>TWU;?)BQ(=*uvJT^L!51Zx44q~!z4@gvEPOw`DfMi{xKpwIzr zE{2`oMB0+DLfj76|Ma)CE9`V`DP^Q8HWIACe7*R2d{eSn8~ly_qC)5wXO9$r-8ljV zLbUgqB0`)skQjbb?-c=d19evV{`A{4mtU!h4FdWpgUM$yJqf_=#YNXo&8)rqV#G62g{kL$5l^f00!>DU4N4&CFqeMCP1KI@{#L~$`%Qo0 zGVF1^K#lB-2K&F)tn4ylL6oE@V%R+>@W_ItG6HZN;@CGzumQgXooKxJ|2l7B@iD2w zz)GD5DQ;nra5_Qbyzbgu2NWs#$(NSHe=g1CpJPM3*Kio949_^JZq`z0yf*9n#KMfO z%paNmu>H8!t#BLNZdj%OrmtEOmf$ATciO8l+M*Rvm#w7!cT!f4S6wu*IMqn77D3@Z zxvJIOZmv8y{#1k4|7l-vplp-(R zsaXGAP7JV<7QVV_X0U+^Oq+5QeAx^4GQ&Fb<-`5B!8il+4swl zQV1p&!~r|saxzbb%(+vM2zTX7B$%HtXl7B=B8i%-WGQu9#K0+g*R8z$XW}d_LUIGI zj*7NJEV?2oNB3-qCx>#*(b5x9KHOc2w;yMpP12H3}E7Cup~9vrPP1iXJOxRzZxT3wfV^-;j#J7eXW zJlWf-Z*IPLYCj;qYj+6h_vB|~Lp7$L@n`6Ob@-3*FW*P}XkZE&B zzcFyS`@4MKO&UiA&O>d?)8kpRxA_dV83HGL?c<(eOiW`hVP{{zD0p_wj)S<}qeey_ z1fbIY;kz=&d~qyF1yGHHFMdMYPE#Y7*VqB-eBM4@)dnG8K=tTT{_vAVl7hc!JJH8F zc4t=-X4)2DTv7va4kNitI8}(=uC0LOp`SxQa?^-IY0_YzP+>K*t5K9Y*1dSe{)`aV zSHJubM)={rE(ze4XdA__A0CBtGy)?nxck}}b@CGupdNXu$9pFdE?=VqaKaAzzQ6dQ zX2Bzd*#N4jr+xmuoxJ1UnTIyPEh^w-`bRxAUe(|_kaz5{qj=~4iD%e^B0#BIhvqAV z4dk3_)qU0laH8fiT8h5@A8zRa4R6HA= zpqZr$Sk5*%K|Ozy38E%0fF?ZOb0B1$VAL^T!Q>+B=u4S*w_!CDlK`$E1Zn*8-f zsc@DiV5vlX#7&4XRlB~Y=>VEtoVjqR8bs>}z@a8`uKRB$YfFm)>^H6nV|O>)-v)}2 z0P8gxv&~+W$*uvB>>~_)q-smU~omg~bbB7RLMg>R$k$-11_h+VX1v=qyXJ zx$f<9&=qQTtu9#_-l81PSPmTkMNS}x@=06}Ep;PE44~5Nq9&{XmEP^fp(Ot4pI1`l zEp=jmlV>L}zch04$G4Te%|?7QDAb!e?lPgyOZe-#A*k!5e?HF_b?6Tk23}m-*it`M zMrOtWJYRgExXK;$QV#9zCpcwgiJvE3h8)KK3l!>VmUm+D3&j+820ci!^UR@fel!#T z;8j~;oxz&Z+5_s^=pFWg_|(LYGNl2v`oh>!!Z|f^nCCip@c0mQ@F>8_rjcID0;h<+ zUPm7ZL0q+{Hg&=dpE&ag#ZVa^Q6Zuy}tEepNMQ$Sgkrje~31$U2tej*%<-q)xf9k9n)CdL=oT?XAX5$<^hnW#nXPS2yia;&o`3M zhXB~uzMwD>@<;T0k_IHfZX_G?MF7j7`dnn2;#L6CM#oPI)*2DoLd(wdEFD!N8=FIl z^VQ|Z3~>y=k*eJfszcVD>zSDpA>j7B&n~h}vlg=Q2OHJ^qAk{Vm-(neJ|tiTR;NU^ zMMGd0PY9U0WMEKepMSNV7YFkaY8Y>{Egm7XzG zB-tV}7G4U0j?v485JN~n(N2y+1L|=M3^oo#Ij;k5#?4j<=H>`+if%42Cuz+zF=pl! z2)(r>41kg~FQn3hfg7Gx5d$Z4oXi#mc@IONB_0A0;Zgul32JO)n+DvOgEN%2R}`Y5 z9?Zh865y2Ke>^D#trde7!X~_suLYMt^nbYj+x=gv|8xsNP(Z~#$1;Y=7uCa9Y5Srx zobcIPL$W5oeO+6Jf20*!vAA{u8m^IGUj1Bq#2*E1rN}NV0Ge3z#|mie9;gK?l15q& zgQ0pd{_3aO0&{lirCaoxLEls!hSNy^>iB_Os0?pt)KcgLw7@&1V$6SXAT({zZSbpO zE3YwG2+*)D0(p<1c-m>x&|gb>1ixVa-=F=a6S_@TT{eLEZ$F^xg!)&z4`i&|S2eYj znAW#n1p~{2%R&^pKELW>C5YF{5N&}_mLIeO;_1WVk>XqqY+~qt$Ms7QxDE-`}$U8LJ_qYt?a9w?CxF3=v?GL`y%ZzD=+^clCRg zJeL2hQ~;oUaZ_d8=6F{QT%d-NB7(gXLidbD+6}=pbo3~GZ1daR=NYLYF3Q<4gSiy)=oYIVBZRSO$R6!gSBFU6%y&ocRVoE&b0vY>wAY zw-CU^E;^UacZ*$(ZBPCiIJsIA>6A#~X}U8Ij&-tI318b6CPrPr<1YpHnn1LvDD>geS@S9`8~D z%Mg04(Acy5a}VBzxI6sCJUqEVdWK`|k1GC-PydJjUc|>w{(G#!C9lYFtE3FkI7h66 z0J*nOYdee==H@lzI?KNM^Q|L^c2~p!3vcJX1A0`M_nYlMM}&x!hx9i3dnT;B{Q7$3 zVwU86)!f>Z%Nu~BPcGe{XK?jtcDo30TAe5<{R8>t(ER`u1n-#WcuwQ^y9@dZNT>{K@qmKfhI$JL_ zC&FczZv?chM&6GcP#N_bpaY4IGDI`BRTxcZ5z8!&HzA@=X^2Ul@G zX1Ta$Gou(U=YoU)rX)qQ$A%SD3sWyW%be>y8zAAZx&0-GV@u(_Q$~@DYX(Aqmrz~W z-WSPG>iWei76I6SAx6PY!(%L2vn(CJLWFo{R*O0qmW7P!iUQkj#4R>SO1pRx?a)!) zWec6%A*}aL5-oi{>;^20_#8?PhTK4JR|Ia^QTy8Pk;MHOf4Lk-fsz&%_lHCzS7n_X zpm}?f3Tc`me2NpmDIUOhU;|h*&4+;^pl5(~@>4WTHwWgp^BrR}O`Yd@YrnJioz#ya z7K!bFt#R`7nEkfMwtvwekNql_6f4GTaDF3bnQwbSiWSG6!2;UB*wi+dZ_C}4_KAlF z+H|U@jN2Gl&0 z#1=sbaxuwyd=m7?HVotb;=Go^D(cHb<#(cDXm zYD0(vCscU;nDU`HeEC@x`WOHl*3X5~vc0@_^>@k~5mfJ&PbZWQX+|;*ad-DA!=?Eo zP5)rYUfvzNSG5q}2kq3dDjko4PQI5IIvs`tozvMR(KJt72e*++26Y~rkDHyH$~(N} zUEP8-;5i$WsQuX+B7PEufX{UNM|33Px>bOpT>+?Tu`T}G^Nyw|T9XTKDYn@ZyenT8 z1mg3{Y~=+-6;Dl5I?OhfRpo2S0q*9)R;EGZ$0#C#ct9T~_fv-bggw-Nw zGK`k?aD3P6JW`T4D7lzlup`LAH8b08WTy;pqjz4kntAv*E}Y%vD;R!%2D=n^PCcq^ zmJC?OGlGeXS-j07;>Pw*2%O!@;}x%||FbYLD{qCvr>ZSX^vl1!4N&g#HN}9A@jaU# zOOrEmg{jXd^A(2pg|56x%bENnKz+8-Q@T8YVcnQ~m`?E_v0>sY#JM0I&r`3>kf>&czql_j1oUX%ND7iCFu|Y)~ zxTRgJ3=Jxz+3Aem^gSj7(q60Fk`KH&DGM+D3k2=wNT76Lv>*9hL5A5iH#DpXl-`*g z;Ar#qpCe{%z8wAxUIwyqRfT;brC|Mt8L|qKtdM|-lTwjHj+OqM!~#&LV^Jc(%s9;5 z-Rxs61pLSK)opEt{^cvcYkCZ!&kmNKn6N^5+39as;(F9ZQG=Dn^>82ixc7NmGJk2w zH$xnFX^p&Vx9)U0SbiNwNTTYHYLm4v=$!xe|3-ro<{q%TX`$bje2-#)mozDCk2(*H zp)5RtCBQp|0q@0`jfc3g5W%G0TZZ_ql03!6hI%keVBN+7DUuj7;|RAOT6%!* z<4jz(w|lXzPYnSgzGz7qIUg+F_I2Gd1e}^GLxwWnC`DRyAOwwD0$$jFGXC2M%Z+QD zXe$(OhULa_fpn~(0n3cz0M{yxEyGY&3#Gx?5g%v9-+yX}ZnvOO_=J8s63G6fzztQ) zOgELKcWm*-cj$Rss|v4Y1H}^7g>ME)lipu$Db0q^=_KAuP_mN*3b3-*P4@GF1=DCo z_B)-_@DppZGRGgoSCm&C;F|J!LNHXO=t4(WbLeTPhQXoMxt8{=3az?iSwmx^EownN zu%0U{FKY89nz8k(d?)l16|;P@^>afsdpR?Sd}5 ztTFD=QhNHUyuB&f928bGd_nE8(U4)jgZX{dWs|3sFBHJ@FWR%s4-=n9#)(FAcU#m6 z6)LD-uzQ{CY5woU`?a>>ppR#>r)#qsS!<{e2@06maSK{Fr0+5w+R9Q$w3 zT#^baV+Ax{281KyN*_<|optBl_zVng#kA)7WhR-iihSAJ#uBts|B0_sWH00K6MR@< zKa0jUwbf7Ve?kG3&O2jhEO4Hz<&-GH$WA_C7o34NMQN{B~I?~-7- zeQ;6>1*rpi9a0J_<3=Z(WMQ94_i0Evh&}`b;d-y%g0HGoT9ZrPTQS_})XS=a@O9K~ zi0Dguv?ce7drFM7FM21!<2iBn?(QLB;t?;QI zyZGlH9;ueU2C3>%rDx)3@DBp*g8u?ILNVHj_7`L`eaml^t1gtCg3{l|R~_!v3Ma81 z*=;^v#Z3uRydW(_#w~9xkWZ{CgKyw+K2Xr)k-n{y$!6{Q3Lb1uuGea2lYF4AeG0+V zIS~`l6GUSzXK#(ZXhld$Z*nwkCWu!xOv%{2^r6^`Ol#sS!=ziBp7>QvuPTOTp!hZ(b{aG10V#z(cQM-x#V%g{S&n?%> kelEbb4*4v#YdcoAP*-IP4!+)L22BHm!xo1a2c07SA6;5Yn*aa+ literal 0 HcmV?d00001 From e97a068bf0ae341b1d1a716f8aafb018815feec5 Mon Sep 17 00:00:00 2001 From: Fouad Date: Tue, 1 Aug 2023 16:21:12 +0100 Subject: [PATCH 16/46] Type documentation for NymSDK (#3701) * set up development process for docs * set up development process for docs * Add local installs for Typedoc on gitignore * Add Typedoc comments on types.ts file * add typedoc config file * update types and add annotations * Add updates on types file * add examples + manage sort order for doc items * update client methods with examples * add description of NymMixnetClientOptions * add description of NymMixnetClientOptions * fix linting --------- Co-authored-by: Lorexia --- sdk/typescript/packages/sdk/.gitignore | 3 +- .../packages/sdk/README-GenerateDocs.md | 17 + sdk/typescript/packages/sdk/package.json | 18 +- .../packages/sdk/src/coconut/index.ts | 5 + .../sdk/src/mixnet/node-tester/constants.ts | 5 - .../sdk/src/mixnet/node-tester/types.ts | 30 -- .../packages/sdk/src/mixnet/wasm/index.ts | 42 ++- .../packages/sdk/src/mixnet/wasm/types.ts | 309 +++++++++++++++--- sdk/typescript/packages/sdk/typedoc.json | 32 ++ yarn.lock | 215 +++++++++++- 10 files changed, 570 insertions(+), 106 deletions(-) create mode 100644 sdk/typescript/packages/sdk/README-GenerateDocs.md delete mode 100644 sdk/typescript/packages/sdk/src/mixnet/node-tester/constants.ts create mode 100644 sdk/typescript/packages/sdk/typedoc.json diff --git a/sdk/typescript/packages/sdk/.gitignore b/sdk/typescript/packages/sdk/.gitignore index 6166d37c02..ed481bbc45 100644 --- a/sdk/typescript/packages/sdk/.gitignore +++ b/sdk/typescript/packages/sdk/.gitignore @@ -1,2 +1,3 @@ src/mixnet/wasm/worker.js -src/mixnet/node-tester/worker.js \ No newline at end of file +src/mixnet/node-tester/worker.js +docs/ \ No newline at end of file diff --git a/sdk/typescript/packages/sdk/README-GenerateDocs.md b/sdk/typescript/packages/sdk/README-GenerateDocs.md new file mode 100644 index 0000000000..7458ba1069 --- /dev/null +++ b/sdk/typescript/packages/sdk/README-GenerateDocs.md @@ -0,0 +1,17 @@ +## Install dependencies + +run `yarn install` to install dependencies + +## Generate docs + +We use TypeDoc for document generation https://typedoc.org/ + +To generate docs run `yarn docs:generate`. Generated docs can be found the `./docs` directory. + +To view the generated docs in a webpage run `yarn docs:serve`. The docs will be available to view at `http://localhost:3000`. + +## Local document development + +To support the development process we have a local server that will watch for changes to the src files and update the docs in real time. + +Run `yarn docs:dev` to start a local server to view the docs. Again, The docs will be available to view at `http://localhost:3000`. diff --git a/sdk/typescript/packages/sdk/package.json b/sdk/typescript/packages/sdk/package.json index c156bd5876..17d2c9d116 100644 --- a/sdk/typescript/packages/sdk/package.json +++ b/sdk/typescript/packages/sdk/package.json @@ -28,11 +28,15 @@ "build:dev": "yarn build:dev:only-this", "build:dev:only-this": "scripts/build.sh", "build:local": "run-s build:dependencies:nym-client-wasm build:dev:only-this", + "docs:watch": "nodemon --ext ts --watch './src/**/*' --watch './typedoc.json' --exec \"yarn docs:generate\"", + "docs:generate": "typedoc", + "docs:serve": "reload -b -d ./docs -p 3000", + "docs:dev": "run-p docs:watch docs:serve ", "test": "node --experimental-vm-modules --no-warnings node_modules/jest/bin/jest.js -c=jest.config.mjs --no-cache" }, "dependencies": { "@npmcli/node-gyp": "^3.0.0", - "@nymproject/nym-client-wasm": "1.0.0", + "@nymproject/nym-client-wasm": "1", "comlink": "^4.3.1", "lerna": "^6.6.2", "node-gyp": "^9.3.1" @@ -52,10 +56,10 @@ "@rollup/plugin-terser": "^0.2.1", "@rollup/plugin-typescript": "^10.0.1", "@rollup/plugin-wasm": "^6.1.1", - "@typescript-eslint/eslint-plugin": "^5.13.0", - "@typescript-eslint/parser": "^5.13.0", "@types/jest": "^27.0.1", "@types/node": "^16.7.13", + "@typescript-eslint/eslint-plugin": "^5.13.0", + "@typescript-eslint/parser": "^5.13.0", "eslint": "^8.10.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-typescript": "^16.1.0", @@ -67,13 +71,15 @@ "eslint-plugin-prettier": "^4.0.0", "eslint-plugin-react": "^7.29.2", "eslint-plugin-react-hooks": "^4.3.0", + "jest": "^29.5.0", + "nodemon": "3.0.1", + "reload": "^3.2.1", "rimraf": "^3.0.2", "rollup": "^3.9.1", "rollup-plugin-base64": "^1.0.1", "rollup-plugin-web-worker-loader": "^1.6.1", - "typescript": "^4.8.4", - "jest": "^29.5.0", "ts-jest": "^29.1.0", - "ts-loader": "^9.4.2" + "typedoc": "^0.24.8", + "typescript": "^4.8.4" } } diff --git a/sdk/typescript/packages/sdk/src/coconut/index.ts b/sdk/typescript/packages/sdk/src/coconut/index.ts index 02138c9bab..3011daa2e0 100644 --- a/sdk/typescript/packages/sdk/src/coconut/index.ts +++ b/sdk/typescript/packages/sdk/src/coconut/index.ts @@ -1,2 +1,7 @@ // eslint-disable-next-line no-console + +/** + * @ignore + * @internal + */ export const notImplementedYet = () => console.log('Not implement, coming soon...'); diff --git a/sdk/typescript/packages/sdk/src/mixnet/node-tester/constants.ts b/sdk/typescript/packages/sdk/src/mixnet/node-tester/constants.ts deleted file mode 100644 index 55770cd39b..0000000000 --- a/sdk/typescript/packages/sdk/src/mixnet/node-tester/constants.ts +++ /dev/null @@ -1,5 +0,0 @@ -const QA_VALIDATOR_URL = 'https://qa-nym-api.qa.nymte.ch/api'; -const QWERTY_VALIDATOR_URL = 'https://qwerty-validator-api.qa.nymte.ch/api'; -const MAINNET_VALIDATOR_URL = 'https://validator.nymtech.net/api/'; - -export { QA_VALIDATOR_URL, QWERTY_VALIDATOR_URL, MAINNET_VALIDATOR_URL }; diff --git a/sdk/typescript/packages/sdk/src/mixnet/node-tester/types.ts b/sdk/typescript/packages/sdk/src/mixnet/node-tester/types.ts index a556fec243..5bf1afb4d1 100644 --- a/sdk/typescript/packages/sdk/src/mixnet/node-tester/types.ts +++ b/sdk/typescript/packages/sdk/src/mixnet/node-tester/types.ts @@ -25,8 +25,6 @@ export interface NodeTesterLoadedEvent { }; } -export type Network = 'QA' | 'SANDBOX' | 'MAINNET'; - export type NodeTestResultResponse = { score: number; sentPackets: number; @@ -35,31 +33,3 @@ export type NodeTestResultResponse = { duplicatePackets: number; duplicateAcks: number; }; - -export type Error = { - kind: 'Error'; - args: { message: string }; -}; - -export type WorkerLoaded = { - kind: 'WorkerLoaded'; -}; - -export type DisplayTesterResults = { - kind: 'DisplayTesterResults'; - args: { - result: NodeTestResultResponse; - }; -}; - -export type TestPacket = { - kind: 'TestPacket'; - args: { - mixnodeIdentity: string; - network: Network; - }; -}; - -export type TestStatus = 'Stopped' | 'Running' | 'Complete'; - -export type NodeTestEvent = Error | DisplayTesterResults | TestPacket | WorkerLoaded; diff --git a/sdk/typescript/packages/sdk/src/mixnet/wasm/index.ts b/sdk/typescript/packages/sdk/src/mixnet/wasm/index.ts index 1b80d844e8..e124b7136c 100644 --- a/sdk/typescript/packages/sdk/src/mixnet/wasm/index.ts +++ b/sdk/typescript/packages/sdk/src/mixnet/wasm/index.ts @@ -5,8 +5,8 @@ import { ConnectedEvent, EventKinds, IWebWorker, - IWebWorkerAsync, - IWebWorkerEvents, + Client, + Events, LoadedEvent, MimeTypes, RawMessageReceivedEvent, @@ -15,20 +15,40 @@ import { import { createSubscriptions } from './subscriptions'; /** - * Client for the Nym mixnet. + * Options for the Nym mixnet client. + * @property autoConvertStringMimeTypes - An array of mime types. + * @example + * ```typescript + * const client = await createNymMixnetClient({ + * autoConvertStringMimeTypes: [MimeTypes.ApplicationJson, MimeTypes.TextPlain], + * }); + * ``` + */ + +export interface NymMixnetClientOptions { + autoConvertStringMimeTypes?: string[] | MimeTypes[]; +} + +/** + * The client for the Nym mixnet which gives access to client methods and event subscriptions. + * Returned by the {@link createNymMixnetClient} function. + * */ export interface NymMixnetClient { - client: IWebWorkerAsync; - events: IWebWorkerEvents; + client: Client; + events: Events; } /** * Create a client to send and receive traffic from the Nym mixnet. - * + * @required + * @returns + * @example + * ```typescript + * const client = await createNymMixnetClient(); + * ``` */ -export const createNymMixnetClient = async (options?: { - autoConvertStringMimeTypes?: string[] | MimeTypes[]; -}): Promise => { +export const createNymMixnetClient = async (options?: NymMixnetClientOptions): Promise => { // create a web worker that runs the WASM client on another thread and wait until it signals that it is ready // eslint-disable-next-line @typescript-eslint/no-use-before-define const worker = await createWorker(); @@ -53,7 +73,7 @@ export const createNymMixnetClient = async (options?: { }); // manage the subscribers, returning self-unsubscribe methods - const events: IWebWorkerEvents = { + const events: Events = { subscribeToConnected: (handler) => addSubscription(EventKinds.Connected, handler), subscribeToLoaded: (handler) => addSubscription(EventKinds.Loaded, handler), subscribeToTextMessageReceivedEvent: (handler) => @@ -65,7 +85,7 @@ export const createNymMixnetClient = async (options?: { }; // let comlink handle interop with the web worker - const client: IWebWorkerAsync = Comlink.wrap(worker); + const client: Client = Comlink.wrap(worker); // set any options if (options?.autoConvertStringMimeTypes) { diff --git a/sdk/typescript/packages/sdk/src/mixnet/wasm/types.ts b/sdk/typescript/packages/sdk/src/mixnet/wasm/types.ts index 1f11384b1a..7df48ba73b 100644 --- a/sdk/typescript/packages/sdk/src/mixnet/wasm/types.ts +++ b/sdk/typescript/packages/sdk/src/mixnet/wasm/types.ts @@ -3,32 +3,138 @@ import type { DebugWasm } from './types-from-wasm-pack'; export * from './types-from-wasm-pack'; /** - * Some common mime types, however, you can always just specify the mime-type as a string + * + * @ignore + * @hidden + * @internal */ -export enum MimeTypes { - ApplicationOctetStream = 'application/octet-stream', - TextPlain = 'text/plain', - ApplicationJson = 'application/json', +export interface IWebWorker { + start: (config: NymClientConfig) => void; + stop: () => void; + selfAddress: () => string | undefined; + setTextMimeTypes: (mimeTypes: string[]) => void; + getTextMimeTypes: () => string[]; + send: (args: { payload: Payload; recipient: string; replySurbs?: number }) => void; + rawSend: (args: { payload: Uint8Array; recipient: string; replySurbs?: number }) => void; } -export interface Payload { - message: string | Uint8Array; - - mimeType?: MimeTypes | string; - - headers?: string; +export interface Client { + /** + * Start the client. + * + * @example + * + * ```typescript + * const client = await createNymMixnetClient(); + * await client.start({ + * clientId: 'my-client', + * nymApiUrl: 'https://validator.nymtech.net/api', + * }); + * + */ + start: (config: NymClientConfig) => Promise; + /** + * Stop the client. + * @example + * ```typescript + * const client = await createNymMixnetClient(); + * await client.start({ + * clientId: 'my-client', + * nymApiUrl: 'https://validator.nymtech.net/api', + * }); + * await client.stop(); + * ``` + */ + stop: () => Promise; + /** + * Get the client address + * @example + * ```typescript + * const client = await createNymMixnetClient(); + * await client.start({ + * clientId: 'my-client', + * nymApiUrl: 'https://validator.nymtech.net/api', + * }); + * const address = await client.selfAddress(); + * ``` + */ + selfAddress: () => Promise; + /** + * Set the mime-types that should be used when using the {@link Client.send} method. + * @example + * ```typescript + * const client = await createNymMixnetClient(); + * await client.start({ + * clientId: 'my-client', + * nymApiUrl: 'https://validator.nymtech.net/api', + * }); + * await client.setTextMimeTypes(['text/plain', 'application/json']); + * ``` + * @param mimeTypes + * @see {@link MimeTypes} + * @see {@link Client.send} + * @see {@link Client.getTextMimeTypes} + */ + setTextMimeTypes: (mimeTypes: string[]) => void; + /** + * Get the mime-types that are automatically converted to strings. + * @example + * ```typescript + * const client = await createNymMixnetClient(); + * await client.start({ + * clientId: 'my-client', + * nymApiUrl: 'https://validator.nymtech.net/api', + * }); + * const mimeTypes = await client.getTextMimeTypes(); + * ``` + * @see {@link MimeTypes} + * @see {@link Payload} + * @see {@link Client.send} + * @see {@link Client.setTextMimeTypes} + */ + getTextMimeTypes: () => Promise; + /** + * Send some data through the mixnet message. + * @example + * ```typescript + * const client = await createNymMixnetClient(); + * await client.start({ + * clientId: 'my-client', + * nymApiUrl: 'https://validator.nymtech.net/api', + * }); + * await client.send({ + * payload: 'Hello world', + * recipient: // recipient address, + * }); + * ``` + * @see {@link MimeTypes} + * @see {@link Payload} + */ + send: (args: { payload: Payload; recipient: string; replySurbs?: number }) => Promise; + /** + * Send a raw payload, without any mime-type conversion. + * @example + * ```typescript + * const client = await createNymMixnetClient(); + * await client.start({ + * clientId: 'my-client', + * nymApiUrl: 'https://validator.nymtech.net/api', + * }); + * const payload = new Uint8Array([1, 2, 3]); + * await client.rawSend({ + * payload, + * recipient: // recipient address, + * }); + * ``` + * @see {@link MimeTypes} + * @see {@link Payload} + */ + rawSend: (args: { payload: Uint8Array; recipient: string; replySurbs?: number }) => Promise; } -export type OnPayloadFn = (payload: Payload) => void; - -export type OnRawPayloadFn = (payload: Uint8Array) => void; - -export type EventHandlerFn = (e: E) => void | Promise; - -export type EventHandlerSubscribeFn = (fn: EventHandlerFn) => EventHandlerUnsubscribeFn; - -export type EventHandlerUnsubscribeFn = () => void; - +/** + * The configuration passed to the {@link Client.start} method of the {@link Client} + */ export interface NymClientConfig { /** * A human-readable id for the client. @@ -56,31 +162,99 @@ export interface NymClientConfig { debug?: DebugWasm; } -export interface IWebWorker { - start: (config: NymClientConfig) => void; - stop: () => void; - selfAddress: () => string | undefined; - setTextMimeTypes: (mimeTypes: string[]) => void; - getTextMimeTypes: () => string[]; - send: (args: { payload: Payload; recipient: string; replySurbs?: number }) => void; - rawSend: (args: { payload: Uint8Array; recipient: string; replySurbs?: number }) => void; -} - -export interface IWebWorkerAsync { - start: (config: NymClientConfig) => Promise; - stop: () => Promise; - selfAddress: () => Promise; - setTextMimeTypes: (mimeTypes: string[]) => void; - getTextMimeTypes: () => Promise; - send: (args: { payload: Payload; recipient: string; replySurbs?: number }) => Promise; - rawSend: (args: { payload: Uint8Array; recipient: string; replySurbs?: number }) => Promise; +export interface Events { + /** + * @see {@link LoadedEvent} + * @example + * ```typescript + * events.subscribeToLoaded((e) => { + * console.log(e.args); // { loaded: true } + * }); + * ``` + */ + subscribeToLoaded: EventHandlerSubscribeFn; + /** + * @see {@link ConnectedEvent} + * @example + * ```typescript + * events.subscribeConnected((e) => { + * console.log(e.args.address); // Client address + * }); + * + */ + subscribeToConnected: EventHandlerSubscribeFn; + /** + * @returns {@link EventHandlerUnsubscribeFn} + * @see {@link StringMessageReceivedEvent} + * @example + * ```typescript + * const unsubscribe = events.subscribeToTextMessageReceivedEvent((e) => { + * console.log(e.args.payload); // string + * }); + * + * // Stop listening to the event + * unsubscribe(); + * ``` + */ + subscribeToTextMessageReceivedEvent: EventHandlerSubscribeFn; + /** + * @returns {@link EventHandlerUnsubscribeFn} + * @see {@link BinaryMessageReceivedEvent} + * @example + * ```typescript + * const unsubscribe = events.subscribeToBinaryMessageReceivedEvent((e) => { + * console.log(e.args.payload); // Uint8Array + * }); + * + * // Stop listening to the event + * unsubscribe(); + * ``` + */ + subscribeToBinaryMessageReceivedEvent: EventHandlerSubscribeFn; + /** + * @returns {@link EventHandlerUnsubscribeFn} + * @see {@link RawMessageReceivedEvent} + * @example + * ```typescript + * const unsubscribe = events.subscribeToRawMessageReceivedEvent((e) => { + * console.log(e.args.payload); // Uint8Array + * }); + * + * // Stop listening to the event + * unsubscribe(); + * ``` + */ + subscribeToRawMessageReceivedEvent: EventHandlerSubscribeFn; } +/** + * Enum representing various event kinds. + * @enum + */ export enum EventKinds { + /** + * The event emitted when the nodetester is ready to be used. + */ Loaded = 'Loaded', + + /** + * The event emitted when connection to the gateway is established. + */ Connected = 'Connected', + + /** + * The event for when a message is received and interpreted as a string. + */ StringMessageReceived = 'StringMessageReceived', + + /** + * The event for when a binary message is received. BinaryMessage is a type of message that contains additional metadata, such as MIME type and some headers, along with the actual payload data. + */ BinaryMessageReceived = 'BinaryMessageReceived', + + /** + * The event for when a raw message is received. RawMessage represents the bytes that are received directly from the mixnet with no further parsing or interpretation done on them. + */ RawMessageReceived = 'RawMessageReceived', } @@ -107,7 +281,6 @@ export interface StringMessageReceivedEvent { headers?: string; }; } - export interface BinaryMessageReceivedEvent { kind: EventKinds.BinaryMessageReceived; args: { @@ -124,10 +297,54 @@ export interface RawMessageReceivedEvent { }; } -export interface IWebWorkerEvents { - subscribeToLoaded: EventHandlerSubscribeFn; - subscribeToConnected: EventHandlerSubscribeFn; - subscribeToTextMessageReceivedEvent: EventHandlerSubscribeFn; - subscribeToBinaryMessageReceivedEvent: EventHandlerSubscribeFn; - subscribeToRawMessageReceivedEvent: EventHandlerSubscribeFn; +/** + * Some common mime types, however, you can always just specify the mime-type as a string + */ +export enum MimeTypes { + ApplicationOctetStream = 'application/octet-stream', + TextPlain = 'text/plain', + ApplicationJson = 'application/json', } + +export interface Payload { + message: string | Uint8Array; + mimeType?: MimeTypes | string; + headers?: string; +} + +/** + * @ignore + * @internal + */ +export type OnPayloadFn = (payload: Payload) => void; +/** + * @ignore + * @internal + */ +export type OnRawPayloadFn = (payload: Uint8Array) => void; + +/** + * The **EventHandlerSubscribeFn** is a function that takes a callback of type {@link EventHandlerFn} + * + * @see {@link Events} + * @see {@link EventHandlerFn} + * @see {@link EventHandlerUnsubscribeFn} + */ +export type EventHandlerSubscribeFn = (fn: EventHandlerFn) => EventHandlerUnsubscribeFn; + +/** + * The **EventHandlerFn** is a callback function that is passed to the {@link EventHandlerSubscribeFn} + * @see {@link Events} + * @see {@link EventHandlerFn} + * @see {@link EventHandlerSubscribeFn} + */ +export type EventHandlerFn = (e: E) => void | Promise; + +/** + * The **EventHandlerUnsubscribeFn** function is returned by the {@link EventHandlerSubscribeFn} + * and can be used to stop listening for particular events + * @see {@link Events} + * @see {@link EventHandlerFn} + * @see {@link EventHandlerSubscribeFn} + */ +export type EventHandlerUnsubscribeFn = () => void; diff --git a/sdk/typescript/packages/sdk/typedoc.json b/sdk/typescript/packages/sdk/typedoc.json new file mode 100644 index 0000000000..507b6156cc --- /dev/null +++ b/sdk/typescript/packages/sdk/typedoc.json @@ -0,0 +1,32 @@ +{ + "sort": ["kind"], + "entryPoints": ["./src/index.ts"], + "out": "./docs", + "exclude": ["./src/**/node-tester/*", "./src/**/wasm/types-from-wasm-pack.ts"], + "kindSortOrder": [ + "Function", + "Interface", + "TypeAlias", + "Reference", + "Project", + "Module", + "Namespace", + "Enum", + "EnumMember", + "Class", + "Constructor", + "Property", + "Variable", + "Accessor", + "Method", + "ObjectLiteral", + "Parameter", + "TypeParameter", + "TypeLiteral", + "CallSignature", + "ConstructorSignature", + "IndexSignature", + "GetSignature", + "SetSignature" + ] +} diff --git a/yarn.lock b/yarn.lock index 8c6092b23f..178152e2f1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6421,6 +6421,11 @@ ansi-regex@^6.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== +ansi-sequence-parser@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ansi-sequence-parser/-/ansi-sequence-parser-1.1.0.tgz#4d790f31236ac20366b23b3916b789e1bde39aed" + integrity sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ== + ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -7821,6 +7826,17 @@ cli-boxes@^2.2.1: resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== +cli-color@~2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/cli-color/-/cli-color-2.0.3.tgz#73769ba969080629670f3f2ef69a4bf4e7cc1879" + integrity sha512-OkoZnxyC4ERN3zLzZaY9Emb7f/MhBOIpePv0Ycok0fJYT+Ouo00UBEIwsVsr0yoow++n5YWlSUgST9GKhNHiRQ== + dependencies: + d "^1.0.1" + es5-ext "^0.10.61" + es6-iterator "^2.0.3" + memoizee "^0.4.15" + timers-ext "^0.1.7" + cli-cursor@3.1.0, cli-cursor@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" @@ -8093,6 +8109,11 @@ commander@^9.4.1: resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30" integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ== +commander@~9.4.0: + version "9.4.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.1.tgz#d1dd8f2ce6faf93147295c0df13c7c21141cfbdd" + integrity sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw== + common-ancestor-path@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz#4f7d2d1394d91b7abdf51871c62f71eadb0182a7" @@ -8871,6 +8892,14 @@ d3-zoom@^2.0.0: d3-selection "2" d3-transition "2" +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + damerau-levenshtein@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" @@ -9678,16 +9707,52 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: + version "0.10.62" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5" + integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA== + dependencies: + es6-iterator "^2.0.3" + es6-symbol "^3.1.3" + next-tick "^1.1.0" + es5-shim@^4.5.13: version "4.6.7" resolved "https://registry.yarnpkg.com/es5-shim/-/es5-shim-4.6.7.tgz#bc67ae0fc3dd520636e0a1601cc73b450ad3e955" integrity sha512-jg21/dmlrNQI7JyyA2w7n+yifSxBng0ZralnSfVZjoCawgNTCnS+yBCyVM9DL5itm7SUnDGgv7hcq2XCZX4iRQ== +es6-iterator@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g== + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + es6-shim@^0.35.5: version "0.35.8" resolved "https://registry.yarnpkg.com/es6-shim/-/es6-shim-0.35.8.tgz#89216f6fbf8bacba3f897c8c0e814d2a41c05fb7" integrity sha512-Twf7I2v4/1tLoIXMT8HlqaBSS5H2wQTs2wx3MNYCI8K1R1/clXyCazrcVCPm/FuO9cyV8+leEaZOWD5C253NDg== +es6-symbol@^3.1.1, es6-symbol@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + +es6-weak-map@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53" + integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA== + dependencies: + d "1" + es5-ext "^0.10.46" + es6-iterator "^2.0.3" + es6-symbol "^3.1.1" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -10150,6 +10215,14 @@ etag@~1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== +event-emitter@^0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + integrity sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA== + dependencies: + d "1" + es5-ext "~0.10.14" + event-target-shim@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" @@ -10330,6 +10403,13 @@ express@^4.17.1, express@^4.17.3, express@^4.18.2: utils-merge "1.0.1" vary "~1.1.2" +ext@^1.1.2: + version "1.7.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f" + integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw== + dependencies: + type "^2.7.2" + extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" @@ -10590,7 +10670,7 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -finalhandler@1.2.0: +finalhandler@1.2.0, finalhandler@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== @@ -12432,6 +12512,11 @@ is-potential-custom-element-name@^1.0.1: resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== +is-promise@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" + integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== + is-reference@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7" @@ -13749,7 +13834,7 @@ json5@^1.0.1, json5@^1.0.2: dependencies: minimist "^1.2.0" -jsonc-parser@3.2.0, jsonc-parser@^3.0.0: +jsonc-parser@3.2.0, jsonc-parser@^3.0.0, jsonc-parser@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== @@ -14314,6 +14399,13 @@ lru-cache@^7.4.4, lru-cache@^7.5.1, lru-cache@^7.7.1: resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.0.tgz#b9e2a6a72a129d81ab317202d93c7691df727e61" integrity sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw== +lru-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3" + integrity sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ== + dependencies: + es5-ext "~0.10.2" + lunr@^2.3.9: version "2.3.9" resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" @@ -14464,7 +14556,7 @@ markdown-extensions@^1.0.0: resolved "https://registry.yarnpkg.com/markdown-extensions/-/markdown-extensions-1.1.1.tgz#fea03b539faeaee9b4ef02a3769b455b189f7fc3" integrity sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q== -marked@^4.0.16: +marked@^4.0.16, marked@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/marked/-/marked-4.3.0.tgz#796362821b019f734054582038b116481b456cf3" integrity sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A== @@ -14662,6 +14754,20 @@ memfs@^3.1.2, memfs@^3.2.2, memfs@^3.4.1, memfs@^3.4.3: dependencies: fs-monkey "^1.0.4" +memoizee@^0.4.15: + version "0.4.15" + resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.15.tgz#e6f3d2da863f318d02225391829a6c5956555b72" + integrity sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ== + dependencies: + d "^1.0.1" + es5-ext "^0.10.53" + es6-weak-map "^2.0.3" + event-emitter "^0.3.5" + is-promise "^2.2.2" + lru-queue "^0.1.0" + next-tick "^1.1.0" + timers-ext "^0.1.7" + memoizerific@^1.11.3: version "1.11.3" resolved "https://registry.yarnpkg.com/memoizerific/-/memoizerific-1.11.3.tgz#7c87a4646444c32d75438570905f2dbd1b1a805a" @@ -15195,7 +15301,7 @@ minimist-options@4.1.0: is-plain-obj "^1.1.0" kind-of "^6.0.3" -minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6: +minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6, minimist@~1.2.0: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== @@ -15505,6 +15611,11 @@ nested-error-stacks@^2.0.0, nested-error-stacks@^2.1.0: resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.1.1.tgz#26c8a3cee6cc05fbcf1e333cd2fc3e003326c0b5" integrity sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw== +next-tick@1, next-tick@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" + integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== + nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" @@ -15632,6 +15743,22 @@ node-releases@^2.0.12: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.12.tgz#35627cc224a23bfb06fb3380f2b3afaaa7eb1039" integrity sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ== +nodemon@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-3.0.1.tgz#affe822a2c5f21354466b2fc8ae83277d27dadc7" + integrity sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw== + dependencies: + chokidar "^3.5.2" + debug "^3.2.7" + ignore-by-default "^1.0.1" + minimatch "^3.1.2" + pstree.remy "^1.1.8" + semver "^7.5.3" + simple-update-notifier "^2.0.0" + supports-color "^5.5.0" + touch "^3.1.0" + undefsafe "^2.0.5" + nodemon@^2.0.21: version "2.0.22" resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.22.tgz#182c45c3a78da486f673d6c1702e00728daf5258" @@ -16143,7 +16270,7 @@ open@^7.0.3: is-docker "^2.0.0" is-wsl "^2.1.1" -open@^8.0.9, open@^8.4.0: +open@^8.0.0, open@^8.0.9, open@^8.4.0: version "8.4.2" resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== @@ -18108,6 +18235,20 @@ relateurl@^0.2.7: resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" integrity sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog== +reload@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/reload/-/reload-3.2.1.tgz#42d43e33e327efe1348c723272c6835fe333349a" + integrity sha512-ZdM8ZSEeI72zkhh6heMEvJ0vHZoovZXcJI6Zae8CzS7o5vO/WjZsAMMr0y1+3I/fCN7y7ZxABoUwwCswcLHkjQ== + dependencies: + cli-color "~2.0.0" + commander "~9.4.0" + finalhandler "~1.2.0" + minimist "~1.2.0" + open "^8.0.0" + serve-static "~1.15.0" + supervisor "~0.12.0" + ws "~8.11.0" + remark-external-links@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/remark-external-links/-/remark-external-links-8.0.0.tgz#308de69482958b5d1cd3692bc9b725ce0240f345" @@ -18730,7 +18871,7 @@ serve-index@^1.9.1: mime-types "~2.1.17" parseurl "~1.3.2" -serve-static@1.15.0: +serve-static@1.15.0, serve-static@~1.15.0: version "1.15.0" resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== @@ -18851,6 +18992,16 @@ shiki@^0.10.1: vscode-oniguruma "^1.6.1" vscode-textmate "5.2.0" +shiki@^0.14.1: + version "0.14.3" + resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.14.3.tgz#d1a93c463942bdafb9866d74d619a4347d0bbf64" + integrity sha512-U3S/a+b0KS+UkTyMjoNojvTgrBHjgp7L6ovhFVZsXmBGnVdQ4K4U9oK0z63w538S91ATngv1vXigHCSWOwnr+g== + dependencies: + ansi-sequence-parser "^1.1.0" + jsonc-parser "^3.2.0" + vscode-oniguruma "^1.7.0" + vscode-textmate "^8.0.0" + side-channel@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" @@ -18908,6 +19059,13 @@ simple-update-notifier@^1.0.7: dependencies: semver "~7.0.0" +simple-update-notifier@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz#d70b92bdab7d6d90dfd73931195a30b6e3d7cebb" + integrity sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w== + dependencies: + semver "^7.5.3" + sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" @@ -19527,6 +19685,11 @@ stylis@4.2.0: resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51" integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== +supervisor@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/supervisor/-/supervisor-0.12.0.tgz#de7e6337015b291851c10f3538c4a7f04917ecc1" + integrity sha512-iBYeU5Or4WiiIa3+ns1DpHIiHjNNXSuYUiixKcznewwo4ImBJ8EobktaAo2csOcauhrz4SvKRTou8Z2C3W28+A== + supports-color@8.1.1, supports-color@^8.0.0: version "8.1.1" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" @@ -19847,6 +20010,14 @@ timers-browserify@^2.0.4: dependencies: setimmediate "^1.0.4" +timers-ext@^0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.7.tgz#6f57ad8578e07a3fb9f91d9387d65647555e25c6" + integrity sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ== + dependencies: + es5-ext "~0.10.46" + next-tick "1" + tiny-warning@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" @@ -20237,6 +20408,16 @@ type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.7.2: + version "2.7.2" + resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0" + integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw== + typed-array-length@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" @@ -20269,6 +20450,16 @@ typedoc@^0.22.13: minimatch "^5.1.0" shiki "^0.10.1" +typedoc@^0.24.8: + version "0.24.8" + resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.24.8.tgz#cce9f47ba6a8d52389f5e583716a2b3b4335b63e" + integrity sha512-ahJ6Cpcvxwaxfu4KtjA8qZNqS43wYt6JL27wYiIgl1vd38WW/KWX11YuAeZhuz9v+ttrutSsgK+XO1CjL1kA3w== + dependencies: + lunr "^2.3.9" + marked "^4.3.0" + minimatch "^9.0.0" + shiki "^0.14.1" + "typescript@^3 || ^4", typescript@^4.6.2, typescript@^4.8.4: version "4.9.5" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" @@ -20850,7 +21041,7 @@ vm-browserify@^1.0.1: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== -vscode-oniguruma@^1.6.1: +vscode-oniguruma@^1.6.1, vscode-oniguruma@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz#439bfad8fe71abd7798338d1cd3dc53a8beea94b" integrity sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA== @@ -20860,6 +21051,11 @@ vscode-textmate@5.2.0: resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-5.2.0.tgz#01f01760a391e8222fe4f33fbccbd1ad71aed74e" integrity sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ== +vscode-textmate@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-8.0.0.tgz#2c7a3b1163ef0441097e0b5d6389cd5504b59e5d" + integrity sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg== + w3c-hr-time@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" @@ -21416,6 +21612,11 @@ ws@^8.13.0, ws@^8.2.3: resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== +ws@~8.11.0: + version "8.11.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.11.0.tgz#6a0d36b8edfd9f96d8b25683db2f8d7de6e8e143" + integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg== + x-default-browser@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/x-default-browser/-/x-default-browser-0.4.0.tgz#70cf0da85da7c0ab5cb0f15a897f2322a6bdd481" From 00b5a46cbc15c13e6e2fcb34247e42eeca8873c2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Aug 2023 15:22:00 +0000 Subject: [PATCH 17/46] Bump semver from 5.7.1 to 5.7.2 in /nym-wallet/webdriver Bumps [semver](https://github.com/npm/node-semver) from 5.7.1 to 5.7.2. - [Release notes](https://github.com/npm/node-semver/releases) - [Changelog](https://github.com/npm/node-semver/blob/v5.7.2/CHANGELOG.md) - [Commits](https://github.com/npm/node-semver/compare/v5.7.1...v5.7.2) --- updated-dependencies: - dependency-name: semver dependency-type: indirect ... Signed-off-by: dependabot[bot] --- nym-wallet/webdriver/yarn.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/nym-wallet/webdriver/yarn.lock b/nym-wallet/webdriver/yarn.lock index 0c01bfb5cc..3e139e91a3 100644 --- a/nym-wallet/webdriver/yarn.lock +++ b/nym-wallet/webdriver/yarn.lock @@ -2024,10 +2024,10 @@ pkg-dir@4.2.0: dependencies: find-up "^4.0.0" -prettier@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.1.tgz#671e11c89c14a4cfc876ce564106c4a6726c9f5c" - integrity sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA== +prettier@^2.8.7: + version "2.8.8" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" + integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== pretty-format@^27.3.1: version "27.3.1" @@ -2259,9 +2259,9 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== "semver@2 || 3 || 4 || 5": - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== serialize-error@^8.0.0: version "8.1.0" From cd70b0de75870a51969d84dbaabffc10fa0d1a9d Mon Sep 17 00:00:00 2001 From: pierre Date: Wed, 2 Aug 2023 11:18:23 +0200 Subject: [PATCH 18/46] build(nc-android): disable sentry upload proguard mapping files --- nym-connect/native/android/app/build.gradle.kts | 6 ++++++ .../android/app/src/main/java/net/nymtech/nyms5/App.kt | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/nym-connect/native/android/app/build.gradle.kts b/nym-connect/native/android/app/build.gradle.kts index b33dd6d715..decadfc6dc 100644 --- a/nym-connect/native/android/app/build.gradle.kts +++ b/nym-connect/native/android/app/build.gradle.kts @@ -101,6 +101,12 @@ android { } } +sentry { + // TODO disable auto upload of mapping files for now to ease FDroid submission + // (avoiding to have to provide a sentry auth token during compile time) + autoUploadProguardMapping.set(false) +} + dependencies { implementation("androidx.core:core-ktx:1.10.1") diff --git a/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/App.kt b/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/App.kt index 105270644c..6da2011ffc 100644 --- a/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/App.kt +++ b/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/App.kt @@ -19,7 +19,6 @@ import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.map import kotlinx.coroutines.runBlocking - val Context.dataStore: DataStore by preferencesDataStore(name = "settings") val monitoringKey = booleanPreferencesKey("monitoring") From 5ab2c738dfaafcf090c9ffa282c0a271c48544ee Mon Sep 17 00:00:00 2001 From: Tommy Verrall Date: Wed, 2 Aug 2023 12:54:09 +0200 Subject: [PATCH 19/46] fix api tests for no blacklisted nodes --- .../gateway/contract-cache-gateway.test.ts | 11 +- .../mixnode/contract-cache-mixnode.test.ts | 167 +++++++++++++----- 2 files changed, 134 insertions(+), 44 deletions(-) diff --git a/nym-api/tests/functional_test/contract_cache/gateway/contract-cache-gateway.test.ts b/nym-api/tests/functional_test/contract_cache/gateway/contract-cache-gateway.test.ts index 465b6a9a12..992e35c89a 100644 --- a/nym-api/tests/functional_test/contract_cache/gateway/contract-cache-gateway.test.ts +++ b/nym-api/tests/functional_test/contract_cache/gateway/contract-cache-gateway.test.ts @@ -40,8 +40,13 @@ describe("Get gateway data", (): void => { it("Get blacklisted gateways", async (): Promise => { const response = await contract.getBlacklistedGateways(); - response.forEach(function (value) { - expect(typeof value).toBe("string"); - }); + if (response === null) { + console.log("No blacklisted gateways"); + expect(response).toBeNull(); + } else { + response.forEach(function (value) { + expect(typeof value).toBe("string"); + }); + } }); }); diff --git a/nym-api/tests/functional_test/contract_cache/mixnode/contract-cache-mixnode.test.ts b/nym-api/tests/functional_test/contract_cache/mixnode/contract-cache-mixnode.test.ts index 31fb8d959d..9cb66539a9 100644 --- a/nym-api/tests/functional_test/contract_cache/mixnode/contract-cache-mixnode.test.ts +++ b/nym-api/tests/functional_test/contract_cache/mixnode/contract-cache-mixnode.test.ts @@ -16,8 +16,12 @@ describe("Get mixnode data", (): void => { //bond information overview expect(typeof mixnode.bond_information.mix_id).toBe("number"); expect(typeof mixnode.bond_information.owner).toBe("string"); - expect(typeof mixnode.bond_information.original_pledge.amount).toBe("string"); - expect(typeof mixnode.bond_information.original_pledge.denom).toBe("string"); + expect(typeof mixnode.bond_information.original_pledge.amount).toBe( + "string" + ); + expect(typeof mixnode.bond_information.original_pledge.denom).toBe( + "string" + ); expect(typeof mixnode.bond_information.layer).toBe("number"); expect(typeof mixnode.bond_information.bonding_height).toBe("number"); expect(typeof mixnode.bond_information.is_unbonding).toBe("boolean"); @@ -30,11 +34,17 @@ describe("Get mixnode data", (): void => { //mixnode expect(typeof mixnode.bond_information.mix_node.host).toBe("string"); - expect(mixnode.bond_information.mix_node.http_api_port).toStrictEqual(8000); - expect(typeof mixnode.bond_information.mix_node.verloc_port).toBe("number"); + expect(mixnode.bond_information.mix_node.http_api_port).toStrictEqual( + 8000 + ); + expect(typeof mixnode.bond_information.mix_node.verloc_port).toBe( + "number" + ); expect(typeof mixnode.bond_information.mix_node.mix_port).toBe("number"); expect(mixnode.bond_information.mix_node.mix_port).toStrictEqual(1789); - expect(typeof mixnode.bond_information.mix_node.verloc_port).toBe("number"); + expect(typeof mixnode.bond_information.mix_node.verloc_port).toBe( + "number" + ); const identitykey = mixnode.bond_information.mix_node.identity_key; if (typeof identitykey === "string") { @@ -51,15 +61,27 @@ describe("Get mixnode data", (): void => { } //rewarding details - expect(typeof mixnode.rewarding_details.cost_params.profit_margin_percent).toBe("string"); - expect(typeof mixnode.rewarding_details.cost_params.interval_operating_cost.denom).toBe("string"); - expect(typeof mixnode.rewarding_details.cost_params.interval_operating_cost.amount).toBe("string"); + expect( + typeof mixnode.rewarding_details.cost_params.profit_margin_percent + ).toBe("string"); + expect( + typeof mixnode.rewarding_details.cost_params.interval_operating_cost + .denom + ).toBe("string"); + expect( + typeof mixnode.rewarding_details.cost_params.interval_operating_cost + .amount + ).toBe("string"); expect(typeof mixnode.rewarding_details.operator).toBe("string"); expect(typeof mixnode.rewarding_details.delegates).toBe("string"); expect(typeof mixnode.rewarding_details.total_unit_reward).toBe("string"); expect(typeof mixnode.rewarding_details.unit_delegation).toBe("string"); - expect(typeof mixnode.rewarding_details.last_rewarded_epoch).toBe("number"); - expect(typeof mixnode.rewarding_details.unique_delegations).toBe("number"); + expect(typeof mixnode.rewarding_details.last_rewarded_epoch).toBe( + "number" + ); + expect(typeof mixnode.rewarding_details.unique_delegations).toBe( + "number" + ); }); }); @@ -76,36 +98,66 @@ describe("Get mixnode data", (): void => { // expect(typeof mixnode.family).toBe("string"); //mixnode details bond info - expect(typeof mixnode.mixnode_details.bond_information.mix_id).toBe("number") - expect(typeof mixnode.mixnode_details.bond_information.owner).toBe("string"); - expect(typeof mixnode.mixnode_details.bond_information.original_pledge.amount).toBe("string"); - expect(typeof mixnode.mixnode_details.bond_information.original_pledge.denom).toBe("string"); - expect(typeof mixnode.mixnode_details.bond_information.layer).toBe("number"); - expect(typeof mixnode.mixnode_details.bond_information.bonding_height).toBe("number"); - expect(typeof mixnode.mixnode_details.bond_information.is_unbonding).toBe("boolean"); + expect(typeof mixnode.mixnode_details.bond_information.mix_id).toBe( + "number" + ); + expect(typeof mixnode.mixnode_details.bond_information.owner).toBe( + "string" + ); + expect( + typeof mixnode.mixnode_details.bond_information.original_pledge.amount + ).toBe("string"); + expect( + typeof mixnode.mixnode_details.bond_information.original_pledge.denom + ).toBe("string"); + expect(typeof mixnode.mixnode_details.bond_information.layer).toBe( + "number" + ); + expect( + typeof mixnode.mixnode_details.bond_information.bonding_height + ).toBe("number"); + expect(typeof mixnode.mixnode_details.bond_information.is_unbonding).toBe( + "boolean" + ); if (mixnode.mixnode_details.bond_information.proxy === null) { return true; } else { - expect(typeof mixnode.mixnode_details.bond_information.proxy).toBe("string"); + expect(typeof mixnode.mixnode_details.bond_information.proxy).toBe( + "string" + ); } //mixnode - expect(typeof mixnode.mixnode_details.bond_information.mix_node.host).toBe("string"); - expect(mixnode.mixnode_details.bond_information.mix_node.http_api_port).toStrictEqual(8000); - expect(typeof mixnode.mixnode_details.bond_information.mix_node.verloc_port).toBe("number"); - expect(typeof mixnode.mixnode_details.bond_information.mix_node.mix_port).toBe("number"); - expect(mixnode.mixnode_details.bond_information.mix_node.mix_port).toStrictEqual(1789); - expect(typeof mixnode.mixnode_details.bond_information.mix_node.verloc_port).toBe("number"); + expect( + typeof mixnode.mixnode_details.bond_information.mix_node.host + ).toBe("string"); + expect( + mixnode.mixnode_details.bond_information.mix_node.http_api_port + ).toStrictEqual(8000); + expect( + typeof mixnode.mixnode_details.bond_information.mix_node.verloc_port + ).toBe("number"); + expect( + typeof mixnode.mixnode_details.bond_information.mix_node.mix_port + ).toBe("number"); + expect( + mixnode.mixnode_details.bond_information.mix_node.mix_port + ).toStrictEqual(1789); + expect( + typeof mixnode.mixnode_details.bond_information.mix_node.verloc_port + ).toBe("number"); - const identitykey2 = mixnode.mixnode_details.bond_information.mix_node.identity_key + const identitykey2 = + mixnode.mixnode_details.bond_information.mix_node.identity_key; if (typeof identitykey2 === "string") { if (identitykey2.length === 43) { return true; } else expect(identitykey2).toHaveLength(44); } - const sphinx2 = mixnode.mixnode_details.bond_information.mix_node.sphinx_key + const sphinx2 = + mixnode.mixnode_details.bond_information.mix_node.sphinx_key; if (typeof sphinx2 === "string") { if (sphinx2.length === 43) { return true; @@ -113,22 +165,45 @@ describe("Get mixnode data", (): void => { } //mixnode rewarding info - expect(typeof mixnode.mixnode_details.rewarding_details.cost_params.profit_margin_percent).toBe("string"); - expect(typeof mixnode.mixnode_details.rewarding_details.cost_params.interval_operating_cost.denom).toBe("string"); - expect(typeof mixnode.mixnode_details.rewarding_details.cost_params.interval_operating_cost.amount).toBe("string"); - expect(typeof mixnode.mixnode_details.rewarding_details.operator).toBe("string"); - expect(typeof mixnode.mixnode_details.rewarding_details.delegates).toBe("string"); - expect(typeof mixnode.mixnode_details.rewarding_details.total_unit_reward).toBe("string"); - expect(typeof mixnode.mixnode_details.rewarding_details.unit_delegation).toBe("string"); - expect(typeof mixnode.mixnode_details.rewarding_details.last_rewarded_epoch).toBe("number"); - expect(typeof mixnode.mixnode_details.rewarding_details.unique_delegations).toBe("number"); + expect( + typeof mixnode.mixnode_details.rewarding_details.cost_params + .profit_margin_percent + ).toBe("string"); + expect( + typeof mixnode.mixnode_details.rewarding_details.cost_params + .interval_operating_cost.denom + ).toBe("string"); + expect( + typeof mixnode.mixnode_details.rewarding_details.cost_params + .interval_operating_cost.amount + ).toBe("string"); + expect(typeof mixnode.mixnode_details.rewarding_details.operator).toBe( + "string" + ); + expect(typeof mixnode.mixnode_details.rewarding_details.delegates).toBe( + "string" + ); + expect( + typeof mixnode.mixnode_details.rewarding_details.total_unit_reward + ).toBe("string"); + expect( + typeof mixnode.mixnode_details.rewarding_details.unit_delegation + ).toBe("string"); + expect( + typeof mixnode.mixnode_details.rewarding_details.last_rewarded_epoch + ).toBe("number"); + expect( + typeof mixnode.mixnode_details.rewarding_details.unique_delegations + ).toBe("number"); }); }); it("Get active mixnodes", async (): Promise => { const response = await contract.getActiveMixnodes(); response.forEach(function (mixnode) { - expect(mixnode.rewarding_details.cost_params.profit_margin_percent).toBeTruthy(); + expect( + mixnode.rewarding_details.cost_params.profit_margin_percent + ).toBeTruthy(); expect(typeof mixnode.bond_information.layer).toBe("number"); }); }); @@ -136,7 +211,10 @@ describe("Get mixnode data", (): void => { it("Get active mixnodes detailed", async (): Promise => { const response = await contract.getActiveMixnodesDetailed(); response.forEach(function (mixnode) { - expect(mixnode.mixnode_details.rewarding_details.cost_params.profit_margin_percent).toBeTruthy(); + expect( + mixnode.mixnode_details.rewarding_details.cost_params + .profit_margin_percent + ).toBeTruthy(); }); }); @@ -150,14 +228,21 @@ describe("Get mixnode data", (): void => { it("Get rewarded mixnodes detailed", async (): Promise => { const response = await contract.getRewardedMixnodesDetailed(); response.forEach(function (mixnode) { - expect(mixnode.mixnode_details.rewarding_details.last_rewarded_epoch).toBeTruthy(); + expect( + mixnode.mixnode_details.rewarding_details.last_rewarded_epoch + ).toBeTruthy(); }); }); it("Get blacklisted mixnodes", async (): Promise => { const response = await contract.getBlacklistedMixnodes(); - response.forEach(function (value) { - expect(typeof value).toBe("number"); - }); + if (response === null) { + console.log("No blacklisted mixnodes"); + expect(response).toBeNull();; + } else { + response.forEach(function (value) { + expect(typeof value).toBe("string"); + }); + } }); }); From c725ae4e2bcd06007839650da2f2e698428c3b42 Mon Sep 17 00:00:00 2001 From: Tommy Verrall Date: Wed, 2 Aug 2023 12:55:46 +0200 Subject: [PATCH 20/46] remove console --- .../contract_cache/gateway/contract-cache-gateway.test.ts | 2 +- .../contract_cache/mixnode/contract-cache-mixnode.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nym-api/tests/functional_test/contract_cache/gateway/contract-cache-gateway.test.ts b/nym-api/tests/functional_test/contract_cache/gateway/contract-cache-gateway.test.ts index 992e35c89a..d83cdc20cd 100644 --- a/nym-api/tests/functional_test/contract_cache/gateway/contract-cache-gateway.test.ts +++ b/nym-api/tests/functional_test/contract_cache/gateway/contract-cache-gateway.test.ts @@ -41,7 +41,7 @@ describe("Get gateway data", (): void => { it("Get blacklisted gateways", async (): Promise => { const response = await contract.getBlacklistedGateways(); if (response === null) { - console.log("No blacklisted gateways"); + // no blacklisted gateways returns an empty array expect(response).toBeNull(); } else { response.forEach(function (value) { diff --git a/nym-api/tests/functional_test/contract_cache/mixnode/contract-cache-mixnode.test.ts b/nym-api/tests/functional_test/contract_cache/mixnode/contract-cache-mixnode.test.ts index 9cb66539a9..33d6f0e97f 100644 --- a/nym-api/tests/functional_test/contract_cache/mixnode/contract-cache-mixnode.test.ts +++ b/nym-api/tests/functional_test/contract_cache/mixnode/contract-cache-mixnode.test.ts @@ -237,7 +237,7 @@ describe("Get mixnode data", (): void => { it("Get blacklisted mixnodes", async (): Promise => { const response = await contract.getBlacklistedMixnodes(); if (response === null) { - console.log("No blacklisted mixnodes"); + // no blacklisted mixnodes returns an empty array expect(response).toBeNull();; } else { response.forEach(function (value) { From 2ed3e646bef77945fb3998667c79fb31d84bde90 Mon Sep 17 00:00:00 2001 From: Tommy Verrall Date: Wed, 2 Aug 2023 13:02:29 +0200 Subject: [PATCH 21/46] linting and removing unused imports --- .../circulating-supply.test.ts | 3 -- .../contract-cache-epochs.test.ts | 3 -- .../gateway/contract-cache-gateway.test.ts | 5 +-- .../mixnode/contract-cache-mixnode.test.ts | 2 +- .../contract_cache/services.test.ts | 42 +++++++++---------- .../status/status-gateway.test.ts | 8 +++- .../status/status-mixnode.test.ts | 24 ++++++++--- nym-api/tests/src/types/ContractCacheTypes.ts | 3 +- 8 files changed, 46 insertions(+), 44 deletions(-) diff --git a/nym-api/tests/functional_test/circulating_supply/circulating-supply.test.ts b/nym-api/tests/functional_test/circulating_supply/circulating-supply.test.ts index c74d039175..b09d56df75 100644 --- a/nym-api/tests/functional_test/circulating_supply/circulating-supply.test.ts +++ b/nym-api/tests/functional_test/circulating_supply/circulating-supply.test.ts @@ -1,12 +1,9 @@ -import ConfigHandler from "../../src/config/configHandler"; import ContractCache from "../../src/endpoints/CirculatingSupply"; let contract: ContractCache; -let config: ConfigHandler; describe("Get circulating supply", (): void => { beforeAll(async (): Promise => { contract = new ContractCache(); - config = ConfigHandler.getInstance(); }); it("Get circulating supply amounts", async (): Promise => { diff --git a/nym-api/tests/functional_test/contract_cache/contract-cache-epochs.test.ts b/nym-api/tests/functional_test/contract_cache/contract-cache-epochs.test.ts index 482817f669..a2923e9c52 100644 --- a/nym-api/tests/functional_test/contract_cache/contract-cache-epochs.test.ts +++ b/nym-api/tests/functional_test/contract_cache/contract-cache-epochs.test.ts @@ -1,13 +1,10 @@ import ContractCache from "../../src/endpoints/ContractCache"; -import ConfigHandler from "../../src/config/configHandler"; let contract: ContractCache; -let config: ConfigHandler; describe("Get epoch info", (): void => { beforeAll(async (): Promise => { contract = new ContractCache(); - config = ConfigHandler.getInstance(); }); it("Get epoch reward params", async (): Promise => { diff --git a/nym-api/tests/functional_test/contract_cache/gateway/contract-cache-gateway.test.ts b/nym-api/tests/functional_test/contract_cache/gateway/contract-cache-gateway.test.ts index d83cdc20cd..e1dc896ad9 100644 --- a/nym-api/tests/functional_test/contract_cache/gateway/contract-cache-gateway.test.ts +++ b/nym-api/tests/functional_test/contract_cache/gateway/contract-cache-gateway.test.ts @@ -1,13 +1,10 @@ import ContractCache from "../../../src/endpoints/ContractCache"; -import ConfigHandler from "../../../src/config/configHandler"; let contract: ContractCache; -let config: ConfigHandler; describe("Get gateway data", (): void => { beforeAll(async (): Promise => { contract = new ContractCache(); - config = ConfigHandler.getInstance(); }); it("Get all gateways", async (): Promise => { @@ -42,7 +39,7 @@ describe("Get gateway data", (): void => { const response = await contract.getBlacklistedGateways(); if (response === null) { // no blacklisted gateways returns an empty array - expect(response).toBeNull(); + expect(response).toBeNull(); } else { response.forEach(function (value) { expect(typeof value).toBe("string"); diff --git a/nym-api/tests/functional_test/contract_cache/mixnode/contract-cache-mixnode.test.ts b/nym-api/tests/functional_test/contract_cache/mixnode/contract-cache-mixnode.test.ts index 33d6f0e97f..af1a40b297 100644 --- a/nym-api/tests/functional_test/contract_cache/mixnode/contract-cache-mixnode.test.ts +++ b/nym-api/tests/functional_test/contract_cache/mixnode/contract-cache-mixnode.test.ts @@ -238,7 +238,7 @@ describe("Get mixnode data", (): void => { const response = await contract.getBlacklistedMixnodes(); if (response === null) { // no blacklisted mixnodes returns an empty array - expect(response).toBeNull();; + expect(response).toBeNull(); } else { response.forEach(function (value) { expect(typeof value).toBe("string"); diff --git a/nym-api/tests/functional_test/contract_cache/services.test.ts b/nym-api/tests/functional_test/contract_cache/services.test.ts index d38adf9d9d..711aaa0246 100644 --- a/nym-api/tests/functional_test/contract_cache/services.test.ts +++ b/nym-api/tests/functional_test/contract_cache/services.test.ts @@ -1,28 +1,24 @@ import ContractCache from "../../src/endpoints/ContractCache"; -import ConfigHandler from "../../src/config/configHandler"; - let contract: ContractCache; -let config: ConfigHandler; describe("Get service provider info", (): void => { - beforeAll(async (): Promise => { - contract = new ContractCache(); - config = ConfigHandler.getInstance(); - }); + beforeAll(async (): Promise => { + contract = new ContractCache(); + }); - it("Get service providers", async (): Promise => { - const response = await contract.getServiceProviders(); - if ("[service_id]" in response) { - response.services.forEach((x) => { - expect(typeof x.service.nym_address.address).toBe("string"); - expect(typeof x.service.service_type).toBe("string"); - expect(typeof x.service.block_height).toBe("number"); - expect(typeof x.service.announcer).toBe("string"); - expect(typeof x.service.deposit.amount).toBe("string"); - expect(typeof x.service.deposit.denom).toBe("string"); - }); - } else if ("[ ]" in response) { - return; - } - }); -}); \ No newline at end of file + it("Get service providers", async (): Promise => { + const response = await contract.getServiceProviders(); + if ("[service_id]" in response) { + response.services.forEach((x) => { + expect(typeof x.service.nym_address.address).toBe("string"); + expect(typeof x.service.service_type).toBe("string"); + expect(typeof x.service.block_height).toBe("number"); + expect(typeof x.service.announcer).toBe("string"); + expect(typeof x.service.deposit.amount).toBe("string"); + expect(typeof x.service.deposit.denom).toBe("string"); + }); + } else if ("[ ]" in response) { + return; + } + }); +}); diff --git a/nym-api/tests/functional_test/status/status-gateway.test.ts b/nym-api/tests/functional_test/status/status-gateway.test.ts index 92435e12d3..71f2becc6d 100644 --- a/nym-api/tests/functional_test/status/status-gateway.test.ts +++ b/nym-api/tests/functional_test/status/status-gateway.test.ts @@ -40,7 +40,9 @@ describe("Get gateway data", (): void => { expect(identity_key).toStrictEqual(response.identity); expect(typeof response.owner).toBe("string"); } else if ("message" in response) { - expect(response.message).toContain("could not find uptime history associated with gateway"); + expect(response.message).toContain( + "could not find uptime history associated with gateway" + ); } }); @@ -58,7 +60,9 @@ describe("Get gateway data", (): void => { expect(identity_key).toStrictEqual(response.identity); expect(typeof response.count).toBe("number"); } else if ("message" in response) { - expect(response.message).toContain("could not find uptime history associated with mixnode"); + expect(response.message).toContain( + "could not find uptime history associated with mixnode" + ); } }); diff --git a/nym-api/tests/functional_test/status/status-mixnode.test.ts b/nym-api/tests/functional_test/status/status-mixnode.test.ts index aaa8054057..6590843f02 100644 --- a/nym-api/tests/functional_test/status/status-mixnode.test.ts +++ b/nym-api/tests/functional_test/status/status-mixnode.test.ts @@ -55,7 +55,9 @@ describe("Get mixnode data", (): void => { expect(identity_key).toStrictEqual(response.mix_id); expect(typeof response.owner).toBe("string"); } else if ("message" in response) { - expect(response.message).toContain("could not find uptime history associated with mixnode"); + expect(response.message).toContain( + "could not find uptime history associated with mixnode" + ); } }); @@ -70,7 +72,9 @@ describe("Get mixnode data", (): void => { const identity_key = config.environmnetConfig.mix_id; const response = await status.getMixnodeRewardComputation(identity_key); if ("estimation" in response) { - expect(response.reward_params.interval.sybil_resistance).toStrictEqual("0.3"); + expect(response.reward_params.interval.sybil_resistance).toStrictEqual( + "0.3" + ); expect(response.reward_params.active_set_size).toStrictEqual(240); expect(typeof response.reward_params.interval.reward_pool).toBe("string"); } else if ("message" in response) { @@ -108,7 +112,9 @@ describe("Get mixnode data", (): void => { const response = await status.getUnfilteredMixnodes(); response.forEach((x) => { expect(typeof x.stake_saturation).toBe("string"); - expect(typeof x.mixnode_details.rewarding_details.last_rewarded_epoch).toBe("number"); + expect( + typeof x.mixnode_details.rewarding_details.last_rewarded_epoch + ).toBe("number"); }); }); @@ -116,7 +122,9 @@ describe("Get mixnode data", (): void => { const identity_key = config.environmnetConfig.mix_id; const response = await status.getMixnodeStatus(identity_key); const unfiltered_mixnodes_response = await status.getUnfilteredMixnodes(); - const mixnode = unfiltered_mixnodes_response.find(x => x.mixnode_details.bond_information.mix_id === identity_key); + const mixnode = unfiltered_mixnodes_response.find( + (x) => x.mixnode_details.bond_information.mix_id === identity_key + ); if (mixnode) { expect(response.status).toStrictEqual("active"); } else { @@ -127,7 +135,9 @@ describe("Get mixnode data", (): void => { it("Get all rewarded mixnodes", async (): Promise => { const response = await status.getDetailedRewardedMixnodes(); response.forEach((x) => { - expect(typeof x.mixnode_details.rewarding_details.last_rewarded_epoch).toBe("number"); + expect( + typeof x.mixnode_details.rewarding_details.last_rewarded_epoch + ).toBe("number"); }); }); @@ -146,7 +156,9 @@ describe("Get mixnode data", (): void => { it("with correct data", async (): Promise => { const mix_id = config.environmnetConfig.mix_id; - const response = await status.sendMixnodeRewardEstimatedComputation(mix_id); + const response = await status.sendMixnodeRewardEstimatedComputation( + mix_id + ); expect(typeof response.estimation.delegates).toBe("string"); }); }); diff --git a/nym-api/tests/src/types/ContractCacheTypes.ts b/nym-api/tests/src/types/ContractCacheTypes.ts index f3cf31e401..e66c3018a8 100644 --- a/nym-api/tests/src/types/ContractCacheTypes.ts +++ b/nym-api/tests/src/types/ContractCacheTypes.ts @@ -125,7 +125,7 @@ export interface EpochLength { } export interface ServiceProviders { - services: (Services)[]; + services: Services[]; } export interface Services { service_id: number; @@ -145,4 +145,3 @@ export interface Deposit { denom: string; amount: string; } - From cbafd37102bc7793464f27f41c47f1f8eef6671c Mon Sep 17 00:00:00 2001 From: Tommy Verrall Date: Wed, 2 Aug 2023 13:22:02 +0200 Subject: [PATCH 22/46] fix config --- .../contract_cache/mixnode/contract-cache-mixnode.test.ts | 2 +- nym-api/tests/src/config/config.yaml | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/nym-api/tests/functional_test/contract_cache/mixnode/contract-cache-mixnode.test.ts b/nym-api/tests/functional_test/contract_cache/mixnode/contract-cache-mixnode.test.ts index af1a40b297..6182f8a63c 100644 --- a/nym-api/tests/functional_test/contract_cache/mixnode/contract-cache-mixnode.test.ts +++ b/nym-api/tests/functional_test/contract_cache/mixnode/contract-cache-mixnode.test.ts @@ -241,7 +241,7 @@ describe("Get mixnode data", (): void => { expect(response).toBeNull(); } else { response.forEach(function (value) { - expect(typeof value).toBe("string"); + expect(typeof value).toBe("number"); }); } }); diff --git a/nym-api/tests/src/config/config.yaml b/nym-api/tests/src/config/config.yaml index 83a9d3fa92..d0f51eff0c 100644 --- a/nym-api/tests/src/config/config.yaml +++ b/nym-api/tests/src/config/config.yaml @@ -10,7 +10,8 @@ qa: log_level: error prod: api_base_url: https://validator.nymtech.net/api/v1 - mixnode_identity: DLdMKLPywEy1vnu3yPrtXvzY7fw1puiiHpA9n9UQatiQ - gateway_identity: CgQrYP8etksSBf4nALNqp93SHPpgFwEUyTsjBNNLj5WM + mix_id: 730 + mixnode_identity: 3pMCJswCyA19MGYWGDWT5fBk2M8ybSZGXttyAoNY5gBB + gateway_identity: 2BuMSfMW3zpeAjKXyKLhmY4QW1DXurrtSPEJ6CjX3SEh log_level: error time_zone: utc From 4696470b19a711abc0a1e5a116067a357d549edf Mon Sep 17 00:00:00 2001 From: mfahampshire Date: Wed, 2 Aug 2023 16:26:41 +0200 Subject: [PATCH 23/46] rephrased intro --- documentation/dev-portal/src/SUMMARY.md | 2 ++ documentation/dev-portal/src/introduction.md | 4 ++-- documentation/dev-portal/src/quickstart/chat-demo.md | 5 +++++ .../dev-portal/src/quickstart/cred-playground.md | 5 +++++ documentation/dev-portal/src/quickstart/overview.md | 12 +++--------- 5 files changed, 17 insertions(+), 11 deletions(-) create mode 100644 documentation/dev-portal/src/quickstart/chat-demo.md create mode 100644 documentation/dev-portal/src/quickstart/cred-playground.md diff --git a/documentation/dev-portal/src/SUMMARY.md b/documentation/dev-portal/src/SUMMARY.md index aeae804662..0e0c02bc58 100644 --- a/documentation/dev-portal/src/SUMMARY.md +++ b/documentation/dev-portal/src/SUMMARY.md @@ -11,6 +11,8 @@ # Quickstart - [Overview](quickstart/overview.md) +- [Chat demo (webapp)](quickstart/chat-demo.md) +- [Coconut Credential Playground (webapp)](quickstart/cred-playground.md) - [SOCKS Proxy (CLI)](quickstart/socks-proxy.md) - [NymConnect Beta (GUI)](quickstart/nymconnect-gui.md) diff --git a/documentation/dev-portal/src/introduction.md b/documentation/dev-portal/src/introduction.md index d679a77c53..7335fab32b 100644 --- a/documentation/dev-portal/src/introduction.md +++ b/documentation/dev-portal/src/introduction.md @@ -1,5 +1,5 @@ # Introduction -Welcome to the Nym Developer Portal, containing the resources and tools needed to build privacy enhanced apps (PEApps) with Nym's technology. Whether you're a seasoned developer or just getting started, our portal is designed to help you create decentralized applications and services utilising the Nym mixnet. +Welcome to the Nym Developer Portal, containing quickstart resources, user manuals, integration information, and tutorials outlining to start building privacy enhanced apps. -Join our community of developers and start building the decentralized future today! +For more in-depth information about nodes, network traffic flows, etc check out the [docs](https://nymtech.net/docs). diff --git a/documentation/dev-portal/src/quickstart/chat-demo.md b/documentation/dev-portal/src/quickstart/chat-demo.md new file mode 100644 index 0000000000..6e2f5c244a --- /dev/null +++ b/documentation/dev-portal/src/quickstart/chat-demo.md @@ -0,0 +1,5 @@ +# Chat demo (webapp) + +You can find a browser-based 'hello world' chat app [here](https://chat-demo.nymtech.net). + +Either open in two browser windows and send messages to yourself, or share with a friend and send messages to each other through the mixnet. diff --git a/documentation/dev-portal/src/quickstart/cred-playground.md b/documentation/dev-portal/src/quickstart/cred-playground.md new file mode 100644 index 0000000000..aa2220940c --- /dev/null +++ b/documentation/dev-portal/src/quickstart/cred-playground.md @@ -0,0 +1,5 @@ +# Coconut Credential Playground (webapp) + +There is a coconut-scheme based Credential Library playground [here](https://coco-demo.nymtech.net/). This is a WASM implementation of our Coconut libraries which generate raw Coconut credentials. Test it to create and re-randomize your own credentials. + +For more information on what is happening here check out the [Coconut docs](https://nymtech.net/docs/coconut.html). diff --git a/documentation/dev-portal/src/quickstart/overview.md b/documentation/dev-portal/src/quickstart/overview.md index b2ac4199c9..534ed60fe5 100644 --- a/documentation/dev-portal/src/quickstart/overview.md +++ b/documentation/dev-portal/src/quickstart/overview.md @@ -1,13 +1,7 @@ # Overview -There are multiple options to quickly connect to Nym and see the network in action without the need for any code changes to your application. At most, these involve running Nym as a second process alongside an existing application in order to send traffic through the mixnet. +There are multiple options to quickly connect to Nym and play with both the mixnet and credentials on the Sandbox testnet. -Demo applications: -* a browser-based 'hello world' [chat application](https://chat-demo.nymtech.net). Either open in two browser windows and send messages to yourself, or share with a friend and send messages to each other through the mixnet! -* a Coconut-scheme based [Credential Library](https://coco-demo.nymtech.net/). This is a WASM implementation of our Coconut libraries which generate raw Coconut credentials. Test it to create and re-randomize your own credentials! -
-Proxy traffic with the Nym Socks5 client: -* set up a plug-and-play connection with the [NymConnect](./nymconnect-gui.md) GUI for proxying Telegram, Electrum, Keybase or Blockstream Green traffic through the mixnet (~2 minutes). -* [Download and run](./socks-proxy.md) the Nym Socks5 client via the CLI, for other desktop applications with SOCKS5 connection options (~30 minutes). +At most, these involve running Nym as a second process alongside an existing application in order to send traffic through the mixnet, most are either interact webpages or a standalone app. -If you've already covered the information in this section, or want to jump straight into integrating/ a Nym connection into an existing application, head to the [Integrations](../integrations/integration-options.md) section. +If you've already covered the information in this section, or want to jump straight into integrating/ a Nym connection into an existing application, head to the [Integrations](../integrations/integration-options.md) section. From b66c4cf0bb9b29b0b326ce7a5dd748fe724ea3ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 3 Aug 2023 11:01:03 +0100 Subject: [PATCH 24/46] removed dependency on wasm-timer fork (#3733) --- Cargo.lock | 39 +- Cargo.toml | 3 + clients/webassembly/Cargo.lock | 53 +- clients/webassembly/Cargo.toml | 2 +- .../src/tester/ephemeral_receiver.rs | 3 +- common/client-core/Cargo.toml | 6 +- .../src/client/cover_traffic_stream.rs | 37 +- common/client-core/src/client/helpers/wasm.rs | 5 +- .../real_traffic_stream.rs | 32 +- common/client-core/src/init/helpers.rs | 16 +- common/client-libs/gateway-client/Cargo.toml | 6 +- .../client-libs/gateway-client/src/client.rs | 25 +- common/nonexhaustive-delayqueue/Cargo.toml | 18 +- common/nonexhaustive-delayqueue/src/lib.rs | 12 +- .../src/wasm_delay_queue/delay_queue.rs | 1234 ----------------- .../src/wasm_delay_queue/mod.rs | 42 - .../src/wasm_delay_queue/wheel/level.rs | 253 ---- .../src/wasm_delay_queue/wheel/mod.rs | 315 ----- .../src/wasm_delay_queue/wheel/stack.rs | 28 - 19 files changed, 102 insertions(+), 2027 deletions(-) delete mode 100644 common/nonexhaustive-delayqueue/src/wasm_delay_queue/delay_queue.rs delete mode 100644 common/nonexhaustive-delayqueue/src/wasm_delay_queue/mod.rs delete mode 100644 common/nonexhaustive-delayqueue/src/wasm_delay_queue/wheel/level.rs delete mode 100644 common/nonexhaustive-delayqueue/src/wasm_delay_queue/wheel/mod.rs delete mode 100644 common/nonexhaustive-delayqueue/src/wasm_delay_queue/wheel/stack.rs diff --git a/Cargo.lock b/Cargo.lock index d576e05c0c..a823625624 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2924,9 +2924,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", ] [[package]] @@ -3808,8 +3805,8 @@ dependencies = [ "url", "wasm-bindgen", "wasm-bindgen-futures", - "wasm-timer", "wasm-utils", + "wasmtimer", "zeroize", ] @@ -4082,8 +4079,8 @@ dependencies = [ "url", "wasm-bindgen", "wasm-bindgen-futures", - "wasm-timer", "wasm-utils", + "wasmtimer", ] [[package]] @@ -4361,12 +4358,10 @@ dependencies = [ name = "nym-nonexhaustive-delayqueue" version = "0.1.0" dependencies = [ - "futures-core", - "slab", "tokio", "tokio-stream", "tokio-util", - "wasm-timer", + "wasmtimer", ] [[package]] @@ -8131,20 +8126,6 @@ version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" -[[package]] -name = "wasm-timer" -version = "0.2.5" -source = "git+https://github.com/mmsinclair/wasm-timer?rev=b9d1a54ad514c2f230a026afe0dde341e98cd7b6#b9d1a54ad514c2f230a026afe0dde341e98cd7b6" -dependencies = [ - "futures", - "js-sys", - "parking_lot 0.11.2", - "pin-utils", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - [[package]] name = "wasm-utils" version = "0.1.0" @@ -8163,6 +8144,20 @@ dependencies = [ "web-sys", ] +[[package]] +name = "wasmtimer" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f656cd8858a5164932d8a90f936700860976ec21eb00e0fe2aa8cab13f6b4cf" +dependencies = [ + "futures", + "js-sys", + "parking_lot 0.12.1", + "pin-utils", + "slab", + "wasm-bindgen", +] + [[package]] name = "web-sys" version = "0.3.60" diff --git a/Cargo.toml b/Cargo.toml index fd137c6bdf..22b4cb99ac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -146,3 +146,6 @@ thiserror = "1.0.38" tokio = "1.24.1" url = "2.2" zeroize = "1.6.0" + +# wasm-related dependencies +wasmtimer = "0.2.0" \ No newline at end of file diff --git a/clients/webassembly/Cargo.lock b/clients/webassembly/Cargo.lock index f0733eac1b..330f31c4d5 100644 --- a/clients/webassembly/Cargo.lock +++ b/clients/webassembly/Cargo.lock @@ -1539,7 +1539,7 @@ checksum = "a604f7a68fbf8103337523b1fadc8ade7361ee3f112f7c680ad179651616aed5" dependencies = [ "futures-core", "lock_api", - "parking_lot", + "parking_lot 0.11.2", ] [[package]] @@ -2114,9 +2114,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ "cfg-if 1.0.0", - "js-sys", - "wasm-bindgen", - "web-sys", ] [[package]] @@ -2501,8 +2498,8 @@ dependencies = [ "url", "wasm-bindgen", "wasm-bindgen-futures", - "wasm-timer", "wasm-utils", + "wasmtimer", "zeroize", ] @@ -2539,8 +2536,8 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "wasm-bindgen-test", - "wasm-timer", "wasm-utils", + "wasmtimer", "wee_alloc", "zeroize", ] @@ -2719,8 +2716,8 @@ dependencies = [ "url", "wasm-bindgen", "wasm-bindgen-futures", - "wasm-timer", "wasm-utils", + "wasmtimer", ] [[package]] @@ -2836,12 +2833,10 @@ dependencies = [ name = "nym-nonexhaustive-delayqueue" version = "0.1.0" dependencies = [ - "futures-core", - "slab", "tokio", "tokio-stream", "tokio-util", - "wasm-timer", + "wasmtimer", ] [[package]] @@ -3252,6 +3247,16 @@ dependencies = [ "parking_lot_core 0.8.6", ] +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core 0.9.7", +] + [[package]] name = "parking_lot_core" version = "0.8.6" @@ -5233,20 +5238,6 @@ dependencies = [ "quote", ] -[[package]] -name = "wasm-timer" -version = "0.2.5" -source = "git+https://github.com/mmsinclair/wasm-timer?rev=b9d1a54ad514c2f230a026afe0dde341e98cd7b6#b9d1a54ad514c2f230a026afe0dde341e98cd7b6" -dependencies = [ - "futures", - "js-sys", - "parking_lot", - "pin-utils", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - [[package]] name = "wasm-utils" version = "0.1.0" @@ -5265,6 +5256,20 @@ dependencies = [ "web-sys", ] +[[package]] +name = "wasmtimer" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f656cd8858a5164932d8a90f936700860976ec21eb00e0fe2aa8cab13f6b4cf" +dependencies = [ + "futures", + "js-sys", + "parking_lot 0.12.1", + "pin-utils", + "slab", + "wasm-bindgen", +] + [[package]] name = "web-sys" version = "0.3.60" diff --git a/clients/webassembly/Cargo.toml b/clients/webassembly/Cargo.toml index 11d1cb131a..7405002cea 100644 --- a/clients/webassembly/Cargo.toml +++ b/clients/webassembly/Cargo.toml @@ -33,7 +33,7 @@ wasm-bindgen-futures = "0.4" thiserror = "1.0.40" zeroize = "1.6.0" -wasm-timer = { git = "https://github.com/mmsinclair/wasm-timer", rev = "b9d1a54ad514c2f230a026afe0dde341e98cd7b6"} +wasmtimer = { version = "0.2.0", features = ["tokio"] } # internal nym-node-tester-utils = { path = "../../common/node-tester-utils" } diff --git a/clients/webassembly/src/tester/ephemeral_receiver.rs b/clients/webassembly/src/tester/ephemeral_receiver.rs index 4f2ce3cd8a..826bfa07b2 100644 --- a/clients/webassembly/src/tester/ephemeral_receiver.rs +++ b/clients/webassembly/src/tester/ephemeral_receiver.rs @@ -10,6 +10,7 @@ use std::collections::HashSet; use std::time::Duration; use tokio::sync::MutexGuard as AsyncMutexGuard; use wasm_utils::{console_error, console_log, console_warn}; +use wasmtimer::tokio::sleep; pub(crate) struct EphemeralTestReceiver<'a> { sent_packets: u32, @@ -90,7 +91,7 @@ impl<'a> EphemeralTestReceiver<'a> { } pub(crate) async fn perform_test(mut self) -> NodeTestResult { - let mut timeout_fut = wasm_timer::Delay::new(self.timeout_duration); + let mut timeout_fut = sleep(self.timeout_duration); loop { tokio::select! { diff --git a/common/client-core/Cargo.toml b/common/client-core/Cargo.toml index d5ae32dbd2..ab1c9b8c04 100644 --- a/common/client-core/Cargo.toml +++ b/common/client-core/Cargo.toml @@ -69,9 +69,9 @@ version = "0.4" [target."cfg(target_arch = \"wasm32\")".dependencies.wasm-bindgen] version = "0.2.83" -[target."cfg(target_arch = \"wasm32\")".dependencies.wasm-timer] -git = "https://github.com/mmsinclair/wasm-timer" -rev = "b9d1a54ad514c2f230a026afe0dde341e98cd7b6" +[target."cfg(target_arch = \"wasm32\")".dependencies.wasmtimer] +workspace = true +features = ["tokio"] [target."cfg(target_arch = \"wasm32\")".dependencies.gloo-timers] version = "0.2.4" diff --git a/common/client-core/src/client/cover_traffic_stream.rs b/common/client-core/src/client/cover_traffic_stream.rs index 8784bfb7ba..c603926933 100644 --- a/common/client-core/src/client/cover_traffic_stream.rs +++ b/common/client-core/src/client/cover_traffic_stream.rs @@ -19,10 +19,10 @@ use std::time::Duration; use tokio::sync::mpsc::error::TrySendError; #[cfg(not(target_arch = "wasm32"))] -use tokio::time; +use tokio::time::{sleep, Sleep}; #[cfg(target_arch = "wasm32")] -use wasm_timer; +use wasmtimer::tokio::{sleep, Sleep}; pub struct LoopCoverTrafficStream where @@ -39,11 +39,7 @@ where /// Internal state, determined by `average_message_sending_delay`, /// used to keep track of when a next packet should be sent out. - #[cfg(not(target_arch = "wasm32"))] - next_delay: Pin>, - - #[cfg(target_arch = "wasm32")] - next_delay: Pin>, + next_delay: Pin>, /// Channel used for sending prepared nym packets to `MixTrafficController` that sends them /// out to the network without any further delays. @@ -90,17 +86,9 @@ where // The next interval value is `next_poisson_delay` after the one that just // yielded. - #[cfg(not(target_arch = "wasm32"))] - { - let now = self.next_delay.deadline(); - let next = now + next_poisson_delay; - self.next_delay.as_mut().reset(next); - } - - #[cfg(target_arch = "wasm32")] - { - self.next_delay.as_mut().reset(next_poisson_delay); - } + let now = self.next_delay.deadline(); + let next = now + next_poisson_delay; + self.next_delay.as_mut().reset(next); Poll::Ready(Some(())) } @@ -120,11 +108,7 @@ impl LoopCoverTrafficStream { ) -> Self { let rng = OsRng; - #[cfg(not(target_arch = "wasm32"))] - let next_delay = Box::pin(time::sleep(Default::default())); - - #[cfg(target_arch = "wasm32")] - let next_delay = Box::pin(wasm_timer::Delay::new(Default::default())); + let next_delay = Box::pin(sleep(Default::default())); LoopCoverTrafficStream { ack_key, @@ -142,12 +126,7 @@ impl LoopCoverTrafficStream { } fn set_next_delay(&mut self, amount: Duration) { - #[cfg(not(target_arch = "wasm32"))] - let next_delay = Box::pin(time::sleep(amount)); - - #[cfg(target_arch = "wasm32")] - let next_delay = Box::pin(wasm_timer::Delay::new(amount)); - + let next_delay = Box::pin(sleep(amount)); self.next_delay = next_delay; } diff --git a/common/client-core/src/client/helpers/wasm.rs b/common/client-core/src/client/helpers/wasm.rs index f04dd64028..5046463ee5 100644 --- a/common/client-core/src/client/helpers/wasm.rs +++ b/common/client-core/src/client/helpers/wasm.rs @@ -2,13 +2,12 @@ // SPDX-License-Identifier: Apache-2.0 use std::time::Duration; -use wasm_timer; -pub use wasm_timer::*; +pub use wasmtimer::{std::Instant, tokio::*}; pub type IntervalStream = gloo_timers::future::IntervalStream; pub(crate) fn get_time_now() -> Instant { - wasm_timer::Instant::now() + Instant::now() } pub(crate) fn new_interval_stream(polling_rate: Duration) -> IntervalStream { diff --git a/common/client-core/src/client/real_messages_control/real_traffic_stream.rs b/common/client-core/src/client/real_messages_control/real_traffic_stream.rs index 44c9810e70..a160a51894 100644 --- a/common/client-core/src/client/real_messages_control/real_traffic_stream.rs +++ b/common/client-core/src/client/real_messages_control/real_traffic_stream.rs @@ -27,9 +27,10 @@ use std::sync::Arc; use std::time::Duration; #[cfg(not(target_arch = "wasm32"))] -use tokio::time; +use tokio::time::{sleep, Sleep}; + #[cfg(target_arch = "wasm32")] -use wasm_timer; +use wasmtimer::tokio::{sleep, Sleep}; mod sending_delay_controller; @@ -82,11 +83,7 @@ where /// Internal state, determined by `average_message_sending_delay`, /// used to keep track of when a next packet should be sent out. - #[cfg(not(target_arch = "wasm32"))] - next_delay: Option>>, - - #[cfg(target_arch = "wasm32")] - next_delay: Option>>, + next_delay: Option>>, // To make sure we don't overload the mix_tx channel, we limit the rate we are pushing // messages. @@ -373,17 +370,9 @@ where // The next interval value is `next_poisson_delay` after the one that just // yielded. - #[cfg(not(target_arch = "wasm32"))] - { - let now = next_delay.deadline(); - let next = now + next_poisson_delay; - next_delay.as_mut().reset(next); - } - - #[cfg(target_arch = "wasm32")] - { - next_delay.as_mut().reset(next_poisson_delay); - } + let now = next_delay.deadline(); + let next = now + next_poisson_delay; + next_delay.as_mut().reset(next); // On every iteration we get new messages from upstream. Given that these come bunched // in `Vec`, this ensures that on average we will fetch messages faster than we can @@ -421,12 +410,7 @@ where self.config.traffic.message_sending_average_delay, ); - #[cfg(not(target_arch = "wasm32"))] - let next_delay = Box::pin(time::sleep(sampled)); - - #[cfg(target_arch = "wasm32")] - let next_delay = Box::pin(wasm_timer::Delay::new(sampled)); - + let next_delay = Box::pin(sleep(sampled)); self.next_delay = Some(next_delay); Poll::Pending diff --git a/common/client-core/src/init/helpers.rs b/common/client-core/src/init/helpers.rs index 1c23d562f9..723e9d02a2 100644 --- a/common/client-core/src/init/helpers.rs +++ b/common/client-core/src/init/helpers.rs @@ -27,13 +27,17 @@ use tokio_tungstenite::connect_async; use tokio_tungstenite::{MaybeTlsStream, WebSocketStream}; #[cfg(not(target_arch = "wasm32"))] type WsConn = WebSocketStream>; +#[cfg(not(target_arch = "wasm32"))] +use tokio::time::sleep; #[cfg(target_arch = "wasm32")] use nym_bandwidth_controller::wasm_mockups::DirectSigningNyxdClient; #[cfg(target_arch = "wasm32")] -use wasm_timer::Instant; -#[cfg(target_arch = "wasm32")] use wasm_utils::websocket::JSWebsocket; +#[cfg(target_arch = "wasm32")] +use wasmtimer::std::Instant; +#[cfg(target_arch = "wasm32")] +use wasmtimer::tokio::sleep; #[cfg(target_arch = "wasm32")] type WsConn = JSWebsocket; @@ -125,15 +129,9 @@ async fn measure_latency(gateway: &gateway::Node) -> Result(()) }; - // thanks to wasm we can't use tokio::time::timeout : ( - #[cfg(not(target_arch = "wasm32"))] - let timeout = tokio::time::sleep(PING_TIMEOUT); - #[cfg(not(target_arch = "wasm32"))] + let timeout = sleep(PING_TIMEOUT); tokio::pin!(timeout); - #[cfg(target_arch = "wasm32")] - let mut timeout = wasm_timer::Delay::new(PING_TIMEOUT); - tokio::select! { _ = &mut timeout => { warn!("timed out while trying to perform measurement...") diff --git a/common/client-libs/gateway-client/Cargo.toml b/common/client-libs/gateway-client/Cargo.toml index 20d5c958b0..197acdadef 100644 --- a/common/client-libs/gateway-client/Cargo.toml +++ b/common/client-libs/gateway-client/Cargo.toml @@ -58,9 +58,9 @@ path = "../../wasm-utils" features = ["websocket"] # only import it in wasm. Prefer proper tokio timer in non-wasm -[target."cfg(target_arch = \"wasm32\")".dependencies.wasm-timer] -git = "https://github.com/mmsinclair/wasm-timer" -rev = "b9d1a54ad514c2f230a026afe0dde341e98cd7b6" +[target."cfg(target_arch = \"wasm32\")".dependencies.wasmtimer] +workspace = true +features = ["tokio"] # this is due to tungstenite using `rand` 0.8 and associated changes in `getrandom` crate # which now does not support wasm32-unknown-unknown target by default. diff --git a/common/client-libs/gateway-client/src/client.rs b/common/client-libs/gateway-client/src/client.rs index a6ef774d8f..bdc2c626df 100644 --- a/common/client-libs/gateway-client/src/client.rs +++ b/common/client-libs/gateway-client/src/client.rs @@ -31,14 +31,16 @@ use tungstenite::protocol::Message; #[cfg(not(target_arch = "wasm32"))] use nym_validator_client::nyxd::traits::DkgQueryClient; #[cfg(not(target_arch = "wasm32"))] +use tokio::time::sleep; +#[cfg(not(target_arch = "wasm32"))] use tokio_tungstenite::connect_async; #[cfg(target_arch = "wasm32")] use nym_bandwidth_controller::wasm_mockups::DkgQueryClient; #[cfg(target_arch = "wasm32")] -use wasm_timer; -#[cfg(target_arch = "wasm32")] use wasm_utils::websocket::JSWebsocket; +#[cfg(target_arch = "wasm32")] +use wasmtimer::tokio::sleep; const DEFAULT_RECONNECTION_ATTEMPTS: usize = 10; const DEFAULT_RECONNECTION_BACKOFF: Duration = Duration::from_secs(5); @@ -198,15 +200,7 @@ impl GatewayClient { } #[cfg(not(target_arch = "wasm32"))] - tokio::time::sleep(self.reconnection_backoff).await; - - #[cfg(target_arch = "wasm32")] - if let Err(err) = wasm_timer::Delay::new(self.reconnection_backoff).await { - error!( - "the timer has gone away while in reconnection backoff! - {}", - err - ); - } + sleep(self.reconnection_backoff).await; } // final attempt (done separately to be able to return a proper error) @@ -235,16 +229,9 @@ impl GatewayClient { _ => return Err(GatewayClientError::ConnectionInInvalidState), }; - #[cfg(not(target_arch = "wasm32"))] - let timeout = tokio::time::sleep(self.response_timeout_duration); - #[cfg(not(target_arch = "wasm32"))] + let timeout = sleep(self.response_timeout_duration); tokio::pin!(timeout); - // technically the `wasm_timer` also works outside wasm, but unless required, - // I really prefer to just stick to tokio - #[cfg(target_arch = "wasm32")] - let mut timeout = wasm_timer::Delay::new(self.response_timeout_duration); - loop { tokio::select! { _ = self.shutdown.recv() => { diff --git a/common/nonexhaustive-delayqueue/Cargo.toml b/common/nonexhaustive-delayqueue/Cargo.toml index 975eb631fe..f79284dd50 100644 --- a/common/nonexhaustive-delayqueue/Cargo.toml +++ b/common/nonexhaustive-delayqueue/Cargo.toml @@ -7,16 +7,16 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -tokio = { version = "1.24.1", features = [] } tokio-stream = "0.1.11" # this one seems to be a thing until `Stream` trait is stabilised in stdlib -tokio-util = { version = "0.7.4", features = ["time"] } -[target."cfg(target_arch = \"wasm32\")".dependencies.wasm-timer] -git = "https://github.com/mmsinclair/wasm-timer" -rev = "b9d1a54ad514c2f230a026afe0dde341e98cd7b6" +[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio] +workspace = true -[target."cfg(target_arch = \"wasm32\")".dependencies.slab] -version = "0.4.4" +[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio-util] +version = "0.7.4" +features = ["time"] + +[target."cfg(target_arch = \"wasm32\")".dependencies.wasmtimer] +workspace = true +features = ["tokio", "tokio-util"] -[target."cfg(target_arch = \"wasm32\")".dependencies.futures-core] -version = "0.3.0" diff --git a/common/nonexhaustive-delayqueue/src/lib.rs b/common/nonexhaustive-delayqueue/src/lib.rs index 4e2329db2b..ee8c9f214c 100644 --- a/common/nonexhaustive-delayqueue/src/lib.rs +++ b/common/nonexhaustive-delayqueue/src/lib.rs @@ -6,12 +6,8 @@ use std::task::{Context, Poll, Waker}; use std::time::Duration; use tokio_stream::Stream; -pub use tokio::time::error::Error as TimerError; - // this is a copy of tokio-util delay_queue with `Sleep` and `Instant` being replaced with // `wasm_timer` equivalents -#[cfg(target_arch = "wasm32")] -mod wasm_delay_queue; #[cfg(not(target_arch = "wasm32"))] type DelayQueue = tokio_util::time::DelayQueue; @@ -23,13 +19,13 @@ pub type QueueKey = tokio_util::time::delay_queue::Key; use tokio::time::Instant; #[cfg(target_arch = "wasm32")] -type DelayQueue = crate::wasm_delay_queue::DelayQueue; +type DelayQueue = wasmtimer::tokio_util::DelayQueue; #[cfg(target_arch = "wasm32")] -pub use crate::wasm_delay_queue::delay_queue::Expired; +pub use wasmtimer::tokio_util::delay_queue::Expired; #[cfg(target_arch = "wasm32")] -pub type QueueKey = crate::wasm_delay_queue::delay_queue::Key; +pub type QueueKey = wasmtimer::tokio_util::delay_queue::Key; #[cfg(target_arch = "wasm32")] -use wasm_timer::Instant; +use wasmtimer::std::Instant; /// A variant of tokio's `DelayQueue`, such that its `Stream` implementation will never return a 'None'. pub struct NonExhaustiveDelayQueue { diff --git a/common/nonexhaustive-delayqueue/src/wasm_delay_queue/delay_queue.rs b/common/nonexhaustive-delayqueue/src/wasm_delay_queue/delay_queue.rs deleted file mode 100644 index 6d18b7b12d..0000000000 --- a/common/nonexhaustive-delayqueue/src/wasm_delay_queue/delay_queue.rs +++ /dev/null @@ -1,1234 +0,0 @@ -//! A queue of delayed elements. -//! -//! See [`DelayQueue`] for more details. -//! -//! [`DelayQueue`]: struct@DelayQueue - -use crate::wasm_delay_queue::sleep_until; -use crate::wasm_delay_queue::wheel::{self, Wheel}; -use core::ops::{Index, IndexMut}; -use futures_core::{ready, Future}; -use slab::Slab; -use std::cmp; -use std::collections::HashMap; -use std::convert::From; -use std::fmt; -use std::fmt::Debug; -use std::marker::PhantomData; -use std::pin::Pin; -use std::task::{self, Poll, Waker}; -use std::time::Duration; -use wasm_timer::{Delay, Instant}; - -/// A queue of delayed elements. -/// -/// Once an element is inserted into the `DelayQueue`, it is yielded once the -/// specified deadline has been reached. -/// -/// # Usage -/// -/// Elements are inserted into `DelayQueue` using the [`insert`] or -/// [`insert_at`] methods. A deadline is provided with the item and a [`Key`] is -/// returned. The key is used to remove the entry or to change the deadline at -/// which it should be yielded back. -/// -/// Once delays have been configured, the `DelayQueue` is used via its -/// [`Stream`] implementation. [`poll_expired`] is called. If an entry has reached its -/// deadline, it is returned. If not, `Poll::Pending` is returned indicating that the -/// current task will be notified once the deadline has been reached. -/// -/// # `Stream` implementation -/// -/// Items are retrieved from the queue via [`DelayQueue::poll_expired`]. If no delays have -/// expired, no items are returned. In this case, `Poll::Pending` is returned and the -/// current task is registered to be notified once the next item's delay has -/// expired. -/// -/// If no items are in the queue, i.e. `is_empty()` returns `true`, then `poll` -/// returns `Poll::Ready(None)`. This indicates that the stream has reached an end. -/// However, if a new item is inserted *after*, `poll` will once again start -/// returning items or `Poll::Pending`. -/// -/// Items are returned ordered by their expirations. Items that are configured -/// to expire first will be returned first. There are no ordering guarantees -/// for items configured to expire at the same instant. Also note that delays are -/// rounded to the closest millisecond. -/// -/// # Implementation -/// -/// The [`DelayQueue`] is backed by a separate instance of a timer wheel similar to that used internally -/// by Tokio's standalone timer utilities such as [`sleep`]. Because of this, it offers the same -/// performance and scalability benefits. -/// -/// State associated with each entry is stored in a [`slab`]. This amortizes the cost of allocation, -/// and allows reuse of the memory allocated for expired entires. -/// -/// Capacity can be checked using [`capacity`] and allocated preemptively by using -/// the [`reserve`] method. -/// -/// # Usage -/// -/// Using `DelayQueue` to manage cache entries. -/// -/// ```rust,no_run -/// use tokio_util::time::{DelayQueue, delay_queue}; -/// -/// use futures::ready; -/// use std::collections::HashMap; -/// use std::task::{Context, Poll}; -/// use std::time::Duration; -/// # type CacheKey = String; -/// # type Value = String; -/// -/// struct Cache { -/// entries: HashMap, -/// expirations: DelayQueue, -/// } -/// -/// const TTL_SECS: u64 = 30; -/// -/// impl Cache { -/// fn insert(&mut self, key: CacheKey, value: Value) { -/// let delay = self.expirations -/// .insert(key.clone(), Duration::from_secs(TTL_SECS)); -/// -/// self.entries.insert(key, (value, delay)); -/// } -/// -/// fn get(&self, key: &CacheKey) -> Option<&Value> { -/// self.entries.get(key) -/// .map(|&(ref v, _)| v) -/// } -/// -/// fn remove(&mut self, key: &CacheKey) { -/// if let Some((_, cache_key)) = self.entries.remove(key) { -/// self.expirations.remove(&cache_key); -/// } -/// } -/// -/// fn poll_purge(&mut self, cx: &mut Context<'_>) -> Poll<()> { -/// while let Some(entry) = ready!(self.expirations.poll_expired(cx)) { -/// self.entries.remove(entry.get_ref()); -/// } -/// -/// Poll::Ready(()) -/// } -/// } -/// ``` -/// -/// [`insert`]: method@Self::insert -/// [`insert_at`]: method@Self::insert_at -/// [`Key`]: struct@Key -/// [`Stream`]: https://docs.rs/futures/0.1/futures/stream/trait.Stream.html -/// [`poll_expired`]: method@Self::poll_expired -/// [`Stream::poll_expired`]: method@Self::poll_expired -/// [`DelayQueue`]: struct@DelayQueue -/// [`sleep`]: fn@tokio::time::sleep -/// [`slab`]: slab -/// [`capacity`]: method@Self::capacity -/// [`reserve`]: method@Self::reserve -#[derive(Debug)] -pub struct DelayQueue { - /// Stores data associated with entries - slab: SlabStorage, - - /// Lookup structure tracking all delays in the queue - wheel: Wheel>, - - /// Delays that were inserted when already expired. These cannot be stored - /// in the wheel - expired: Stack, - - /// Delay expiring when the *first* item in the queue expires - delay: Option>>, - - /// Wheel polling state - wheel_now: u64, - - /// Instant at which the timer starts - start: Instant, - - /// Waker that is invoked when we potentially need to reset the timer. - /// Because we lazily create the timer when the first entry is created, we - /// need to awaken any poller that polled us before that point. - waker: Option, -} - -#[derive(Default)] -struct SlabStorage { - inner: Slab>, - - // A `compact` call requires a re-mapping of the `Key`s that were changed - // during the `compact` call of the `slab`. Since the keys that were given out - // cannot be changed retroactively we need to keep track of these re-mappings. - // The keys of `key_map` correspond to the old keys that were given out and - // the values to the `Key`s that were re-mapped by the `compact` call. - key_map: HashMap, - - // Index used to create new keys to hand out. - next_key_index: usize, - - // Whether `compact` has been called, necessary in order to decide whether - // to include keys in `key_map`. - compact_called: bool, -} - -impl SlabStorage { - pub(crate) fn with_capacity(capacity: usize) -> SlabStorage { - SlabStorage { - inner: Slab::with_capacity(capacity), - key_map: HashMap::new(), - next_key_index: 0, - compact_called: false, - } - } - - // Inserts data into the inner slab and re-maps keys if necessary - pub(crate) fn insert(&mut self, val: Data) -> Key { - let mut key = KeyInternal::new(self.inner.insert(val)); - let key_contained = self.key_map.contains_key(&key.into()); - - if key_contained { - // It's possible that a `compact` call creates capacity in `self.inner` in - // such a way that a `self.inner.insert` call creates a `key` which was - // previously given out during an `insert` call prior to the `compact` call. - // If `key` is contained in `self.key_map`, we have encountered this exact situation, - // We need to create a new key `key_to_give_out` and include the relation - // `key_to_give_out` -> `key` in `self.key_map`. - let key_to_give_out = self.create_new_key(); - assert!(!self.key_map.contains_key(&key_to_give_out.into())); - self.key_map.insert(key_to_give_out.into(), key); - key = key_to_give_out; - } else if self.compact_called { - // Include an identity mapping in `self.key_map` in order to allow us to - // panic if a key that was handed out is removed more than once. - self.key_map.insert(key.into(), key); - } - - key.into() - } - - // Re-map the key in case compact was previously called. - // Note: Since we include identity mappings in key_map after compact was called, - // we have information about all keys that were handed out. In the case in which - // compact was called and we try to remove a Key that was previously removed - // we can detect invalid keys if no key is found in `key_map`. This is necessary - // in order to prevent situations in which a previously removed key - // corresponds to a re-mapped key internally and which would then be incorrectly - // removed from the slab. - // - // Example to illuminate this problem: - // - // Let's assume our `key_map` is {1 -> 2, 2 -> 1} and we call remove(1). If we - // were to remove 1 again, we would not find it inside `key_map` anymore. - // If we were to imply from this that no re-mapping was necessary, we would - // incorrectly remove 1 from `self.slab.inner`, which corresponds to the - // handed-out key 2. - pub(crate) fn remove(&mut self, key: &Key) -> Data { - let remapped_key = if self.compact_called { - match self.key_map.remove(key) { - Some(key_internal) => key_internal, - None => panic!("invalid key"), - } - } else { - (*key).into() - }; - - self.inner.remove(remapped_key.index) - } - - pub(crate) fn shrink_to_fit(&mut self) { - self.inner.shrink_to_fit(); - self.key_map.shrink_to_fit(); - } - - pub(crate) fn compact(&mut self) { - if !self.compact_called { - for (key, _) in self.inner.iter() { - self.key_map.insert(Key::new(key), KeyInternal::new(key)); - } - } - - let mut remapping = HashMap::new(); - self.inner.compact(|_, from, to| { - remapping.insert(from, to); - true - }); - - // At this point `key_map` contains a mapping for every element. - for internal_key in self.key_map.values_mut() { - if let Some(new_internal_key) = remapping.get(&internal_key.index) { - *internal_key = KeyInternal::new(*new_internal_key); - } - } - - if self.key_map.capacity() > 2 * self.key_map.len() { - self.key_map.shrink_to_fit(); - } - - self.compact_called = true; - } - - // Tries to re-map a `Key` that was given out to the user to its - // corresponding internal key. - fn remap_key(&self, key: &Key) -> Option { - let key_map = &self.key_map; - if self.compact_called { - key_map.get(&*key).copied() - } else { - Some((*key).into()) - } - } - - fn create_new_key(&mut self) -> KeyInternal { - while self.key_map.contains_key(&Key::new(self.next_key_index)) { - self.next_key_index = self.next_key_index.wrapping_add(1); - } - - KeyInternal::new(self.next_key_index) - } - - pub(crate) fn len(&self) -> usize { - self.inner.len() - } - - pub(crate) fn capacity(&self) -> usize { - self.inner.capacity() - } - - pub(crate) fn clear(&mut self) { - self.inner.clear(); - self.key_map.clear(); - self.compact_called = false; - } - - pub(crate) fn reserve(&mut self, additional: usize) { - self.inner.reserve(additional); - - if self.compact_called { - self.key_map.reserve(additional); - } - } - - pub(crate) fn is_empty(&self) -> bool { - self.inner.is_empty() - } - - pub(crate) fn contains(&self, key: &Key) -> bool { - let remapped_key = self.remap_key(key); - - match remapped_key { - Some(internal_key) => self.inner.contains(internal_key.index), - None => false, - } - } -} - -impl fmt::Debug for SlabStorage -where - T: fmt::Debug, -{ - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - if fmt.alternate() { - fmt.debug_map().entries(self.inner.iter()).finish() - } else { - fmt.debug_struct("Slab") - .field("len", &self.len()) - .field("cap", &self.capacity()) - .finish() - } - } -} - -impl Index for SlabStorage { - type Output = Data; - - fn index(&self, key: Key) -> &Self::Output { - let remapped_key = self.remap_key(&key); - - match remapped_key { - Some(internal_key) => &self.inner[internal_key.index], - None => panic!("Invalid index {}", key.index), - } - } -} - -impl IndexMut for SlabStorage { - fn index_mut(&mut self, key: Key) -> &mut Data { - let remapped_key = self.remap_key(&key); - - match remapped_key { - Some(internal_key) => &mut self.inner[internal_key.index], - None => panic!("Invalid index {}", key.index), - } - } -} - -/// An entry in `DelayQueue` that has expired and been removed. -/// -/// Values are returned by [`DelayQueue::poll_expired`]. -/// -/// [`DelayQueue::poll_expired`]: method@DelayQueue::poll_expired -#[derive(Debug)] -pub struct Expired { - /// The data stored in the queue - data: T, - - /// The expiration time - deadline: Instant, - - /// The key associated with the entry - key: Key, -} - -/// Token to a value stored in a `DelayQueue`. -/// -/// Instances of `Key` are returned by [`DelayQueue::insert`]. See [`DelayQueue`] -/// documentation for more details. -/// -/// [`DelayQueue`]: struct@DelayQueue -/// [`DelayQueue::insert`]: method@DelayQueue::insert -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct Key { - index: usize, -} - -// Whereas `Key` is given out to users that use `DelayQueue`, internally we use -// `KeyInternal` as the key type in order to make the logic of mapping between keys -// as a result of `compact` calls clearer. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -struct KeyInternal { - index: usize, -} - -#[derive(Debug)] -struct Stack { - /// Head of the stack - head: Option, - _p: PhantomData T>, -} - -#[derive(Debug)] -struct Data { - /// The data being stored in the queue and will be returned at the requested - /// instant. - inner: T, - - /// The instant at which the item is returned. - when: u64, - - /// Set to true when stored in the `expired` queue - expired: bool, - - /// Next entry in the stack - next: Option, - - /// Previous entry in the stack - prev: Option, -} - -/// Maximum number of entries the queue can handle -const MAX_ENTRIES: usize = (1 << 30) - 1; - -impl DelayQueue { - /// Creates a new, empty, `DelayQueue`. - /// - /// The queue will not allocate storage until items are inserted into it. - /// - /// # Examples - /// - /// ```rust - /// # use tokio_util::time::DelayQueue; - /// let delay_queue: DelayQueue = DelayQueue::new(); - /// ``` - pub fn new() -> DelayQueue { - DelayQueue::with_capacity(0) - } - - /// Creates a new, empty, `DelayQueue` with the specified capacity. - /// - /// The queue will be able to hold at least `capacity` elements without - /// reallocating. If `capacity` is 0, the queue will not allocate for - /// storage. - /// - /// # Examples - /// - /// ```rust - /// # use tokio_util::time::DelayQueue; - /// # use std::time::Duration; - /// - /// # #[tokio::main] - /// # async fn main() { - /// let mut delay_queue = DelayQueue::with_capacity(10); - /// - /// // These insertions are done without further allocation - /// for i in 0..10 { - /// delay_queue.insert(i, Duration::from_secs(i)); - /// } - /// - /// // This will make the queue allocate additional storage - /// delay_queue.insert(11, Duration::from_secs(11)); - /// # } - /// ``` - pub fn with_capacity(capacity: usize) -> DelayQueue { - DelayQueue { - wheel: Wheel::new(), - slab: SlabStorage::with_capacity(capacity), - expired: Stack::default(), - delay: None, - wheel_now: 0, - start: Instant::now(), - waker: None, - } - } - - /// Inserts `value` into the queue set to expire at a specific instant in - /// time. - /// - /// This function is identical to `insert`, but takes an `Instant` instead - /// of a `Duration`. - /// - /// `value` is stored in the queue until `when` is reached. At which point, - /// `value` will be returned from [`poll_expired`]. If `when` has already been - /// reached, then `value` is immediately made available to poll. - /// - /// The return value represents the insertion and is used as an argument to - /// [`remove`] and [`reset`]. Note that [`Key`] is a token and is reused once - /// `value` is removed from the queue either by calling [`poll_expired`] after - /// `when` is reached or by calling [`remove`]. At this point, the caller - /// must take care to not use the returned [`Key`] again as it may reference - /// a different item in the queue. - /// - /// See [type] level documentation for more details. - /// - /// # Panics - /// - /// This function panics if `when` is too far in the future. - /// - /// # Examples - /// - /// Basic usage - /// - /// ```rust - /// use tokio::time::{Duration, Instant}; - /// use tokio_util::time::DelayQueue; - /// - /// # #[tokio::main] - /// # async fn main() { - /// let mut delay_queue = DelayQueue::new(); - /// let key = delay_queue.insert_at( - /// "foo", Instant::now() + Duration::from_secs(5)); - /// - /// // Remove the entry - /// let item = delay_queue.remove(&key); - /// assert_eq!(*item.get_ref(), "foo"); - /// # } - /// ``` - /// - /// [`poll_expired`]: method@Self::poll_expired - /// [`remove`]: method@Self::remove - /// [`reset`]: method@Self::reset - /// [`Key`]: struct@Key - /// [type]: # - #[track_caller] - pub fn insert_at(&mut self, value: T, when: Instant) -> Key { - assert!(self.slab.len() < MAX_ENTRIES, "max entries exceeded"); - - // Normalize the deadline. Values cannot be set to expire in the past. - let when = self.normalize_deadline(when); - - // Insert the value in the store - let key = self.slab.insert(Data { - inner: value, - when, - expired: false, - next: None, - prev: None, - }); - - self.insert_idx(when, key); - - // Set a new delay if the current's deadline is later than the one of the new item - let should_set_delay = if let Some(ref delay) = self.delay { - let current_exp = self.normalize_deadline(delay.deadline()); - current_exp > when - } else { - true - }; - - if should_set_delay { - if let Some(waker) = self.waker.take() { - waker.wake(); - } - - let delay_time = self.start + Duration::from_millis(when); - if let Some(ref mut delay) = &mut self.delay { - delay.as_mut().reset_at(delay_time); - } else { - self.delay = Some(Box::pin(sleep_until(delay_time))); - } - } - - key - } - - /// Attempts to pull out the next value of the delay queue, registering the - /// current task for wakeup if the value is not yet available, and returning - /// `None` if the queue is exhausted. - pub fn poll_expired(&mut self, cx: &mut task::Context<'_>) -> Poll>> { - if !self - .waker - .as_ref() - .map(|w| w.will_wake(cx.waker())) - .unwrap_or(false) - { - self.waker = Some(cx.waker().clone()); - } - - let item = ready!(self.poll_idx(cx)); - Poll::Ready(item.map(|key| { - let data = self.slab.remove(&key); - debug_assert!(data.next.is_none()); - debug_assert!(data.prev.is_none()); - - Expired { - key, - data: data.inner, - deadline: self.start + Duration::from_millis(data.when), - } - })) - } - - /// Inserts `value` into the queue set to expire after the requested duration - /// elapses. - /// - /// This function is identical to `insert_at`, but takes a `Duration` - /// instead of an `Instant`. - /// - /// `value` is stored in the queue until `timeout` duration has - /// elapsed after `insert` was called. At that point, `value` will - /// be returned from [`poll_expired`]. If `timeout` is a `Duration` of - /// zero, then `value` is immediately made available to poll. - /// - /// The return value represents the insertion and is used as an - /// argument to [`remove`] and [`reset`]. Note that [`Key`] is a - /// token and is reused once `value` is removed from the queue - /// either by calling [`poll_expired`] after `timeout` has elapsed - /// or by calling [`remove`]. At this point, the caller must not - /// use the returned [`Key`] again as it may reference a different - /// item in the queue. - /// - /// See [type] level documentation for more details. - /// - /// # Panics - /// - /// This function panics if `timeout` is greater than the maximum - /// duration supported by the timer in the current `Runtime`. - /// - /// # Examples - /// - /// Basic usage - /// - /// ```rust - /// use tokio_util::time::DelayQueue; - /// use std::time::Duration; - /// - /// # #[tokio::main] - /// # async fn main() { - /// let mut delay_queue = DelayQueue::new(); - /// let key = delay_queue.insert("foo", Duration::from_secs(5)); - /// - /// // Remove the entry - /// let item = delay_queue.remove(&key); - /// assert_eq!(*item.get_ref(), "foo"); - /// # } - /// ``` - /// - /// [`poll_expired`]: method@Self::poll_expired - /// [`remove`]: method@Self::remove - /// [`reset`]: method@Self::reset - /// [`Key`]: struct@Key - /// [type]: # - #[track_caller] - pub fn insert(&mut self, value: T, timeout: Duration) -> Key { - self.insert_at(value, Instant::now() + timeout) - } - - #[track_caller] - fn insert_idx(&mut self, when: u64, key: Key) { - use self::wheel::{InsertError, Stack}; - - // Register the deadline with the timer wheel - match self.wheel.insert(when, key, &mut self.slab) { - Ok(_) => {} - Err((_, InsertError::Elapsed)) => { - self.slab[key].expired = true; - // The delay is already expired, store it in the expired queue - self.expired.push(key, &mut self.slab); - } - Err((_, err)) => panic!("invalid deadline; err={:?}", err), - } - } - - /// Removes the key from the expired queue or the timer wheel - /// depending on its expiration status. - /// - /// # Panics - /// - /// Panics if the key is not contained in the expired queue or the wheel. - #[track_caller] - fn remove_key(&mut self, key: &Key) { - use crate::wasm_delay_queue::wheel::Stack; - - // Special case the `expired` queue - if self.slab[*key].expired { - self.expired.remove(key, &mut self.slab); - } else { - self.wheel.remove(key, &mut self.slab); - } - } - - /// Removes the item associated with `key` from the queue. - /// - /// There must be an item associated with `key`. The function returns the - /// removed item as well as the `Instant` at which it will the delay will - /// have expired. - /// - /// # Panics - /// - /// The function panics if `key` is not contained by the queue. - /// - /// # Examples - /// - /// Basic usage - /// - /// ```rust - /// use tokio_util::time::DelayQueue; - /// use std::time::Duration; - /// - /// # #[tokio::main] - /// # async fn main() { - /// let mut delay_queue = DelayQueue::new(); - /// let key = delay_queue.insert("foo", Duration::from_secs(5)); - /// - /// // Remove the entry - /// let item = delay_queue.remove(&key); - /// assert_eq!(*item.get_ref(), "foo"); - /// # } - /// ``` - #[track_caller] - pub fn remove(&mut self, key: &Key) -> Expired { - let prev_deadline = self.next_deadline(); - - self.remove_key(key); - let data = self.slab.remove(key); - - let next_deadline = self.next_deadline(); - if prev_deadline != next_deadline { - match (next_deadline, &mut self.delay) { - (None, _) => self.delay = None, - (Some(deadline), Some(delay)) => delay.as_mut().reset_at(deadline), - (Some(deadline), None) => self.delay = Some(Box::pin(sleep_until(deadline))), - } - } - - Expired { - key: Key::new(key.index), - data: data.inner, - deadline: self.start + Duration::from_millis(data.when), - } - } - - /// Sets the delay of the item associated with `key` to expire at `when`. - /// - /// This function is identical to `reset` but takes an `Instant` instead of - /// a `Duration`. - /// - /// The item remains in the queue but the delay is set to expire at `when`. - /// If `when` is in the past, then the item is immediately made available to - /// the caller. - /// - /// # Panics - /// - /// This function panics if `when` is too far in the future or if `key` is - /// not contained by the queue. - /// - /// # Examples - /// - /// Basic usage - /// - /// ```rust - /// use tokio::time::{Duration, Instant}; - /// use tokio_util::time::DelayQueue; - /// - /// # #[tokio::main] - /// # async fn main() { - /// let mut delay_queue = DelayQueue::new(); - /// let key = delay_queue.insert("foo", Duration::from_secs(5)); - /// - /// // "foo" is scheduled to be returned in 5 seconds - /// - /// delay_queue.reset_at(&key, Instant::now() + Duration::from_secs(10)); - /// - /// // "foo" is now scheduled to be returned in 10 seconds - /// # } - /// ``` - #[track_caller] - pub fn reset_at(&mut self, key: &Key, when: Instant) { - self.remove_key(key); - - // Normalize the deadline. Values cannot be set to expire in the past. - let when = self.normalize_deadline(when); - - self.slab[*key].when = when; - self.slab[*key].expired = false; - - self.insert_idx(when, *key); - - let next_deadline = self.next_deadline(); - if let (Some(ref mut delay), Some(deadline)) = (&mut self.delay, next_deadline) { - // This should awaken us if necessary (ie, if already expired) - delay.as_mut().reset_at(deadline); - } - } - - /// Shrink the capacity of the slab, which `DelayQueue` uses internally for storage allocation. - /// This function is not guaranteed to, and in most cases, won't decrease the capacity of the slab - /// to the number of elements still contained in it, because elements cannot be moved to a different - /// index. To decrease the capacity to the size of the slab use [`compact`]. - /// - /// This function can take O(n) time even when the capacity cannot be reduced or the allocation is - /// shrunk in place. Repeated calls run in O(1) though. - /// - /// [`compact`]: method@Self::compact - pub fn shrink_to_fit(&mut self) { - self.slab.shrink_to_fit(); - } - - /// Shrink the capacity of the slab, which `DelayQueue` uses internally for storage allocation, - /// to the number of elements that are contained in it. - /// - /// This methods runs in O(n). - /// - /// # Examples - /// - /// Basic usage - /// - /// ```rust - /// use tokio_util::time::DelayQueue; - /// use std::time::Duration; - /// - /// # #[tokio::main] - /// # async fn main() { - /// let mut delay_queue = DelayQueue::with_capacity(10); - /// - /// let key1 = delay_queue.insert(5, Duration::from_secs(5)); - /// let key2 = delay_queue.insert(10, Duration::from_secs(10)); - /// let key3 = delay_queue.insert(15, Duration::from_secs(15)); - /// - /// delay_queue.remove(&key2); - /// - /// delay_queue.compact(); - /// assert_eq!(delay_queue.capacity(), 2); - /// # } - /// ``` - pub fn compact(&mut self) { - self.slab.compact(); - } - - /// Returns the next time to poll as determined by the wheel - fn next_deadline(&mut self) -> Option { - self.wheel - .poll_at() - .map(|poll_at| self.start + Duration::from_millis(poll_at)) - } - - /// Sets the delay of the item associated with `key` to expire after - /// `timeout`. - /// - /// This function is identical to `reset_at` but takes a `Duration` instead - /// of an `Instant`. - /// - /// The item remains in the queue but the delay is set to expire after - /// `timeout`. If `timeout` is zero, then the item is immediately made - /// available to the caller. - /// - /// # Panics - /// - /// This function panics if `timeout` is greater than the maximum supported - /// duration or if `key` is not contained by the queue. - /// - /// # Examples - /// - /// Basic usage - /// - /// ```rust - /// use tokio_util::time::DelayQueue; - /// use std::time::Duration; - /// - /// # #[tokio::main] - /// # async fn main() { - /// let mut delay_queue = DelayQueue::new(); - /// let key = delay_queue.insert("foo", Duration::from_secs(5)); - /// - /// // "foo" is scheduled to be returned in 5 seconds - /// - /// delay_queue.reset(&key, Duration::from_secs(10)); - /// - /// // "foo"is now scheduled to be returned in 10 seconds - /// # } - /// ``` - #[track_caller] - pub fn reset(&mut self, key: &Key, timeout: Duration) { - self.reset_at(key, Instant::now() + timeout); - } - - /// Clears the queue, removing all items. - /// - /// After calling `clear`, [`poll_expired`] will return `Ok(Ready(None))`. - /// - /// Note that this method has no effect on the allocated capacity. - /// - /// [`poll_expired`]: method@Self::poll_expired - /// - /// # Examples - /// - /// ```rust - /// use tokio_util::time::DelayQueue; - /// use std::time::Duration; - /// - /// # #[tokio::main] - /// # async fn main() { - /// let mut delay_queue = DelayQueue::new(); - /// - /// delay_queue.insert("foo", Duration::from_secs(5)); - /// - /// assert!(!delay_queue.is_empty()); - /// - /// delay_queue.clear(); - /// - /// assert!(delay_queue.is_empty()); - /// # } - /// ``` - pub fn clear(&mut self) { - self.slab.clear(); - self.expired = Stack::default(); - self.wheel = Wheel::new(); - self.delay = None; - } - - /// Returns the number of elements the queue can hold without reallocating. - /// - /// # Examples - /// - /// ```rust - /// use tokio_util::time::DelayQueue; - /// - /// let delay_queue: DelayQueue = DelayQueue::with_capacity(10); - /// assert_eq!(delay_queue.capacity(), 10); - /// ``` - pub fn capacity(&self) -> usize { - self.slab.capacity() - } - - /// Returns the number of elements currently in the queue. - /// - /// # Examples - /// - /// ```rust - /// use tokio_util::time::DelayQueue; - /// use std::time::Duration; - /// - /// # #[tokio::main] - /// # async fn main() { - /// let mut delay_queue: DelayQueue = DelayQueue::with_capacity(10); - /// assert_eq!(delay_queue.len(), 0); - /// delay_queue.insert(3, Duration::from_secs(5)); - /// assert_eq!(delay_queue.len(), 1); - /// # } - /// ``` - pub fn len(&self) -> usize { - self.slab.len() - } - - /// Reserves capacity for at least `additional` more items to be queued - /// without allocating. - /// - /// `reserve` does nothing if the queue already has sufficient capacity for - /// `additional` more values. If more capacity is required, a new segment of - /// memory will be allocated and all existing values will be copied into it. - /// As such, if the queue is already very large, a call to `reserve` can end - /// up being expensive. - /// - /// The queue may reserve more than `additional` extra space in order to - /// avoid frequent reallocations. - /// - /// # Panics - /// - /// Panics if the new capacity exceeds the maximum number of entries the - /// queue can contain. - /// - /// # Examples - /// - /// ``` - /// use tokio_util::time::DelayQueue; - /// use std::time::Duration; - /// - /// # #[tokio::main] - /// # async fn main() { - /// let mut delay_queue = DelayQueue::new(); - /// - /// delay_queue.insert("hello", Duration::from_secs(10)); - /// delay_queue.reserve(10); - /// - /// assert!(delay_queue.capacity() >= 11); - /// # } - /// ``` - #[track_caller] - pub fn reserve(&mut self, additional: usize) { - assert!( - self.slab.capacity() + additional <= MAX_ENTRIES, - "max queue capacity exceeded" - ); - self.slab.reserve(additional); - } - - /// Returns `true` if there are no items in the queue. - /// - /// Note that this function returns `false` even if all items have not yet - /// expired and a call to `poll` will return `Poll::Pending`. - /// - /// # Examples - /// - /// ``` - /// use tokio_util::time::DelayQueue; - /// use std::time::Duration; - /// - /// # #[tokio::main] - /// # async fn main() { - /// let mut delay_queue = DelayQueue::new(); - /// assert!(delay_queue.is_empty()); - /// - /// delay_queue.insert("hello", Duration::from_secs(5)); - /// assert!(!delay_queue.is_empty()); - /// # } - /// ``` - pub fn is_empty(&self) -> bool { - self.slab.is_empty() - } - - /// Polls the queue, returning the index of the next slot in the slab that - /// should be returned. - /// - /// A slot should be returned when the associated deadline has been reached. - fn poll_idx(&mut self, cx: &mut task::Context<'_>) -> Poll> { - use self::wheel::Stack; - - let expired = self.expired.pop(&mut self.slab); - - if expired.is_some() { - return Poll::Ready(expired); - } - - loop { - if let Some(ref mut delay) = self.delay { - ready!(Pin::new(&mut *delay).poll(cx)).ok(); - - let now = crate::wasm_delay_queue::ms( - delay.deadline() - self.start, - crate::wasm_delay_queue::Round::Down, - ); - - self.wheel_now = now; - } - - // We poll the wheel to get the next value out before finding the next deadline. - let wheel_idx = self.wheel.poll(self.wheel_now, &mut self.slab); - - self.delay = self.next_deadline().map(|when| Box::pin(sleep_until(when))); - - if let Some(idx) = wheel_idx { - return Poll::Ready(Some(idx)); - } - - if self.delay.is_none() { - return Poll::Ready(None); - } - } - } - - fn normalize_deadline(&self, when: Instant) -> u64 { - let when = if when < self.start { - 0 - } else { - crate::wasm_delay_queue::ms(when - self.start, crate::wasm_delay_queue::Round::Up) - }; - - cmp::max(when, self.wheel.elapsed()) - } -} - -// We never put `T` in a `Pin`... -impl Unpin for DelayQueue {} - -impl Default for DelayQueue { - fn default() -> DelayQueue { - DelayQueue::new() - } -} - -impl futures_core::Stream for DelayQueue { - // DelayQueue seems much more specific, where a user may care that it - // has reached capacity, so return those errors instead of panicking. - type Item = Expired; - - fn poll_next(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll> { - DelayQueue::poll_expired(self.get_mut(), cx) - } -} - -impl wheel::Stack for Stack { - type Owned = Key; - type Borrowed = Key; - type Store = SlabStorage; - - fn is_empty(&self) -> bool { - self.head.is_none() - } - - fn push(&mut self, item: Self::Owned, store: &mut Self::Store) { - // Ensure the entry is not already in a stack. - debug_assert!(store[item].next.is_none()); - debug_assert!(store[item].prev.is_none()); - - // Remove the old head entry - let old = self.head.take(); - - if let Some(idx) = old { - store[idx].prev = Some(item); - } - - store[item].next = old; - self.head = Some(item); - } - - fn pop(&mut self, store: &mut Self::Store) -> Option { - if let Some(key) = self.head { - self.head = store[key].next; - - if let Some(idx) = self.head { - store[idx].prev = None; - } - - store[key].next = None; - debug_assert!(store[key].prev.is_none()); - - Some(key) - } else { - None - } - } - - #[track_caller] - fn remove(&mut self, item: &Self::Borrowed, store: &mut Self::Store) { - let key = *item; - assert!(store.contains(item)); - - // Ensure that the entry is in fact contained by the stack - debug_assert!({ - // This walks the full linked list even if an entry is found. - let mut next = self.head; - let mut contains = false; - - while let Some(idx) = next { - let data = &store[idx]; - - if idx == *item { - debug_assert!(!contains); - contains = true; - } - - next = data.next; - } - - contains - }); - - if let Some(next) = store[key].next { - store[next].prev = store[key].prev; - } - - if let Some(prev) = store[key].prev { - store[prev].next = store[key].next; - } else { - self.head = store[key].next; - } - - store[key].next = None; - store[key].prev = None; - } - - fn when(item: &Self::Borrowed, store: &Self::Store) -> u64 { - store[*item].when - } -} - -impl Default for Stack { - fn default() -> Stack { - Stack { - head: None, - _p: PhantomData, - } - } -} - -impl Key { - pub(crate) fn new(index: usize) -> Key { - Key { index } - } -} - -impl KeyInternal { - pub(crate) fn new(index: usize) -> KeyInternal { - KeyInternal { index } - } -} - -impl From for KeyInternal { - fn from(item: Key) -> Self { - KeyInternal::new(item.index) - } -} - -impl From for Key { - fn from(item: KeyInternal) -> Self { - Key::new(item.index) - } -} - -impl Expired { - /// Returns a reference to the inner value. - pub fn get_ref(&self) -> &T { - &self.data - } - - /// Returns a mutable reference to the inner value. - pub fn get_mut(&mut self) -> &mut T { - &mut self.data - } - - /// Consumes `self` and returns the inner value. - pub fn into_inner(self) -> T { - self.data - } - - /// Returns the deadline that the expiration was set to. - pub fn deadline(&self) -> Instant { - self.deadline - } - - /// Returns the key that the expiration is indexed by. - pub fn key(&self) -> Key { - self.key - } -} diff --git a/common/nonexhaustive-delayqueue/src/wasm_delay_queue/mod.rs b/common/nonexhaustive-delayqueue/src/wasm_delay_queue/mod.rs deleted file mode 100644 index fa8b62f561..0000000000 --- a/common/nonexhaustive-delayqueue/src/wasm_delay_queue/mod.rs +++ /dev/null @@ -1,42 +0,0 @@ -use std::time::Duration; - -mod wheel; - -pub mod delay_queue; - -#[doc(inline)] -pub use delay_queue::DelayQueue; - -// ===== Internal utils ===== - -enum Round { - Up, - Down, -} - -/// Convert a `Duration` to milliseconds, rounding up and saturating at -/// `u64::MAX`. -/// -/// The saturating is fine because `u64::MAX` milliseconds are still many -/// million years. -#[inline] -fn ms(duration: Duration, round: Round) -> u64 { - const NANOS_PER_MILLI: u32 = 1_000_000; - const MILLIS_PER_SEC: u64 = 1_000; - - // Round up. - let millis = match round { - Round::Up => (duration.subsec_nanos() + NANOS_PER_MILLI - 1) / NANOS_PER_MILLI, - Round::Down => duration.subsec_millis(), - }; - - duration - .as_secs() - .saturating_mul(MILLIS_PER_SEC) - .saturating_add(u64::from(millis)) -} - -#[inline] -fn sleep_until(deadline: wasm_timer::Instant) -> wasm_timer::Delay { - wasm_timer::Delay::new_at(deadline) -} diff --git a/common/nonexhaustive-delayqueue/src/wasm_delay_queue/wheel/level.rs b/common/nonexhaustive-delayqueue/src/wasm_delay_queue/wheel/level.rs deleted file mode 100644 index f84d80e265..0000000000 --- a/common/nonexhaustive-delayqueue/src/wasm_delay_queue/wheel/level.rs +++ /dev/null @@ -1,253 +0,0 @@ -use crate::wasm_delay_queue::wheel::Stack; - -use std::fmt; - -/// Wheel for a single level in the timer. This wheel contains 64 slots. -pub(crate) struct Level { - level: usize, - - /// Bit field tracking which slots currently contain entries. - /// - /// Using a bit field to track slots that contain entries allows avoiding a - /// scan to find entries. This field is updated when entries are added or - /// removed from a slot. - /// - /// The least-significant bit represents slot zero. - occupied: u64, - - /// Slots - slot: [T; LEVEL_MULT], -} - -/// Indicates when a slot must be processed next. -#[derive(Debug)] -pub(crate) struct Expiration { - /// The level containing the slot. - pub(crate) level: usize, - - /// The slot index. - pub(crate) slot: usize, - - /// The instant at which the slot needs to be processed. - pub(crate) deadline: u64, -} - -/// Level multiplier. -/// -/// Being a power of 2 is very important. -const LEVEL_MULT: usize = 64; - -impl Level { - pub(crate) fn new(level: usize) -> Level { - // Rust's derived implementations for arrays require that the value - // contained by the array be `Copy`. So, here we have to manually - // initialize every single slot. - macro_rules! s { - () => { - T::default() - }; - } - - Level { - level, - occupied: 0, - slot: [ - // It does not look like the necessary traits are - // derived for [T; 64]. - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - s!(), - ], - } - } - - /// Finds the slot that needs to be processed next and returns the slot and - /// `Instant` at which this slot must be processed. - pub(crate) fn next_expiration(&self, now: u64) -> Option { - // Use the `occupied` bit field to get the index of the next slot that - // needs to be processed. - let slot = match self.next_occupied_slot(now) { - Some(slot) => slot, - None => return None, - }; - - // From the slot index, calculate the `Instant` at which it needs to be - // processed. This value *must* be in the future with respect to `now`. - - let level_range = level_range(self.level); - let slot_range = slot_range(self.level); - - // TODO: This can probably be simplified w/ power of 2 math - let level_start = now - (now % level_range); - let deadline = level_start + slot as u64 * slot_range; - - debug_assert!( - deadline >= now, - "deadline={}; now={}; level={}; slot={}; occupied={:b}", - deadline, - now, - self.level, - slot, - self.occupied - ); - - Some(Expiration { - level: self.level, - slot, - deadline, - }) - } - - fn next_occupied_slot(&self, now: u64) -> Option { - if self.occupied == 0 { - return None; - } - - // Get the slot for now using Maths - let now_slot = (now / slot_range(self.level)) as usize; - let occupied = self.occupied.rotate_right(now_slot as u32); - let zeros = occupied.trailing_zeros() as usize; - let slot = (zeros + now_slot) % 64; - - Some(slot) - } - - pub(crate) fn add_entry(&mut self, when: u64, item: T::Owned, store: &mut T::Store) { - let slot = slot_for(when, self.level); - - self.slot[slot].push(item, store); - self.occupied |= occupied_bit(slot); - } - - pub(crate) fn remove_entry(&mut self, when: u64, item: &T::Borrowed, store: &mut T::Store) { - let slot = slot_for(when, self.level); - - self.slot[slot].remove(item, store); - - if self.slot[slot].is_empty() { - // The bit is currently set - debug_assert!(self.occupied & occupied_bit(slot) != 0); - - // Unset the bit - self.occupied ^= occupied_bit(slot); - } - } - - pub(crate) fn pop_entry_slot(&mut self, slot: usize, store: &mut T::Store) -> Option { - let ret = self.slot[slot].pop(store); - - if ret.is_some() && self.slot[slot].is_empty() { - // The bit is currently set - debug_assert!(self.occupied & occupied_bit(slot) != 0); - - self.occupied ^= occupied_bit(slot); - } - - ret - } -} - -impl fmt::Debug for Level { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_struct("Level") - .field("occupied", &self.occupied) - .finish() - } -} - -fn occupied_bit(slot: usize) -> u64 { - 1 << slot -} - -fn slot_range(level: usize) -> u64 { - LEVEL_MULT.pow(level as u32) as u64 -} - -fn level_range(level: usize) -> u64 { - LEVEL_MULT as u64 * slot_range(level) -} - -/// Convert a duration (milliseconds) and a level to a slot position -fn slot_for(duration: u64, level: usize) -> usize { - ((duration >> (level * 6)) % LEVEL_MULT as u64) as usize -} - -#[cfg(all(test, not(loom)))] -mod test { - use super::*; - - #[test] - fn test_slot_for() { - for pos in 0..64 { - assert_eq!(pos as usize, slot_for(pos, 0)); - } - - for level in 1..5 { - for pos in level..64 { - let a = pos * 64_usize.pow(level as u32); - assert_eq!(pos as usize, slot_for(a as u64, level)); - } - } - } -} diff --git a/common/nonexhaustive-delayqueue/src/wasm_delay_queue/wheel/mod.rs b/common/nonexhaustive-delayqueue/src/wasm_delay_queue/wheel/mod.rs deleted file mode 100644 index ffa05ab71b..0000000000 --- a/common/nonexhaustive-delayqueue/src/wasm_delay_queue/wheel/mod.rs +++ /dev/null @@ -1,315 +0,0 @@ -mod level; -pub(crate) use self::level::Expiration; -use self::level::Level; - -mod stack; -pub(crate) use self::stack::Stack; - -use std::borrow::Borrow; -use std::fmt::Debug; -use std::usize; - -/// Timing wheel implementation. -/// -/// This type provides the hashed timing wheel implementation that backs `Timer` -/// and `DelayQueue`. -/// -/// The structure is generic over `T: Stack`. This allows handling timeout data -/// being stored on the heap or in a slab. In order to support the latter case, -/// the slab must be passed into each function allowing the implementation to -/// lookup timer entries. -/// -/// See `Timer` documentation for some implementation notes. -#[derive(Debug)] -pub(crate) struct Wheel { - /// The number of milliseconds elapsed since the wheel started. - elapsed: u64, - - /// Timer wheel. - /// - /// Levels: - /// - /// * 1 ms slots / 64 ms range - /// * 64 ms slots / ~ 4 sec range - /// * ~ 4 sec slots / ~ 4 min range - /// * ~ 4 min slots / ~ 4 hr range - /// * ~ 4 hr slots / ~ 12 day range - /// * ~ 12 day slots / ~ 2 yr range - levels: Vec>, -} - -/// Number of levels. Each level has 64 slots. By using 6 levels with 64 slots -/// each, the timer is able to track time up to 2 years into the future with a -/// precision of 1 millisecond. -const NUM_LEVELS: usize = 6; - -/// The maximum duration of a delay -const MAX_DURATION: u64 = (1 << (6 * NUM_LEVELS)) - 1; - -#[derive(Debug)] -pub(crate) enum InsertError { - Elapsed, - Invalid, -} - -impl Wheel -where - T: Stack, -{ - /// Create a new timing wheel - pub(crate) fn new() -> Wheel { - let levels = (0..NUM_LEVELS).map(Level::new).collect(); - - Wheel { elapsed: 0, levels } - } - - /// Return the number of milliseconds that have elapsed since the timing - /// wheel's creation. - pub(crate) fn elapsed(&self) -> u64 { - self.elapsed - } - - /// Insert an entry into the timing wheel. - /// - /// # Arguments - /// - /// * `when`: is the instant at which the entry should be fired. It is - /// represented as the number of milliseconds since the creation - /// of the timing wheel. - /// - /// * `item`: The item to insert into the wheel. - /// - /// * `store`: The slab or `()` when using heap storage. - /// - /// # Return - /// - /// Returns `Ok` when the item is successfully inserted, `Err` otherwise. - /// - /// `Err(Elapsed)` indicates that `when` represents an instant that has - /// already passed. In this case, the caller should fire the timeout - /// immediately. - /// - /// `Err(Invalid)` indicates an invalid `when` argument as been supplied. - pub(crate) fn insert( - &mut self, - when: u64, - item: T::Owned, - store: &mut T::Store, - ) -> Result<(), (T::Owned, InsertError)> { - if when <= self.elapsed { - return Err((item, InsertError::Elapsed)); - } else if when - self.elapsed > MAX_DURATION { - return Err((item, InsertError::Invalid)); - } - - // Get the level at which the entry should be stored - let level = self.level_for(when); - - self.levels[level].add_entry(when, item, store); - - debug_assert!({ - self.levels[level] - .next_expiration(self.elapsed) - .map(|e| e.deadline >= self.elapsed) - .unwrap_or(true) - }); - - Ok(()) - } - - /// Remove `item` from the timing wheel. - #[track_caller] - pub(crate) fn remove(&mut self, item: &T::Borrowed, store: &mut T::Store) { - let when = T::when(item, store); - - assert!( - self.elapsed <= when, - "elapsed={}; when={}", - self.elapsed, - when - ); - - let level = self.level_for(when); - - self.levels[level].remove_entry(when, item, store); - } - - /// Instant at which to poll - pub(crate) fn poll_at(&self) -> Option { - self.next_expiration().map(|expiration| expiration.deadline) - } - - /// Advances the timer up to the instant represented by `now`. - pub(crate) fn poll(&mut self, now: u64, store: &mut T::Store) -> Option { - loop { - let expiration = self.next_expiration().and_then(|expiration| { - if expiration.deadline > now { - None - } else { - Some(expiration) - } - }); - - match expiration { - Some(ref expiration) => { - if let Some(item) = self.poll_expiration(expiration, store) { - return Some(item); - } - - self.set_elapsed(expiration.deadline); - } - None => { - // in this case the poll did not indicate an expiration - // _and_ we were not able to find a next expiration in - // the current list of timers. advance to the poll's - // current time and do nothing else. - self.set_elapsed(now); - return None; - } - } - } - } - - /// Returns the instant at which the next timeout expires. - fn next_expiration(&self) -> Option { - // Check all levels - for level in 0..NUM_LEVELS { - if let Some(expiration) = self.levels[level].next_expiration(self.elapsed) { - // There cannot be any expirations at a higher level that happen - // before this one. - debug_assert!(self.no_expirations_before(level + 1, expiration.deadline)); - - return Some(expiration); - } - } - - None - } - - /// Used for debug assertions - fn no_expirations_before(&self, start_level: usize, before: u64) -> bool { - let mut res = true; - - for l2 in start_level..NUM_LEVELS { - if let Some(e2) = self.levels[l2].next_expiration(self.elapsed) { - if e2.deadline < before { - res = false; - } - } - } - - res - } - - /// iteratively find entries that are between the wheel's current - /// time and the expiration time. for each in that population either - /// return it for notification (in the case of the last level) or tier - /// it down to the next level (in all other cases). - pub(crate) fn poll_expiration( - &mut self, - expiration: &Expiration, - store: &mut T::Store, - ) -> Option { - while let Some(item) = self.pop_entry(expiration, store) { - if expiration.level == 0 { - debug_assert_eq!(T::when(item.borrow(), store), expiration.deadline); - - return Some(item); - } else { - let when = T::when(item.borrow(), store); - - let next_level = expiration.level - 1; - - self.levels[next_level].add_entry(when, item, store); - } - } - - None - } - - fn set_elapsed(&mut self, when: u64) { - assert!( - self.elapsed <= when, - "elapsed={:?}; when={:?}", - self.elapsed, - when - ); - - if when > self.elapsed { - self.elapsed = when; - } - } - - fn pop_entry(&mut self, expiration: &Expiration, store: &mut T::Store) -> Option { - self.levels[expiration.level].pop_entry_slot(expiration.slot, store) - } - - fn level_for(&self, when: u64) -> usize { - level_for(self.elapsed, when) - } -} - -fn level_for(elapsed: u64, when: u64) -> usize { - const SLOT_MASK: u64 = (1 << 6) - 1; - - // Mask in the trailing bits ignored by the level calculation in order to cap - // the possible leading zeros - let masked = elapsed ^ when | SLOT_MASK; - - let leading_zeros = masked.leading_zeros() as usize; - let significant = 63 - leading_zeros; - significant / 6 -} - -#[cfg(all(test, not(loom)))] -mod test { - use super::*; - - #[test] - fn test_level_for() { - for pos in 0..64 { - assert_eq!( - 0, - level_for(0, pos), - "level_for({}) -- binary = {:b}", - pos, - pos - ); - } - - for level in 1..5 { - for pos in level..64 { - let a = pos * 64_usize.pow(level as u32); - assert_eq!( - level, - level_for(0, a as u64), - "level_for({}) -- binary = {:b}", - a, - a - ); - - if pos > level { - let a = a - 1; - assert_eq!( - level, - level_for(0, a as u64), - "level_for({}) -- binary = {:b}", - a, - a - ); - } - - if pos < 64 { - let a = a + 1; - assert_eq!( - level, - level_for(0, a as u64), - "level_for({}) -- binary = {:b}", - a, - a - ); - } - } - } - } -} diff --git a/common/nonexhaustive-delayqueue/src/wasm_delay_queue/wheel/stack.rs b/common/nonexhaustive-delayqueue/src/wasm_delay_queue/wheel/stack.rs deleted file mode 100644 index c87adcafda..0000000000 --- a/common/nonexhaustive-delayqueue/src/wasm_delay_queue/wheel/stack.rs +++ /dev/null @@ -1,28 +0,0 @@ -use std::borrow::Borrow; -use std::cmp::Eq; -use std::hash::Hash; - -/// Abstracts the stack operations needed to track timeouts. -pub(crate) trait Stack: Default { - /// Type of the item stored in the stack - type Owned: Borrow; - - /// Borrowed item - type Borrowed: Eq + Hash; - - /// Item storage, this allows a slab to be used instead of just the heap - type Store; - - /// Returns `true` if the stack is empty - fn is_empty(&self) -> bool; - - /// Push an item onto the stack - fn push(&mut self, item: Self::Owned, store: &mut Self::Store); - - /// Pop an item from the stack - fn pop(&mut self, store: &mut Self::Store) -> Option; - - fn remove(&mut self, item: &Self::Borrowed, store: &mut Self::Store); - - fn when(item: &Self::Borrowed, store: &Self::Store) -> u64; -} From 55bd7f8a61f5d3735958b00ec909fe28db6dde5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogdan-=C8=98tefan=20Neac=C5=9Fu?= Date: Thu, 3 Aug 2023 17:07:59 +0300 Subject: [PATCH 25/46] Fix doubling the data dir in nym-api (#3739) --- nym-api/src/support/config/mod.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/nym-api/src/support/config/mod.rs b/nym-api/src/support/config/mod.rs index 1e74708bda..51f2c6726c 100644 --- a/nym-api/src/support/config/mod.rs +++ b/nym-api/src/support/config/mod.rs @@ -106,15 +106,14 @@ impl NymConfigTemplate for Config { impl Config { pub fn new>(id: S) -> Self { - let base_data_dir = default_data_directory(id.as_ref()); Config { base: Base::new_default(id.as_ref()), - network_monitor: NetworkMonitor::new_default(&base_data_dir), - node_status_api: NodeStatusAPI::new_default(&base_data_dir), + network_monitor: NetworkMonitor::new_default(id.as_ref()), + node_status_api: NodeStatusAPI::new_default(id.as_ref()), topology_cacher: Default::default(), circulating_supply_cacher: Default::default(), rewarding: Default::default(), - coconut_signer: CoconutSigner::new_default(base_data_dir), + coconut_signer: CoconutSigner::new_default(id.as_ref()), } } From 9285aaf48764b424db1d13e4ed46810afb376fb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 3 Aug 2023 15:09:07 +0100 Subject: [PATCH 26/46] Generate json schema for all used contracts (#3693) * removed sealed impl of serde for tx::Fee * further upgraded cosmwasm to 1.3.0 * wip * created schema for mixnet contract * updated return type of 'GetBondedMixnodeDetailsByIdentity' query * fixed imported version of serde_json_wasm * updated return type of 'GetFamilyByHead' query * updated return type of 'GetFamilyByLabel' query * updated return type of 'GetFamilyMembersByHead' and 'GetFamilyMembersByLabel' queries * fixed broken tests due to type changes * added support for GetFamilyMembersByLabel and GetFamilyMembersByHead queries in 'mixnet_query_client' * moved 'Account' and 'VestingContractError' to common crate * created schema for vesting contract * Added documentation for all query messages in the vesting contract * improved mixnet contract schema by adding documentation to all query types * feature-locking cw2 import * created schema for the name service contract * created schema for the service provider directory contract * created schema for the coconut bandwidth contract * created schema for the coconut dkg contract * created schema for the coconut cw4 group contract * created schema for the coconut cw3 multisig contract * fixed missing import and adjusted makefile * cargo fmt * clippy * adjusted contract CI to build with --lib flag * missing --lib flag in the makefile * updated lock files * makefile for generating the schemas * added github action to check for schema difference * adding missing step to checkout the repo --- .github/workflows/check-contract-schema.yml | 25 + .github/workflows/contracts.yml | 6 +- Cargo.lock | 140 +- Cargo.toml | 22 +- Makefile | 7 +- clients/webassembly/Cargo.lock | 121 +- .../client-libs/validator-client/Cargo.toml | 1 - .../validator-client/src/nyxd/fee/mod.rs | 57 +- .../src/nyxd/traits/mixnet_query_client.rs | 49 +- .../src/nyxd/traits/vesting_query_client.rs | 3 +- .../src/nyxd/traits/vesting_signing_client.rs | 6 +- .../mixnet/delegators/delegate_to_mixnode.rs | 1 + .../rewards/claim_delegator_reward.rs | 1 + .../rewards/vesting_claim_delegator_reward.rs | 1 + .../delegators/undelegate_from_mixnode.rs | 1 + .../delegators/vesting_delegate_to_mixnode.rs | 1 + .../vesting_undelegate_from_mixnode.rs | 1 + .../create_family_join_permit_sign_payload.rs | 1 + .../operators/mixnode/families/join_family.rs | 2 +- .../mixnode/families/leave_family.rs | 2 +- .../vesting/create_vesting_schedule.rs | 2 +- .../coconut-bandwidth-contract/Cargo.toml | 7 +- .../coconut-bandwidth-contract/src/deposit.rs | 5 +- .../coconut-bandwidth-contract/src/msg.rs | 30 +- .../src/spend_credential.rs | 16 +- .../coconut-dkg/Cargo.toml | 6 +- .../coconut-dkg/src/dealer.rs | 25 +- .../coconut-dkg/src/msg.rs | 43 +- .../coconut-dkg/src/types.rs | 20 +- .../coconut-dkg/src/verification_key.rs | 9 +- .../contracts-common/Cargo.toml | 7 +- .../contracts-common/src/dealings.rs | 2 - .../contracts-common/src/types.rs | 12 +- .../mixnet-contract/Cargo.toml | 11 +- .../mixnet-contract/src/delegation.rs | 34 +- .../mixnet-contract/src/error.rs | 3 + .../mixnet-contract/src/families.rs | 78 +- .../mixnet-contract/src/gateway.rs | 59 +- .../mixnet-contract/src/interval.rs | 129 +- .../mixnet-contract/src/lib.rs | 27 +- .../mixnet-contract/src/mixnode.rs | 125 +- .../mixnet-contract/src/msg.rs | 305 +- .../mixnet-contract/src/pending_events.rs | 182 +- .../mixnet-contract/src/reward_params.rs | 35 +- .../mixnet-contract/src/rewarding/mod.rs | 53 +- .../mixnet-contract/src/signing.rs | 0 .../mixnet-contract/src/types.rs | 62 +- .../multisig-contract/Cargo.toml | 2 +- .../name-service/Cargo.toml | 6 +- .../name-service/src/msg.rs | 72 +- .../name-service/src/response.rs | 21 +- .../name-service/src/types.rs | 17 +- .../service-provider-directory/Cargo.toml | 7 +- .../service-provider-directory/src/msg.rs | 61 +- .../src/response.rs | 24 +- .../src/signing_types.rs | 10 +- .../service-provider-directory/src/types.rs | 17 +- .../vesting-contract/Cargo.toml | 5 +- .../vesting-contract/src/account.rs | 124 + .../vesting-contract/src/error.rs | 11 +- .../vesting-contract/src/lib.rs | 140 +- .../vesting-contract/src/messages.rs | 199 +- .../vesting-contract/src/types.rs | 166 + common/types/Cargo.toml | 3 +- common/types/src/delegation.rs | 2 +- common/types/src/mixnode.rs | 8 +- common/types/src/pending_events.rs | 4 +- common/types/src/vesting.rs | 4 +- contracts/Cargo.lock | 134 +- contracts/Cargo.toml | 24 +- contracts/Makefile | 25 + contracts/coconut-bandwidth/.cargo/config | 4 + contracts/coconut-bandwidth/Cargo.toml | 9 +- contracts/coconut-bandwidth/Makefile | 2 + .../schema/nym-coconut-bandwidth.json | 382 + .../coconut-bandwidth/schema/raw/execute.json | 130 + .../schema/raw/instantiate.json | 22 + .../coconut-bandwidth/schema/raw/migrate.json | 6 + .../coconut-bandwidth/schema/raw/query.json | 56 + ...response_to_get_all_spent_credentials.json | 86 + .../raw/response_to_get_spent_credential.json | 74 + contracts/coconut-bandwidth/src/bin/schema.rs | 16 + contracts/coconut-bandwidth/src/state.rs | 3 +- contracts/coconut-dkg/.cargo/config | 5 + contracts/coconut-dkg/Cargo.toml | 11 +- contracts/coconut-dkg/Makefile | 2 + .../coconut-dkg/schema/nym-coconut-dkg.json | 1023 ++ contracts/coconut-dkg/schema/raw/execute.json | 150 + .../coconut-dkg/schema/raw/instantiate.json | 78 + contracts/coconut-dkg/schema/raw/migrate.json | 6 + contracts/coconut-dkg/schema/raw/query.json | 198 + .../raw/response_to_get_current_dealers.json | 66 + .../response_to_get_current_epoch_state.json | 201 + ...sponse_to_get_current_epoch_threshold.json | 7 + .../raw/response_to_get_dealer_details.json | 64 + .../schema/raw/response_to_get_dealing.json | 64 + .../raw/response_to_get_initial_dealers.json | 39 + .../raw/response_to_get_past_dealers.json | 66 + .../response_to_get_verification_keys.json | 76 + contracts/coconut-dkg/src/bin/schema.rs | 14 + contracts/coconut-dkg/src/state/mod.rs | 3 +- .../src/decrease_mixnode_pledge.rs | 3 +- contracts/mixnet/.cargo/config | 4 +- contracts/mixnet/Cargo.toml | 10 +- contracts/mixnet/Makefile | 3 + contracts/mixnet/examples/schema.rs | 19 - .../mixnet/schema/nym-mixnet-contract.json | 8507 +++++++++++++++++ .../{execute_msg.json => raw/execute.json} | 401 +- .../instantiate.json} | 4 +- .../{migrate_msg.json => raw/migrate.json} | 3 +- .../schema/{query_msg.json => raw/query.json} | 337 +- .../raw/response_to_get_all_delegations.json | 128 + .../response_to_get_all_families_paged.json | 62 + .../response_to_get_all_members_paged.json | 42 + ...et_bonded_mixnode_details_by_identity.json | 342 + ...response_to_get_c_w2_contract_version.json | 20 + .../raw/response_to_get_contract_version.json | 40 + ...ponse_to_get_current_interval_details.json | 97 + .../response_to_get_delegation_details.json | 117 + ...response_to_get_delegator_delegations.json | 128 + .../raw/response_to_get_epoch_status.json | 93 + ...imated_current_epoch_delegator_reward.json | 89 + ...timated_current_epoch_operator_reward.json | 89 + .../raw/response_to_get_family_by_head.json | 67 + .../raw/response_to_get_family_by_label.json | 63 + ...esponse_to_get_family_members_by_head.json | 34 + ...sponse_to_get_family_members_by_label.json | 24 + .../raw/response_to_get_gateway_bond.json | 154 + .../schema/raw/response_to_get_gateways.json | 160 + .../response_to_get_layer_distribution.json | 32 + .../raw/response_to_get_mix_node_bonds.json | 193 + .../response_to_get_mix_nodes_detailed.json | 350 + .../response_to_get_mixnode_delegations.json | 116 + .../raw/response_to_get_mixnode_details.json | 344 + ...onse_to_get_mixnode_rewarding_details.json | 155 + ...ponse_to_get_number_of_pending_events.json | 25 + .../raw/response_to_get_owned_gateway.json | 158 + .../raw/response_to_get_owned_mixnode.json | 346 + ...ponse_to_get_pending_delegator_reward.json | 74 + .../response_to_get_pending_epoch_event.json | 298 + .../response_to_get_pending_epoch_events.json | 331 + ...esponse_to_get_pending_interval_event.json | 291 + ...sponse_to_get_pending_interval_events.json | 324 + ..._get_pending_mix_node_operator_reward.json | 74 + ...sponse_to_get_pending_operator_reward.json | 74 + .../raw/response_to_get_rewarded_set.json | 61 + .../raw/response_to_get_rewarding_params.json | 129 + ...se_to_get_rewarding_validator_address.json | 5 + .../raw/response_to_get_signing_nonce.json | 7 + .../raw/response_to_get_stake_saturation.json | 46 + .../schema/raw/response_to_get_state.json | 115 + .../raw/response_to_get_state_params.json | 61 + ..._to_get_unbonded_mix_node_information.json | 76 + .../response_to_get_unbonded_mix_nodes.json | 94 + ...et_unbonded_mix_nodes_by_identity_key.json | 94 + ...se_to_get_unbonded_mix_nodes_by_owner.json | 94 + contracts/mixnet/src/bin/schema.rs | 14 + contracts/mixnet/src/contract.rs | 8 +- contracts/mixnet/src/families/queries.rs | 52 +- contracts/mixnet/src/families/storage.rs | 36 +- contracts/mixnet/src/families/transactions.rs | 36 +- contracts/mixnet/src/mixnodes/queries.rs | 24 +- contracts/mixnet/src/support/tests/mod.rs | 2 +- .../multisig/cw3-flex-multisig/.cargo/config | 6 +- .../multisig/cw3-flex-multisig/Cargo.toml | 7 +- contracts/multisig/cw3-flex-multisig/Makefile | 2 + .../schema/cw3-flex-multisig.json | 5201 ++++++++++ .../cw3-flex-multisig/schema/raw/execute.json | 976 ++ .../schema/raw/instantiate.json | 261 + .../cw3-flex-multisig/schema/raw/migrate.json | 18 + .../cw3-flex-multisig/schema/raw/query.json | 232 + .../schema/raw/response_to_config.json | 269 + .../raw/response_to_list_proposals.json | 1045 ++ .../schema/raw/response_to_list_voters.json | 37 + .../schema/raw/response_to_list_votes.json | 80 + .../schema/raw/response_to_proposal.json | 1030 ++ .../raw/response_to_reverse_proposals.json | 1045 ++ .../schema/raw/response_to_threshold.json | 103 + .../schema/raw/response_to_vote.json | 81 + .../schema/raw/response_to_voter.json | 16 + .../cw3-flex-multisig/src/bin/schema.rs | 14 + contracts/multisig/cw4-group/Cargo.toml | 5 + contracts/multisig/cw4-group/Makefile | 2 + .../multisig/cw4-group/schema/cw4-group.json | 395 + .../cw4-group/schema/raw/execute.json | 125 + .../cw4-group/schema/raw/instantiate.json | 45 + .../multisig/cw4-group/schema/raw/query.json | 114 + .../schema/raw/response_to_admin.json | 15 + .../schema/raw/response_to_hooks.json | 17 + .../schema/raw/response_to_list_members.json | 38 + .../schema/raw/response_to_member.json | 16 + .../schema/raw/response_to_total_weight.json | 16 + .../multisig/cw4-group/src/bin/schema.rs | 13 + contracts/name-service/.cargo/config | 4 + contracts/name-service/Cargo.toml | 8 + contracts/name-service/Makefile | 2 + .../name-service/schema/nym-name-service.json | 1242 +++ .../name-service/schema/raw/execute.json | 181 + .../name-service/schema/raw/instantiate.json | 35 + .../name-service/schema/raw/migrate.json | 6 + contracts/name-service/schema/raw/query.json | 210 + .../schema/raw/response_to_all.json | 158 + .../schema/raw/response_to_by_address.json | 143 + .../schema/raw/response_to_by_name.json | 128 + .../schema/raw/response_to_by_owner.json | 143 + .../schema/raw/response_to_config.json | 35 + ...response_to_get_c_w2_contract_version.json | 20 + .../raw/response_to_get_contract_version.json | 40 + .../schema/raw/response_to_name_id.json | 128 + .../schema/raw/response_to_signing_nonce.json | 7 + contracts/name-service/src/bin/schema.rs | 14 + contracts/name-service/src/state/names.rs | 2 + .../service-provider-directory/.cargo/config | 2 +- .../service-provider-directory/Cargo.toml | 8 + contracts/service-provider-directory/Makefile | 2 + .../nym-service-provider-directory.json | 1104 +++ .../schema/raw/execute.json | 181 + .../schema/raw/instantiate.json | 35 + .../schema/raw/migrate.json | 6 + .../schema/raw/query.json | 184 + .../schema/raw/response_to_all.json | 162 + .../schema/raw/response_to_by_announcer.json | 147 + .../raw/response_to_by_nym_address.json | 147 + .../schema/raw/response_to_config.json | 35 + ...response_to_get_c_w2_contract_version.json | 20 + .../raw/response_to_get_contract_version.json | 40 + .../schema/raw/response_to_service_id.json | 132 + .../schema/raw/response_to_signing_nonce.json | 7 + .../src/bin/schema.rs | 16 + .../src/state/services.rs | 2 + contracts/vesting/.cargo/config | 4 + contracts/vesting/Cargo.toml | 9 +- contracts/vesting/Makefile | 5 +- .../vesting/schema/nym-vesting-contract.json | 2841 ++++++ contracts/vesting/schema/raw/execute.json | 971 ++ contracts/vesting/schema/raw/instantiate.json | 18 + contracts/vesting/schema/raw/migrate.json | 6 + contracts/vesting/schema/raw/query.json | 719 ++ .../schema/raw/response_to_get_account.json | 179 + .../raw/response_to_get_accounts_paged.json | 61 + ...e_to_get_accounts_vesting_coins_paged.json | 89 + .../raw/response_to_get_all_delegations.json | 90 + ...response_to_get_c_w2_contract_version.json | 20 + .../raw/response_to_get_contract_version.json | 40 + ...esponse_to_get_current_vesting_period.json | 36 + .../raw/response_to_get_delegated_coins.json | 23 + .../raw/response_to_get_delegation.json | 47 + .../raw/response_to_get_delegation_times.json | 50 + .../schema/raw/response_to_get_end_time.json | 16 + .../schema/raw/response_to_get_gateway.json | 72 + ...get_historical_vesting_staking_reward.json | 23 + .../schema/raw/response_to_get_mixnode.json | 72 + .../raw/response_to_get_original_vesting.json | 55 + .../raw/response_to_get_pledged_coins.json | 23 + ...esponse_to_get_spendable_reward_coins.json | 23 + ...esponse_to_get_spendable_vested_coins.json | 23 + .../raw/response_to_get_staked_coins.json | 23 + .../raw/response_to_get_start_time.json | 16 + ...sponse_to_get_total_delegation_amount.json | 23 + .../raw/response_to_get_vested_coins.json | 23 + .../raw/response_to_get_vesting_coins.json | 23 + .../raw/response_to_get_withdrawn_coins.json | 23 + .../schema/raw/response_to_locked_coins.json | 23 + .../raw/response_to_spendable_coins.json | 23 + contracts/vesting/src/bin/schema.rs | 14 + contracts/vesting/src/contract.rs | 52 +- contracts/vesting/src/lib.rs | 1 - contracts/vesting/src/queries.rs | 61 +- contracts/vesting/src/storage.rs | 103 +- contracts/vesting/src/support/tests.rs | 12 +- .../vesting/src/traits/bonding_account.rs | 31 +- .../vesting/src/traits/delegating_account.rs | 12 +- contracts/vesting/src/traits/node_families.rs | 10 +- .../vesting/src/traits/vesting_account.rs | 31 +- contracts/vesting/src/transactions.rs | 118 +- .../src/vesting/account/delegating_account.rs | 17 +- .../account/gateway_bonding_account.rs | 15 +- .../account/mixnode_bonding_account.rs | 35 +- contracts/vesting/src/vesting/account/mod.rs | 392 +- .../src/vesting/account/node_families.rs | 11 +- .../src/vesting/account/vesting_account.rs | 32 +- contracts/vesting/src/vesting/mod.rs | 48 +- nym-connect/desktop/Cargo.lock | 133 +- nym-wallet/Cargo.lock | 132 +- nym-wallet/nym-wallet-types/Cargo.toml | 4 +- nym-wallet/src-tauri/Cargo.toml | 4 +- nym-wallet/src-tauri/src/utils.rs | 4 +- 287 files changed, 41959 insertions(+), 1828 deletions(-) create mode 100644 .github/workflows/check-contract-schema.yml delete mode 100644 common/cosmwasm-smart-contracts/mixnet-contract/src/signing.rs create mode 100644 common/cosmwasm-smart-contracts/vesting-contract/src/account.rs rename contracts/vesting/src/errors.rs => common/cosmwasm-smart-contracts/vesting-contract/src/error.rs (92%) create mode 100644 common/cosmwasm-smart-contracts/vesting-contract/src/types.rs create mode 100644 contracts/Makefile create mode 100644 contracts/coconut-bandwidth/.cargo/config create mode 100644 contracts/coconut-bandwidth/Makefile create mode 100644 contracts/coconut-bandwidth/schema/nym-coconut-bandwidth.json create mode 100644 contracts/coconut-bandwidth/schema/raw/execute.json create mode 100644 contracts/coconut-bandwidth/schema/raw/instantiate.json create mode 100644 contracts/coconut-bandwidth/schema/raw/migrate.json create mode 100644 contracts/coconut-bandwidth/schema/raw/query.json create mode 100644 contracts/coconut-bandwidth/schema/raw/response_to_get_all_spent_credentials.json create mode 100644 contracts/coconut-bandwidth/schema/raw/response_to_get_spent_credential.json create mode 100644 contracts/coconut-bandwidth/src/bin/schema.rs create mode 100644 contracts/coconut-dkg/.cargo/config create mode 100644 contracts/coconut-dkg/Makefile create mode 100644 contracts/coconut-dkg/schema/nym-coconut-dkg.json create mode 100644 contracts/coconut-dkg/schema/raw/execute.json create mode 100644 contracts/coconut-dkg/schema/raw/instantiate.json create mode 100644 contracts/coconut-dkg/schema/raw/migrate.json create mode 100644 contracts/coconut-dkg/schema/raw/query.json create mode 100644 contracts/coconut-dkg/schema/raw/response_to_get_current_dealers.json create mode 100644 contracts/coconut-dkg/schema/raw/response_to_get_current_epoch_state.json create mode 100644 contracts/coconut-dkg/schema/raw/response_to_get_current_epoch_threshold.json create mode 100644 contracts/coconut-dkg/schema/raw/response_to_get_dealer_details.json create mode 100644 contracts/coconut-dkg/schema/raw/response_to_get_dealing.json create mode 100644 contracts/coconut-dkg/schema/raw/response_to_get_initial_dealers.json create mode 100644 contracts/coconut-dkg/schema/raw/response_to_get_past_dealers.json create mode 100644 contracts/coconut-dkg/schema/raw/response_to_get_verification_keys.json create mode 100644 contracts/coconut-dkg/src/bin/schema.rs delete mode 100644 contracts/mixnet/examples/schema.rs create mode 100644 contracts/mixnet/schema/nym-mixnet-contract.json rename contracts/mixnet/schema/{execute_msg.json => raw/execute.json} (73%) rename contracts/mixnet/schema/{instantiate_msg.json => raw/instantiate.json} (97%) rename contracts/mixnet/schema/{migrate_msg.json => raw/migrate.json} (85%) rename contracts/mixnet/schema/{query_msg.json => raw/query.json} (56%) create mode 100644 contracts/mixnet/schema/raw/response_to_get_all_delegations.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_all_families_paged.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_all_members_paged.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_bonded_mixnode_details_by_identity.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_c_w2_contract_version.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_contract_version.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_current_interval_details.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_delegation_details.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_delegator_delegations.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_epoch_status.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_estimated_current_epoch_delegator_reward.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_estimated_current_epoch_operator_reward.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_family_by_head.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_family_by_label.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_family_members_by_head.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_family_members_by_label.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_gateway_bond.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_gateways.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_layer_distribution.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_mix_node_bonds.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_mix_nodes_detailed.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_mixnode_delegations.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_mixnode_details.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_mixnode_rewarding_details.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_number_of_pending_events.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_owned_gateway.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_owned_mixnode.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_pending_delegator_reward.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_pending_epoch_event.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_pending_epoch_events.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_pending_interval_event.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_pending_interval_events.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_pending_mix_node_operator_reward.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_pending_operator_reward.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_rewarded_set.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_rewarding_params.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_rewarding_validator_address.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_signing_nonce.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_stake_saturation.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_state.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_state_params.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_unbonded_mix_node_information.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_unbonded_mix_nodes.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_unbonded_mix_nodes_by_identity_key.json create mode 100644 contracts/mixnet/schema/raw/response_to_get_unbonded_mix_nodes_by_owner.json create mode 100644 contracts/mixnet/src/bin/schema.rs create mode 100644 contracts/multisig/cw3-flex-multisig/Makefile create mode 100644 contracts/multisig/cw3-flex-multisig/schema/cw3-flex-multisig.json create mode 100644 contracts/multisig/cw3-flex-multisig/schema/raw/execute.json create mode 100644 contracts/multisig/cw3-flex-multisig/schema/raw/instantiate.json create mode 100644 contracts/multisig/cw3-flex-multisig/schema/raw/migrate.json create mode 100644 contracts/multisig/cw3-flex-multisig/schema/raw/query.json create mode 100644 contracts/multisig/cw3-flex-multisig/schema/raw/response_to_config.json create mode 100644 contracts/multisig/cw3-flex-multisig/schema/raw/response_to_list_proposals.json create mode 100644 contracts/multisig/cw3-flex-multisig/schema/raw/response_to_list_voters.json create mode 100644 contracts/multisig/cw3-flex-multisig/schema/raw/response_to_list_votes.json create mode 100644 contracts/multisig/cw3-flex-multisig/schema/raw/response_to_proposal.json create mode 100644 contracts/multisig/cw3-flex-multisig/schema/raw/response_to_reverse_proposals.json create mode 100644 contracts/multisig/cw3-flex-multisig/schema/raw/response_to_threshold.json create mode 100644 contracts/multisig/cw3-flex-multisig/schema/raw/response_to_vote.json create mode 100644 contracts/multisig/cw3-flex-multisig/schema/raw/response_to_voter.json create mode 100644 contracts/multisig/cw3-flex-multisig/src/bin/schema.rs create mode 100644 contracts/multisig/cw4-group/Makefile create mode 100644 contracts/multisig/cw4-group/schema/cw4-group.json create mode 100644 contracts/multisig/cw4-group/schema/raw/execute.json create mode 100644 contracts/multisig/cw4-group/schema/raw/instantiate.json create mode 100644 contracts/multisig/cw4-group/schema/raw/query.json create mode 100644 contracts/multisig/cw4-group/schema/raw/response_to_admin.json create mode 100644 contracts/multisig/cw4-group/schema/raw/response_to_hooks.json create mode 100644 contracts/multisig/cw4-group/schema/raw/response_to_list_members.json create mode 100644 contracts/multisig/cw4-group/schema/raw/response_to_member.json create mode 100644 contracts/multisig/cw4-group/schema/raw/response_to_total_weight.json create mode 100644 contracts/multisig/cw4-group/src/bin/schema.rs create mode 100644 contracts/name-service/.cargo/config create mode 100644 contracts/name-service/Makefile create mode 100644 contracts/name-service/schema/nym-name-service.json create mode 100644 contracts/name-service/schema/raw/execute.json create mode 100644 contracts/name-service/schema/raw/instantiate.json create mode 100644 contracts/name-service/schema/raw/migrate.json create mode 100644 contracts/name-service/schema/raw/query.json create mode 100644 contracts/name-service/schema/raw/response_to_all.json create mode 100644 contracts/name-service/schema/raw/response_to_by_address.json create mode 100644 contracts/name-service/schema/raw/response_to_by_name.json create mode 100644 contracts/name-service/schema/raw/response_to_by_owner.json create mode 100644 contracts/name-service/schema/raw/response_to_config.json create mode 100644 contracts/name-service/schema/raw/response_to_get_c_w2_contract_version.json create mode 100644 contracts/name-service/schema/raw/response_to_get_contract_version.json create mode 100644 contracts/name-service/schema/raw/response_to_name_id.json create mode 100644 contracts/name-service/schema/raw/response_to_signing_nonce.json create mode 100644 contracts/name-service/src/bin/schema.rs create mode 100644 contracts/service-provider-directory/Makefile create mode 100644 contracts/service-provider-directory/schema/nym-service-provider-directory.json create mode 100644 contracts/service-provider-directory/schema/raw/execute.json create mode 100644 contracts/service-provider-directory/schema/raw/instantiate.json create mode 100644 contracts/service-provider-directory/schema/raw/migrate.json create mode 100644 contracts/service-provider-directory/schema/raw/query.json create mode 100644 contracts/service-provider-directory/schema/raw/response_to_all.json create mode 100644 contracts/service-provider-directory/schema/raw/response_to_by_announcer.json create mode 100644 contracts/service-provider-directory/schema/raw/response_to_by_nym_address.json create mode 100644 contracts/service-provider-directory/schema/raw/response_to_config.json create mode 100644 contracts/service-provider-directory/schema/raw/response_to_get_c_w2_contract_version.json create mode 100644 contracts/service-provider-directory/schema/raw/response_to_get_contract_version.json create mode 100644 contracts/service-provider-directory/schema/raw/response_to_service_id.json create mode 100644 contracts/service-provider-directory/schema/raw/response_to_signing_nonce.json create mode 100644 contracts/service-provider-directory/src/bin/schema.rs create mode 100644 contracts/vesting/.cargo/config create mode 100644 contracts/vesting/schema/nym-vesting-contract.json create mode 100644 contracts/vesting/schema/raw/execute.json create mode 100644 contracts/vesting/schema/raw/instantiate.json create mode 100644 contracts/vesting/schema/raw/migrate.json create mode 100644 contracts/vesting/schema/raw/query.json create mode 100644 contracts/vesting/schema/raw/response_to_get_account.json create mode 100644 contracts/vesting/schema/raw/response_to_get_accounts_paged.json create mode 100644 contracts/vesting/schema/raw/response_to_get_accounts_vesting_coins_paged.json create mode 100644 contracts/vesting/schema/raw/response_to_get_all_delegations.json create mode 100644 contracts/vesting/schema/raw/response_to_get_c_w2_contract_version.json create mode 100644 contracts/vesting/schema/raw/response_to_get_contract_version.json create mode 100644 contracts/vesting/schema/raw/response_to_get_current_vesting_period.json create mode 100644 contracts/vesting/schema/raw/response_to_get_delegated_coins.json create mode 100644 contracts/vesting/schema/raw/response_to_get_delegation.json create mode 100644 contracts/vesting/schema/raw/response_to_get_delegation_times.json create mode 100644 contracts/vesting/schema/raw/response_to_get_end_time.json create mode 100644 contracts/vesting/schema/raw/response_to_get_gateway.json create mode 100644 contracts/vesting/schema/raw/response_to_get_historical_vesting_staking_reward.json create mode 100644 contracts/vesting/schema/raw/response_to_get_mixnode.json create mode 100644 contracts/vesting/schema/raw/response_to_get_original_vesting.json create mode 100644 contracts/vesting/schema/raw/response_to_get_pledged_coins.json create mode 100644 contracts/vesting/schema/raw/response_to_get_spendable_reward_coins.json create mode 100644 contracts/vesting/schema/raw/response_to_get_spendable_vested_coins.json create mode 100644 contracts/vesting/schema/raw/response_to_get_staked_coins.json create mode 100644 contracts/vesting/schema/raw/response_to_get_start_time.json create mode 100644 contracts/vesting/schema/raw/response_to_get_total_delegation_amount.json create mode 100644 contracts/vesting/schema/raw/response_to_get_vested_coins.json create mode 100644 contracts/vesting/schema/raw/response_to_get_vesting_coins.json create mode 100644 contracts/vesting/schema/raw/response_to_get_withdrawn_coins.json create mode 100644 contracts/vesting/schema/raw/response_to_locked_coins.json create mode 100644 contracts/vesting/schema/raw/response_to_spendable_coins.json create mode 100644 contracts/vesting/src/bin/schema.rs diff --git a/.github/workflows/check-contract-schema.yml b/.github/workflows/check-contract-schema.yml new file mode 100644 index 0000000000..700440bdd5 --- /dev/null +++ b/.github/workflows/check-contract-schema.yml @@ -0,0 +1,25 @@ +name: Check Contract Schema + +on: + push: + paths: + - 'contracts/**' + - 'common/**' + pull_request: + paths: + - 'contracts/**' + - 'common/**' + +jobs: + check-schema: + name: Generate and check schema + runs-on: ubuntu-latest + steps: + - name: Check out repository code + uses: actions/checkout@v2 + + - name: Generate the schema + run: make contract-schema + + - name: Check for diff + run: git diff --exit-code diff --git a/.github/workflows/contracts.yml b/.github/workflows/contracts.yml index 9de2cab348..64aeabb5d7 100644 --- a/.github/workflows/contracts.yml +++ b/.github/workflows/contracts.yml @@ -48,12 +48,12 @@ jobs: RUSTFLAGS: '-C link-arg=-s' with: command: build - args: --manifest-path contracts/Cargo.toml --workspace --target wasm32-unknown-unknown + args: --manifest-path contracts/Cargo.toml --workspace --lib --target wasm32-unknown-unknown - uses: actions-rs/cargo@v1 with: command: test - args: --manifest-path contracts/Cargo.toml + args: --lib --manifest-path contracts/Cargo.toml - uses: actions-rs/cargo@v1 with: @@ -64,4 +64,4 @@ jobs: if: ${{ matrix.rust != 'nightly' }} with: command: clippy - args: --manifest-path contracts/Cargo.toml --workspace --all-targets -- -D warnings + args: --lib --manifest-path contracts/Cargo.toml --workspace --all-targets -- -D warnings diff --git a/Cargo.lock b/Cargo.lock index a823625624..43b8e6eff2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -541,6 +541,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "bnum" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "845141a4fade3f790628b7daaaa298a25b204fb28907eb54febe5142db6ce653" + [[package]] name = "bs58" version = "0.4.0" @@ -969,9 +975,9 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.2.5" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75836a10cb9654c54e77ee56da94d592923092a10b369cdb0dbd56acefc16340" +checksum = "0d076a08ec01ed23c4396aca98ec73a38fa1fee5f310465add52b4108181c7a8" dependencies = [ "digest 0.10.7", "ed25519-zebra", @@ -982,18 +988,18 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.2.5" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c9f7f0e51bfc7295f7b2664fe8513c966428642aa765dad8a74acdab5e0c773" +checksum = "dec361f3c09d7b41221948fc17be9b3c96cb58e55a02f82da36f888a651f2584" dependencies = [ "syn 1.0.109", ] [[package]] name = "cosmwasm-schema" -version = "1.2.5" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f00b363610218eea83f24bbab09e1a7c3920b79f068334fdfcc62f6129ef9fc" +checksum = "bb6b2fb76758ef59cddc77f2e2ae91c22f77da49037e9f182e9c2833f0e959b1" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -1004,9 +1010,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.2.5" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae38f909b2822d32b275c9e2db9728497aa33ffe67dd463bc67c6a3b7092785c" +checksum = "2bfa39422f0d9f1c9a6fd3711573258495314dfa3aae738ea825ecd9964bc659" dependencies = [ "proc-macro2", "quote", @@ -1015,11 +1021,12 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.2.5" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a49b85345e811c8e80ec55d0d091e4fcb4f00f97ab058f9be5f614c444a730cb" +checksum = "1f6dc2ee23313add5ecacc3ccac217b9967ad9d2d11bd56e5da6aa65a9da6138" dependencies = [ "base64 0.13.1", + "bnum", "cosmwasm-crypto", "cosmwasm-derive", "derivative", @@ -1027,10 +1034,9 @@ dependencies = [ "hex", "schemars", "serde", - "serde-json-wasm 0.5.1", + "serde-json-wasm", "sha2 0.10.6", "thiserror", - "uint", ] [[package]] @@ -1203,12 +1209,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - [[package]] name = "crypto-bigint" version = "0.4.9" @@ -1370,9 +1370,9 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91440ce8ec4f0642798bc8c8cb6b9b53c1926c6dadaf0eed267a5145cd529071" +checksum = "d5d8edce4b78785f36413f67387e4be7d0cb7d032b5d4164bcc024f9c3f3f2ea" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1385,9 +1385,9 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053a5083c258acd68386734f428a5a171b29f7d733151ae83090c6fcc9417ffa" +checksum = "3f0e92a069d62067f3472c62e30adedb4cab1754725c0f2a682b3128d2bf3c79" dependencies = [ "cosmwasm-std", "schemars", @@ -1411,22 +1411,23 @@ dependencies = [ [[package]] name = "cw2" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fb70cee2cf0b4a8ff7253e6bc6647107905e8eb37208f87d54f67810faa62f8" +checksum = "29ac2dc7a55ad64173ca1e0a46697c31b7a5c51342f55a1e84a724da4eb99908" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", "serde", + "thiserror", ] [[package]] name = "cw20" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91666da6c7b40c8dd5ff94df655a28114efc10c79b70b4d06f13c31e37d60609" +checksum = "011c45920f8200bd5d32d4fe52502506f64f2f75651ab408054d4cfc75ca3a9b" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1437,9 +1438,9 @@ dependencies = [ [[package]] name = "cw3" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fe0b587008aa221cd2a2579a21990a28c4347dc53ad43167c68ad765f5b6efa" +checksum = "171af3d9127de6805a7dd819fb070c7d2f6c3ea85f4193f42cef259f0a7f33d5" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1452,9 +1453,9 @@ dependencies = [ [[package]] name = "cw4" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c236e0bae02ce97e89235a681dd0e07d099524b369f1ef908d704db3e6b049b" +checksum = "a398696307efadaaa2d0850076f865fa706c959d493cb4203314f72be6b77a64" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -3846,22 +3847,21 @@ dependencies = [ name = "nym-coconut-bandwidth-contract-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", + "cw2", "nym-multisig-contract-common", - "schemars", - "serde", ] [[package]] name = "nym-coconut-dkg-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-utils", "nym-contracts-common", "nym-multisig-contract-common", - "schemars", - "serde", ] [[package]] @@ -3893,6 +3893,7 @@ name = "nym-contracts-common" version = "0.5.0" dependencies = [ "bs58 0.4.0", + "cosmwasm-schema", "cosmwasm-std", "schemars", "serde", @@ -4141,14 +4142,16 @@ name = "nym-mixnet-contract-common" version = "0.6.0" dependencies = [ "bs58 0.4.0", + "cosmwasm-schema", "cosmwasm-std", + "cw2", "humantime-serde", "log", "nym-contracts-common", "rand_chacha 0.3.1", "schemars", "serde", - "serde-json-wasm 0.4.1", + "serde-json-wasm", "serde_repr", "thiserror", "time 0.3.21", @@ -4249,11 +4252,12 @@ dependencies = [ name = "nym-name-service-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-controllers", "cw-utils", + "cw2", "nym-contracts-common", - "schemars", "serde", "thiserror", ] @@ -4449,12 +4453,12 @@ dependencies = [ name = "nym-service-provider-directory-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-controllers", "cw-utils", + "cw2", "nym-contracts-common", - "schemars", - "serde", "thiserror", ] @@ -4804,7 +4808,6 @@ dependencies = [ "nym-config", "nym-mixnet-contract-common", "nym-validator-client", - "nym-vesting-contract", "nym-vesting-contract-common", "reqwest", "schemars", @@ -4846,7 +4849,6 @@ dependencies = [ "nym-name-service-common", "nym-network-defaults", "nym-service-provider-directory-common", - "nym-vesting-contract", "nym-vesting-contract-common", "openssl", "prost", @@ -4862,33 +4864,17 @@ dependencies = [ "zeroize", ] -[[package]] -name = "nym-vesting-contract" -version = "1.4.0" -dependencies = [ - "cosmwasm-derive", - "cosmwasm-std", - "cw-storage-plus", - "cw2", - "nym-contracts-common", - "nym-mixnet-contract-common", - "nym-vesting-contract-common", - "schemars", - "semver 1.0.17", - "serde", - "thiserror", - "vergen", -] - [[package]] name = "nym-vesting-contract-common" version = "0.7.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", + "cw2", "nym-contracts-common", "nym-mixnet-contract-common", - "schemars", "serde", + "thiserror", "ts-rs", ] @@ -4904,7 +4890,6 @@ dependencies = [ "nym-network-defaults", "nym-types", "nym-validator-client", - "nym-vesting-contract", "nym-vesting-contract-common", "serde", "serde_json", @@ -6431,18 +6416,9 @@ dependencies = [ [[package]] name = "serde-json-wasm" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" -dependencies = [ - "serde", -] - -[[package]] -name = "serde-json-wasm" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" +checksum = "a15bee9b04dd165c3f4e142628982ddde884c2022a89e8ddf99c4829bf2c3a58" dependencies = [ "serde", ] @@ -6980,12 +6956,6 @@ dependencies = [ "loom", ] -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "stringprep" version = "0.1.2" @@ -7197,9 +7167,9 @@ dependencies = [ [[package]] name = "tendermint-rpc" -version = "0.32.0" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd2cc789170db5a35d4e0bb2490035c03ef96df08f119bee25fd8dab5a09aa25" +checksum = "d119d83a130537fc4a98c3c9eb6899ebe857fea4860400a61675bfb5f0b35129" dependencies = [ "async-trait", "bytes", @@ -7818,18 +7788,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" -[[package]] -name = "uint" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - [[package]] name = "uncased" version = "0.9.9" diff --git a/Cargo.toml b/Cargo.toml index 22b4cb99ac..666d1f76fc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -117,20 +117,22 @@ anyhow = "1.0.71" async-trait = "0.1.64" bip39 = { version = "2.0.0", features = ["zeroize"] } cfg-if = "1.0.0" -cosmwasm-derive = "=1.2.5" -cosmwasm-schema = "=1.2.5" -cosmwasm-std = "=1.2.5" -cosmwasm-storage = "=1.2.5" +cosmwasm-derive = "=1.3.0" +cosmwasm-schema = "=1.3.0" +cosmwasm-std = "=1.3.0" +# use 0.5.0 as that's the version used by cosmwasm-std 1.3.0 +# (and ideally we don't want to pull the same dependency twice) +serde-json-wasm = "=0.5.0" +cosmwasm-storage = "=1.3.0" cosmrs = "=0.14.0" # same version as used by cosmrs tendermint-rpc = "=0.32" cw-utils = "=1.0.1" -cw-storage-plus = "=1.0.1" -cw2 = { version = "=1.0.1" } -cw3 = { version = "=1.0.1" } -cw3-fixed-multisig = { version = "=1.0.1" } -cw4 = { version = "=1.0.1" } -cw-controllers = { version = "=1.0.1" } +cw-storage-plus = "=1.1.0" +cw2 = { version = "=1.1.0" } +cw3 = { version = "=1.1.0" } +cw4 = { version = "=1.1.0" } +cw-controllers = { version = "=1.1.0" } dotenvy = "0.15.6" generic-array = "0.14.7" k256 = "0.13" diff --git a/Makefile b/Makefile index ad812f11b8..2576489be9 100644 --- a/Makefile +++ b/Makefile @@ -73,7 +73,7 @@ endef # Generate targets for the various cargo workspaces $(eval $(call add_cargo_workspace,main,.)) -$(eval $(call add_cargo_workspace,contracts,contracts,--target wasm32-unknown-unknown)) +$(eval $(call add_cargo_workspace,contracts,contracts,--lib --target wasm32-unknown-unknown)) $(eval $(call add_cargo_workspace,wasm-client,clients/webassembly,--target wasm32-unknown-unknown)) $(eval $(call add_cargo_workspace,wallet,nym-wallet,)) $(eval $(call add_cargo_workspace,connect,nym-connect/desktop)) @@ -104,7 +104,7 @@ NAME_SERVICE_CONTRACT=$(CONTRACTS_OUT_DIR)/nym_name_service.wasm wasm: wasm-build wasm-opt wasm-build: - RUSTFLAGS='-C link-arg=-s' cargo build --manifest-path contracts/Cargo.toml --release --target wasm32-unknown-unknown + RUSTFLAGS='-C link-arg=-s' cargo build --lib --manifest-path contracts/Cargo.toml --release --target wasm32-unknown-unknown wasm-opt: wasm-opt --disable-sign-ext -Os $(VESTING_CONTRACT) -o $(VESTING_CONTRACT) @@ -112,6 +112,9 @@ wasm-opt: wasm-opt --disable-sign-ext -Os $(SERVICE_PROVIDER_DIRECTORY_CONTRACT) -o $(SERVICE_PROVIDER_DIRECTORY_CONTRACT) wasm-opt --disable-sign-ext -Os $(NAME_SERVICE_CONTRACT) -o $(NAME_SERVICE_CONTRACT) +contract-schema: + $(MAKE) -C contracts schema + # ----------------------------------------------------------------------------- # Misc # ----------------------------------------------------------------------------- diff --git a/clients/webassembly/Cargo.lock b/clients/webassembly/Cargo.lock index 330f31c4d5..793f321a97 100644 --- a/clients/webassembly/Cargo.lock +++ b/clients/webassembly/Cargo.lock @@ -378,6 +378,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "bnum" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "845141a4fade3f790628b7daaaa298a25b204fb28907eb54febe5142db6ce653" + [[package]] name = "bs58" version = "0.4.0" @@ -658,18 +664,18 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.2.5" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c9f7f0e51bfc7295f7b2664fe8513c966428642aa765dad8a74acdab5e0c773" +checksum = "dec361f3c09d7b41221948fc17be9b3c96cb58e55a02f82da36f888a651f2584" dependencies = [ "syn 1.0.109", ] [[package]] name = "cosmwasm-schema" -version = "1.2.5" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f00b363610218eea83f24bbab09e1a7c3920b79f068334fdfcc62f6129ef9fc" +checksum = "bb6b2fb76758ef59cddc77f2e2ae91c22f77da49037e9f182e9c2833f0e959b1" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -680,9 +686,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.2.5" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae38f909b2822d32b275c9e2db9728497aa33ffe67dd463bc67c6a3b7092785c" +checksum = "2bfa39422f0d9f1c9a6fd3711573258495314dfa3aae738ea825ecd9964bc659" dependencies = [ "proc-macro2", "quote", @@ -691,11 +697,12 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.2.5" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a49b85345e811c8e80ec55d0d091e4fcb4f00f97ab058f9be5f614c444a730cb" +checksum = "1f6dc2ee23313add5ecacc3ccac217b9967ad9d2d11bd56e5da6aa65a9da6138" dependencies = [ "base64 0.13.1", + "bnum", "cosmwasm-crypto", "cosmwasm-derive", "derivative", @@ -703,10 +710,9 @@ dependencies = [ "hex", "schemars", "serde", - "serde-json-wasm 0.5.1", + "serde-json-wasm", "sha2 0.10.6", "thiserror", - "uint", ] [[package]] @@ -810,12 +816,6 @@ dependencies = [ "cfg-if 1.0.0", ] -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - [[package]] name = "crypto-bigint" version = "0.4.9" @@ -927,9 +927,9 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91440ce8ec4f0642798bc8c8cb6b9b53c1926c6dadaf0eed267a5145cd529071" +checksum = "d5d8edce4b78785f36413f67387e4be7d0cb7d032b5d4164bcc024f9c3f3f2ea" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -942,9 +942,9 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053a5083c258acd68386734f428a5a171b29f7d733151ae83090c6fcc9417ffa" +checksum = "3f0e92a069d62067f3472c62e30adedb4cab1754725c0f2a682b3128d2bf3c79" dependencies = [ "cosmwasm-std", "schemars", @@ -968,15 +968,16 @@ dependencies = [ [[package]] name = "cw2" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fb70cee2cf0b4a8ff7253e6bc6647107905e8eb37208f87d54f67810faa62f8" +checksum = "29ac2dc7a55ad64173ca1e0a46697c31b7a5c51342f55a1e84a724da4eb99908" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", "serde", + "thiserror", ] [[package]] @@ -994,9 +995,9 @@ dependencies = [ [[package]] name = "cw3" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fe0b587008aa221cd2a2579a21990a28c4347dc53ad43167c68ad765f5b6efa" +checksum = "171af3d9127de6805a7dd819fb070c7d2f6c3ea85f4193f42cef259f0a7f33d5" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1009,9 +1010,9 @@ dependencies = [ [[package]] name = "cw4" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c236e0bae02ce97e89235a681dd0e07d099524b369f1ef908d704db3e6b049b" +checksum = "a398696307efadaaa2d0850076f865fa706c959d493cb4203314f72be6b77a64" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -2566,22 +2567,20 @@ dependencies = [ name = "nym-coconut-bandwidth-contract-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "nym-multisig-contract-common", - "schemars", - "serde", ] [[package]] name = "nym-coconut-dkg-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-utils", "nym-contracts-common", "nym-multisig-contract-common", - "schemars", - "serde", ] [[package]] @@ -2613,6 +2612,7 @@ name = "nym-contracts-common" version = "0.5.0" dependencies = [ "bs58 0.4.0", + "cosmwasm-schema", "cosmwasm-std", "schemars", "serde", @@ -2757,13 +2757,14 @@ name = "nym-mixnet-contract-common" version = "0.6.0" dependencies = [ "bs58 0.4.0", + "cosmwasm-schema", "cosmwasm-std", "humantime-serde", "log", "nym-contracts-common", "schemars", "serde", - "serde-json-wasm 0.4.1", + "serde-json-wasm", "serde_repr", "thiserror", "time", @@ -2788,11 +2789,11 @@ dependencies = [ name = "nym-name-service-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-controllers", "cw-utils", "nym-contracts-common", - "schemars", "serde", "thiserror", ] @@ -2867,12 +2868,11 @@ dependencies = [ name = "nym-service-provider-directory-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-controllers", "cw-utils", "nym-contracts-common", - "schemars", - "serde", "thiserror", ] @@ -3096,7 +3096,6 @@ dependencies = [ "nym-name-service-common", "nym-network-defaults", "nym-service-provider-directory-common", - "nym-vesting-contract", "nym-vesting-contract-common", "openssl", "prost", @@ -3111,33 +3110,16 @@ dependencies = [ "zeroize", ] -[[package]] -name = "nym-vesting-contract" -version = "1.4.0" -dependencies = [ - "cosmwasm-derive", - "cosmwasm-std", - "cw-storage-plus", - "cw2", - "nym-contracts-common", - "nym-mixnet-contract-common", - "nym-vesting-contract-common", - "schemars", - "semver 1.0.17", - "serde", - "thiserror", - "vergen", -] - [[package]] name = "nym-vesting-contract-common" version = "0.7.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "nym-contracts-common", "nym-mixnet-contract-common", - "schemars", "serde", + "thiserror", ] [[package]] @@ -4061,18 +4043,9 @@ dependencies = [ [[package]] name = "serde-json-wasm" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" -dependencies = [ - "serde", -] - -[[package]] -name = "serde-json-wasm" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" +checksum = "a15bee9b04dd165c3f4e142628982ddde884c2022a89e8ddf99c4829bf2c3a58" dependencies = [ "serde", ] @@ -4516,12 +4489,6 @@ dependencies = [ "tokio-rustls 0.23.4", ] -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "stringprep" version = "0.1.2" @@ -4984,18 +4951,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" -[[package]] -name = "uint" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - [[package]] name = "unicode-bidi" version = "0.3.13" diff --git a/common/client-libs/validator-client/Cargo.toml b/common/client-libs/validator-client/Cargo.toml index 31475887bc..5ac785a9c7 100644 --- a/common/client-libs/validator-client/Cargo.toml +++ b/common/client-libs/validator-client/Cargo.toml @@ -20,7 +20,6 @@ nym-multisig-contract-common = { path = "../../cosmwasm-smart-contracts/multisig 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" } -nym-vesting-contract = { path = "../../../contracts/vesting" } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } reqwest = { version = "0.11", features = ["json"] } diff --git a/common/client-libs/validator-client/src/nyxd/fee/mod.rs b/common/client-libs/validator-client/src/nyxd/fee/mod.rs index 0d67544203..ee30d1ffe5 100644 --- a/common/client-libs/validator-client/src/nyxd/fee/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/fee/mod.rs @@ -32,7 +32,7 @@ impl Display for AutoFeeGrant { #[derive(Debug, Clone, Serialize, Deserialize)] pub enum Fee { - Manual(#[serde(with = "sealed::TxFee")] tx::Fee), + Manual(tx::Fee), Auto(Option), PayerGranterAuto(AutoFeeGrant), } @@ -121,58 +121,3 @@ impl GasAdjustable for Gas { } } } - -// a workaround to provide serde implementation for tx::Fee. We don't want to ever expose any of those -// types to the public and ideally they will get replaced by proper implementation inside comrs -mod sealed { - use cosmrs::tx::{self}; - use cosmrs::{AccountId, Denom as CosmosDenom}; - use cosmrs::{Coin as CosmosCoin, Gas}; - use serde::{Deserialize, Deserializer, Serialize, Serializer}; - - #[derive(Serialize, Deserialize, Clone)] - struct Coin { - denom: CosmosDenom, - amount: u128, - } - - impl From for CosmosCoin { - fn from(val: Coin) -> Self { - CosmosCoin { - denom: val.denom, - amount: val.amount, - } - } - } - - impl From for Coin { - fn from(val: CosmosCoin) -> Self { - Coin { - denom: val.denom, - amount: val.amount, - } - } - } - - fn coin_vec_ser(val: &[CosmosCoin], serializer: S) -> Result { - let vec: Vec = val.iter().cloned().map(Into::into).collect(); - vec.serialize(serializer) - } - fn coin_vec_deser<'de, D: Deserializer<'de>>( - deserializer: D, - ) -> Result, D::Error> { - let vec: Vec = Deserialize::deserialize(deserializer)?; - Ok(vec.iter().cloned().map(Into::into).collect()) - } - - #[derive(Serialize, Deserialize)] - #[serde(remote = "tx::Fee")] - pub(super) struct TxFee { - #[serde(serialize_with = "coin_vec_ser")] - #[serde(deserialize_with = "coin_vec_deser")] - pub amount: Vec, - pub gas_limit: Gas, - pub payer: Option, - pub granter: Option, - } -} diff --git a/common/client-libs/validator-client/src/nyxd/traits/mixnet_query_client.rs b/common/client-libs/validator-client/src/nyxd/traits/mixnet_query_client.rs index 84e4defaee..0297b90452 100644 --- a/common/client-libs/validator-client/src/nyxd/traits/mixnet_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/traits/mixnet_query_client.rs @@ -8,10 +8,9 @@ use async_trait::async_trait; use cosmrs::AccountId; use nym_contracts_common::signing::Nonce; use nym_mixnet_contract_common::delegation::{MixNodeDelegationResponse, OwnerProxySubKey}; -use nym_mixnet_contract_common::families::Family; use nym_mixnet_contract_common::mixnode::{ - MixNodeDetails, MixnodeRewardingDetailsResponse, PagedMixnodesDetailsResponse, - PagedUnbondedMixnodesResponse, StakeSaturationResponse, UnbondedMixnodeResponse, + MixnodeRewardingDetailsResponse, PagedMixnodesDetailsResponse, PagedUnbondedMixnodesResponse, + StakeSaturationResponse, UnbondedMixnodeResponse, }; use nym_mixnet_contract_common::reward_params::{Performance, RewardingParams}; use nym_mixnet_contract_common::rewarding::{ @@ -19,14 +18,15 @@ use nym_mixnet_contract_common::rewarding::{ }; use nym_mixnet_contract_common::{ delegation, ContractBuildInformation, ContractState, ContractStateParams, - CurrentIntervalResponse, EpochEventId, EpochStatus, GatewayBondResponse, - GatewayOwnershipResponse, IdentityKey, IntervalEventId, LayerDistribution, MixId, - MixOwnershipResponse, MixnodeDetailsResponse, NumberOfPendingEventsResponse, - PagedAllDelegationsResponse, PagedDelegatorDelegationsResponse, PagedFamiliesResponse, - PagedGatewayResponse, PagedMembersResponse, PagedMixNodeDelegationsResponse, - PagedMixnodeBondsResponse, PagedRewardedSetResponse, PendingEpochEventResponse, - PendingEpochEventsResponse, PendingIntervalEventResponse, PendingIntervalEventsResponse, - QueryMsg as MixnetQueryMsg, + CurrentIntervalResponse, EpochEventId, EpochStatus, FamilyByHeadResponse, + FamilyByLabelResponse, FamilyMembersByHeadResponse, FamilyMembersByLabelResponse, + GatewayBondResponse, GatewayOwnershipResponse, IdentityKey, IntervalEventId, LayerDistribution, + MixId, MixOwnershipResponse, MixnodeDetailsByIdentityResponse, MixnodeDetailsResponse, + NumberOfPendingEventsResponse, PagedAllDelegationsResponse, PagedDelegatorDelegationsResponse, + PagedFamiliesResponse, PagedGatewayResponse, PagedMembersResponse, + PagedMixNodeDelegationsResponse, PagedMixnodeBondsResponse, PagedRewardedSetResponse, + PendingEpochEventResponse, PendingEpochEventsResponse, PendingIntervalEventResponse, + PendingIntervalEventsResponse, QueryMsg as MixnetQueryMsg, }; use serde::Deserialize; @@ -100,6 +100,24 @@ pub trait MixnetQueryClient { .await } + async fn get_family_members_by_head + Send>( + &self, + head: S, + ) -> Result { + self.query_mixnet_contract(MixnetQueryMsg::GetFamilyMembersByHead { head: head.into() }) + .await + } + + async fn get_family_members_by_label + Send>( + &self, + label: S, + ) -> Result { + self.query_mixnet_contract(MixnetQueryMsg::GetFamilyMembersByLabel { + label: label.into(), + }) + .await + } + // mixnode-related: async fn get_mixnode_bonds_paged( @@ -178,7 +196,7 @@ pub trait MixnetQueryClient { async fn get_mixnode_details_by_identity( &self, mix_identity: IdentityKey, - ) -> Result, NyxdError> { + ) -> Result { self.query_mixnet_contract(MixnetQueryMsg::GetBondedMixnodeDetailsByIdentity { mix_identity, }) @@ -415,14 +433,17 @@ pub trait MixnetQueryClient { .await } - async fn get_node_family_by_label(&self, label: &str) -> Result, NyxdError> { + async fn get_node_family_by_label( + &self, + label: &str, + ) -> Result { self.query_mixnet_contract(MixnetQueryMsg::GetFamilyByLabel { label: label.to_string(), }) .await } - async fn get_node_family_by_head(&self, head: &str) -> Result, NyxdError> { + async fn get_node_family_by_head(&self, head: &str) -> Result { self.query_mixnet_contract(MixnetQueryMsg::GetFamilyByHead { head: head.to_string(), }) diff --git a/common/client-libs/validator-client/src/nyxd/traits/vesting_query_client.rs b/common/client-libs/validator-client/src/nyxd/traits/vesting_query_client.rs index 2f8931f98a..c70f0a78ca 100644 --- a/common/client-libs/validator-client/src/nyxd/traits/vesting_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/traits/vesting_query_client.rs @@ -10,12 +10,11 @@ use cosmwasm_std::{Coin as CosmWasmCoin, Timestamp}; use nym_contracts_common::ContractBuildInformation; use nym_mixnet_contract_common::MixId; use nym_vesting_contract_common::{ - messages::QueryMsg as VestingQueryMsg, AccountVestingCoins, AccountsResponse, + messages::QueryMsg as VestingQueryMsg, Account, AccountVestingCoins, AccountsResponse, AllDelegationsResponse, BaseVestingAccountInfo, DelegationTimesResponse, OriginalVestingResponse, Period, PledgeData, VestingCoinsResponse, VestingDelegation, }; use serde::Deserialize; -use vesting_contract::vesting::Account; #[async_trait] pub trait VestingQueryClient { diff --git a/common/client-libs/validator-client/src/nyxd/traits/vesting_signing_client.rs b/common/client-libs/validator-client/src/nyxd/traits/vesting_signing_client.rs index aba0d219cf..f1354566dd 100644 --- a/common/client-libs/validator-client/src/nyxd/traits/vesting_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/traits/vesting_signing_client.rs @@ -12,10 +12,8 @@ use nym_mixnet_contract_common::families::FamilyHead; use nym_mixnet_contract_common::gateway::GatewayConfigUpdate; use nym_mixnet_contract_common::mixnode::{MixNodeConfigUpdate, MixNodeCostParams}; use nym_mixnet_contract_common::{Gateway, MixId, MixNode}; -use nym_vesting_contract_common::messages::{ - ExecuteMsg as VestingExecuteMsg, VestingSpecification, -}; -use nym_vesting_contract_common::PledgeCap; +use nym_vesting_contract_common::messages::ExecuteMsg as VestingExecuteMsg; +use nym_vesting_contract_common::{PledgeCap, VestingSpecification}; #[async_trait] pub trait VestingSigningClient { diff --git a/common/commands/src/validator/mixnet/delegators/delegate_to_mixnode.rs b/common/commands/src/validator/mixnet/delegators/delegate_to_mixnode.rs index 6efa068545..f07cd21d5f 100644 --- a/common/commands/src/validator/mixnet/delegators/delegate_to_mixnode.rs +++ b/common/commands/src/validator/mixnet/delegators/delegate_to_mixnode.rs @@ -34,6 +34,7 @@ pub async fn delegate_to_mixnode(args: Args, client: SigningClient) { .get_mixnode_details_by_identity(identity_key) .await .expect("contract query failed") + .mixnode_details .expect("mixnode with the specified identity doesnt exist"); node_details.mix_id() } diff --git a/common/commands/src/validator/mixnet/delegators/rewards/claim_delegator_reward.rs b/common/commands/src/validator/mixnet/delegators/rewards/claim_delegator_reward.rs index 3f2ce6b197..61265c9ac5 100644 --- a/common/commands/src/validator/mixnet/delegators/rewards/claim_delegator_reward.rs +++ b/common/commands/src/validator/mixnet/delegators/rewards/claim_delegator_reward.rs @@ -29,6 +29,7 @@ pub async fn claim_delegator_reward(args: Args, client: SigningClient) { .get_mixnode_details_by_identity(identity_key) .await .expect("contract query failed") + .mixnode_details .expect("mixnode with the specified identity doesnt exist"); node_details.mix_id() } diff --git a/common/commands/src/validator/mixnet/delegators/rewards/vesting_claim_delegator_reward.rs b/common/commands/src/validator/mixnet/delegators/rewards/vesting_claim_delegator_reward.rs index 96733206f9..6d9e0bcbf7 100644 --- a/common/commands/src/validator/mixnet/delegators/rewards/vesting_claim_delegator_reward.rs +++ b/common/commands/src/validator/mixnet/delegators/rewards/vesting_claim_delegator_reward.rs @@ -29,6 +29,7 @@ pub async fn vesting_claim_delegator_reward(args: Args, client: SigningClient) { .get_mixnode_details_by_identity(identity_key) .await .expect("contract query failed") + .mixnode_details .expect("mixnode with the specified identity doesnt exist"); node_details.mix_id() } diff --git a/common/commands/src/validator/mixnet/delegators/undelegate_from_mixnode.rs b/common/commands/src/validator/mixnet/delegators/undelegate_from_mixnode.rs index 2e4ce7b8cd..790f518267 100644 --- a/common/commands/src/validator/mixnet/delegators/undelegate_from_mixnode.rs +++ b/common/commands/src/validator/mixnet/delegators/undelegate_from_mixnode.rs @@ -29,6 +29,7 @@ pub async fn undelegate_from_mixnode(args: Args, client: SigningClient) { .get_mixnode_details_by_identity(identity_key) .await .expect("contract query failed") + .mixnode_details .expect("mixnode with the specified identity doesnt exist"); node_details.mix_id() } diff --git a/common/commands/src/validator/mixnet/delegators/vesting_delegate_to_mixnode.rs b/common/commands/src/validator/mixnet/delegators/vesting_delegate_to_mixnode.rs index ec10a60193..41a992f0ed 100644 --- a/common/commands/src/validator/mixnet/delegators/vesting_delegate_to_mixnode.rs +++ b/common/commands/src/validator/mixnet/delegators/vesting_delegate_to_mixnode.rs @@ -40,6 +40,7 @@ pub async fn vesting_delegate_to_mixnode(args: Args, client: SigningClient) { .get_mixnode_details_by_identity(identity_key) .await .expect("contract query failed") + .mixnode_details .expect("mixnode with the specified identity doesnt exist"); node_details.mix_id() } diff --git a/common/commands/src/validator/mixnet/delegators/vesting_undelegate_from_mixnode.rs b/common/commands/src/validator/mixnet/delegators/vesting_undelegate_from_mixnode.rs index 4f8dac045e..42493f493d 100644 --- a/common/commands/src/validator/mixnet/delegators/vesting_undelegate_from_mixnode.rs +++ b/common/commands/src/validator/mixnet/delegators/vesting_undelegate_from_mixnode.rs @@ -34,6 +34,7 @@ pub async fn vesting_undelegate_from_mixnode(args: Args, client: SigningClient) .get_mixnode_details_by_identity(identity_key) .await .expect("contract query failed") + .mixnode_details .expect("mixnode with the specified identity doesnt exist"); node_details.mix_id() } diff --git a/common/commands/src/validator/mixnet/operators/mixnode/families/create_family_join_permit_sign_payload.rs b/common/commands/src/validator/mixnet/operators/mixnode/families/create_family_join_permit_sign_payload.rs index a305df4839..7b02731b30 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/families/create_family_join_permit_sign_payload.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/families/create_family_join_permit_sign_payload.rs @@ -50,6 +50,7 @@ pub async fn create_family_join_permit_sign_payload(args: Args, client: QueryCli .get_node_family_by_head(mixnode.bond_information.identity()) .await .unwrap() + .family .is_none() { eprintln!("{} does not even seem to own a family!", args.address); diff --git a/common/commands/src/validator/mixnet/operators/mixnode/families/join_family.rs b/common/commands/src/validator/mixnet/operators/mixnode/families/join_family.rs index 8b888e8bd6..b69dd7a4b2 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/families/join_family.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/families/join_family.rs @@ -28,7 +28,7 @@ pub struct Args { pub async fn join_family(args: Args, client: SigningClient) { info!("Join family"); - let family_head = FamilyHead::new(&args.family_head.to_base58_string()); + let family_head = FamilyHead::new(args.family_head.to_base58_string()); let res = if args.with_vesting_account { client diff --git a/common/commands/src/validator/mixnet/operators/mixnode/families/leave_family.rs b/common/commands/src/validator/mixnet/operators/mixnode/families/leave_family.rs index 5cb06e7762..193c003ab4 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/families/leave_family.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/families/leave_family.rs @@ -23,7 +23,7 @@ pub struct Args { pub async fn leave_family(args: Args, client: SigningClient) { info!("Leave family"); - let family_head = FamilyHead::new(&args.family_head.to_base58_string()); + let family_head = FamilyHead::new(args.family_head.to_base58_string()); let res = if args.with_vesting_account { client diff --git a/common/commands/src/validator/vesting/create_vesting_schedule.rs b/common/commands/src/validator/vesting/create_vesting_schedule.rs index 524cdf67e1..f7397bf14c 100644 --- a/common/commands/src/validator/vesting/create_vesting_schedule.rs +++ b/common/commands/src/validator/vesting/create_vesting_schedule.rs @@ -11,7 +11,7 @@ use nym_network_defaults::NymNetworkDetails; use nym_validator_client::nyxd::traits::VestingSigningClient; use nym_validator_client::nyxd::AccountId; use nym_validator_client::nyxd::{CosmosCoin, Denom}; -use nym_vesting_contract_common::messages::VestingSpecification; +use nym_vesting_contract_common::types::VestingSpecification; use nym_vesting_contract_common::PledgeCap; use crate::context::SigningClient; diff --git a/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/Cargo.toml b/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/Cargo.toml index fc5e1b43d7..90cf90ba17 100644 --- a/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/Cargo.toml +++ b/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/Cargo.toml @@ -7,6 +7,9 @@ edition = "2021" [dependencies] cosmwasm-std = { workspace = true } -schemars = "0.8" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } +cosmwasm-schema = { workspace = true } +cw2 = { workspace = true, optional = true } nym-multisig-contract-common = { path = "../multisig-contract" } + +[features] +schema = ["cw2"] \ No newline at end of file diff --git a/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/src/deposit.rs b/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/src/deposit.rs index d0572c3c91..c0e3a4acd3 100644 --- a/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/src/deposit.rs +++ b/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/src/deposit.rs @@ -1,10 +1,9 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; +use cosmwasm_schema::cw_serde; -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +#[cw_serde] pub struct DepositData { deposit_info: String, identity_key: String, diff --git a/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/src/msg.rs b/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/src/msg.rs index 8fffcc81eb..8387ac4ec5 100644 --- a/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/src/msg.rs +++ b/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/src/msg.rs @@ -1,39 +1,41 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use cosmwasm_std::Coin; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - use crate::{deposit::DepositData, spend_credential::SpendCredentialData}; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::Coin; -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +#[cfg(feature = "schema")] +use crate::spend_credential::{PagedSpendCredentialResponse, SpendCredentialResponse}; +#[cfg(feature = "schema")] +use cosmwasm_schema::QueryResponses; + +#[cw_serde] pub struct InstantiateMsg { pub multisig_addr: String, pub pool_addr: String, pub mix_denom: String, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum ExecuteMsg { DepositFunds { data: DepositData }, SpendCredential { data: SpendCredentialData }, ReleaseFunds { funds: Coin }, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] +#[cfg_attr(feature = "schema", derive(QueryResponses))] pub enum QueryMsg { - GetSpentCredential { - blinded_serial_number: String, - }, + #[cfg_attr(feature = "schema", returns(SpendCredentialResponse))] + GetSpentCredential { blinded_serial_number: String }, + + #[cfg_attr(feature = "schema", returns(PagedSpendCredentialResponse))] GetAllSpentCredentials { limit: Option, start_after: Option, }, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub struct MigrateMsg {} diff --git a/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/src/spend_credential.rs b/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/src/spend_credential.rs index 7cb47dc73b..d8fc108d14 100644 --- a/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/src/spend_credential.rs +++ b/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/src/spend_credential.rs @@ -1,14 +1,13 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use cosmwasm_schema::cw_serde; use cosmwasm_std::{from_binary, to_binary, Addr, Coin, CosmosMsg, StdResult, WasmMsg}; use nym_multisig_contract_common::msg::ExecuteMsg as MultisigExecuteMsg; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; use crate::msg::ExecuteMsg; -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +#[cw_serde] pub struct SpendCredentialData { funds: Coin, blinded_serial_number: String, @@ -37,13 +36,14 @@ impl SpendCredentialData { } } -#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +#[cw_serde] +#[derive(Copy)] pub enum SpendCredentialStatus { InProgress, Spent, } -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +#[cw_serde] pub struct SpendCredential { funds: Coin, blinded_serial_number: String, @@ -74,10 +74,12 @@ impl SpendCredential { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +#[cw_serde] pub struct PagedSpendCredentialResponse { pub spend_credentials: Vec, 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, } @@ -95,7 +97,7 @@ impl PagedSpendCredentialResponse { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +#[cw_serde] pub struct SpendCredentialResponse { pub spend_credential: Option, } diff --git a/common/cosmwasm-smart-contracts/coconut-dkg/Cargo.toml b/common/cosmwasm-smart-contracts/coconut-dkg/Cargo.toml index 1f6d6c3f3f..271d5b5bb9 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg/Cargo.toml +++ b/common/cosmwasm-smart-contracts/coconut-dkg/Cargo.toml @@ -6,10 +6,12 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } cw-utils = { workspace = true } -schemars = "0.8" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } contracts-common = { path = "../contracts-common", package = "nym-contracts-common" } nym-multisig-contract-common = { path = "../multisig-contract" } + +[features] +schema = [] \ No newline at end of file diff --git a/common/cosmwasm-smart-contracts/coconut-dkg/src/dealer.rs b/common/cosmwasm-smart-contracts/coconut-dkg/src/dealer.rs index 7b24be4869..3547345fa1 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg/src/dealer.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg/src/dealer.rs @@ -2,11 +2,10 @@ // SPDX-License-Identifier: Apache-2.0 use crate::types::{ContractSafeBytes, EncodedBTEPublicKeyWithProof, NodeIndex}; +use cosmwasm_schema::cw_serde; use cosmwasm_std::Addr; -use serde::{Deserialize, Serialize}; -#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub struct DealerDetails { pub address: Addr, pub bte_public_key_with_proof: EncodedBTEPublicKeyWithProof, @@ -14,8 +13,8 @@ pub struct DealerDetails { pub assigned_index: NodeIndex, } -#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)] -#[serde(rename_all = "snake_case")] +#[cw_serde] +#[derive(Copy)] pub enum DealerType { Current, Past, @@ -28,8 +27,7 @@ impl DealerType { } } -#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub struct DealerDetailsResponse { pub details: Option, pub dealer_type: DealerType, @@ -44,11 +42,12 @@ impl DealerDetailsResponse { } } -#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub struct PagedDealerResponse { pub dealers: Vec, 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, } @@ -66,8 +65,7 @@ impl PagedDealerResponse { } } -#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub struct ContractDealing { pub dealing: ContractSafeBytes, pub dealer: Addr, @@ -79,11 +77,12 @@ impl ContractDealing { } } -#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub struct PagedDealingsResponse { pub dealings: Vec, 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, } diff --git a/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs b/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs index 62891e8fe7..076f84291c 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs @@ -3,11 +3,19 @@ use crate::types::{ContractSafeBytes, EncodedBTEPublicKeyWithProof, EpochId, TimeConfiguration}; use crate::verification_key::VerificationKeyShare; +use cosmwasm_schema::cw_serde; use cosmwasm_std::Addr; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +#[cfg(feature = "schema")] +use crate::{ + dealer::{DealerDetailsResponse, PagedDealerResponse, PagedDealingsResponse}, + types::{Epoch, InitialReplacementData}, + verification_key::PagedVKSharesResponse, +}; +#[cfg(feature = "schema")] +use cosmwasm_schema::QueryResponses; + +#[cw_serde] pub struct InstantiateMsg { pub group_addr: String, pub multisig_addr: String, @@ -15,8 +23,7 @@ pub struct InstantiateMsg { pub mix_denom: String, } -#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum ExecuteMsg { RegisterDealer { bte_key_with_proof: EncodedBTEPublicKeyWithProof, @@ -44,28 +51,41 @@ pub enum ExecuteMsg { AdvanceEpochState {}, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] +#[cfg_attr(feature = "schema", derive(QueryResponses))] pub enum QueryMsg { + #[cfg_attr(feature = "schema", returns(Epoch))] GetCurrentEpochState {}, + + #[cfg_attr(feature = "schema", returns(u64))] GetCurrentEpochThreshold {}, + + #[cfg_attr(feature = "schema", returns(Option))] GetInitialDealers {}, - GetDealerDetails { - dealer_address: String, - }, + + #[cfg_attr(feature = "schema", returns(DealerDetailsResponse))] + GetDealerDetails { dealer_address: String }, + + #[cfg_attr(feature = "schema", returns(PagedDealerResponse))] GetCurrentDealers { limit: Option, start_after: Option, }, + + #[cfg_attr(feature = "schema", returns(PagedDealerResponse))] GetPastDealers { limit: Option, start_after: Option, }, + + #[cfg_attr(feature = "schema", returns(PagedDealingsResponse))] GetDealing { idx: u64, limit: Option, start_after: Option, }, + + #[cfg_attr(feature = "schema", returns(PagedVKSharesResponse))] GetVerificationKeys { epoch_id: EpochId, limit: Option, @@ -73,6 +93,5 @@ pub enum QueryMsg { }, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub struct MigrateMsg {} diff --git a/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs b/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs index ee0b854eb9..b01f1101ab 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs @@ -1,8 +1,7 @@ -// Copyright 2022 - Nym Technologies SA +// Copyright 2022-2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; +use cosmwasm_schema::cw_serde; use std::fmt::{Display, Formatter}; use std::str::FromStr; @@ -18,15 +17,14 @@ pub type EpochId = u64; // 2 public attributes, 2 private attributes, 1 fixed for coconut credential pub const TOTAL_DEALINGS: usize = 2 + 2 + 1; -#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq, Eq, Ord, PartialOrd)] +#[cw_serde] pub struct InitialReplacementData { pub initial_dealers: Vec, pub initial_height: u64, } -#[derive( - Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, Ord, PartialOrd, JsonSchema, -)] +#[cw_serde] +#[derive(Copy)] pub struct TimeConfiguration { // The time sign-up is open for dealers to join pub public_key_submission_time_secs: u64, @@ -75,8 +73,8 @@ impl Default for TimeConfiguration { } } -#[derive(Serialize, Deserialize, Default, Clone, Copy, Debug, PartialEq, Eq, Ord, PartialOrd)] -#[serde(rename_all = "snake_case")] +#[cw_serde] +#[derive(Copy, Default)] pub struct Epoch { pub state: EpochState, pub epoch_id: EpochId, @@ -155,8 +153,8 @@ impl Epoch { // 8. InProgress -> all receivers have all their secrets derived and all is good // // Note: It's important that the variant ordering is not changed otherwise it would mess up the derived `PartialOrd` -#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, Ord, PartialOrd)] -#[serde(rename_all = "snake_case")] +#[cw_serde] +#[derive(Copy)] pub enum EpochState { PublicKeySubmission { resharing: bool }, DealingExchange { resharing: bool }, diff --git a/common/cosmwasm-smart-contracts/coconut-dkg/src/verification_key.rs b/common/cosmwasm-smart-contracts/coconut-dkg/src/verification_key.rs index 9b8338b6f1..7a3d02f2e8 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg/src/verification_key.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg/src/verification_key.rs @@ -3,14 +3,14 @@ use crate::msg::ExecuteMsg; use crate::types::{EpochId, NodeIndex}; +use cosmwasm_schema::cw_serde; use cosmwasm_std::{from_binary, to_binary, Addr, CosmosMsg, StdResult, Timestamp, WasmMsg}; use cw_utils::Expiration; use nym_multisig_contract_common::msg::ExecuteMsg as MultisigExecuteMsg; -use serde::{Deserialize, Serialize}; pub type VerificationKeyShare = String; -#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +#[cw_serde] pub struct ContractVKShare { pub share: VerificationKeyShare, pub announce_address: String, @@ -20,11 +20,12 @@ pub struct ContractVKShare { pub verified: bool, } -#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub struct PagedVKSharesResponse { pub shares: Vec, 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, } diff --git a/common/cosmwasm-smart-contracts/contracts-common/Cargo.toml b/common/cosmwasm-smart-contracts/contracts-common/Cargo.toml index 512c3edc6b..fc55402be0 100644 --- a/common/cosmwasm-smart-contracts/contracts-common/Cargo.toml +++ b/common/cosmwasm-smart-contracts/contracts-common/Cargo.toml @@ -10,9 +10,10 @@ repository = { workspace = true } [dependencies] bs58 = "0.4.0" cosmwasm-std = { workspace = true } +cosmwasm-schema = { workspace = true } schemars = "0.8" -serde = { version = "1.0", features = ["derive"] } -thiserror = "1" +serde = { workspace = true, features = ["derive"] } +thiserror = { workspace = true } [dev-dependencies] -serde_json = "1.0.0" +serde_json = { workspace = true } diff --git a/common/cosmwasm-smart-contracts/contracts-common/src/dealings.rs b/common/cosmwasm-smart-contracts/contracts-common/src/dealings.rs index 87251d38e7..8c79ccbcfc 100644 --- a/common/cosmwasm-smart-contracts/contracts-common/src/dealings.rs +++ b/common/cosmwasm-smart-contracts/contracts-common/src/dealings.rs @@ -1,8 +1,6 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -#[cfg(feature = "dkg")] -use nym_dkg::{error::DkgError, Dealing}; use schemars::JsonSchema; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::fmt::{Display, Formatter}; diff --git a/common/cosmwasm-smart-contracts/contracts-common/src/types.rs b/common/cosmwasm-smart-contracts/contracts-common/src/types.rs index 858907bafa..4dca6b173b 100644 --- a/common/cosmwasm-smart-contracts/contracts-common/src/types.rs +++ b/common/cosmwasm-smart-contracts/contracts-common/src/types.rs @@ -1,16 +1,17 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use cosmwasm_schema::cw_serde; use cosmwasm_std::Decimal; use cosmwasm_std::Uint128; -use schemars::JsonSchema; use serde::de::Error; -use serde::{Deserialize, Deserializer, Serialize}; +use serde::{Deserialize, Deserializer}; use std::fmt::{self, Display, Formatter}; use std::ops::Mul; use std::str::FromStr; use thiserror::Error; +/// Ed25519 public key strinfified into base58. pub type IdentityKey = String; pub type IdentityKeyRef<'a> = &'a str; @@ -32,9 +33,8 @@ pub enum ContractsCommonError { /// Percent represents a value between 0 and 100% /// (i.e. between 0.0 and 1.0) -#[derive( - Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Serialize, Deserialize, JsonSchema, -)] +#[cw_serde] +#[derive(Copy, Default, PartialOrd)] pub struct Percent(#[serde(deserialize_with = "de_decimal_percent")] Decimal); impl Percent { @@ -129,7 +129,7 @@ where // TODO: there's no reason this couldn't be used for proper binaries, but in that case // perhaps the struct should get renamed and moved to a "more" common crate -#[derive(Debug, Serialize, Deserialize)] +#[cw_serde] pub struct ContractBuildInformation { // VERGEN_BUILD_TIMESTAMP /// Provides the build timestamp, for example `2021-02-23T20:14:46.558472672+00:00`. diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/Cargo.toml b/common/cosmwasm-smart-contracts/mixnet-contract/Cargo.toml index 736cedf911..47397d7b88 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/Cargo.toml +++ b/common/cosmwasm-smart-contracts/mixnet-contract/Cargo.toml @@ -11,14 +11,16 @@ repository = { workspace = true } [dependencies] bs58 = "0.4.0" cosmwasm-std = { workspace = true } -serde = { version = "1.0", features = ["derive"] } +cosmwasm-schema = { workspace = true } +cw2 = { workspace = true, optional = true } +serde = { workspace = true, features = ["derive"] } serde_repr = "0.1" + +# we still have to preserve that import for `JsonSchema` for `Layer` type (since we can't use cw_serde macro due to custom serde impl) schemars = "0.8" thiserror = "1.0" contracts-common = { path = "../contracts-common", package = "nym-contracts-common", version = "0.5.0" } -# use 0.4.1 as that's the version used by cosmwasm-std 1.0.0 -# (and ideally we don't want to pull the same dependency twice) -serde-json-wasm = "=0.4.1" +serde-json-wasm = { workspace = true } humantime-serde = "1.1.1" # TO CHECK WHETHER STILL NEEDED: @@ -33,4 +35,5 @@ time = { version = "0.3.5", features = ["serde", "macros"] } [features] default = [] contract-testing = [] +schema = ["cw2"] generate-ts = ['ts-rs'] diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/delegation.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/delegation.rs index 55294498b8..3a7cdd7702 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/delegation.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/delegation.rs @@ -1,15 +1,11 @@ // Copyright 2021-2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -// due to code generated by JsonSchema -#![allow(clippy::field_reassign_with_default)] - use crate::constants::TOKEN_SUPPLY; use crate::helpers::IntoBaseDecimal; use crate::{Addr, MixId}; +use cosmwasm_schema::cw_serde; use cosmwasm_std::{Coin, Decimal, StdResult}; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; // just use a string representation of those so that we wouldn't need to bother with decoding bytes // and trying to figure out whether they're valid, etc @@ -37,7 +33,9 @@ pub fn generate_owner_storage_subkey( } } -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, JsonSchema)] +/// Information about tokens being delegated towards given mixnode in order to accrue rewards +/// with their work. +#[cw_serde] pub struct Delegation { /// Address of the owner of this delegation. pub owner: Addr, @@ -114,9 +112,13 @@ impl Delegation { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +/// Response containing paged list of all delegations made towards particular mixnode. +#[cw_serde] pub struct PagedMixNodeDelegationsResponse { + /// Each individual delegation made. pub delegations: Vec, + + /// Field indicating paging information for the following queries if the caller wishes to get further entries. pub start_next_after: Option, } @@ -129,9 +131,13 @@ impl PagedMixNodeDelegationsResponse { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +/// Response containing paged list of all delegations made by the particular address. +#[cw_serde] pub struct PagedDelegatorDelegationsResponse { + /// Each individual delegation made. pub delegations: Vec, + + /// Field indicating paging information for the following queries if the caller wishes to get further entries. pub start_next_after: Option<(MixId, OwnerProxySubKey)>, } @@ -147,9 +153,13 @@ impl PagedDelegatorDelegationsResponse { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +/// Response containing delegation details. +#[cw_serde] pub struct MixNodeDelegationResponse { + /// If the delegation exists, this field contains its detailed information. pub delegation: Option, + + /// Flag indicating whether the node towards which the delegation was made is still bonded in the network. pub mixnode_still_bonded: bool, } @@ -162,9 +172,13 @@ impl MixNodeDelegationResponse { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +/// Response containing paged list of all delegations currently active. +#[cw_serde] pub struct PagedAllDelegationsResponse { + /// Each individual delegation made. pub delegations: Vec, + + /// Field indicating paging information for the following queries if the caller wishes to get further entries. pub start_next_after: Option, } diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/error.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/error.rs index 0b572183ac..6007884cc8 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/error.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/error.rs @@ -165,6 +165,9 @@ pub enum MixnetContractError { #[error("Family with head {head} does not exist!")] FamilyDoesNotExist { head: String }, + #[error("Family with label {label} does not exist!")] + FamilyLabelDoesNotExist { label: String }, + #[error("Family with label '{0}' already exists")] FamilyWithLabelExists(String), diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/families.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/families.rs index 122e1690f6..5b44483c83 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/families.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/families.rs @@ -1,22 +1,34 @@ +// Copyright 2022-2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + use crate::{IdentityKey, IdentityKeyRef}; +use cosmwasm_schema::cw_serde; use cosmwasm_std::Addr; use schemars::JsonSchema; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::fmt::{Display, Formatter}; use std::str::FromStr; +/// A group of mixnodes associated with particular staking entity. +/// When defined all nodes belonging to the same family will be prioritised to be put onto the same layer. #[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))] #[cfg_attr( feature = "generate-ts", ts(export_to = "ts-packages/types/src/types/rust/NodeFamily.ts") )] -#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq, JsonSchema)] +#[cw_serde] pub struct Family { + /// Owner of this family. head: FamilyHead, + + /// Optional proxy (i.e. vesting contract address) used when creating the family. proxy: Option, + + /// Human readable label for this family. label: String, } +/// Head of particular family as identified by its identity key (i.e. public component of its ed25519 keypair stringified into base58). #[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))] #[cfg_attr( feature = "generate-ts", @@ -62,8 +74,8 @@ impl Display for FamilyHead { } impl FamilyHead { - pub fn new(identity: IdentityKeyRef<'_>) -> Self { - FamilyHead(identity.to_string()) + pub fn new>(identity: S) -> Self { + FamilyHead(identity.into()) } pub fn identity(&self) -> IdentityKeyRef<'_> { @@ -99,6 +111,66 @@ impl Family { } } +/// Response containing paged list of all families registered in the contract. +#[cw_serde] +pub struct PagedFamiliesResponse { + /// The families registered in the contract. + pub families: Vec, + + /// Field indicating paging information for the following queries if the caller wishes to get further entries. + pub start_next_after: Option, +} + +/// Response containing paged list of all family members (of ALL families) registered in the contract. +#[cw_serde] +pub struct PagedMembersResponse { + /// The members alongside their family heads. + pub members: Vec<(IdentityKey, FamilyHead)>, + + /// Field indicating paging information for the following queries if the caller wishes to get further entries. + pub start_next_after: Option, +} + +/// Response containing family information. +#[cw_serde] +pub struct FamilyByHeadResponse { + /// The family head used for the query. + pub head: FamilyHead, + + /// If applicable, the family associated with the provided head. + pub family: Option, +} + +/// Response containing family information. +#[cw_serde] +pub struct FamilyByLabelResponse { + /// The family label used for the query. + pub label: String, + + /// If applicable, the family associated with the provided label. + pub family: Option, +} + +/// Response containing family members information. +#[cw_serde] +pub struct FamilyMembersByHeadResponse { + /// The family head used for the query. + pub head: FamilyHead, + + /// All members belonging to the specified family. + pub members: Vec, +} + +/// Response containing family members information. +#[cw_serde] +pub struct FamilyMembersByLabelResponse { + /// The family label used for the query. + pub label: String, + + /// All members belonging to the specified family. + pub members: Vec, +} + #[cfg(test)] mod tests { use super::*; diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/gateway.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/gateway.rs index c312d42bf7..fd29090374 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/gateway.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/gateway.rs @@ -1,34 +1,56 @@ // Copyright 2021-2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -// due to code generated by JsonSchema -#![allow(clippy::field_reassign_with_default)] - use crate::{IdentityKey, SphinxKey}; +use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Coin}; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; use std::cmp::Ordering; use std::fmt::Display; -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, PartialOrd, Serialize, JsonSchema)] +/// Information provided by the node operator during bonding that are used to allow other entities to use the services of this node. +#[cw_serde] +#[derive(PartialOrd)] pub struct Gateway { + /// Network address of this gateway, for example 1.1.1.1 or foo.gateway.com pub host: String, + + /// Port used by this gateway for listening for mix packets. pub mix_port: u16, + + /// Port used by this gateway for listening for client requests. pub clients_port: u16, + + /// The physical, self-reported, location of this gateway. + // this field should be deprecated in favour of externally hosted information, like the mixnodes'. pub location: String, + + /// Base58-encoded x25519 public key used for sphinx key derivation. pub sphinx_key: SphinxKey, + /// Base58 encoded ed25519 EdDSA public key of the gateway used to derive shared keys with clients pub identity_key: IdentityKey, + + /// The self-reported semver version of this gateway. pub version: String, } -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +/// Basic gateway information provided by the node operator. +#[cw_serde] pub struct GatewayBond { + /// Original amount pledged by the operator of this node. pub pledge_amount: Coin, + + /// Address of the owner of this gateway. pub owner: Addr, + + /// Block height at which this gateway has been bonded. pub block_height: u64, + + /// Information provided by the operator for the purposes of bonding. pub gateway: Gateway, + + /// Entity who bonded this gateway on behalf of the owner. + /// If exists, it's most likely the address of the vesting contract. pub proxy: Option, } @@ -117,7 +139,7 @@ impl Display for GatewayBond { feature = "generate-ts", ts(export_to = "ts-packages/types/src/types/rust/GatewayConfigUpdate.ts") )] -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +#[cw_serde] pub struct GatewayConfigUpdate { pub host: String, pub mix_port: u16, @@ -132,10 +154,17 @@ impl GatewayConfigUpdate { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +/// Response containing paged list of all gateway bonds in the contract. +#[cw_serde] pub struct PagedGatewayResponse { + /// The gateway bond information present in the contract. pub nodes: Vec, + + /// Maximum number of entries that could be included in a response. `per_page <= nodes.len()` + // this field is rather redundant and should be deprecated. 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, } @@ -153,15 +182,23 @@ impl PagedGatewayResponse { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +/// Response containing details of a gateway belonging to the particular owner. +#[cw_serde] pub struct GatewayOwnershipResponse { + /// Validated address of the gateway owner. pub address: Addr, + + /// If the provided address owns a gateway, this field contains its details. pub gateway: Option, } -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +/// Response containing details of a gateway with the provided identity key. +#[cw_serde] pub struct GatewayBondResponse { + /// The identity key (base58-encoded ed25519 public key) of the gateway. pub identity: IdentityKey, + + /// If there exists a gateway with the provided identity key, this field contains its details. pub gateway: Option, } diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/interval.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/interval.rs index 5afdbd827e..cee4cf02be 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/interval.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/interval.rs @@ -2,20 +2,20 @@ // SPDX-License-Identifier: Apache-2.0 use crate::error::MixnetContractError; -use crate::pending_events::{PendingEpochEvent, PendingIntervalEvent}; -use crate::{ - EpochEventId, EpochId, IntervalEventId, IntervalId, MixId, PendingEpochEventData, - PendingIntervalEventData, -}; +use crate::MixId; +use cosmwasm_schema::cw_serde; +use cosmwasm_schema::schemars::gen::SchemaGenerator; +use cosmwasm_schema::schemars::schema::{InstanceType, Schema, SchemaObject}; +use cosmwasm_schema::schemars::JsonSchema; use cosmwasm_std::{Addr, Env}; -use schemars::gen::SchemaGenerator; -use schemars::schema::{InstanceType, Schema, SchemaObject}; -use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use std::fmt::{Display, Formatter}; use std::time::Duration; use time::OffsetDateTime; +pub type EpochId = u32; +pub type IntervalId = u32; + // internally, since version 0.3.6, time uses deserialize_any for deserialization, which can't be handled // by serde wasm. We could just downgrade to 0.3.5 and call it a day, but then it would break // when we decided to upgrade it at some point in the future. And then it would have been more problematic @@ -64,12 +64,15 @@ pub(crate) mod string_rfc3339_offset_date_time { } } -#[derive(Debug, Serialize, Deserialize, Eq, PartialEq)] +/// The status of the current rewarding epoch. +#[cw_serde] pub struct EpochStatus { // TODO: introduce mechanism to allow another validator to take over if no progress has been made in X blocks / Y seconds /// Specifies either, which validator is currently performing progression into the following epoch (if the epoch is currently being progressed), /// or which validator was responsible for progressing into the current epoch (if the epoch is currently in progress) pub being_advanced_by: Addr, + + /// The concrete state of the epoch. pub state: EpochState, } @@ -150,7 +153,9 @@ impl EpochStatus { } } -#[derive(Debug, Clone, Copy, Serialize, Deserialize, Eq, PartialEq)] +/// The state of the current rewarding epoch. +#[cw_serde] +#[derive(Copy)] pub enum EpochState { /// Represents the state of an epoch that's in progress (well, duh.) /// All actions are allowed to be issued. @@ -159,8 +164,10 @@ pub enum EpochState { /// Represents the state of an epoch when the rewarding entity has been decided on, /// and the mixnodes are in the process of being rewarded for their work in this epoch. Rewarding { + /// The id of the last node that has already received its rewards. last_rewarded: MixId, + /// The id of the last node that's going to be rewarded before progressing into the next state. final_node_id: MixId, // total_rewarded: u32, }, @@ -191,6 +198,7 @@ impl Display for EpochState { } } +/// Specification of a rewarding interval. #[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))] #[cfg_attr( feature = "generate-ts", @@ -198,7 +206,10 @@ impl Display for EpochState { )] #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Serialize)] pub struct Interval { + /// Monotonously increasing id of this interval. id: IntervalId, + + /// Number of epochs in this interval. epochs_in_interval: u32, // TODO add a better TS type generation @@ -207,10 +218,17 @@ pub struct Interval { // note: the `ts-rs failed to parse this attribute. It will be ignored.` warning emitted during // compilation is fine (I guess). `ts-rs` can't handle `with` serde attribute, but that's okay // since we explicitly specified this field should correspond to typescript's string + /// The timestamp indicating the start of the current rewarding epoch. current_epoch_start: OffsetDateTime, + + /// Monotonously increasing id of the current epoch in this interval. current_epoch_id: EpochId, + + /// The duration of all epochs in this interval. #[cfg_attr(feature = "generate-ts", ts(type = "{ secs: number; nanos: number; }"))] epoch_length: Duration, + + /// The total amount of elapsed epochs since the first epoch of the first interval. total_elapsed_epochs: EpochId, } @@ -455,11 +473,19 @@ impl Display for Interval { } } -#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Serialize)] +/// Information about the current rewarding interval. +#[cw_serde] pub struct CurrentIntervalResponse { + /// Detailed information about the underlying interval. pub interval: Interval, + + /// The current blocktime pub current_blocktime: u64, + + /// Flag indicating whether the current interval is over and it should be advanced. pub is_current_interval_over: bool, + + /// Flag indicating whether the current epoch is over and it should be advanced. pub is_current_epoch_over: bool, } @@ -489,87 +515,6 @@ impl CurrentIntervalResponse { } } -#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] -pub struct PendingEpochEventsResponse { - pub seconds_until_executable: i64, - pub events: Vec, - pub start_next_after: Option, -} - -impl PendingEpochEventsResponse { - pub fn new( - seconds_until_executable: i64, - events: Vec, - start_next_after: Option, - ) -> Self { - PendingEpochEventsResponse { - seconds_until_executable, - events, - start_next_after, - } - } -} - -#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] -pub struct PendingIntervalEventsResponse { - pub seconds_until_executable: i64, - pub events: Vec, - pub start_next_after: Option, -} - -impl PendingIntervalEventsResponse { - pub fn new( - seconds_until_executable: i64, - events: Vec, - start_next_after: Option, - ) -> Self { - PendingIntervalEventsResponse { - seconds_until_executable, - events, - start_next_after, - } - } -} - -#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] -pub struct PendingEpochEventResponse { - pub event_id: EpochEventId, - pub event: Option, -} - -impl PendingEpochEventResponse { - pub fn new(event_id: EpochEventId, event: Option) -> Self { - PendingEpochEventResponse { event_id, event } - } -} - -#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] -pub struct PendingIntervalEventResponse { - pub event_id: IntervalEventId, - pub event: Option, -} - -impl PendingIntervalEventResponse { - pub fn new(event_id: IntervalEventId, event: Option) -> Self { - PendingIntervalEventResponse { event_id, event } - } -} - -#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] -pub struct NumberOfPendingEventsResponse { - pub epoch_events: u32, - pub interval_events: u32, -} - -impl NumberOfPendingEventsResponse { - pub fn new(epoch_events: u32, interval_events: u32) -> Self { - Self { - epoch_events, - interval_events, - } - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/lib.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/lib.rs index e2a4a67a56..50a5e90aec 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/lib.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/lib.rs @@ -11,14 +11,14 @@ pub mod events; pub mod families; pub mod gateway; pub mod helpers; -mod interval; +pub mod interval; pub mod mixnode; -mod msg; +pub mod msg; pub mod pending_events; pub mod reward_params; pub mod rewarding; pub mod signing_types; -mod types; +pub mod types; pub use contracts_common::types::*; pub use cosmwasm_std::{Addr, Coin, Decimal, Fraction}; @@ -26,25 +26,32 @@ pub use delegation::{ Delegation, PagedAllDelegationsResponse, PagedDelegatorDelegationsResponse, PagedMixNodeDelegationsResponse, }; +pub use families::{ + Family, FamilyByHeadResponse, FamilyByLabelResponse, FamilyHead, FamilyMembersByHeadResponse, + FamilyMembersByLabelResponse, PagedFamiliesResponse, PagedMembersResponse, +}; pub use gateway::{ Gateway, GatewayBond, GatewayBondResponse, GatewayConfigUpdate, GatewayOwnershipResponse, PagedGatewayResponse, }; pub use interval::{ - CurrentIntervalResponse, EpochState, EpochStatus, Interval, NumberOfPendingEventsResponse, - PendingEpochEventResponse, PendingEpochEventsResponse, PendingIntervalEventResponse, - PendingIntervalEventsResponse, + CurrentIntervalResponse, EpochId, EpochState, EpochStatus, Interval, IntervalId, }; pub use mixnode::{ Layer, MixNode, MixNodeBond, MixNodeConfigUpdate, MixNodeCostParams, MixNodeDetails, - MixNodeRewarding, MixOwnershipResponse, MixnodeDetailsResponse, PagedMixnodeBondsResponse, - RewardedSetNodeStatus, UnbondedMixnode, + MixNodeRewarding, MixOwnershipResponse, MixnodeDetailsByIdentityResponse, + MixnodeDetailsResponse, PagedMixnodeBondsResponse, RewardedSetNodeStatus, UnbondedMixnode, }; pub use msg::*; pub use pending_events::{ - PendingEpochEvent, PendingEpochEventData, PendingEpochEventKind, PendingIntervalEvent, - PendingIntervalEventData, PendingIntervalEventKind, + EpochEventId, IntervalEventId, NumberOfPendingEventsResponse, PendingEpochEvent, + PendingEpochEventData, PendingEpochEventKind, PendingEpochEventResponse, + PendingEpochEventsResponse, PendingIntervalEvent, PendingIntervalEventData, + PendingIntervalEventKind, PendingIntervalEventResponse, PendingIntervalEventsResponse, }; pub use reward_params::{IntervalRewardParams, IntervalRewardingParamsUpdate, RewardingParams}; +pub use rewarding::{ + EstimatedCurrentEpochRewardResponse, PagedRewardedSetResponse, PendingRewardResponse, +}; pub use signing_types::*; pub use types::*; diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs index 69f1a89209..248bc7e143 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs @@ -11,19 +11,24 @@ use crate::reward_params::{NodeRewardParams, RewardingParams}; use crate::rewarding::helpers::truncate_reward; use crate::rewarding::RewardDistribution; use crate::{Delegation, EpochEventId, EpochId, IdentityKey, MixId, Percent, SphinxKey}; +use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Coin, Decimal, StdResult, Uint128}; use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; +/// Current state of given node in the rewarded set. #[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))] #[cfg_attr( feature = "generate-ts", ts(export_to = "ts-packages/types/src/types/rust/RewardedSetNodeStatus.ts") )] -#[derive(Clone, Copy, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq)] +#[cw_serde] +#[derive(Copy)] pub enum RewardedSetNodeStatus { + /// Node that is currently active, i.e. is expected to be used by clients for mixing packets. Active, + + /// Node that is currently in standby, i.e. it's present in the rewarded set but is not active. Standby, } @@ -33,10 +38,16 @@ impl RewardedSetNodeStatus { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +/// Full details associated with given mixnode. +#[cw_serde] pub struct MixNodeDetails { + /// Basic bond information of this mixnode, such as owner address, original pledge, etc. pub bond_information: MixNodeBond, + + /// Details used for computation of rewarding related data. pub rewarding_details: MixNodeRewarding, + + /// Adjustments to the mixnode that are ought to happen during future epoch transitions. #[serde(default)] pub pending_changes: PendingMixNodeChanges, } @@ -86,7 +97,7 @@ impl MixNodeDetails { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +#[cw_serde] pub struct MixNodeRewarding { /// Information provided by the operator that influence the cost function. pub cost_params: MixNodeCostParams, @@ -464,8 +475,8 @@ impl MixNodeRewarding { } } -// operator information + data assigned by the contract(s) -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +/// Basic mixnode information provided by the node operator. +#[cw_serde] pub struct MixNodeBond { /// Unique id assigned to the bonded mixnode. pub mix_id: MixId, @@ -533,21 +544,24 @@ impl MixNodeBond { } } -// information provided by the operator -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +/// Information provided by the node operator during bonding that are used to allow other entities to use the services of this node. +#[cw_serde] #[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))] #[cfg_attr( feature = "generate-ts", ts(export_to = "ts-packages/types/src/types/rust/Mixnode.ts") )] pub struct MixNode { - /// Network address of this mixnode, for example 1.1.1.1:1234 or foo.mixnode.com + /// Network address of this mixnode, for example 1.1.1.1 or foo.mixnode.com pub host: String, + /// Port used by this mixnode for listening for mix packets. pub mix_port: u16, + /// Port used by this mixnode for listening for verloc requests. pub verloc_port: u16, + /// Port used by this mixnode for its http(s) API pub http_api_port: u16, /// Base58-encoded x25519 public key used for sphinx key derivation. @@ -556,11 +570,15 @@ pub struct MixNode { /// Base58-encoded ed25519 EdDSA public key. pub identity_key: IdentityKey, + /// The self-reported semver version of this mixnode. pub version: String, } -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +/// The cost parameters, or the cost function, defined for the particular mixnode that influences +/// how the rewards should be split between the node operator and its delegators. +#[cw_serde] pub struct MixNodeCostParams { + /// The profit margin of the associated mixnode, i.e. the desired percent of the reward to be distributed to the operator. pub profit_margin_percent: Percent, /// Operating cost of the associated mixnode per the entire interval. @@ -633,7 +651,8 @@ impl From for u8 { feature = "generate-ts", ts(export_to = "ts-packages/types/src/types/rust/PendingMixnodeChanges.ts") )] -#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +#[cw_serde] +#[derive(Default, Copy)] pub struct PendingMixNodeChanges { pub pledge_change: Option, // pub cost_params_change: Option, @@ -647,21 +666,27 @@ impl PendingMixNodeChanges { } } +/// Basic information of a node that used to be part of the mix network but has already unbonded. #[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))] #[cfg_attr( feature = "generate-ts", ts(export_to = "ts-packages/types/src/types/rust/UnbondedMixnode.ts") )] -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +#[cw_serde] pub struct UnbondedMixnode { + /// Base58-encoded ed25519 EdDSA public key. pub identity_key: IdentityKey, + /// Address of the owner of this mixnode. #[cfg_attr(feature = "generate-ts", ts(type = "string"))] pub owner: Addr, + /// Entity who bonded this mixnode on behalf of the owner. + /// If exists, it's most likely the address of the vesting contract. #[cfg_attr(feature = "generate-ts", ts(type = "string | null"))] pub proxy: Option, + /// Block height at which this mixnode has unbonded. #[cfg_attr(feature = "generate-ts", ts(type = "number"))] pub unbonding_height: u64, } @@ -671,7 +696,7 @@ pub struct UnbondedMixnode { feature = "generate-ts", ts(export_to = "ts-packages/types/src/types/rust/MixNodeConfigUpdate.ts") )] -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +#[cw_serde] pub struct MixNodeConfigUpdate { pub host: String, pub mix_port: u16, @@ -686,10 +711,17 @@ impl MixNodeConfigUpdate { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +/// Response containing paged list of all mixnode bonds in the contract. +#[cw_serde] pub struct PagedMixnodeBondsResponse { + /// The mixnode bond information present in the contract. pub nodes: Vec, + + /// Maximum number of entries that could be included in a response. `per_page <= nodes.len()` + // this field is rather redundant and should be deprecated. 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, } @@ -703,10 +735,19 @@ impl PagedMixnodeBondsResponse { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +/// Response containing paged list of all mixnode details in the contract. +#[cw_serde] pub struct PagedMixnodesDetailsResponse { + /// All mixnode details stored in the contract. + /// Apart from the basic bond information it also contains details required for all future reward calculation + /// as well as any pending changes requested by the operator. pub nodes: Vec, + + /// Maximum number of entries that could be included in a response. `per_page <= nodes.len()` + // this field is rather redundant and should be deprecated. 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, } @@ -724,10 +765,17 @@ impl PagedMixnodesDetailsResponse { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +/// Response containing paged list of all mixnodes that have ever unbonded. +#[cw_serde] pub struct PagedUnbondedMixnodesResponse { + /// The past ids of unbonded mixnodes alongside their basic information such as the owner or the identity key. pub nodes: Vec<(MixId, UnbondedMixnode)>, + + /// Maximum number of entries that could be included in a response. `per_page <= nodes.len()` + // this field is rather redundant and should be deprecated. 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, } @@ -745,33 +793,68 @@ impl PagedUnbondedMixnodesResponse { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +/// Response containing details of a mixnode belonging to the particular owner. +#[cw_serde] pub struct MixOwnershipResponse { + /// Validated address of the mixnode owner. pub address: Addr, + + /// If the provided address owns a mixnode, this field contains its detailed information. pub mixnode_details: Option, } -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +/// Response containing details of a mixnode with the provided id. +#[cw_serde] pub struct MixnodeDetailsResponse { + /// Id of the requested mixnode. pub mix_id: MixId, + + /// If there exists a mixnode with the provided id, this field contains its detailed information. pub mixnode_details: Option, } -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +/// Response containing details of a bonded mixnode with the provided identity key. +#[cw_serde] +pub struct MixnodeDetailsByIdentityResponse { + /// The identity key (base58-encoded ed25519 public key) of the mixnode. + pub identity_key: IdentityKey, + + /// If there exists a bonded mixnode with the provided identity key, this field contains its detailed information. + pub mixnode_details: Option, +} + +/// Response containing rewarding information of a mixnode with the provided id. +#[cw_serde] pub struct MixnodeRewardingDetailsResponse { + /// Id of the requested mixnode. pub mix_id: MixId, + + /// If there exists a mixnode with the provided id, this field contains its rewarding information. pub rewarding_details: Option, } -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +/// Response containing basic information of an unbonded mixnode with the provided id. +#[cw_serde] pub struct UnbondedMixnodeResponse { + /// Id of the requested mixnode. pub mix_id: MixId, + + /// If there existed a mixnode with the provided id, this field contains its basic information. pub unbonded_info: Option, } -#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +/// Response containing the current state of the stake saturation of a mixnode with the provided id. +#[cw_serde] pub struct StakeSaturationResponse { + /// Id of the requested mixnode. pub mix_id: MixId, + + /// The current stake saturation of this node that is indirectly used in reward calculation formulas. + /// Note that it can't be larger than 1. pub current_saturation: Option, + + /// The current, absolute, stake saturation of this node. + /// Note that as the name suggests it can be larger than 1. + /// However, anything beyond that value has no effect on the total node reward. pub uncapped_saturation: Option, } diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/msg.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/msg.rs index 24603147a0..ca154e231b 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/msg.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/msg.rs @@ -1,28 +1,54 @@ // Copyright 2021-2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::delegation::OwnerProxySubKey; +use crate::delegation::{self, OwnerProxySubKey}; use crate::error::MixnetContractError; use crate::families::FamilyHead; -use crate::gateway::GatewayConfigUpdate; +use crate::gateway::{Gateway, GatewayConfigUpdate}; use crate::helpers::IntoBaseDecimal; -use crate::mixnode::{MixNodeConfigUpdate, MixNodeCostParams}; +use crate::mixnode::{Layer, MixNode, MixNodeConfigUpdate, MixNodeCostParams}; +use crate::pending_events::{EpochEventId, IntervalEventId}; use crate::reward_params::{ IntervalRewardParams, IntervalRewardingParamsUpdate, Performance, RewardingParams, }; -use crate::{ - delegation, ContractStateParams, EpochEventId, IntervalEventId, Layer, LayerAssignment, MixId, - Percent, -}; -use crate::{Gateway, IdentityKey, MixNode}; -use contracts_common::signing::MessageSignature; +use crate::types::{ContractStateParams, LayerAssignment, MixId}; +use contracts_common::{signing::MessageSignature, IdentityKey, Percent}; +use cosmwasm_schema::cw_serde; use cosmwasm_std::{Coin, Decimal}; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; use std::time::Duration; -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cfg(feature = "schema")] +use crate::{ + delegation::{ + MixNodeDelegationResponse, PagedAllDelegationsResponse, PagedDelegatorDelegationsResponse, + PagedMixNodeDelegationsResponse, + }, + families::{ + FamilyByHeadResponse, FamilyByLabelResponse, FamilyMembersByHeadResponse, + FamilyMembersByLabelResponse, PagedFamiliesResponse, PagedMembersResponse, + }, + gateway::{GatewayBondResponse, GatewayOwnershipResponse, PagedGatewayResponse}, + interval::{CurrentIntervalResponse, EpochStatus}, + mixnode::{ + MixOwnershipResponse, MixnodeDetailsByIdentityResponse, MixnodeDetailsResponse, + MixnodeRewardingDetailsResponse, PagedMixnodeBondsResponse, PagedMixnodesDetailsResponse, + PagedUnbondedMixnodesResponse, StakeSaturationResponse, UnbondedMixnodeResponse, + }, + pending_events::{ + NumberOfPendingEventsResponse, PendingEpochEventResponse, PendingEpochEventsResponse, + PendingIntervalEventResponse, PendingIntervalEventsResponse, + }, + rewarding::{ + EstimatedCurrentEpochRewardResponse, PagedRewardedSetResponse, PendingRewardResponse, + }, + types::{ContractState, LayerDistribution}, +}; +#[cfg(feature = "schema")] +use contracts_common::{signing::Nonce, ContractBuildInformation}; +#[cfg(feature = "schema")] +use cosmwasm_schema::QueryResponses; + +#[cw_serde] pub struct InstantiateMsg { pub rewarding_validator_address: String, pub vesting_contract_address: String, @@ -33,8 +59,7 @@ pub struct InstantiateMsg { pub initial_rewarding_params: InitialRewardingParams, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub struct InitialRewardingParams { pub initial_reward_pool: Decimal, pub initial_staking_supply: Decimal, @@ -76,8 +101,7 @@ impl InitialRewardingParams { } } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum ExecuteMsg { AssignNodeLayer { mix_id: MixId, @@ -365,177 +389,376 @@ impl ExecuteMsg { } } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] +#[cfg_attr(feature = "schema", derive(QueryResponses))] pub enum QueryMsg { // families + /// Gets the list of families registered in this contract. + #[cfg_attr(feature = "schema", returns(PagedFamiliesResponse))] GetAllFamiliesPaged { + /// Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default. limit: Option, + + /// Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response. start_after: Option, }, + + /// Gets the list of all family members registered in this contract. + #[cfg_attr(feature = "schema", returns(PagedMembersResponse))] GetAllMembersPaged { + /// Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default. limit: Option, + + /// Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response. start_after: Option, }, - GetFamilyByHead { - head: String, - }, - GetFamilyByLabel { - label: String, - }, - GetFamilyMembersByHead { - head: String, - }, - GetFamilyMembersByLabel { - label: String, - }, + + /// Attempts to lookup family information given the family head. + #[cfg_attr(feature = "schema", returns(FamilyByHeadResponse))] + GetFamilyByHead { head: String }, + + /// Attempts to lookup family information given the family label. + #[cfg_attr(feature = "schema", returns(FamilyByLabelResponse))] + GetFamilyByLabel { label: String }, + + /// Attempts to retrieve family members given the family head. + #[cfg_attr(feature = "schema", returns(FamilyMembersByHeadResponse))] + GetFamilyMembersByHead { head: String }, + + /// Attempts to retrieve family members given the family label. + #[cfg_attr(feature = "schema", returns(FamilyMembersByLabelResponse))] + GetFamilyMembersByLabel { label: String }, + // state/sys-params-related + /// 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 {}, + + /// Gets the address of the validator that's allowed to send rewarding transactions and transition the epoch. + #[cfg_attr(feature = "schema", returns(String))] GetRewardingValidatorAddress {}, + + /// Gets the contract parameters that could be adjusted in a transaction by the contract admin. + #[cfg_attr(feature = "schema", returns(ContractStateParams))] GetStateParams {}, + + /// Gets the current state of the contract. + #[cfg_attr(feature = "schema", returns(ContractState))] GetState {}, + + /// Gets the current parameters used for reward calculation. + #[cfg_attr(feature = "schema", returns(RewardingParams))] GetRewardingParams {}, + + /// Gets the status of the current rewarding epoch. + #[cfg_attr(feature = "schema", returns(EpochStatus))] GetEpochStatus {}, + + /// Get the details of the current rewarding interval. + #[cfg_attr(feature = "schema", returns(CurrentIntervalResponse))] GetCurrentIntervalDetails {}, + + /// Gets the current list of mixnodes in the rewarded set. + #[cfg_attr(feature = "schema", returns(PagedRewardedSetResponse))] GetRewardedSet { + /// Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default. limit: Option, + + /// Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response. start_after: Option, }, // mixnode-related: + /// Gets the basic list of all currently bonded mixnodes. + #[cfg_attr(feature = "schema", returns(PagedMixnodeBondsResponse))] GetMixNodeBonds { + /// Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default. limit: Option, + + /// Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response. start_after: Option, }, + + /// Gets the detailed list of all currently bonded mixnodes. + #[cfg_attr(feature = "schema", returns(PagedMixnodesDetailsResponse))] GetMixNodesDetailed { + /// Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default. limit: Option, + + /// Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response. start_after: Option, }, + + /// Gets the basic list of all unbonded mixnodes. + #[cfg_attr(feature = "schema", returns(PagedUnbondedMixnodesResponse))] GetUnbondedMixNodes { + /// Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default. limit: Option, + + /// Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response. start_after: Option, }, + + /// Gets the basic list of all unbonded mixnodes that belonged to a particular owner. + #[cfg_attr(feature = "schema", returns(PagedUnbondedMixnodesResponse))] GetUnbondedMixNodesByOwner { + /// The address of the owner of the the mixnodes used for the query. owner: String, + + /// Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default. limit: Option, + + /// Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response. start_after: Option, }, + + /// Gets the basic list of all unbonded mixnodes that used the particular identity key. + #[cfg_attr(feature = "schema", returns(PagedUnbondedMixnodesResponse))] GetUnbondedMixNodesByIdentityKey { + /// The identity key (base58-encoded ed25519 public key) of the mixnode used for the query. identity_key: String, + + /// Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default. limit: Option, + + /// Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response. start_after: Option, }, + + /// Gets the detailed mixnode information belonging to the particular owner. + #[cfg_attr(feature = "schema", returns(MixOwnershipResponse))] GetOwnedMixnode { + /// Address of the mixnode owner to use for the query. address: String, }, + + /// Gets the detailed mixnode information of a node with the provided id. + #[cfg_attr(feature = "schema", returns(MixnodeDetailsResponse))] GetMixnodeDetails { + /// Id of the node to query. mix_id: MixId, }, + + /// Gets the rewarding information of a mixnode with the provided id. + #[cfg_attr(feature = "schema", returns(MixnodeRewardingDetailsResponse))] GetMixnodeRewardingDetails { + /// Id of the node to query. mix_id: MixId, }, + + /// Gets the stake saturation of a mixnode with the provided id. + #[cfg_attr(feature = "schema", returns(StakeSaturationResponse))] GetStakeSaturation { + /// Id of the node to query. mix_id: MixId, }, + + /// Gets the basic information of an unbonded mixnode with the provided id. + #[cfg_attr(feature = "schema", returns(UnbondedMixnodeResponse))] GetUnbondedMixNodeInformation { + /// Id of the node to query. mix_id: MixId, }, + + /// Gets the detailed mixnode information of a node given its current identity key. + #[cfg_attr(feature = "schema", returns(MixnodeDetailsByIdentityResponse))] GetBondedMixnodeDetailsByIdentity { + /// The identity key (base58-encoded ed25519 public key) of the mixnode used for the query. mix_identity: IdentityKey, }, + + /// Gets the current layer configuration of the mix network. + #[cfg_attr(feature = "schema", returns(LayerDistribution))] GetLayerDistribution {}, + // gateway-related: + /// Gets the basic list of all currently bonded gateways. + #[cfg_attr(feature = "schema", returns(PagedGatewayResponse))] GetGateways { + /// Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response. start_after: Option, + + /// Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default. limit: Option, }, + + /// Gets the gateway details of a node given its identity key. + #[cfg_attr(feature = "schema", returns(GatewayBondResponse))] GetGatewayBond { + /// The identity key (base58-encoded ed25519 public key) of the gateway used for the query. identity: IdentityKey, }, + + /// Gets the detailed gateway information belonging to the particular owner. + #[cfg_attr(feature = "schema", returns(GatewayOwnershipResponse))] GetOwnedGateway { + /// Address of the gateway owner to use for the query. address: String, }, // delegation-related: - // gets all [paged] delegations associated with particular mixnode + /// Gets all delegations associated with particular mixnode + #[cfg_attr(feature = "schema", returns(PagedMixNodeDelegationsResponse))] GetMixnodeDelegations { + /// Id of the node to query. mix_id: MixId, - // since `start_after` is user-provided input, we can't use `Addr` as we - // can't guarantee it's validated. - start_after: Option, + + /// Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response. + start_after: Option, + + /// Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default. limit: Option, }, - // gets all [paged] delegations associated with particular delegator + + /// Gets all delegations associated with particular delegator + #[cfg_attr(feature = "schema", returns(PagedDelegatorDelegationsResponse))] GetDelegatorDelegations { // since `delegator` is user-provided input, we can't use `Addr` as we // can't guarantee it's validated. + /// The address of the owner of the delegations. delegator: String, + + /// Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response. start_after: Option<(MixId, OwnerProxySubKey)>, + + /// Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default. limit: Option, }, - // gets delegation associated with particular mixnode, delegator pair + + /// Gets delegation information associated with particular mixnode - delegator pair + #[cfg_attr(feature = "schema", returns(MixNodeDelegationResponse))] GetDelegationDetails { + /// Id of the node to query. mix_id: MixId, + + /// The address of the owner of the delegation. delegator: String, + + /// Entity who made the delegation on behalf of the owner. + /// If present, it's most likely the address of the vesting contract. proxy: Option, }, - // gets all delegations in the system + + /// Gets all delegations in the system + #[cfg_attr(feature = "schema", returns(PagedAllDelegationsResponse))] GetAllDelegations { + /// Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response. start_after: Option, + + /// Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default. limit: Option, }, // rewards related + /// Gets the reward amount accrued by the node operator that has not yet been claimed. + #[cfg_attr(feature = "schema", returns(PendingRewardResponse))] GetPendingOperatorReward { + /// Address of the operator to use for the query. address: String, }, + + /// Gets the reward amount accrued by the particular mixnode that has not yet been claimed. + #[cfg_attr(feature = "schema", returns(PendingRewardResponse))] GetPendingMixNodeOperatorReward { + /// Id of the node to query. mix_id: MixId, }, + + /// Gets the reward amount accrued by the particular delegator that has not yet been claimed. + #[cfg_attr(feature = "schema", returns(PendingRewardResponse))] GetPendingDelegatorReward { + /// Address of the delegator to use for the query. address: String, + + /// Id of the node to query. mix_id: MixId, + + /// Entity who made the delegation on behalf of the owner. + /// If present, it's most likely the address of the vesting contract. proxy: Option, }, - // given the provided performance, estimate the reward at the end of the current epoch + + /// Given the provided node performance, attempt to estimate the operator reward for the current epoch. + #[cfg_attr(feature = "schema", returns(EstimatedCurrentEpochRewardResponse))] GetEstimatedCurrentEpochOperatorReward { + /// Id of the node to query. mix_id: MixId, + + /// The estimated performance for the current epoch of the given node. estimated_performance: Performance, }, + + /// Given the provided node performance, attempt to estimate the delegator reward for the current epoch. + #[cfg_attr(feature = "schema", returns(EstimatedCurrentEpochRewardResponse))] GetEstimatedCurrentEpochDelegatorReward { + /// Address of the delegator to use for the query. address: String, + + /// Id of the node to query. mix_id: MixId, + + /// Entity who made the delegation on behalf of the owner. + /// If present, it's most likely the address of the vesting contract. proxy: Option, + + /// The estimated performance for the current epoch of the given node. estimated_performance: Performance, }, // interval-related + /// Gets the list of all currently pending epoch events that will be resolved once the current epoch finishes. + #[cfg_attr(feature = "schema", returns(PendingEpochEventsResponse))] GetPendingEpochEvents { + /// Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default. limit: Option, + + /// Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response. start_after: Option, }, + + /// Gets the list of all currently pending interval events that will be resolved once the current interval finishes. + #[cfg_attr(feature = "schema", returns(PendingIntervalEventsResponse))] GetPendingIntervalEvents { + /// Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default. limit: Option, + + /// Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response. start_after: Option, }, + + /// Gets detailed information about a pending epoch event given its id. + #[cfg_attr(feature = "schema", returns(PendingEpochEventResponse))] GetPendingEpochEvent { + /// The unique id associated with the event. event_id: EpochEventId, }, + + /// Gets detailed information about a pending interval event given its id. + #[cfg_attr(feature = "schema", returns(PendingIntervalEventResponse))] GetPendingIntervalEvent { + /// The unique id associated with the event. event_id: IntervalEventId, }, + + /// Gets the information about the number of currently pending epoch and interval events. + #[cfg_attr(feature = "schema", returns(NumberOfPendingEventsResponse))] GetNumberOfPendingEvents {}, // signing-related + /// Gets the signing nonce associated with the particular cosmos address. + #[cfg_attr(feature = "schema", returns(Nonce))] GetSigningNonce { + /// Cosmos address used for the query of the signing nonce. address: String, }, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub struct MigrateMsg { pub vesting_contract_address: Option, } diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/pending_events.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/pending_events.rs index 5f4db1ab90..595839c99f 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/pending_events.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/pending_events.rs @@ -3,49 +3,95 @@ use crate::mixnode::MixNodeCostParams; use crate::reward_params::IntervalRewardingParamsUpdate; -use crate::{BlockHeight, EpochEventId, IntervalEventId, MixId}; +use crate::{BlockHeight, MixId}; +use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Coin}; -use serde::{Deserialize, Serialize}; -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] +pub type EpochEventId = u32; +pub type IntervalEventId = u32; + +/// A request made at some point in the current epoch that's going to get resolved once the epoch rolls over. +#[cw_serde] pub struct PendingEpochEvent { + /// The unique id associated with the event. pub id: EpochEventId, + + /// The underlying event details, containing its type and information on how it should get resolved. pub event: PendingEpochEventData, } -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] +/// Details of a particular pending epoch event. +#[cw_serde] pub struct PendingEpochEventData { + /// The block height at which the request has been made. pub created_at: BlockHeight, + + /// The underlying event data, containing its concrete type and information on how it should get resolved. pub kind: PendingEpochEventKind, } -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] +/// Enum encompassing all possible epoch events. +#[cw_serde] pub enum PendingEpochEventKind { // can't just pass the `Delegation` struct here as it's impossible to determine // `cumulative_reward_ratio` ahead of time + /// Request to create a delegation towards particular mixnode. + /// Note that if such delegation already exists, it will get updated with the provided token amount. Delegate { + /// The address of the owner of the delegation. owner: Addr, + + /// The id of the mixnode used for the delegation. mix_id: MixId, + + /// The amount of tokens to use for the delegation. amount: Coin, + + /// Entity who made the delegation on behalf of the owner. + /// If present, it's most likely the address of the vesting contract. proxy: Option, }, + + /// Request to remove delegation from particular mixnode. Undelegate { + /// The address of the owner of the delegation. owner: Addr, + + /// The id of the mixnode used for the delegation. mix_id: MixId, + + /// Entity who made the delegation on behalf of the owner. + /// If present, it's most likely the address of the vesting contract. proxy: Option, }, + + /// Request to pledge more tokens (by the node operator) towards its node. PledgeMore { + /// The id of the mixnode that will have its pledge updated. mix_id: MixId, + + /// The amount of additional tokens to use by the pledge. amount: Coin, }, + + /// Request to decrease amount of pledged tokens (by the node operator) from its node. DecreasePledge { + /// The id of the mixnode that will have its pledge updated. mix_id: MixId, + + /// The amount of tokens that should be removed from the pledge. decrease_by: Coin, }, + + /// Request to unbond a mixnode and completely remove it from the network. UnbondMixnode { + /// The id of the mixnode that will get unbonded. mix_id: MixId, }, + + /// Request to update the current size of the active set. UpdateActiveSetSize { + /// The new desired size of the active set. new_size: u32, }, } @@ -68,29 +114,50 @@ impl From<(EpochEventId, PendingEpochEventData)> for PendingEpochEvent { } } -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] +/// A request made at some point in the current interval that's going to get resolved once the interval rolls over. +#[cw_serde] pub struct PendingIntervalEvent { + /// The unique id associated with the event. pub id: IntervalEventId, + + /// The underlying event details, containing its type and information on how it should get resolved. pub event: PendingIntervalEventData, } -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] +/// Details of a particular pending interval event. +#[cw_serde] pub struct PendingIntervalEventData { + /// The block height at which the request has been made. pub created_at: BlockHeight, + + /// The underlying event data, containing its concrete type and information on how it should get resolved. pub kind: PendingIntervalEventKind, } -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] +/// Enum encompassing all possible interval events. +#[cw_serde] pub enum PendingIntervalEventKind { + /// Request to update cost parameters of given mixnode. ChangeMixCostParams { + /// The id of the mixnode that will have its cost parameters updated. mix_id: MixId, + + /// The new updated cost function of this mixnode. new_costs: MixNodeCostParams, }, + + /// Request to update the underlying rewarding parameters used by the system UpdateRewardingParams { + /// The detailed specification of the update. update: IntervalRewardingParamsUpdate, }, + + /// Request to change the next interval configuration. UpdateIntervalConfig { + /// The new number of epochs in intervals. epochs_in_interval: u32, + + /// The new epoch duration. epoch_duration_secs: u64, }, } @@ -112,3 +179,102 @@ impl From<(IntervalEventId, PendingIntervalEventData)> for PendingIntervalEvent } } } + +/// Response containing all currently pending epoch events that will be resolved once the current epoch finishes. +#[cw_serde] +pub struct PendingEpochEventsResponse { + /// Amount of seconds until the events would be eligible to be resolved. + /// It's equivalent to the time until the current epoch finishes. + pub seconds_until_executable: i64, + + /// The currently pending events. + pub events: Vec, + + /// Field indicating paging information for the following queries if the caller wishes to get further entries. + pub start_next_after: Option, +} + +impl PendingEpochEventsResponse { + pub fn new( + seconds_until_executable: i64, + events: Vec, + start_next_after: Option, + ) -> Self { + PendingEpochEventsResponse { + seconds_until_executable, + events, + start_next_after, + } + } +} + +/// Response containing all currently pending interval events that will be resolved once the current interval finishes. +#[cw_serde] +pub struct PendingIntervalEventsResponse { + /// Amount of seconds until the events would be eligible to be resolved. + /// It's equivalent to the time until the current interval finishes. + pub seconds_until_executable: i64, + + /// The currently pending events. + pub events: Vec, + + /// Field indicating paging information for the following queries if the caller wishes to get further entries. + pub start_next_after: Option, +} + +impl PendingIntervalEventsResponse { + pub fn new( + seconds_until_executable: i64, + events: Vec, + start_next_after: Option, + ) -> Self { + PendingIntervalEventsResponse { + seconds_until_executable, + events, + start_next_after, + } + } +} + +#[cw_serde] +pub struct PendingEpochEventResponse { + pub event_id: EpochEventId, + pub event: Option, +} + +impl PendingEpochEventResponse { + pub fn new(event_id: EpochEventId, event: Option) -> Self { + PendingEpochEventResponse { event_id, event } + } +} + +#[cw_serde] +pub struct PendingIntervalEventResponse { + pub event_id: IntervalEventId, + pub event: Option, +} + +impl PendingIntervalEventResponse { + pub fn new(event_id: IntervalEventId, event: Option) -> Self { + PendingIntervalEventResponse { event_id, event } + } +} + +/// Response containing number of currently pending epoch and interval events. +#[cw_serde] +pub struct NumberOfPendingEventsResponse { + /// The number of the currently pending epoch events. + pub epoch_events: u32, + + /// The number of the currently pending epoch events. + pub interval_events: u32, +} + +impl NumberOfPendingEventsResponse { + pub fn new(epoch_events: u32, interval_events: u32) -> Self { + Self { + epoch_events, + interval_events, + } + } +} diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/reward_params.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/reward_params.rs index 74777eb99f..4928bd6a1e 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/reward_params.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/reward_params.rs @@ -3,9 +3,8 @@ use crate::helpers::IntoBaseDecimal; use crate::{error::MixnetContractError, Percent}; +use cosmwasm_schema::cw_serde; use cosmwasm_std::Decimal; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; pub type Performance = Percent; @@ -15,7 +14,8 @@ pub type Performance = Percent; feature = "generate-ts", ts(export_to = "ts-packages/types/src/types/rust/IntervalRewardParams.ts") )] -#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, PartialOrd, Serialize, JsonSchema)] +#[cw_serde] +#[derive(Copy)] pub struct IntervalRewardParams { /// Current value of the rewarding pool. /// It is expected to be constant throughout the interval. @@ -74,21 +74,26 @@ impl IntervalRewardParams { } } +/// Parameters used for reward calculation. #[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))] #[cfg_attr( feature = "generate-ts", ts(export_to = "ts-packages/types/src/types/rust/RewardingParams.ts") )] -#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, PartialOrd, Serialize, JsonSchema)] +#[cw_serde] +#[derive(Copy)] pub struct RewardingParams { /// Parameters that should remain unchanged throughout an interval. pub interval: IntervalRewardParams, - // while the active set size can change between epochs to accommodate for bandwidth demands, + // while the rewarded set size can change between epochs to accommodate for bandwidth demands, // the active set size should be unchanged between epochs and should only be adjusted between // intervals. However, it makes more sense to keep both of those values together as they're // very strongly related to each other. + /// The expected number of mixnodes in the rewarded set (i.e. active + standby). pub rewarded_set_size: u32, + + /// The expected number of mixnodes in the active set. pub active_set_size: u32, } @@ -224,9 +229,14 @@ impl RewardingParams { } // TODO: possibly refactor this -#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, PartialOrd, Serialize, JsonSchema)] +/// Parameters used for rewarding particular mixnode. +#[cw_serde] +#[derive(Copy)] pub struct NodeRewardParams { + /// Performance of the particular node in the current epoch. pub performance: Percent, + + /// Flag indicating whether the node has been in the active set during the epoch. pub in_active_set: bool, } @@ -239,33 +249,40 @@ impl NodeRewardParams { } } +/// Specification on how the rewarding params should be updated. #[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))] #[cfg_attr( feature = "generate-ts", ts(export_to = "ts-packages/types/src/types/rust/IntervalRewardingParamsUpdate.ts") )] -#[derive( - Clone, Copy, Debug, Default, Deserialize, PartialEq, Eq, PartialOrd, Serialize, JsonSchema, -)] +#[cw_serde] +#[derive(Copy, Default)] pub struct IntervalRewardingParamsUpdate { #[cfg_attr(feature = "generate-ts", ts(type = "string | null"))] + /// Defines the new value of the reward pool. pub reward_pool: Option, #[cfg_attr(feature = "generate-ts", ts(type = "string | null"))] + /// Defines the new value of the staking supply. pub staking_supply: Option, #[cfg_attr(feature = "generate-ts", ts(type = "string | null"))] + /// Defines the new value of the staking supply scale factor. pub staking_supply_scale_factor: Option, #[cfg_attr(feature = "generate-ts", ts(type = "string | null"))] + /// Defines the new value of the sybil resistance percent. pub sybil_resistance_percent: Option, #[cfg_attr(feature = "generate-ts", ts(type = "string | null"))] + /// Defines the new value of the active set work factor. pub active_set_work_factor: Option, #[cfg_attr(feature = "generate-ts", ts(type = "string | null"))] + /// Defines the new value of the interval pool emission rate. pub interval_pool_emission: Option, + /// Defines the new size of the rewarded set. pub rewarded_set_size: Option, } diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/rewarding/mod.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/rewarding/mod.rs index 650e39a2ff..4ef9cd433a 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/rewarding/mod.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/rewarding/mod.rs @@ -1,9 +1,9 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::{MixId, RewardedSetNodeStatus}; +use cosmwasm_schema::cw_serde; use cosmwasm_std::{Coin, Decimal}; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; pub mod helpers; pub mod simulator; @@ -13,32 +13,52 @@ pub mod simulator; feature = "generate-ts", ts(export_to = "ts-packages/types/src/types/rust/RewardEstimate.ts") )] -#[derive(Clone, Copy, Debug, Default, Deserialize, Serialize, JsonSchema, PartialEq, Eq)] +#[cw_serde] +#[derive(Copy, Default)] pub struct RewardEstimate { + /// The amount of **decimal** coins that are going to get distributed to the node, + /// i.e. the operator and all its delegators. #[cfg_attr(feature = "generate-ts", ts(type = "string"))] pub total_node_reward: Decimal, // note that operator reward includes the operating_cost, // i.e. say total_node_reward was `1nym` and operating_cost was `2nym` // in that case the operator reward would still be `1nym` as opposed to 0 + /// The share of the reward that is going to get distributed to the node operator. #[cfg_attr(feature = "generate-ts", ts(type = "string"))] pub operator: Decimal, + + /// The share of the reward that is going to get distributed among the node delegators. #[cfg_attr(feature = "generate-ts", ts(type = "string"))] pub delegates: Decimal, + + /// The operating cost of this node. Note: it's already included in the operator reward. #[cfg_attr(feature = "generate-ts", ts(type = "string"))] pub operating_cost: Decimal, } -#[derive(Clone, Copy, Debug, Default, Deserialize, Serialize, JsonSchema, PartialEq, Eq)] +#[cw_serde] +#[derive(Copy, Default)] pub struct RewardDistribution { + /// The share of the reward that is going to get distributed to the node operator. pub operator: Decimal, + + /// The share of the reward that is going to get distributed among the node delegators. pub delegates: Decimal, } -#[derive(Clone, Debug, Default, Deserialize, Serialize, JsonSchema, PartialEq, Eq)] +/// Response containing information about accrued rewards. +#[cw_serde] +#[derive(Default)] pub struct PendingRewardResponse { + /// The amount of tokens initially staked. pub amount_staked: Option, + + /// The amount of tokens that could be claimed. pub amount_earned: Option, + + /// The full pending rewards. Note that it's nearly identical to `amount_earned`, + /// however, it contains few additional decimal points for more accurate reward calculation. pub amount_earned_detailed: Option, /// The associated mixnode is still fully bonded, meaning it is neither unbonded @@ -46,14 +66,25 @@ pub struct PendingRewardResponse { pub mixnode_still_fully_bonded: bool, } -#[derive(Clone, Debug, Default, Deserialize, Serialize, JsonSchema, PartialEq, Eq)] +/// Response containing estimation of node rewards for the current epoch. +#[cw_serde] pub struct EstimatedCurrentEpochRewardResponse { + /// The amount of tokens initially staked. pub original_stake: Option, + /// The current stake value given all past rewarding and compounding since the original staking was performed. pub current_stake_value: Option, + + /// The current stake value. Note that it's nearly identical to `current_stake_value`, + /// however, it contains few additional decimal points for more accurate reward calculation. pub current_stake_value_detailed_amount: Option, + /// The reward estimation for the current epoch, i.e. the amount of tokens that could be claimable + /// after the epoch finishes and the state of the network does not change. pub estimation: Option, + + /// The full reward estimation. Note that it's nearly identical to `estimation`, + /// however, it contains few additional decimal points for more accurate reward calculation. pub detailed_estimation_amount: Option, } @@ -68,3 +99,13 @@ impl EstimatedCurrentEpochRewardResponse { } } } + +/// Response containing paged list of all mixnodes in the rewarded set. +#[cw_serde] +pub struct PagedRewardedSetResponse { + /// Nodes in the current rewarded set. + pub nodes: Vec<(MixId, RewardedSetNodeStatus)>, + + /// Field indicating paging information for the following queries if the caller wishes to get further entries. + pub start_next_after: Option, +} diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/signing.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/signing.rs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/types.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/types.rs index e0a8109f98..e1ff854bb9 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/types.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/types.rs @@ -2,29 +2,26 @@ // SPDX-License-Identifier: Apache-2.0 use crate::error::MixnetContractError; -use crate::families::{Family, FamilyHead}; -use crate::{Layer, RewardedSetNodeStatus}; -use contracts_common::IdentityKey; +use crate::Layer; +use cosmwasm_schema::cw_serde; use cosmwasm_std::Addr; use cosmwasm_std::Coin; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; use std::ops::Index; // type aliases for better reasoning about available data pub type SphinxKey = String; pub type SphinxKeyRef<'a> = &'a str; -pub type EpochId = u32; -pub type IntervalId = u32; + pub type MixId = u32; pub type BlockHeight = u64; -pub type EpochEventId = u32; -pub type IntervalEventId = u32; -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, PartialEq, Eq)] +/// Specifies layer assignment for the given mixnode. +#[cw_serde] pub struct LayerAssignment { + /// The id of the mixnode. mix_id: MixId, + + /// The layer to which it's going to be assigned layer: Layer, } @@ -42,10 +39,17 @@ impl LayerAssignment { } } -#[derive(Debug, Default, Serialize, Deserialize, Copy, Clone, Eq, PartialEq)] +/// The current layer distribution of the mix network. +#[cw_serde] +#[derive(Copy, Default)] pub struct LayerDistribution { + /// Number of nodes on the first layer. pub layer1: u64, + + /// Number of nodes on the second layer. pub layer2: u64, + + /// Number of nodes on the third layer. pub layer3: u64, } @@ -118,19 +122,29 @@ impl Index for LayerDistribution { } } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +/// The current state of the mixnet contract. +#[cw_serde] pub struct ContractState { - pub owner: Addr, // only the owner account can update state + /// Address of the contract owner. + pub owner: Addr, + + /// Address of "rewarding validator" (nym-api) that's allowed to send any rewarding-related transactions. pub rewarding_validator_address: Addr, /// Address of the vesting contract to which the mixnet contract would be sending all /// track-related messages. pub vesting_contract_address: Addr, + + /// The expected denom used for rewarding (and realistically any other operation). + /// Default: `unym` pub rewarding_denom: String, + + /// Contract parameters that could be adjusted in a transaction the contract admin. pub params: ContractStateParams, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +/// Contract parameters that could be adjusted in a transaction by the contract admin. +#[cw_serde] pub struct ContractStateParams { /// Minimum amount a delegator must stake in orders for his delegation to get accepted. pub minimum_mixnode_delegation: Option, @@ -141,21 +155,3 @@ pub struct ContractStateParams { /// Minimum amount a gateway must pledge to get into the system. pub minimum_gateway_pledge: Coin, } - -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, JsonSchema)] -pub struct PagedRewardedSetResponse { - pub nodes: Vec<(MixId, RewardedSetNodeStatus)>, - pub start_next_after: Option, -} - -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, JsonSchema)] -pub struct PagedFamiliesResponse { - pub families: Vec, - pub start_next_after: Option, -} - -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, JsonSchema)] -pub struct PagedMembersResponse { - pub members: Vec<(IdentityKey, FamilyHead)>, - pub start_next_after: Option, -} diff --git a/common/cosmwasm-smart-contracts/multisig-contract/Cargo.toml b/common/cosmwasm-smart-contracts/multisig-contract/Cargo.toml index 2a6753267e..d419e25086 100644 --- a/common/cosmwasm-smart-contracts/multisig-contract/Cargo.toml +++ b/common/cosmwasm-smart-contracts/multisig-contract/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" [dependencies] cw-utils = { workspace = true } cw3 = { workspace = true } -cw4 = { workspace= true } +cw4 = { workspace = true } cw-storage-plus = { workspace = true } cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } diff --git a/common/cosmwasm-smart-contracts/name-service/Cargo.toml b/common/cosmwasm-smart-contracts/name-service/Cargo.toml index 23fb221e23..4af7d851f1 100644 --- a/common/cosmwasm-smart-contracts/name-service/Cargo.toml +++ b/common/cosmwasm-smart-contracts/name-service/Cargo.toml @@ -6,10 +6,14 @@ edition = "2021" # 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" } -schemars = "0.8" serde = { workspace = true, features = ["derive"] } thiserror = { workspace = true } + +[features] +schema = ["cw2"] \ No newline at end of file diff --git a/common/cosmwasm-smart-contracts/name-service/src/msg.rs b/common/cosmwasm-smart-contracts/name-service/src/msg.rs index 9a8e2b8ecf..cdac95c215 100644 --- a/common/cosmwasm-smart-contracts/name-service/src/msg.rs +++ b/common/cosmwasm-smart-contracts/name-service/src/msg.rs @@ -1,10 +1,22 @@ +// Copyright 2023 - Nym Technologies SA +// 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; -use serde::{Deserialize, Serialize}; -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] -#[serde(rename_all = "snake_case")] +#[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, } @@ -15,22 +27,23 @@ impl InstantiateMsg { } } -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub struct MigrateMsg {} -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] -#[serde(rename_all = "snake_case")] +#[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 }, } @@ -61,33 +74,42 @@ impl ExecuteMsg { } } -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] -#[serde(rename_all = "snake_case")] +#[cw_serde] +#[cfg_attr(feature = "schema", derive(QueryResponses))] pub enum QueryMsg { /// Query the name by it's assigned id - NameId { - name_id: NameId, - }, - // Query the names by the registrator - ByOwner { - owner: String, - }, - ByName { - name: NymName, - }, - ByAddress { - address: Address, - }, + #[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, start_after: Option, }, - SigningNonce { - address: String, - }, + + #[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 {}, } diff --git a/common/cosmwasm-smart-contracts/name-service/src/response.rs b/common/cosmwasm-smart-contracts/name-service/src/response.rs index 8087195eee..162021d7c7 100644 --- a/common/cosmwasm-smart-contracts/name-service/src/response.rs +++ b/common/cosmwasm-smart-contracts/name-service/src/response.rs @@ -1,10 +1,11 @@ -use crate::{NameId, RegisteredName}; -use cosmwasm_std::Coin; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)] -#[serde(rename_all = "snake_case")] +use crate::{NameId, RegisteredName}; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::Coin; + +#[cw_serde] pub struct NamesListResponse { pub names: Vec, } @@ -23,11 +24,12 @@ impl From<&[RegisteredName]> for NamesListResponse { } } -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub struct PagedNamesListResponse { pub names: Vec, 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, } @@ -45,8 +47,7 @@ impl PagedNamesListResponse { } } -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub struct ConfigResponse { pub deposit_required: Coin, } diff --git a/common/cosmwasm-smart-contracts/name-service/src/types.rs b/common/cosmwasm-smart-contracts/name-service/src/types.rs index dd44340815..c595e82452 100644 --- a/common/cosmwasm-smart-contracts/name-service/src/types.rs +++ b/common/cosmwasm-smart-contracts/name-service/src/types.rs @@ -1,14 +1,15 @@ -use std::fmt::{Display, Formatter}; +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 +use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Coin}; use nym_contracts_common::IdentityKey; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; +use std::fmt::{Display, Formatter}; /// The directory of names are indexed by [`NameId`]. pub type NameId = u32; -#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, JsonSchema)] +#[cw_serde] pub struct RegisteredName { /// Unique id assigned to the registerd name. pub id: NameId, @@ -33,7 +34,7 @@ impl RegisteredName { } } -#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, JsonSchema)] +#[cw_serde] pub struct NameDetails { /// The name pointing to the nym address pub name: NymName, @@ -48,8 +49,7 @@ pub struct NameDetails { /// String representation of a nym address, which is of the form /// client_id.client_enc@gateway_id. /// NOTE: entirely unvalidated. -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum Address { NymAddress(String), // Possible extension: @@ -83,8 +83,7 @@ impl Display for Address { } /// Name stored and pointing a to a nym-address -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub struct NymName(String); #[derive(Debug)] diff --git a/common/cosmwasm-smart-contracts/service-provider-directory/Cargo.toml b/common/cosmwasm-smart-contracts/service-provider-directory/Cargo.toml index 3965734b2d..aed3912abd 100644 --- a/common/cosmwasm-smart-contracts/service-provider-directory/Cargo.toml +++ b/common/cosmwasm-smart-contracts/service-provider-directory/Cargo.toml @@ -6,10 +6,13 @@ edition = "2021" # 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" } -schemars = "0.8" -serde = { workspace = true, features = ["derive"] } thiserror = { workspace = true } + +[features] +schema = ["cw2"] \ No newline at end of file diff --git a/common/cosmwasm-smart-contracts/service-provider-directory/src/msg.rs b/common/cosmwasm-smart-contracts/service-provider-directory/src/msg.rs index f66ad787a5..0c7928e079 100644 --- a/common/cosmwasm-smart-contracts/service-provider-directory/src/msg.rs +++ b/common/cosmwasm-smart-contracts/service-provider-directory/src/msg.rs @@ -1,10 +1,22 @@ +// Copyright 2023 - Nym Technologies SA +// 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; -use serde::{Deserialize, Serialize}; -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] -#[serde(rename_all = "snake_case")] +#[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, } @@ -15,12 +27,10 @@ impl InstantiateMsg { } } -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub struct MigrateMsg {} -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum ExecuteMsg { Announce { service: ServiceDetails, @@ -64,28 +74,37 @@ impl ExecuteMsg { } } -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] -#[serde(rename_all = "snake_case")] +#[cw_serde] +#[cfg_attr(feature = "schema", derive(QueryResponses))] pub enum QueryMsg { - ServiceId { - service_id: ServiceId, - }, - ByAnnouncer { - announcer: String, - }, - ByNymAddress { - nym_address: NymAddress, - }, + #[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, start_after: Option, }, - SigningNonce { - address: String, - }, + + #[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 {}, } diff --git a/common/cosmwasm-smart-contracts/service-provider-directory/src/response.rs b/common/cosmwasm-smart-contracts/service-provider-directory/src/response.rs index 8b6bf16fbf..dd9392c2d9 100644 --- a/common/cosmwasm-smart-contracts/service-provider-directory/src/response.rs +++ b/common/cosmwasm-smart-contracts/service-provider-directory/src/response.rs @@ -1,17 +1,17 @@ -use crate::{Service, ServiceId}; -use cosmwasm_std::Coin; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] -#[serde(rename_all = "snake_case")] +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, } -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub struct ServicesListResponse { pub services: Vec, } @@ -30,11 +30,12 @@ impl From<&[Service]> for ServicesListResponse { } } -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub struct PagedServicesListResponse { pub services: Vec, 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, } @@ -52,8 +53,7 @@ impl PagedServicesListResponse { } } -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub struct ConfigResponse { pub deposit_required: Coin, } diff --git a/common/cosmwasm-smart-contracts/service-provider-directory/src/signing_types.rs b/common/cosmwasm-smart-contracts/service-provider-directory/src/signing_types.rs index 742470b2cd..fb9752d10a 100644 --- a/common/cosmwasm-smart-contracts/service-provider-directory/src/signing_types.rs +++ b/common/cosmwasm-smart-contracts/service-provider-directory/src/signing_types.rs @@ -1,15 +1,17 @@ +// Copyright 2023 - Nym Technologies SA +// 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, }; -use serde::Serialize; - -use crate::ServiceDetails; pub type SignableServiceProviderAnnounceMsg = SignableMessage>; -#[derive(Serialize)] +#[cw_serde] pub struct ServiceProviderAnnounce { service: ServiceDetails, } diff --git a/common/cosmwasm-smart-contracts/service-provider-directory/src/types.rs b/common/cosmwasm-smart-contracts/service-provider-directory/src/types.rs index c3ad296fa2..845c05b768 100644 --- a/common/cosmwasm-smart-contracts/service-provider-directory/src/types.rs +++ b/common/cosmwasm-smart-contracts/service-provider-directory/src/types.rs @@ -1,14 +1,15 @@ -use std::fmt::{Display, Formatter}; +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 +use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Coin}; use nym_contracts_common::IdentityKey; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; +use std::fmt::{Display, Formatter}; /// The directory of services are indexed by [`ServiceId`]. pub type ServiceId = u32; -#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, JsonSchema)] +#[cw_serde] pub struct Service { /// Unique id assigned to the anounced service. pub service_id: ServiceId, @@ -22,7 +23,7 @@ pub struct Service { pub deposit: Coin, } -#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, JsonSchema)] +#[cw_serde] pub struct ServiceDetails { /// The address of the service. pub nym_address: NymAddress, @@ -33,8 +34,7 @@ pub struct ServiceDetails { } /// The types of addresses supported. -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum NymAddress { /// String representation of a nym address, which is of the form /// client_id.client_enc@gateway_id. @@ -64,8 +64,7 @@ impl Display for NymAddress { } /// The type of services provider supported -#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Debug, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum ServiceType { NetworkRequester, } diff --git a/common/cosmwasm-smart-contracts/vesting-contract/Cargo.toml b/common/cosmwasm-smart-contracts/vesting-contract/Cargo.toml index 516f8a8e35..f5fa35df5f 100644 --- a/common/cosmwasm-smart-contracts/vesting-contract/Cargo.toml +++ b/common/cosmwasm-smart-contracts/vesting-contract/Cargo.toml @@ -9,11 +9,14 @@ repository = { workspace = true } [dependencies] cosmwasm-std = { workspace = true } +cosmwasm-schema = { workspace = true } +cw2 = { workspace = true, optional = true } mixnet-contract-common = { path = "../mixnet-contract", package = "nym-mixnet-contract-common", version = "0.6.0" } contracts-common = { path = "../contracts-common", package = "nym-contracts-common", version = "0.5.0" } serde = { version = "1.0", features = ["derive"] } -schemars = "0.8" +thiserror = "1.0" ts-rs = {version = "6.1.2", optional = true} [features] +schema = ["cw2"] generate-ts = ["ts-rs"] diff --git a/common/cosmwasm-smart-contracts/vesting-contract/src/account.rs b/common/cosmwasm-smart-contracts/vesting-contract/src/account.rs new file mode 100644 index 0000000000..0d1e5b754e --- /dev/null +++ b/common/cosmwasm-smart-contracts/vesting-contract/src/account.rs @@ -0,0 +1,124 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::{Period, PledgeCap, VestingContractError, VestingPeriod}; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, Coin, Timestamp}; + +// this shouldn't really be exposed like this, but we really don't want to migrate the contract just for this... +pub type VestingAccountStorageKey = u32; + +/// Vesting account information. +#[cw_serde] +pub struct Account { + /// Address of the owner of the vesting account. + pub owner_address: Addr, + + /// Optional address of an account allowed to perform staking on behalf of the owner. + pub staking_address: Option, + + /// The starting vesting time. + pub start_time: Timestamp, + + /// All vesting periods for this account. + pub periods: Vec, + + /// The initial amount of coins used creation of this account. + pub coin: Coin, + + /// The id/storage_key of this vesting account. + pub storage_key: VestingAccountStorageKey, + + /// Optional custom pledge cap of this vesting account. + #[serde(default)] + pub pledge_cap: Option, +} + +impl Account { + pub fn pledge_cap(&self) -> PledgeCap { + self.pledge_cap.clone().unwrap_or_default() + } + + pub fn coin(&self) -> Coin { + self.coin.clone() + } + + pub fn num_vesting_periods(&self) -> usize { + self.periods.len() + } + + pub fn period_duration(&self) -> Result { + self.periods + .get(0) + .ok_or(VestingContractError::UnpopulatedVestingPeriods { + owner: self.owner_address.clone(), + }) + .map(|p| p.period_seconds) + } + + pub fn storage_key(&self) -> u32 { + self.storage_key + } + + pub fn owner_address(&self) -> Addr { + self.owner_address.clone() + } + + pub fn staking_address(&self) -> Option<&Addr> { + self.staking_address.as_ref() + } + + pub fn periods(&self) -> Vec { + self.periods.clone() + } + + pub fn start_time(&self) -> Timestamp { + self.start_time + } + + pub fn tokens_per_period(&self) -> Result { + let amount = self.coin.amount.u128(); + if amount < self.num_vesting_periods() as u128 { + Err(VestingContractError::ImprobableVestingAmount(amount)) + } else { + // Remainder tokens will be lumped into the last period. + Ok(amount / self.num_vesting_periods() as u128) + } + } + + /// Returns the index of the next vesting period. Unless the current time is somehow in the past or vesting has not started yet. + /// In case vesting is over it will always return NUM_VESTING_PERIODS. + pub fn get_current_vesting_period( + &self, + block_time: Timestamp, + ) -> Result { + let first_period = + self.periods + .first() + .ok_or(VestingContractError::UnpopulatedVestingPeriods { + owner: self.owner_address.clone(), + })?; + + let last_period = + self.periods + .last() + .ok_or(VestingContractError::UnpopulatedVestingPeriods { + owner: self.owner_address.clone(), + })?; + + if block_time.seconds() < first_period.start_time { + Ok(Period::Before) + } else if last_period.end_time() < block_time { + Ok(Period::After) + } else { + let mut index = 0; + for period in &self.periods { + if block_time < period.end_time() { + break; + } + index += 1; + } + Ok(Period::In(index)) + } + } +} diff --git a/contracts/vesting/src/errors.rs b/common/cosmwasm-smart-contracts/vesting-contract/src/error.rs similarity index 92% rename from contracts/vesting/src/errors.rs rename to common/cosmwasm-smart-contracts/vesting-contract/src/error.rs index 2b92be0c8c..65825c6ad9 100644 --- a/contracts/vesting/src/errors.rs +++ b/common/cosmwasm-smart-contracts/vesting-contract/src/error.rs @@ -1,10 +1,13 @@ -use crate::storage::AccountStorageKey; +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::account::VestingAccountStorageKey; use cosmwasm_std::{Addr, Coin, OverflowError, StdError, Uint128}; use mixnet_contract_common::MixId; use thiserror::Error; #[derive(Error, Debug, PartialEq)] -pub enum ContractError { +pub enum VestingContractError { #[error("VESTING ({}): {0}", line!())] Std(#[from] StdError), @@ -27,7 +30,7 @@ pub enum ContractError { InsufficientSpendable(String, u128), #[error( - "VESTING ({}):Only delegation owner can perform delegation actions, {0} is not the delegation owner" + "VESTING ({}):Only delegation owner can perform delegation actions, {0} is not the delegation owner" , line!())] NotDelegate(String), @@ -91,7 +94,7 @@ pub enum ContractError { #[error("VESTING: {address} ({acc_id} has already performed {num} individual delegations towards {mix_id}. No further delegations are allowed. Please consider consolidating those delegations instead. The current cap is {cap}.")] TooManyDelegations { address: Addr, - acc_id: AccountStorageKey, + acc_id: VestingAccountStorageKey, mix_id: MixId, num: u32, cap: u32, diff --git a/common/cosmwasm-smart-contracts/vesting-contract/src/lib.rs b/common/cosmwasm-smart-contracts/vesting-contract/src/lib.rs index 6c456674a5..31fab7a7ef 100644 --- a/common/cosmwasm-smart-contracts/vesting-contract/src/lib.rs +++ b/common/cosmwasm-smart-contracts/vesting-contract/src/lib.rs @@ -4,83 +4,31 @@ #![warn(clippy::expect_used)] #![warn(clippy::unwrap_used)] -use contracts_common::Percent; -use cosmwasm_std::{Addr, Coin, Timestamp, Uint128}; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, Coin}; use mixnet_contract_common::MixId; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; -use std::str::FromStr; - -pub use messages::{ExecuteMsg, InitMsg, MigrateMsg, QueryMsg}; +pub mod account; +pub mod error; pub mod events; pub mod messages; +pub mod types; -#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))] -#[cfg_attr( - feature = "generate-ts", - ts(export_to = "ts-packages/types/src/types/rust/Period.ts") -)] -#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Clone, JsonSchema)] -pub enum Period { - Before, - In(usize), - After, -} +pub use account::Account; +pub use error::VestingContractError; +pub use messages::{ExecuteMsg, InitMsg, MigrateMsg, QueryMsg}; +pub use types::*; -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub struct PledgeData { - pub amount: Coin, - pub block_time: Timestamp, -} - -impl PledgeData { - pub fn amount(&self) -> Coin { - self.amount.clone() - } - - pub fn block_time(&self) -> Timestamp { - self.block_time - } - - pub fn new(amount: Coin, block_time: Timestamp) -> Self { - Self { amount, block_time } - } -} - -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub enum PledgeCap { - Percent(Percent), - Absolute(Uint128), // This has to be in unym -} - -impl FromStr for PledgeCap { - type Err = String; - - fn from_str(cap: &str) -> Result { - let cap = cap.replace('_', "").replace(',', "."); - match Percent::from_str(&cap) { - Ok(p) => Ok(PledgeCap::Percent(p)), - Err(_) => match cap.parse::() { - Ok(i) => Ok(PledgeCap::Absolute(Uint128::from(i))), - Err(_e) => Err(format!("Could not parse {cap} as Percent or Uint128")), - }, - } - } -} - -impl Default for PledgeCap { - fn default() -> Self { - #[allow(clippy::expect_used)] - PledgeCap::Percent(Percent::from_percentage_value(10).expect("This can never fail!")) - } -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +/// Details about the original vesting specification used when the account was created. +#[cw_serde] pub struct OriginalVestingResponse { + /// The original amount that was used for the creation of this vesting account pub amount: Coin, + + /// The number of vesting periods that the account was created with pub number_of_periods: usize, + + /// Duration of each vesting period in seconds pub period_duration: u64, } @@ -106,57 +54,73 @@ impl OriginalVestingResponse { } } -#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Clone, JsonSchema)] -pub struct VestingDelegation { - pub account_id: u32, - pub mix_id: MixId, - pub block_timestamp: u64, - pub amount: Uint128, -} - -impl VestingDelegation { - pub fn storage_key(&self) -> (u32, MixId, u64) { - (self.account_id, self.mix_id, self.block_timestamp) - } -} - -#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Clone, JsonSchema)] +/// Response containing timestamps of all delegations made towards particular mixnode by given vesting account. +#[cw_serde] pub struct DelegationTimesResponse { + /// Address of this account's owner pub owner: Addr, + + /// Id associated with this account pub account_id: u32, + + /// Id of the mixnode towards which the delegation was made pub mix_id: MixId, + + /// All timestamps where a delegation was made pub delegation_timestamps: Vec, } -#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Clone, JsonSchema)] +/// Response containing paged list of all vesting delegations made using vesting coins. +#[cw_serde] pub struct AllDelegationsResponse { + /// The actual vesting delegations made. pub delegations: Vec, + + /// Field indicating paging information for the following queries if the caller wishes to get further entries. pub start_next_after: Option<(u32, MixId, u64)>, } -#[derive(Debug, Serialize, Deserialize, Clone, JsonSchema)] +/// Basic information regarding particular vesting account alongside the amount of vesting coins. +#[cw_serde] pub struct AccountVestingCoins { + /// Id associated with this account pub account_id: u32, + + /// Address of this account's owner pub owner: Addr, + + /// Coins that are still vesting belonging to this account. pub still_vesting: Coin, } -#[derive(Debug, Serialize, Deserialize, Clone, JsonSchema)] +/// Response containing vesting coins held in this contract +#[cw_serde] pub struct VestingCoinsResponse { + /// The actual accounts, and their vesting coins, returned by the query. pub accounts: Vec, + + /// Field indicating paging information for the following queries if the caller wishes to get further entries. pub start_next_after: Option, } -#[derive(Debug, Serialize, Deserialize, Clone, JsonSchema)] +/// Basic information regarding particular vesting account +#[cw_serde] pub struct BaseVestingAccountInfo { + /// Id associated with this account pub account_id: u32, + + /// Address of this account's owner pub owner: Addr, // TODO: should this particular query/response expose anything else? } -#[derive(Debug, Serialize, Deserialize, Clone, JsonSchema)] +/// Response containing basic vesting account information +#[cw_serde] pub struct AccountsResponse { + /// The actual accounts returned by the query. pub accounts: Vec, + + /// Field indicating paging information for the following queries if the caller wishes to get further entries. pub start_next_after: Option, } diff --git a/common/cosmwasm-smart-contracts/vesting-contract/src/messages.rs b/common/cosmwasm-smart-contracts/vesting-contract/src/messages.rs index f4d7147e2c..6593926445 100644 --- a/common/cosmwasm-smart-contracts/vesting-contract/src/messages.rs +++ b/common/cosmwasm-smart-contracts/vesting-contract/src/messages.rs @@ -1,4 +1,9 @@ +// Copyright 2021-2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::{PledgeCap, VestingSpecification}; use contracts_common::signing::MessageSignature; +use cosmwasm_schema::cw_serde; use cosmwasm_std::{Coin, Timestamp}; use mixnet_contract_common::families::FamilyHead; use mixnet_contract_common::{ @@ -6,57 +11,30 @@ use mixnet_contract_common::{ mixnode::{MixNodeConfigUpdate, MixNodeCostParams}, Gateway, IdentityKey, MixId, MixNode, }; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; -use crate::PledgeCap; +#[cfg(feature = "schema")] +use contracts_common::ContractBuildInformation; +#[cfg(feature = "schema")] +use cosmwasm_schema::QueryResponses; -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cfg(feature = "schema")] +use crate::{ + account::Account, + types::{Period, PledgeData, VestingDelegation}, + AccountsResponse, AllDelegationsResponse, DelegationTimesResponse, OriginalVestingResponse, + VestingCoinsResponse, +}; + +#[cw_serde] pub struct InitMsg { pub mixnet_contract_address: String, pub mix_denom: String, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub struct MigrateMsg {} -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, Default)] -pub struct VestingSpecification { - start_time: Option, - period_seconds: Option, - num_periods: Option, -} - -impl VestingSpecification { - pub fn new( - start_time: Option, - period_seconds: Option, - num_periods: Option, - ) -> Self { - Self { - start_time, - period_seconds, - num_periods, - } - } - - pub fn start_time(&self) -> Option { - self.start_time - } - - pub fn period_seconds(&self) -> u64 { - self.period_seconds.unwrap_or(3 * 30 * 86400) - } - - pub fn num_periods(&self) -> u64 { - self.num_periods.unwrap_or(8) - } -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum ExecuteMsg { // Families /// Only owner of the node can crate the family with node as head @@ -197,93 +175,226 @@ impl ExecuteMsg { } } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] +/// Queries exposed by this contract. +#[cw_serde] +#[cfg_attr(feature = "schema", derive(QueryResponses))] pub enum QueryMsg { + /// 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 {}, + + /// Gets the list of vesting accounts held in this contract. + #[cfg_attr(feature = "schema", returns(AccountsResponse))] GetAccountsPaged { + /// Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response. start_next_after: Option, + + /// Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default. limit: Option, }, + + /// Gets the list of coins that are still vesting for each account held in this contract. + #[cfg_attr(feature = "schema", returns(VestingCoinsResponse))] GetAccountsVestingCoinsPaged { + /// Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response. start_next_after: Option, + + /// Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default. limit: Option, }, + + /// Returns the amount of locked coins for the provided vesting account, + /// i.e. coins that are still vesting but have not been staked. + /// `locked_coins = vesting_coins - staked_coins` + #[cfg_attr(feature = "schema", returns(Coin))] LockedCoins { + /// Address of the vesting account in question. vesting_account_address: String, + + /// (deprecated) Optional argument specifying that the query should be performed against non-current block. block_time: Option, }, + + /// Returns the amount of spendable coins for the provided vesting account, + /// i.e. coins that could be withdrawn. + /// `spendable_coins = account_balance - locked_coins` + /// note: `account_balance` is the amount of coins still physically present in this contract, i.e. not withdrawn or staked. + #[cfg_attr(feature = "schema", returns(Coin))] SpendableCoins { + /// Address of the vesting account in question. vesting_account_address: String, + + /// (deprecated) Optional argument specifying that the query should be performed against non-current block. block_time: Option, }, + + /// Returns the amount of coins that have already vested for the provided vesting account address. + #[cfg_attr(feature = "schema", returns(Coin))] GetVestedCoins { + /// Address of the vesting account in question. vesting_account_address: String, + + /// (deprecated) Optional argument specifying that the query should be performed against non-current block. block_time: Option, }, + + /// Returns the amount of coins that are still vesting for the provided vesting account address. + #[cfg_attr(feature = "schema", returns(Coin))] GetVestingCoins { + /// Address of the vesting account in question. vesting_account_address: String, + + /// (deprecated) Optional argument specifying that the query should be performed against non-current block. block_time: Option, }, + + /// Returns the starting vesting time for the provided vesting account, + /// i.e. the beginning of the first vesting period. + #[cfg_attr(feature = "schema", returns(Timestamp))] GetStartTime { + /// Address of the vesting account in question. vesting_account_address: String, }, + + /// Returns the ending vesting time for the provided vesting account, + /// i.e. the end of the last vesting period. + #[cfg_attr(feature = "schema", returns(Timestamp))] GetEndTime { + /// Address of the vesting account in question. vesting_account_address: String, }, + + /// Returns the initial vesting specification used for the provided vesting account address. + #[cfg_attr(feature = "schema", returns(OriginalVestingResponse))] GetOriginalVesting { + /// Address of the vesting account in question. vesting_account_address: String, }, + + /// Returns the total amount of coins accrued through claimed staking rewards by the provided vesting account. + #[cfg_attr(feature = "schema", returns(Coin))] GetHistoricalVestingStakingReward { + /// Address of the vesting account in question. vesting_account_address: String, }, + + /// Returns the amount of spendable vesting coins for the provided vesting account, + /// i.e. coins that could be withdrawn that originated from the vesting specification. + #[cfg_attr(feature = "schema", returns(Coin))] GetSpendableVestedCoins { + /// Address of the vesting account in question. vesting_account_address: String, }, + + /// Returns the amount of spendable reward coins for the provided vesting account, + /// i.e. coins that could be withdrawn that originated from the claimed staking rewards. + #[cfg_attr(feature = "schema", returns(Coin))] GetSpendableRewardCoins { + /// Address of the vesting account in question. vesting_account_address: String, }, + + /// Returns the amount of coins that are currently delegated for the provided vesting account address. + #[cfg_attr(feature = "schema", returns(Coin))] GetDelegatedCoins { + /// Address of the vesting account in question. vesting_account_address: String, }, + + /// Returns the amount of coins that are currently pledged for the provided vesting account address. + #[cfg_attr(feature = "schema", returns(Coin))] GetPledgedCoins { + /// Address of the vesting account in question. vesting_account_address: String, }, + + /// Returns the amount of coins that are currently staked (i.e. delegations + pledges) for the provided vesting account address. + #[cfg_attr(feature = "schema", returns(Coin))] GetStakedCoins { + /// Address of the vesting account in question. vesting_account_address: String, }, + + /// Returns the amount of coins that got withdrawn for the provided vesting account address. + #[cfg_attr(feature = "schema", returns(Coin))] GetWithdrawnCoins { + /// Address of the vesting account in question. vesting_account_address: String, }, + + /// Returns detailed information associated with the account for the provided vesting account address. + #[cfg_attr(feature = "schema", returns(Account))] GetAccount { + /// Address of the vesting account in question. address: String, }, + + /// Returns pledge information (if applicable) for bonded mixnode for the provided vesting account address. + #[cfg_attr(feature = "schema", returns(Option))] GetMixnode { + /// Address of the vesting account in question. address: String, }, + + /// Returns pledge information (if applicable) for bonded gateway for the provided vesting account address. + #[cfg_attr(feature = "schema", returns(Option))] GetGateway { + /// Address of the vesting account in question. address: String, }, + + /// Returns the current vesting period for the provided vesting account address. + #[cfg_attr(feature = "schema", returns(Period))] GetCurrentVestingPeriod { + /// Address of the vesting account in question. address: String, }, + + /// Returns the information about particular vesting delegation. + #[cfg_attr(feature = "schema", returns(VestingDelegation))] GetDelegation { + /// Address of the vesting account in question. address: String, + + /// Id of the mixnode towards which the delegation has been made. mix_id: MixId, + + /// Block timestamp of the delegation. block_timestamp_secs: u64, }, + + /// Returns the total amount of coins delegated towards particular mixnode by the provided vesting account address. + #[cfg_attr(feature = "schema", returns(Coin))] GetTotalDelegationAmount { + /// Address of the vesting account in question. address: String, + + /// Id of the mixnode towards which the delegations have been made. mix_id: MixId, }, + + /// Returns timestamps of delegations made towards particular mixnode by the provided vesting account address. + #[cfg_attr(feature = "schema", returns(DelegationTimesResponse))] GetDelegationTimes { + /// Address of the vesting account in question. address: String, + + /// Id of the mixnode towards which the delegations have been made. mix_id: MixId, }, + + /// Returns all active delegations made with vesting tokens stored in this contract. + #[cfg_attr(feature = "schema", returns(AllDelegationsResponse))] GetAllDelegations { + /// Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response. start_after: Option<(u32, MixId, u64)>, + + /// Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default. limit: Option, }, } diff --git a/common/cosmwasm-smart-contracts/vesting-contract/src/types.rs b/common/cosmwasm-smart-contracts/vesting-contract/src/types.rs new file mode 100644 index 0000000000..60fd3c0aea --- /dev/null +++ b/common/cosmwasm-smart-contracts/vesting-contract/src/types.rs @@ -0,0 +1,166 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use contracts_common::Percent; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Coin, Timestamp, Uint128}; +use mixnet_contract_common::MixId; +use std::str::FromStr; + +#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))] +#[cfg_attr( + feature = "generate-ts", + ts(export_to = "ts-packages/types/src/types/rust/Period.ts") +)] +#[cw_serde] +/// The vesting period. +pub enum Period { + /// Defines a pre-vesting period. + Before, + + /// Defines currently active vesting period. + In(usize), + + /// Defines a post-vesting period. + After, +} + +/// Information regarding pledge (i.e. mixnode or gateway bonding) made with vesting tokens. +#[cw_serde] +pub struct PledgeData { + /// The amount pledged. + pub amount: Coin, + + /// The block timestamp where the pledge occurred. + pub block_time: Timestamp, +} + +impl PledgeData { + pub fn amount(&self) -> Coin { + self.amount.clone() + } + + pub fn block_time(&self) -> Timestamp { + self.block_time + } + + pub fn new(amount: Coin, block_time: Timestamp) -> Self { + Self { amount, block_time } + } +} + +/// Defines cap for pleding/staking tokens. +#[cw_serde] +pub enum PledgeCap { + /// Specifies a percent-based pledge cap, i.e. only given % of tokens could be pledged/staked. + Percent(Percent), + + /// Specifies an absolute pledge cap, i.e. an explicit value that could be pledged/staked. + Absolute(Uint128), // This has to be in unym +} + +impl FromStr for PledgeCap { + type Err = String; + + fn from_str(cap: &str) -> Result { + let cap = cap.replace('_', "").replace(',', "."); + match Percent::from_str(&cap) { + Ok(p) => Ok(PledgeCap::Percent(p)), + Err(_) => match cap.parse::() { + Ok(i) => Ok(PledgeCap::Absolute(Uint128::from(i))), + Err(_e) => Err(format!("Could not parse {cap} as Percent or Uint128")), + }, + } + } +} + +impl Default for PledgeCap { + fn default() -> Self { + #[allow(clippy::expect_used)] + PledgeCap::Percent(Percent::from_percentage_value(10).expect("This can never fail!")) + } +} + +/// Vesting period details. +#[cw_serde] +pub struct VestingPeriod { + /// The start time of this vesting period, as unix timestamp. + pub start_time: u64, + + /// The duration (in seconds) of the vesting period. + pub period_seconds: u64, +} + +impl VestingPeriod { + pub fn end_time(&self) -> Timestamp { + Timestamp::from_seconds(self.start_time + self.period_seconds) + } +} + +#[cw_serde] +#[derive(Default)] +pub struct VestingSpecification { + start_time: Option, + period_seconds: Option, + num_periods: Option, +} + +impl VestingSpecification { + pub fn new( + start_time: Option, + period_seconds: Option, + num_periods: Option, + ) -> Self { + Self { + start_time, + period_seconds, + num_periods, + } + } + + pub fn start_time(&self) -> Option { + self.start_time + } + + pub fn period_seconds(&self) -> u64 { + self.period_seconds.unwrap_or(3 * 30 * 86400) + } + + pub fn num_periods(&self) -> u64 { + self.num_periods.unwrap_or(8) + } + + pub fn populate_vesting_periods(&self, start_time: u64) -> Vec { + let mut periods = Vec::with_capacity(self.num_periods() as usize); + for i in 0..self.num_periods() { + let period = VestingPeriod { + start_time: start_time + i * self.period_seconds(), + period_seconds: self.period_seconds(), + }; + periods.push(period); + } + periods + } +} + +/// Details about particular vesting delegation. +#[cw_serde] +pub struct VestingDelegation { + /// The id of the vesting account that has made the delegation. + pub account_id: u32, + + /// The id of the mixnode towards which the delegation has been made. + pub mix_id: MixId, + + /// The block timestamp when the delegation has been made. + pub block_timestamp: u64, + + /// The raw amount delegated (interpreted to be in the same denom as the underlying vesting specification) + pub amount: Uint128, +} + +impl VestingDelegation { + pub fn storage_key(&self) -> (u32, MixId, u64) { + (self.account_id, self.mix_id, self.block_timestamp) + } +} diff --git a/common/types/Cargo.toml b/common/types/Cargo.toml index c99bbf3e30..cbf12b4364 100644 --- a/common/types/Cargo.toml +++ b/common/types/Cargo.toml @@ -27,8 +27,7 @@ nym-mixnet-contract-common = { path = "../../common/cosmwasm-smart-contracts/mix nym-vesting-contract-common = { path = "../../common/cosmwasm-smart-contracts/vesting-contract" } nym-config = { path = "../../common/config" } nym-coconut-interface = { path = "../../common/coconut-interface" } -# Used for Type conversion, can be extracted but its a lot of work -nym-vesting-contract = { path = "../../contracts/vesting" } + [dev-dependencies] tempfile = "3.3.0" diff --git a/common/types/src/delegation.rs b/common/types/src/delegation.rs index 399bf7b91b..550f17a261 100644 --- a/common/types/src/delegation.rs +++ b/common/types/src/delegation.rs @@ -41,7 +41,7 @@ impl Delegation { feature = "generate-ts", ts(export_to = "ts-packages/types/src/types/rust/DelegationWithEverything.ts") )] -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, JsonSchema)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, JsonSchema)] pub struct DelegationWithEverything { pub owner: String, pub mix_id: MixId, diff --git a/common/types/src/mixnode.rs b/common/types/src/mixnode.rs index 145f9c409f..02246aad68 100644 --- a/common/types/src/mixnode.rs +++ b/common/types/src/mixnode.rs @@ -20,7 +20,7 @@ use std::net::IpAddr; feature = "generate-ts", ts(export_to = "ts-packages/types/src/types/rust/MixNodeDetails.ts") )] -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] pub struct MixNodeDetails { pub bond_information: MixNodeBond, pub rewarding_details: MixNodeRewarding, @@ -49,7 +49,7 @@ impl MixNodeDetails { feature = "generate-ts", ts(export_to = "ts-packages/types/src/types/rust/MixNodeBond.ts") )] -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] pub struct MixNodeBond { pub mix_id: MixId, pub owner: String, @@ -85,7 +85,7 @@ impl MixNodeBond { feature = "generate-ts", ts(export_to = "ts-packages/types/src/types/rust/MixNodeRewarding.ts") )] -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] pub struct MixNodeRewarding { pub cost_params: MixNodeCostParams, @@ -131,7 +131,7 @@ impl MixNodeRewarding { feature = "generate-ts", ts(export_to = "ts-packages/types/src/types/rust/MixNodeCostParams.ts") )] -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] pub struct MixNodeCostParams { #[cfg_attr(feature = "generate-ts", ts(type = "string"))] pub profit_margin_percent: Percent, diff --git a/common/types/src/pending_events.rs b/common/types/src/pending_events.rs index 23ecdf4f19..f5789890bf 100644 --- a/common/types/src/pending_events.rs +++ b/common/types/src/pending_events.rs @@ -127,7 +127,7 @@ impl PendingEpochEventData { feature = "generate-ts", ts(export_to = "ts-packages/types/src/types/rust/PendingIntervalEvent.ts") )] -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, JsonSchema)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, JsonSchema)] pub struct PendingIntervalEvent { pub id: IntervalEventId, pub created_at: BlockHeight, @@ -155,7 +155,7 @@ impl PendingIntervalEvent { feature = "generate-ts", ts(export_to = "ts-packages/types/src/types/rust/PendingIntervalEventData.ts") )] -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, JsonSchema)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, JsonSchema)] pub enum PendingIntervalEventData { ChangeMixCostParams { mix_id: MixId, diff --git a/common/types/src/vesting.rs b/common/types/src/vesting.rs index 9be8ef03da..1071b21324 100644 --- a/common/types/src/vesting.rs +++ b/common/types/src/vesting.rs @@ -1,10 +1,10 @@ use crate::currency::{DecCoin, RegisteredCoins}; use crate::error::TypesError; +use nym_vesting_contract_common::account::Account as ContractVestingAccount; +use nym_vesting_contract_common::types::VestingPeriod as ContractVestingPeriod; use nym_vesting_contract_common::OriginalVestingResponse as ContractOriginalVestingResponse; use nym_vesting_contract_common::PledgeData as ContractPledgeData; use serde::{Deserialize, Serialize}; -use vesting_contract::vesting::Account as ContractVestingAccount; -use vesting_contract::vesting::VestingPeriod as ContractVestingPeriod; #[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))] #[cfg_attr( diff --git a/contracts/Cargo.lock b/contracts/Cargo.lock index 3d719dd6dc..1a87652242 100644 --- a/contracts/Cargo.lock +++ b/contracts/Cargo.lock @@ -73,6 +73,12 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bnum" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "845141a4fade3f790628b7daaaa298a25b204fb28907eb54febe5142db6ce653" + [[package]] name = "bs58" version = "0.4.0" @@ -145,9 +151,9 @@ checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" [[package]] name = "cosmwasm-crypto" -version = "1.2.5" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75836a10cb9654c54e77ee56da94d592923092a10b369cdb0dbd56acefc16340" +checksum = "0d076a08ec01ed23c4396aca98ec73a38fa1fee5f310465add52b4108181c7a8" dependencies = [ "digest 0.10.7", "ed25519-zebra", @@ -158,18 +164,18 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.2.5" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c9f7f0e51bfc7295f7b2664fe8513c966428642aa765dad8a74acdab5e0c773" +checksum = "dec361f3c09d7b41221948fc17be9b3c96cb58e55a02f82da36f888a651f2584" dependencies = [ "syn 1.0.109", ] [[package]] name = "cosmwasm-schema" -version = "1.2.5" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f00b363610218eea83f24bbab09e1a7c3920b79f068334fdfcc62f6129ef9fc" +checksum = "bb6b2fb76758ef59cddc77f2e2ae91c22f77da49037e9f182e9c2833f0e959b1" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -180,9 +186,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.2.5" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae38f909b2822d32b275c9e2db9728497aa33ffe67dd463bc67c6a3b7092785c" +checksum = "2bfa39422f0d9f1c9a6fd3711573258495314dfa3aae738ea825ecd9964bc659" dependencies = [ "proc-macro2", "quote", @@ -191,11 +197,12 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.2.5" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a49b85345e811c8e80ec55d0d091e4fcb4f00f97ab058f9be5f614c444a730cb" +checksum = "1f6dc2ee23313add5ecacc3ccac217b9967ad9d2d11bd56e5da6aa65a9da6138" dependencies = [ "base64 0.13.1", + "bnum", "cosmwasm-crypto", "cosmwasm-derive", "derivative", @@ -203,17 +210,16 @@ dependencies = [ "hex", "schemars", "serde", - "serde-json-wasm 0.5.1", + "serde-json-wasm", "sha2 0.10.6", "thiserror", - "uint", ] [[package]] name = "cosmwasm-storage" -version = "1.2.5" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3737a3aac48f5ed883b5b73bfb731e77feebd8fc6b43419844ec2971072164d" +checksum = "7ade8cae79dc08a06bcf119c0854ffaed11bd8cb1013c6b04abfe1f51f36211e" dependencies = [ "cosmwasm-std", "serde", @@ -228,12 +234,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - [[package]] name = "crypto-bigint" version = "0.4.9" @@ -271,9 +271,9 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91440ce8ec4f0642798bc8c8cb6b9b53c1926c6dadaf0eed267a5145cd529071" +checksum = "d5d8edce4b78785f36413f67387e4be7d0cb7d032b5d4164bcc024f9c3f3f2ea" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -305,9 +305,9 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053a5083c258acd68386734f428a5a171b29f7d733151ae83090c6fcc9417ffa" +checksum = "3f0e92a069d62067f3472c62e30adedb4cab1754725c0f2a682b3128d2bf3c79" dependencies = [ "cosmwasm-std", "schemars", @@ -331,22 +331,23 @@ dependencies = [ [[package]] name = "cw2" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fb70cee2cf0b4a8ff7253e6bc6647107905e8eb37208f87d54f67810faa62f8" +checksum = "29ac2dc7a55ad64173ca1e0a46697c31b7a5c51342f55a1e84a724da4eb99908" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", "serde", + "thiserror", ] [[package]] name = "cw20" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91666da6c7b40c8dd5ff94df655a28114efc10c79b70b4d06f13c31e37d60609" +checksum = "011c45920f8200bd5d32d4fe52502506f64f2f75651ab408054d4cfc75ca3a9b" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -375,9 +376,9 @@ dependencies = [ [[package]] name = "cw3" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fe0b587008aa221cd2a2579a21990a28c4347dc53ad43167c68ad765f5b6efa" +checksum = "171af3d9127de6805a7dd819fb070c7d2f6c3ea85f4193f42cef259f0a7f33d5" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -390,9 +391,9 @@ dependencies = [ [[package]] name = "cw3-fixed-multisig" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9e2415adb201e5e89dab34edf59d7dc166bc558526de009a49ae66276c9119a" +checksum = "705875c68f95870e9707e7b72b50631ddc58c07517d6cc43758306e38921118e" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -409,6 +410,7 @@ dependencies = [ name = "cw3-flex-multisig" version = "1.0.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", "cw-storage-plus", @@ -422,14 +424,13 @@ dependencies = [ "cw4-group", "nym-group-contract-common", "nym-multisig-contract-common", - "schemars", ] [[package]] name = "cw4" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c236e0bae02ce97e89235a681dd0e07d099524b369f1ef908d704db3e6b049b" +checksum = "a398696307efadaaa2d0850076f865fa706c959d493cb4203314f72be6b77a64" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1022,13 +1023,13 @@ dependencies = [ name = "nym-coconut-bandwidth" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cosmwasm-storage", "cw-controllers", "cw-storage-plus", "nym-coconut-bandwidth-contract-common", "nym-multisig-contract-common", - "schemars", "serde", "thiserror", ] @@ -1037,16 +1038,17 @@ dependencies = [ name = "nym-coconut-bandwidth-contract-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", + "cw2", "nym-multisig-contract-common", - "schemars", - "serde", ] [[package]] name = "nym-coconut-dkg" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cosmwasm-storage", "cw-controllers", @@ -1058,7 +1060,6 @@ dependencies = [ "nym-coconut-dkg-common", "nym-group-contract-common", "rusty-fork", - "schemars", "serde", "thiserror", ] @@ -1067,12 +1068,11 @@ dependencies = [ name = "nym-coconut-dkg-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-utils", "nym-contracts-common", "nym-multisig-contract-common", - "schemars", - "serde", ] [[package]] @@ -1080,6 +1080,7 @@ name = "nym-contracts-common" version = "0.5.0" dependencies = [ "bs58", + "cosmwasm-schema", "cosmwasm-std", "schemars", "serde", @@ -1128,7 +1129,6 @@ dependencies = [ "nym-mixnet-contract-common", "nym-vesting-contract-common", "rand_chacha 0.2.2", - "schemars", "semver", "serde", "thiserror", @@ -1141,13 +1141,15 @@ name = "nym-mixnet-contract-common" version = "0.6.0" dependencies = [ "bs58", + "cosmwasm-schema", "cosmwasm-std", + "cw2", "humantime-serde", "log", "nym-contracts-common", "schemars", "serde", - "serde-json-wasm 0.4.1", + "serde-json-wasm", "serde_repr", "thiserror", "time", @@ -1174,6 +1176,7 @@ version = "0.1.0" dependencies = [ "anyhow", "bs58", + "cosmwasm-schema", "cosmwasm-std", "cw-controllers", "cw-multi-test", @@ -1196,11 +1199,12 @@ dependencies = [ name = "nym-name-service-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-controllers", "cw-utils", + "cw2", "nym-contracts-common", - "schemars", "serde", "thiserror", ] @@ -1218,6 +1222,7 @@ version = "0.1.0" dependencies = [ "anyhow", "bs58", + "cosmwasm-schema", "cosmwasm-std", "cw-controllers", "cw-multi-test", @@ -1239,12 +1244,12 @@ dependencies = [ name = "nym-service-provider-directory-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-controllers", "cw-utils", + "cw2", "nym-contracts-common", - "schemars", - "serde", "thiserror", ] @@ -1262,6 +1267,7 @@ dependencies = [ "base64 0.21.0", "cosmwasm-crypto", "cosmwasm-derive", + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "cw2", @@ -1270,7 +1276,6 @@ dependencies = [ "nym-mixnet-contract-common", "nym-vesting-contract-common", "rand_chacha 0.3.1", - "schemars", "semver", "serde", "serde_json", @@ -1282,11 +1287,13 @@ dependencies = [ name = "nym-vesting-contract-common" version = "0.7.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", + "cw2", "nym-contracts-common", "nym-mixnet-contract-common", - "schemars", "serde", + "thiserror", ] [[package]] @@ -1657,18 +1664,9 @@ dependencies = [ [[package]] name = "serde-json-wasm" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" -dependencies = [ - "serde", -] - -[[package]] -name = "serde-json-wasm" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" +checksum = "a15bee9b04dd165c3f4e142628982ddde884c2022a89e8ddf99c4829bf2c3a58" dependencies = [ "serde", ] @@ -1770,12 +1768,6 @@ dependencies = [ "der", ] -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "subtle" version = "2.4.1" @@ -1894,18 +1886,6 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" -[[package]] -name = "uint" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - [[package]] name = "unicode-bidi" version = "0.3.12" diff --git a/contracts/Cargo.toml b/contracts/Cargo.toml index 1b20380ad7..0887794260 100644 --- a/contracts/Cargo.toml +++ b/contracts/Cargo.toml @@ -32,17 +32,17 @@ incremental = false overflow-checks = true [workspace.dependencies] -cosmwasm-crypto = "=1.2.5" -cosmwasm-derive = "=1.2.5" -cosmwasm-schema = "=1.2.5" -cosmwasm-std = "=1.2.5" -cosmwasm-storage = "=1.2.5" -cw-controllers = "=1.0.1" +cosmwasm-crypto = "=1.3.0" +cosmwasm-derive = "=1.3.0" +cosmwasm-schema = "=1.3.0" +cosmwasm-std = "=1.3.0" +cosmwasm-storage = "=1.3.0" +cw-controllers = "=1.1.0" cw-multi-test = "=0.16.4" -cw-storage-plus = "=1.0.1" +cw-storage-plus = "=1.1.0" cw-utils = "=1.0.1" -cw2 = "=1.0.1" -cw3 = "=1.0.1" -cw3-fixed-multisig = "=1.0.1" -cw4 = "=1.0.1" -cw20 = "=1.0.1" +cw2 = "=1.1.0" +cw3 = "=1.1.0" +cw3-fixed-multisig = "=1.1.0" +cw4 = "=1.1.0" +cw20 = "=1.1.0" diff --git a/contracts/Makefile b/contracts/Makefile new file mode 100644 index 0000000000..941959bf0c --- /dev/null +++ b/contracts/Makefile @@ -0,0 +1,25 @@ +schema: coconut-bandwidth-schema coconut-dkg-schema mixnet-schema name-service-schema service-provider-directory-schema vesting-schema multisig-schema group-schema + +coconut-bandwidth-schema: + $(MAKE) -C coconut-bandwidth generate-schema + +coconut-dkg-schema: + $(MAKE) -C coconut-dkg generate-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 + +multisig-schema: + $(MAKE) -C multisig/cw3-flex-multisig generate-schema + +group-schema: + $(MAKE) -C multisig/cw4-group generate-schema diff --git a/contracts/coconut-bandwidth/.cargo/config b/contracts/coconut-bandwidth/.cargo/config new file mode 100644 index 0000000000..2fb2c1afdb --- /dev/null +++ b/contracts/coconut-bandwidth/.cargo/config @@ -0,0 +1,4 @@ +[alias] +wasm = "build --release --lib --target wasm32-unknown-unknown" +unit-test = "test --lib" +schema = "run --bin schema --features=schema-gen" \ No newline at end of file diff --git a/contracts/coconut-bandwidth/Cargo.toml b/contracts/coconut-bandwidth/Cargo.toml index 69bb7088d5..5ed8e5f98b 100644 --- a/contracts/coconut-bandwidth/Cargo.toml +++ b/contracts/coconut-bandwidth/Cargo.toml @@ -5,6 +5,10 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[[bin]] +name = "schema" +required-features = ["schema-gen"] + [lib] crate-type = ["cdylib", "rlib"] @@ -13,10 +17,13 @@ nym-coconut-bandwidth-contract-common = { path = "../../common/cosmwasm-smart-co nym-multisig-contract-common = { path = "../../common/cosmwasm-smart-contracts/multisig-contract" } cosmwasm-std = { workspace = true } +cosmwasm-schema = { workspace = true, optional = true } cosmwasm-storage = { workspace = true } cw-storage-plus = { workspace = true } cw-controllers = { workspace = true } -schemars = "0.8" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = "1.0.23" + +[features] +schema-gen = ["nym-coconut-bandwidth-contract-common/schema", "cosmwasm-schema"] \ No newline at end of file diff --git a/contracts/coconut-bandwidth/Makefile b/contracts/coconut-bandwidth/Makefile new file mode 100644 index 0000000000..f138e2c879 --- /dev/null +++ b/contracts/coconut-bandwidth/Makefile @@ -0,0 +1,2 @@ +generate-schema: + cargo schema \ No newline at end of file diff --git a/contracts/coconut-bandwidth/schema/nym-coconut-bandwidth.json b/contracts/coconut-bandwidth/schema/nym-coconut-bandwidth.json new file mode 100644 index 0000000000..1b210e85f9 --- /dev/null +++ b/contracts/coconut-bandwidth/schema/nym-coconut-bandwidth.json @@ -0,0 +1,382 @@ +{ + "contract_name": "nym-coconut-bandwidth", + "contract_version": "0.1.0", + "idl_version": "1.0.0", + "instantiate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "mix_denom", + "multisig_addr", + "pool_addr" + ], + "properties": { + "mix_denom": { + "type": "string" + }, + "multisig_addr": { + "type": "string" + }, + "pool_addr": { + "type": "string" + } + }, + "additionalProperties": false + }, + "execute": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "deposit_funds" + ], + "properties": { + "deposit_funds": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/definitions/DepositData" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "spend_credential" + ], + "properties": { + "spend_credential": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/definitions/SpendCredentialData" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "release_funds" + ], + "properties": { + "release_funds": { + "type": "object", + "required": [ + "funds" + ], + "properties": { + "funds": { + "$ref": "#/definitions/Coin" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "DepositData": { + "type": "object", + "required": [ + "deposit_info", + "encryption_key", + "identity_key" + ], + "properties": { + "deposit_info": { + "type": "string" + }, + "encryption_key": { + "type": "string" + }, + "identity_key": { + "type": "string" + } + }, + "additionalProperties": false + }, + "SpendCredentialData": { + "type": "object", + "required": [ + "blinded_serial_number", + "funds", + "gateway_cosmos_address" + ], + "properties": { + "blinded_serial_number": { + "type": "string" + }, + "funds": { + "$ref": "#/definitions/Coin" + }, + "gateway_cosmos_address": { + "type": "string" + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "query": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "get_spent_credential" + ], + "properties": { + "get_spent_credential": { + "type": "object", + "required": [ + "blinded_serial_number" + ], + "properties": { + "blinded_serial_number": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "get_all_spent_credentials" + ], + "properties": { + "get_all_spent_credentials": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "migrate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "type": "object", + "additionalProperties": false + }, + "sudo": null, + "responses": { + "get_all_spent_credentials": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedSpendCredentialResponse", + "type": "object", + "required": [ + "per_page", + "spend_credentials" + ], + "properties": { + "per_page": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "spend_credentials": { + "type": "array", + "items": { + "$ref": "#/definitions/SpendCredential" + } + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "SpendCredential": { + "type": "object", + "required": [ + "blinded_serial_number", + "funds", + "gateway_cosmos_address", + "status" + ], + "properties": { + "blinded_serial_number": { + "type": "string" + }, + "funds": { + "$ref": "#/definitions/Coin" + }, + "gateway_cosmos_address": { + "$ref": "#/definitions/Addr" + }, + "status": { + "$ref": "#/definitions/SpendCredentialStatus" + } + }, + "additionalProperties": false + }, + "SpendCredentialStatus": { + "type": "string", + "enum": [ + "in_progress", + "spent" + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_spent_credential": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "SpendCredentialResponse", + "type": "object", + "properties": { + "spend_credential": { + "anyOf": [ + { + "$ref": "#/definitions/SpendCredential" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "SpendCredential": { + "type": "object", + "required": [ + "blinded_serial_number", + "funds", + "gateway_cosmos_address", + "status" + ], + "properties": { + "blinded_serial_number": { + "type": "string" + }, + "funds": { + "$ref": "#/definitions/Coin" + }, + "gateway_cosmos_address": { + "$ref": "#/definitions/Addr" + }, + "status": { + "$ref": "#/definitions/SpendCredentialStatus" + } + }, + "additionalProperties": false + }, + "SpendCredentialStatus": { + "type": "string", + "enum": [ + "in_progress", + "spent" + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + } + } +} diff --git a/contracts/coconut-bandwidth/schema/raw/execute.json b/contracts/coconut-bandwidth/schema/raw/execute.json new file mode 100644 index 0000000000..027b423f7a --- /dev/null +++ b/contracts/coconut-bandwidth/schema/raw/execute.json @@ -0,0 +1,130 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "deposit_funds" + ], + "properties": { + "deposit_funds": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/definitions/DepositData" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "spend_credential" + ], + "properties": { + "spend_credential": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/definitions/SpendCredentialData" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "release_funds" + ], + "properties": { + "release_funds": { + "type": "object", + "required": [ + "funds" + ], + "properties": { + "funds": { + "$ref": "#/definitions/Coin" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "DepositData": { + "type": "object", + "required": [ + "deposit_info", + "encryption_key", + "identity_key" + ], + "properties": { + "deposit_info": { + "type": "string" + }, + "encryption_key": { + "type": "string" + }, + "identity_key": { + "type": "string" + } + }, + "additionalProperties": false + }, + "SpendCredentialData": { + "type": "object", + "required": [ + "blinded_serial_number", + "funds", + "gateway_cosmos_address" + ], + "properties": { + "blinded_serial_number": { + "type": "string" + }, + "funds": { + "$ref": "#/definitions/Coin" + }, + "gateway_cosmos_address": { + "type": "string" + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/coconut-bandwidth/schema/raw/instantiate.json b/contracts/coconut-bandwidth/schema/raw/instantiate.json new file mode 100644 index 0000000000..172dc76d79 --- /dev/null +++ b/contracts/coconut-bandwidth/schema/raw/instantiate.json @@ -0,0 +1,22 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "mix_denom", + "multisig_addr", + "pool_addr" + ], + "properties": { + "mix_denom": { + "type": "string" + }, + "multisig_addr": { + "type": "string" + }, + "pool_addr": { + "type": "string" + } + }, + "additionalProperties": false +} diff --git a/contracts/coconut-bandwidth/schema/raw/migrate.json b/contracts/coconut-bandwidth/schema/raw/migrate.json new file mode 100644 index 0000000000..7fbe8c5708 --- /dev/null +++ b/contracts/coconut-bandwidth/schema/raw/migrate.json @@ -0,0 +1,6 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "type": "object", + "additionalProperties": false +} diff --git a/contracts/coconut-bandwidth/schema/raw/query.json b/contracts/coconut-bandwidth/schema/raw/query.json new file mode 100644 index 0000000000..afdfae331d --- /dev/null +++ b/contracts/coconut-bandwidth/schema/raw/query.json @@ -0,0 +1,56 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "get_spent_credential" + ], + "properties": { + "get_spent_credential": { + "type": "object", + "required": [ + "blinded_serial_number" + ], + "properties": { + "blinded_serial_number": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "get_all_spent_credentials" + ], + "properties": { + "get_all_spent_credentials": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] +} diff --git a/contracts/coconut-bandwidth/schema/raw/response_to_get_all_spent_credentials.json b/contracts/coconut-bandwidth/schema/raw/response_to_get_all_spent_credentials.json new file mode 100644 index 0000000000..733da87081 --- /dev/null +++ b/contracts/coconut-bandwidth/schema/raw/response_to_get_all_spent_credentials.json @@ -0,0 +1,86 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedSpendCredentialResponse", + "type": "object", + "required": [ + "per_page", + "spend_credentials" + ], + "properties": { + "per_page": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "spend_credentials": { + "type": "array", + "items": { + "$ref": "#/definitions/SpendCredential" + } + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "SpendCredential": { + "type": "object", + "required": [ + "blinded_serial_number", + "funds", + "gateway_cosmos_address", + "status" + ], + "properties": { + "blinded_serial_number": { + "type": "string" + }, + "funds": { + "$ref": "#/definitions/Coin" + }, + "gateway_cosmos_address": { + "$ref": "#/definitions/Addr" + }, + "status": { + "$ref": "#/definitions/SpendCredentialStatus" + } + }, + "additionalProperties": false + }, + "SpendCredentialStatus": { + "type": "string", + "enum": [ + "in_progress", + "spent" + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/coconut-bandwidth/schema/raw/response_to_get_spent_credential.json b/contracts/coconut-bandwidth/schema/raw/response_to_get_spent_credential.json new file mode 100644 index 0000000000..9af4def85b --- /dev/null +++ b/contracts/coconut-bandwidth/schema/raw/response_to_get_spent_credential.json @@ -0,0 +1,74 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "SpendCredentialResponse", + "type": "object", + "properties": { + "spend_credential": { + "anyOf": [ + { + "$ref": "#/definitions/SpendCredential" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "SpendCredential": { + "type": "object", + "required": [ + "blinded_serial_number", + "funds", + "gateway_cosmos_address", + "status" + ], + "properties": { + "blinded_serial_number": { + "type": "string" + }, + "funds": { + "$ref": "#/definitions/Coin" + }, + "gateway_cosmos_address": { + "$ref": "#/definitions/Addr" + }, + "status": { + "$ref": "#/definitions/SpendCredentialStatus" + } + }, + "additionalProperties": false + }, + "SpendCredentialStatus": { + "type": "string", + "enum": [ + "in_progress", + "spent" + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/coconut-bandwidth/src/bin/schema.rs b/contracts/coconut-bandwidth/src/bin/schema.rs new file mode 100644 index 0000000000..4956eb33f4 --- /dev/null +++ b/contracts/coconut-bandwidth/src/bin/schema.rs @@ -0,0 +1,16 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use cosmwasm_schema::write_api; +use nym_coconut_bandwidth_contract_common::msg::{ + ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg, +}; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + query: QueryMsg, + execute: ExecuteMsg, + migrate: MigrateMsg, + } +} diff --git a/contracts/coconut-bandwidth/src/state.rs b/contracts/coconut-bandwidth/src/state.rs index 74b969341c..855d9fa07a 100644 --- a/contracts/coconut-bandwidth/src/state.rs +++ b/contracts/coconut-bandwidth/src/state.rs @@ -4,12 +4,11 @@ use cosmwasm_std::Addr; use cw_controllers::Admin; use cw_storage_plus::Item; -use schemars::JsonSchema; use serde::{Deserialize, Serialize}; pub const ADMIN: Admin = Admin::new("admin"); -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] +#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)] pub struct Config { pub multisig_addr: Addr, pub pool_addr: Addr, diff --git a/contracts/coconut-dkg/.cargo/config b/contracts/coconut-dkg/.cargo/config new file mode 100644 index 0000000000..2f698e22b3 --- /dev/null +++ b/contracts/coconut-dkg/.cargo/config @@ -0,0 +1,5 @@ +[alias] +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --target wasm32-unknown-unknown" +unit-test = "test --lib" +schema = "run --bin schema --features=schema-gen" \ No newline at end of file diff --git a/contracts/coconut-dkg/Cargo.toml b/contracts/coconut-dkg/Cargo.toml index f877df138d..794c1f3a0f 100644 --- a/contracts/coconut-dkg/Cargo.toml +++ b/contracts/coconut-dkg/Cargo.toml @@ -5,19 +5,22 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[[bin]] +name = "schema" +required-features = ["schema-gen"] + [lib] crate-type = ["cdylib", "rlib"] [dependencies] nym-coconut-dkg-common = { path = "../../common/cosmwasm-smart-contracts/coconut-dkg" } +cosmwasm-schema = { workspace = true, optional = true } cosmwasm-std = { workspace = true } cosmwasm-storage = { workspace = true } cw-storage-plus = { workspace = true } cw-controllers = { workspace = true } cw4 = { workspace = true } - -schemars = "0.8" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = "1.0.23" @@ -27,3 +30,7 @@ cw4-group = { path = "../multisig/cw4-group" } nym-group-contract-common = { path = "../../common/cosmwasm-smart-contracts/group-contract" } lazy_static = "1.4" rusty-fork = "0.3" + +[features] +schema-gen = ["nym-coconut-dkg-common/schema", "cosmwasm-schema"] + diff --git a/contracts/coconut-dkg/Makefile b/contracts/coconut-dkg/Makefile new file mode 100644 index 0000000000..f138e2c879 --- /dev/null +++ b/contracts/coconut-dkg/Makefile @@ -0,0 +1,2 @@ +generate-schema: + cargo schema \ No newline at end of file diff --git a/contracts/coconut-dkg/schema/nym-coconut-dkg.json b/contracts/coconut-dkg/schema/nym-coconut-dkg.json new file mode 100644 index 0000000000..035f1bfe8f --- /dev/null +++ b/contracts/coconut-dkg/schema/nym-coconut-dkg.json @@ -0,0 +1,1023 @@ +{ + "contract_name": "nym-coconut-dkg", + "contract_version": "0.1.0", + "idl_version": "1.0.0", + "instantiate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "group_addr", + "mix_denom", + "multisig_addr" + ], + "properties": { + "group_addr": { + "type": "string" + }, + "mix_denom": { + "type": "string" + }, + "multisig_addr": { + "type": "string" + }, + "time_configuration": { + "anyOf": [ + { + "$ref": "#/definitions/TimeConfiguration" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "TimeConfiguration": { + "type": "object", + "required": [ + "dealing_exchange_time_secs", + "in_progress_time_secs", + "public_key_submission_time_secs", + "verification_key_finalization_time_secs", + "verification_key_submission_time_secs", + "verification_key_validation_time_secs" + ], + "properties": { + "dealing_exchange_time_secs": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "in_progress_time_secs": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "public_key_submission_time_secs": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "verification_key_finalization_time_secs": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "verification_key_submission_time_secs": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "verification_key_validation_time_secs": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } + }, + "execute": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "register_dealer" + ], + "properties": { + "register_dealer": { + "type": "object", + "required": [ + "announce_address", + "bte_key_with_proof", + "resharing" + ], + "properties": { + "announce_address": { + "type": "string" + }, + "bte_key_with_proof": { + "type": "string" + }, + "resharing": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "commit_dealing" + ], + "properties": { + "commit_dealing": { + "type": "object", + "required": [ + "dealing_bytes", + "resharing" + ], + "properties": { + "dealing_bytes": { + "$ref": "#/definitions/ContractSafeBytes" + }, + "resharing": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "commit_verification_key_share" + ], + "properties": { + "commit_verification_key_share": { + "type": "object", + "required": [ + "resharing", + "share" + ], + "properties": { + "resharing": { + "type": "boolean" + }, + "share": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "verify_verification_key_share" + ], + "properties": { + "verify_verification_key_share": { + "type": "object", + "required": [ + "owner", + "resharing" + ], + "properties": { + "owner": { + "$ref": "#/definitions/Addr" + }, + "resharing": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "surpassed_threshold" + ], + "properties": { + "surpassed_threshold": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "advance_epoch_state" + ], + "properties": { + "advance_epoch_state": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "ContractSafeBytes": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + } + } + }, + "query": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "get_current_epoch_state" + ], + "properties": { + "get_current_epoch_state": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "get_current_epoch_threshold" + ], + "properties": { + "get_current_epoch_threshold": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "get_initial_dealers" + ], + "properties": { + "get_initial_dealers": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "get_dealer_details" + ], + "properties": { + "get_dealer_details": { + "type": "object", + "required": [ + "dealer_address" + ], + "properties": { + "dealer_address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "get_current_dealers" + ], + "properties": { + "get_current_dealers": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "get_past_dealers" + ], + "properties": { + "get_past_dealers": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "get_dealing" + ], + "properties": { + "get_dealing": { + "type": "object", + "required": [ + "idx" + ], + "properties": { + "idx": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "get_verification_keys" + ], + "properties": { + "get_verification_keys": { + "type": "object", + "required": [ + "epoch_id" + ], + "properties": { + "epoch_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "migrate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "type": "object", + "additionalProperties": false + }, + "sudo": null, + "responses": { + "get_current_dealers": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedDealerResponse", + "type": "object", + "required": [ + "dealers", + "per_page" + ], + "properties": { + "dealers": { + "type": "array", + "items": { + "$ref": "#/definitions/DealerDetails" + } + }, + "per_page": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "DealerDetails": { + "type": "object", + "required": [ + "address", + "announce_address", + "assigned_index", + "bte_public_key_with_proof" + ], + "properties": { + "address": { + "$ref": "#/definitions/Addr" + }, + "announce_address": { + "type": "string" + }, + "assigned_index": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "bte_public_key_with_proof": { + "type": "string" + } + }, + "additionalProperties": false + } + } + }, + "get_current_epoch_state": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Epoch", + "type": "object", + "required": [ + "epoch_id", + "finish_timestamp", + "state", + "time_configuration" + ], + "properties": { + "epoch_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "finish_timestamp": { + "$ref": "#/definitions/Timestamp" + }, + "state": { + "$ref": "#/definitions/EpochState" + }, + "time_configuration": { + "$ref": "#/definitions/TimeConfiguration" + } + }, + "additionalProperties": false, + "definitions": { + "EpochState": { + "oneOf": [ + { + "type": "string", + "enum": [ + "in_progress" + ] + }, + { + "type": "object", + "required": [ + "public_key_submission" + ], + "properties": { + "public_key_submission": { + "type": "object", + "required": [ + "resharing" + ], + "properties": { + "resharing": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "dealing_exchange" + ], + "properties": { + "dealing_exchange": { + "type": "object", + "required": [ + "resharing" + ], + "properties": { + "resharing": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "verification_key_submission" + ], + "properties": { + "verification_key_submission": { + "type": "object", + "required": [ + "resharing" + ], + "properties": { + "resharing": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "verification_key_validation" + ], + "properties": { + "verification_key_validation": { + "type": "object", + "required": [ + "resharing" + ], + "properties": { + "resharing": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "verification_key_finalization" + ], + "properties": { + "verification_key_finalization": { + "type": "object", + "required": [ + "resharing" + ], + "properties": { + "resharing": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "TimeConfiguration": { + "type": "object", + "required": [ + "dealing_exchange_time_secs", + "in_progress_time_secs", + "public_key_submission_time_secs", + "verification_key_finalization_time_secs", + "verification_key_submission_time_secs", + "verification_key_validation_time_secs" + ], + "properties": { + "dealing_exchange_time_secs": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "in_progress_time_secs": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "public_key_submission_time_secs": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "verification_key_finalization_time_secs": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "verification_key_submission_time_secs": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "verification_key_validation_time_secs": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + } + } + }, + "get_current_epoch_threshold": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "uint64", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "get_dealer_details": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "DealerDetailsResponse", + "type": "object", + "required": [ + "dealer_type" + ], + "properties": { + "dealer_type": { + "$ref": "#/definitions/DealerType" + }, + "details": { + "anyOf": [ + { + "$ref": "#/definitions/DealerDetails" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "DealerDetails": { + "type": "object", + "required": [ + "address", + "announce_address", + "assigned_index", + "bte_public_key_with_proof" + ], + "properties": { + "address": { + "$ref": "#/definitions/Addr" + }, + "announce_address": { + "type": "string" + }, + "assigned_index": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "bte_public_key_with_proof": { + "type": "string" + } + }, + "additionalProperties": false + }, + "DealerType": { + "type": "string", + "enum": [ + "current", + "past", + "unknown" + ] + } + } + }, + "get_dealing": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedDealingsResponse", + "type": "object", + "required": [ + "dealings", + "per_page" + ], + "properties": { + "dealings": { + "type": "array", + "items": { + "$ref": "#/definitions/ContractDealing" + } + }, + "per_page": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "ContractDealing": { + "type": "object", + "required": [ + "dealer", + "dealing" + ], + "properties": { + "dealer": { + "$ref": "#/definitions/Addr" + }, + "dealing": { + "$ref": "#/definitions/ContractSafeBytes" + } + }, + "additionalProperties": false + }, + "ContractSafeBytes": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + } + } + }, + "get_initial_dealers": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Nullable_InitialReplacementData", + "anyOf": [ + { + "$ref": "#/definitions/InitialReplacementData" + }, + { + "type": "null" + } + ], + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "InitialReplacementData": { + "type": "object", + "required": [ + "initial_dealers", + "initial_height" + ], + "properties": { + "initial_dealers": { + "type": "array", + "items": { + "$ref": "#/definitions/Addr" + } + }, + "initial_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } + }, + "get_past_dealers": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedDealerResponse", + "type": "object", + "required": [ + "dealers", + "per_page" + ], + "properties": { + "dealers": { + "type": "array", + "items": { + "$ref": "#/definitions/DealerDetails" + } + }, + "per_page": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "DealerDetails": { + "type": "object", + "required": [ + "address", + "announce_address", + "assigned_index", + "bte_public_key_with_proof" + ], + "properties": { + "address": { + "$ref": "#/definitions/Addr" + }, + "announce_address": { + "type": "string" + }, + "assigned_index": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "bte_public_key_with_proof": { + "type": "string" + } + }, + "additionalProperties": false + } + } + }, + "get_verification_keys": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedVKSharesResponse", + "type": "object", + "required": [ + "per_page", + "shares" + ], + "properties": { + "per_page": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "shares": { + "type": "array", + "items": { + "$ref": "#/definitions/ContractVKShare" + } + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "ContractVKShare": { + "type": "object", + "required": [ + "announce_address", + "epoch_id", + "node_index", + "owner", + "share", + "verified" + ], + "properties": { + "announce_address": { + "type": "string" + }, + "epoch_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "node_index": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "owner": { + "$ref": "#/definitions/Addr" + }, + "share": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false + } + } + } + } +} diff --git a/contracts/coconut-dkg/schema/raw/execute.json b/contracts/coconut-dkg/schema/raw/execute.json new file mode 100644 index 0000000000..5e87d1dc07 --- /dev/null +++ b/contracts/coconut-dkg/schema/raw/execute.json @@ -0,0 +1,150 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "register_dealer" + ], + "properties": { + "register_dealer": { + "type": "object", + "required": [ + "announce_address", + "bte_key_with_proof", + "resharing" + ], + "properties": { + "announce_address": { + "type": "string" + }, + "bte_key_with_proof": { + "type": "string" + }, + "resharing": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "commit_dealing" + ], + "properties": { + "commit_dealing": { + "type": "object", + "required": [ + "dealing_bytes", + "resharing" + ], + "properties": { + "dealing_bytes": { + "$ref": "#/definitions/ContractSafeBytes" + }, + "resharing": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "commit_verification_key_share" + ], + "properties": { + "commit_verification_key_share": { + "type": "object", + "required": [ + "resharing", + "share" + ], + "properties": { + "resharing": { + "type": "boolean" + }, + "share": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "verify_verification_key_share" + ], + "properties": { + "verify_verification_key_share": { + "type": "object", + "required": [ + "owner", + "resharing" + ], + "properties": { + "owner": { + "$ref": "#/definitions/Addr" + }, + "resharing": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "surpassed_threshold" + ], + "properties": { + "surpassed_threshold": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "advance_epoch_state" + ], + "properties": { + "advance_epoch_state": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "ContractSafeBytes": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + } + } +} diff --git a/contracts/coconut-dkg/schema/raw/instantiate.json b/contracts/coconut-dkg/schema/raw/instantiate.json new file mode 100644 index 0000000000..af468be6c6 --- /dev/null +++ b/contracts/coconut-dkg/schema/raw/instantiate.json @@ -0,0 +1,78 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "group_addr", + "mix_denom", + "multisig_addr" + ], + "properties": { + "group_addr": { + "type": "string" + }, + "mix_denom": { + "type": "string" + }, + "multisig_addr": { + "type": "string" + }, + "time_configuration": { + "anyOf": [ + { + "$ref": "#/definitions/TimeConfiguration" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "TimeConfiguration": { + "type": "object", + "required": [ + "dealing_exchange_time_secs", + "in_progress_time_secs", + "public_key_submission_time_secs", + "verification_key_finalization_time_secs", + "verification_key_submission_time_secs", + "verification_key_validation_time_secs" + ], + "properties": { + "dealing_exchange_time_secs": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "in_progress_time_secs": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "public_key_submission_time_secs": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "verification_key_finalization_time_secs": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "verification_key_submission_time_secs": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "verification_key_validation_time_secs": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/coconut-dkg/schema/raw/migrate.json b/contracts/coconut-dkg/schema/raw/migrate.json new file mode 100644 index 0000000000..7fbe8c5708 --- /dev/null +++ b/contracts/coconut-dkg/schema/raw/migrate.json @@ -0,0 +1,6 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "type": "object", + "additionalProperties": false +} diff --git a/contracts/coconut-dkg/schema/raw/query.json b/contracts/coconut-dkg/schema/raw/query.json new file mode 100644 index 0000000000..c165069598 --- /dev/null +++ b/contracts/coconut-dkg/schema/raw/query.json @@ -0,0 +1,198 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "get_current_epoch_state" + ], + "properties": { + "get_current_epoch_state": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "get_current_epoch_threshold" + ], + "properties": { + "get_current_epoch_threshold": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "get_initial_dealers" + ], + "properties": { + "get_initial_dealers": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "get_dealer_details" + ], + "properties": { + "get_dealer_details": { + "type": "object", + "required": [ + "dealer_address" + ], + "properties": { + "dealer_address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "get_current_dealers" + ], + "properties": { + "get_current_dealers": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "get_past_dealers" + ], + "properties": { + "get_past_dealers": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "get_dealing" + ], + "properties": { + "get_dealing": { + "type": "object", + "required": [ + "idx" + ], + "properties": { + "idx": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "get_verification_keys" + ], + "properties": { + "get_verification_keys": { + "type": "object", + "required": [ + "epoch_id" + ], + "properties": { + "epoch_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] +} diff --git a/contracts/coconut-dkg/schema/raw/response_to_get_current_dealers.json b/contracts/coconut-dkg/schema/raw/response_to_get_current_dealers.json new file mode 100644 index 0000000000..e08ceedf09 --- /dev/null +++ b/contracts/coconut-dkg/schema/raw/response_to_get_current_dealers.json @@ -0,0 +1,66 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedDealerResponse", + "type": "object", + "required": [ + "dealers", + "per_page" + ], + "properties": { + "dealers": { + "type": "array", + "items": { + "$ref": "#/definitions/DealerDetails" + } + }, + "per_page": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "DealerDetails": { + "type": "object", + "required": [ + "address", + "announce_address", + "assigned_index", + "bte_public_key_with_proof" + ], + "properties": { + "address": { + "$ref": "#/definitions/Addr" + }, + "announce_address": { + "type": "string" + }, + "assigned_index": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "bte_public_key_with_proof": { + "type": "string" + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/coconut-dkg/schema/raw/response_to_get_current_epoch_state.json b/contracts/coconut-dkg/schema/raw/response_to_get_current_epoch_state.json new file mode 100644 index 0000000000..8af981b9db --- /dev/null +++ b/contracts/coconut-dkg/schema/raw/response_to_get_current_epoch_state.json @@ -0,0 +1,201 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Epoch", + "type": "object", + "required": [ + "epoch_id", + "finish_timestamp", + "state", + "time_configuration" + ], + "properties": { + "epoch_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "finish_timestamp": { + "$ref": "#/definitions/Timestamp" + }, + "state": { + "$ref": "#/definitions/EpochState" + }, + "time_configuration": { + "$ref": "#/definitions/TimeConfiguration" + } + }, + "additionalProperties": false, + "definitions": { + "EpochState": { + "oneOf": [ + { + "type": "string", + "enum": [ + "in_progress" + ] + }, + { + "type": "object", + "required": [ + "public_key_submission" + ], + "properties": { + "public_key_submission": { + "type": "object", + "required": [ + "resharing" + ], + "properties": { + "resharing": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "dealing_exchange" + ], + "properties": { + "dealing_exchange": { + "type": "object", + "required": [ + "resharing" + ], + "properties": { + "resharing": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "verification_key_submission" + ], + "properties": { + "verification_key_submission": { + "type": "object", + "required": [ + "resharing" + ], + "properties": { + "resharing": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "verification_key_validation" + ], + "properties": { + "verification_key_validation": { + "type": "object", + "required": [ + "resharing" + ], + "properties": { + "resharing": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "verification_key_finalization" + ], + "properties": { + "verification_key_finalization": { + "type": "object", + "required": [ + "resharing" + ], + "properties": { + "resharing": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "TimeConfiguration": { + "type": "object", + "required": [ + "dealing_exchange_time_secs", + "in_progress_time_secs", + "public_key_submission_time_secs", + "verification_key_finalization_time_secs", + "verification_key_submission_time_secs", + "verification_key_validation_time_secs" + ], + "properties": { + "dealing_exchange_time_secs": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "in_progress_time_secs": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "public_key_submission_time_secs": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "verification_key_finalization_time_secs": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "verification_key_submission_time_secs": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "verification_key_validation_time_secs": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/coconut-dkg/schema/raw/response_to_get_current_epoch_threshold.json b/contracts/coconut-dkg/schema/raw/response_to_get_current_epoch_threshold.json new file mode 100644 index 0000000000..7b729a7b96 --- /dev/null +++ b/contracts/coconut-dkg/schema/raw/response_to_get_current_epoch_threshold.json @@ -0,0 +1,7 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "uint64", + "type": "integer", + "format": "uint64", + "minimum": 0.0 +} diff --git a/contracts/coconut-dkg/schema/raw/response_to_get_dealer_details.json b/contracts/coconut-dkg/schema/raw/response_to_get_dealer_details.json new file mode 100644 index 0000000000..474a247a99 --- /dev/null +++ b/contracts/coconut-dkg/schema/raw/response_to_get_dealer_details.json @@ -0,0 +1,64 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "DealerDetailsResponse", + "type": "object", + "required": [ + "dealer_type" + ], + "properties": { + "dealer_type": { + "$ref": "#/definitions/DealerType" + }, + "details": { + "anyOf": [ + { + "$ref": "#/definitions/DealerDetails" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "DealerDetails": { + "type": "object", + "required": [ + "address", + "announce_address", + "assigned_index", + "bte_public_key_with_proof" + ], + "properties": { + "address": { + "$ref": "#/definitions/Addr" + }, + "announce_address": { + "type": "string" + }, + "assigned_index": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "bte_public_key_with_proof": { + "type": "string" + } + }, + "additionalProperties": false + }, + "DealerType": { + "type": "string", + "enum": [ + "current", + "past", + "unknown" + ] + } + } +} diff --git a/contracts/coconut-dkg/schema/raw/response_to_get_dealing.json b/contracts/coconut-dkg/schema/raw/response_to_get_dealing.json new file mode 100644 index 0000000000..8fc350b74c --- /dev/null +++ b/contracts/coconut-dkg/schema/raw/response_to_get_dealing.json @@ -0,0 +1,64 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedDealingsResponse", + "type": "object", + "required": [ + "dealings", + "per_page" + ], + "properties": { + "dealings": { + "type": "array", + "items": { + "$ref": "#/definitions/ContractDealing" + } + }, + "per_page": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "ContractDealing": { + "type": "object", + "required": [ + "dealer", + "dealing" + ], + "properties": { + "dealer": { + "$ref": "#/definitions/Addr" + }, + "dealing": { + "$ref": "#/definitions/ContractSafeBytes" + } + }, + "additionalProperties": false + }, + "ContractSafeBytes": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + } + } +} diff --git a/contracts/coconut-dkg/schema/raw/response_to_get_initial_dealers.json b/contracts/coconut-dkg/schema/raw/response_to_get_initial_dealers.json new file mode 100644 index 0000000000..cd8c3df351 --- /dev/null +++ b/contracts/coconut-dkg/schema/raw/response_to_get_initial_dealers.json @@ -0,0 +1,39 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Nullable_InitialReplacementData", + "anyOf": [ + { + "$ref": "#/definitions/InitialReplacementData" + }, + { + "type": "null" + } + ], + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "InitialReplacementData": { + "type": "object", + "required": [ + "initial_dealers", + "initial_height" + ], + "properties": { + "initial_dealers": { + "type": "array", + "items": { + "$ref": "#/definitions/Addr" + } + }, + "initial_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/coconut-dkg/schema/raw/response_to_get_past_dealers.json b/contracts/coconut-dkg/schema/raw/response_to_get_past_dealers.json new file mode 100644 index 0000000000..e08ceedf09 --- /dev/null +++ b/contracts/coconut-dkg/schema/raw/response_to_get_past_dealers.json @@ -0,0 +1,66 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedDealerResponse", + "type": "object", + "required": [ + "dealers", + "per_page" + ], + "properties": { + "dealers": { + "type": "array", + "items": { + "$ref": "#/definitions/DealerDetails" + } + }, + "per_page": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "DealerDetails": { + "type": "object", + "required": [ + "address", + "announce_address", + "assigned_index", + "bte_public_key_with_proof" + ], + "properties": { + "address": { + "$ref": "#/definitions/Addr" + }, + "announce_address": { + "type": "string" + }, + "assigned_index": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "bte_public_key_with_proof": { + "type": "string" + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/coconut-dkg/schema/raw/response_to_get_verification_keys.json b/contracts/coconut-dkg/schema/raw/response_to_get_verification_keys.json new file mode 100644 index 0000000000..d0fc6e1deb --- /dev/null +++ b/contracts/coconut-dkg/schema/raw/response_to_get_verification_keys.json @@ -0,0 +1,76 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedVKSharesResponse", + "type": "object", + "required": [ + "per_page", + "shares" + ], + "properties": { + "per_page": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "shares": { + "type": "array", + "items": { + "$ref": "#/definitions/ContractVKShare" + } + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "ContractVKShare": { + "type": "object", + "required": [ + "announce_address", + "epoch_id", + "node_index", + "owner", + "share", + "verified" + ], + "properties": { + "announce_address": { + "type": "string" + }, + "epoch_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "node_index": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "owner": { + "$ref": "#/definitions/Addr" + }, + "share": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/coconut-dkg/src/bin/schema.rs b/contracts/coconut-dkg/src/bin/schema.rs new file mode 100644 index 0000000000..7a66216cfa --- /dev/null +++ b/contracts/coconut-dkg/src/bin/schema.rs @@ -0,0 +1,14 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use cosmwasm_schema::write_api; +use nym_coconut_dkg_common::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + query: QueryMsg, + execute: ExecuteMsg, + migrate: MigrateMsg, + } +} diff --git a/contracts/coconut-dkg/src/state/mod.rs b/contracts/coconut-dkg/src/state/mod.rs index 533bd98a0a..90abdc3711 100644 --- a/contracts/coconut-dkg/src/state/mod.rs +++ b/contracts/coconut-dkg/src/state/mod.rs @@ -5,14 +5,13 @@ use cosmwasm_std::Addr; use cw4::Cw4Contract; use cw_controllers::Admin; use cw_storage_plus::Item; -use schemars::JsonSchema; use serde::{Deserialize, Serialize}; // unique items pub const STATE: Item = Item::new("state"); pub const MULTISIG: Admin = Admin::new("multisig"); -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)] pub struct State { pub mix_denom: String, pub multisig_addr: Addr, diff --git a/contracts/mixnet-vesting-integration-tests/src/decrease_mixnode_pledge.rs b/contracts/mixnet-vesting-integration-tests/src/decrease_mixnode_pledge.rs index c2ec5bd71b..a9930e23f7 100644 --- a/contracts/mixnet-vesting-integration-tests/src/decrease_mixnode_pledge.rs +++ b/contracts/mixnet-vesting-integration-tests/src/decrease_mixnode_pledge.rs @@ -9,8 +9,7 @@ use nym_contracts_common::Percent; use nym_mixnet_contract_common::error::MixnetContractError; use nym_mixnet_contract_common::{ContractStateParams, MixNodeCostParams}; use nym_mixnet_contract_common::{MixOwnershipResponse, QueryMsg as MixnetQueryMsg}; -use nym_vesting_contract_common::ExecuteMsg as VestingExecuteMsg; -use vesting_contract::errors::ContractError as VestingContractError; +use nym_vesting_contract_common::{ExecuteMsg as VestingExecuteMsg, VestingContractError}; #[test] fn decrease_mixnode_pledge_from_vesting_account_with_minimum_pledge() { diff --git a/contracts/mixnet/.cargo/config b/contracts/mixnet/.cargo/config index 336b618a17..2fb2c1afdb 100644 --- a/contracts/mixnet/.cargo/config +++ b/contracts/mixnet/.cargo/config @@ -1,4 +1,4 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" +wasm = "build --release --lib --target wasm32-unknown-unknown" unit-test = "test --lib" -schema = "run --example schema" +schema = "run --bin schema --features=schema-gen" \ No newline at end of file diff --git a/contracts/mixnet/Cargo.toml b/contracts/mixnet/Cargo.toml index acdbfd4617..999ef93c8b 100644 --- a/contracts/mixnet/Cargo.toml +++ b/contracts/mixnet/Cargo.toml @@ -17,6 +17,10 @@ exclude = [ # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[[bin]] +name = "schema" +required-features = ["schema-gen"] + [lib] name = "mixnet_contract" crate-type = ["cdylib", "rlib"] @@ -26,6 +30,7 @@ mixnet-contract-common = { path = "../../common/cosmwasm-smart-contracts/mixnet- vesting-contract-common = { path = "../../common/cosmwasm-smart-contracts/vesting-contract", package = "nym-vesting-contract-common", version = "0.7.0" } nym-contracts-common = { path = "../../common/cosmwasm-smart-contracts/contracts-common", version = "0.5.0" } +cosmwasm-schema = { workspace = true, optional = true } cosmwasm-std = { workspace = true } cosmwasm-storage = { workspace = true } cosmwasm-derive = { workspace = true } @@ -33,14 +38,12 @@ cw2 = { workspace = true } cw-storage-plus = { workspace = true } bs58 = "0.4.0" -schemars = "0.8" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } time = { version = "0.3", features = ["macros"] } semver = { version = "1.0.16", default-features = false } [dev-dependencies] -cosmwasm-schema = { workspace = true } rand_chacha = "0.2" nym-crypto = { path = "../../common/crypto", features = ["asymmetric", "rand"] } @@ -50,6 +53,9 @@ vergen = { version = "=7.4.3", default-features = false, features = ["build", "g [features] default = [] contract-testing = ["mixnet-contract-common/contract-testing"] +schema-gen = ["mixnet-contract-common/schema", "cosmwasm-schema"] [profile.release] overflow-checks = true + + diff --git a/contracts/mixnet/Makefile b/contracts/mixnet/Makefile index 7741d05913..01452be701 100644 --- a/contracts/mixnet/Makefile +++ b/contracts/mixnet/Makefile @@ -3,3 +3,6 @@ opt: wasm wasm: RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown + +generate-schema: + cargo schema \ No newline at end of file diff --git a/contracts/mixnet/examples/schema.rs b/contracts/mixnet/examples/schema.rs deleted file mode 100644 index 46e555aff3..0000000000 --- a/contracts/mixnet/examples/schema.rs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2021 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use cosmwasm_schema::{export_schema, remove_schemas, schema_for}; -use mixnet_contract_common::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; -use std::env::current_dir; -use std::fs::create_dir_all; - -fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema(&schema_for!(InstantiateMsg), &out_dir); - export_schema(&schema_for!(ExecuteMsg), &out_dir); - export_schema(&schema_for!(QueryMsg), &out_dir); - export_schema(&schema_for!(MigrateMsg), &out_dir); -} diff --git a/contracts/mixnet/schema/nym-mixnet-contract.json b/contracts/mixnet/schema/nym-mixnet-contract.json new file mode 100644 index 0000000000..22cf2a118d --- /dev/null +++ b/contracts/mixnet/schema/nym-mixnet-contract.json @@ -0,0 +1,8507 @@ +{ + "contract_name": "nym-mixnet-contract", + "contract_version": "1.4.0", + "idl_version": "1.0.0", + "instantiate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "epoch_duration", + "epochs_in_interval", + "initial_rewarding_params", + "rewarding_denom", + "rewarding_validator_address", + "vesting_contract_address" + ], + "properties": { + "epoch_duration": { + "$ref": "#/definitions/Duration" + }, + "epochs_in_interval": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "initial_rewarding_params": { + "$ref": "#/definitions/InitialRewardingParams" + }, + "rewarding_denom": { + "type": "string" + }, + "rewarding_validator_address": { + "type": "string" + }, + "vesting_contract_address": { + "type": "string" + } + }, + "additionalProperties": false, + "definitions": { + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Duration": { + "type": "object", + "required": [ + "nanos", + "secs" + ], + "properties": { + "nanos": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "secs": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + }, + "InitialRewardingParams": { + "type": "object", + "required": [ + "active_set_size", + "active_set_work_factor", + "initial_reward_pool", + "initial_staking_supply", + "interval_pool_emission", + "rewarded_set_size", + "staking_supply_scale_factor", + "sybil_resistance" + ], + "properties": { + "active_set_size": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "active_set_work_factor": { + "$ref": "#/definitions/Decimal" + }, + "initial_reward_pool": { + "$ref": "#/definitions/Decimal" + }, + "initial_staking_supply": { + "$ref": "#/definitions/Decimal" + }, + "interval_pool_emission": { + "$ref": "#/definitions/Percent" + }, + "rewarded_set_size": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "staking_supply_scale_factor": { + "$ref": "#/definitions/Percent" + }, + "sybil_resistance": { + "$ref": "#/definitions/Percent" + } + }, + "additionalProperties": false + }, + "Percent": { + "description": "Percent represents a value between 0 and 100% (i.e. between 0.0 and 1.0)", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + } + } + }, + "execute": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "assign_node_layer" + ], + "properties": { + "assign_node_layer": { + "type": "object", + "required": [ + "layer", + "mix_id" + ], + "properties": { + "layer": { + "$ref": "#/definitions/Layer" + }, + "mix_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Only owner of the node can crate the family with node as head", + "type": "object", + "required": [ + "create_family" + ], + "properties": { + "create_family": { + "type": "object", + "required": [ + "label" + ], + "properties": { + "label": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Family head needs to sign the joining node IdentityKey", + "type": "object", + "required": [ + "join_family" + ], + "properties": { + "join_family": { + "type": "object", + "required": [ + "family_head", + "join_permit" + ], + "properties": { + "family_head": { + "$ref": "#/definitions/FamilyHead" + }, + "join_permit": { + "$ref": "#/definitions/MessageSignature" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "leave_family" + ], + "properties": { + "leave_family": { + "type": "object", + "required": [ + "family_head" + ], + "properties": { + "family_head": { + "$ref": "#/definitions/FamilyHead" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "kick_family_member" + ], + "properties": { + "kick_family_member": { + "type": "object", + "required": [ + "member" + ], + "properties": { + "member": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "create_family_on_behalf" + ], + "properties": { + "create_family_on_behalf": { + "type": "object", + "required": [ + "label", + "owner_address" + ], + "properties": { + "label": { + "type": "string" + }, + "owner_address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Family head needs to sign the joining node IdentityKey, MixNode needs to provide its signature proving that it wants to join the family", + "type": "object", + "required": [ + "join_family_on_behalf" + ], + "properties": { + "join_family_on_behalf": { + "type": "object", + "required": [ + "family_head", + "join_permit", + "member_address" + ], + "properties": { + "family_head": { + "$ref": "#/definitions/FamilyHead" + }, + "join_permit": { + "$ref": "#/definitions/MessageSignature" + }, + "member_address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "leave_family_on_behalf" + ], + "properties": { + "leave_family_on_behalf": { + "type": "object", + "required": [ + "family_head", + "member_address" + ], + "properties": { + "family_head": { + "$ref": "#/definitions/FamilyHead" + }, + "member_address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "kick_family_member_on_behalf" + ], + "properties": { + "kick_family_member_on_behalf": { + "type": "object", + "required": [ + "head_address", + "member" + ], + "properties": { + "head_address": { + "type": "string" + }, + "member": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_rewarding_validator_address" + ], + "properties": { + "update_rewarding_validator_address": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_contract_state_params" + ], + "properties": { + "update_contract_state_params": { + "type": "object", + "required": [ + "updated_parameters" + ], + "properties": { + "updated_parameters": { + "$ref": "#/definitions/ContractStateParams" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_active_set_size" + ], + "properties": { + "update_active_set_size": { + "type": "object", + "required": [ + "active_set_size", + "force_immediately" + ], + "properties": { + "active_set_size": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "force_immediately": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_rewarding_params" + ], + "properties": { + "update_rewarding_params": { + "type": "object", + "required": [ + "force_immediately", + "updated_params" + ], + "properties": { + "force_immediately": { + "type": "boolean" + }, + "updated_params": { + "$ref": "#/definitions/IntervalRewardingParamsUpdate" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_interval_config" + ], + "properties": { + "update_interval_config": { + "type": "object", + "required": [ + "epoch_duration_secs", + "epochs_in_interval", + "force_immediately" + ], + "properties": { + "epoch_duration_secs": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "epochs_in_interval": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "force_immediately": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "begin_epoch_transition" + ], + "properties": { + "begin_epoch_transition": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "advance_current_epoch" + ], + "properties": { + "advance_current_epoch": { + "type": "object", + "required": [ + "expected_active_set_size", + "new_rewarded_set" + ], + "properties": { + "expected_active_set_size": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "new_rewarded_set": { + "type": "array", + "items": { + "$ref": "#/definitions/LayerAssignment" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "reconcile_epoch_events" + ], + "properties": { + "reconcile_epoch_events": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "bond_mixnode" + ], + "properties": { + "bond_mixnode": { + "type": "object", + "required": [ + "cost_params", + "mix_node", + "owner_signature" + ], + "properties": { + "cost_params": { + "$ref": "#/definitions/MixNodeCostParams" + }, + "mix_node": { + "$ref": "#/definitions/MixNode" + }, + "owner_signature": { + "$ref": "#/definitions/MessageSignature" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "bond_mixnode_on_behalf" + ], + "properties": { + "bond_mixnode_on_behalf": { + "type": "object", + "required": [ + "cost_params", + "mix_node", + "owner", + "owner_signature" + ], + "properties": { + "cost_params": { + "$ref": "#/definitions/MixNodeCostParams" + }, + "mix_node": { + "$ref": "#/definitions/MixNode" + }, + "owner": { + "type": "string" + }, + "owner_signature": { + "$ref": "#/definitions/MessageSignature" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "pledge_more" + ], + "properties": { + "pledge_more": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "pledge_more_on_behalf" + ], + "properties": { + "pledge_more_on_behalf": { + "type": "object", + "required": [ + "owner" + ], + "properties": { + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "decrease_pledge" + ], + "properties": { + "decrease_pledge": { + "type": "object", + "required": [ + "decrease_by" + ], + "properties": { + "decrease_by": { + "$ref": "#/definitions/Coin" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "decrease_pledge_on_behalf" + ], + "properties": { + "decrease_pledge_on_behalf": { + "type": "object", + "required": [ + "decrease_by", + "owner" + ], + "properties": { + "decrease_by": { + "$ref": "#/definitions/Coin" + }, + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "unbond_mixnode" + ], + "properties": { + "unbond_mixnode": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "unbond_mixnode_on_behalf" + ], + "properties": { + "unbond_mixnode_on_behalf": { + "type": "object", + "required": [ + "owner" + ], + "properties": { + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_mixnode_cost_params" + ], + "properties": { + "update_mixnode_cost_params": { + "type": "object", + "required": [ + "new_costs" + ], + "properties": { + "new_costs": { + "$ref": "#/definitions/MixNodeCostParams" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_mixnode_cost_params_on_behalf" + ], + "properties": { + "update_mixnode_cost_params_on_behalf": { + "type": "object", + "required": [ + "new_costs", + "owner" + ], + "properties": { + "new_costs": { + "$ref": "#/definitions/MixNodeCostParams" + }, + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_mixnode_config" + ], + "properties": { + "update_mixnode_config": { + "type": "object", + "required": [ + "new_config" + ], + "properties": { + "new_config": { + "$ref": "#/definitions/MixNodeConfigUpdate" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_mixnode_config_on_behalf" + ], + "properties": { + "update_mixnode_config_on_behalf": { + "type": "object", + "required": [ + "new_config", + "owner" + ], + "properties": { + "new_config": { + "$ref": "#/definitions/MixNodeConfigUpdate" + }, + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "bond_gateway" + ], + "properties": { + "bond_gateway": { + "type": "object", + "required": [ + "gateway", + "owner_signature" + ], + "properties": { + "gateway": { + "$ref": "#/definitions/Gateway" + }, + "owner_signature": { + "$ref": "#/definitions/MessageSignature" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "bond_gateway_on_behalf" + ], + "properties": { + "bond_gateway_on_behalf": { + "type": "object", + "required": [ + "gateway", + "owner", + "owner_signature" + ], + "properties": { + "gateway": { + "$ref": "#/definitions/Gateway" + }, + "owner": { + "type": "string" + }, + "owner_signature": { + "$ref": "#/definitions/MessageSignature" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "unbond_gateway" + ], + "properties": { + "unbond_gateway": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "unbond_gateway_on_behalf" + ], + "properties": { + "unbond_gateway_on_behalf": { + "type": "object", + "required": [ + "owner" + ], + "properties": { + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_gateway_config" + ], + "properties": { + "update_gateway_config": { + "type": "object", + "required": [ + "new_config" + ], + "properties": { + "new_config": { + "$ref": "#/definitions/GatewayConfigUpdate" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_gateway_config_on_behalf" + ], + "properties": { + "update_gateway_config_on_behalf": { + "type": "object", + "required": [ + "new_config", + "owner" + ], + "properties": { + "new_config": { + "$ref": "#/definitions/GatewayConfigUpdate" + }, + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "delegate_to_mixnode" + ], + "properties": { + "delegate_to_mixnode": { + "type": "object", + "required": [ + "mix_id" + ], + "properties": { + "mix_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "delegate_to_mixnode_on_behalf" + ], + "properties": { + "delegate_to_mixnode_on_behalf": { + "type": "object", + "required": [ + "delegate", + "mix_id" + ], + "properties": { + "delegate": { + "type": "string" + }, + "mix_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "undelegate_from_mixnode" + ], + "properties": { + "undelegate_from_mixnode": { + "type": "object", + "required": [ + "mix_id" + ], + "properties": { + "mix_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "undelegate_from_mixnode_on_behalf" + ], + "properties": { + "undelegate_from_mixnode_on_behalf": { + "type": "object", + "required": [ + "delegate", + "mix_id" + ], + "properties": { + "delegate": { + "type": "string" + }, + "mix_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "reward_mixnode" + ], + "properties": { + "reward_mixnode": { + "type": "object", + "required": [ + "mix_id", + "performance" + ], + "properties": { + "mix_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "performance": { + "$ref": "#/definitions/Percent" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "withdraw_operator_reward" + ], + "properties": { + "withdraw_operator_reward": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "withdraw_operator_reward_on_behalf" + ], + "properties": { + "withdraw_operator_reward_on_behalf": { + "type": "object", + "required": [ + "owner" + ], + "properties": { + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "withdraw_delegator_reward" + ], + "properties": { + "withdraw_delegator_reward": { + "type": "object", + "required": [ + "mix_id" + ], + "properties": { + "mix_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "withdraw_delegator_reward_on_behalf" + ], + "properties": { + "withdraw_delegator_reward_on_behalf": { + "type": "object", + "required": [ + "mix_id", + "owner" + ], + "properties": { + "mix_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "ContractStateParams": { + "description": "Contract parameters that could be adjusted in a transaction by the contract admin.", + "type": "object", + "required": [ + "minimum_gateway_pledge", + "minimum_mixnode_pledge" + ], + "properties": { + "minimum_gateway_pledge": { + "description": "Minimum amount a gateway must pledge to get into the system.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "minimum_mixnode_delegation": { + "description": "Minimum amount a delegator must stake in orders for his delegation to get accepted.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + }, + "minimum_mixnode_pledge": { + "description": "Minimum amount a mixnode must pledge to get into the system.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + } + }, + "additionalProperties": false + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "FamilyHead": { + "description": "Head of particular family as identified by its identity key (i.e. public component of its ed25519 keypair stringified into base58).", + "type": "string" + }, + "Gateway": { + "description": "Information provided by the node operator during bonding that are used to allow other entities to use the services of this node.", + "type": "object", + "required": [ + "clients_port", + "host", + "identity_key", + "location", + "mix_port", + "sphinx_key", + "version" + ], + "properties": { + "clients_port": { + "description": "Port used by this gateway for listening for client requests.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "host": { + "description": "Network address of this gateway, for example 1.1.1.1 or foo.gateway.com", + "type": "string" + }, + "identity_key": { + "description": "Base58 encoded ed25519 EdDSA public key of the gateway used to derive shared keys with clients", + "type": "string" + }, + "location": { + "description": "The physical, self-reported, location of this gateway.", + "type": "string" + }, + "mix_port": { + "description": "Port used by this gateway for listening for mix packets.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "sphinx_key": { + "description": "Base58-encoded x25519 public key used for sphinx key derivation.", + "type": "string" + }, + "version": { + "description": "The self-reported semver version of this gateway.", + "type": "string" + } + }, + "additionalProperties": false + }, + "GatewayConfigUpdate": { + "type": "object", + "required": [ + "clients_port", + "host", + "location", + "mix_port", + "version" + ], + "properties": { + "clients_port": { + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "host": { + "type": "string" + }, + "location": { + "type": "string" + }, + "mix_port": { + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "version": { + "type": "string" + } + }, + "additionalProperties": false + }, + "IntervalRewardingParamsUpdate": { + "description": "Specification on how the rewarding params should be updated.", + "type": "object", + "properties": { + "active_set_work_factor": { + "description": "Defines the new value of the active set work factor.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "interval_pool_emission": { + "description": "Defines the new value of the interval pool emission rate.", + "anyOf": [ + { + "$ref": "#/definitions/Percent" + }, + { + "type": "null" + } + ] + }, + "reward_pool": { + "description": "Defines the new value of the reward pool.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "rewarded_set_size": { + "description": "Defines the new size of the rewarded set.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "staking_supply": { + "description": "Defines the new value of the staking supply.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "staking_supply_scale_factor": { + "description": "Defines the new value of the staking supply scale factor.", + "anyOf": [ + { + "$ref": "#/definitions/Percent" + }, + { + "type": "null" + } + ] + }, + "sybil_resistance_percent": { + "description": "Defines the new value of the sybil resistance percent.", + "anyOf": [ + { + "$ref": "#/definitions/Percent" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "Layer": { + "type": "string", + "enum": [ + "One", + "Two", + "Three" + ] + }, + "LayerAssignment": { + "description": "Specifies layer assignment for the given mixnode.", + "type": "object", + "required": [ + "layer", + "mix_id" + ], + "properties": { + "layer": { + "description": "The layer to which it's going to be assigned", + "allOf": [ + { + "$ref": "#/definitions/Layer" + } + ] + }, + "mix_id": { + "description": "The id of the mixnode.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "MessageSignature": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + }, + "MixNode": { + "description": "Information provided by the node operator during bonding that are used to allow other entities to use the services of this node.", + "type": "object", + "required": [ + "host", + "http_api_port", + "identity_key", + "mix_port", + "sphinx_key", + "verloc_port", + "version" + ], + "properties": { + "host": { + "description": "Network address of this mixnode, for example 1.1.1.1 or foo.mixnode.com", + "type": "string" + }, + "http_api_port": { + "description": "Port used by this mixnode for its http(s) API", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "identity_key": { + "description": "Base58-encoded ed25519 EdDSA public key.", + "type": "string" + }, + "mix_port": { + "description": "Port used by this mixnode for listening for mix packets.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "sphinx_key": { + "description": "Base58-encoded x25519 public key used for sphinx key derivation.", + "type": "string" + }, + "verloc_port": { + "description": "Port used by this mixnode for listening for verloc requests.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "version": { + "description": "The self-reported semver version of this mixnode.", + "type": "string" + } + }, + "additionalProperties": false + }, + "MixNodeConfigUpdate": { + "type": "object", + "required": [ + "host", + "http_api_port", + "mix_port", + "verloc_port", + "version" + ], + "properties": { + "host": { + "type": "string" + }, + "http_api_port": { + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "mix_port": { + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "verloc_port": { + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "version": { + "type": "string" + } + }, + "additionalProperties": false + }, + "MixNodeCostParams": { + "description": "The cost parameters, or the cost function, defined for the particular mixnode that influences how the rewards should be split between the node operator and its delegators.", + "type": "object", + "required": [ + "interval_operating_cost", + "profit_margin_percent" + ], + "properties": { + "interval_operating_cost": { + "description": "Operating cost of the associated mixnode per the entire interval.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "profit_margin_percent": { + "description": "The profit margin of the associated mixnode, i.e. the desired percent of the reward to be distributed to the operator.", + "allOf": [ + { + "$ref": "#/definitions/Percent" + } + ] + } + }, + "additionalProperties": false + }, + "Percent": { + "description": "Percent represents a value between 0 and 100% (i.e. between 0.0 and 1.0)", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "query": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "description": "Gets the list of families registered in this contract.", + "type": "object", + "required": [ + "get_all_families_paged" + ], + "properties": { + "get_all_families_paged": { + "type": "object", + "properties": { + "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the list of all family members registered in this contract.", + "type": "object", + "required": [ + "get_all_members_paged" + ], + "properties": { + "get_all_members_paged": { + "type": "object", + "properties": { + "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Attempts to lookup family information given the family head.", + "type": "object", + "required": [ + "get_family_by_head" + ], + "properties": { + "get_family_by_head": { + "type": "object", + "required": [ + "head" + ], + "properties": { + "head": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Attempts to lookup family information given the family label.", + "type": "object", + "required": [ + "get_family_by_label" + ], + "properties": { + "get_family_by_label": { + "type": "object", + "required": [ + "label" + ], + "properties": { + "label": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Attempts to retrieve family members given the family head.", + "type": "object", + "required": [ + "get_family_members_by_head" + ], + "properties": { + "get_family_members_by_head": { + "type": "object", + "required": [ + "head" + ], + "properties": { + "head": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Attempts to retrieve family members given the family label.", + "type": "object", + "required": [ + "get_family_members_by_label" + ], + "properties": { + "get_family_members_by_label": { + "type": "object", + "required": [ + "label" + ], + "properties": { + "label": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets build information of this contract, such as the commit hash used for the build or rustc version.", + "type": "object", + "required": [ + "get_contract_version" + ], + "properties": { + "get_contract_version": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the stored contract version information that's required by the CW2 spec interface for migrations.", + "type": "object", + "required": [ + "get_cw2_contract_version" + ], + "properties": { + "get_cw2_contract_version": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the address of the validator that's allowed to send rewarding transactions and transition the epoch.", + "type": "object", + "required": [ + "get_rewarding_validator_address" + ], + "properties": { + "get_rewarding_validator_address": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the contract parameters that could be adjusted in a transaction by the contract admin.", + "type": "object", + "required": [ + "get_state_params" + ], + "properties": { + "get_state_params": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the current state of the contract.", + "type": "object", + "required": [ + "get_state" + ], + "properties": { + "get_state": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the current parameters used for reward calculation.", + "type": "object", + "required": [ + "get_rewarding_params" + ], + "properties": { + "get_rewarding_params": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the status of the current rewarding epoch.", + "type": "object", + "required": [ + "get_epoch_status" + ], + "properties": { + "get_epoch_status": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Get the details of the current rewarding interval.", + "type": "object", + "required": [ + "get_current_interval_details" + ], + "properties": { + "get_current_interval_details": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the current list of mixnodes in the rewarded set.", + "type": "object", + "required": [ + "get_rewarded_set" + ], + "properties": { + "get_rewarded_set": { + "type": "object", + "properties": { + "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the basic list of all currently bonded mixnodes.", + "type": "object", + "required": [ + "get_mix_node_bonds" + ], + "properties": { + "get_mix_node_bonds": { + "type": "object", + "properties": { + "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the detailed list of all currently bonded mixnodes.", + "type": "object", + "required": [ + "get_mix_nodes_detailed" + ], + "properties": { + "get_mix_nodes_detailed": { + "type": "object", + "properties": { + "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the basic list of all unbonded mixnodes.", + "type": "object", + "required": [ + "get_unbonded_mix_nodes" + ], + "properties": { + "get_unbonded_mix_nodes": { + "type": "object", + "properties": { + "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the basic list of all unbonded mixnodes that belonged to a particular owner.", + "type": "object", + "required": [ + "get_unbonded_mix_nodes_by_owner" + ], + "properties": { + "get_unbonded_mix_nodes_by_owner": { + "type": "object", + "required": [ + "owner" + ], + "properties": { + "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "description": "The address of the owner of the the mixnodes used for the query.", + "type": "string" + }, + "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the basic list of all unbonded mixnodes that used the particular identity key.", + "type": "object", + "required": [ + "get_unbonded_mix_nodes_by_identity_key" + ], + "properties": { + "get_unbonded_mix_nodes_by_identity_key": { + "type": "object", + "required": [ + "identity_key" + ], + "properties": { + "identity_key": { + "description": "The identity key (base58-encoded ed25519 public key) of the mixnode used for the query.", + "type": "string" + }, + "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the detailed mixnode information belonging to the particular owner.", + "type": "object", + "required": [ + "get_owned_mixnode" + ], + "properties": { + "get_owned_mixnode": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "Address of the mixnode owner to use for the query.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the detailed mixnode information of a node with the provided id.", + "type": "object", + "required": [ + "get_mixnode_details" + ], + "properties": { + "get_mixnode_details": { + "type": "object", + "required": [ + "mix_id" + ], + "properties": { + "mix_id": { + "description": "Id of the node to query.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the rewarding information of a mixnode with the provided id.", + "type": "object", + "required": [ + "get_mixnode_rewarding_details" + ], + "properties": { + "get_mixnode_rewarding_details": { + "type": "object", + "required": [ + "mix_id" + ], + "properties": { + "mix_id": { + "description": "Id of the node to query.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the stake saturation of a mixnode with the provided id.", + "type": "object", + "required": [ + "get_stake_saturation" + ], + "properties": { + "get_stake_saturation": { + "type": "object", + "required": [ + "mix_id" + ], + "properties": { + "mix_id": { + "description": "Id of the node to query.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the basic information of an unbonded mixnode with the provided id.", + "type": "object", + "required": [ + "get_unbonded_mix_node_information" + ], + "properties": { + "get_unbonded_mix_node_information": { + "type": "object", + "required": [ + "mix_id" + ], + "properties": { + "mix_id": { + "description": "Id of the node to query.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the detailed mixnode information of a node given its current identity key.", + "type": "object", + "required": [ + "get_bonded_mixnode_details_by_identity" + ], + "properties": { + "get_bonded_mixnode_details_by_identity": { + "type": "object", + "required": [ + "mix_identity" + ], + "properties": { + "mix_identity": { + "description": "The identity key (base58-encoded ed25519 public key) of the mixnode used for the query.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the current layer configuration of the mix network.", + "type": "object", + "required": [ + "get_layer_distribution" + ], + "properties": { + "get_layer_distribution": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the basic list of all currently bonded gateways.", + "type": "object", + "required": [ + "get_gateways" + ], + "properties": { + "get_gateways": { + "type": "object", + "properties": { + "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the gateway details of a node given its identity key.", + "type": "object", + "required": [ + "get_gateway_bond" + ], + "properties": { + "get_gateway_bond": { + "type": "object", + "required": [ + "identity" + ], + "properties": { + "identity": { + "description": "The identity key (base58-encoded ed25519 public key) of the gateway used for the query.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the detailed gateway information belonging to the particular owner.", + "type": "object", + "required": [ + "get_owned_gateway" + ], + "properties": { + "get_owned_gateway": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "Address of the gateway owner to use for the query.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets all delegations associated with particular mixnode", + "type": "object", + "required": [ + "get_mixnode_delegations" + ], + "properties": { + "get_mixnode_delegations": { + "type": "object", + "required": [ + "mix_id" + ], + "properties": { + "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "mix_id": { + "description": "Id of the node to query.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets all delegations associated with particular delegator", + "type": "object", + "required": [ + "get_delegator_delegations" + ], + "properties": { + "get_delegator_delegations": { + "type": "object", + "required": [ + "delegator" + ], + "properties": { + "delegator": { + "description": "The address of the owner of the delegations.", + "type": "string" + }, + "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "string" + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets delegation information associated with particular mixnode - delegator pair", + "type": "object", + "required": [ + "get_delegation_details" + ], + "properties": { + "get_delegation_details": { + "type": "object", + "required": [ + "delegator", + "mix_id" + ], + "properties": { + "delegator": { + "description": "The address of the owner of the delegation.", + "type": "string" + }, + "mix_id": { + "description": "Id of the node to query.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "proxy": { + "description": "Entity who made the delegation on behalf of the owner. If present, it's most likely the address of the vesting contract.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets all delegations in the system", + "type": "object", + "required": [ + "get_all_delegations" + ], + "properties": { + "get_all_delegations": { + "type": "object", + "properties": { + "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "string" + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the reward amount accrued by the node operator that has not yet been claimed.", + "type": "object", + "required": [ + "get_pending_operator_reward" + ], + "properties": { + "get_pending_operator_reward": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "Address of the operator to use for the query.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the reward amount accrued by the particular mixnode that has not yet been claimed.", + "type": "object", + "required": [ + "get_pending_mix_node_operator_reward" + ], + "properties": { + "get_pending_mix_node_operator_reward": { + "type": "object", + "required": [ + "mix_id" + ], + "properties": { + "mix_id": { + "description": "Id of the node to query.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the reward amount accrued by the particular delegator that has not yet been claimed.", + "type": "object", + "required": [ + "get_pending_delegator_reward" + ], + "properties": { + "get_pending_delegator_reward": { + "type": "object", + "required": [ + "address", + "mix_id" + ], + "properties": { + "address": { + "description": "Address of the delegator to use for the query.", + "type": "string" + }, + "mix_id": { + "description": "Id of the node to query.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "proxy": { + "description": "Entity who made the delegation on behalf of the owner. If present, it's most likely the address of the vesting contract.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Given the provided node performance, attempt to estimate the operator reward for the current epoch.", + "type": "object", + "required": [ + "get_estimated_current_epoch_operator_reward" + ], + "properties": { + "get_estimated_current_epoch_operator_reward": { + "type": "object", + "required": [ + "estimated_performance", + "mix_id" + ], + "properties": { + "estimated_performance": { + "description": "The estimated performance for the current epoch of the given node.", + "allOf": [ + { + "$ref": "#/definitions/Percent" + } + ] + }, + "mix_id": { + "description": "Id of the node to query.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Given the provided node performance, attempt to estimate the delegator reward for the current epoch.", + "type": "object", + "required": [ + "get_estimated_current_epoch_delegator_reward" + ], + "properties": { + "get_estimated_current_epoch_delegator_reward": { + "type": "object", + "required": [ + "address", + "estimated_performance", + "mix_id" + ], + "properties": { + "address": { + "description": "Address of the delegator to use for the query.", + "type": "string" + }, + "estimated_performance": { + "description": "The estimated performance for the current epoch of the given node.", + "allOf": [ + { + "$ref": "#/definitions/Percent" + } + ] + }, + "mix_id": { + "description": "Id of the node to query.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "proxy": { + "description": "Entity who made the delegation on behalf of the owner. If present, it's most likely the address of the vesting contract.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the list of all currently pending epoch events that will be resolved once the current epoch finishes.", + "type": "object", + "required": [ + "get_pending_epoch_events" + ], + "properties": { + "get_pending_epoch_events": { + "type": "object", + "properties": { + "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the list of all currently pending interval events that will be resolved once the current interval finishes.", + "type": "object", + "required": [ + "get_pending_interval_events" + ], + "properties": { + "get_pending_interval_events": { + "type": "object", + "properties": { + "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets detailed information about a pending epoch event given its id.", + "type": "object", + "required": [ + "get_pending_epoch_event" + ], + "properties": { + "get_pending_epoch_event": { + "type": "object", + "required": [ + "event_id" + ], + "properties": { + "event_id": { + "description": "The unique id associated with the event.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets detailed information about a pending interval event given its id.", + "type": "object", + "required": [ + "get_pending_interval_event" + ], + "properties": { + "get_pending_interval_event": { + "type": "object", + "required": [ + "event_id" + ], + "properties": { + "event_id": { + "description": "The unique id associated with the event.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the information about the number of currently pending epoch and interval events.", + "type": "object", + "required": [ + "get_number_of_pending_events" + ], + "properties": { + "get_number_of_pending_events": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the signing nonce associated with the particular cosmos address.", + "type": "object", + "required": [ + "get_signing_nonce" + ], + "properties": { + "get_signing_nonce": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "Cosmos address used for the query of the signing nonce.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Percent": { + "description": "Percent represents a value between 0 and 100% (i.e. between 0.0 and 1.0)", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + } + } + }, + "migrate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "type": "object", + "properties": { + "vesting_contract_address": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + }, + "sudo": null, + "responses": { + "get_all_delegations": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedAllDelegationsResponse", + "description": "Response containing paged list of all delegations currently active.", + "type": "object", + "required": [ + "delegations" + ], + "properties": { + "delegations": { + "description": "Each individual delegation made.", + "type": "array", + "items": { + "$ref": "#/definitions/Delegation" + } + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "string" + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Delegation": { + "description": "Information about tokens being delegated towards given mixnode in order to accrue rewards with their work.", + "type": "object", + "required": [ + "amount", + "cumulative_reward_ratio", + "height", + "mix_id", + "owner" + ], + "properties": { + "amount": { + "description": "Original delegation amount. Note that it is never mutated as delegation accumulates rewards.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "cumulative_reward_ratio": { + "description": "Value of the \"unit delegation\" associated with the mixnode at the time of delegation.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "height": { + "description": "Block height where this delegation occurred.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "mix_id": { + "description": "Id of the MixNode that this delegation was performed against.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "description": "Address of the owner of this delegation.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Proxy address used to delegate the funds on behalf of another address", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_all_families_paged": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedFamiliesResponse", + "description": "Response containing paged list of all families registered in the contract.", + "type": "object", + "required": [ + "families" + ], + "properties": { + "families": { + "description": "The families registered in the contract.", + "type": "array", + "items": { + "$ref": "#/definitions/Family" + } + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false, + "definitions": { + "Family": { + "description": "A group of mixnodes associated with particular staking entity. When defined all nodes belonging to the same family will be prioritised to be put onto the same layer.", + "type": "object", + "required": [ + "head", + "label" + ], + "properties": { + "head": { + "description": "Owner of this family.", + "allOf": [ + { + "$ref": "#/definitions/FamilyHead" + } + ] + }, + "label": { + "description": "Human readable label for this family.", + "type": "string" + }, + "proxy": { + "description": "Optional proxy (i.e. vesting contract address) used when creating the family.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + }, + "FamilyHead": { + "description": "Head of particular family as identified by its identity key (i.e. public component of its ed25519 keypair stringified into base58).", + "type": "string" + } + } + }, + "get_all_members_paged": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedMembersResponse", + "description": "Response containing paged list of all family members (of ALL families) registered in the contract.", + "type": "object", + "required": [ + "members" + ], + "properties": { + "members": { + "description": "The members alongside their family heads.", + "type": "array", + "items": { + "type": "array", + "items": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/FamilyHead" + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false, + "definitions": { + "FamilyHead": { + "description": "Head of particular family as identified by its identity key (i.e. public component of its ed25519 keypair stringified into base58).", + "type": "string" + } + } + }, + "get_bonded_mixnode_details_by_identity": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MixnodeDetailsByIdentityResponse", + "description": "Response containing details of a bonded mixnode with the provided identity key.", + "type": "object", + "required": [ + "identity_key" + ], + "properties": { + "identity_key": { + "description": "The identity key (base58-encoded ed25519 public key) of the mixnode.", + "type": "string" + }, + "mixnode_details": { + "description": "If there exists a bonded mixnode with the provided identity key, this field contains its detailed information.", + "anyOf": [ + { + "$ref": "#/definitions/MixNodeDetails" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Layer": { + "type": "string", + "enum": [ + "One", + "Two", + "Three" + ] + }, + "MixNode": { + "description": "Information provided by the node operator during bonding that are used to allow other entities to use the services of this node.", + "type": "object", + "required": [ + "host", + "http_api_port", + "identity_key", + "mix_port", + "sphinx_key", + "verloc_port", + "version" + ], + "properties": { + "host": { + "description": "Network address of this mixnode, for example 1.1.1.1 or foo.mixnode.com", + "type": "string" + }, + "http_api_port": { + "description": "Port used by this mixnode for its http(s) API", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "identity_key": { + "description": "Base58-encoded ed25519 EdDSA public key.", + "type": "string" + }, + "mix_port": { + "description": "Port used by this mixnode for listening for mix packets.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "sphinx_key": { + "description": "Base58-encoded x25519 public key used for sphinx key derivation.", + "type": "string" + }, + "verloc_port": { + "description": "Port used by this mixnode for listening for verloc requests.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "version": { + "description": "The self-reported semver version of this mixnode.", + "type": "string" + } + }, + "additionalProperties": false + }, + "MixNodeBond": { + "description": "Basic mixnode information provided by the node operator.", + "type": "object", + "required": [ + "bonding_height", + "is_unbonding", + "layer", + "mix_id", + "mix_node", + "original_pledge", + "owner" + ], + "properties": { + "bonding_height": { + "description": "Block height at which this mixnode has been bonded.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "is_unbonding": { + "description": "Flag to indicate whether this node is in the process of unbonding, that will conclude upon the epoch finishing.", + "type": "boolean" + }, + "layer": { + "description": "Layer assigned to this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/Layer" + } + ] + }, + "mix_id": { + "description": "Unique id assigned to the bonded mixnode.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "mix_node": { + "description": "Information provided by the operator for the purposes of bonding.", + "allOf": [ + { + "$ref": "#/definitions/MixNode" + } + ] + }, + "original_pledge": { + "description": "Original amount pledged by the operator of this node.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "owner": { + "description": "Address of the owner of this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Entity who bonded this mixnode on behalf of the owner. If exists, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeCostParams": { + "description": "The cost parameters, or the cost function, defined for the particular mixnode that influences how the rewards should be split between the node operator and its delegators.", + "type": "object", + "required": [ + "interval_operating_cost", + "profit_margin_percent" + ], + "properties": { + "interval_operating_cost": { + "description": "Operating cost of the associated mixnode per the entire interval.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "profit_margin_percent": { + "description": "The profit margin of the associated mixnode, i.e. the desired percent of the reward to be distributed to the operator.", + "allOf": [ + { + "$ref": "#/definitions/Percent" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeDetails": { + "description": "Full details associated with given mixnode.", + "type": "object", + "required": [ + "bond_information", + "rewarding_details" + ], + "properties": { + "bond_information": { + "description": "Basic bond information of this mixnode, such as owner address, original pledge, etc.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeBond" + } + ] + }, + "pending_changes": { + "description": "Adjustments to the mixnode that are ought to happen during future epoch transitions.", + "default": { + "pledge_change": null + }, + "allOf": [ + { + "$ref": "#/definitions/PendingMixNodeChanges" + } + ] + }, + "rewarding_details": { + "description": "Details used for computation of rewarding related data.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeRewarding" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeRewarding": { + "type": "object", + "required": [ + "cost_params", + "delegates", + "last_rewarded_epoch", + "operator", + "total_unit_reward", + "unique_delegations", + "unit_delegation" + ], + "properties": { + "cost_params": { + "description": "Information provided by the operator that influence the cost function.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeCostParams" + } + ] + }, + "delegates": { + "description": "Total delegation and compounded reward earned by all node delegators.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "last_rewarded_epoch": { + "description": "Marks the epoch when this node was last rewarded so that we wouldn't accidentally attempt to reward it multiple times in the same epoch.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "operator": { + "description": "Total pledge and compounded reward earned by the node operator.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "total_unit_reward": { + "description": "Cumulative reward earned by the \"unit delegation\" since the block 0.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "unique_delegations": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "unit_delegation": { + "description": "Value of the theoretical \"unit delegation\" that has delegated to this mixnode at block 0.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + } + }, + "additionalProperties": false + }, + "PendingMixNodeChanges": { + "type": "object", + "properties": { + "pledge_change": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "Percent": { + "description": "Percent represents a value between 0 and 100% (i.e. between 0.0 and 1.0)", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_c_w2_contract_version": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ContractVersion", + "type": "object", + "required": [ + "contract", + "version" + ], + "properties": { + "contract": { + "description": "contract is the crate name of the implementing contract, eg. `crate:cw20-base` we will use other prefixes for other languages, and their standard global namespacing", + "type": "string" + }, + "version": { + "description": "version is any string that this implementation knows. It may be simple counter \"1\", \"2\". or semantic version on release tags \"v0.7.0\", or some custom feature flag list. the only code that needs to understand the version parsing is code that knows how to migrate from the given contract (and is tied to it's implementation somehow)", + "type": "string" + } + }, + "additionalProperties": false + }, + "get_contract_version": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ContractBuildInformation", + "type": "object", + "required": [ + "build_timestamp", + "build_version", + "commit_branch", + "commit_sha", + "commit_timestamp", + "rustc_version" + ], + "properties": { + "build_timestamp": { + "description": "Provides the build timestamp, for example `2021-02-23T20:14:46.558472672+00:00`.", + "type": "string" + }, + "build_version": { + "description": "Provides the build version, for example `0.1.0-9-g46f83e1`.", + "type": "string" + }, + "commit_branch": { + "description": "Provides the name of the git branch that was used for the build, for example `master`.", + "type": "string" + }, + "commit_sha": { + "description": "Provides the hash of the commit that was used for the build, for example `46f83e112520533338245862d366f6a02cef07d4`.", + "type": "string" + }, + "commit_timestamp": { + "description": "Provides the timestamp of the commit that was used for the build, for example `2021-02-23T08:08:02-05:00`.", + "type": "string" + }, + "rustc_version": { + "description": "Provides the rustc version that was used for the build, for example `1.52.0-nightly`.", + "type": "string" + } + }, + "additionalProperties": false + }, + "get_current_interval_details": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "CurrentIntervalResponse", + "description": "Information about the current rewarding interval.", + "type": "object", + "required": [ + "current_blocktime", + "interval", + "is_current_epoch_over", + "is_current_interval_over" + ], + "properties": { + "current_blocktime": { + "description": "The current blocktime", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "interval": { + "description": "Detailed information about the underlying interval.", + "allOf": [ + { + "$ref": "#/definitions/Interval" + } + ] + }, + "is_current_epoch_over": { + "description": "Flag indicating whether the current epoch is over and it should be advanced.", + "type": "boolean" + }, + "is_current_interval_over": { + "description": "Flag indicating whether the current interval is over and it should be advanced.", + "type": "boolean" + } + }, + "additionalProperties": false, + "definitions": { + "Duration": { + "type": "object", + "required": [ + "nanos", + "secs" + ], + "properties": { + "nanos": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "secs": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + }, + "Interval": { + "type": "object", + "required": [ + "current_epoch_id", + "current_epoch_start", + "epoch_length", + "epochs_in_interval", + "id", + "total_elapsed_epochs" + ], + "properties": { + "current_epoch_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "current_epoch_start": { + "type": "string" + }, + "epoch_length": { + "$ref": "#/definitions/Duration" + }, + "epochs_in_interval": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "total_elapsed_epochs": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + } + } + } + }, + "get_delegation_details": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MixNodeDelegationResponse", + "description": "Response containing delegation details.", + "type": "object", + "required": [ + "mixnode_still_bonded" + ], + "properties": { + "delegation": { + "description": "If the delegation exists, this field contains its detailed information.", + "anyOf": [ + { + "$ref": "#/definitions/Delegation" + }, + { + "type": "null" + } + ] + }, + "mixnode_still_bonded": { + "description": "Flag indicating whether the node towards which the delegation was made is still bonded in the network.", + "type": "boolean" + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Delegation": { + "description": "Information about tokens being delegated towards given mixnode in order to accrue rewards with their work.", + "type": "object", + "required": [ + "amount", + "cumulative_reward_ratio", + "height", + "mix_id", + "owner" + ], + "properties": { + "amount": { + "description": "Original delegation amount. Note that it is never mutated as delegation accumulates rewards.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "cumulative_reward_ratio": { + "description": "Value of the \"unit delegation\" associated with the mixnode at the time of delegation.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "height": { + "description": "Block height where this delegation occurred.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "mix_id": { + "description": "Id of the MixNode that this delegation was performed against.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "description": "Address of the owner of this delegation.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Proxy address used to delegate the funds on behalf of another address", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_delegator_delegations": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedDelegatorDelegationsResponse", + "description": "Response containing paged list of all delegations made by the particular address.", + "type": "object", + "required": [ + "delegations" + ], + "properties": { + "delegations": { + "description": "Each individual delegation made.", + "type": "array", + "items": { + "$ref": "#/definitions/Delegation" + } + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "string" + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Delegation": { + "description": "Information about tokens being delegated towards given mixnode in order to accrue rewards with their work.", + "type": "object", + "required": [ + "amount", + "cumulative_reward_ratio", + "height", + "mix_id", + "owner" + ], + "properties": { + "amount": { + "description": "Original delegation amount. Note that it is never mutated as delegation accumulates rewards.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "cumulative_reward_ratio": { + "description": "Value of the \"unit delegation\" associated with the mixnode at the time of delegation.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "height": { + "description": "Block height where this delegation occurred.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "mix_id": { + "description": "Id of the MixNode that this delegation was performed against.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "description": "Address of the owner of this delegation.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Proxy address used to delegate the funds on behalf of another address", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_epoch_status": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "EpochStatus", + "description": "The status of the current rewarding epoch.", + "type": "object", + "required": [ + "being_advanced_by", + "state" + ], + "properties": { + "being_advanced_by": { + "description": "Specifies either, which validator is currently performing progression into the following epoch (if the epoch is currently being progressed), or which validator was responsible for progressing into the current epoch (if the epoch is currently in progress)", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "state": { + "description": "The concrete state of the epoch.", + "allOf": [ + { + "$ref": "#/definitions/EpochState" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "EpochState": { + "description": "The state of the current rewarding epoch.", + "oneOf": [ + { + "description": "Represents the state of an epoch that's in progress (well, duh.) All actions are allowed to be issued.", + "type": "string", + "enum": [ + "in_progress" + ] + }, + { + "description": "Represents the state of an epoch when the rewarding entity has been decided on, and the mixnodes are in the process of being rewarded for their work in this epoch.", + "type": "object", + "required": [ + "rewarding" + ], + "properties": { + "rewarding": { + "type": "object", + "required": [ + "final_node_id", + "last_rewarded" + ], + "properties": { + "final_node_id": { + "description": "The id of the last node that's going to be rewarded before progressing into the next state.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "last_rewarded": { + "description": "The id of the last node that has already received its rewards.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Represents the state of an epoch when all mixnodes have already been rewarded for their work in this epoch and all issued actions should now get resolved before being allowed to advance into the next epoch.", + "type": "string", + "enum": [ + "reconciling_events" + ] + }, + { + "description": "Represents the state of an epoch when all mixnodes have already been rewarded for their work in this epoch, all issued actions got resolved and the epoch should now be advanced whilst assigning new rewarded set.", + "type": "string", + "enum": [ + "advancing_epoch" + ] + } + ] + } + } + }, + "get_estimated_current_epoch_delegator_reward": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "EstimatedCurrentEpochRewardResponse", + "description": "Response containing estimation of node rewards for the current epoch.", + "type": "object", + "properties": { + "current_stake_value": { + "description": "The current stake value given all past rewarding and compounding since the original staking was performed.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + }, + "current_stake_value_detailed_amount": { + "description": "The current stake value. Note that it's nearly identical to `current_stake_value`, however, it contains few additional decimal points for more accurate reward calculation.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "detailed_estimation_amount": { + "description": "The full reward estimation. Note that it's nearly identical to `estimation`, however, it contains few additional decimal points for more accurate reward calculation.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "estimation": { + "description": "The reward estimation for the current epoch, i.e. the amount of tokens that could be claimable after the epoch finishes and the state of the network does not change.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + }, + "original_stake": { + "description": "The amount of tokens initially staked.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_estimated_current_epoch_operator_reward": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "EstimatedCurrentEpochRewardResponse", + "description": "Response containing estimation of node rewards for the current epoch.", + "type": "object", + "properties": { + "current_stake_value": { + "description": "The current stake value given all past rewarding and compounding since the original staking was performed.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + }, + "current_stake_value_detailed_amount": { + "description": "The current stake value. Note that it's nearly identical to `current_stake_value`, however, it contains few additional decimal points for more accurate reward calculation.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "detailed_estimation_amount": { + "description": "The full reward estimation. Note that it's nearly identical to `estimation`, however, it contains few additional decimal points for more accurate reward calculation.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "estimation": { + "description": "The reward estimation for the current epoch, i.e. the amount of tokens that could be claimable after the epoch finishes and the state of the network does not change.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + }, + "original_stake": { + "description": "The amount of tokens initially staked.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_family_by_head": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "FamilyByHeadResponse", + "description": "Response containing family information.", + "type": "object", + "required": [ + "head" + ], + "properties": { + "family": { + "description": "If applicable, the family associated with the provided head.", + "anyOf": [ + { + "$ref": "#/definitions/Family" + }, + { + "type": "null" + } + ] + }, + "head": { + "description": "The family head used for the query.", + "allOf": [ + { + "$ref": "#/definitions/FamilyHead" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Family": { + "description": "A group of mixnodes associated with particular staking entity. When defined all nodes belonging to the same family will be prioritised to be put onto the same layer.", + "type": "object", + "required": [ + "head", + "label" + ], + "properties": { + "head": { + "description": "Owner of this family.", + "allOf": [ + { + "$ref": "#/definitions/FamilyHead" + } + ] + }, + "label": { + "description": "Human readable label for this family.", + "type": "string" + }, + "proxy": { + "description": "Optional proxy (i.e. vesting contract address) used when creating the family.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + }, + "FamilyHead": { + "description": "Head of particular family as identified by its identity key (i.e. public component of its ed25519 keypair stringified into base58).", + "type": "string" + } + } + }, + "get_family_by_label": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "FamilyByLabelResponse", + "description": "Response containing family information.", + "type": "object", + "required": [ + "label" + ], + "properties": { + "family": { + "description": "If applicable, the family associated with the provided label.", + "anyOf": [ + { + "$ref": "#/definitions/Family" + }, + { + "type": "null" + } + ] + }, + "label": { + "description": "The family label used for the query.", + "type": "string" + } + }, + "additionalProperties": false, + "definitions": { + "Family": { + "description": "A group of mixnodes associated with particular staking entity. When defined all nodes belonging to the same family will be prioritised to be put onto the same layer.", + "type": "object", + "required": [ + "head", + "label" + ], + "properties": { + "head": { + "description": "Owner of this family.", + "allOf": [ + { + "$ref": "#/definitions/FamilyHead" + } + ] + }, + "label": { + "description": "Human readable label for this family.", + "type": "string" + }, + "proxy": { + "description": "Optional proxy (i.e. vesting contract address) used when creating the family.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + }, + "FamilyHead": { + "description": "Head of particular family as identified by its identity key (i.e. public component of its ed25519 keypair stringified into base58).", + "type": "string" + } + } + }, + "get_family_members_by_head": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "FamilyMembersByHeadResponse", + "description": "Response containing family members information.", + "type": "object", + "required": [ + "head", + "members" + ], + "properties": { + "head": { + "description": "The family head used for the query.", + "allOf": [ + { + "$ref": "#/definitions/FamilyHead" + } + ] + }, + "members": { + "description": "All members belonging to the specified family.", + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false, + "definitions": { + "FamilyHead": { + "description": "Head of particular family as identified by its identity key (i.e. public component of its ed25519 keypair stringified into base58).", + "type": "string" + } + } + }, + "get_family_members_by_label": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "FamilyMembersByLabelResponse", + "description": "Response containing family members information.", + "type": "object", + "required": [ + "label", + "members" + ], + "properties": { + "label": { + "description": "The family label used for the query.", + "type": "string" + }, + "members": { + "description": "All members belonging to the specified family.", + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "get_gateway_bond": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "GatewayBondResponse", + "description": "Response containing details of a gateway with the provided identity key.", + "type": "object", + "required": [ + "identity" + ], + "properties": { + "gateway": { + "description": "If there exists a gateway with the provided identity key, this field contains its details.", + "anyOf": [ + { + "$ref": "#/definitions/GatewayBond" + }, + { + "type": "null" + } + ] + }, + "identity": { + "description": "The identity key (base58-encoded ed25519 public key) of the gateway.", + "type": "string" + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Gateway": { + "description": "Information provided by the node operator during bonding that are used to allow other entities to use the services of this node.", + "type": "object", + "required": [ + "clients_port", + "host", + "identity_key", + "location", + "mix_port", + "sphinx_key", + "version" + ], + "properties": { + "clients_port": { + "description": "Port used by this gateway for listening for client requests.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "host": { + "description": "Network address of this gateway, for example 1.1.1.1 or foo.gateway.com", + "type": "string" + }, + "identity_key": { + "description": "Base58 encoded ed25519 EdDSA public key of the gateway used to derive shared keys with clients", + "type": "string" + }, + "location": { + "description": "The physical, self-reported, location of this gateway.", + "type": "string" + }, + "mix_port": { + "description": "Port used by this gateway for listening for mix packets.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "sphinx_key": { + "description": "Base58-encoded x25519 public key used for sphinx key derivation.", + "type": "string" + }, + "version": { + "description": "The self-reported semver version of this gateway.", + "type": "string" + } + }, + "additionalProperties": false + }, + "GatewayBond": { + "description": "Basic gateway information provided by the node operator.", + "type": "object", + "required": [ + "block_height", + "gateway", + "owner", + "pledge_amount" + ], + "properties": { + "block_height": { + "description": "Block height at which this gateway has been bonded.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "gateway": { + "description": "Information provided by the operator for the purposes of bonding.", + "allOf": [ + { + "$ref": "#/definitions/Gateway" + } + ] + }, + "owner": { + "description": "Address of the owner of this gateway.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "pledge_amount": { + "description": "Original amount pledged by the operator of this node.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "proxy": { + "description": "Entity who bonded this gateway on behalf of the owner. If exists, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_gateways": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedGatewayResponse", + "description": "Response containing paged list of all gateway bonds in the contract.", + "type": "object", + "required": [ + "nodes", + "per_page" + ], + "properties": { + "nodes": { + "description": "The gateway bond information present in the contract.", + "type": "array", + "items": { + "$ref": "#/definitions/GatewayBond" + } + }, + "per_page": { + "description": "Maximum number of entries that could be included in a response. `per_page <= nodes.len()`", + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Gateway": { + "description": "Information provided by the node operator during bonding that are used to allow other entities to use the services of this node.", + "type": "object", + "required": [ + "clients_port", + "host", + "identity_key", + "location", + "mix_port", + "sphinx_key", + "version" + ], + "properties": { + "clients_port": { + "description": "Port used by this gateway for listening for client requests.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "host": { + "description": "Network address of this gateway, for example 1.1.1.1 or foo.gateway.com", + "type": "string" + }, + "identity_key": { + "description": "Base58 encoded ed25519 EdDSA public key of the gateway used to derive shared keys with clients", + "type": "string" + }, + "location": { + "description": "The physical, self-reported, location of this gateway.", + "type": "string" + }, + "mix_port": { + "description": "Port used by this gateway for listening for mix packets.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "sphinx_key": { + "description": "Base58-encoded x25519 public key used for sphinx key derivation.", + "type": "string" + }, + "version": { + "description": "The self-reported semver version of this gateway.", + "type": "string" + } + }, + "additionalProperties": false + }, + "GatewayBond": { + "description": "Basic gateway information provided by the node operator.", + "type": "object", + "required": [ + "block_height", + "gateway", + "owner", + "pledge_amount" + ], + "properties": { + "block_height": { + "description": "Block height at which this gateway has been bonded.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "gateway": { + "description": "Information provided by the operator for the purposes of bonding.", + "allOf": [ + { + "$ref": "#/definitions/Gateway" + } + ] + }, + "owner": { + "description": "Address of the owner of this gateway.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "pledge_amount": { + "description": "Original amount pledged by the operator of this node.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "proxy": { + "description": "Entity who bonded this gateway on behalf of the owner. If exists, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_layer_distribution": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "LayerDistribution", + "description": "The current layer distribution of the mix network.", + "type": "object", + "required": [ + "layer1", + "layer2", + "layer3" + ], + "properties": { + "layer1": { + "description": "Number of nodes on the first layer.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "layer2": { + "description": "Number of nodes on the second layer.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "layer3": { + "description": "Number of nodes on the third layer.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "get_mix_node_bonds": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedMixnodeBondsResponse", + "description": "Response containing paged list of all mixnode bonds in the contract.", + "type": "object", + "required": [ + "nodes", + "per_page" + ], + "properties": { + "nodes": { + "description": "The mixnode bond information present in the contract.", + "type": "array", + "items": { + "$ref": "#/definitions/MixNodeBond" + } + }, + "per_page": { + "description": "Maximum number of entries that could be included in a response. `per_page <= nodes.len()`", + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Layer": { + "type": "string", + "enum": [ + "One", + "Two", + "Three" + ] + }, + "MixNode": { + "description": "Information provided by the node operator during bonding that are used to allow other entities to use the services of this node.", + "type": "object", + "required": [ + "host", + "http_api_port", + "identity_key", + "mix_port", + "sphinx_key", + "verloc_port", + "version" + ], + "properties": { + "host": { + "description": "Network address of this mixnode, for example 1.1.1.1 or foo.mixnode.com", + "type": "string" + }, + "http_api_port": { + "description": "Port used by this mixnode for its http(s) API", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "identity_key": { + "description": "Base58-encoded ed25519 EdDSA public key.", + "type": "string" + }, + "mix_port": { + "description": "Port used by this mixnode for listening for mix packets.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "sphinx_key": { + "description": "Base58-encoded x25519 public key used for sphinx key derivation.", + "type": "string" + }, + "verloc_port": { + "description": "Port used by this mixnode for listening for verloc requests.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "version": { + "description": "The self-reported semver version of this mixnode.", + "type": "string" + } + }, + "additionalProperties": false + }, + "MixNodeBond": { + "description": "Basic mixnode information provided by the node operator.", + "type": "object", + "required": [ + "bonding_height", + "is_unbonding", + "layer", + "mix_id", + "mix_node", + "original_pledge", + "owner" + ], + "properties": { + "bonding_height": { + "description": "Block height at which this mixnode has been bonded.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "is_unbonding": { + "description": "Flag to indicate whether this node is in the process of unbonding, that will conclude upon the epoch finishing.", + "type": "boolean" + }, + "layer": { + "description": "Layer assigned to this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/Layer" + } + ] + }, + "mix_id": { + "description": "Unique id assigned to the bonded mixnode.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "mix_node": { + "description": "Information provided by the operator for the purposes of bonding.", + "allOf": [ + { + "$ref": "#/definitions/MixNode" + } + ] + }, + "original_pledge": { + "description": "Original amount pledged by the operator of this node.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "owner": { + "description": "Address of the owner of this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Entity who bonded this mixnode on behalf of the owner. If exists, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_mix_nodes_detailed": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedMixnodesDetailsResponse", + "description": "Response containing paged list of all mixnode details in the contract.", + "type": "object", + "required": [ + "nodes", + "per_page" + ], + "properties": { + "nodes": { + "description": "All mixnode details stored in the contract. Apart from the basic bond information it also contains details required for all future reward calculation as well as any pending changes requested by the operator.", + "type": "array", + "items": { + "$ref": "#/definitions/MixNodeDetails" + } + }, + "per_page": { + "description": "Maximum number of entries that could be included in a response. `per_page <= nodes.len()`", + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Layer": { + "type": "string", + "enum": [ + "One", + "Two", + "Three" + ] + }, + "MixNode": { + "description": "Information provided by the node operator during bonding that are used to allow other entities to use the services of this node.", + "type": "object", + "required": [ + "host", + "http_api_port", + "identity_key", + "mix_port", + "sphinx_key", + "verloc_port", + "version" + ], + "properties": { + "host": { + "description": "Network address of this mixnode, for example 1.1.1.1 or foo.mixnode.com", + "type": "string" + }, + "http_api_port": { + "description": "Port used by this mixnode for its http(s) API", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "identity_key": { + "description": "Base58-encoded ed25519 EdDSA public key.", + "type": "string" + }, + "mix_port": { + "description": "Port used by this mixnode for listening for mix packets.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "sphinx_key": { + "description": "Base58-encoded x25519 public key used for sphinx key derivation.", + "type": "string" + }, + "verloc_port": { + "description": "Port used by this mixnode for listening for verloc requests.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "version": { + "description": "The self-reported semver version of this mixnode.", + "type": "string" + } + }, + "additionalProperties": false + }, + "MixNodeBond": { + "description": "Basic mixnode information provided by the node operator.", + "type": "object", + "required": [ + "bonding_height", + "is_unbonding", + "layer", + "mix_id", + "mix_node", + "original_pledge", + "owner" + ], + "properties": { + "bonding_height": { + "description": "Block height at which this mixnode has been bonded.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "is_unbonding": { + "description": "Flag to indicate whether this node is in the process of unbonding, that will conclude upon the epoch finishing.", + "type": "boolean" + }, + "layer": { + "description": "Layer assigned to this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/Layer" + } + ] + }, + "mix_id": { + "description": "Unique id assigned to the bonded mixnode.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "mix_node": { + "description": "Information provided by the operator for the purposes of bonding.", + "allOf": [ + { + "$ref": "#/definitions/MixNode" + } + ] + }, + "original_pledge": { + "description": "Original amount pledged by the operator of this node.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "owner": { + "description": "Address of the owner of this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Entity who bonded this mixnode on behalf of the owner. If exists, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeCostParams": { + "description": "The cost parameters, or the cost function, defined for the particular mixnode that influences how the rewards should be split between the node operator and its delegators.", + "type": "object", + "required": [ + "interval_operating_cost", + "profit_margin_percent" + ], + "properties": { + "interval_operating_cost": { + "description": "Operating cost of the associated mixnode per the entire interval.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "profit_margin_percent": { + "description": "The profit margin of the associated mixnode, i.e. the desired percent of the reward to be distributed to the operator.", + "allOf": [ + { + "$ref": "#/definitions/Percent" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeDetails": { + "description": "Full details associated with given mixnode.", + "type": "object", + "required": [ + "bond_information", + "rewarding_details" + ], + "properties": { + "bond_information": { + "description": "Basic bond information of this mixnode, such as owner address, original pledge, etc.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeBond" + } + ] + }, + "pending_changes": { + "description": "Adjustments to the mixnode that are ought to happen during future epoch transitions.", + "default": { + "pledge_change": null + }, + "allOf": [ + { + "$ref": "#/definitions/PendingMixNodeChanges" + } + ] + }, + "rewarding_details": { + "description": "Details used for computation of rewarding related data.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeRewarding" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeRewarding": { + "type": "object", + "required": [ + "cost_params", + "delegates", + "last_rewarded_epoch", + "operator", + "total_unit_reward", + "unique_delegations", + "unit_delegation" + ], + "properties": { + "cost_params": { + "description": "Information provided by the operator that influence the cost function.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeCostParams" + } + ] + }, + "delegates": { + "description": "Total delegation and compounded reward earned by all node delegators.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "last_rewarded_epoch": { + "description": "Marks the epoch when this node was last rewarded so that we wouldn't accidentally attempt to reward it multiple times in the same epoch.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "operator": { + "description": "Total pledge and compounded reward earned by the node operator.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "total_unit_reward": { + "description": "Cumulative reward earned by the \"unit delegation\" since the block 0.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "unique_delegations": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "unit_delegation": { + "description": "Value of the theoretical \"unit delegation\" that has delegated to this mixnode at block 0.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + } + }, + "additionalProperties": false + }, + "PendingMixNodeChanges": { + "type": "object", + "properties": { + "pledge_change": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "Percent": { + "description": "Percent represents a value between 0 and 100% (i.e. between 0.0 and 1.0)", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_mixnode_delegations": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedMixNodeDelegationsResponse", + "description": "Response containing paged list of all delegations made towards particular mixnode.", + "type": "object", + "required": [ + "delegations" + ], + "properties": { + "delegations": { + "description": "Each individual delegation made.", + "type": "array", + "items": { + "$ref": "#/definitions/Delegation" + } + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Delegation": { + "description": "Information about tokens being delegated towards given mixnode in order to accrue rewards with their work.", + "type": "object", + "required": [ + "amount", + "cumulative_reward_ratio", + "height", + "mix_id", + "owner" + ], + "properties": { + "amount": { + "description": "Original delegation amount. Note that it is never mutated as delegation accumulates rewards.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "cumulative_reward_ratio": { + "description": "Value of the \"unit delegation\" associated with the mixnode at the time of delegation.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "height": { + "description": "Block height where this delegation occurred.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "mix_id": { + "description": "Id of the MixNode that this delegation was performed against.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "description": "Address of the owner of this delegation.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Proxy address used to delegate the funds on behalf of another address", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_mixnode_details": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MixnodeDetailsResponse", + "description": "Response containing details of a mixnode with the provided id.", + "type": "object", + "required": [ + "mix_id" + ], + "properties": { + "mix_id": { + "description": "Id of the requested mixnode.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "mixnode_details": { + "description": "If there exists a mixnode with the provided id, this field contains its detailed information.", + "anyOf": [ + { + "$ref": "#/definitions/MixNodeDetails" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Layer": { + "type": "string", + "enum": [ + "One", + "Two", + "Three" + ] + }, + "MixNode": { + "description": "Information provided by the node operator during bonding that are used to allow other entities to use the services of this node.", + "type": "object", + "required": [ + "host", + "http_api_port", + "identity_key", + "mix_port", + "sphinx_key", + "verloc_port", + "version" + ], + "properties": { + "host": { + "description": "Network address of this mixnode, for example 1.1.1.1 or foo.mixnode.com", + "type": "string" + }, + "http_api_port": { + "description": "Port used by this mixnode for its http(s) API", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "identity_key": { + "description": "Base58-encoded ed25519 EdDSA public key.", + "type": "string" + }, + "mix_port": { + "description": "Port used by this mixnode for listening for mix packets.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "sphinx_key": { + "description": "Base58-encoded x25519 public key used for sphinx key derivation.", + "type": "string" + }, + "verloc_port": { + "description": "Port used by this mixnode for listening for verloc requests.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "version": { + "description": "The self-reported semver version of this mixnode.", + "type": "string" + } + }, + "additionalProperties": false + }, + "MixNodeBond": { + "description": "Basic mixnode information provided by the node operator.", + "type": "object", + "required": [ + "bonding_height", + "is_unbonding", + "layer", + "mix_id", + "mix_node", + "original_pledge", + "owner" + ], + "properties": { + "bonding_height": { + "description": "Block height at which this mixnode has been bonded.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "is_unbonding": { + "description": "Flag to indicate whether this node is in the process of unbonding, that will conclude upon the epoch finishing.", + "type": "boolean" + }, + "layer": { + "description": "Layer assigned to this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/Layer" + } + ] + }, + "mix_id": { + "description": "Unique id assigned to the bonded mixnode.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "mix_node": { + "description": "Information provided by the operator for the purposes of bonding.", + "allOf": [ + { + "$ref": "#/definitions/MixNode" + } + ] + }, + "original_pledge": { + "description": "Original amount pledged by the operator of this node.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "owner": { + "description": "Address of the owner of this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Entity who bonded this mixnode on behalf of the owner. If exists, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeCostParams": { + "description": "The cost parameters, or the cost function, defined for the particular mixnode that influences how the rewards should be split between the node operator and its delegators.", + "type": "object", + "required": [ + "interval_operating_cost", + "profit_margin_percent" + ], + "properties": { + "interval_operating_cost": { + "description": "Operating cost of the associated mixnode per the entire interval.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "profit_margin_percent": { + "description": "The profit margin of the associated mixnode, i.e. the desired percent of the reward to be distributed to the operator.", + "allOf": [ + { + "$ref": "#/definitions/Percent" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeDetails": { + "description": "Full details associated with given mixnode.", + "type": "object", + "required": [ + "bond_information", + "rewarding_details" + ], + "properties": { + "bond_information": { + "description": "Basic bond information of this mixnode, such as owner address, original pledge, etc.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeBond" + } + ] + }, + "pending_changes": { + "description": "Adjustments to the mixnode that are ought to happen during future epoch transitions.", + "default": { + "pledge_change": null + }, + "allOf": [ + { + "$ref": "#/definitions/PendingMixNodeChanges" + } + ] + }, + "rewarding_details": { + "description": "Details used for computation of rewarding related data.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeRewarding" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeRewarding": { + "type": "object", + "required": [ + "cost_params", + "delegates", + "last_rewarded_epoch", + "operator", + "total_unit_reward", + "unique_delegations", + "unit_delegation" + ], + "properties": { + "cost_params": { + "description": "Information provided by the operator that influence the cost function.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeCostParams" + } + ] + }, + "delegates": { + "description": "Total delegation and compounded reward earned by all node delegators.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "last_rewarded_epoch": { + "description": "Marks the epoch when this node was last rewarded so that we wouldn't accidentally attempt to reward it multiple times in the same epoch.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "operator": { + "description": "Total pledge and compounded reward earned by the node operator.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "total_unit_reward": { + "description": "Cumulative reward earned by the \"unit delegation\" since the block 0.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "unique_delegations": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "unit_delegation": { + "description": "Value of the theoretical \"unit delegation\" that has delegated to this mixnode at block 0.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + } + }, + "additionalProperties": false + }, + "PendingMixNodeChanges": { + "type": "object", + "properties": { + "pledge_change": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "Percent": { + "description": "Percent represents a value between 0 and 100% (i.e. between 0.0 and 1.0)", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_mixnode_rewarding_details": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MixnodeRewardingDetailsResponse", + "description": "Response containing rewarding information of a mixnode with the provided id.", + "type": "object", + "required": [ + "mix_id" + ], + "properties": { + "mix_id": { + "description": "Id of the requested mixnode.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "rewarding_details": { + "description": "If there exists a mixnode with the provided id, this field contains its rewarding information.", + "anyOf": [ + { + "$ref": "#/definitions/MixNodeRewarding" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "MixNodeCostParams": { + "description": "The cost parameters, or the cost function, defined for the particular mixnode that influences how the rewards should be split between the node operator and its delegators.", + "type": "object", + "required": [ + "interval_operating_cost", + "profit_margin_percent" + ], + "properties": { + "interval_operating_cost": { + "description": "Operating cost of the associated mixnode per the entire interval.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "profit_margin_percent": { + "description": "The profit margin of the associated mixnode, i.e. the desired percent of the reward to be distributed to the operator.", + "allOf": [ + { + "$ref": "#/definitions/Percent" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeRewarding": { + "type": "object", + "required": [ + "cost_params", + "delegates", + "last_rewarded_epoch", + "operator", + "total_unit_reward", + "unique_delegations", + "unit_delegation" + ], + "properties": { + "cost_params": { + "description": "Information provided by the operator that influence the cost function.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeCostParams" + } + ] + }, + "delegates": { + "description": "Total delegation and compounded reward earned by all node delegators.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "last_rewarded_epoch": { + "description": "Marks the epoch when this node was last rewarded so that we wouldn't accidentally attempt to reward it multiple times in the same epoch.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "operator": { + "description": "Total pledge and compounded reward earned by the node operator.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "total_unit_reward": { + "description": "Cumulative reward earned by the \"unit delegation\" since the block 0.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "unique_delegations": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "unit_delegation": { + "description": "Value of the theoretical \"unit delegation\" that has delegated to this mixnode at block 0.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + } + }, + "additionalProperties": false + }, + "Percent": { + "description": "Percent represents a value between 0 and 100% (i.e. between 0.0 and 1.0)", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_number_of_pending_events": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "NumberOfPendingEventsResponse", + "description": "Response containing number of currently pending epoch and interval events.", + "type": "object", + "required": [ + "epoch_events", + "interval_events" + ], + "properties": { + "epoch_events": { + "description": "The number of the currently pending epoch events.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "interval_events": { + "description": "The number of the currently pending epoch events.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "get_owned_gateway": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "GatewayOwnershipResponse", + "description": "Response containing details of a gateway belonging to the particular owner.", + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "Validated address of the gateway owner.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "gateway": { + "description": "If the provided address owns a gateway, this field contains its details.", + "anyOf": [ + { + "$ref": "#/definitions/GatewayBond" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Gateway": { + "description": "Information provided by the node operator during bonding that are used to allow other entities to use the services of this node.", + "type": "object", + "required": [ + "clients_port", + "host", + "identity_key", + "location", + "mix_port", + "sphinx_key", + "version" + ], + "properties": { + "clients_port": { + "description": "Port used by this gateway for listening for client requests.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "host": { + "description": "Network address of this gateway, for example 1.1.1.1 or foo.gateway.com", + "type": "string" + }, + "identity_key": { + "description": "Base58 encoded ed25519 EdDSA public key of the gateway used to derive shared keys with clients", + "type": "string" + }, + "location": { + "description": "The physical, self-reported, location of this gateway.", + "type": "string" + }, + "mix_port": { + "description": "Port used by this gateway for listening for mix packets.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "sphinx_key": { + "description": "Base58-encoded x25519 public key used for sphinx key derivation.", + "type": "string" + }, + "version": { + "description": "The self-reported semver version of this gateway.", + "type": "string" + } + }, + "additionalProperties": false + }, + "GatewayBond": { + "description": "Basic gateway information provided by the node operator.", + "type": "object", + "required": [ + "block_height", + "gateway", + "owner", + "pledge_amount" + ], + "properties": { + "block_height": { + "description": "Block height at which this gateway has been bonded.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "gateway": { + "description": "Information provided by the operator for the purposes of bonding.", + "allOf": [ + { + "$ref": "#/definitions/Gateway" + } + ] + }, + "owner": { + "description": "Address of the owner of this gateway.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "pledge_amount": { + "description": "Original amount pledged by the operator of this node.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "proxy": { + "description": "Entity who bonded this gateway on behalf of the owner. If exists, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_owned_mixnode": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MixOwnershipResponse", + "description": "Response containing details of a mixnode belonging to the particular owner.", + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "Validated address of the mixnode owner.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "mixnode_details": { + "description": "If the provided address owns a mixnode, this field contains its detailed information.", + "anyOf": [ + { + "$ref": "#/definitions/MixNodeDetails" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Layer": { + "type": "string", + "enum": [ + "One", + "Two", + "Three" + ] + }, + "MixNode": { + "description": "Information provided by the node operator during bonding that are used to allow other entities to use the services of this node.", + "type": "object", + "required": [ + "host", + "http_api_port", + "identity_key", + "mix_port", + "sphinx_key", + "verloc_port", + "version" + ], + "properties": { + "host": { + "description": "Network address of this mixnode, for example 1.1.1.1 or foo.mixnode.com", + "type": "string" + }, + "http_api_port": { + "description": "Port used by this mixnode for its http(s) API", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "identity_key": { + "description": "Base58-encoded ed25519 EdDSA public key.", + "type": "string" + }, + "mix_port": { + "description": "Port used by this mixnode for listening for mix packets.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "sphinx_key": { + "description": "Base58-encoded x25519 public key used for sphinx key derivation.", + "type": "string" + }, + "verloc_port": { + "description": "Port used by this mixnode for listening for verloc requests.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "version": { + "description": "The self-reported semver version of this mixnode.", + "type": "string" + } + }, + "additionalProperties": false + }, + "MixNodeBond": { + "description": "Basic mixnode information provided by the node operator.", + "type": "object", + "required": [ + "bonding_height", + "is_unbonding", + "layer", + "mix_id", + "mix_node", + "original_pledge", + "owner" + ], + "properties": { + "bonding_height": { + "description": "Block height at which this mixnode has been bonded.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "is_unbonding": { + "description": "Flag to indicate whether this node is in the process of unbonding, that will conclude upon the epoch finishing.", + "type": "boolean" + }, + "layer": { + "description": "Layer assigned to this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/Layer" + } + ] + }, + "mix_id": { + "description": "Unique id assigned to the bonded mixnode.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "mix_node": { + "description": "Information provided by the operator for the purposes of bonding.", + "allOf": [ + { + "$ref": "#/definitions/MixNode" + } + ] + }, + "original_pledge": { + "description": "Original amount pledged by the operator of this node.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "owner": { + "description": "Address of the owner of this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Entity who bonded this mixnode on behalf of the owner. If exists, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeCostParams": { + "description": "The cost parameters, or the cost function, defined for the particular mixnode that influences how the rewards should be split between the node operator and its delegators.", + "type": "object", + "required": [ + "interval_operating_cost", + "profit_margin_percent" + ], + "properties": { + "interval_operating_cost": { + "description": "Operating cost of the associated mixnode per the entire interval.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "profit_margin_percent": { + "description": "The profit margin of the associated mixnode, i.e. the desired percent of the reward to be distributed to the operator.", + "allOf": [ + { + "$ref": "#/definitions/Percent" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeDetails": { + "description": "Full details associated with given mixnode.", + "type": "object", + "required": [ + "bond_information", + "rewarding_details" + ], + "properties": { + "bond_information": { + "description": "Basic bond information of this mixnode, such as owner address, original pledge, etc.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeBond" + } + ] + }, + "pending_changes": { + "description": "Adjustments to the mixnode that are ought to happen during future epoch transitions.", + "default": { + "pledge_change": null + }, + "allOf": [ + { + "$ref": "#/definitions/PendingMixNodeChanges" + } + ] + }, + "rewarding_details": { + "description": "Details used for computation of rewarding related data.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeRewarding" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeRewarding": { + "type": "object", + "required": [ + "cost_params", + "delegates", + "last_rewarded_epoch", + "operator", + "total_unit_reward", + "unique_delegations", + "unit_delegation" + ], + "properties": { + "cost_params": { + "description": "Information provided by the operator that influence the cost function.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeCostParams" + } + ] + }, + "delegates": { + "description": "Total delegation and compounded reward earned by all node delegators.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "last_rewarded_epoch": { + "description": "Marks the epoch when this node was last rewarded so that we wouldn't accidentally attempt to reward it multiple times in the same epoch.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "operator": { + "description": "Total pledge and compounded reward earned by the node operator.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "total_unit_reward": { + "description": "Cumulative reward earned by the \"unit delegation\" since the block 0.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "unique_delegations": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "unit_delegation": { + "description": "Value of the theoretical \"unit delegation\" that has delegated to this mixnode at block 0.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + } + }, + "additionalProperties": false + }, + "PendingMixNodeChanges": { + "type": "object", + "properties": { + "pledge_change": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "Percent": { + "description": "Percent represents a value between 0 and 100% (i.e. between 0.0 and 1.0)", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_pending_delegator_reward": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PendingRewardResponse", + "description": "Response containing information about accrued rewards.", + "type": "object", + "required": [ + "mixnode_still_fully_bonded" + ], + "properties": { + "amount_earned": { + "description": "The amount of tokens that could be claimed.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + }, + "amount_earned_detailed": { + "description": "The full pending rewards. Note that it's nearly identical to `amount_earned`, however, it contains few additional decimal points for more accurate reward calculation.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "amount_staked": { + "description": "The amount of tokens initially staked.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + }, + "mixnode_still_fully_bonded": { + "description": "The associated mixnode is still fully bonded, meaning it is neither unbonded nor in the process of unbonding that would have finished at the epoch transition.", + "type": "boolean" + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_pending_epoch_event": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PendingEpochEventResponse", + "type": "object", + "required": [ + "event_id" + ], + "properties": { + "event": { + "anyOf": [ + { + "$ref": "#/definitions/PendingEpochEventData" + }, + { + "type": "null" + } + ] + }, + "event_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "PendingEpochEventData": { + "description": "Details of a particular pending epoch event.", + "type": "object", + "required": [ + "created_at", + "kind" + ], + "properties": { + "created_at": { + "description": "The block height at which the request has been made.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "kind": { + "description": "The underlying event data, containing its concrete type and information on how it should get resolved.", + "allOf": [ + { + "$ref": "#/definitions/PendingEpochEventKind" + } + ] + } + }, + "additionalProperties": false + }, + "PendingEpochEventKind": { + "description": "Enum encompassing all possible epoch events.", + "oneOf": [ + { + "description": "Request to create a delegation towards particular mixnode. Note that if such delegation already exists, it will get updated with the provided token amount.", + "type": "object", + "required": [ + "delegate" + ], + "properties": { + "delegate": { + "type": "object", + "required": [ + "amount", + "mix_id", + "owner" + ], + "properties": { + "amount": { + "description": "The amount of tokens to use for the delegation.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "mix_id": { + "description": "The id of the mixnode used for the delegation.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "description": "The address of the owner of the delegation.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Entity who made the delegation on behalf of the owner. If present, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Request to remove delegation from particular mixnode.", + "type": "object", + "required": [ + "undelegate" + ], + "properties": { + "undelegate": { + "type": "object", + "required": [ + "mix_id", + "owner" + ], + "properties": { + "mix_id": { + "description": "The id of the mixnode used for the delegation.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "description": "The address of the owner of the delegation.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Entity who made the delegation on behalf of the owner. If present, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Request to pledge more tokens (by the node operator) towards its node.", + "type": "object", + "required": [ + "pledge_more" + ], + "properties": { + "pledge_more": { + "type": "object", + "required": [ + "amount", + "mix_id" + ], + "properties": { + "amount": { + "description": "The amount of additional tokens to use by the pledge.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "mix_id": { + "description": "The id of the mixnode that will have its pledge updated.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Request to decrease amount of pledged tokens (by the node operator) from its node.", + "type": "object", + "required": [ + "decrease_pledge" + ], + "properties": { + "decrease_pledge": { + "type": "object", + "required": [ + "decrease_by", + "mix_id" + ], + "properties": { + "decrease_by": { + "description": "The amount of tokens that should be removed from the pledge.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "mix_id": { + "description": "The id of the mixnode that will have its pledge updated.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Request to unbond a mixnode and completely remove it from the network.", + "type": "object", + "required": [ + "unbond_mixnode" + ], + "properties": { + "unbond_mixnode": { + "type": "object", + "required": [ + "mix_id" + ], + "properties": { + "mix_id": { + "description": "The id of the mixnode that will get unbonded.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Request to update the current size of the active set.", + "type": "object", + "required": [ + "update_active_set_size" + ], + "properties": { + "update_active_set_size": { + "type": "object", + "required": [ + "new_size" + ], + "properties": { + "new_size": { + "description": "The new desired size of the active set.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_pending_epoch_events": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PendingEpochEventsResponse", + "description": "Response containing all currently pending epoch events that will be resolved once the current epoch finishes.", + "type": "object", + "required": [ + "events", + "seconds_until_executable" + ], + "properties": { + "events": { + "description": "The currently pending events.", + "type": "array", + "items": { + "$ref": "#/definitions/PendingEpochEvent" + } + }, + "seconds_until_executable": { + "description": "Amount of seconds until the events would be eligible to be resolved. It's equivalent to the time until the current epoch finishes.", + "type": "integer", + "format": "int64" + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "PendingEpochEvent": { + "description": "A request made at some point in the current epoch that's going to get resolved once the epoch rolls over.", + "type": "object", + "required": [ + "event", + "id" + ], + "properties": { + "event": { + "description": "The underlying event details, containing its type and information on how it should get resolved.", + "allOf": [ + { + "$ref": "#/definitions/PendingEpochEventData" + } + ] + }, + "id": { + "description": "The unique id associated with the event.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "PendingEpochEventData": { + "description": "Details of a particular pending epoch event.", + "type": "object", + "required": [ + "created_at", + "kind" + ], + "properties": { + "created_at": { + "description": "The block height at which the request has been made.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "kind": { + "description": "The underlying event data, containing its concrete type and information on how it should get resolved.", + "allOf": [ + { + "$ref": "#/definitions/PendingEpochEventKind" + } + ] + } + }, + "additionalProperties": false + }, + "PendingEpochEventKind": { + "description": "Enum encompassing all possible epoch events.", + "oneOf": [ + { + "description": "Request to create a delegation towards particular mixnode. Note that if such delegation already exists, it will get updated with the provided token amount.", + "type": "object", + "required": [ + "delegate" + ], + "properties": { + "delegate": { + "type": "object", + "required": [ + "amount", + "mix_id", + "owner" + ], + "properties": { + "amount": { + "description": "The amount of tokens to use for the delegation.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "mix_id": { + "description": "The id of the mixnode used for the delegation.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "description": "The address of the owner of the delegation.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Entity who made the delegation on behalf of the owner. If present, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Request to remove delegation from particular mixnode.", + "type": "object", + "required": [ + "undelegate" + ], + "properties": { + "undelegate": { + "type": "object", + "required": [ + "mix_id", + "owner" + ], + "properties": { + "mix_id": { + "description": "The id of the mixnode used for the delegation.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "description": "The address of the owner of the delegation.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Entity who made the delegation on behalf of the owner. If present, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Request to pledge more tokens (by the node operator) towards its node.", + "type": "object", + "required": [ + "pledge_more" + ], + "properties": { + "pledge_more": { + "type": "object", + "required": [ + "amount", + "mix_id" + ], + "properties": { + "amount": { + "description": "The amount of additional tokens to use by the pledge.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "mix_id": { + "description": "The id of the mixnode that will have its pledge updated.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Request to decrease amount of pledged tokens (by the node operator) from its node.", + "type": "object", + "required": [ + "decrease_pledge" + ], + "properties": { + "decrease_pledge": { + "type": "object", + "required": [ + "decrease_by", + "mix_id" + ], + "properties": { + "decrease_by": { + "description": "The amount of tokens that should be removed from the pledge.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "mix_id": { + "description": "The id of the mixnode that will have its pledge updated.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Request to unbond a mixnode and completely remove it from the network.", + "type": "object", + "required": [ + "unbond_mixnode" + ], + "properties": { + "unbond_mixnode": { + "type": "object", + "required": [ + "mix_id" + ], + "properties": { + "mix_id": { + "description": "The id of the mixnode that will get unbonded.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Request to update the current size of the active set.", + "type": "object", + "required": [ + "update_active_set_size" + ], + "properties": { + "update_active_set_size": { + "type": "object", + "required": [ + "new_size" + ], + "properties": { + "new_size": { + "description": "The new desired size of the active set.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_pending_interval_event": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PendingIntervalEventResponse", + "type": "object", + "required": [ + "event_id" + ], + "properties": { + "event": { + "anyOf": [ + { + "$ref": "#/definitions/PendingIntervalEventData" + }, + { + "type": "null" + } + ] + }, + "event_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "IntervalRewardingParamsUpdate": { + "description": "Specification on how the rewarding params should be updated.", + "type": "object", + "properties": { + "active_set_work_factor": { + "description": "Defines the new value of the active set work factor.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "interval_pool_emission": { + "description": "Defines the new value of the interval pool emission rate.", + "anyOf": [ + { + "$ref": "#/definitions/Percent" + }, + { + "type": "null" + } + ] + }, + "reward_pool": { + "description": "Defines the new value of the reward pool.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "rewarded_set_size": { + "description": "Defines the new size of the rewarded set.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "staking_supply": { + "description": "Defines the new value of the staking supply.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "staking_supply_scale_factor": { + "description": "Defines the new value of the staking supply scale factor.", + "anyOf": [ + { + "$ref": "#/definitions/Percent" + }, + { + "type": "null" + } + ] + }, + "sybil_resistance_percent": { + "description": "Defines the new value of the sybil resistance percent.", + "anyOf": [ + { + "$ref": "#/definitions/Percent" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeCostParams": { + "description": "The cost parameters, or the cost function, defined for the particular mixnode that influences how the rewards should be split between the node operator and its delegators.", + "type": "object", + "required": [ + "interval_operating_cost", + "profit_margin_percent" + ], + "properties": { + "interval_operating_cost": { + "description": "Operating cost of the associated mixnode per the entire interval.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "profit_margin_percent": { + "description": "The profit margin of the associated mixnode, i.e. the desired percent of the reward to be distributed to the operator.", + "allOf": [ + { + "$ref": "#/definitions/Percent" + } + ] + } + }, + "additionalProperties": false + }, + "PendingIntervalEventData": { + "description": "Details of a particular pending interval event.", + "type": "object", + "required": [ + "created_at", + "kind" + ], + "properties": { + "created_at": { + "description": "The block height at which the request has been made.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "kind": { + "description": "The underlying event data, containing its concrete type and information on how it should get resolved.", + "allOf": [ + { + "$ref": "#/definitions/PendingIntervalEventKind" + } + ] + } + }, + "additionalProperties": false + }, + "PendingIntervalEventKind": { + "description": "Enum encompassing all possible interval events.", + "oneOf": [ + { + "description": "Request to update cost parameters of given mixnode.", + "type": "object", + "required": [ + "change_mix_cost_params" + ], + "properties": { + "change_mix_cost_params": { + "type": "object", + "required": [ + "mix_id", + "new_costs" + ], + "properties": { + "mix_id": { + "description": "The id of the mixnode that will have its cost parameters updated.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "new_costs": { + "description": "The new updated cost function of this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeCostParams" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Request to update the underlying rewarding parameters used by the system", + "type": "object", + "required": [ + "update_rewarding_params" + ], + "properties": { + "update_rewarding_params": { + "type": "object", + "required": [ + "update" + ], + "properties": { + "update": { + "description": "The detailed specification of the update.", + "allOf": [ + { + "$ref": "#/definitions/IntervalRewardingParamsUpdate" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Request to change the next interval configuration.", + "type": "object", + "required": [ + "update_interval_config" + ], + "properties": { + "update_interval_config": { + "type": "object", + "required": [ + "epoch_duration_secs", + "epochs_in_interval" + ], + "properties": { + "epoch_duration_secs": { + "description": "The new epoch duration.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "epochs_in_interval": { + "description": "The new number of epochs in intervals.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Percent": { + "description": "Percent represents a value between 0 and 100% (i.e. between 0.0 and 1.0)", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_pending_interval_events": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PendingIntervalEventsResponse", + "description": "Response containing all currently pending interval events that will be resolved once the current interval finishes.", + "type": "object", + "required": [ + "events", + "seconds_until_executable" + ], + "properties": { + "events": { + "description": "The currently pending events.", + "type": "array", + "items": { + "$ref": "#/definitions/PendingIntervalEvent" + } + }, + "seconds_until_executable": { + "description": "Amount of seconds until the events would be eligible to be resolved. It's equivalent to the time until the current interval finishes.", + "type": "integer", + "format": "int64" + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "IntervalRewardingParamsUpdate": { + "description": "Specification on how the rewarding params should be updated.", + "type": "object", + "properties": { + "active_set_work_factor": { + "description": "Defines the new value of the active set work factor.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "interval_pool_emission": { + "description": "Defines the new value of the interval pool emission rate.", + "anyOf": [ + { + "$ref": "#/definitions/Percent" + }, + { + "type": "null" + } + ] + }, + "reward_pool": { + "description": "Defines the new value of the reward pool.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "rewarded_set_size": { + "description": "Defines the new size of the rewarded set.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "staking_supply": { + "description": "Defines the new value of the staking supply.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "staking_supply_scale_factor": { + "description": "Defines the new value of the staking supply scale factor.", + "anyOf": [ + { + "$ref": "#/definitions/Percent" + }, + { + "type": "null" + } + ] + }, + "sybil_resistance_percent": { + "description": "Defines the new value of the sybil resistance percent.", + "anyOf": [ + { + "$ref": "#/definitions/Percent" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeCostParams": { + "description": "The cost parameters, or the cost function, defined for the particular mixnode that influences how the rewards should be split between the node operator and its delegators.", + "type": "object", + "required": [ + "interval_operating_cost", + "profit_margin_percent" + ], + "properties": { + "interval_operating_cost": { + "description": "Operating cost of the associated mixnode per the entire interval.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "profit_margin_percent": { + "description": "The profit margin of the associated mixnode, i.e. the desired percent of the reward to be distributed to the operator.", + "allOf": [ + { + "$ref": "#/definitions/Percent" + } + ] + } + }, + "additionalProperties": false + }, + "PendingIntervalEvent": { + "description": "A request made at some point in the current interval that's going to get resolved once the interval rolls over.", + "type": "object", + "required": [ + "event", + "id" + ], + "properties": { + "event": { + "description": "The underlying event details, containing its type and information on how it should get resolved.", + "allOf": [ + { + "$ref": "#/definitions/PendingIntervalEventData" + } + ] + }, + "id": { + "description": "The unique id associated with the event.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "PendingIntervalEventData": { + "description": "Details of a particular pending interval event.", + "type": "object", + "required": [ + "created_at", + "kind" + ], + "properties": { + "created_at": { + "description": "The block height at which the request has been made.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "kind": { + "description": "The underlying event data, containing its concrete type and information on how it should get resolved.", + "allOf": [ + { + "$ref": "#/definitions/PendingIntervalEventKind" + } + ] + } + }, + "additionalProperties": false + }, + "PendingIntervalEventKind": { + "description": "Enum encompassing all possible interval events.", + "oneOf": [ + { + "description": "Request to update cost parameters of given mixnode.", + "type": "object", + "required": [ + "change_mix_cost_params" + ], + "properties": { + "change_mix_cost_params": { + "type": "object", + "required": [ + "mix_id", + "new_costs" + ], + "properties": { + "mix_id": { + "description": "The id of the mixnode that will have its cost parameters updated.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "new_costs": { + "description": "The new updated cost function of this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeCostParams" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Request to update the underlying rewarding parameters used by the system", + "type": "object", + "required": [ + "update_rewarding_params" + ], + "properties": { + "update_rewarding_params": { + "type": "object", + "required": [ + "update" + ], + "properties": { + "update": { + "description": "The detailed specification of the update.", + "allOf": [ + { + "$ref": "#/definitions/IntervalRewardingParamsUpdate" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Request to change the next interval configuration.", + "type": "object", + "required": [ + "update_interval_config" + ], + "properties": { + "update_interval_config": { + "type": "object", + "required": [ + "epoch_duration_secs", + "epochs_in_interval" + ], + "properties": { + "epoch_duration_secs": { + "description": "The new epoch duration.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "epochs_in_interval": { + "description": "The new number of epochs in intervals.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Percent": { + "description": "Percent represents a value between 0 and 100% (i.e. between 0.0 and 1.0)", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_pending_mix_node_operator_reward": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PendingRewardResponse", + "description": "Response containing information about accrued rewards.", + "type": "object", + "required": [ + "mixnode_still_fully_bonded" + ], + "properties": { + "amount_earned": { + "description": "The amount of tokens that could be claimed.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + }, + "amount_earned_detailed": { + "description": "The full pending rewards. Note that it's nearly identical to `amount_earned`, however, it contains few additional decimal points for more accurate reward calculation.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "amount_staked": { + "description": "The amount of tokens initially staked.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + }, + "mixnode_still_fully_bonded": { + "description": "The associated mixnode is still fully bonded, meaning it is neither unbonded nor in the process of unbonding that would have finished at the epoch transition.", + "type": "boolean" + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_pending_operator_reward": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PendingRewardResponse", + "description": "Response containing information about accrued rewards.", + "type": "object", + "required": [ + "mixnode_still_fully_bonded" + ], + "properties": { + "amount_earned": { + "description": "The amount of tokens that could be claimed.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + }, + "amount_earned_detailed": { + "description": "The full pending rewards. Note that it's nearly identical to `amount_earned`, however, it contains few additional decimal points for more accurate reward calculation.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "amount_staked": { + "description": "The amount of tokens initially staked.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + }, + "mixnode_still_fully_bonded": { + "description": "The associated mixnode is still fully bonded, meaning it is neither unbonded nor in the process of unbonding that would have finished at the epoch transition.", + "type": "boolean" + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_rewarded_set": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedRewardedSetResponse", + "description": "Response containing paged list of all mixnodes in the rewarded set.", + "type": "object", + "required": [ + "nodes" + ], + "properties": { + "nodes": { + "description": "Nodes in the current rewarded set.", + "type": "array", + "items": { + "type": "array", + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "$ref": "#/definitions/RewardedSetNodeStatus" + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "RewardedSetNodeStatus": { + "description": "Current state of given node in the rewarded set.", + "oneOf": [ + { + "description": "Node that is currently active, i.e. is expected to be used by clients for mixing packets.", + "type": "string", + "enum": [ + "active" + ] + }, + { + "description": "Node that is currently in standby, i.e. it's present in the rewarded set but is not active.", + "type": "string", + "enum": [ + "standby" + ] + } + ] + } + } + }, + "get_rewarding_params": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "RewardingParams", + "description": "Parameters used for reward calculation.", + "type": "object", + "required": [ + "active_set_size", + "interval", + "rewarded_set_size" + ], + "properties": { + "active_set_size": { + "description": "The expected number of mixnodes in the active set.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "interval": { + "description": "Parameters that should remain unchanged throughout an interval.", + "allOf": [ + { + "$ref": "#/definitions/IntervalRewardParams" + } + ] + }, + "rewarded_set_size": { + "description": "The expected number of mixnodes in the rewarded set (i.e. active + standby).", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "IntervalRewardParams": { + "description": "Parameters required by the mix-mining reward distribution that do not change during an interval.", + "type": "object", + "required": [ + "active_set_work_factor", + "epoch_reward_budget", + "interval_pool_emission", + "reward_pool", + "stake_saturation_point", + "staking_supply", + "staking_supply_scale_factor", + "sybil_resistance" + ], + "properties": { + "active_set_work_factor": { + "description": "Current active set work factor. It is not really expected to be changing very often. As a matter of fact, unless there's a very specific reason, it should remain constant.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "epoch_reward_budget": { + "description": "Current value of the computed reward budget per epoch, per node. It is expected to be constant throughout the interval.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "interval_pool_emission": { + "description": "Current maximum interval pool emission. Assuming all nodes in the rewarded set are fully saturated and have 100% performance, this % of the reward pool would get distributed in rewards to all operators and its delegators. It is not really expected to be changing very often. As a matter of fact, unless there's a very specific reason, it should remain constant.", + "allOf": [ + { + "$ref": "#/definitions/Percent" + } + ] + }, + "reward_pool": { + "description": "Current value of the rewarding pool. It is expected to be constant throughout the interval.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "stake_saturation_point": { + "description": "Current value of the stake saturation point. It is expected to be constant throughout the interval.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "staking_supply": { + "description": "Current value of the staking supply. It is expected to be constant throughout the interval.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "staking_supply_scale_factor": { + "description": "Defines the percentage of stake needed to reach saturation for all of the nodes in the rewarded set. Also known as `beta`.", + "allOf": [ + { + "$ref": "#/definitions/Percent" + } + ] + }, + "sybil_resistance": { + "description": "Current value of the sybil resistance percent (`alpha`). It is not really expected to be changing very often. As a matter of fact, unless there's a very specific reason, it should remain constant.", + "allOf": [ + { + "$ref": "#/definitions/Percent" + } + ] + } + }, + "additionalProperties": false + }, + "Percent": { + "description": "Percent represents a value between 0 and 100% (i.e. between 0.0 and 1.0)", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + } + } + }, + "get_rewarding_validator_address": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "String", + "type": "string" + }, + "get_signing_nonce": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "uint32", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "get_stake_saturation": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "StakeSaturationResponse", + "description": "Response containing the current state of the stake saturation of a mixnode with the provided id.", + "type": "object", + "required": [ + "mix_id" + ], + "properties": { + "current_saturation": { + "description": "The current stake saturation of this node that is indirectly used in reward calculation formulas. Note that it can't be larger than 1.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "mix_id": { + "description": "Id of the requested mixnode.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "uncapped_saturation": { + "description": "The current, absolute, stake saturation of this node. Note that as the name suggests it can be larger than 1. However, anything beyond that value has no effect on the total node reward.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + } + } + }, + "get_state": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ContractState", + "description": "The current state of the mixnet contract.", + "type": "object", + "required": [ + "owner", + "params", + "rewarding_denom", + "rewarding_validator_address", + "vesting_contract_address" + ], + "properties": { + "owner": { + "description": "Address of the contract owner.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "params": { + "description": "Contract parameters that could be adjusted in a transaction the contract admin.", + "allOf": [ + { + "$ref": "#/definitions/ContractStateParams" + } + ] + }, + "rewarding_denom": { + "description": "The expected denom used for rewarding (and realistically any other operation). Default: `unym`", + "type": "string" + }, + "rewarding_validator_address": { + "description": "Address of \"rewarding validator\" (nym-api) that's allowed to send any rewarding-related transactions.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "vesting_contract_address": { + "description": "Address of the vesting contract to which the mixnet contract would be sending all track-related messages.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "ContractStateParams": { + "description": "Contract parameters that could be adjusted in a transaction by the contract admin.", + "type": "object", + "required": [ + "minimum_gateway_pledge", + "minimum_mixnode_pledge" + ], + "properties": { + "minimum_gateway_pledge": { + "description": "Minimum amount a gateway must pledge to get into the system.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "minimum_mixnode_delegation": { + "description": "Minimum amount a delegator must stake in orders for his delegation to get accepted.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + }, + "minimum_mixnode_pledge": { + "description": "Minimum amount a mixnode must pledge to get into the system.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_state_params": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ContractStateParams", + "description": "Contract parameters that could be adjusted in a transaction by the contract admin.", + "type": "object", + "required": [ + "minimum_gateway_pledge", + "minimum_mixnode_pledge" + ], + "properties": { + "minimum_gateway_pledge": { + "description": "Minimum amount a gateway must pledge to get into the system.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "minimum_mixnode_delegation": { + "description": "Minimum amount a delegator must stake in orders for his delegation to get accepted.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + }, + "minimum_mixnode_pledge": { + "description": "Minimum amount a mixnode must pledge to get into the system.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_unbonded_mix_node_information": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "UnbondedMixnodeResponse", + "description": "Response containing basic information of an unbonded mixnode with the provided id.", + "type": "object", + "required": [ + "mix_id" + ], + "properties": { + "mix_id": { + "description": "Id of the requested mixnode.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "unbonded_info": { + "description": "If there existed a mixnode with the provided id, this field contains its basic information.", + "anyOf": [ + { + "$ref": "#/definitions/UnbondedMixnode" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "UnbondedMixnode": { + "description": "Basic information of a node that used to be part of the mix network but has already unbonded.", + "type": "object", + "required": [ + "identity_key", + "owner", + "unbonding_height" + ], + "properties": { + "identity_key": { + "description": "Base58-encoded ed25519 EdDSA public key.", + "type": "string" + }, + "owner": { + "description": "Address of the owner of this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Entity who bonded this mixnode on behalf of the owner. If exists, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + }, + "unbonding_height": { + "description": "Block height at which this mixnode has unbonded.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } + }, + "get_unbonded_mix_nodes": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedUnbondedMixnodesResponse", + "description": "Response containing paged list of all mixnodes that have ever unbonded.", + "type": "object", + "required": [ + "nodes", + "per_page" + ], + "properties": { + "nodes": { + "description": "The past ids of unbonded mixnodes alongside their basic information such as the owner or the identity key.", + "type": "array", + "items": { + "type": "array", + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "$ref": "#/definitions/UnbondedMixnode" + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "per_page": { + "description": "Maximum number of entries that could be included in a response. `per_page <= nodes.len()`", + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "UnbondedMixnode": { + "description": "Basic information of a node that used to be part of the mix network but has already unbonded.", + "type": "object", + "required": [ + "identity_key", + "owner", + "unbonding_height" + ], + "properties": { + "identity_key": { + "description": "Base58-encoded ed25519 EdDSA public key.", + "type": "string" + }, + "owner": { + "description": "Address of the owner of this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Entity who bonded this mixnode on behalf of the owner. If exists, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + }, + "unbonding_height": { + "description": "Block height at which this mixnode has unbonded.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } + }, + "get_unbonded_mix_nodes_by_identity_key": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedUnbondedMixnodesResponse", + "description": "Response containing paged list of all mixnodes that have ever unbonded.", + "type": "object", + "required": [ + "nodes", + "per_page" + ], + "properties": { + "nodes": { + "description": "The past ids of unbonded mixnodes alongside their basic information such as the owner or the identity key.", + "type": "array", + "items": { + "type": "array", + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "$ref": "#/definitions/UnbondedMixnode" + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "per_page": { + "description": "Maximum number of entries that could be included in a response. `per_page <= nodes.len()`", + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "UnbondedMixnode": { + "description": "Basic information of a node that used to be part of the mix network but has already unbonded.", + "type": "object", + "required": [ + "identity_key", + "owner", + "unbonding_height" + ], + "properties": { + "identity_key": { + "description": "Base58-encoded ed25519 EdDSA public key.", + "type": "string" + }, + "owner": { + "description": "Address of the owner of this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Entity who bonded this mixnode on behalf of the owner. If exists, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + }, + "unbonding_height": { + "description": "Block height at which this mixnode has unbonded.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } + }, + "get_unbonded_mix_nodes_by_owner": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedUnbondedMixnodesResponse", + "description": "Response containing paged list of all mixnodes that have ever unbonded.", + "type": "object", + "required": [ + "nodes", + "per_page" + ], + "properties": { + "nodes": { + "description": "The past ids of unbonded mixnodes alongside their basic information such as the owner or the identity key.", + "type": "array", + "items": { + "type": "array", + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "$ref": "#/definitions/UnbondedMixnode" + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "per_page": { + "description": "Maximum number of entries that could be included in a response. `per_page <= nodes.len()`", + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "UnbondedMixnode": { + "description": "Basic information of a node that used to be part of the mix network but has already unbonded.", + "type": "object", + "required": [ + "identity_key", + "owner", + "unbonding_height" + ], + "properties": { + "identity_key": { + "description": "Base58-encoded ed25519 EdDSA public key.", + "type": "string" + }, + "owner": { + "description": "Address of the owner of this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Entity who bonded this mixnode on behalf of the owner. If exists, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + }, + "unbonding_height": { + "description": "Block height at which this mixnode has unbonded.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } + } + } +} diff --git a/contracts/mixnet/schema/execute_msg.json b/contracts/mixnet/schema/raw/execute.json similarity index 73% rename from contracts/mixnet/schema/execute_msg.json rename to contracts/mixnet/schema/raw/execute.json index b50d74a447..c4f1817fc9 100644 --- a/contracts/mixnet/schema/execute_msg.json +++ b/contracts/mixnet/schema/raw/execute.json @@ -23,7 +23,8 @@ "format": "uint32", "minimum": 0.0 } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -38,17 +39,14 @@ "create_family": { "type": "object", "required": [ - "label", - "owner_signature" + "label" ], "properties": { "label": { "type": "string" - }, - "owner_signature": { - "type": "string" } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -64,16 +62,17 @@ "type": "object", "required": [ "family_head", - "signature" + "join_permit" ], "properties": { "family_head": { - "type": "string" + "$ref": "#/definitions/FamilyHead" }, - "signature": { - "type": "string" + "join_permit": { + "$ref": "#/definitions/MessageSignature" } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -87,17 +86,14 @@ "leave_family": { "type": "object", "required": [ - "family_head", - "signature" + "family_head" ], "properties": { "family_head": { - "type": "string" - }, - "signature": { - "type": "string" + "$ref": "#/definitions/FamilyHead" } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -111,17 +107,14 @@ "kick_family_member": { "type": "object", "required": [ - "member", - "signature" + "member" ], "properties": { "member": { "type": "string" - }, - "signature": { - "type": "string" } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -136,8 +129,7 @@ "type": "object", "required": [ "label", - "owner_address", - "owner_signature" + "owner_address" ], "properties": { "label": { @@ -145,17 +137,15 @@ }, "owner_address": { "type": "string" - }, - "owner_signature": { - "type": "string" } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { - "description": "Family head needs to sign the joining node IdentityKey", + "description": "Family head needs to sign the joining node IdentityKey, MixNode needs to provide its signature proving that it wants to join the family", "type": "object", "required": [ "join_family_on_behalf" @@ -165,20 +155,21 @@ "type": "object", "required": [ "family_head", - "member_address", - "signature" + "join_permit", + "member_address" ], "properties": { "family_head": { - "type": "string" + "$ref": "#/definitions/FamilyHead" + }, + "join_permit": { + "$ref": "#/definitions/MessageSignature" }, "member_address": { "type": "string" - }, - "signature": { - "type": "string" } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -193,20 +184,17 @@ "type": "object", "required": [ "family_head", - "member_address", - "signature" + "member_address" ], "properties": { "family_head": { - "type": "string" + "$ref": "#/definitions/FamilyHead" }, "member_address": { "type": "string" - }, - "signature": { - "type": "string" } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -221,8 +209,7 @@ "type": "object", "required": [ "head_address", - "member", - "signature" + "member" ], "properties": { "head_address": { @@ -230,11 +217,9 @@ }, "member": { "type": "string" - }, - "signature": { - "type": "string" } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -254,7 +239,8 @@ "address": { "type": "string" } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -274,7 +260,8 @@ "updated_parameters": { "$ref": "#/definitions/ContractStateParams" } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -300,7 +287,8 @@ "force_immediately": { "type": "boolean" } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -324,7 +312,8 @@ "updated_params": { "$ref": "#/definitions/IntervalRewardingParamsUpdate" } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -356,7 +345,21 @@ "force_immediately": { "type": "boolean" } - } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "begin_epoch_transition" + ], + "properties": { + "begin_epoch_transition": { + "type": "object", + "additionalProperties": false } }, "additionalProperties": false @@ -385,7 +388,8 @@ "$ref": "#/definitions/LayerAssignment" } } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -407,7 +411,8 @@ "format": "uint32", "minimum": 0.0 } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -433,9 +438,10 @@ "$ref": "#/definitions/MixNode" }, "owner_signature": { - "type": "string" + "$ref": "#/definitions/MessageSignature" } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -465,9 +471,10 @@ "type": "string" }, "owner_signature": { - "type": "string" + "$ref": "#/definitions/MessageSignature" } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -479,7 +486,8 @@ ], "properties": { "pledge_more": { - "type": "object" + "type": "object", + "additionalProperties": false } }, "additionalProperties": false @@ -499,7 +507,54 @@ "owner": { "type": "string" } - } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "decrease_pledge" + ], + "properties": { + "decrease_pledge": { + "type": "object", + "required": [ + "decrease_by" + ], + "properties": { + "decrease_by": { + "$ref": "#/definitions/Coin" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "decrease_pledge_on_behalf" + ], + "properties": { + "decrease_pledge_on_behalf": { + "type": "object", + "required": [ + "decrease_by", + "owner" + ], + "properties": { + "decrease_by": { + "$ref": "#/definitions/Coin" + }, + "owner": { + "type": "string" + } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -511,7 +566,8 @@ ], "properties": { "unbond_mixnode": { - "type": "object" + "type": "object", + "additionalProperties": false } }, "additionalProperties": false @@ -531,7 +587,8 @@ "owner": { "type": "string" } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -551,7 +608,8 @@ "new_costs": { "$ref": "#/definitions/MixNodeCostParams" } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -575,7 +633,8 @@ "owner": { "type": "string" } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -595,7 +654,8 @@ "new_config": { "$ref": "#/definitions/MixNodeConfigUpdate" } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -619,7 +679,8 @@ "owner": { "type": "string" } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -641,9 +702,10 @@ "$ref": "#/definitions/Gateway" }, "owner_signature": { - "type": "string" + "$ref": "#/definitions/MessageSignature" } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -669,9 +731,10 @@ "type": "string" }, "owner_signature": { - "type": "string" + "$ref": "#/definitions/MessageSignature" } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -683,7 +746,8 @@ ], "properties": { "unbond_gateway": { - "type": "object" + "type": "object", + "additionalProperties": false } }, "additionalProperties": false @@ -703,7 +767,54 @@ "owner": { "type": "string" } - } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_gateway_config" + ], + "properties": { + "update_gateway_config": { + "type": "object", + "required": [ + "new_config" + ], + "properties": { + "new_config": { + "$ref": "#/definitions/GatewayConfigUpdate" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_gateway_config_on_behalf" + ], + "properties": { + "update_gateway_config_on_behalf": { + "type": "object", + "required": [ + "new_config", + "owner" + ], + "properties": { + "new_config": { + "$ref": "#/definitions/GatewayConfigUpdate" + }, + "owner": { + "type": "string" + } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -725,7 +836,8 @@ "format": "uint32", "minimum": 0.0 } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -751,7 +863,8 @@ "format": "uint32", "minimum": 0.0 } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -773,7 +886,8 @@ "format": "uint32", "minimum": 0.0 } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -799,7 +913,8 @@ "format": "uint32", "minimum": 0.0 } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -825,7 +940,8 @@ "performance": { "$ref": "#/definitions/Percent" } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -837,7 +953,8 @@ ], "properties": { "withdraw_operator_reward": { - "type": "object" + "type": "object", + "additionalProperties": false } }, "additionalProperties": false @@ -857,7 +974,8 @@ "owner": { "type": "string" } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -879,7 +997,8 @@ "format": "uint32", "minimum": 0.0 } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -905,7 +1024,8 @@ "owner": { "type": "string" } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -928,6 +1048,7 @@ } }, "ContractStateParams": { + "description": "Contract parameters that could be adjusted in a transaction by the contract admin.", "type": "object", "required": [ "minimum_gateway_pledge", @@ -961,13 +1082,19 @@ } ] } - } + }, + "additionalProperties": false }, "Decimal": { "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", "type": "string" }, + "FamilyHead": { + "description": "Head of particular family as identified by its identity key (i.e. public component of its ed25519 keypair stringified into base58).", + "type": "string" + }, "Gateway": { + "description": "Information provided by the node operator during bonding that are used to allow other entities to use the services of this node.", "type": "object", "required": [ "clients_port", @@ -980,17 +1107,58 @@ ], "properties": { "clients_port": { + "description": "Port used by this gateway for listening for client requests.", "type": "integer", "format": "uint16", "minimum": 0.0 }, "host": { + "description": "Network address of this gateway, for example 1.1.1.1 or foo.gateway.com", "type": "string" }, "identity_key": { "description": "Base58 encoded ed25519 EdDSA public key of the gateway used to derive shared keys with clients", "type": "string" }, + "location": { + "description": "The physical, self-reported, location of this gateway.", + "type": "string" + }, + "mix_port": { + "description": "Port used by this gateway for listening for mix packets.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "sphinx_key": { + "description": "Base58-encoded x25519 public key used for sphinx key derivation.", + "type": "string" + }, + "version": { + "description": "The self-reported semver version of this gateway.", + "type": "string" + } + }, + "additionalProperties": false + }, + "GatewayConfigUpdate": { + "type": "object", + "required": [ + "clients_port", + "host", + "location", + "mix_port", + "version" + ], + "properties": { + "clients_port": { + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "host": { + "type": "string" + }, "location": { "type": "string" }, @@ -999,18 +1167,18 @@ "format": "uint16", "minimum": 0.0 }, - "sphinx_key": { - "type": "string" - }, "version": { "type": "string" } - } + }, + "additionalProperties": false }, "IntervalRewardingParamsUpdate": { + "description": "Specification on how the rewarding params should be updated.", "type": "object", "properties": { "active_set_work_factor": { + "description": "Defines the new value of the active set work factor.", "anyOf": [ { "$ref": "#/definitions/Decimal" @@ -1021,6 +1189,7 @@ ] }, "interval_pool_emission": { + "description": "Defines the new value of the interval pool emission rate.", "anyOf": [ { "$ref": "#/definitions/Percent" @@ -1031,6 +1200,7 @@ ] }, "reward_pool": { + "description": "Defines the new value of the reward pool.", "anyOf": [ { "$ref": "#/definitions/Decimal" @@ -1041,6 +1211,7 @@ ] }, "rewarded_set_size": { + "description": "Defines the new size of the rewarded set.", "type": [ "integer", "null" @@ -1049,6 +1220,7 @@ "minimum": 0.0 }, "staking_supply": { + "description": "Defines the new value of the staking supply.", "anyOf": [ { "$ref": "#/definitions/Decimal" @@ -1059,6 +1231,7 @@ ] }, "staking_supply_scale_factor": { + "description": "Defines the new value of the staking supply scale factor.", "anyOf": [ { "$ref": "#/definitions/Percent" @@ -1069,6 +1242,7 @@ ] }, "sybil_resistance_percent": { + "description": "Defines the new value of the sybil resistance percent.", "anyOf": [ { "$ref": "#/definitions/Percent" @@ -1078,7 +1252,8 @@ } ] } - } + }, + "additionalProperties": false }, "Layer": { "type": "string", @@ -1089,6 +1264,7 @@ ] }, "LayerAssignment": { + "description": "Specifies layer assignment for the given mixnode.", "type": "object", "required": [ "layer", @@ -1096,16 +1272,32 @@ ], "properties": { "layer": { - "$ref": "#/definitions/Layer" + "description": "The layer to which it's going to be assigned", + "allOf": [ + { + "$ref": "#/definitions/Layer" + } + ] }, "mix_id": { + "description": "The id of the mixnode.", "type": "integer", "format": "uint32", "minimum": 0.0 } + }, + "additionalProperties": false + }, + "MessageSignature": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 } }, "MixNode": { + "description": "Information provided by the node operator during bonding that are used to allow other entities to use the services of this node.", "type": "object", "required": [ "host", @@ -1118,10 +1310,11 @@ ], "properties": { "host": { - "description": "Network address of this mixnode, for example 1.1.1.1:1234 or foo.mixnode.com", + "description": "Network address of this mixnode, for example 1.1.1.1 or foo.mixnode.com", "type": "string" }, "http_api_port": { + "description": "Port used by this mixnode for its http(s) API", "type": "integer", "format": "uint16", "minimum": 0.0 @@ -1131,6 +1324,7 @@ "type": "string" }, "mix_port": { + "description": "Port used by this mixnode for listening for mix packets.", "type": "integer", "format": "uint16", "minimum": 0.0 @@ -1140,14 +1334,17 @@ "type": "string" }, "verloc_port": { + "description": "Port used by this mixnode for listening for verloc requests.", "type": "integer", "format": "uint16", "minimum": 0.0 }, "version": { + "description": "The self-reported semver version of this mixnode.", "type": "string" } - } + }, + "additionalProperties": false }, "MixNodeConfigUpdate": { "type": "object", @@ -1180,9 +1377,11 @@ "version": { "type": "string" } - } + }, + "additionalProperties": false }, "MixNodeCostParams": { + "description": "The cost parameters, or the cost function, defined for the particular mixnode that influences how the rewards should be split between the node operator and its delegators.", "type": "object", "required": [ "interval_operating_cost", @@ -1198,9 +1397,15 @@ ] }, "profit_margin_percent": { - "$ref": "#/definitions/Percent" + "description": "The profit margin of the associated mixnode, i.e. the desired percent of the reward to be distributed to the operator.", + "allOf": [ + { + "$ref": "#/definitions/Percent" + } + ] } - } + }, + "additionalProperties": false }, "Percent": { "description": "Percent represents a value between 0 and 100% (i.e. between 0.0 and 1.0)", diff --git a/contracts/mixnet/schema/instantiate_msg.json b/contracts/mixnet/schema/raw/instantiate.json similarity index 97% rename from contracts/mixnet/schema/instantiate_msg.json rename to contracts/mixnet/schema/raw/instantiate.json index 6d7c0ea33a..60cf202f08 100644 --- a/contracts/mixnet/schema/instantiate_msg.json +++ b/contracts/mixnet/schema/raw/instantiate.json @@ -32,6 +32,7 @@ "type": "string" } }, + "additionalProperties": false, "definitions": { "Decimal": { "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", @@ -97,7 +98,8 @@ "sybil_resistance": { "$ref": "#/definitions/Percent" } - } + }, + "additionalProperties": false }, "Percent": { "description": "Percent represents a value between 0 and 100% (i.e. between 0.0 and 1.0)", diff --git a/contracts/mixnet/schema/migrate_msg.json b/contracts/mixnet/schema/raw/migrate.json similarity index 85% rename from contracts/mixnet/schema/migrate_msg.json rename to contracts/mixnet/schema/raw/migrate.json index d1975efa64..e9962aaf92 100644 --- a/contracts/mixnet/schema/migrate_msg.json +++ b/contracts/mixnet/schema/raw/migrate.json @@ -9,5 +9,6 @@ "null" ] } - } + }, + "additionalProperties": false } diff --git a/contracts/mixnet/schema/query_msg.json b/contracts/mixnet/schema/raw/query.json similarity index 56% rename from contracts/mixnet/schema/query_msg.json rename to contracts/mixnet/schema/raw/query.json index a8dde27e0a..f4738a91fe 100644 --- a/contracts/mixnet/schema/query_msg.json +++ b/contracts/mixnet/schema/raw/query.json @@ -3,6 +3,7 @@ "title": "QueryMsg", "oneOf": [ { + "description": "Gets the list of families registered in this contract.", "type": "object", "required": [ "get_all_families_paged" @@ -12,6 +13,7 @@ "type": "object", "properties": { "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", "type": [ "integer", "null" @@ -20,17 +22,20 @@ "minimum": 0.0 }, "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", "type": [ "string", "null" ] } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets the list of all family members registered in this contract.", "type": "object", "required": [ "get_all_members_paged" @@ -40,6 +45,7 @@ "type": "object", "properties": { "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", "type": [ "integer", "null" @@ -48,17 +54,20 @@ "minimum": 0.0 }, "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", "type": [ "string", "null" ] } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Attempts to lookup family information given the family head.", "type": "object", "required": [ "get_family_by_head" @@ -73,12 +82,14 @@ "head": { "type": "string" } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Attempts to lookup family information given the family label.", "type": "object", "required": [ "get_family_by_label" @@ -93,12 +104,14 @@ "label": { "type": "string" } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Attempts to retrieve family members given the family head.", "type": "object", "required": [ "get_family_members_by_head" @@ -113,12 +126,14 @@ "head": { "type": "string" } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Attempts to retrieve family members given the family label.", "type": "object", "required": [ "get_family_members_by_label" @@ -133,84 +148,126 @@ "label": { "type": "string" } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets build information of this contract, such as the commit hash used for the build or rustc version.", "type": "object", "required": [ "get_contract_version" ], "properties": { "get_contract_version": { - "type": "object" + "type": "object", + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets the stored contract version information that's required by the CW2 spec interface for migrations.", + "type": "object", + "required": [ + "get_cw2_contract_version" + ], + "properties": { + "get_cw2_contract_version": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the address of the validator that's allowed to send rewarding transactions and transition the epoch.", "type": "object", "required": [ "get_rewarding_validator_address" ], "properties": { "get_rewarding_validator_address": { - "type": "object" + "type": "object", + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets the contract parameters that could be adjusted in a transaction by the contract admin.", "type": "object", "required": [ "get_state_params" ], "properties": { "get_state_params": { - "type": "object" + "type": "object", + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets the current state of the contract.", "type": "object", "required": [ "get_state" ], "properties": { "get_state": { - "type": "object" + "type": "object", + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets the current parameters used for reward calculation.", "type": "object", "required": [ "get_rewarding_params" ], "properties": { "get_rewarding_params": { - "type": "object" + "type": "object", + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets the status of the current rewarding epoch.", + "type": "object", + "required": [ + "get_epoch_status" + ], + "properties": { + "get_epoch_status": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Get the details of the current rewarding interval.", "type": "object", "required": [ "get_current_interval_details" ], "properties": { "get_current_interval_details": { - "type": "object" + "type": "object", + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets the current list of mixnodes in the rewarded set.", "type": "object", "required": [ "get_rewarded_set" @@ -220,6 +277,7 @@ "type": "object", "properties": { "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", "type": [ "integer", "null" @@ -228,6 +286,7 @@ "minimum": 0.0 }, "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", "type": [ "integer", "null" @@ -235,12 +294,14 @@ "format": "uint32", "minimum": 0.0 } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets the basic list of all currently bonded mixnodes.", "type": "object", "required": [ "get_mix_node_bonds" @@ -250,6 +311,7 @@ "type": "object", "properties": { "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", "type": [ "integer", "null" @@ -258,6 +320,7 @@ "minimum": 0.0 }, "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", "type": [ "integer", "null" @@ -265,12 +328,14 @@ "format": "uint32", "minimum": 0.0 } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets the detailed list of all currently bonded mixnodes.", "type": "object", "required": [ "get_mix_nodes_detailed" @@ -280,6 +345,7 @@ "type": "object", "properties": { "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", "type": [ "integer", "null" @@ -288,6 +354,7 @@ "minimum": 0.0 }, "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", "type": [ "integer", "null" @@ -295,12 +362,14 @@ "format": "uint32", "minimum": 0.0 } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets the basic list of all unbonded mixnodes.", "type": "object", "required": [ "get_unbonded_mix_nodes" @@ -310,6 +379,7 @@ "type": "object", "properties": { "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", "type": [ "integer", "null" @@ -318,6 +388,7 @@ "minimum": 0.0 }, "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", "type": [ "integer", "null" @@ -325,12 +396,14 @@ "format": "uint32", "minimum": 0.0 } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets the basic list of all unbonded mixnodes that belonged to a particular owner.", "type": "object", "required": [ "get_unbonded_mix_nodes_by_owner" @@ -343,6 +416,7 @@ ], "properties": { "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", "type": [ "integer", "null" @@ -351,9 +425,11 @@ "minimum": 0.0 }, "owner": { + "description": "The address of the owner of the the mixnodes used for the query.", "type": "string" }, "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", "type": [ "integer", "null" @@ -361,12 +437,14 @@ "format": "uint32", "minimum": 0.0 } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets the basic list of all unbonded mixnodes that used the particular identity key.", "type": "object", "required": [ "get_unbonded_mix_nodes_by_identity_key" @@ -379,9 +457,11 @@ ], "properties": { "identity_key": { + "description": "The identity key (base58-encoded ed25519 public key) of the mixnode used for the query.", "type": "string" }, "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", "type": [ "integer", "null" @@ -390,6 +470,7 @@ "minimum": 0.0 }, "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", "type": [ "integer", "null" @@ -397,12 +478,14 @@ "format": "uint32", "minimum": 0.0 } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets the detailed mixnode information belonging to the particular owner.", "type": "object", "required": [ "get_owned_mixnode" @@ -415,14 +498,17 @@ ], "properties": { "address": { + "description": "Address of the mixnode owner to use for the query.", "type": "string" } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets the detailed mixnode information of a node with the provided id.", "type": "object", "required": [ "get_mixnode_details" @@ -435,16 +521,19 @@ ], "properties": { "mix_id": { + "description": "Id of the node to query.", "type": "integer", "format": "uint32", "minimum": 0.0 } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets the rewarding information of a mixnode with the provided id.", "type": "object", "required": [ "get_mixnode_rewarding_details" @@ -457,16 +546,19 @@ ], "properties": { "mix_id": { + "description": "Id of the node to query.", "type": "integer", "format": "uint32", "minimum": 0.0 } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets the stake saturation of a mixnode with the provided id.", "type": "object", "required": [ "get_stake_saturation" @@ -479,16 +571,19 @@ ], "properties": { "mix_id": { + "description": "Id of the node to query.", "type": "integer", "format": "uint32", "minimum": 0.0 } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets the basic information of an unbonded mixnode with the provided id.", "type": "object", "required": [ "get_unbonded_mix_node_information" @@ -501,16 +596,19 @@ ], "properties": { "mix_id": { + "description": "Id of the node to query.", "type": "integer", "format": "uint32", "minimum": 0.0 } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets the detailed mixnode information of a node given its current identity key.", "type": "object", "required": [ "get_bonded_mixnode_details_by_identity" @@ -523,26 +621,31 @@ ], "properties": { "mix_identity": { + "description": "The identity key (base58-encoded ed25519 public key) of the mixnode used for the query.", "type": "string" } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets the current layer configuration of the mix network.", "type": "object", "required": [ "get_layer_distribution" ], "properties": { "get_layer_distribution": { - "type": "object" + "type": "object", + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets the basic list of all currently bonded gateways.", "type": "object", "required": [ "get_gateways" @@ -552,6 +655,7 @@ "type": "object", "properties": { "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", "type": [ "integer", "null" @@ -560,17 +664,20 @@ "minimum": 0.0 }, "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", "type": [ "string", "null" ] } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets the gateway details of a node given its identity key.", "type": "object", "required": [ "get_gateway_bond" @@ -583,14 +690,17 @@ ], "properties": { "identity": { + "description": "The identity key (base58-encoded ed25519 public key) of the gateway used for the query.", "type": "string" } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets the detailed gateway information belonging to the particular owner.", "type": "object", "required": [ "get_owned_gateway" @@ -603,14 +713,17 @@ ], "properties": { "address": { + "description": "Address of the gateway owner to use for the query.", "type": "string" } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets all delegations associated with particular mixnode", "type": "object", "required": [ "get_mixnode_delegations" @@ -623,6 +736,7 @@ ], "properties": { "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", "type": [ "integer", "null" @@ -631,22 +745,26 @@ "minimum": 0.0 }, "mix_id": { + "description": "Id of the node to query.", "type": "integer", "format": "uint32", "minimum": 0.0 }, "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", "type": [ "string", "null" ] } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets all delegations associated with particular delegator", "type": "object", "required": [ "get_delegator_delegations" @@ -659,9 +777,11 @@ ], "properties": { "delegator": { + "description": "The address of the owner of the delegations.", "type": "string" }, "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", "type": [ "integer", "null" @@ -670,6 +790,7 @@ "minimum": 0.0 }, "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", "type": [ "array", "null" @@ -687,12 +808,14 @@ "maxItems": 2, "minItems": 2 } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets delegation information associated with particular mixnode - delegator pair", "type": "object", "required": [ "get_delegation_details" @@ -706,25 +829,30 @@ ], "properties": { "delegator": { + "description": "The address of the owner of the delegation.", "type": "string" }, "mix_id": { + "description": "Id of the node to query.", "type": "integer", "format": "uint32", "minimum": 0.0 }, "proxy": { + "description": "Entity who made the delegation on behalf of the owner. If present, it's most likely the address of the vesting contract.", "type": [ "string", "null" ] } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets all delegations in the system", "type": "object", "required": [ "get_all_delegations" @@ -734,6 +862,7 @@ "type": "object", "properties": { "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", "type": [ "integer", "null" @@ -742,6 +871,7 @@ "minimum": 0.0 }, "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", "type": [ "array", "null" @@ -759,12 +889,14 @@ "maxItems": 2, "minItems": 2 } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets the reward amount accrued by the node operator that has not yet been claimed.", "type": "object", "required": [ "get_pending_operator_reward" @@ -777,14 +909,17 @@ ], "properties": { "address": { + "description": "Address of the operator to use for the query.", "type": "string" } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets the reward amount accrued by the particular mixnode that has not yet been claimed.", "type": "object", "required": [ "get_pending_mix_node_operator_reward" @@ -797,16 +932,19 @@ ], "properties": { "mix_id": { + "description": "Id of the node to query.", "type": "integer", "format": "uint32", "minimum": 0.0 } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets the reward amount accrued by the particular delegator that has not yet been claimed.", "type": "object", "required": [ "get_pending_delegator_reward" @@ -820,25 +958,30 @@ ], "properties": { "address": { + "description": "Address of the delegator to use for the query.", "type": "string" }, "mix_id": { + "description": "Id of the node to query.", "type": "integer", "format": "uint32", "minimum": 0.0 }, "proxy": { + "description": "Entity who made the delegation on behalf of the owner. If present, it's most likely the address of the vesting contract.", "type": [ "string", "null" ] } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Given the provided node performance, attempt to estimate the operator reward for the current epoch.", "type": "object", "required": [ "get_estimated_current_epoch_operator_reward" @@ -852,19 +995,27 @@ ], "properties": { "estimated_performance": { - "$ref": "#/definitions/Percent" + "description": "The estimated performance for the current epoch of the given node.", + "allOf": [ + { + "$ref": "#/definitions/Percent" + } + ] }, "mix_id": { + "description": "Id of the node to query.", "type": "integer", "format": "uint32", "minimum": 0.0 } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Given the provided node performance, attempt to estimate the delegator reward for the current epoch.", "type": "object", "required": [ "get_estimated_current_epoch_delegator_reward" @@ -879,28 +1030,38 @@ ], "properties": { "address": { + "description": "Address of the delegator to use for the query.", "type": "string" }, "estimated_performance": { - "$ref": "#/definitions/Percent" + "description": "The estimated performance for the current epoch of the given node.", + "allOf": [ + { + "$ref": "#/definitions/Percent" + } + ] }, "mix_id": { + "description": "Id of the node to query.", "type": "integer", "format": "uint32", "minimum": 0.0 }, "proxy": { + "description": "Entity who made the delegation on behalf of the owner. If present, it's most likely the address of the vesting contract.", "type": [ "string", "null" ] } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets the list of all currently pending epoch events that will be resolved once the current epoch finishes.", "type": "object", "required": [ "get_pending_epoch_events" @@ -910,6 +1071,7 @@ "type": "object", "properties": { "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", "type": [ "integer", "null" @@ -918,6 +1080,7 @@ "minimum": 0.0 }, "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", "type": [ "integer", "null" @@ -925,12 +1088,14 @@ "format": "uint32", "minimum": 0.0 } - } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "Gets the list of all currently pending interval events that will be resolved once the current interval finishes.", "type": "object", "required": [ "get_pending_interval_events" @@ -940,6 +1105,7 @@ "type": "object", "properties": { "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", "type": [ "integer", "null" @@ -948,6 +1114,7 @@ "minimum": 0.0 }, "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", "type": [ "integer", "null" @@ -955,7 +1122,95 @@ "format": "uint32", "minimum": 0.0 } - } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets detailed information about a pending epoch event given its id.", + "type": "object", + "required": [ + "get_pending_epoch_event" + ], + "properties": { + "get_pending_epoch_event": { + "type": "object", + "required": [ + "event_id" + ], + "properties": { + "event_id": { + "description": "The unique id associated with the event.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets detailed information about a pending interval event given its id.", + "type": "object", + "required": [ + "get_pending_interval_event" + ], + "properties": { + "get_pending_interval_event": { + "type": "object", + "required": [ + "event_id" + ], + "properties": { + "event_id": { + "description": "The unique id associated with the event.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the information about the number of currently pending epoch and interval events.", + "type": "object", + "required": [ + "get_number_of_pending_events" + ], + "properties": { + "get_number_of_pending_events": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the signing nonce associated with the particular cosmos address.", + "type": "object", + "required": [ + "get_signing_nonce" + ], + "properties": { + "get_signing_nonce": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "Cosmos address used for the query of the signing nonce.", + "type": "string" + } + }, + "additionalProperties": false } }, "additionalProperties": false diff --git a/contracts/mixnet/schema/raw/response_to_get_all_delegations.json b/contracts/mixnet/schema/raw/response_to_get_all_delegations.json new file mode 100644 index 0000000000..a919220c46 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_all_delegations.json @@ -0,0 +1,128 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedAllDelegationsResponse", + "description": "Response containing paged list of all delegations currently active.", + "type": "object", + "required": [ + "delegations" + ], + "properties": { + "delegations": { + "description": "Each individual delegation made.", + "type": "array", + "items": { + "$ref": "#/definitions/Delegation" + } + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "string" + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Delegation": { + "description": "Information about tokens being delegated towards given mixnode in order to accrue rewards with their work.", + "type": "object", + "required": [ + "amount", + "cumulative_reward_ratio", + "height", + "mix_id", + "owner" + ], + "properties": { + "amount": { + "description": "Original delegation amount. Note that it is never mutated as delegation accumulates rewards.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "cumulative_reward_ratio": { + "description": "Value of the \"unit delegation\" associated with the mixnode at the time of delegation.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "height": { + "description": "Block height where this delegation occurred.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "mix_id": { + "description": "Id of the MixNode that this delegation was performed against.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "description": "Address of the owner of this delegation.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Proxy address used to delegate the funds on behalf of another address", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_all_families_paged.json b/contracts/mixnet/schema/raw/response_to_get_all_families_paged.json new file mode 100644 index 0000000000..6744e15be6 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_all_families_paged.json @@ -0,0 +1,62 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedFamiliesResponse", + "description": "Response containing paged list of all families registered in the contract.", + "type": "object", + "required": [ + "families" + ], + "properties": { + "families": { + "description": "The families registered in the contract.", + "type": "array", + "items": { + "$ref": "#/definitions/Family" + } + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false, + "definitions": { + "Family": { + "description": "A group of mixnodes associated with particular staking entity. When defined all nodes belonging to the same family will be prioritised to be put onto the same layer.", + "type": "object", + "required": [ + "head", + "label" + ], + "properties": { + "head": { + "description": "Owner of this family.", + "allOf": [ + { + "$ref": "#/definitions/FamilyHead" + } + ] + }, + "label": { + "description": "Human readable label for this family.", + "type": "string" + }, + "proxy": { + "description": "Optional proxy (i.e. vesting contract address) used when creating the family.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + }, + "FamilyHead": { + "description": "Head of particular family as identified by its identity key (i.e. public component of its ed25519 keypair stringified into base58).", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_all_members_paged.json b/contracts/mixnet/schema/raw/response_to_get_all_members_paged.json new file mode 100644 index 0000000000..69da663f92 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_all_members_paged.json @@ -0,0 +1,42 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedMembersResponse", + "description": "Response containing paged list of all family members (of ALL families) registered in the contract.", + "type": "object", + "required": [ + "members" + ], + "properties": { + "members": { + "description": "The members alongside their family heads.", + "type": "array", + "items": { + "type": "array", + "items": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/FamilyHead" + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false, + "definitions": { + "FamilyHead": { + "description": "Head of particular family as identified by its identity key (i.e. public component of its ed25519 keypair stringified into base58).", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_bonded_mixnode_details_by_identity.json b/contracts/mixnet/schema/raw/response_to_get_bonded_mixnode_details_by_identity.json new file mode 100644 index 0000000000..59fc029331 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_bonded_mixnode_details_by_identity.json @@ -0,0 +1,342 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MixnodeDetailsByIdentityResponse", + "description": "Response containing details of a bonded mixnode with the provided identity key.", + "type": "object", + "required": [ + "identity_key" + ], + "properties": { + "identity_key": { + "description": "The identity key (base58-encoded ed25519 public key) of the mixnode.", + "type": "string" + }, + "mixnode_details": { + "description": "If there exists a bonded mixnode with the provided identity key, this field contains its detailed information.", + "anyOf": [ + { + "$ref": "#/definitions/MixNodeDetails" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Layer": { + "type": "string", + "enum": [ + "One", + "Two", + "Three" + ] + }, + "MixNode": { + "description": "Information provided by the node operator during bonding that are used to allow other entities to use the services of this node.", + "type": "object", + "required": [ + "host", + "http_api_port", + "identity_key", + "mix_port", + "sphinx_key", + "verloc_port", + "version" + ], + "properties": { + "host": { + "description": "Network address of this mixnode, for example 1.1.1.1 or foo.mixnode.com", + "type": "string" + }, + "http_api_port": { + "description": "Port used by this mixnode for its http(s) API", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "identity_key": { + "description": "Base58-encoded ed25519 EdDSA public key.", + "type": "string" + }, + "mix_port": { + "description": "Port used by this mixnode for listening for mix packets.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "sphinx_key": { + "description": "Base58-encoded x25519 public key used for sphinx key derivation.", + "type": "string" + }, + "verloc_port": { + "description": "Port used by this mixnode for listening for verloc requests.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "version": { + "description": "The self-reported semver version of this mixnode.", + "type": "string" + } + }, + "additionalProperties": false + }, + "MixNodeBond": { + "description": "Basic mixnode information provided by the node operator.", + "type": "object", + "required": [ + "bonding_height", + "is_unbonding", + "layer", + "mix_id", + "mix_node", + "original_pledge", + "owner" + ], + "properties": { + "bonding_height": { + "description": "Block height at which this mixnode has been bonded.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "is_unbonding": { + "description": "Flag to indicate whether this node is in the process of unbonding, that will conclude upon the epoch finishing.", + "type": "boolean" + }, + "layer": { + "description": "Layer assigned to this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/Layer" + } + ] + }, + "mix_id": { + "description": "Unique id assigned to the bonded mixnode.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "mix_node": { + "description": "Information provided by the operator for the purposes of bonding.", + "allOf": [ + { + "$ref": "#/definitions/MixNode" + } + ] + }, + "original_pledge": { + "description": "Original amount pledged by the operator of this node.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "owner": { + "description": "Address of the owner of this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Entity who bonded this mixnode on behalf of the owner. If exists, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeCostParams": { + "description": "The cost parameters, or the cost function, defined for the particular mixnode that influences how the rewards should be split between the node operator and its delegators.", + "type": "object", + "required": [ + "interval_operating_cost", + "profit_margin_percent" + ], + "properties": { + "interval_operating_cost": { + "description": "Operating cost of the associated mixnode per the entire interval.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "profit_margin_percent": { + "description": "The profit margin of the associated mixnode, i.e. the desired percent of the reward to be distributed to the operator.", + "allOf": [ + { + "$ref": "#/definitions/Percent" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeDetails": { + "description": "Full details associated with given mixnode.", + "type": "object", + "required": [ + "bond_information", + "rewarding_details" + ], + "properties": { + "bond_information": { + "description": "Basic bond information of this mixnode, such as owner address, original pledge, etc.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeBond" + } + ] + }, + "pending_changes": { + "description": "Adjustments to the mixnode that are ought to happen during future epoch transitions.", + "default": { + "pledge_change": null + }, + "allOf": [ + { + "$ref": "#/definitions/PendingMixNodeChanges" + } + ] + }, + "rewarding_details": { + "description": "Details used for computation of rewarding related data.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeRewarding" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeRewarding": { + "type": "object", + "required": [ + "cost_params", + "delegates", + "last_rewarded_epoch", + "operator", + "total_unit_reward", + "unique_delegations", + "unit_delegation" + ], + "properties": { + "cost_params": { + "description": "Information provided by the operator that influence the cost function.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeCostParams" + } + ] + }, + "delegates": { + "description": "Total delegation and compounded reward earned by all node delegators.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "last_rewarded_epoch": { + "description": "Marks the epoch when this node was last rewarded so that we wouldn't accidentally attempt to reward it multiple times in the same epoch.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "operator": { + "description": "Total pledge and compounded reward earned by the node operator.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "total_unit_reward": { + "description": "Cumulative reward earned by the \"unit delegation\" since the block 0.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "unique_delegations": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "unit_delegation": { + "description": "Value of the theoretical \"unit delegation\" that has delegated to this mixnode at block 0.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + } + }, + "additionalProperties": false + }, + "PendingMixNodeChanges": { + "type": "object", + "properties": { + "pledge_change": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "Percent": { + "description": "Percent represents a value between 0 and 100% (i.e. between 0.0 and 1.0)", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_c_w2_contract_version.json b/contracts/mixnet/schema/raw/response_to_get_c_w2_contract_version.json new file mode 100644 index 0000000000..3ded8c84d9 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_c_w2_contract_version.json @@ -0,0 +1,20 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ContractVersion", + "type": "object", + "required": [ + "contract", + "version" + ], + "properties": { + "contract": { + "description": "contract is the crate name of the implementing contract, eg. `crate:cw20-base` we will use other prefixes for other languages, and their standard global namespacing", + "type": "string" + }, + "version": { + "description": "version is any string that this implementation knows. It may be simple counter \"1\", \"2\". or semantic version on release tags \"v0.7.0\", or some custom feature flag list. the only code that needs to understand the version parsing is code that knows how to migrate from the given contract (and is tied to it's implementation somehow)", + "type": "string" + } + }, + "additionalProperties": false +} diff --git a/contracts/mixnet/schema/raw/response_to_get_contract_version.json b/contracts/mixnet/schema/raw/response_to_get_contract_version.json new file mode 100644 index 0000000000..60ae65f3d1 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_contract_version.json @@ -0,0 +1,40 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ContractBuildInformation", + "type": "object", + "required": [ + "build_timestamp", + "build_version", + "commit_branch", + "commit_sha", + "commit_timestamp", + "rustc_version" + ], + "properties": { + "build_timestamp": { + "description": "Provides the build timestamp, for example `2021-02-23T20:14:46.558472672+00:00`.", + "type": "string" + }, + "build_version": { + "description": "Provides the build version, for example `0.1.0-9-g46f83e1`.", + "type": "string" + }, + "commit_branch": { + "description": "Provides the name of the git branch that was used for the build, for example `master`.", + "type": "string" + }, + "commit_sha": { + "description": "Provides the hash of the commit that was used for the build, for example `46f83e112520533338245862d366f6a02cef07d4`.", + "type": "string" + }, + "commit_timestamp": { + "description": "Provides the timestamp of the commit that was used for the build, for example `2021-02-23T08:08:02-05:00`.", + "type": "string" + }, + "rustc_version": { + "description": "Provides the rustc version that was used for the build, for example `1.52.0-nightly`.", + "type": "string" + } + }, + "additionalProperties": false +} diff --git a/contracts/mixnet/schema/raw/response_to_get_current_interval_details.json b/contracts/mixnet/schema/raw/response_to_get_current_interval_details.json new file mode 100644 index 0000000000..1a90ceb1eb --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_current_interval_details.json @@ -0,0 +1,97 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "CurrentIntervalResponse", + "description": "Information about the current rewarding interval.", + "type": "object", + "required": [ + "current_blocktime", + "interval", + "is_current_epoch_over", + "is_current_interval_over" + ], + "properties": { + "current_blocktime": { + "description": "The current blocktime", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "interval": { + "description": "Detailed information about the underlying interval.", + "allOf": [ + { + "$ref": "#/definitions/Interval" + } + ] + }, + "is_current_epoch_over": { + "description": "Flag indicating whether the current epoch is over and it should be advanced.", + "type": "boolean" + }, + "is_current_interval_over": { + "description": "Flag indicating whether the current interval is over and it should be advanced.", + "type": "boolean" + } + }, + "additionalProperties": false, + "definitions": { + "Duration": { + "type": "object", + "required": [ + "nanos", + "secs" + ], + "properties": { + "nanos": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "secs": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + }, + "Interval": { + "type": "object", + "required": [ + "current_epoch_id", + "current_epoch_start", + "epoch_length", + "epochs_in_interval", + "id", + "total_elapsed_epochs" + ], + "properties": { + "current_epoch_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "current_epoch_start": { + "type": "string" + }, + "epoch_length": { + "$ref": "#/definitions/Duration" + }, + "epochs_in_interval": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "total_elapsed_epochs": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + } + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_delegation_details.json b/contracts/mixnet/schema/raw/response_to_get_delegation_details.json new file mode 100644 index 0000000000..8371493b30 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_delegation_details.json @@ -0,0 +1,117 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MixNodeDelegationResponse", + "description": "Response containing delegation details.", + "type": "object", + "required": [ + "mixnode_still_bonded" + ], + "properties": { + "delegation": { + "description": "If the delegation exists, this field contains its detailed information.", + "anyOf": [ + { + "$ref": "#/definitions/Delegation" + }, + { + "type": "null" + } + ] + }, + "mixnode_still_bonded": { + "description": "Flag indicating whether the node towards which the delegation was made is still bonded in the network.", + "type": "boolean" + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Delegation": { + "description": "Information about tokens being delegated towards given mixnode in order to accrue rewards with their work.", + "type": "object", + "required": [ + "amount", + "cumulative_reward_ratio", + "height", + "mix_id", + "owner" + ], + "properties": { + "amount": { + "description": "Original delegation amount. Note that it is never mutated as delegation accumulates rewards.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "cumulative_reward_ratio": { + "description": "Value of the \"unit delegation\" associated with the mixnode at the time of delegation.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "height": { + "description": "Block height where this delegation occurred.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "mix_id": { + "description": "Id of the MixNode that this delegation was performed against.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "description": "Address of the owner of this delegation.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Proxy address used to delegate the funds on behalf of another address", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_delegator_delegations.json b/contracts/mixnet/schema/raw/response_to_get_delegator_delegations.json new file mode 100644 index 0000000000..b6e7e7a6ee --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_delegator_delegations.json @@ -0,0 +1,128 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedDelegatorDelegationsResponse", + "description": "Response containing paged list of all delegations made by the particular address.", + "type": "object", + "required": [ + "delegations" + ], + "properties": { + "delegations": { + "description": "Each individual delegation made.", + "type": "array", + "items": { + "$ref": "#/definitions/Delegation" + } + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "string" + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Delegation": { + "description": "Information about tokens being delegated towards given mixnode in order to accrue rewards with their work.", + "type": "object", + "required": [ + "amount", + "cumulative_reward_ratio", + "height", + "mix_id", + "owner" + ], + "properties": { + "amount": { + "description": "Original delegation amount. Note that it is never mutated as delegation accumulates rewards.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "cumulative_reward_ratio": { + "description": "Value of the \"unit delegation\" associated with the mixnode at the time of delegation.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "height": { + "description": "Block height where this delegation occurred.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "mix_id": { + "description": "Id of the MixNode that this delegation was performed against.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "description": "Address of the owner of this delegation.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Proxy address used to delegate the funds on behalf of another address", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_epoch_status.json b/contracts/mixnet/schema/raw/response_to_get_epoch_status.json new file mode 100644 index 0000000000..1a85e633bf --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_epoch_status.json @@ -0,0 +1,93 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "EpochStatus", + "description": "The status of the current rewarding epoch.", + "type": "object", + "required": [ + "being_advanced_by", + "state" + ], + "properties": { + "being_advanced_by": { + "description": "Specifies either, which validator is currently performing progression into the following epoch (if the epoch is currently being progressed), or which validator was responsible for progressing into the current epoch (if the epoch is currently in progress)", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "state": { + "description": "The concrete state of the epoch.", + "allOf": [ + { + "$ref": "#/definitions/EpochState" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "EpochState": { + "description": "The state of the current rewarding epoch.", + "oneOf": [ + { + "description": "Represents the state of an epoch that's in progress (well, duh.) All actions are allowed to be issued.", + "type": "string", + "enum": [ + "in_progress" + ] + }, + { + "description": "Represents the state of an epoch when the rewarding entity has been decided on, and the mixnodes are in the process of being rewarded for their work in this epoch.", + "type": "object", + "required": [ + "rewarding" + ], + "properties": { + "rewarding": { + "type": "object", + "required": [ + "final_node_id", + "last_rewarded" + ], + "properties": { + "final_node_id": { + "description": "The id of the last node that's going to be rewarded before progressing into the next state.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "last_rewarded": { + "description": "The id of the last node that has already received its rewards.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Represents the state of an epoch when all mixnodes have already been rewarded for their work in this epoch and all issued actions should now get resolved before being allowed to advance into the next epoch.", + "type": "string", + "enum": [ + "reconciling_events" + ] + }, + { + "description": "Represents the state of an epoch when all mixnodes have already been rewarded for their work in this epoch, all issued actions got resolved and the epoch should now be advanced whilst assigning new rewarded set.", + "type": "string", + "enum": [ + "advancing_epoch" + ] + } + ] + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_estimated_current_epoch_delegator_reward.json b/contracts/mixnet/schema/raw/response_to_get_estimated_current_epoch_delegator_reward.json new file mode 100644 index 0000000000..94ca8beb78 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_estimated_current_epoch_delegator_reward.json @@ -0,0 +1,89 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "EstimatedCurrentEpochRewardResponse", + "description": "Response containing estimation of node rewards for the current epoch.", + "type": "object", + "properties": { + "current_stake_value": { + "description": "The current stake value given all past rewarding and compounding since the original staking was performed.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + }, + "current_stake_value_detailed_amount": { + "description": "The current stake value. Note that it's nearly identical to `current_stake_value`, however, it contains few additional decimal points for more accurate reward calculation.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "detailed_estimation_amount": { + "description": "The full reward estimation. Note that it's nearly identical to `estimation`, however, it contains few additional decimal points for more accurate reward calculation.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "estimation": { + "description": "The reward estimation for the current epoch, i.e. the amount of tokens that could be claimable after the epoch finishes and the state of the network does not change.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + }, + "original_stake": { + "description": "The amount of tokens initially staked.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_estimated_current_epoch_operator_reward.json b/contracts/mixnet/schema/raw/response_to_get_estimated_current_epoch_operator_reward.json new file mode 100644 index 0000000000..94ca8beb78 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_estimated_current_epoch_operator_reward.json @@ -0,0 +1,89 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "EstimatedCurrentEpochRewardResponse", + "description": "Response containing estimation of node rewards for the current epoch.", + "type": "object", + "properties": { + "current_stake_value": { + "description": "The current stake value given all past rewarding and compounding since the original staking was performed.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + }, + "current_stake_value_detailed_amount": { + "description": "The current stake value. Note that it's nearly identical to `current_stake_value`, however, it contains few additional decimal points for more accurate reward calculation.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "detailed_estimation_amount": { + "description": "The full reward estimation. Note that it's nearly identical to `estimation`, however, it contains few additional decimal points for more accurate reward calculation.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "estimation": { + "description": "The reward estimation for the current epoch, i.e. the amount of tokens that could be claimable after the epoch finishes and the state of the network does not change.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + }, + "original_stake": { + "description": "The amount of tokens initially staked.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_family_by_head.json b/contracts/mixnet/schema/raw/response_to_get_family_by_head.json new file mode 100644 index 0000000000..d7bc69b639 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_family_by_head.json @@ -0,0 +1,67 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "FamilyByHeadResponse", + "description": "Response containing family information.", + "type": "object", + "required": [ + "head" + ], + "properties": { + "family": { + "description": "If applicable, the family associated with the provided head.", + "anyOf": [ + { + "$ref": "#/definitions/Family" + }, + { + "type": "null" + } + ] + }, + "head": { + "description": "The family head used for the query.", + "allOf": [ + { + "$ref": "#/definitions/FamilyHead" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Family": { + "description": "A group of mixnodes associated with particular staking entity. When defined all nodes belonging to the same family will be prioritised to be put onto the same layer.", + "type": "object", + "required": [ + "head", + "label" + ], + "properties": { + "head": { + "description": "Owner of this family.", + "allOf": [ + { + "$ref": "#/definitions/FamilyHead" + } + ] + }, + "label": { + "description": "Human readable label for this family.", + "type": "string" + }, + "proxy": { + "description": "Optional proxy (i.e. vesting contract address) used when creating the family.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + }, + "FamilyHead": { + "description": "Head of particular family as identified by its identity key (i.e. public component of its ed25519 keypair stringified into base58).", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_family_by_label.json b/contracts/mixnet/schema/raw/response_to_get_family_by_label.json new file mode 100644 index 0000000000..c007bd05dc --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_family_by_label.json @@ -0,0 +1,63 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "FamilyByLabelResponse", + "description": "Response containing family information.", + "type": "object", + "required": [ + "label" + ], + "properties": { + "family": { + "description": "If applicable, the family associated with the provided label.", + "anyOf": [ + { + "$ref": "#/definitions/Family" + }, + { + "type": "null" + } + ] + }, + "label": { + "description": "The family label used for the query.", + "type": "string" + } + }, + "additionalProperties": false, + "definitions": { + "Family": { + "description": "A group of mixnodes associated with particular staking entity. When defined all nodes belonging to the same family will be prioritised to be put onto the same layer.", + "type": "object", + "required": [ + "head", + "label" + ], + "properties": { + "head": { + "description": "Owner of this family.", + "allOf": [ + { + "$ref": "#/definitions/FamilyHead" + } + ] + }, + "label": { + "description": "Human readable label for this family.", + "type": "string" + }, + "proxy": { + "description": "Optional proxy (i.e. vesting contract address) used when creating the family.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + }, + "FamilyHead": { + "description": "Head of particular family as identified by its identity key (i.e. public component of its ed25519 keypair stringified into base58).", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_family_members_by_head.json b/contracts/mixnet/schema/raw/response_to_get_family_members_by_head.json new file mode 100644 index 0000000000..7975599604 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_family_members_by_head.json @@ -0,0 +1,34 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "FamilyMembersByHeadResponse", + "description": "Response containing family members information.", + "type": "object", + "required": [ + "head", + "members" + ], + "properties": { + "head": { + "description": "The family head used for the query.", + "allOf": [ + { + "$ref": "#/definitions/FamilyHead" + } + ] + }, + "members": { + "description": "All members belonging to the specified family.", + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false, + "definitions": { + "FamilyHead": { + "description": "Head of particular family as identified by its identity key (i.e. public component of its ed25519 keypair stringified into base58).", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_family_members_by_label.json b/contracts/mixnet/schema/raw/response_to_get_family_members_by_label.json new file mode 100644 index 0000000000..a76bb07f7d --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_family_members_by_label.json @@ -0,0 +1,24 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "FamilyMembersByLabelResponse", + "description": "Response containing family members information.", + "type": "object", + "required": [ + "label", + "members" + ], + "properties": { + "label": { + "description": "The family label used for the query.", + "type": "string" + }, + "members": { + "description": "All members belonging to the specified family.", + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false +} diff --git a/contracts/mixnet/schema/raw/response_to_get_gateway_bond.json b/contracts/mixnet/schema/raw/response_to_get_gateway_bond.json new file mode 100644 index 0000000000..dd7f99b4a4 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_gateway_bond.json @@ -0,0 +1,154 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "GatewayBondResponse", + "description": "Response containing details of a gateway with the provided identity key.", + "type": "object", + "required": [ + "identity" + ], + "properties": { + "gateway": { + "description": "If there exists a gateway with the provided identity key, this field contains its details.", + "anyOf": [ + { + "$ref": "#/definitions/GatewayBond" + }, + { + "type": "null" + } + ] + }, + "identity": { + "description": "The identity key (base58-encoded ed25519 public key) of the gateway.", + "type": "string" + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Gateway": { + "description": "Information provided by the node operator during bonding that are used to allow other entities to use the services of this node.", + "type": "object", + "required": [ + "clients_port", + "host", + "identity_key", + "location", + "mix_port", + "sphinx_key", + "version" + ], + "properties": { + "clients_port": { + "description": "Port used by this gateway for listening for client requests.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "host": { + "description": "Network address of this gateway, for example 1.1.1.1 or foo.gateway.com", + "type": "string" + }, + "identity_key": { + "description": "Base58 encoded ed25519 EdDSA public key of the gateway used to derive shared keys with clients", + "type": "string" + }, + "location": { + "description": "The physical, self-reported, location of this gateway.", + "type": "string" + }, + "mix_port": { + "description": "Port used by this gateway for listening for mix packets.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "sphinx_key": { + "description": "Base58-encoded x25519 public key used for sphinx key derivation.", + "type": "string" + }, + "version": { + "description": "The self-reported semver version of this gateway.", + "type": "string" + } + }, + "additionalProperties": false + }, + "GatewayBond": { + "description": "Basic gateway information provided by the node operator.", + "type": "object", + "required": [ + "block_height", + "gateway", + "owner", + "pledge_amount" + ], + "properties": { + "block_height": { + "description": "Block height at which this gateway has been bonded.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "gateway": { + "description": "Information provided by the operator for the purposes of bonding.", + "allOf": [ + { + "$ref": "#/definitions/Gateway" + } + ] + }, + "owner": { + "description": "Address of the owner of this gateway.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "pledge_amount": { + "description": "Original amount pledged by the operator of this node.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "proxy": { + "description": "Entity who bonded this gateway on behalf of the owner. If exists, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_gateways.json b/contracts/mixnet/schema/raw/response_to_get_gateways.json new file mode 100644 index 0000000000..0ec50135b6 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_gateways.json @@ -0,0 +1,160 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedGatewayResponse", + "description": "Response containing paged list of all gateway bonds in the contract.", + "type": "object", + "required": [ + "nodes", + "per_page" + ], + "properties": { + "nodes": { + "description": "The gateway bond information present in the contract.", + "type": "array", + "items": { + "$ref": "#/definitions/GatewayBond" + } + }, + "per_page": { + "description": "Maximum number of entries that could be included in a response. `per_page <= nodes.len()`", + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Gateway": { + "description": "Information provided by the node operator during bonding that are used to allow other entities to use the services of this node.", + "type": "object", + "required": [ + "clients_port", + "host", + "identity_key", + "location", + "mix_port", + "sphinx_key", + "version" + ], + "properties": { + "clients_port": { + "description": "Port used by this gateway for listening for client requests.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "host": { + "description": "Network address of this gateway, for example 1.1.1.1 or foo.gateway.com", + "type": "string" + }, + "identity_key": { + "description": "Base58 encoded ed25519 EdDSA public key of the gateway used to derive shared keys with clients", + "type": "string" + }, + "location": { + "description": "The physical, self-reported, location of this gateway.", + "type": "string" + }, + "mix_port": { + "description": "Port used by this gateway for listening for mix packets.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "sphinx_key": { + "description": "Base58-encoded x25519 public key used for sphinx key derivation.", + "type": "string" + }, + "version": { + "description": "The self-reported semver version of this gateway.", + "type": "string" + } + }, + "additionalProperties": false + }, + "GatewayBond": { + "description": "Basic gateway information provided by the node operator.", + "type": "object", + "required": [ + "block_height", + "gateway", + "owner", + "pledge_amount" + ], + "properties": { + "block_height": { + "description": "Block height at which this gateway has been bonded.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "gateway": { + "description": "Information provided by the operator for the purposes of bonding.", + "allOf": [ + { + "$ref": "#/definitions/Gateway" + } + ] + }, + "owner": { + "description": "Address of the owner of this gateway.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "pledge_amount": { + "description": "Original amount pledged by the operator of this node.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "proxy": { + "description": "Entity who bonded this gateway on behalf of the owner. If exists, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_layer_distribution.json b/contracts/mixnet/schema/raw/response_to_get_layer_distribution.json new file mode 100644 index 0000000000..0ed27f33cb --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_layer_distribution.json @@ -0,0 +1,32 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "LayerDistribution", + "description": "The current layer distribution of the mix network.", + "type": "object", + "required": [ + "layer1", + "layer2", + "layer3" + ], + "properties": { + "layer1": { + "description": "Number of nodes on the first layer.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "layer2": { + "description": "Number of nodes on the second layer.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "layer3": { + "description": "Number of nodes on the third layer.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false +} diff --git a/contracts/mixnet/schema/raw/response_to_get_mix_node_bonds.json b/contracts/mixnet/schema/raw/response_to_get_mix_node_bonds.json new file mode 100644 index 0000000000..61bdf6b3f1 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_mix_node_bonds.json @@ -0,0 +1,193 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedMixnodeBondsResponse", + "description": "Response containing paged list of all mixnode bonds in the contract.", + "type": "object", + "required": [ + "nodes", + "per_page" + ], + "properties": { + "nodes": { + "description": "The mixnode bond information present in the contract.", + "type": "array", + "items": { + "$ref": "#/definitions/MixNodeBond" + } + }, + "per_page": { + "description": "Maximum number of entries that could be included in a response. `per_page <= nodes.len()`", + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Layer": { + "type": "string", + "enum": [ + "One", + "Two", + "Three" + ] + }, + "MixNode": { + "description": "Information provided by the node operator during bonding that are used to allow other entities to use the services of this node.", + "type": "object", + "required": [ + "host", + "http_api_port", + "identity_key", + "mix_port", + "sphinx_key", + "verloc_port", + "version" + ], + "properties": { + "host": { + "description": "Network address of this mixnode, for example 1.1.1.1 or foo.mixnode.com", + "type": "string" + }, + "http_api_port": { + "description": "Port used by this mixnode for its http(s) API", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "identity_key": { + "description": "Base58-encoded ed25519 EdDSA public key.", + "type": "string" + }, + "mix_port": { + "description": "Port used by this mixnode for listening for mix packets.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "sphinx_key": { + "description": "Base58-encoded x25519 public key used for sphinx key derivation.", + "type": "string" + }, + "verloc_port": { + "description": "Port used by this mixnode for listening for verloc requests.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "version": { + "description": "The self-reported semver version of this mixnode.", + "type": "string" + } + }, + "additionalProperties": false + }, + "MixNodeBond": { + "description": "Basic mixnode information provided by the node operator.", + "type": "object", + "required": [ + "bonding_height", + "is_unbonding", + "layer", + "mix_id", + "mix_node", + "original_pledge", + "owner" + ], + "properties": { + "bonding_height": { + "description": "Block height at which this mixnode has been bonded.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "is_unbonding": { + "description": "Flag to indicate whether this node is in the process of unbonding, that will conclude upon the epoch finishing.", + "type": "boolean" + }, + "layer": { + "description": "Layer assigned to this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/Layer" + } + ] + }, + "mix_id": { + "description": "Unique id assigned to the bonded mixnode.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "mix_node": { + "description": "Information provided by the operator for the purposes of bonding.", + "allOf": [ + { + "$ref": "#/definitions/MixNode" + } + ] + }, + "original_pledge": { + "description": "Original amount pledged by the operator of this node.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "owner": { + "description": "Address of the owner of this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Entity who bonded this mixnode on behalf of the owner. If exists, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_mix_nodes_detailed.json b/contracts/mixnet/schema/raw/response_to_get_mix_nodes_detailed.json new file mode 100644 index 0000000000..bc95bb0839 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_mix_nodes_detailed.json @@ -0,0 +1,350 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedMixnodesDetailsResponse", + "description": "Response containing paged list of all mixnode details in the contract.", + "type": "object", + "required": [ + "nodes", + "per_page" + ], + "properties": { + "nodes": { + "description": "All mixnode details stored in the contract. Apart from the basic bond information it also contains details required for all future reward calculation as well as any pending changes requested by the operator.", + "type": "array", + "items": { + "$ref": "#/definitions/MixNodeDetails" + } + }, + "per_page": { + "description": "Maximum number of entries that could be included in a response. `per_page <= nodes.len()`", + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Layer": { + "type": "string", + "enum": [ + "One", + "Two", + "Three" + ] + }, + "MixNode": { + "description": "Information provided by the node operator during bonding that are used to allow other entities to use the services of this node.", + "type": "object", + "required": [ + "host", + "http_api_port", + "identity_key", + "mix_port", + "sphinx_key", + "verloc_port", + "version" + ], + "properties": { + "host": { + "description": "Network address of this mixnode, for example 1.1.1.1 or foo.mixnode.com", + "type": "string" + }, + "http_api_port": { + "description": "Port used by this mixnode for its http(s) API", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "identity_key": { + "description": "Base58-encoded ed25519 EdDSA public key.", + "type": "string" + }, + "mix_port": { + "description": "Port used by this mixnode for listening for mix packets.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "sphinx_key": { + "description": "Base58-encoded x25519 public key used for sphinx key derivation.", + "type": "string" + }, + "verloc_port": { + "description": "Port used by this mixnode for listening for verloc requests.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "version": { + "description": "The self-reported semver version of this mixnode.", + "type": "string" + } + }, + "additionalProperties": false + }, + "MixNodeBond": { + "description": "Basic mixnode information provided by the node operator.", + "type": "object", + "required": [ + "bonding_height", + "is_unbonding", + "layer", + "mix_id", + "mix_node", + "original_pledge", + "owner" + ], + "properties": { + "bonding_height": { + "description": "Block height at which this mixnode has been bonded.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "is_unbonding": { + "description": "Flag to indicate whether this node is in the process of unbonding, that will conclude upon the epoch finishing.", + "type": "boolean" + }, + "layer": { + "description": "Layer assigned to this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/Layer" + } + ] + }, + "mix_id": { + "description": "Unique id assigned to the bonded mixnode.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "mix_node": { + "description": "Information provided by the operator for the purposes of bonding.", + "allOf": [ + { + "$ref": "#/definitions/MixNode" + } + ] + }, + "original_pledge": { + "description": "Original amount pledged by the operator of this node.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "owner": { + "description": "Address of the owner of this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Entity who bonded this mixnode on behalf of the owner. If exists, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeCostParams": { + "description": "The cost parameters, or the cost function, defined for the particular mixnode that influences how the rewards should be split between the node operator and its delegators.", + "type": "object", + "required": [ + "interval_operating_cost", + "profit_margin_percent" + ], + "properties": { + "interval_operating_cost": { + "description": "Operating cost of the associated mixnode per the entire interval.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "profit_margin_percent": { + "description": "The profit margin of the associated mixnode, i.e. the desired percent of the reward to be distributed to the operator.", + "allOf": [ + { + "$ref": "#/definitions/Percent" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeDetails": { + "description": "Full details associated with given mixnode.", + "type": "object", + "required": [ + "bond_information", + "rewarding_details" + ], + "properties": { + "bond_information": { + "description": "Basic bond information of this mixnode, such as owner address, original pledge, etc.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeBond" + } + ] + }, + "pending_changes": { + "description": "Adjustments to the mixnode that are ought to happen during future epoch transitions.", + "default": { + "pledge_change": null + }, + "allOf": [ + { + "$ref": "#/definitions/PendingMixNodeChanges" + } + ] + }, + "rewarding_details": { + "description": "Details used for computation of rewarding related data.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeRewarding" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeRewarding": { + "type": "object", + "required": [ + "cost_params", + "delegates", + "last_rewarded_epoch", + "operator", + "total_unit_reward", + "unique_delegations", + "unit_delegation" + ], + "properties": { + "cost_params": { + "description": "Information provided by the operator that influence the cost function.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeCostParams" + } + ] + }, + "delegates": { + "description": "Total delegation and compounded reward earned by all node delegators.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "last_rewarded_epoch": { + "description": "Marks the epoch when this node was last rewarded so that we wouldn't accidentally attempt to reward it multiple times in the same epoch.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "operator": { + "description": "Total pledge and compounded reward earned by the node operator.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "total_unit_reward": { + "description": "Cumulative reward earned by the \"unit delegation\" since the block 0.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "unique_delegations": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "unit_delegation": { + "description": "Value of the theoretical \"unit delegation\" that has delegated to this mixnode at block 0.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + } + }, + "additionalProperties": false + }, + "PendingMixNodeChanges": { + "type": "object", + "properties": { + "pledge_change": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "Percent": { + "description": "Percent represents a value between 0 and 100% (i.e. between 0.0 and 1.0)", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_mixnode_delegations.json b/contracts/mixnet/schema/raw/response_to_get_mixnode_delegations.json new file mode 100644 index 0000000000..82d8c56b90 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_mixnode_delegations.json @@ -0,0 +1,116 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedMixNodeDelegationsResponse", + "description": "Response containing paged list of all delegations made towards particular mixnode.", + "type": "object", + "required": [ + "delegations" + ], + "properties": { + "delegations": { + "description": "Each individual delegation made.", + "type": "array", + "items": { + "$ref": "#/definitions/Delegation" + } + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Delegation": { + "description": "Information about tokens being delegated towards given mixnode in order to accrue rewards with their work.", + "type": "object", + "required": [ + "amount", + "cumulative_reward_ratio", + "height", + "mix_id", + "owner" + ], + "properties": { + "amount": { + "description": "Original delegation amount. Note that it is never mutated as delegation accumulates rewards.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "cumulative_reward_ratio": { + "description": "Value of the \"unit delegation\" associated with the mixnode at the time of delegation.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "height": { + "description": "Block height where this delegation occurred.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "mix_id": { + "description": "Id of the MixNode that this delegation was performed against.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "description": "Address of the owner of this delegation.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Proxy address used to delegate the funds on behalf of another address", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_mixnode_details.json b/contracts/mixnet/schema/raw/response_to_get_mixnode_details.json new file mode 100644 index 0000000000..4d7bd42da4 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_mixnode_details.json @@ -0,0 +1,344 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MixnodeDetailsResponse", + "description": "Response containing details of a mixnode with the provided id.", + "type": "object", + "required": [ + "mix_id" + ], + "properties": { + "mix_id": { + "description": "Id of the requested mixnode.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "mixnode_details": { + "description": "If there exists a mixnode with the provided id, this field contains its detailed information.", + "anyOf": [ + { + "$ref": "#/definitions/MixNodeDetails" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Layer": { + "type": "string", + "enum": [ + "One", + "Two", + "Three" + ] + }, + "MixNode": { + "description": "Information provided by the node operator during bonding that are used to allow other entities to use the services of this node.", + "type": "object", + "required": [ + "host", + "http_api_port", + "identity_key", + "mix_port", + "sphinx_key", + "verloc_port", + "version" + ], + "properties": { + "host": { + "description": "Network address of this mixnode, for example 1.1.1.1 or foo.mixnode.com", + "type": "string" + }, + "http_api_port": { + "description": "Port used by this mixnode for its http(s) API", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "identity_key": { + "description": "Base58-encoded ed25519 EdDSA public key.", + "type": "string" + }, + "mix_port": { + "description": "Port used by this mixnode for listening for mix packets.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "sphinx_key": { + "description": "Base58-encoded x25519 public key used for sphinx key derivation.", + "type": "string" + }, + "verloc_port": { + "description": "Port used by this mixnode for listening for verloc requests.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "version": { + "description": "The self-reported semver version of this mixnode.", + "type": "string" + } + }, + "additionalProperties": false + }, + "MixNodeBond": { + "description": "Basic mixnode information provided by the node operator.", + "type": "object", + "required": [ + "bonding_height", + "is_unbonding", + "layer", + "mix_id", + "mix_node", + "original_pledge", + "owner" + ], + "properties": { + "bonding_height": { + "description": "Block height at which this mixnode has been bonded.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "is_unbonding": { + "description": "Flag to indicate whether this node is in the process of unbonding, that will conclude upon the epoch finishing.", + "type": "boolean" + }, + "layer": { + "description": "Layer assigned to this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/Layer" + } + ] + }, + "mix_id": { + "description": "Unique id assigned to the bonded mixnode.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "mix_node": { + "description": "Information provided by the operator for the purposes of bonding.", + "allOf": [ + { + "$ref": "#/definitions/MixNode" + } + ] + }, + "original_pledge": { + "description": "Original amount pledged by the operator of this node.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "owner": { + "description": "Address of the owner of this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Entity who bonded this mixnode on behalf of the owner. If exists, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeCostParams": { + "description": "The cost parameters, or the cost function, defined for the particular mixnode that influences how the rewards should be split between the node operator and its delegators.", + "type": "object", + "required": [ + "interval_operating_cost", + "profit_margin_percent" + ], + "properties": { + "interval_operating_cost": { + "description": "Operating cost of the associated mixnode per the entire interval.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "profit_margin_percent": { + "description": "The profit margin of the associated mixnode, i.e. the desired percent of the reward to be distributed to the operator.", + "allOf": [ + { + "$ref": "#/definitions/Percent" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeDetails": { + "description": "Full details associated with given mixnode.", + "type": "object", + "required": [ + "bond_information", + "rewarding_details" + ], + "properties": { + "bond_information": { + "description": "Basic bond information of this mixnode, such as owner address, original pledge, etc.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeBond" + } + ] + }, + "pending_changes": { + "description": "Adjustments to the mixnode that are ought to happen during future epoch transitions.", + "default": { + "pledge_change": null + }, + "allOf": [ + { + "$ref": "#/definitions/PendingMixNodeChanges" + } + ] + }, + "rewarding_details": { + "description": "Details used for computation of rewarding related data.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeRewarding" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeRewarding": { + "type": "object", + "required": [ + "cost_params", + "delegates", + "last_rewarded_epoch", + "operator", + "total_unit_reward", + "unique_delegations", + "unit_delegation" + ], + "properties": { + "cost_params": { + "description": "Information provided by the operator that influence the cost function.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeCostParams" + } + ] + }, + "delegates": { + "description": "Total delegation and compounded reward earned by all node delegators.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "last_rewarded_epoch": { + "description": "Marks the epoch when this node was last rewarded so that we wouldn't accidentally attempt to reward it multiple times in the same epoch.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "operator": { + "description": "Total pledge and compounded reward earned by the node operator.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "total_unit_reward": { + "description": "Cumulative reward earned by the \"unit delegation\" since the block 0.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "unique_delegations": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "unit_delegation": { + "description": "Value of the theoretical \"unit delegation\" that has delegated to this mixnode at block 0.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + } + }, + "additionalProperties": false + }, + "PendingMixNodeChanges": { + "type": "object", + "properties": { + "pledge_change": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "Percent": { + "description": "Percent represents a value between 0 and 100% (i.e. between 0.0 and 1.0)", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_mixnode_rewarding_details.json b/contracts/mixnet/schema/raw/response_to_get_mixnode_rewarding_details.json new file mode 100644 index 0000000000..9b30dc4a75 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_mixnode_rewarding_details.json @@ -0,0 +1,155 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MixnodeRewardingDetailsResponse", + "description": "Response containing rewarding information of a mixnode with the provided id.", + "type": "object", + "required": [ + "mix_id" + ], + "properties": { + "mix_id": { + "description": "Id of the requested mixnode.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "rewarding_details": { + "description": "If there exists a mixnode with the provided id, this field contains its rewarding information.", + "anyOf": [ + { + "$ref": "#/definitions/MixNodeRewarding" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "MixNodeCostParams": { + "description": "The cost parameters, or the cost function, defined for the particular mixnode that influences how the rewards should be split between the node operator and its delegators.", + "type": "object", + "required": [ + "interval_operating_cost", + "profit_margin_percent" + ], + "properties": { + "interval_operating_cost": { + "description": "Operating cost of the associated mixnode per the entire interval.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "profit_margin_percent": { + "description": "The profit margin of the associated mixnode, i.e. the desired percent of the reward to be distributed to the operator.", + "allOf": [ + { + "$ref": "#/definitions/Percent" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeRewarding": { + "type": "object", + "required": [ + "cost_params", + "delegates", + "last_rewarded_epoch", + "operator", + "total_unit_reward", + "unique_delegations", + "unit_delegation" + ], + "properties": { + "cost_params": { + "description": "Information provided by the operator that influence the cost function.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeCostParams" + } + ] + }, + "delegates": { + "description": "Total delegation and compounded reward earned by all node delegators.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "last_rewarded_epoch": { + "description": "Marks the epoch when this node was last rewarded so that we wouldn't accidentally attempt to reward it multiple times in the same epoch.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "operator": { + "description": "Total pledge and compounded reward earned by the node operator.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "total_unit_reward": { + "description": "Cumulative reward earned by the \"unit delegation\" since the block 0.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "unique_delegations": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "unit_delegation": { + "description": "Value of the theoretical \"unit delegation\" that has delegated to this mixnode at block 0.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + } + }, + "additionalProperties": false + }, + "Percent": { + "description": "Percent represents a value between 0 and 100% (i.e. between 0.0 and 1.0)", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_number_of_pending_events.json b/contracts/mixnet/schema/raw/response_to_get_number_of_pending_events.json new file mode 100644 index 0000000000..520dbce29c --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_number_of_pending_events.json @@ -0,0 +1,25 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "NumberOfPendingEventsResponse", + "description": "Response containing number of currently pending epoch and interval events.", + "type": "object", + "required": [ + "epoch_events", + "interval_events" + ], + "properties": { + "epoch_events": { + "description": "The number of the currently pending epoch events.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "interval_events": { + "description": "The number of the currently pending epoch events.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false +} diff --git a/contracts/mixnet/schema/raw/response_to_get_owned_gateway.json b/contracts/mixnet/schema/raw/response_to_get_owned_gateway.json new file mode 100644 index 0000000000..50f2bbd4ad --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_owned_gateway.json @@ -0,0 +1,158 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "GatewayOwnershipResponse", + "description": "Response containing details of a gateway belonging to the particular owner.", + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "Validated address of the gateway owner.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "gateway": { + "description": "If the provided address owns a gateway, this field contains its details.", + "anyOf": [ + { + "$ref": "#/definitions/GatewayBond" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Gateway": { + "description": "Information provided by the node operator during bonding that are used to allow other entities to use the services of this node.", + "type": "object", + "required": [ + "clients_port", + "host", + "identity_key", + "location", + "mix_port", + "sphinx_key", + "version" + ], + "properties": { + "clients_port": { + "description": "Port used by this gateway for listening for client requests.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "host": { + "description": "Network address of this gateway, for example 1.1.1.1 or foo.gateway.com", + "type": "string" + }, + "identity_key": { + "description": "Base58 encoded ed25519 EdDSA public key of the gateway used to derive shared keys with clients", + "type": "string" + }, + "location": { + "description": "The physical, self-reported, location of this gateway.", + "type": "string" + }, + "mix_port": { + "description": "Port used by this gateway for listening for mix packets.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "sphinx_key": { + "description": "Base58-encoded x25519 public key used for sphinx key derivation.", + "type": "string" + }, + "version": { + "description": "The self-reported semver version of this gateway.", + "type": "string" + } + }, + "additionalProperties": false + }, + "GatewayBond": { + "description": "Basic gateway information provided by the node operator.", + "type": "object", + "required": [ + "block_height", + "gateway", + "owner", + "pledge_amount" + ], + "properties": { + "block_height": { + "description": "Block height at which this gateway has been bonded.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "gateway": { + "description": "Information provided by the operator for the purposes of bonding.", + "allOf": [ + { + "$ref": "#/definitions/Gateway" + } + ] + }, + "owner": { + "description": "Address of the owner of this gateway.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "pledge_amount": { + "description": "Original amount pledged by the operator of this node.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "proxy": { + "description": "Entity who bonded this gateway on behalf of the owner. If exists, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_owned_mixnode.json b/contracts/mixnet/schema/raw/response_to_get_owned_mixnode.json new file mode 100644 index 0000000000..da895c4bf4 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_owned_mixnode.json @@ -0,0 +1,346 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MixOwnershipResponse", + "description": "Response containing details of a mixnode belonging to the particular owner.", + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "Validated address of the mixnode owner.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "mixnode_details": { + "description": "If the provided address owns a mixnode, this field contains its detailed information.", + "anyOf": [ + { + "$ref": "#/definitions/MixNodeDetails" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Layer": { + "type": "string", + "enum": [ + "One", + "Two", + "Three" + ] + }, + "MixNode": { + "description": "Information provided by the node operator during bonding that are used to allow other entities to use the services of this node.", + "type": "object", + "required": [ + "host", + "http_api_port", + "identity_key", + "mix_port", + "sphinx_key", + "verloc_port", + "version" + ], + "properties": { + "host": { + "description": "Network address of this mixnode, for example 1.1.1.1 or foo.mixnode.com", + "type": "string" + }, + "http_api_port": { + "description": "Port used by this mixnode for its http(s) API", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "identity_key": { + "description": "Base58-encoded ed25519 EdDSA public key.", + "type": "string" + }, + "mix_port": { + "description": "Port used by this mixnode for listening for mix packets.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "sphinx_key": { + "description": "Base58-encoded x25519 public key used for sphinx key derivation.", + "type": "string" + }, + "verloc_port": { + "description": "Port used by this mixnode for listening for verloc requests.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "version": { + "description": "The self-reported semver version of this mixnode.", + "type": "string" + } + }, + "additionalProperties": false + }, + "MixNodeBond": { + "description": "Basic mixnode information provided by the node operator.", + "type": "object", + "required": [ + "bonding_height", + "is_unbonding", + "layer", + "mix_id", + "mix_node", + "original_pledge", + "owner" + ], + "properties": { + "bonding_height": { + "description": "Block height at which this mixnode has been bonded.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "is_unbonding": { + "description": "Flag to indicate whether this node is in the process of unbonding, that will conclude upon the epoch finishing.", + "type": "boolean" + }, + "layer": { + "description": "Layer assigned to this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/Layer" + } + ] + }, + "mix_id": { + "description": "Unique id assigned to the bonded mixnode.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "mix_node": { + "description": "Information provided by the operator for the purposes of bonding.", + "allOf": [ + { + "$ref": "#/definitions/MixNode" + } + ] + }, + "original_pledge": { + "description": "Original amount pledged by the operator of this node.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "owner": { + "description": "Address of the owner of this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Entity who bonded this mixnode on behalf of the owner. If exists, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeCostParams": { + "description": "The cost parameters, or the cost function, defined for the particular mixnode that influences how the rewards should be split between the node operator and its delegators.", + "type": "object", + "required": [ + "interval_operating_cost", + "profit_margin_percent" + ], + "properties": { + "interval_operating_cost": { + "description": "Operating cost of the associated mixnode per the entire interval.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "profit_margin_percent": { + "description": "The profit margin of the associated mixnode, i.e. the desired percent of the reward to be distributed to the operator.", + "allOf": [ + { + "$ref": "#/definitions/Percent" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeDetails": { + "description": "Full details associated with given mixnode.", + "type": "object", + "required": [ + "bond_information", + "rewarding_details" + ], + "properties": { + "bond_information": { + "description": "Basic bond information of this mixnode, such as owner address, original pledge, etc.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeBond" + } + ] + }, + "pending_changes": { + "description": "Adjustments to the mixnode that are ought to happen during future epoch transitions.", + "default": { + "pledge_change": null + }, + "allOf": [ + { + "$ref": "#/definitions/PendingMixNodeChanges" + } + ] + }, + "rewarding_details": { + "description": "Details used for computation of rewarding related data.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeRewarding" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeRewarding": { + "type": "object", + "required": [ + "cost_params", + "delegates", + "last_rewarded_epoch", + "operator", + "total_unit_reward", + "unique_delegations", + "unit_delegation" + ], + "properties": { + "cost_params": { + "description": "Information provided by the operator that influence the cost function.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeCostParams" + } + ] + }, + "delegates": { + "description": "Total delegation and compounded reward earned by all node delegators.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "last_rewarded_epoch": { + "description": "Marks the epoch when this node was last rewarded so that we wouldn't accidentally attempt to reward it multiple times in the same epoch.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "operator": { + "description": "Total pledge and compounded reward earned by the node operator.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "total_unit_reward": { + "description": "Cumulative reward earned by the \"unit delegation\" since the block 0.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "unique_delegations": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "unit_delegation": { + "description": "Value of the theoretical \"unit delegation\" that has delegated to this mixnode at block 0.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + } + }, + "additionalProperties": false + }, + "PendingMixNodeChanges": { + "type": "object", + "properties": { + "pledge_change": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "Percent": { + "description": "Percent represents a value between 0 and 100% (i.e. between 0.0 and 1.0)", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_pending_delegator_reward.json b/contracts/mixnet/schema/raw/response_to_get_pending_delegator_reward.json new file mode 100644 index 0000000000..e885d5976c --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_pending_delegator_reward.json @@ -0,0 +1,74 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PendingRewardResponse", + "description": "Response containing information about accrued rewards.", + "type": "object", + "required": [ + "mixnode_still_fully_bonded" + ], + "properties": { + "amount_earned": { + "description": "The amount of tokens that could be claimed.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + }, + "amount_earned_detailed": { + "description": "The full pending rewards. Note that it's nearly identical to `amount_earned`, however, it contains few additional decimal points for more accurate reward calculation.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "amount_staked": { + "description": "The amount of tokens initially staked.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + }, + "mixnode_still_fully_bonded": { + "description": "The associated mixnode is still fully bonded, meaning it is neither unbonded nor in the process of unbonding that would have finished at the epoch transition.", + "type": "boolean" + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_pending_epoch_event.json b/contracts/mixnet/schema/raw/response_to_get_pending_epoch_event.json new file mode 100644 index 0000000000..7588cad3e9 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_pending_epoch_event.json @@ -0,0 +1,298 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PendingEpochEventResponse", + "type": "object", + "required": [ + "event_id" + ], + "properties": { + "event": { + "anyOf": [ + { + "$ref": "#/definitions/PendingEpochEventData" + }, + { + "type": "null" + } + ] + }, + "event_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "PendingEpochEventData": { + "description": "Details of a particular pending epoch event.", + "type": "object", + "required": [ + "created_at", + "kind" + ], + "properties": { + "created_at": { + "description": "The block height at which the request has been made.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "kind": { + "description": "The underlying event data, containing its concrete type and information on how it should get resolved.", + "allOf": [ + { + "$ref": "#/definitions/PendingEpochEventKind" + } + ] + } + }, + "additionalProperties": false + }, + "PendingEpochEventKind": { + "description": "Enum encompassing all possible epoch events.", + "oneOf": [ + { + "description": "Request to create a delegation towards particular mixnode. Note that if such delegation already exists, it will get updated with the provided token amount.", + "type": "object", + "required": [ + "delegate" + ], + "properties": { + "delegate": { + "type": "object", + "required": [ + "amount", + "mix_id", + "owner" + ], + "properties": { + "amount": { + "description": "The amount of tokens to use for the delegation.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "mix_id": { + "description": "The id of the mixnode used for the delegation.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "description": "The address of the owner of the delegation.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Entity who made the delegation on behalf of the owner. If present, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Request to remove delegation from particular mixnode.", + "type": "object", + "required": [ + "undelegate" + ], + "properties": { + "undelegate": { + "type": "object", + "required": [ + "mix_id", + "owner" + ], + "properties": { + "mix_id": { + "description": "The id of the mixnode used for the delegation.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "description": "The address of the owner of the delegation.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Entity who made the delegation on behalf of the owner. If present, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Request to pledge more tokens (by the node operator) towards its node.", + "type": "object", + "required": [ + "pledge_more" + ], + "properties": { + "pledge_more": { + "type": "object", + "required": [ + "amount", + "mix_id" + ], + "properties": { + "amount": { + "description": "The amount of additional tokens to use by the pledge.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "mix_id": { + "description": "The id of the mixnode that will have its pledge updated.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Request to decrease amount of pledged tokens (by the node operator) from its node.", + "type": "object", + "required": [ + "decrease_pledge" + ], + "properties": { + "decrease_pledge": { + "type": "object", + "required": [ + "decrease_by", + "mix_id" + ], + "properties": { + "decrease_by": { + "description": "The amount of tokens that should be removed from the pledge.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "mix_id": { + "description": "The id of the mixnode that will have its pledge updated.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Request to unbond a mixnode and completely remove it from the network.", + "type": "object", + "required": [ + "unbond_mixnode" + ], + "properties": { + "unbond_mixnode": { + "type": "object", + "required": [ + "mix_id" + ], + "properties": { + "mix_id": { + "description": "The id of the mixnode that will get unbonded.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Request to update the current size of the active set.", + "type": "object", + "required": [ + "update_active_set_size" + ], + "properties": { + "update_active_set_size": { + "type": "object", + "required": [ + "new_size" + ], + "properties": { + "new_size": { + "description": "The new desired size of the active set.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_pending_epoch_events.json b/contracts/mixnet/schema/raw/response_to_get_pending_epoch_events.json new file mode 100644 index 0000000000..09a4d03787 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_pending_epoch_events.json @@ -0,0 +1,331 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PendingEpochEventsResponse", + "description": "Response containing all currently pending epoch events that will be resolved once the current epoch finishes.", + "type": "object", + "required": [ + "events", + "seconds_until_executable" + ], + "properties": { + "events": { + "description": "The currently pending events.", + "type": "array", + "items": { + "$ref": "#/definitions/PendingEpochEvent" + } + }, + "seconds_until_executable": { + "description": "Amount of seconds until the events would be eligible to be resolved. It's equivalent to the time until the current epoch finishes.", + "type": "integer", + "format": "int64" + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "PendingEpochEvent": { + "description": "A request made at some point in the current epoch that's going to get resolved once the epoch rolls over.", + "type": "object", + "required": [ + "event", + "id" + ], + "properties": { + "event": { + "description": "The underlying event details, containing its type and information on how it should get resolved.", + "allOf": [ + { + "$ref": "#/definitions/PendingEpochEventData" + } + ] + }, + "id": { + "description": "The unique id associated with the event.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "PendingEpochEventData": { + "description": "Details of a particular pending epoch event.", + "type": "object", + "required": [ + "created_at", + "kind" + ], + "properties": { + "created_at": { + "description": "The block height at which the request has been made.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "kind": { + "description": "The underlying event data, containing its concrete type and information on how it should get resolved.", + "allOf": [ + { + "$ref": "#/definitions/PendingEpochEventKind" + } + ] + } + }, + "additionalProperties": false + }, + "PendingEpochEventKind": { + "description": "Enum encompassing all possible epoch events.", + "oneOf": [ + { + "description": "Request to create a delegation towards particular mixnode. Note that if such delegation already exists, it will get updated with the provided token amount.", + "type": "object", + "required": [ + "delegate" + ], + "properties": { + "delegate": { + "type": "object", + "required": [ + "amount", + "mix_id", + "owner" + ], + "properties": { + "amount": { + "description": "The amount of tokens to use for the delegation.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "mix_id": { + "description": "The id of the mixnode used for the delegation.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "description": "The address of the owner of the delegation.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Entity who made the delegation on behalf of the owner. If present, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Request to remove delegation from particular mixnode.", + "type": "object", + "required": [ + "undelegate" + ], + "properties": { + "undelegate": { + "type": "object", + "required": [ + "mix_id", + "owner" + ], + "properties": { + "mix_id": { + "description": "The id of the mixnode used for the delegation.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "description": "The address of the owner of the delegation.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Entity who made the delegation on behalf of the owner. If present, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Request to pledge more tokens (by the node operator) towards its node.", + "type": "object", + "required": [ + "pledge_more" + ], + "properties": { + "pledge_more": { + "type": "object", + "required": [ + "amount", + "mix_id" + ], + "properties": { + "amount": { + "description": "The amount of additional tokens to use by the pledge.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "mix_id": { + "description": "The id of the mixnode that will have its pledge updated.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Request to decrease amount of pledged tokens (by the node operator) from its node.", + "type": "object", + "required": [ + "decrease_pledge" + ], + "properties": { + "decrease_pledge": { + "type": "object", + "required": [ + "decrease_by", + "mix_id" + ], + "properties": { + "decrease_by": { + "description": "The amount of tokens that should be removed from the pledge.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "mix_id": { + "description": "The id of the mixnode that will have its pledge updated.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Request to unbond a mixnode and completely remove it from the network.", + "type": "object", + "required": [ + "unbond_mixnode" + ], + "properties": { + "unbond_mixnode": { + "type": "object", + "required": [ + "mix_id" + ], + "properties": { + "mix_id": { + "description": "The id of the mixnode that will get unbonded.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Request to update the current size of the active set.", + "type": "object", + "required": [ + "update_active_set_size" + ], + "properties": { + "update_active_set_size": { + "type": "object", + "required": [ + "new_size" + ], + "properties": { + "new_size": { + "description": "The new desired size of the active set.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_pending_interval_event.json b/contracts/mixnet/schema/raw/response_to_get_pending_interval_event.json new file mode 100644 index 0000000000..a0877027a9 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_pending_interval_event.json @@ -0,0 +1,291 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PendingIntervalEventResponse", + "type": "object", + "required": [ + "event_id" + ], + "properties": { + "event": { + "anyOf": [ + { + "$ref": "#/definitions/PendingIntervalEventData" + }, + { + "type": "null" + } + ] + }, + "event_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "IntervalRewardingParamsUpdate": { + "description": "Specification on how the rewarding params should be updated.", + "type": "object", + "properties": { + "active_set_work_factor": { + "description": "Defines the new value of the active set work factor.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "interval_pool_emission": { + "description": "Defines the new value of the interval pool emission rate.", + "anyOf": [ + { + "$ref": "#/definitions/Percent" + }, + { + "type": "null" + } + ] + }, + "reward_pool": { + "description": "Defines the new value of the reward pool.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "rewarded_set_size": { + "description": "Defines the new size of the rewarded set.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "staking_supply": { + "description": "Defines the new value of the staking supply.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "staking_supply_scale_factor": { + "description": "Defines the new value of the staking supply scale factor.", + "anyOf": [ + { + "$ref": "#/definitions/Percent" + }, + { + "type": "null" + } + ] + }, + "sybil_resistance_percent": { + "description": "Defines the new value of the sybil resistance percent.", + "anyOf": [ + { + "$ref": "#/definitions/Percent" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeCostParams": { + "description": "The cost parameters, or the cost function, defined for the particular mixnode that influences how the rewards should be split between the node operator and its delegators.", + "type": "object", + "required": [ + "interval_operating_cost", + "profit_margin_percent" + ], + "properties": { + "interval_operating_cost": { + "description": "Operating cost of the associated mixnode per the entire interval.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "profit_margin_percent": { + "description": "The profit margin of the associated mixnode, i.e. the desired percent of the reward to be distributed to the operator.", + "allOf": [ + { + "$ref": "#/definitions/Percent" + } + ] + } + }, + "additionalProperties": false + }, + "PendingIntervalEventData": { + "description": "Details of a particular pending interval event.", + "type": "object", + "required": [ + "created_at", + "kind" + ], + "properties": { + "created_at": { + "description": "The block height at which the request has been made.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "kind": { + "description": "The underlying event data, containing its concrete type and information on how it should get resolved.", + "allOf": [ + { + "$ref": "#/definitions/PendingIntervalEventKind" + } + ] + } + }, + "additionalProperties": false + }, + "PendingIntervalEventKind": { + "description": "Enum encompassing all possible interval events.", + "oneOf": [ + { + "description": "Request to update cost parameters of given mixnode.", + "type": "object", + "required": [ + "change_mix_cost_params" + ], + "properties": { + "change_mix_cost_params": { + "type": "object", + "required": [ + "mix_id", + "new_costs" + ], + "properties": { + "mix_id": { + "description": "The id of the mixnode that will have its cost parameters updated.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "new_costs": { + "description": "The new updated cost function of this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeCostParams" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Request to update the underlying rewarding parameters used by the system", + "type": "object", + "required": [ + "update_rewarding_params" + ], + "properties": { + "update_rewarding_params": { + "type": "object", + "required": [ + "update" + ], + "properties": { + "update": { + "description": "The detailed specification of the update.", + "allOf": [ + { + "$ref": "#/definitions/IntervalRewardingParamsUpdate" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Request to change the next interval configuration.", + "type": "object", + "required": [ + "update_interval_config" + ], + "properties": { + "update_interval_config": { + "type": "object", + "required": [ + "epoch_duration_secs", + "epochs_in_interval" + ], + "properties": { + "epoch_duration_secs": { + "description": "The new epoch duration.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "epochs_in_interval": { + "description": "The new number of epochs in intervals.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Percent": { + "description": "Percent represents a value between 0 and 100% (i.e. between 0.0 and 1.0)", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_pending_interval_events.json b/contracts/mixnet/schema/raw/response_to_get_pending_interval_events.json new file mode 100644 index 0000000000..ccbdc22178 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_pending_interval_events.json @@ -0,0 +1,324 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PendingIntervalEventsResponse", + "description": "Response containing all currently pending interval events that will be resolved once the current interval finishes.", + "type": "object", + "required": [ + "events", + "seconds_until_executable" + ], + "properties": { + "events": { + "description": "The currently pending events.", + "type": "array", + "items": { + "$ref": "#/definitions/PendingIntervalEvent" + } + }, + "seconds_until_executable": { + "description": "Amount of seconds until the events would be eligible to be resolved. It's equivalent to the time until the current interval finishes.", + "type": "integer", + "format": "int64" + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "IntervalRewardingParamsUpdate": { + "description": "Specification on how the rewarding params should be updated.", + "type": "object", + "properties": { + "active_set_work_factor": { + "description": "Defines the new value of the active set work factor.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "interval_pool_emission": { + "description": "Defines the new value of the interval pool emission rate.", + "anyOf": [ + { + "$ref": "#/definitions/Percent" + }, + { + "type": "null" + } + ] + }, + "reward_pool": { + "description": "Defines the new value of the reward pool.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "rewarded_set_size": { + "description": "Defines the new size of the rewarded set.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "staking_supply": { + "description": "Defines the new value of the staking supply.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "staking_supply_scale_factor": { + "description": "Defines the new value of the staking supply scale factor.", + "anyOf": [ + { + "$ref": "#/definitions/Percent" + }, + { + "type": "null" + } + ] + }, + "sybil_resistance_percent": { + "description": "Defines the new value of the sybil resistance percent.", + "anyOf": [ + { + "$ref": "#/definitions/Percent" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "MixNodeCostParams": { + "description": "The cost parameters, or the cost function, defined for the particular mixnode that influences how the rewards should be split between the node operator and its delegators.", + "type": "object", + "required": [ + "interval_operating_cost", + "profit_margin_percent" + ], + "properties": { + "interval_operating_cost": { + "description": "Operating cost of the associated mixnode per the entire interval.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "profit_margin_percent": { + "description": "The profit margin of the associated mixnode, i.e. the desired percent of the reward to be distributed to the operator.", + "allOf": [ + { + "$ref": "#/definitions/Percent" + } + ] + } + }, + "additionalProperties": false + }, + "PendingIntervalEvent": { + "description": "A request made at some point in the current interval that's going to get resolved once the interval rolls over.", + "type": "object", + "required": [ + "event", + "id" + ], + "properties": { + "event": { + "description": "The underlying event details, containing its type and information on how it should get resolved.", + "allOf": [ + { + "$ref": "#/definitions/PendingIntervalEventData" + } + ] + }, + "id": { + "description": "The unique id associated with the event.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "PendingIntervalEventData": { + "description": "Details of a particular pending interval event.", + "type": "object", + "required": [ + "created_at", + "kind" + ], + "properties": { + "created_at": { + "description": "The block height at which the request has been made.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "kind": { + "description": "The underlying event data, containing its concrete type and information on how it should get resolved.", + "allOf": [ + { + "$ref": "#/definitions/PendingIntervalEventKind" + } + ] + } + }, + "additionalProperties": false + }, + "PendingIntervalEventKind": { + "description": "Enum encompassing all possible interval events.", + "oneOf": [ + { + "description": "Request to update cost parameters of given mixnode.", + "type": "object", + "required": [ + "change_mix_cost_params" + ], + "properties": { + "change_mix_cost_params": { + "type": "object", + "required": [ + "mix_id", + "new_costs" + ], + "properties": { + "mix_id": { + "description": "The id of the mixnode that will have its cost parameters updated.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "new_costs": { + "description": "The new updated cost function of this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/MixNodeCostParams" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Request to update the underlying rewarding parameters used by the system", + "type": "object", + "required": [ + "update_rewarding_params" + ], + "properties": { + "update_rewarding_params": { + "type": "object", + "required": [ + "update" + ], + "properties": { + "update": { + "description": "The detailed specification of the update.", + "allOf": [ + { + "$ref": "#/definitions/IntervalRewardingParamsUpdate" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Request to change the next interval configuration.", + "type": "object", + "required": [ + "update_interval_config" + ], + "properties": { + "update_interval_config": { + "type": "object", + "required": [ + "epoch_duration_secs", + "epochs_in_interval" + ], + "properties": { + "epoch_duration_secs": { + "description": "The new epoch duration.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "epochs_in_interval": { + "description": "The new number of epochs in intervals.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Percent": { + "description": "Percent represents a value between 0 and 100% (i.e. between 0.0 and 1.0)", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_pending_mix_node_operator_reward.json b/contracts/mixnet/schema/raw/response_to_get_pending_mix_node_operator_reward.json new file mode 100644 index 0000000000..e885d5976c --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_pending_mix_node_operator_reward.json @@ -0,0 +1,74 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PendingRewardResponse", + "description": "Response containing information about accrued rewards.", + "type": "object", + "required": [ + "mixnode_still_fully_bonded" + ], + "properties": { + "amount_earned": { + "description": "The amount of tokens that could be claimed.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + }, + "amount_earned_detailed": { + "description": "The full pending rewards. Note that it's nearly identical to `amount_earned`, however, it contains few additional decimal points for more accurate reward calculation.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "amount_staked": { + "description": "The amount of tokens initially staked.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + }, + "mixnode_still_fully_bonded": { + "description": "The associated mixnode is still fully bonded, meaning it is neither unbonded nor in the process of unbonding that would have finished at the epoch transition.", + "type": "boolean" + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_pending_operator_reward.json b/contracts/mixnet/schema/raw/response_to_get_pending_operator_reward.json new file mode 100644 index 0000000000..e885d5976c --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_pending_operator_reward.json @@ -0,0 +1,74 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PendingRewardResponse", + "description": "Response containing information about accrued rewards.", + "type": "object", + "required": [ + "mixnode_still_fully_bonded" + ], + "properties": { + "amount_earned": { + "description": "The amount of tokens that could be claimed.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + }, + "amount_earned_detailed": { + "description": "The full pending rewards. Note that it's nearly identical to `amount_earned`, however, it contains few additional decimal points for more accurate reward calculation.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "amount_staked": { + "description": "The amount of tokens initially staked.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + }, + "mixnode_still_fully_bonded": { + "description": "The associated mixnode is still fully bonded, meaning it is neither unbonded nor in the process of unbonding that would have finished at the epoch transition.", + "type": "boolean" + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_rewarded_set.json b/contracts/mixnet/schema/raw/response_to_get_rewarded_set.json new file mode 100644 index 0000000000..e623d3c1a8 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_rewarded_set.json @@ -0,0 +1,61 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedRewardedSetResponse", + "description": "Response containing paged list of all mixnodes in the rewarded set.", + "type": "object", + "required": [ + "nodes" + ], + "properties": { + "nodes": { + "description": "Nodes in the current rewarded set.", + "type": "array", + "items": { + "type": "array", + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "$ref": "#/definitions/RewardedSetNodeStatus" + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "RewardedSetNodeStatus": { + "description": "Current state of given node in the rewarded set.", + "oneOf": [ + { + "description": "Node that is currently active, i.e. is expected to be used by clients for mixing packets.", + "type": "string", + "enum": [ + "active" + ] + }, + { + "description": "Node that is currently in standby, i.e. it's present in the rewarded set but is not active.", + "type": "string", + "enum": [ + "standby" + ] + } + ] + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_rewarding_params.json b/contracts/mixnet/schema/raw/response_to_get_rewarding_params.json new file mode 100644 index 0000000000..8840bc31f2 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_rewarding_params.json @@ -0,0 +1,129 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "RewardingParams", + "description": "Parameters used for reward calculation.", + "type": "object", + "required": [ + "active_set_size", + "interval", + "rewarded_set_size" + ], + "properties": { + "active_set_size": { + "description": "The expected number of mixnodes in the active set.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "interval": { + "description": "Parameters that should remain unchanged throughout an interval.", + "allOf": [ + { + "$ref": "#/definitions/IntervalRewardParams" + } + ] + }, + "rewarded_set_size": { + "description": "The expected number of mixnodes in the rewarded set (i.e. active + standby).", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "IntervalRewardParams": { + "description": "Parameters required by the mix-mining reward distribution that do not change during an interval.", + "type": "object", + "required": [ + "active_set_work_factor", + "epoch_reward_budget", + "interval_pool_emission", + "reward_pool", + "stake_saturation_point", + "staking_supply", + "staking_supply_scale_factor", + "sybil_resistance" + ], + "properties": { + "active_set_work_factor": { + "description": "Current active set work factor. It is not really expected to be changing very often. As a matter of fact, unless there's a very specific reason, it should remain constant.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "epoch_reward_budget": { + "description": "Current value of the computed reward budget per epoch, per node. It is expected to be constant throughout the interval.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "interval_pool_emission": { + "description": "Current maximum interval pool emission. Assuming all nodes in the rewarded set are fully saturated and have 100% performance, this % of the reward pool would get distributed in rewards to all operators and its delegators. It is not really expected to be changing very often. As a matter of fact, unless there's a very specific reason, it should remain constant.", + "allOf": [ + { + "$ref": "#/definitions/Percent" + } + ] + }, + "reward_pool": { + "description": "Current value of the rewarding pool. It is expected to be constant throughout the interval.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "stake_saturation_point": { + "description": "Current value of the stake saturation point. It is expected to be constant throughout the interval.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "staking_supply": { + "description": "Current value of the staking supply. It is expected to be constant throughout the interval.", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "staking_supply_scale_factor": { + "description": "Defines the percentage of stake needed to reach saturation for all of the nodes in the rewarded set. Also known as `beta`.", + "allOf": [ + { + "$ref": "#/definitions/Percent" + } + ] + }, + "sybil_resistance": { + "description": "Current value of the sybil resistance percent (`alpha`). It is not really expected to be changing very often. As a matter of fact, unless there's a very specific reason, it should remain constant.", + "allOf": [ + { + "$ref": "#/definitions/Percent" + } + ] + } + }, + "additionalProperties": false + }, + "Percent": { + "description": "Percent represents a value between 0 and 100% (i.e. between 0.0 and 1.0)", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_rewarding_validator_address.json b/contracts/mixnet/schema/raw/response_to_get_rewarding_validator_address.json new file mode 100644 index 0000000000..f689acebfd --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_rewarding_validator_address.json @@ -0,0 +1,5 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "String", + "type": "string" +} diff --git a/contracts/mixnet/schema/raw/response_to_get_signing_nonce.json b/contracts/mixnet/schema/raw/response_to_get_signing_nonce.json new file mode 100644 index 0000000000..de85c3e56e --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_signing_nonce.json @@ -0,0 +1,7 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "uint32", + "type": "integer", + "format": "uint32", + "minimum": 0.0 +} diff --git a/contracts/mixnet/schema/raw/response_to_get_stake_saturation.json b/contracts/mixnet/schema/raw/response_to_get_stake_saturation.json new file mode 100644 index 0000000000..4a86c03934 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_stake_saturation.json @@ -0,0 +1,46 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "StakeSaturationResponse", + "description": "Response containing the current state of the stake saturation of a mixnode with the provided id.", + "type": "object", + "required": [ + "mix_id" + ], + "properties": { + "current_saturation": { + "description": "The current stake saturation of this node that is indirectly used in reward calculation formulas. Note that it can't be larger than 1.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + }, + "mix_id": { + "description": "Id of the requested mixnode.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "uncapped_saturation": { + "description": "The current, absolute, stake saturation of this node. Note that as the name suggests it can be larger than 1. However, anything beyond that value has no effect on the total node reward.", + "anyOf": [ + { + "$ref": "#/definitions/Decimal" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_state.json b/contracts/mixnet/schema/raw/response_to_get_state.json new file mode 100644 index 0000000000..0888e30787 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_state.json @@ -0,0 +1,115 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ContractState", + "description": "The current state of the mixnet contract.", + "type": "object", + "required": [ + "owner", + "params", + "rewarding_denom", + "rewarding_validator_address", + "vesting_contract_address" + ], + "properties": { + "owner": { + "description": "Address of the contract owner.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "params": { + "description": "Contract parameters that could be adjusted in a transaction the contract admin.", + "allOf": [ + { + "$ref": "#/definitions/ContractStateParams" + } + ] + }, + "rewarding_denom": { + "description": "The expected denom used for rewarding (and realistically any other operation). Default: `unym`", + "type": "string" + }, + "rewarding_validator_address": { + "description": "Address of \"rewarding validator\" (nym-api) that's allowed to send any rewarding-related transactions.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "vesting_contract_address": { + "description": "Address of the vesting contract to which the mixnet contract would be sending all track-related messages.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "ContractStateParams": { + "description": "Contract parameters that could be adjusted in a transaction by the contract admin.", + "type": "object", + "required": [ + "minimum_gateway_pledge", + "minimum_mixnode_pledge" + ], + "properties": { + "minimum_gateway_pledge": { + "description": "Minimum amount a gateway must pledge to get into the system.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "minimum_mixnode_delegation": { + "description": "Minimum amount a delegator must stake in orders for his delegation to get accepted.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + }, + "minimum_mixnode_pledge": { + "description": "Minimum amount a mixnode must pledge to get into the system.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_state_params.json b/contracts/mixnet/schema/raw/response_to_get_state_params.json new file mode 100644 index 0000000000..6e05de3035 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_state_params.json @@ -0,0 +1,61 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ContractStateParams", + "description": "Contract parameters that could be adjusted in a transaction by the contract admin.", + "type": "object", + "required": [ + "minimum_gateway_pledge", + "minimum_mixnode_pledge" + ], + "properties": { + "minimum_gateway_pledge": { + "description": "Minimum amount a gateway must pledge to get into the system.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "minimum_mixnode_delegation": { + "description": "Minimum amount a delegator must stake in orders for his delegation to get accepted.", + "anyOf": [ + { + "$ref": "#/definitions/Coin" + }, + { + "type": "null" + } + ] + }, + "minimum_mixnode_pledge": { + "description": "Minimum amount a mixnode must pledge to get into the system.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_unbonded_mix_node_information.json b/contracts/mixnet/schema/raw/response_to_get_unbonded_mix_node_information.json new file mode 100644 index 0000000000..9fa546e39c --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_unbonded_mix_node_information.json @@ -0,0 +1,76 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "UnbondedMixnodeResponse", + "description": "Response containing basic information of an unbonded mixnode with the provided id.", + "type": "object", + "required": [ + "mix_id" + ], + "properties": { + "mix_id": { + "description": "Id of the requested mixnode.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "unbonded_info": { + "description": "If there existed a mixnode with the provided id, this field contains its basic information.", + "anyOf": [ + { + "$ref": "#/definitions/UnbondedMixnode" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "UnbondedMixnode": { + "description": "Basic information of a node that used to be part of the mix network but has already unbonded.", + "type": "object", + "required": [ + "identity_key", + "owner", + "unbonding_height" + ], + "properties": { + "identity_key": { + "description": "Base58-encoded ed25519 EdDSA public key.", + "type": "string" + }, + "owner": { + "description": "Address of the owner of this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Entity who bonded this mixnode on behalf of the owner. If exists, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + }, + "unbonding_height": { + "description": "Block height at which this mixnode has unbonded.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_unbonded_mix_nodes.json b/contracts/mixnet/schema/raw/response_to_get_unbonded_mix_nodes.json new file mode 100644 index 0000000000..6209bcc677 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_unbonded_mix_nodes.json @@ -0,0 +1,94 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedUnbondedMixnodesResponse", + "description": "Response containing paged list of all mixnodes that have ever unbonded.", + "type": "object", + "required": [ + "nodes", + "per_page" + ], + "properties": { + "nodes": { + "description": "The past ids of unbonded mixnodes alongside their basic information such as the owner or the identity key.", + "type": "array", + "items": { + "type": "array", + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "$ref": "#/definitions/UnbondedMixnode" + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "per_page": { + "description": "Maximum number of entries that could be included in a response. `per_page <= nodes.len()`", + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "UnbondedMixnode": { + "description": "Basic information of a node that used to be part of the mix network but has already unbonded.", + "type": "object", + "required": [ + "identity_key", + "owner", + "unbonding_height" + ], + "properties": { + "identity_key": { + "description": "Base58-encoded ed25519 EdDSA public key.", + "type": "string" + }, + "owner": { + "description": "Address of the owner of this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Entity who bonded this mixnode on behalf of the owner. If exists, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + }, + "unbonding_height": { + "description": "Block height at which this mixnode has unbonded.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_unbonded_mix_nodes_by_identity_key.json b/contracts/mixnet/schema/raw/response_to_get_unbonded_mix_nodes_by_identity_key.json new file mode 100644 index 0000000000..6209bcc677 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_unbonded_mix_nodes_by_identity_key.json @@ -0,0 +1,94 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedUnbondedMixnodesResponse", + "description": "Response containing paged list of all mixnodes that have ever unbonded.", + "type": "object", + "required": [ + "nodes", + "per_page" + ], + "properties": { + "nodes": { + "description": "The past ids of unbonded mixnodes alongside their basic information such as the owner or the identity key.", + "type": "array", + "items": { + "type": "array", + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "$ref": "#/definitions/UnbondedMixnode" + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "per_page": { + "description": "Maximum number of entries that could be included in a response. `per_page <= nodes.len()`", + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "UnbondedMixnode": { + "description": "Basic information of a node that used to be part of the mix network but has already unbonded.", + "type": "object", + "required": [ + "identity_key", + "owner", + "unbonding_height" + ], + "properties": { + "identity_key": { + "description": "Base58-encoded ed25519 EdDSA public key.", + "type": "string" + }, + "owner": { + "description": "Address of the owner of this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Entity who bonded this mixnode on behalf of the owner. If exists, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + }, + "unbonding_height": { + "description": "Block height at which this mixnode has unbonded.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/mixnet/schema/raw/response_to_get_unbonded_mix_nodes_by_owner.json b/contracts/mixnet/schema/raw/response_to_get_unbonded_mix_nodes_by_owner.json new file mode 100644 index 0000000000..6209bcc677 --- /dev/null +++ b/contracts/mixnet/schema/raw/response_to_get_unbonded_mix_nodes_by_owner.json @@ -0,0 +1,94 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedUnbondedMixnodesResponse", + "description": "Response containing paged list of all mixnodes that have ever unbonded.", + "type": "object", + "required": [ + "nodes", + "per_page" + ], + "properties": { + "nodes": { + "description": "The past ids of unbonded mixnodes alongside their basic information such as the owner or the identity key.", + "type": "array", + "items": { + "type": "array", + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "$ref": "#/definitions/UnbondedMixnode" + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "per_page": { + "description": "Maximum number of entries that could be included in a response. `per_page <= nodes.len()`", + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "UnbondedMixnode": { + "description": "Basic information of a node that used to be part of the mix network but has already unbonded.", + "type": "object", + "required": [ + "identity_key", + "owner", + "unbonding_height" + ], + "properties": { + "identity_key": { + "description": "Base58-encoded ed25519 EdDSA public key.", + "type": "string" + }, + "owner": { + "description": "Address of the owner of this mixnode.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "proxy": { + "description": "Entity who bonded this mixnode on behalf of the owner. If exists, it's most likely the address of the vesting contract.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + }, + "unbonding_height": { + "description": "Block height at which this mixnode has unbonded.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/mixnet/src/bin/schema.rs b/contracts/mixnet/src/bin/schema.rs new file mode 100644 index 0000000000..c1e48ba16a --- /dev/null +++ b/contracts/mixnet/src/bin/schema.rs @@ -0,0 +1,14 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use cosmwasm_schema::write_api; +use mixnet_contract_common::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + query: QueryMsg, + execute: ExecuteMsg, + migrate: MigrateMsg, + } +} diff --git a/contracts/mixnet/src/contract.rs b/contracts/mixnet/src/contract.rs index f380b316f2..892f4d2298 100644 --- a/contracts/mixnet/src/contract.rs +++ b/contracts/mixnet/src/contract.rs @@ -404,12 +404,12 @@ pub fn query( to_binary(&crate::mixnet_contract_settings::queries::query_contract_version()) } QueryMsg::GetCW2ContractVersion {} => to_binary(&cw2::get_contract_version(deps.storage)?), - QueryMsg::GetStateParams {} => to_binary( - &crate::mixnet_contract_settings::queries::query_contract_settings_params(deps)?, - ), QueryMsg::GetRewardingValidatorAddress {} => to_binary( &crate::mixnet_contract_settings::queries::query_rewarding_validator_address(deps)?, ), + QueryMsg::GetStateParams {} => to_binary( + &crate::mixnet_contract_settings::queries::query_contract_settings_params(deps)?, + ), QueryMsg::GetState {} => { to_binary(&crate::mixnet_contract_settings::queries::query_contract_state(deps)?) } @@ -594,6 +594,8 @@ pub fn query( QueryMsg::GetNumberOfPendingEvents {} => to_binary( &crate::interval::queries::query_number_of_pending_events(deps)?, ), + + // signing-related QueryMsg::GetSigningNonce { address } => to_binary( &crate::signing::queries::query_current_signing_nonce(deps, address)?, ), diff --git a/contracts/mixnet/src/families/queries.rs b/contracts/mixnet/src/families/queries.rs index dc4799f0b9..96c7f79e23 100644 --- a/contracts/mixnet/src/families/queries.rs +++ b/contracts/mixnet/src/families/queries.rs @@ -1,47 +1,65 @@ // Copyright 2022-2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use super::storage::{families, get_family, get_members, MEMBERS}; +use super::storage::{families, get_members, must_get_family, MEMBERS}; use crate::constants::{FAMILIES_DEFAULT_RETRIEVAL_LIMIT, FAMILIES_MAX_RETRIEVAL_LIMIT}; +use crate::families::storage::must_get_family_by_label; use cosmwasm_std::{Order, Storage}; use cw_storage_plus::Bound; -use mixnet_contract_common::families::{Family, FamilyHead}; +use mixnet_contract_common::families::{ + Family, FamilyByHeadResponse, FamilyByLabelResponse, FamilyHead, FamilyMembersByHeadResponse, + PagedFamiliesResponse, PagedMembersResponse, +}; use mixnet_contract_common::{error::MixnetContractError, IdentityKeyRef}; -use mixnet_contract_common::{IdentityKey, PagedFamiliesResponse, PagedMembersResponse}; -use std::collections::HashSet; +use mixnet_contract_common::{FamilyMembersByLabelResponse, IdentityKey}; pub fn get_family_by_label( label: String, storage: &dyn Storage, -) -> Result, MixnetContractError> { - Ok(families().idx.label.item(storage, label)?.map(|o| o.1)) +) -> Result { + let family = families() + .idx + .label + .item(storage, label.clone())? + .map(|o| o.1); + Ok(FamilyByLabelResponse { label, family }) } pub fn get_family_by_head( head: IdentityKeyRef<'_>, storage: &dyn Storage, -) -> Result, MixnetContractError> { - Ok(families().may_load(storage, head.to_string())?) +) -> Result { + let family = families().may_load(storage, head.to_string())?; + Ok(FamilyByHeadResponse { + head: FamilyHead::new(head), + family, + }) } +// TODO: this should be returning a paged response! pub fn get_family_members_by_head( head: IdentityKeyRef<'_>, storage: &dyn Storage, -) -> Result, MixnetContractError> { +) -> Result { let family_head = FamilyHead::new(head); - let family = get_family(&family_head, storage)?; - get_members(&family, storage) + let family = must_get_family(&family_head, storage)?; + let members = get_members(&family, storage)?; + + Ok(FamilyMembersByHeadResponse { + head: family.head().to_owned(), + members, + }) } +// TODO: this should be returning a paged response! pub fn get_family_members_by_label( label: String, storage: &dyn Storage, -) -> Result>, MixnetContractError> { - if let Some(family) = families().idx.label.item(storage, label)?.map(|o| o.1) { - Ok(Some(get_members(&family, storage)?)) - } else { - Ok(None) - } +) -> Result { + let family = must_get_family_by_label(label.clone(), storage)?; + let members = get_members(&family, storage)?; + + Ok(FamilyMembersByLabelResponse { label, members }) } pub fn get_all_families_paged( diff --git a/contracts/mixnet/src/families/storage.rs b/contracts/mixnet/src/families/storage.rs index 1bdd421206..05b9566b7d 100644 --- a/contracts/mixnet/src/families/storage.rs +++ b/contracts/mixnet/src/families/storage.rs @@ -5,12 +5,13 @@ use cosmwasm_std::{Order, Storage}; use cw_storage_plus::{Index, IndexList, IndexedMap, Map, UniqueIndex}; use mixnet_contract_common::families::{Family, FamilyHead}; use mixnet_contract_common::{error::MixnetContractError, IdentityKey, IdentityKeyRef}; -use std::collections::HashSet; use crate::constants::{FAMILIES_INDEX_NAMESPACE, FAMILIES_MAP_NAMESPACE, MEMBERS_MAP_NAMESPACE}; +type FamilyHeadKey = IdentityKey; + pub struct FamilyIndex<'a> { - pub label: UniqueIndex<'a, String, Family>, + pub label: UniqueIndex<'a, FamilyHeadKey, Family>, } impl<'a> IndexList for FamilyIndex<'a> { @@ -21,7 +22,7 @@ impl<'a> IndexList for FamilyIndex<'a> { } // storage access function. -pub fn families<'a>() -> IndexedMap<'a, String, Family, FamilyIndex<'a>> { +pub fn families<'a>() -> IndexedMap<'a, FamilyHeadKey, Family, FamilyIndex<'a>> { let indexes = FamilyIndex { label: UniqueIndex::new(|d| d.label().to_string(), FAMILIES_INDEX_NAMESPACE), }; @@ -30,10 +31,11 @@ pub fn families<'a>() -> IndexedMap<'a, String, Family, FamilyIndex<'a>> { pub const MEMBERS: Map = Map::new(MEMBERS_MAP_NAMESPACE); +// TODO: this introduces an unbounded query. We should redesign it. pub fn get_members( family: &Family, store: &dyn Storage, -) -> Result, MixnetContractError> { +) -> Result, MixnetContractError> { Ok(MEMBERS .range(store, None, None, Order::Ascending) .filter_map(|res| res.ok()) @@ -42,15 +44,29 @@ pub fn get_members( .collect()) } -pub fn get_family(head: &FamilyHead, store: &dyn Storage) -> Result { +pub fn must_get_family( + head: &FamilyHead, + store: &dyn Storage, +) -> Result { let key = head.identity(); - if let Some(family) = families().may_load(store, key.to_string())? { - Ok(family) - } else { - Err(MixnetContractError::FamilyDoesNotExist { + + families() + .may_load(store, key.to_string())? + .ok_or(MixnetContractError::FamilyDoesNotExist { head: head.identity().to_string(), }) - } +} + +pub fn must_get_family_by_label( + label: String, + store: &dyn Storage, +) -> Result { + families() + .idx + .label + .item(store, label.clone())? + .map(|record| record.1) + .ok_or(MixnetContractError::FamilyLabelDoesNotExist { label }) } pub fn save_family(f: &Family, store: &mut dyn Storage) -> Result<(), MixnetContractError> { diff --git a/contracts/mixnet/src/families/transactions.rs b/contracts/mixnet/src/families/transactions.rs index 5a6a9b28e0..912cbc7146 100644 --- a/contracts/mixnet/src/families/transactions.rs +++ b/contracts/mixnet/src/families/transactions.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use super::storage::{ - add_family_member, get_family, is_any_member, is_family_member, remove_family_member, + add_family_member, is_any_member, is_family_member, must_get_family, remove_family_member, save_family, }; use crate::families::queries::get_family_by_label; @@ -48,12 +48,15 @@ fn _try_create_family( let family_head = FamilyHead::new(existing_bond.identity()); // can't overwrite existing family - if get_family(&family_head, deps.storage).is_ok() { + if must_get_family(&family_head, deps.storage).is_ok() { return Err(MixnetContractError::FamilyCanHaveOnlyOne); } // the label must be unique - if get_family_by_label(label.clone(), deps.storage)?.is_some() { + if get_family_by_label(label.clone(), deps.storage)? + .family + .is_some() + { return Err(MixnetContractError::FamilyWithLabelExists(label)); } @@ -118,7 +121,7 @@ fn _try_join_family( join_permit, )?; - let family = get_family(&family_head, deps.storage)?; + let family = must_get_family(&family_head, deps.storage)?; add_family_member(&family, deps.storage, existing_bond.identity())?; @@ -162,7 +165,7 @@ fn _try_leave_family( }); } - let family = get_family(&family_head, deps.storage)?; + let family = must_get_family(&family_head, deps.storage)?; if !is_family_member(deps.storage, &family, existing_bond.identity())? { return Err(MixnetContractError::NotAMember { head: family_head.identity().to_string(), @@ -215,7 +218,7 @@ fn _try_head_kick_member( // get the family details let family_head = FamilyHead::new(head_bond.identity()); - let family = get_family(&family_head, deps.storage)?; + let family = must_get_family(&family_head, deps.storage)?; // make sure the member we're trying to kick is an actual member if !is_family_member(deps.storage, &family, &member)? { @@ -290,7 +293,7 @@ mod test { try_create_family(test.deps_mut(), mock_info(head, &[]), "test".to_string()).unwrap(); let family_head = FamilyHead::new(&head_mixnode.identity_key); - assert!(get_family(&family_head, test.deps().storage).is_ok()); + assert!(must_get_family(&family_head, test.deps().storage).is_ok()); let nope = try_create_family( test.deps_mut(), @@ -306,12 +309,15 @@ mod test { }, } - let family = get_family_by_label("test".to_string(), test.deps().storage).unwrap(); + let family = get_family_by_label("test".to_string(), test.deps().storage) + .unwrap() + .family; assert!(family.is_some()); assert_eq!(family.unwrap().head_identity(), family_head.identity()); let family = get_family_by_head(family_head.identity(), test.deps().storage) .unwrap() + .family .unwrap(); assert_eq!(family.head_identity(), family_head.identity()); @@ -326,7 +332,7 @@ mod test { ) .unwrap(); - let family = get_family(&family_head, test.deps().storage).unwrap(); + let family = must_get_family(&family_head, test.deps().storage).unwrap(); assert!( is_family_member(test.deps().storage, &family, &member_mixnode.identity_key).unwrap() @@ -334,7 +340,7 @@ mod test { try_leave_family(test.deps_mut(), mock_info(member, &[]), family_head.clone()).unwrap(); - let family = get_family(&family_head, test.deps().storage).unwrap(); + let family = must_get_family(&family_head, test.deps().storage).unwrap(); assert!( !is_family_member(test.deps().storage, &family, &member_mixnode.identity_key).unwrap() ); @@ -350,7 +356,7 @@ mod test { ) .unwrap(); - let family = get_family(&family_head, test.deps().storage).unwrap(); + let family = must_get_family(&family_head, test.deps().storage).unwrap(); assert!( is_family_member(test.deps().storage, &family, &member_mixnode.identity_key).unwrap() @@ -363,7 +369,7 @@ mod test { ) .unwrap(); - let family = get_family(&family_head, test.deps().storage).unwrap(); + let family = must_get_family(&family_head, test.deps().storage).unwrap(); assert!( !is_family_member(test.deps().storage, &family, &member_mixnode.identity_key).unwrap() ); @@ -429,7 +435,7 @@ mod test { ); let head_identity = head_keys.public_key().to_base58_string(); - let family_head = FamilyHead::new(&head_identity); + let family_head = FamilyHead::new(head_identity); let res = try_join_family_on_behalf( test.deps_mut(), mock_info(illegal_proxy.as_ref(), &[]), @@ -475,7 +481,7 @@ mod test { ); let head_identity = head_keys.public_key().to_base58_string(); - let family_head = FamilyHead::new(&head_identity); + let family_head = FamilyHead::new(head_identity); try_join_family_on_behalf( test.deps_mut(), mock_info(vesting_contract.as_ref(), &[]), @@ -529,7 +535,7 @@ mod test { ); let head_identity = head_keys.public_key().to_base58_string(); - let family_head = FamilyHead::new(&head_identity); + let family_head = FamilyHead::new(head_identity); try_join_family_on_behalf( test.deps_mut(), diff --git a/contracts/mixnet/src/mixnodes/queries.rs b/contracts/mixnet/src/mixnodes/queries.rs index 5bf845c4a9..5d7b61054d 100644 --- a/contracts/mixnet/src/mixnodes/queries.rs +++ b/contracts/mixnet/src/mixnodes/queries.rs @@ -19,8 +19,8 @@ use mixnet_contract_common::mixnode::{ PagedUnbondedMixnodesResponse, StakeSaturationResponse, UnbondedMixnodeResponse, }; use mixnet_contract_common::{ - IdentityKey, LayerDistribution, MixId, MixOwnershipResponse, MixnodeDetailsResponse, - PagedMixnodeBondsResponse, + IdentityKey, LayerDistribution, MixId, MixOwnershipResponse, MixnodeDetailsByIdentityResponse, + MixnodeDetailsResponse, PagedMixnodeBondsResponse, }; pub fn query_mixnode_bonds_paged( @@ -189,12 +189,16 @@ pub fn query_mixnode_details(deps: Deps<'_>, mix_id: MixId) -> StdResult, - mix_identity: IdentityKey, -) -> StdResult> { - get_mixnode_details_by_identity(deps.storage, mix_identity) + identity_key: IdentityKey, +) -> StdResult { + let mixnode_details = get_mixnode_details_by_identity(deps.storage, identity_key.clone())?; + + Ok(MixnodeDetailsByIdentityResponse { + identity_key, + mixnode_details, + }) } pub fn query_mixnode_rewarding_details( @@ -1110,7 +1114,9 @@ pub(crate) mod tests { let mut test = TestSetup::new(); // no node under this identity - let res = query_mixnode_details_by_identity(test.deps(), "foomp".into()).unwrap(); + let res = query_mixnode_details_by_identity(test.deps(), "foomp".into()) + .unwrap() + .mixnode_details; assert!(res.is_none()); // it exists @@ -1122,7 +1128,9 @@ pub(crate) mod tests { .unwrap(); let mix_identity = expected.bond_information.identity(); - let res = query_mixnode_details_by_identity(test.deps(), mix_identity.into()).unwrap(); + let res = query_mixnode_details_by_identity(test.deps(), mix_identity.into()) + .unwrap() + .mixnode_details; assert_eq!(expected, res.unwrap()); } diff --git a/contracts/mixnet/src/support/tests/mod.rs b/contracts/mixnet/src/support/tests/mod.rs index 6b0e838a1a..851d394bfe 100644 --- a/contracts/mixnet/src/support/tests/mod.rs +++ b/contracts/mixnet/src/support/tests/mod.rs @@ -224,7 +224,7 @@ pub mod test_helpers { let join_permit = self.generate_family_join_permit(head_keys, &member_identity, vesting); - let family_head = FamilyHead::new(&head_identity); + let family_head = FamilyHead::new(head_identity); try_join_family( self.deps_mut(), diff --git a/contracts/multisig/cw3-flex-multisig/.cargo/config b/contracts/multisig/cw3-flex-multisig/.cargo/config index 8d4bc738b1..dbc331ef7a 100644 --- a/contracts/multisig/cw3-flex-multisig/.cargo/config +++ b/contracts/multisig/cw3-flex-multisig/.cargo/config @@ -1,6 +1,6 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" unit-test = "test --lib" integration-test = "test --test integration" -schema = "run --example schema" +schema = "run --bin schema --features=schema-gen" \ No newline at end of file diff --git a/contracts/multisig/cw3-flex-multisig/Cargo.toml b/contracts/multisig/cw3-flex-multisig/Cargo.toml index b849828069..bd0e980bde 100644 --- a/contracts/multisig/cw3-flex-multisig/Cargo.toml +++ b/contracts/multisig/cw3-flex-multisig/Cargo.toml @@ -9,6 +9,10 @@ repository = "https://github.com/CosmWasm/cw-plus" homepage = "https://cosmwasm.com" documentation = "https://docs.cosmwasm.com" +[[bin]] +name = "schema" +required-features = ["schema-gen"] + [lib] crate-type = ["cdylib", "rlib"] @@ -16,6 +20,7 @@ crate-type = ["cdylib", "rlib"] backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] +schema-gen = ["cosmwasm-schema"] [dependencies] cw-utils = { workspace = true } @@ -25,8 +30,8 @@ cw3-fixed-multisig = { workspace = true, features = ["library"] } cw4 = { workspace = true } cw20 = { workspace = true } cw-storage-plus = { workspace = true } +cosmwasm-schema = { workspace = true, optional = true } cosmwasm-std = { workspace = true } -schemars = "0.8.1" nym-group-contract-common = { path = "../../../common/cosmwasm-smart-contracts/group-contract" } nym-multisig-contract-common = { path= "../../../common/cosmwasm-smart-contracts/multisig-contract" } diff --git a/contracts/multisig/cw3-flex-multisig/Makefile b/contracts/multisig/cw3-flex-multisig/Makefile new file mode 100644 index 0000000000..f138e2c879 --- /dev/null +++ b/contracts/multisig/cw3-flex-multisig/Makefile @@ -0,0 +1,2 @@ +generate-schema: + cargo schema \ No newline at end of file diff --git a/contracts/multisig/cw3-flex-multisig/schema/cw3-flex-multisig.json b/contracts/multisig/cw3-flex-multisig/schema/cw3-flex-multisig.json new file mode 100644 index 0000000000..7f49430331 --- /dev/null +++ b/contracts/multisig/cw3-flex-multisig/schema/cw3-flex-multisig.json @@ -0,0 +1,5201 @@ +{ + "contract_name": "cw3-flex-multisig", + "contract_version": "1.0.0", + "idl_version": "1.0.0", + "instantiate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "coconut_bandwidth_contract_address", + "coconut_dkg_contract_address", + "group_addr", + "max_voting_period", + "threshold" + ], + "properties": { + "coconut_bandwidth_contract_address": { + "type": "string" + }, + "coconut_dkg_contract_address": { + "type": "string" + }, + "executor": { + "anyOf": [ + { + "$ref": "#/definitions/Executor" + }, + { + "type": "null" + } + ] + }, + "group_addr": { + "type": "string" + }, + "max_voting_period": { + "$ref": "#/definitions/Duration" + }, + "proposal_deposit": { + "description": "The cost of creating a proposal (if any).", + "anyOf": [ + { + "$ref": "#/definitions/UncheckedDepositInfo" + }, + { + "type": "null" + } + ] + }, + "threshold": { + "$ref": "#/definitions/Threshold" + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Duration": { + "description": "Duration is a delta of time. You can add it to a BlockInfo or Expiration to move that further in the future. Note that an height-based Duration and a time-based Expiration cannot be combined", + "oneOf": [ + { + "type": "object", + "required": [ + "height" + ], + "properties": { + "height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "Time in seconds", + "type": "object", + "required": [ + "time" + ], + "properties": { + "time": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + ] + }, + "Executor": { + "description": "Defines who is able to execute proposals once passed", + "oneOf": [ + { + "description": "Any member of the voting group, even with 0 points", + "type": "string", + "enum": [ + "member" + ] + }, + { + "description": "Only the given address", + "type": "object", + "required": [ + "only" + ], + "properties": { + "only": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + ] + }, + "Threshold": { + "description": "This defines the different ways tallies can happen.\n\nThe total_weight used for calculating success as well as the weights of each individual voter used in tallying should be snapshotted at the beginning of the block at which the proposal starts (this is likely the responsibility of a correct cw4 implementation). See also `ThresholdResponse` in the cw3 spec.", + "oneOf": [ + { + "description": "Declares that a fixed weight of Yes votes is needed to pass. See `ThresholdResponse.AbsoluteCount` in the cw3 spec for details.", + "type": "object", + "required": [ + "absolute_count" + ], + "properties": { + "absolute_count": { + "type": "object", + "required": [ + "weight" + ], + "properties": { + "weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Declares a percentage of the total weight that must cast Yes votes in order for a proposal to pass. See `ThresholdResponse.AbsolutePercentage` in the cw3 spec for details.", + "type": "object", + "required": [ + "absolute_percentage" + ], + "properties": { + "absolute_percentage": { + "type": "object", + "required": [ + "percentage" + ], + "properties": { + "percentage": { + "$ref": "#/definitions/Decimal" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Declares a `quorum` of the total votes that must participate in the election in order for the vote to be considered at all. See `ThresholdResponse.ThresholdQuorum` in the cw3 spec for details.", + "type": "object", + "required": [ + "threshold_quorum" + ], + "properties": { + "threshold_quorum": { + "type": "object", + "required": [ + "quorum", + "threshold" + ], + "properties": { + "quorum": { + "$ref": "#/definitions/Decimal" + }, + "threshold": { + "$ref": "#/definitions/Decimal" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "UncheckedDenom": { + "oneOf": [ + { + "type": "object", + "required": [ + "native" + ], + "properties": { + "native": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "cw20" + ], + "properties": { + "cw20": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "UncheckedDepositInfo": { + "description": "Information about the deposit required to create a proposal. For use in messages. To validate, transform into `DepositInfo` via `into_checked()`.", + "type": "object", + "required": [ + "amount", + "denom", + "refund_failed_proposals" + ], + "properties": { + "amount": { + "description": "The number tokens required for payment.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "denom": { + "description": "The denom of the deposit payment.", + "allOf": [ + { + "$ref": "#/definitions/UncheckedDenom" + } + ] + }, + "refund_failed_proposals": { + "description": "Should failed proposals have their deposits refunded?", + "type": "boolean" + } + }, + "additionalProperties": false + } + } + }, + "execute": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "propose" + ], + "properties": { + "propose": { + "type": "object", + "required": [ + "description", + "msgs", + "title" + ], + "properties": { + "description": { + "type": "string" + }, + "latest": { + "anyOf": [ + { + "$ref": "#/definitions/Expiration" + }, + { + "type": "null" + } + ] + }, + "msgs": { + "type": "array", + "items": { + "$ref": "#/definitions/CosmosMsg_for_Empty" + } + }, + "title": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "vote" + ], + "properties": { + "vote": { + "type": "object", + "required": [ + "proposal_id", + "vote" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "vote": { + "$ref": "#/definitions/Vote" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "execute" + ], + "properties": { + "execute": { + "type": "object", + "required": [ + "proposal_id" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "close" + ], + "properties": { + "close": { + "type": "object", + "required": [ + "proposal_id" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Handles update hook messages from the group contract", + "type": "object", + "required": [ + "member_changed_hook" + ], + "properties": { + "member_changed_hook": { + "$ref": "#/definitions/MemberChangedHookMsg" + } + }, + "additionalProperties": false + } + ], + "definitions": { + "BankMsg": { + "description": "The message types of the bank module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto", + "oneOf": [ + { + "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "send" + ], + "properties": { + "send": { + "type": "object", + "required": [ + "amount", + "to_address" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "to_address": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", + "type": "object", + "required": [ + "burn" + ], + "properties": { + "burn": { + "type": "object", + "required": [ + "amount" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "CosmosMsg_for_Empty": { + "oneOf": [ + { + "type": "object", + "required": [ + "bank" + ], + "properties": { + "bank": { + "$ref": "#/definitions/BankMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "custom" + ], + "properties": { + "custom": { + "$ref": "#/definitions/Empty" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "staking" + ], + "properties": { + "staking": { + "$ref": "#/definitions/StakingMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "distribution" + ], + "properties": { + "distribution": { + "$ref": "#/definitions/DistributionMsg" + } + }, + "additionalProperties": false + }, + { + "description": "A Stargate message encoded the same way as a protobuf [Any](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto). This is the same structure as messages in `TxBody` from [ADR-020](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-020-protobuf-transaction-encoding.md)", + "type": "object", + "required": [ + "stargate" + ], + "properties": { + "stargate": { + "type": "object", + "required": [ + "type_url", + "value" + ], + "properties": { + "type_url": { + "type": "string" + }, + "value": { + "$ref": "#/definitions/Binary" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "ibc" + ], + "properties": { + "ibc": { + "$ref": "#/definitions/IbcMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "wasm" + ], + "properties": { + "wasm": { + "$ref": "#/definitions/WasmMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "gov" + ], + "properties": { + "gov": { + "$ref": "#/definitions/GovMsg" + } + }, + "additionalProperties": false + } + ] + }, + "DistributionMsg": { + "description": "The message types of the distribution module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto", + "oneOf": [ + { + "description": "This is translated to a [MsgSetWithdrawAddress](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L29-L37). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "set_withdraw_address" + ], + "properties": { + "set_withdraw_address": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "The `withdraw_address`", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [[MsgWithdrawDelegatorReward](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L42-L50). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "withdraw_delegator_reward" + ], + "properties": { + "withdraw_delegator_reward": { + "type": "object", + "required": [ + "validator" + ], + "properties": { + "validator": { + "description": "The `validator_address`", + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Empty": { + "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", + "type": "object" + }, + "Expiration": { + "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", + "oneOf": [ + { + "description": "AtHeight will expire when `env.block.height` >= height", + "type": "object", + "required": [ + "at_height" + ], + "properties": { + "at_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "AtTime will expire when `env.block.time` >= time", + "type": "object", + "required": [ + "at_time" + ], + "properties": { + "at_time": { + "$ref": "#/definitions/Timestamp" + } + }, + "additionalProperties": false + }, + { + "description": "Never will never expire. Used to express the empty variant", + "type": "object", + "required": [ + "never" + ], + "properties": { + "never": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "GovMsg": { + "description": "This message type allows the contract interact with the [x/gov] module in order to cast votes.\n\n[x/gov]: https://github.com/cosmos/cosmos-sdk/tree/v0.45.12/x/gov\n\n## Examples\n\nCast a simple vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); use cosmwasm_std::{GovMsg, VoteOption};\n\n#[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::Vote { proposal_id: 4, vote: VoteOption::Yes, })) } ```\n\nCast a weighted vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); # #[cfg(feature = \"cosmwasm_1_2\")] use cosmwasm_std::{Decimal, GovMsg, VoteOption, WeightedVoteOption};\n\n# #[cfg(feature = \"cosmwasm_1_2\")] #[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::VoteWeighted { proposal_id: 4, options: vec![ WeightedVoteOption { option: VoteOption::Yes, weight: Decimal::percent(65), }, WeightedVoteOption { option: VoteOption::Abstain, weight: Decimal::percent(35), }, ], })) } ```", + "oneOf": [ + { + "description": "This maps directly to [MsgVote](https://github.com/cosmos/cosmos-sdk/blob/v0.42.5/proto/cosmos/gov/v1beta1/tx.proto#L46-L56) in the Cosmos SDK with voter set to the contract address.", + "type": "object", + "required": [ + "vote" + ], + "properties": { + "vote": { + "type": "object", + "required": [ + "proposal_id", + "vote" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "vote": { + "description": "The vote option.\n\nThis should be called \"option\" for consistency with Cosmos SDK. Sorry for that. See .", + "allOf": [ + { + "$ref": "#/definitions/VoteOption" + } + ] + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcMsg": { + "description": "These are messages in the IBC lifecycle. Only usable by IBC-enabled contracts (contracts that directly speak the IBC protocol via 6 entry points)", + "oneOf": [ + { + "description": "Sends bank tokens owned by the contract to the given address on another chain. The channel must already be established between the ibctransfer module on this chain and a matching module on the remote chain. We cannot select the port_id, this is whatever the local chain has bound the ibctransfer module to.", + "type": "object", + "required": [ + "transfer" + ], + "properties": { + "transfer": { + "type": "object", + "required": [ + "amount", + "channel_id", + "timeout", + "to_address" + ], + "properties": { + "amount": { + "description": "packet data only supports one coin https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/ibc/applications/transfer/v1/transfer.proto#L11-L20", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "channel_id": { + "description": "exisiting channel to send the tokens over", + "type": "string" + }, + "timeout": { + "description": "when packet times out, measured on remote chain", + "allOf": [ + { + "$ref": "#/definitions/IbcTimeout" + } + ] + }, + "to_address": { + "description": "address on the remote chain to receive these tokens", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Sends an IBC packet with given data over the existing channel. Data should be encoded in a format defined by the channel version, and the module on the other side should know how to parse this.", + "type": "object", + "required": [ + "send_packet" + ], + "properties": { + "send_packet": { + "type": "object", + "required": [ + "channel_id", + "data", + "timeout" + ], + "properties": { + "channel_id": { + "type": "string" + }, + "data": { + "$ref": "#/definitions/Binary" + }, + "timeout": { + "description": "when packet times out, measured on remote chain", + "allOf": [ + { + "$ref": "#/definitions/IbcTimeout" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This will close an existing channel that is owned by this contract. Port is auto-assigned to the contract's IBC port", + "type": "object", + "required": [ + "close_channel" + ], + "properties": { + "close_channel": { + "type": "object", + "required": [ + "channel_id" + ], + "properties": { + "channel_id": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcTimeout": { + "description": "In IBC each package must set at least one type of timeout: the timestamp or the block height. Using this rather complex enum instead of two timeout fields we ensure that at least one timeout is set.", + "type": "object", + "properties": { + "block": { + "anyOf": [ + { + "$ref": "#/definitions/IbcTimeoutBlock" + }, + { + "type": "null" + } + ] + }, + "timestamp": { + "anyOf": [ + { + "$ref": "#/definitions/Timestamp" + }, + { + "type": "null" + } + ] + } + } + }, + "IbcTimeoutBlock": { + "description": "IBCTimeoutHeight Height is a monotonically increasing data type that can be compared against another Height for the purposes of updating and freezing clients. Ordering is (revision_number, timeout_height)", + "type": "object", + "required": [ + "height", + "revision" + ], + "properties": { + "height": { + "description": "block height after which the packet times out. the height within the given revision", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "revision": { + "description": "the version that the client is currently on (eg. after reseting the chain this could increment 1 as height drops to 0)", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + }, + "MemberChangedHookMsg": { + "description": "MemberChangedHookMsg should be de/serialized under `MemberChangedHook()` variant in a ExecuteMsg. This contains a list of all diffs on the given transaction.", + "type": "object", + "required": [ + "diffs" + ], + "properties": { + "diffs": { + "type": "array", + "items": { + "$ref": "#/definitions/MemberDiff" + } + } + }, + "additionalProperties": false + }, + "MemberDiff": { + "description": "MemberDiff shows the old and new states for a given cw4 member They cannot both be None. old = None, new = Some -> Insert old = Some, new = Some -> Update old = Some, new = None -> Delete", + "type": "object", + "required": [ + "key" + ], + "properties": { + "key": { + "type": "string" + }, + "new": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + }, + "old": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "StakingMsg": { + "description": "The message types of the staking module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto", + "oneOf": [ + { + "description": "This is translated to a [MsgDelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L81-L90). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "delegate" + ], + "properties": { + "delegate": { + "type": "object", + "required": [ + "amount", + "validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [MsgUndelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L112-L121). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "undelegate" + ], + "properties": { + "undelegate": { + "type": "object", + "required": [ + "amount", + "validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [MsgBeginRedelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L95-L105). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "redelegate" + ], + "properties": { + "redelegate": { + "type": "object", + "required": [ + "amount", + "dst_validator", + "src_validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "dst_validator": { + "type": "string" + }, + "src_validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + }, + "Vote": { + "oneOf": [ + { + "description": "Marks support for the proposal.", + "type": "string", + "enum": [ + "yes" + ] + }, + { + "description": "Marks opposition to the proposal.", + "type": "string", + "enum": [ + "no" + ] + }, + { + "description": "Marks participation but does not count towards the ratio of support / opposed", + "type": "string", + "enum": [ + "abstain" + ] + }, + { + "description": "Veto is generally to be treated as a No vote. Some implementations may allow certain voters to be able to Veto, or them to be counted stronger than No in some way.", + "type": "string", + "enum": [ + "veto" + ] + } + ] + }, + "VoteOption": { + "type": "string", + "enum": [ + "yes", + "no", + "abstain", + "no_with_veto" + ] + }, + "WasmMsg": { + "description": "The message types of the wasm module.\n\nSee https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto", + "oneOf": [ + { + "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L68-L78). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "execute" + ], + "properties": { + "execute": { + "type": "object", + "required": [ + "contract_addr", + "funds", + "msg" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "msg": { + "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThe contract address is non-predictable. But it is guaranteed that when emitting the same Instantiate message multiple times, multiple instances on different addresses will be generated. See also Instantiate2.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/CosmWasm/wasmd/blob/v0.29.2/proto/cosmwasm/wasm/v1/tx.proto#L53-L71). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "instantiate" + ], + "properties": { + "instantiate": { + "type": "object", + "required": [ + "code_id", + "funds", + "label", + "msg" + ], + "properties": { + "admin": { + "type": [ + "string", + "null" + ] + }, + "code_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "label": { + "description": "A human-readbale label for the contract", + "type": "string" + }, + "msg": { + "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "migrate" + ], + "properties": { + "migrate": { + "type": "object", + "required": [ + "contract_addr", + "msg", + "new_code_id" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "msg": { + "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + }, + "new_code_id": { + "description": "the code_id of the new logic to place in the given contract", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", + "type": "object", + "required": [ + "update_admin" + ], + "properties": { + "update_admin": { + "type": "object", + "required": [ + "admin", + "contract_addr" + ], + "properties": { + "admin": { + "type": "string" + }, + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", + "type": "object", + "required": [ + "clear_admin" + ], + "properties": { + "clear_admin": { + "type": "object", + "required": [ + "contract_addr" + ], + "properties": { + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + } + } + }, + "query": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "threshold" + ], + "properties": { + "threshold": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "proposal" + ], + "properties": { + "proposal": { + "type": "object", + "required": [ + "proposal_id" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "list_proposals" + ], + "properties": { + "list_proposals": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "reverse_proposals" + ], + "properties": { + "reverse_proposals": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_before": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "vote" + ], + "properties": { + "vote": { + "type": "object", + "required": [ + "proposal_id", + "voter" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "voter": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "list_votes" + ], + "properties": { + "list_votes": { + "type": "object", + "required": [ + "proposal_id" + ], + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "voter" + ], + "properties": { + "voter": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "list_voters" + ], + "properties": { + "list_voters": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the current configuration.", + "type": "object", + "required": [ + "config" + ], + "properties": { + "config": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "migrate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "type": "object", + "required": [ + "coconut_bandwidth_address", + "coconut_dkg_address" + ], + "properties": { + "coconut_bandwidth_address": { + "type": "string" + }, + "coconut_dkg_address": { + "type": "string" + } + }, + "additionalProperties": false + }, + "sudo": null, + "responses": { + "config": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Config", + "type": "object", + "required": [ + "coconut_bandwidth_addr", + "coconut_dkg_addr", + "group_addr", + "max_voting_period", + "threshold" + ], + "properties": { + "coconut_bandwidth_addr": { + "$ref": "#/definitions/Addr" + }, + "coconut_dkg_addr": { + "$ref": "#/definitions/Addr" + }, + "executor": { + "anyOf": [ + { + "$ref": "#/definitions/Executor" + }, + { + "type": "null" + } + ] + }, + "group_addr": { + "$ref": "#/definitions/Cw4Contract" + }, + "max_voting_period": { + "$ref": "#/definitions/Duration" + }, + "proposal_deposit": { + "description": "The price, if any, of creating a new proposal.", + "anyOf": [ + { + "$ref": "#/definitions/DepositInfo" + }, + { + "type": "null" + } + ] + }, + "threshold": { + "$ref": "#/definitions/Threshold" + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Cw4Contract": { + "description": "Cw4Contract is a wrapper around Addr that provides a lot of helpers for working with cw4 contracts\n\nIf you wish to persist this, convert to Cw4CanonicalContract via .canonical()", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Denom": { + "oneOf": [ + { + "type": "object", + "required": [ + "native" + ], + "properties": { + "native": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "cw20" + ], + "properties": { + "cw20": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + ] + }, + "DepositInfo": { + "description": "Information about the deposit required to create a proposal.", + "type": "object", + "required": [ + "amount", + "denom", + "refund_failed_proposals" + ], + "properties": { + "amount": { + "description": "The number tokens required for payment.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "denom": { + "description": "The denom of the deposit payment.", + "allOf": [ + { + "$ref": "#/definitions/Denom" + } + ] + }, + "refund_failed_proposals": { + "description": "Should failed proposals have their deposits refunded?", + "type": "boolean" + } + }, + "additionalProperties": false + }, + "Duration": { + "description": "Duration is a delta of time. You can add it to a BlockInfo or Expiration to move that further in the future. Note that an height-based Duration and a time-based Expiration cannot be combined", + "oneOf": [ + { + "type": "object", + "required": [ + "height" + ], + "properties": { + "height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "Time in seconds", + "type": "object", + "required": [ + "time" + ], + "properties": { + "time": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + ] + }, + "Executor": { + "description": "Defines who is able to execute proposals once passed", + "oneOf": [ + { + "description": "Any member of the voting group, even with 0 points", + "type": "string", + "enum": [ + "member" + ] + }, + { + "description": "Only the given address", + "type": "object", + "required": [ + "only" + ], + "properties": { + "only": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + ] + }, + "Threshold": { + "description": "This defines the different ways tallies can happen.\n\nThe total_weight used for calculating success as well as the weights of each individual voter used in tallying should be snapshotted at the beginning of the block at which the proposal starts (this is likely the responsibility of a correct cw4 implementation). See also `ThresholdResponse` in the cw3 spec.", + "oneOf": [ + { + "description": "Declares that a fixed weight of Yes votes is needed to pass. See `ThresholdResponse.AbsoluteCount` in the cw3 spec for details.", + "type": "object", + "required": [ + "absolute_count" + ], + "properties": { + "absolute_count": { + "type": "object", + "required": [ + "weight" + ], + "properties": { + "weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Declares a percentage of the total weight that must cast Yes votes in order for a proposal to pass. See `ThresholdResponse.AbsolutePercentage` in the cw3 spec for details.", + "type": "object", + "required": [ + "absolute_percentage" + ], + "properties": { + "absolute_percentage": { + "type": "object", + "required": [ + "percentage" + ], + "properties": { + "percentage": { + "$ref": "#/definitions/Decimal" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Declares a `quorum` of the total votes that must participate in the election in order for the vote to be considered at all. See `ThresholdResponse.ThresholdQuorum` in the cw3 spec for details.", + "type": "object", + "required": [ + "threshold_quorum" + ], + "properties": { + "threshold_quorum": { + "type": "object", + "required": [ + "quorum", + "threshold" + ], + "properties": { + "quorum": { + "$ref": "#/definitions/Decimal" + }, + "threshold": { + "$ref": "#/definitions/Decimal" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "list_proposals": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ProposalListResponse_for_Empty", + "type": "object", + "required": [ + "proposals" + ], + "properties": { + "proposals": { + "type": "array", + "items": { + "$ref": "#/definitions/ProposalResponse_for_Empty" + } + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "BankMsg": { + "description": "The message types of the bank module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto", + "oneOf": [ + { + "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "send" + ], + "properties": { + "send": { + "type": "object", + "required": [ + "amount", + "to_address" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "to_address": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", + "type": "object", + "required": [ + "burn" + ], + "properties": { + "burn": { + "type": "object", + "required": [ + "amount" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "CosmosMsg_for_Empty": { + "oneOf": [ + { + "type": "object", + "required": [ + "bank" + ], + "properties": { + "bank": { + "$ref": "#/definitions/BankMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "custom" + ], + "properties": { + "custom": { + "$ref": "#/definitions/Empty" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "staking" + ], + "properties": { + "staking": { + "$ref": "#/definitions/StakingMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "distribution" + ], + "properties": { + "distribution": { + "$ref": "#/definitions/DistributionMsg" + } + }, + "additionalProperties": false + }, + { + "description": "A Stargate message encoded the same way as a protobuf [Any](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto). This is the same structure as messages in `TxBody` from [ADR-020](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-020-protobuf-transaction-encoding.md)", + "type": "object", + "required": [ + "stargate" + ], + "properties": { + "stargate": { + "type": "object", + "required": [ + "type_url", + "value" + ], + "properties": { + "type_url": { + "type": "string" + }, + "value": { + "$ref": "#/definitions/Binary" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "ibc" + ], + "properties": { + "ibc": { + "$ref": "#/definitions/IbcMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "wasm" + ], + "properties": { + "wasm": { + "$ref": "#/definitions/WasmMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "gov" + ], + "properties": { + "gov": { + "$ref": "#/definitions/GovMsg" + } + }, + "additionalProperties": false + } + ] + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Denom": { + "oneOf": [ + { + "type": "object", + "required": [ + "native" + ], + "properties": { + "native": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "cw20" + ], + "properties": { + "cw20": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + ] + }, + "DepositInfo": { + "description": "Information about the deposit required to create a proposal.", + "type": "object", + "required": [ + "amount", + "denom", + "refund_failed_proposals" + ], + "properties": { + "amount": { + "description": "The number tokens required for payment.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "denom": { + "description": "The denom of the deposit payment.", + "allOf": [ + { + "$ref": "#/definitions/Denom" + } + ] + }, + "refund_failed_proposals": { + "description": "Should failed proposals have their deposits refunded?", + "type": "boolean" + } + }, + "additionalProperties": false + }, + "DistributionMsg": { + "description": "The message types of the distribution module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto", + "oneOf": [ + { + "description": "This is translated to a [MsgSetWithdrawAddress](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L29-L37). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "set_withdraw_address" + ], + "properties": { + "set_withdraw_address": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "The `withdraw_address`", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [[MsgWithdrawDelegatorReward](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L42-L50). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "withdraw_delegator_reward" + ], + "properties": { + "withdraw_delegator_reward": { + "type": "object", + "required": [ + "validator" + ], + "properties": { + "validator": { + "description": "The `validator_address`", + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Empty": { + "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", + "type": "object" + }, + "Expiration": { + "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", + "oneOf": [ + { + "description": "AtHeight will expire when `env.block.height` >= height", + "type": "object", + "required": [ + "at_height" + ], + "properties": { + "at_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "AtTime will expire when `env.block.time` >= time", + "type": "object", + "required": [ + "at_time" + ], + "properties": { + "at_time": { + "$ref": "#/definitions/Timestamp" + } + }, + "additionalProperties": false + }, + { + "description": "Never will never expire. Used to express the empty variant", + "type": "object", + "required": [ + "never" + ], + "properties": { + "never": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "GovMsg": { + "description": "This message type allows the contract interact with the [x/gov] module in order to cast votes.\n\n[x/gov]: https://github.com/cosmos/cosmos-sdk/tree/v0.45.12/x/gov\n\n## Examples\n\nCast a simple vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); use cosmwasm_std::{GovMsg, VoteOption};\n\n#[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::Vote { proposal_id: 4, vote: VoteOption::Yes, })) } ```\n\nCast a weighted vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); # #[cfg(feature = \"cosmwasm_1_2\")] use cosmwasm_std::{Decimal, GovMsg, VoteOption, WeightedVoteOption};\n\n# #[cfg(feature = \"cosmwasm_1_2\")] #[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::VoteWeighted { proposal_id: 4, options: vec![ WeightedVoteOption { option: VoteOption::Yes, weight: Decimal::percent(65), }, WeightedVoteOption { option: VoteOption::Abstain, weight: Decimal::percent(35), }, ], })) } ```", + "oneOf": [ + { + "description": "This maps directly to [MsgVote](https://github.com/cosmos/cosmos-sdk/blob/v0.42.5/proto/cosmos/gov/v1beta1/tx.proto#L46-L56) in the Cosmos SDK with voter set to the contract address.", + "type": "object", + "required": [ + "vote" + ], + "properties": { + "vote": { + "type": "object", + "required": [ + "proposal_id", + "vote" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "vote": { + "description": "The vote option.\n\nThis should be called \"option\" for consistency with Cosmos SDK. Sorry for that. See .", + "allOf": [ + { + "$ref": "#/definitions/VoteOption" + } + ] + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcMsg": { + "description": "These are messages in the IBC lifecycle. Only usable by IBC-enabled contracts (contracts that directly speak the IBC protocol via 6 entry points)", + "oneOf": [ + { + "description": "Sends bank tokens owned by the contract to the given address on another chain. The channel must already be established between the ibctransfer module on this chain and a matching module on the remote chain. We cannot select the port_id, this is whatever the local chain has bound the ibctransfer module to.", + "type": "object", + "required": [ + "transfer" + ], + "properties": { + "transfer": { + "type": "object", + "required": [ + "amount", + "channel_id", + "timeout", + "to_address" + ], + "properties": { + "amount": { + "description": "packet data only supports one coin https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/ibc/applications/transfer/v1/transfer.proto#L11-L20", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "channel_id": { + "description": "exisiting channel to send the tokens over", + "type": "string" + }, + "timeout": { + "description": "when packet times out, measured on remote chain", + "allOf": [ + { + "$ref": "#/definitions/IbcTimeout" + } + ] + }, + "to_address": { + "description": "address on the remote chain to receive these tokens", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Sends an IBC packet with given data over the existing channel. Data should be encoded in a format defined by the channel version, and the module on the other side should know how to parse this.", + "type": "object", + "required": [ + "send_packet" + ], + "properties": { + "send_packet": { + "type": "object", + "required": [ + "channel_id", + "data", + "timeout" + ], + "properties": { + "channel_id": { + "type": "string" + }, + "data": { + "$ref": "#/definitions/Binary" + }, + "timeout": { + "description": "when packet times out, measured on remote chain", + "allOf": [ + { + "$ref": "#/definitions/IbcTimeout" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This will close an existing channel that is owned by this contract. Port is auto-assigned to the contract's IBC port", + "type": "object", + "required": [ + "close_channel" + ], + "properties": { + "close_channel": { + "type": "object", + "required": [ + "channel_id" + ], + "properties": { + "channel_id": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcTimeout": { + "description": "In IBC each package must set at least one type of timeout: the timestamp or the block height. Using this rather complex enum instead of two timeout fields we ensure that at least one timeout is set.", + "type": "object", + "properties": { + "block": { + "anyOf": [ + { + "$ref": "#/definitions/IbcTimeoutBlock" + }, + { + "type": "null" + } + ] + }, + "timestamp": { + "anyOf": [ + { + "$ref": "#/definitions/Timestamp" + }, + { + "type": "null" + } + ] + } + } + }, + "IbcTimeoutBlock": { + "description": "IBCTimeoutHeight Height is a monotonically increasing data type that can be compared against another Height for the purposes of updating and freezing clients. Ordering is (revision_number, timeout_height)", + "type": "object", + "required": [ + "height", + "revision" + ], + "properties": { + "height": { + "description": "block height after which the packet times out. the height within the given revision", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "revision": { + "description": "the version that the client is currently on (eg. after reseting the chain this could increment 1 as height drops to 0)", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + }, + "ProposalResponse_for_Empty": { + "description": "Note, if you are storing custom messages in the proposal, the querier needs to know what possible custom message types those are in order to parse the response", + "type": "object", + "required": [ + "description", + "expires", + "id", + "msgs", + "proposer", + "status", + "threshold", + "title" + ], + "properties": { + "deposit": { + "anyOf": [ + { + "$ref": "#/definitions/DepositInfo" + }, + { + "type": "null" + } + ] + }, + "description": { + "type": "string" + }, + "expires": { + "$ref": "#/definitions/Expiration" + }, + "id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "msgs": { + "type": "array", + "items": { + "$ref": "#/definitions/CosmosMsg_for_Empty" + } + }, + "proposer": { + "$ref": "#/definitions/Addr" + }, + "status": { + "$ref": "#/definitions/Status" + }, + "threshold": { + "description": "This is the threshold that is applied to this proposal. Both the rules of the voting contract, as well as the total_weight of the voting group may have changed since this time. That means that the generic `Threshold{}` query does not provide valid information for existing proposals.", + "allOf": [ + { + "$ref": "#/definitions/ThresholdResponse" + } + ] + }, + "title": { + "type": "string" + } + }, + "additionalProperties": false + }, + "StakingMsg": { + "description": "The message types of the staking module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto", + "oneOf": [ + { + "description": "This is translated to a [MsgDelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L81-L90). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "delegate" + ], + "properties": { + "delegate": { + "type": "object", + "required": [ + "amount", + "validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [MsgUndelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L112-L121). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "undelegate" + ], + "properties": { + "undelegate": { + "type": "object", + "required": [ + "amount", + "validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [MsgBeginRedelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L95-L105). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "redelegate" + ], + "properties": { + "redelegate": { + "type": "object", + "required": [ + "amount", + "dst_validator", + "src_validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "dst_validator": { + "type": "string" + }, + "src_validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Status": { + "oneOf": [ + { + "description": "proposal was created, but voting has not yet begun for whatever reason", + "type": "string", + "enum": [ + "pending" + ] + }, + { + "description": "you can vote on this", + "type": "string", + "enum": [ + "open" + ] + }, + { + "description": "voting is over and it did not pass", + "type": "string", + "enum": [ + "rejected" + ] + }, + { + "description": "voting is over and it did pass, but has not yet executed", + "type": "string", + "enum": [ + "passed" + ] + }, + { + "description": "voting is over it passed, and the proposal was executed", + "type": "string", + "enum": [ + "executed" + ] + } + ] + }, + "ThresholdResponse": { + "description": "This defines the different ways tallies can happen. Every contract should support a subset of these, ideally all.\n\nThe total_weight used for calculating success as well as the weights of each individual voter used in tallying should be snapshotted at the beginning of the block at which the proposal starts (this is likely the responsibility of a correct cw4 implementation).", + "oneOf": [ + { + "description": "Declares that a fixed weight of yes votes is needed to pass. It does not matter how many no votes are cast, or how many do not vote, as long as `weight` yes votes are cast.\n\nThis is the simplest format and usually suitable for small multisigs of trusted parties, like 3 of 5. (weight: 3, total_weight: 5)\n\nA proposal of this type can pass early as soon as the needed weight of yes votes has been cast.", + "type": "object", + "required": [ + "absolute_count" + ], + "properties": { + "absolute_count": { + "type": "object", + "required": [ + "total_weight", + "weight" + ], + "properties": { + "total_weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Declares a percentage of the total weight that must cast Yes votes, in order for a proposal to pass. The passing weight is computed over the total weight minus the weight of the abstained votes.\n\nThis is useful for similar circumstances as `AbsoluteCount`, where we have a relatively small set of voters, and participation is required. It is understood that if the voting set (group) changes between different proposals that refer to the same group, each proposal will work with a different set of voter weights (the ones snapshotted at proposal creation), and the passing weight for each proposal will be computed based on the absolute percentage, times the total weights of the members at the time of each proposal creation.\n\nExample: we set `percentage` to 51%. Proposal 1 starts when there is a `total_weight` of 5. This will require 3 weight of Yes votes in order to pass. Later, the Proposal 2 starts but the `total_weight` of the group has increased to 9. That proposal will then automatically require 5 Yes of 9 to pass, rather than 3 yes of 9 as would be the case with `AbsoluteCount`.", + "type": "object", + "required": [ + "absolute_percentage" + ], + "properties": { + "absolute_percentage": { + "type": "object", + "required": [ + "percentage", + "total_weight" + ], + "properties": { + "percentage": { + "$ref": "#/definitions/Decimal" + }, + "total_weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "In addition to a `threshold`, declares a `quorum` of the total votes that must participate in the election in order for the vote to be considered at all. Within the votes that were cast, it requires `threshold` votes in favor. That is calculated by ignoring the Abstain votes (they count towards `quorum`, but do not influence `threshold`). That is, we calculate `Yes / (Yes + No + Veto)` and compare it with `threshold` to consider if the proposal was passed.\n\nIt is rather difficult for a proposal of this type to pass early. That can only happen if the required quorum has been already met, and there are already enough Yes votes for the proposal to pass.\n\n30% Yes votes, 10% No votes, and 20% Abstain would pass early if quorum <= 60% (who has cast votes) and if the threshold is <= 37.5% (the remaining 40% voting no => 30% yes + 50% no). Once the voting period has passed with no additional votes, that same proposal would be considered successful if quorum <= 60% and threshold <= 75% (percent in favor if we ignore abstain votes).\n\nThis type is more common in general elections, where participation is often expected to be low, and `AbsolutePercentage` would either be too high to pass anything, or allow low percentages to pass, independently of if there was high participation in the election or not.", + "type": "object", + "required": [ + "threshold_quorum" + ], + "properties": { + "threshold_quorum": { + "type": "object", + "required": [ + "quorum", + "threshold", + "total_weight" + ], + "properties": { + "quorum": { + "$ref": "#/definitions/Decimal" + }, + "threshold": { + "$ref": "#/definitions/Decimal" + }, + "total_weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + }, + "VoteOption": { + "type": "string", + "enum": [ + "yes", + "no", + "abstain", + "no_with_veto" + ] + }, + "WasmMsg": { + "description": "The message types of the wasm module.\n\nSee https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto", + "oneOf": [ + { + "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L68-L78). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "execute" + ], + "properties": { + "execute": { + "type": "object", + "required": [ + "contract_addr", + "funds", + "msg" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "msg": { + "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThe contract address is non-predictable. But it is guaranteed that when emitting the same Instantiate message multiple times, multiple instances on different addresses will be generated. See also Instantiate2.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/CosmWasm/wasmd/blob/v0.29.2/proto/cosmwasm/wasm/v1/tx.proto#L53-L71). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "instantiate" + ], + "properties": { + "instantiate": { + "type": "object", + "required": [ + "code_id", + "funds", + "label", + "msg" + ], + "properties": { + "admin": { + "type": [ + "string", + "null" + ] + }, + "code_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "label": { + "description": "A human-readbale label for the contract", + "type": "string" + }, + "msg": { + "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "migrate" + ], + "properties": { + "migrate": { + "type": "object", + "required": [ + "contract_addr", + "msg", + "new_code_id" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "msg": { + "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + }, + "new_code_id": { + "description": "the code_id of the new logic to place in the given contract", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", + "type": "object", + "required": [ + "update_admin" + ], + "properties": { + "update_admin": { + "type": "object", + "required": [ + "admin", + "contract_addr" + ], + "properties": { + "admin": { + "type": "string" + }, + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", + "type": "object", + "required": [ + "clear_admin" + ], + "properties": { + "clear_admin": { + "type": "object", + "required": [ + "contract_addr" + ], + "properties": { + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + } + } + }, + "list_voters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "VoterListResponse", + "type": "object", + "required": [ + "voters" + ], + "properties": { + "voters": { + "type": "array", + "items": { + "$ref": "#/definitions/VoterDetail" + } + } + }, + "additionalProperties": false, + "definitions": { + "VoterDetail": { + "type": "object", + "required": [ + "addr", + "weight" + ], + "properties": { + "addr": { + "type": "string" + }, + "weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } + }, + "list_votes": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "VoteListResponse", + "type": "object", + "required": [ + "votes" + ], + "properties": { + "votes": { + "type": "array", + "items": { + "$ref": "#/definitions/VoteInfo" + } + } + }, + "additionalProperties": false, + "definitions": { + "Vote": { + "oneOf": [ + { + "description": "Marks support for the proposal.", + "type": "string", + "enum": [ + "yes" + ] + }, + { + "description": "Marks opposition to the proposal.", + "type": "string", + "enum": [ + "no" + ] + }, + { + "description": "Marks participation but does not count towards the ratio of support / opposed", + "type": "string", + "enum": [ + "abstain" + ] + }, + { + "description": "Veto is generally to be treated as a No vote. Some implementations may allow certain voters to be able to Veto, or them to be counted stronger than No in some way.", + "type": "string", + "enum": [ + "veto" + ] + } + ] + }, + "VoteInfo": { + "description": "Returns the vote (opinion as well as weight counted) as well as the address of the voter who submitted it", + "type": "object", + "required": [ + "proposal_id", + "vote", + "voter", + "weight" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "vote": { + "$ref": "#/definitions/Vote" + }, + "voter": { + "type": "string" + }, + "weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } + }, + "proposal": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ProposalResponse_for_Empty", + "description": "Note, if you are storing custom messages in the proposal, the querier needs to know what possible custom message types those are in order to parse the response", + "type": "object", + "required": [ + "description", + "expires", + "id", + "msgs", + "proposer", + "status", + "threshold", + "title" + ], + "properties": { + "deposit": { + "anyOf": [ + { + "$ref": "#/definitions/DepositInfo" + }, + { + "type": "null" + } + ] + }, + "description": { + "type": "string" + }, + "expires": { + "$ref": "#/definitions/Expiration" + }, + "id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "msgs": { + "type": "array", + "items": { + "$ref": "#/definitions/CosmosMsg_for_Empty" + } + }, + "proposer": { + "$ref": "#/definitions/Addr" + }, + "status": { + "$ref": "#/definitions/Status" + }, + "threshold": { + "description": "This is the threshold that is applied to this proposal. Both the rules of the voting contract, as well as the total_weight of the voting group may have changed since this time. That means that the generic `Threshold{}` query does not provide valid information for existing proposals.", + "allOf": [ + { + "$ref": "#/definitions/ThresholdResponse" + } + ] + }, + "title": { + "type": "string" + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "BankMsg": { + "description": "The message types of the bank module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto", + "oneOf": [ + { + "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "send" + ], + "properties": { + "send": { + "type": "object", + "required": [ + "amount", + "to_address" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "to_address": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", + "type": "object", + "required": [ + "burn" + ], + "properties": { + "burn": { + "type": "object", + "required": [ + "amount" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "CosmosMsg_for_Empty": { + "oneOf": [ + { + "type": "object", + "required": [ + "bank" + ], + "properties": { + "bank": { + "$ref": "#/definitions/BankMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "custom" + ], + "properties": { + "custom": { + "$ref": "#/definitions/Empty" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "staking" + ], + "properties": { + "staking": { + "$ref": "#/definitions/StakingMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "distribution" + ], + "properties": { + "distribution": { + "$ref": "#/definitions/DistributionMsg" + } + }, + "additionalProperties": false + }, + { + "description": "A Stargate message encoded the same way as a protobuf [Any](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto). This is the same structure as messages in `TxBody` from [ADR-020](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-020-protobuf-transaction-encoding.md)", + "type": "object", + "required": [ + "stargate" + ], + "properties": { + "stargate": { + "type": "object", + "required": [ + "type_url", + "value" + ], + "properties": { + "type_url": { + "type": "string" + }, + "value": { + "$ref": "#/definitions/Binary" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "ibc" + ], + "properties": { + "ibc": { + "$ref": "#/definitions/IbcMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "wasm" + ], + "properties": { + "wasm": { + "$ref": "#/definitions/WasmMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "gov" + ], + "properties": { + "gov": { + "$ref": "#/definitions/GovMsg" + } + }, + "additionalProperties": false + } + ] + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Denom": { + "oneOf": [ + { + "type": "object", + "required": [ + "native" + ], + "properties": { + "native": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "cw20" + ], + "properties": { + "cw20": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + ] + }, + "DepositInfo": { + "description": "Information about the deposit required to create a proposal.", + "type": "object", + "required": [ + "amount", + "denom", + "refund_failed_proposals" + ], + "properties": { + "amount": { + "description": "The number tokens required for payment.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "denom": { + "description": "The denom of the deposit payment.", + "allOf": [ + { + "$ref": "#/definitions/Denom" + } + ] + }, + "refund_failed_proposals": { + "description": "Should failed proposals have their deposits refunded?", + "type": "boolean" + } + }, + "additionalProperties": false + }, + "DistributionMsg": { + "description": "The message types of the distribution module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto", + "oneOf": [ + { + "description": "This is translated to a [MsgSetWithdrawAddress](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L29-L37). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "set_withdraw_address" + ], + "properties": { + "set_withdraw_address": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "The `withdraw_address`", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [[MsgWithdrawDelegatorReward](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L42-L50). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "withdraw_delegator_reward" + ], + "properties": { + "withdraw_delegator_reward": { + "type": "object", + "required": [ + "validator" + ], + "properties": { + "validator": { + "description": "The `validator_address`", + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Empty": { + "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", + "type": "object" + }, + "Expiration": { + "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", + "oneOf": [ + { + "description": "AtHeight will expire when `env.block.height` >= height", + "type": "object", + "required": [ + "at_height" + ], + "properties": { + "at_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "AtTime will expire when `env.block.time` >= time", + "type": "object", + "required": [ + "at_time" + ], + "properties": { + "at_time": { + "$ref": "#/definitions/Timestamp" + } + }, + "additionalProperties": false + }, + { + "description": "Never will never expire. Used to express the empty variant", + "type": "object", + "required": [ + "never" + ], + "properties": { + "never": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "GovMsg": { + "description": "This message type allows the contract interact with the [x/gov] module in order to cast votes.\n\n[x/gov]: https://github.com/cosmos/cosmos-sdk/tree/v0.45.12/x/gov\n\n## Examples\n\nCast a simple vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); use cosmwasm_std::{GovMsg, VoteOption};\n\n#[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::Vote { proposal_id: 4, vote: VoteOption::Yes, })) } ```\n\nCast a weighted vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); # #[cfg(feature = \"cosmwasm_1_2\")] use cosmwasm_std::{Decimal, GovMsg, VoteOption, WeightedVoteOption};\n\n# #[cfg(feature = \"cosmwasm_1_2\")] #[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::VoteWeighted { proposal_id: 4, options: vec![ WeightedVoteOption { option: VoteOption::Yes, weight: Decimal::percent(65), }, WeightedVoteOption { option: VoteOption::Abstain, weight: Decimal::percent(35), }, ], })) } ```", + "oneOf": [ + { + "description": "This maps directly to [MsgVote](https://github.com/cosmos/cosmos-sdk/blob/v0.42.5/proto/cosmos/gov/v1beta1/tx.proto#L46-L56) in the Cosmos SDK with voter set to the contract address.", + "type": "object", + "required": [ + "vote" + ], + "properties": { + "vote": { + "type": "object", + "required": [ + "proposal_id", + "vote" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "vote": { + "description": "The vote option.\n\nThis should be called \"option\" for consistency with Cosmos SDK. Sorry for that. See .", + "allOf": [ + { + "$ref": "#/definitions/VoteOption" + } + ] + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcMsg": { + "description": "These are messages in the IBC lifecycle. Only usable by IBC-enabled contracts (contracts that directly speak the IBC protocol via 6 entry points)", + "oneOf": [ + { + "description": "Sends bank tokens owned by the contract to the given address on another chain. The channel must already be established between the ibctransfer module on this chain and a matching module on the remote chain. We cannot select the port_id, this is whatever the local chain has bound the ibctransfer module to.", + "type": "object", + "required": [ + "transfer" + ], + "properties": { + "transfer": { + "type": "object", + "required": [ + "amount", + "channel_id", + "timeout", + "to_address" + ], + "properties": { + "amount": { + "description": "packet data only supports one coin https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/ibc/applications/transfer/v1/transfer.proto#L11-L20", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "channel_id": { + "description": "exisiting channel to send the tokens over", + "type": "string" + }, + "timeout": { + "description": "when packet times out, measured on remote chain", + "allOf": [ + { + "$ref": "#/definitions/IbcTimeout" + } + ] + }, + "to_address": { + "description": "address on the remote chain to receive these tokens", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Sends an IBC packet with given data over the existing channel. Data should be encoded in a format defined by the channel version, and the module on the other side should know how to parse this.", + "type": "object", + "required": [ + "send_packet" + ], + "properties": { + "send_packet": { + "type": "object", + "required": [ + "channel_id", + "data", + "timeout" + ], + "properties": { + "channel_id": { + "type": "string" + }, + "data": { + "$ref": "#/definitions/Binary" + }, + "timeout": { + "description": "when packet times out, measured on remote chain", + "allOf": [ + { + "$ref": "#/definitions/IbcTimeout" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This will close an existing channel that is owned by this contract. Port is auto-assigned to the contract's IBC port", + "type": "object", + "required": [ + "close_channel" + ], + "properties": { + "close_channel": { + "type": "object", + "required": [ + "channel_id" + ], + "properties": { + "channel_id": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcTimeout": { + "description": "In IBC each package must set at least one type of timeout: the timestamp or the block height. Using this rather complex enum instead of two timeout fields we ensure that at least one timeout is set.", + "type": "object", + "properties": { + "block": { + "anyOf": [ + { + "$ref": "#/definitions/IbcTimeoutBlock" + }, + { + "type": "null" + } + ] + }, + "timestamp": { + "anyOf": [ + { + "$ref": "#/definitions/Timestamp" + }, + { + "type": "null" + } + ] + } + } + }, + "IbcTimeoutBlock": { + "description": "IBCTimeoutHeight Height is a monotonically increasing data type that can be compared against another Height for the purposes of updating and freezing clients. Ordering is (revision_number, timeout_height)", + "type": "object", + "required": [ + "height", + "revision" + ], + "properties": { + "height": { + "description": "block height after which the packet times out. the height within the given revision", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "revision": { + "description": "the version that the client is currently on (eg. after reseting the chain this could increment 1 as height drops to 0)", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + }, + "StakingMsg": { + "description": "The message types of the staking module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto", + "oneOf": [ + { + "description": "This is translated to a [MsgDelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L81-L90). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "delegate" + ], + "properties": { + "delegate": { + "type": "object", + "required": [ + "amount", + "validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [MsgUndelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L112-L121). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "undelegate" + ], + "properties": { + "undelegate": { + "type": "object", + "required": [ + "amount", + "validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [MsgBeginRedelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L95-L105). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "redelegate" + ], + "properties": { + "redelegate": { + "type": "object", + "required": [ + "amount", + "dst_validator", + "src_validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "dst_validator": { + "type": "string" + }, + "src_validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Status": { + "oneOf": [ + { + "description": "proposal was created, but voting has not yet begun for whatever reason", + "type": "string", + "enum": [ + "pending" + ] + }, + { + "description": "you can vote on this", + "type": "string", + "enum": [ + "open" + ] + }, + { + "description": "voting is over and it did not pass", + "type": "string", + "enum": [ + "rejected" + ] + }, + { + "description": "voting is over and it did pass, but has not yet executed", + "type": "string", + "enum": [ + "passed" + ] + }, + { + "description": "voting is over it passed, and the proposal was executed", + "type": "string", + "enum": [ + "executed" + ] + } + ] + }, + "ThresholdResponse": { + "description": "This defines the different ways tallies can happen. Every contract should support a subset of these, ideally all.\n\nThe total_weight used for calculating success as well as the weights of each individual voter used in tallying should be snapshotted at the beginning of the block at which the proposal starts (this is likely the responsibility of a correct cw4 implementation).", + "oneOf": [ + { + "description": "Declares that a fixed weight of yes votes is needed to pass. It does not matter how many no votes are cast, or how many do not vote, as long as `weight` yes votes are cast.\n\nThis is the simplest format and usually suitable for small multisigs of trusted parties, like 3 of 5. (weight: 3, total_weight: 5)\n\nA proposal of this type can pass early as soon as the needed weight of yes votes has been cast.", + "type": "object", + "required": [ + "absolute_count" + ], + "properties": { + "absolute_count": { + "type": "object", + "required": [ + "total_weight", + "weight" + ], + "properties": { + "total_weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Declares a percentage of the total weight that must cast Yes votes, in order for a proposal to pass. The passing weight is computed over the total weight minus the weight of the abstained votes.\n\nThis is useful for similar circumstances as `AbsoluteCount`, where we have a relatively small set of voters, and participation is required. It is understood that if the voting set (group) changes between different proposals that refer to the same group, each proposal will work with a different set of voter weights (the ones snapshotted at proposal creation), and the passing weight for each proposal will be computed based on the absolute percentage, times the total weights of the members at the time of each proposal creation.\n\nExample: we set `percentage` to 51%. Proposal 1 starts when there is a `total_weight` of 5. This will require 3 weight of Yes votes in order to pass. Later, the Proposal 2 starts but the `total_weight` of the group has increased to 9. That proposal will then automatically require 5 Yes of 9 to pass, rather than 3 yes of 9 as would be the case with `AbsoluteCount`.", + "type": "object", + "required": [ + "absolute_percentage" + ], + "properties": { + "absolute_percentage": { + "type": "object", + "required": [ + "percentage", + "total_weight" + ], + "properties": { + "percentage": { + "$ref": "#/definitions/Decimal" + }, + "total_weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "In addition to a `threshold`, declares a `quorum` of the total votes that must participate in the election in order for the vote to be considered at all. Within the votes that were cast, it requires `threshold` votes in favor. That is calculated by ignoring the Abstain votes (they count towards `quorum`, but do not influence `threshold`). That is, we calculate `Yes / (Yes + No + Veto)` and compare it with `threshold` to consider if the proposal was passed.\n\nIt is rather difficult for a proposal of this type to pass early. That can only happen if the required quorum has been already met, and there are already enough Yes votes for the proposal to pass.\n\n30% Yes votes, 10% No votes, and 20% Abstain would pass early if quorum <= 60% (who has cast votes) and if the threshold is <= 37.5% (the remaining 40% voting no => 30% yes + 50% no). Once the voting period has passed with no additional votes, that same proposal would be considered successful if quorum <= 60% and threshold <= 75% (percent in favor if we ignore abstain votes).\n\nThis type is more common in general elections, where participation is often expected to be low, and `AbsolutePercentage` would either be too high to pass anything, or allow low percentages to pass, independently of if there was high participation in the election or not.", + "type": "object", + "required": [ + "threshold_quorum" + ], + "properties": { + "threshold_quorum": { + "type": "object", + "required": [ + "quorum", + "threshold", + "total_weight" + ], + "properties": { + "quorum": { + "$ref": "#/definitions/Decimal" + }, + "threshold": { + "$ref": "#/definitions/Decimal" + }, + "total_weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + }, + "VoteOption": { + "type": "string", + "enum": [ + "yes", + "no", + "abstain", + "no_with_veto" + ] + }, + "WasmMsg": { + "description": "The message types of the wasm module.\n\nSee https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto", + "oneOf": [ + { + "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L68-L78). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "execute" + ], + "properties": { + "execute": { + "type": "object", + "required": [ + "contract_addr", + "funds", + "msg" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "msg": { + "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThe contract address is non-predictable. But it is guaranteed that when emitting the same Instantiate message multiple times, multiple instances on different addresses will be generated. See also Instantiate2.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/CosmWasm/wasmd/blob/v0.29.2/proto/cosmwasm/wasm/v1/tx.proto#L53-L71). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "instantiate" + ], + "properties": { + "instantiate": { + "type": "object", + "required": [ + "code_id", + "funds", + "label", + "msg" + ], + "properties": { + "admin": { + "type": [ + "string", + "null" + ] + }, + "code_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "label": { + "description": "A human-readbale label for the contract", + "type": "string" + }, + "msg": { + "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "migrate" + ], + "properties": { + "migrate": { + "type": "object", + "required": [ + "contract_addr", + "msg", + "new_code_id" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "msg": { + "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + }, + "new_code_id": { + "description": "the code_id of the new logic to place in the given contract", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", + "type": "object", + "required": [ + "update_admin" + ], + "properties": { + "update_admin": { + "type": "object", + "required": [ + "admin", + "contract_addr" + ], + "properties": { + "admin": { + "type": "string" + }, + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", + "type": "object", + "required": [ + "clear_admin" + ], + "properties": { + "clear_admin": { + "type": "object", + "required": [ + "contract_addr" + ], + "properties": { + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + } + } + }, + "reverse_proposals": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ProposalListResponse_for_Empty", + "type": "object", + "required": [ + "proposals" + ], + "properties": { + "proposals": { + "type": "array", + "items": { + "$ref": "#/definitions/ProposalResponse_for_Empty" + } + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "BankMsg": { + "description": "The message types of the bank module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto", + "oneOf": [ + { + "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "send" + ], + "properties": { + "send": { + "type": "object", + "required": [ + "amount", + "to_address" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "to_address": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", + "type": "object", + "required": [ + "burn" + ], + "properties": { + "burn": { + "type": "object", + "required": [ + "amount" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "CosmosMsg_for_Empty": { + "oneOf": [ + { + "type": "object", + "required": [ + "bank" + ], + "properties": { + "bank": { + "$ref": "#/definitions/BankMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "custom" + ], + "properties": { + "custom": { + "$ref": "#/definitions/Empty" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "staking" + ], + "properties": { + "staking": { + "$ref": "#/definitions/StakingMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "distribution" + ], + "properties": { + "distribution": { + "$ref": "#/definitions/DistributionMsg" + } + }, + "additionalProperties": false + }, + { + "description": "A Stargate message encoded the same way as a protobuf [Any](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto). This is the same structure as messages in `TxBody` from [ADR-020](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-020-protobuf-transaction-encoding.md)", + "type": "object", + "required": [ + "stargate" + ], + "properties": { + "stargate": { + "type": "object", + "required": [ + "type_url", + "value" + ], + "properties": { + "type_url": { + "type": "string" + }, + "value": { + "$ref": "#/definitions/Binary" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "ibc" + ], + "properties": { + "ibc": { + "$ref": "#/definitions/IbcMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "wasm" + ], + "properties": { + "wasm": { + "$ref": "#/definitions/WasmMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "gov" + ], + "properties": { + "gov": { + "$ref": "#/definitions/GovMsg" + } + }, + "additionalProperties": false + } + ] + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Denom": { + "oneOf": [ + { + "type": "object", + "required": [ + "native" + ], + "properties": { + "native": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "cw20" + ], + "properties": { + "cw20": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + ] + }, + "DepositInfo": { + "description": "Information about the deposit required to create a proposal.", + "type": "object", + "required": [ + "amount", + "denom", + "refund_failed_proposals" + ], + "properties": { + "amount": { + "description": "The number tokens required for payment.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "denom": { + "description": "The denom of the deposit payment.", + "allOf": [ + { + "$ref": "#/definitions/Denom" + } + ] + }, + "refund_failed_proposals": { + "description": "Should failed proposals have their deposits refunded?", + "type": "boolean" + } + }, + "additionalProperties": false + }, + "DistributionMsg": { + "description": "The message types of the distribution module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto", + "oneOf": [ + { + "description": "This is translated to a [MsgSetWithdrawAddress](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L29-L37). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "set_withdraw_address" + ], + "properties": { + "set_withdraw_address": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "The `withdraw_address`", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [[MsgWithdrawDelegatorReward](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L42-L50). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "withdraw_delegator_reward" + ], + "properties": { + "withdraw_delegator_reward": { + "type": "object", + "required": [ + "validator" + ], + "properties": { + "validator": { + "description": "The `validator_address`", + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Empty": { + "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", + "type": "object" + }, + "Expiration": { + "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", + "oneOf": [ + { + "description": "AtHeight will expire when `env.block.height` >= height", + "type": "object", + "required": [ + "at_height" + ], + "properties": { + "at_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "AtTime will expire when `env.block.time` >= time", + "type": "object", + "required": [ + "at_time" + ], + "properties": { + "at_time": { + "$ref": "#/definitions/Timestamp" + } + }, + "additionalProperties": false + }, + { + "description": "Never will never expire. Used to express the empty variant", + "type": "object", + "required": [ + "never" + ], + "properties": { + "never": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "GovMsg": { + "description": "This message type allows the contract interact with the [x/gov] module in order to cast votes.\n\n[x/gov]: https://github.com/cosmos/cosmos-sdk/tree/v0.45.12/x/gov\n\n## Examples\n\nCast a simple vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); use cosmwasm_std::{GovMsg, VoteOption};\n\n#[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::Vote { proposal_id: 4, vote: VoteOption::Yes, })) } ```\n\nCast a weighted vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); # #[cfg(feature = \"cosmwasm_1_2\")] use cosmwasm_std::{Decimal, GovMsg, VoteOption, WeightedVoteOption};\n\n# #[cfg(feature = \"cosmwasm_1_2\")] #[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::VoteWeighted { proposal_id: 4, options: vec![ WeightedVoteOption { option: VoteOption::Yes, weight: Decimal::percent(65), }, WeightedVoteOption { option: VoteOption::Abstain, weight: Decimal::percent(35), }, ], })) } ```", + "oneOf": [ + { + "description": "This maps directly to [MsgVote](https://github.com/cosmos/cosmos-sdk/blob/v0.42.5/proto/cosmos/gov/v1beta1/tx.proto#L46-L56) in the Cosmos SDK with voter set to the contract address.", + "type": "object", + "required": [ + "vote" + ], + "properties": { + "vote": { + "type": "object", + "required": [ + "proposal_id", + "vote" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "vote": { + "description": "The vote option.\n\nThis should be called \"option\" for consistency with Cosmos SDK. Sorry for that. See .", + "allOf": [ + { + "$ref": "#/definitions/VoteOption" + } + ] + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcMsg": { + "description": "These are messages in the IBC lifecycle. Only usable by IBC-enabled contracts (contracts that directly speak the IBC protocol via 6 entry points)", + "oneOf": [ + { + "description": "Sends bank tokens owned by the contract to the given address on another chain. The channel must already be established between the ibctransfer module on this chain and a matching module on the remote chain. We cannot select the port_id, this is whatever the local chain has bound the ibctransfer module to.", + "type": "object", + "required": [ + "transfer" + ], + "properties": { + "transfer": { + "type": "object", + "required": [ + "amount", + "channel_id", + "timeout", + "to_address" + ], + "properties": { + "amount": { + "description": "packet data only supports one coin https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/ibc/applications/transfer/v1/transfer.proto#L11-L20", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "channel_id": { + "description": "exisiting channel to send the tokens over", + "type": "string" + }, + "timeout": { + "description": "when packet times out, measured on remote chain", + "allOf": [ + { + "$ref": "#/definitions/IbcTimeout" + } + ] + }, + "to_address": { + "description": "address on the remote chain to receive these tokens", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Sends an IBC packet with given data over the existing channel. Data should be encoded in a format defined by the channel version, and the module on the other side should know how to parse this.", + "type": "object", + "required": [ + "send_packet" + ], + "properties": { + "send_packet": { + "type": "object", + "required": [ + "channel_id", + "data", + "timeout" + ], + "properties": { + "channel_id": { + "type": "string" + }, + "data": { + "$ref": "#/definitions/Binary" + }, + "timeout": { + "description": "when packet times out, measured on remote chain", + "allOf": [ + { + "$ref": "#/definitions/IbcTimeout" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This will close an existing channel that is owned by this contract. Port is auto-assigned to the contract's IBC port", + "type": "object", + "required": [ + "close_channel" + ], + "properties": { + "close_channel": { + "type": "object", + "required": [ + "channel_id" + ], + "properties": { + "channel_id": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcTimeout": { + "description": "In IBC each package must set at least one type of timeout: the timestamp or the block height. Using this rather complex enum instead of two timeout fields we ensure that at least one timeout is set.", + "type": "object", + "properties": { + "block": { + "anyOf": [ + { + "$ref": "#/definitions/IbcTimeoutBlock" + }, + { + "type": "null" + } + ] + }, + "timestamp": { + "anyOf": [ + { + "$ref": "#/definitions/Timestamp" + }, + { + "type": "null" + } + ] + } + } + }, + "IbcTimeoutBlock": { + "description": "IBCTimeoutHeight Height is a monotonically increasing data type that can be compared against another Height for the purposes of updating and freezing clients. Ordering is (revision_number, timeout_height)", + "type": "object", + "required": [ + "height", + "revision" + ], + "properties": { + "height": { + "description": "block height after which the packet times out. the height within the given revision", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "revision": { + "description": "the version that the client is currently on (eg. after reseting the chain this could increment 1 as height drops to 0)", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + }, + "ProposalResponse_for_Empty": { + "description": "Note, if you are storing custom messages in the proposal, the querier needs to know what possible custom message types those are in order to parse the response", + "type": "object", + "required": [ + "description", + "expires", + "id", + "msgs", + "proposer", + "status", + "threshold", + "title" + ], + "properties": { + "deposit": { + "anyOf": [ + { + "$ref": "#/definitions/DepositInfo" + }, + { + "type": "null" + } + ] + }, + "description": { + "type": "string" + }, + "expires": { + "$ref": "#/definitions/Expiration" + }, + "id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "msgs": { + "type": "array", + "items": { + "$ref": "#/definitions/CosmosMsg_for_Empty" + } + }, + "proposer": { + "$ref": "#/definitions/Addr" + }, + "status": { + "$ref": "#/definitions/Status" + }, + "threshold": { + "description": "This is the threshold that is applied to this proposal. Both the rules of the voting contract, as well as the total_weight of the voting group may have changed since this time. That means that the generic `Threshold{}` query does not provide valid information for existing proposals.", + "allOf": [ + { + "$ref": "#/definitions/ThresholdResponse" + } + ] + }, + "title": { + "type": "string" + } + }, + "additionalProperties": false + }, + "StakingMsg": { + "description": "The message types of the staking module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto", + "oneOf": [ + { + "description": "This is translated to a [MsgDelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L81-L90). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "delegate" + ], + "properties": { + "delegate": { + "type": "object", + "required": [ + "amount", + "validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [MsgUndelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L112-L121). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "undelegate" + ], + "properties": { + "undelegate": { + "type": "object", + "required": [ + "amount", + "validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [MsgBeginRedelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L95-L105). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "redelegate" + ], + "properties": { + "redelegate": { + "type": "object", + "required": [ + "amount", + "dst_validator", + "src_validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "dst_validator": { + "type": "string" + }, + "src_validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Status": { + "oneOf": [ + { + "description": "proposal was created, but voting has not yet begun for whatever reason", + "type": "string", + "enum": [ + "pending" + ] + }, + { + "description": "you can vote on this", + "type": "string", + "enum": [ + "open" + ] + }, + { + "description": "voting is over and it did not pass", + "type": "string", + "enum": [ + "rejected" + ] + }, + { + "description": "voting is over and it did pass, but has not yet executed", + "type": "string", + "enum": [ + "passed" + ] + }, + { + "description": "voting is over it passed, and the proposal was executed", + "type": "string", + "enum": [ + "executed" + ] + } + ] + }, + "ThresholdResponse": { + "description": "This defines the different ways tallies can happen. Every contract should support a subset of these, ideally all.\n\nThe total_weight used for calculating success as well as the weights of each individual voter used in tallying should be snapshotted at the beginning of the block at which the proposal starts (this is likely the responsibility of a correct cw4 implementation).", + "oneOf": [ + { + "description": "Declares that a fixed weight of yes votes is needed to pass. It does not matter how many no votes are cast, or how many do not vote, as long as `weight` yes votes are cast.\n\nThis is the simplest format and usually suitable for small multisigs of trusted parties, like 3 of 5. (weight: 3, total_weight: 5)\n\nA proposal of this type can pass early as soon as the needed weight of yes votes has been cast.", + "type": "object", + "required": [ + "absolute_count" + ], + "properties": { + "absolute_count": { + "type": "object", + "required": [ + "total_weight", + "weight" + ], + "properties": { + "total_weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Declares a percentage of the total weight that must cast Yes votes, in order for a proposal to pass. The passing weight is computed over the total weight minus the weight of the abstained votes.\n\nThis is useful for similar circumstances as `AbsoluteCount`, where we have a relatively small set of voters, and participation is required. It is understood that if the voting set (group) changes between different proposals that refer to the same group, each proposal will work with a different set of voter weights (the ones snapshotted at proposal creation), and the passing weight for each proposal will be computed based on the absolute percentage, times the total weights of the members at the time of each proposal creation.\n\nExample: we set `percentage` to 51%. Proposal 1 starts when there is a `total_weight` of 5. This will require 3 weight of Yes votes in order to pass. Later, the Proposal 2 starts but the `total_weight` of the group has increased to 9. That proposal will then automatically require 5 Yes of 9 to pass, rather than 3 yes of 9 as would be the case with `AbsoluteCount`.", + "type": "object", + "required": [ + "absolute_percentage" + ], + "properties": { + "absolute_percentage": { + "type": "object", + "required": [ + "percentage", + "total_weight" + ], + "properties": { + "percentage": { + "$ref": "#/definitions/Decimal" + }, + "total_weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "In addition to a `threshold`, declares a `quorum` of the total votes that must participate in the election in order for the vote to be considered at all. Within the votes that were cast, it requires `threshold` votes in favor. That is calculated by ignoring the Abstain votes (they count towards `quorum`, but do not influence `threshold`). That is, we calculate `Yes / (Yes + No + Veto)` and compare it with `threshold` to consider if the proposal was passed.\n\nIt is rather difficult for a proposal of this type to pass early. That can only happen if the required quorum has been already met, and there are already enough Yes votes for the proposal to pass.\n\n30% Yes votes, 10% No votes, and 20% Abstain would pass early if quorum <= 60% (who has cast votes) and if the threshold is <= 37.5% (the remaining 40% voting no => 30% yes + 50% no). Once the voting period has passed with no additional votes, that same proposal would be considered successful if quorum <= 60% and threshold <= 75% (percent in favor if we ignore abstain votes).\n\nThis type is more common in general elections, where participation is often expected to be low, and `AbsolutePercentage` would either be too high to pass anything, or allow low percentages to pass, independently of if there was high participation in the election or not.", + "type": "object", + "required": [ + "threshold_quorum" + ], + "properties": { + "threshold_quorum": { + "type": "object", + "required": [ + "quorum", + "threshold", + "total_weight" + ], + "properties": { + "quorum": { + "$ref": "#/definitions/Decimal" + }, + "threshold": { + "$ref": "#/definitions/Decimal" + }, + "total_weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + }, + "VoteOption": { + "type": "string", + "enum": [ + "yes", + "no", + "abstain", + "no_with_veto" + ] + }, + "WasmMsg": { + "description": "The message types of the wasm module.\n\nSee https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto", + "oneOf": [ + { + "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L68-L78). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "execute" + ], + "properties": { + "execute": { + "type": "object", + "required": [ + "contract_addr", + "funds", + "msg" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "msg": { + "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThe contract address is non-predictable. But it is guaranteed that when emitting the same Instantiate message multiple times, multiple instances on different addresses will be generated. See also Instantiate2.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/CosmWasm/wasmd/blob/v0.29.2/proto/cosmwasm/wasm/v1/tx.proto#L53-L71). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "instantiate" + ], + "properties": { + "instantiate": { + "type": "object", + "required": [ + "code_id", + "funds", + "label", + "msg" + ], + "properties": { + "admin": { + "type": [ + "string", + "null" + ] + }, + "code_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "label": { + "description": "A human-readbale label for the contract", + "type": "string" + }, + "msg": { + "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "migrate" + ], + "properties": { + "migrate": { + "type": "object", + "required": [ + "contract_addr", + "msg", + "new_code_id" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "msg": { + "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + }, + "new_code_id": { + "description": "the code_id of the new logic to place in the given contract", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", + "type": "object", + "required": [ + "update_admin" + ], + "properties": { + "update_admin": { + "type": "object", + "required": [ + "admin", + "contract_addr" + ], + "properties": { + "admin": { + "type": "string" + }, + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", + "type": "object", + "required": [ + "clear_admin" + ], + "properties": { + "clear_admin": { + "type": "object", + "required": [ + "contract_addr" + ], + "properties": { + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + } + } + }, + "threshold": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ThresholdResponse", + "description": "This defines the different ways tallies can happen. Every contract should support a subset of these, ideally all.\n\nThe total_weight used for calculating success as well as the weights of each individual voter used in tallying should be snapshotted at the beginning of the block at which the proposal starts (this is likely the responsibility of a correct cw4 implementation).", + "oneOf": [ + { + "description": "Declares that a fixed weight of yes votes is needed to pass. It does not matter how many no votes are cast, or how many do not vote, as long as `weight` yes votes are cast.\n\nThis is the simplest format and usually suitable for small multisigs of trusted parties, like 3 of 5. (weight: 3, total_weight: 5)\n\nA proposal of this type can pass early as soon as the needed weight of yes votes has been cast.", + "type": "object", + "required": [ + "absolute_count" + ], + "properties": { + "absolute_count": { + "type": "object", + "required": [ + "total_weight", + "weight" + ], + "properties": { + "total_weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Declares a percentage of the total weight that must cast Yes votes, in order for a proposal to pass. The passing weight is computed over the total weight minus the weight of the abstained votes.\n\nThis is useful for similar circumstances as `AbsoluteCount`, where we have a relatively small set of voters, and participation is required. It is understood that if the voting set (group) changes between different proposals that refer to the same group, each proposal will work with a different set of voter weights (the ones snapshotted at proposal creation), and the passing weight for each proposal will be computed based on the absolute percentage, times the total weights of the members at the time of each proposal creation.\n\nExample: we set `percentage` to 51%. Proposal 1 starts when there is a `total_weight` of 5. This will require 3 weight of Yes votes in order to pass. Later, the Proposal 2 starts but the `total_weight` of the group has increased to 9. That proposal will then automatically require 5 Yes of 9 to pass, rather than 3 yes of 9 as would be the case with `AbsoluteCount`.", + "type": "object", + "required": [ + "absolute_percentage" + ], + "properties": { + "absolute_percentage": { + "type": "object", + "required": [ + "percentage", + "total_weight" + ], + "properties": { + "percentage": { + "$ref": "#/definitions/Decimal" + }, + "total_weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "In addition to a `threshold`, declares a `quorum` of the total votes that must participate in the election in order for the vote to be considered at all. Within the votes that were cast, it requires `threshold` votes in favor. That is calculated by ignoring the Abstain votes (they count towards `quorum`, but do not influence `threshold`). That is, we calculate `Yes / (Yes + No + Veto)` and compare it with `threshold` to consider if the proposal was passed.\n\nIt is rather difficult for a proposal of this type to pass early. That can only happen if the required quorum has been already met, and there are already enough Yes votes for the proposal to pass.\n\n30% Yes votes, 10% No votes, and 20% Abstain would pass early if quorum <= 60% (who has cast votes) and if the threshold is <= 37.5% (the remaining 40% voting no => 30% yes + 50% no). Once the voting period has passed with no additional votes, that same proposal would be considered successful if quorum <= 60% and threshold <= 75% (percent in favor if we ignore abstain votes).\n\nThis type is more common in general elections, where participation is often expected to be low, and `AbsolutePercentage` would either be too high to pass anything, or allow low percentages to pass, independently of if there was high participation in the election or not.", + "type": "object", + "required": [ + "threshold_quorum" + ], + "properties": { + "threshold_quorum": { + "type": "object", + "required": [ + "quorum", + "threshold", + "total_weight" + ], + "properties": { + "quorum": { + "$ref": "#/definitions/Decimal" + }, + "threshold": { + "$ref": "#/definitions/Decimal" + }, + "total_weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + } + } + }, + "vote": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "VoteResponse", + "type": "object", + "properties": { + "vote": { + "anyOf": [ + { + "$ref": "#/definitions/VoteInfo" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Vote": { + "oneOf": [ + { + "description": "Marks support for the proposal.", + "type": "string", + "enum": [ + "yes" + ] + }, + { + "description": "Marks opposition to the proposal.", + "type": "string", + "enum": [ + "no" + ] + }, + { + "description": "Marks participation but does not count towards the ratio of support / opposed", + "type": "string", + "enum": [ + "abstain" + ] + }, + { + "description": "Veto is generally to be treated as a No vote. Some implementations may allow certain voters to be able to Veto, or them to be counted stronger than No in some way.", + "type": "string", + "enum": [ + "veto" + ] + } + ] + }, + "VoteInfo": { + "description": "Returns the vote (opinion as well as weight counted) as well as the address of the voter who submitted it", + "type": "object", + "required": [ + "proposal_id", + "vote", + "voter", + "weight" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "vote": { + "$ref": "#/definitions/Vote" + }, + "voter": { + "type": "string" + }, + "weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } + }, + "voter": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "VoterResponse", + "type": "object", + "properties": { + "weight": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/multisig/cw3-flex-multisig/schema/raw/execute.json b/contracts/multisig/cw3-flex-multisig/schema/raw/execute.json new file mode 100644 index 0000000000..8c5eb3cdae --- /dev/null +++ b/contracts/multisig/cw3-flex-multisig/schema/raw/execute.json @@ -0,0 +1,976 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "propose" + ], + "properties": { + "propose": { + "type": "object", + "required": [ + "description", + "msgs", + "title" + ], + "properties": { + "description": { + "type": "string" + }, + "latest": { + "anyOf": [ + { + "$ref": "#/definitions/Expiration" + }, + { + "type": "null" + } + ] + }, + "msgs": { + "type": "array", + "items": { + "$ref": "#/definitions/CosmosMsg_for_Empty" + } + }, + "title": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "vote" + ], + "properties": { + "vote": { + "type": "object", + "required": [ + "proposal_id", + "vote" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "vote": { + "$ref": "#/definitions/Vote" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "execute" + ], + "properties": { + "execute": { + "type": "object", + "required": [ + "proposal_id" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "close" + ], + "properties": { + "close": { + "type": "object", + "required": [ + "proposal_id" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Handles update hook messages from the group contract", + "type": "object", + "required": [ + "member_changed_hook" + ], + "properties": { + "member_changed_hook": { + "$ref": "#/definitions/MemberChangedHookMsg" + } + }, + "additionalProperties": false + } + ], + "definitions": { + "BankMsg": { + "description": "The message types of the bank module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto", + "oneOf": [ + { + "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "send" + ], + "properties": { + "send": { + "type": "object", + "required": [ + "amount", + "to_address" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "to_address": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", + "type": "object", + "required": [ + "burn" + ], + "properties": { + "burn": { + "type": "object", + "required": [ + "amount" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "CosmosMsg_for_Empty": { + "oneOf": [ + { + "type": "object", + "required": [ + "bank" + ], + "properties": { + "bank": { + "$ref": "#/definitions/BankMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "custom" + ], + "properties": { + "custom": { + "$ref": "#/definitions/Empty" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "staking" + ], + "properties": { + "staking": { + "$ref": "#/definitions/StakingMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "distribution" + ], + "properties": { + "distribution": { + "$ref": "#/definitions/DistributionMsg" + } + }, + "additionalProperties": false + }, + { + "description": "A Stargate message encoded the same way as a protobuf [Any](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto). This is the same structure as messages in `TxBody` from [ADR-020](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-020-protobuf-transaction-encoding.md)", + "type": "object", + "required": [ + "stargate" + ], + "properties": { + "stargate": { + "type": "object", + "required": [ + "type_url", + "value" + ], + "properties": { + "type_url": { + "type": "string" + }, + "value": { + "$ref": "#/definitions/Binary" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "ibc" + ], + "properties": { + "ibc": { + "$ref": "#/definitions/IbcMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "wasm" + ], + "properties": { + "wasm": { + "$ref": "#/definitions/WasmMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "gov" + ], + "properties": { + "gov": { + "$ref": "#/definitions/GovMsg" + } + }, + "additionalProperties": false + } + ] + }, + "DistributionMsg": { + "description": "The message types of the distribution module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto", + "oneOf": [ + { + "description": "This is translated to a [MsgSetWithdrawAddress](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L29-L37). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "set_withdraw_address" + ], + "properties": { + "set_withdraw_address": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "The `withdraw_address`", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [[MsgWithdrawDelegatorReward](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L42-L50). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "withdraw_delegator_reward" + ], + "properties": { + "withdraw_delegator_reward": { + "type": "object", + "required": [ + "validator" + ], + "properties": { + "validator": { + "description": "The `validator_address`", + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Empty": { + "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", + "type": "object" + }, + "Expiration": { + "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", + "oneOf": [ + { + "description": "AtHeight will expire when `env.block.height` >= height", + "type": "object", + "required": [ + "at_height" + ], + "properties": { + "at_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "AtTime will expire when `env.block.time` >= time", + "type": "object", + "required": [ + "at_time" + ], + "properties": { + "at_time": { + "$ref": "#/definitions/Timestamp" + } + }, + "additionalProperties": false + }, + { + "description": "Never will never expire. Used to express the empty variant", + "type": "object", + "required": [ + "never" + ], + "properties": { + "never": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "GovMsg": { + "description": "This message type allows the contract interact with the [x/gov] module in order to cast votes.\n\n[x/gov]: https://github.com/cosmos/cosmos-sdk/tree/v0.45.12/x/gov\n\n## Examples\n\nCast a simple vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); use cosmwasm_std::{GovMsg, VoteOption};\n\n#[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::Vote { proposal_id: 4, vote: VoteOption::Yes, })) } ```\n\nCast a weighted vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); # #[cfg(feature = \"cosmwasm_1_2\")] use cosmwasm_std::{Decimal, GovMsg, VoteOption, WeightedVoteOption};\n\n# #[cfg(feature = \"cosmwasm_1_2\")] #[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::VoteWeighted { proposal_id: 4, options: vec![ WeightedVoteOption { option: VoteOption::Yes, weight: Decimal::percent(65), }, WeightedVoteOption { option: VoteOption::Abstain, weight: Decimal::percent(35), }, ], })) } ```", + "oneOf": [ + { + "description": "This maps directly to [MsgVote](https://github.com/cosmos/cosmos-sdk/blob/v0.42.5/proto/cosmos/gov/v1beta1/tx.proto#L46-L56) in the Cosmos SDK with voter set to the contract address.", + "type": "object", + "required": [ + "vote" + ], + "properties": { + "vote": { + "type": "object", + "required": [ + "proposal_id", + "vote" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "vote": { + "description": "The vote option.\n\nThis should be called \"option\" for consistency with Cosmos SDK. Sorry for that. See .", + "allOf": [ + { + "$ref": "#/definitions/VoteOption" + } + ] + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcMsg": { + "description": "These are messages in the IBC lifecycle. Only usable by IBC-enabled contracts (contracts that directly speak the IBC protocol via 6 entry points)", + "oneOf": [ + { + "description": "Sends bank tokens owned by the contract to the given address on another chain. The channel must already be established between the ibctransfer module on this chain and a matching module on the remote chain. We cannot select the port_id, this is whatever the local chain has bound the ibctransfer module to.", + "type": "object", + "required": [ + "transfer" + ], + "properties": { + "transfer": { + "type": "object", + "required": [ + "amount", + "channel_id", + "timeout", + "to_address" + ], + "properties": { + "amount": { + "description": "packet data only supports one coin https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/ibc/applications/transfer/v1/transfer.proto#L11-L20", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "channel_id": { + "description": "exisiting channel to send the tokens over", + "type": "string" + }, + "timeout": { + "description": "when packet times out, measured on remote chain", + "allOf": [ + { + "$ref": "#/definitions/IbcTimeout" + } + ] + }, + "to_address": { + "description": "address on the remote chain to receive these tokens", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Sends an IBC packet with given data over the existing channel. Data should be encoded in a format defined by the channel version, and the module on the other side should know how to parse this.", + "type": "object", + "required": [ + "send_packet" + ], + "properties": { + "send_packet": { + "type": "object", + "required": [ + "channel_id", + "data", + "timeout" + ], + "properties": { + "channel_id": { + "type": "string" + }, + "data": { + "$ref": "#/definitions/Binary" + }, + "timeout": { + "description": "when packet times out, measured on remote chain", + "allOf": [ + { + "$ref": "#/definitions/IbcTimeout" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This will close an existing channel that is owned by this contract. Port is auto-assigned to the contract's IBC port", + "type": "object", + "required": [ + "close_channel" + ], + "properties": { + "close_channel": { + "type": "object", + "required": [ + "channel_id" + ], + "properties": { + "channel_id": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcTimeout": { + "description": "In IBC each package must set at least one type of timeout: the timestamp or the block height. Using this rather complex enum instead of two timeout fields we ensure that at least one timeout is set.", + "type": "object", + "properties": { + "block": { + "anyOf": [ + { + "$ref": "#/definitions/IbcTimeoutBlock" + }, + { + "type": "null" + } + ] + }, + "timestamp": { + "anyOf": [ + { + "$ref": "#/definitions/Timestamp" + }, + { + "type": "null" + } + ] + } + } + }, + "IbcTimeoutBlock": { + "description": "IBCTimeoutHeight Height is a monotonically increasing data type that can be compared against another Height for the purposes of updating and freezing clients. Ordering is (revision_number, timeout_height)", + "type": "object", + "required": [ + "height", + "revision" + ], + "properties": { + "height": { + "description": "block height after which the packet times out. the height within the given revision", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "revision": { + "description": "the version that the client is currently on (eg. after reseting the chain this could increment 1 as height drops to 0)", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + }, + "MemberChangedHookMsg": { + "description": "MemberChangedHookMsg should be de/serialized under `MemberChangedHook()` variant in a ExecuteMsg. This contains a list of all diffs on the given transaction.", + "type": "object", + "required": [ + "diffs" + ], + "properties": { + "diffs": { + "type": "array", + "items": { + "$ref": "#/definitions/MemberDiff" + } + } + }, + "additionalProperties": false + }, + "MemberDiff": { + "description": "MemberDiff shows the old and new states for a given cw4 member They cannot both be None. old = None, new = Some -> Insert old = Some, new = Some -> Update old = Some, new = None -> Delete", + "type": "object", + "required": [ + "key" + ], + "properties": { + "key": { + "type": "string" + }, + "new": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + }, + "old": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "StakingMsg": { + "description": "The message types of the staking module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto", + "oneOf": [ + { + "description": "This is translated to a [MsgDelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L81-L90). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "delegate" + ], + "properties": { + "delegate": { + "type": "object", + "required": [ + "amount", + "validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [MsgUndelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L112-L121). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "undelegate" + ], + "properties": { + "undelegate": { + "type": "object", + "required": [ + "amount", + "validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [MsgBeginRedelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L95-L105). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "redelegate" + ], + "properties": { + "redelegate": { + "type": "object", + "required": [ + "amount", + "dst_validator", + "src_validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "dst_validator": { + "type": "string" + }, + "src_validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + }, + "Vote": { + "oneOf": [ + { + "description": "Marks support for the proposal.", + "type": "string", + "enum": [ + "yes" + ] + }, + { + "description": "Marks opposition to the proposal.", + "type": "string", + "enum": [ + "no" + ] + }, + { + "description": "Marks participation but does not count towards the ratio of support / opposed", + "type": "string", + "enum": [ + "abstain" + ] + }, + { + "description": "Veto is generally to be treated as a No vote. Some implementations may allow certain voters to be able to Veto, or them to be counted stronger than No in some way.", + "type": "string", + "enum": [ + "veto" + ] + } + ] + }, + "VoteOption": { + "type": "string", + "enum": [ + "yes", + "no", + "abstain", + "no_with_veto" + ] + }, + "WasmMsg": { + "description": "The message types of the wasm module.\n\nSee https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto", + "oneOf": [ + { + "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L68-L78). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "execute" + ], + "properties": { + "execute": { + "type": "object", + "required": [ + "contract_addr", + "funds", + "msg" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "msg": { + "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThe contract address is non-predictable. But it is guaranteed that when emitting the same Instantiate message multiple times, multiple instances on different addresses will be generated. See also Instantiate2.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/CosmWasm/wasmd/blob/v0.29.2/proto/cosmwasm/wasm/v1/tx.proto#L53-L71). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "instantiate" + ], + "properties": { + "instantiate": { + "type": "object", + "required": [ + "code_id", + "funds", + "label", + "msg" + ], + "properties": { + "admin": { + "type": [ + "string", + "null" + ] + }, + "code_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "label": { + "description": "A human-readbale label for the contract", + "type": "string" + }, + "msg": { + "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "migrate" + ], + "properties": { + "migrate": { + "type": "object", + "required": [ + "contract_addr", + "msg", + "new_code_id" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "msg": { + "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + }, + "new_code_id": { + "description": "the code_id of the new logic to place in the given contract", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", + "type": "object", + "required": [ + "update_admin" + ], + "properties": { + "update_admin": { + "type": "object", + "required": [ + "admin", + "contract_addr" + ], + "properties": { + "admin": { + "type": "string" + }, + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", + "type": "object", + "required": [ + "clear_admin" + ], + "properties": { + "clear_admin": { + "type": "object", + "required": [ + "contract_addr" + ], + "properties": { + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + } + } +} diff --git a/contracts/multisig/cw3-flex-multisig/schema/raw/instantiate.json b/contracts/multisig/cw3-flex-multisig/schema/raw/instantiate.json new file mode 100644 index 0000000000..90fa8736e6 --- /dev/null +++ b/contracts/multisig/cw3-flex-multisig/schema/raw/instantiate.json @@ -0,0 +1,261 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "coconut_bandwidth_contract_address", + "coconut_dkg_contract_address", + "group_addr", + "max_voting_period", + "threshold" + ], + "properties": { + "coconut_bandwidth_contract_address": { + "type": "string" + }, + "coconut_dkg_contract_address": { + "type": "string" + }, + "executor": { + "anyOf": [ + { + "$ref": "#/definitions/Executor" + }, + { + "type": "null" + } + ] + }, + "group_addr": { + "type": "string" + }, + "max_voting_period": { + "$ref": "#/definitions/Duration" + }, + "proposal_deposit": { + "description": "The cost of creating a proposal (if any).", + "anyOf": [ + { + "$ref": "#/definitions/UncheckedDepositInfo" + }, + { + "type": "null" + } + ] + }, + "threshold": { + "$ref": "#/definitions/Threshold" + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Duration": { + "description": "Duration is a delta of time. You can add it to a BlockInfo or Expiration to move that further in the future. Note that an height-based Duration and a time-based Expiration cannot be combined", + "oneOf": [ + { + "type": "object", + "required": [ + "height" + ], + "properties": { + "height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "Time in seconds", + "type": "object", + "required": [ + "time" + ], + "properties": { + "time": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + ] + }, + "Executor": { + "description": "Defines who is able to execute proposals once passed", + "oneOf": [ + { + "description": "Any member of the voting group, even with 0 points", + "type": "string", + "enum": [ + "member" + ] + }, + { + "description": "Only the given address", + "type": "object", + "required": [ + "only" + ], + "properties": { + "only": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + ] + }, + "Threshold": { + "description": "This defines the different ways tallies can happen.\n\nThe total_weight used for calculating success as well as the weights of each individual voter used in tallying should be snapshotted at the beginning of the block at which the proposal starts (this is likely the responsibility of a correct cw4 implementation). See also `ThresholdResponse` in the cw3 spec.", + "oneOf": [ + { + "description": "Declares that a fixed weight of Yes votes is needed to pass. See `ThresholdResponse.AbsoluteCount` in the cw3 spec for details.", + "type": "object", + "required": [ + "absolute_count" + ], + "properties": { + "absolute_count": { + "type": "object", + "required": [ + "weight" + ], + "properties": { + "weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Declares a percentage of the total weight that must cast Yes votes in order for a proposal to pass. See `ThresholdResponse.AbsolutePercentage` in the cw3 spec for details.", + "type": "object", + "required": [ + "absolute_percentage" + ], + "properties": { + "absolute_percentage": { + "type": "object", + "required": [ + "percentage" + ], + "properties": { + "percentage": { + "$ref": "#/definitions/Decimal" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Declares a `quorum` of the total votes that must participate in the election in order for the vote to be considered at all. See `ThresholdResponse.ThresholdQuorum` in the cw3 spec for details.", + "type": "object", + "required": [ + "threshold_quorum" + ], + "properties": { + "threshold_quorum": { + "type": "object", + "required": [ + "quorum", + "threshold" + ], + "properties": { + "quorum": { + "$ref": "#/definitions/Decimal" + }, + "threshold": { + "$ref": "#/definitions/Decimal" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "UncheckedDenom": { + "oneOf": [ + { + "type": "object", + "required": [ + "native" + ], + "properties": { + "native": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "cw20" + ], + "properties": { + "cw20": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "UncheckedDepositInfo": { + "description": "Information about the deposit required to create a proposal. For use in messages. To validate, transform into `DepositInfo` via `into_checked()`.", + "type": "object", + "required": [ + "amount", + "denom", + "refund_failed_proposals" + ], + "properties": { + "amount": { + "description": "The number tokens required for payment.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "denom": { + "description": "The denom of the deposit payment.", + "allOf": [ + { + "$ref": "#/definitions/UncheckedDenom" + } + ] + }, + "refund_failed_proposals": { + "description": "Should failed proposals have their deposits refunded?", + "type": "boolean" + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/multisig/cw3-flex-multisig/schema/raw/migrate.json b/contracts/multisig/cw3-flex-multisig/schema/raw/migrate.json new file mode 100644 index 0000000000..b983a8e05c --- /dev/null +++ b/contracts/multisig/cw3-flex-multisig/schema/raw/migrate.json @@ -0,0 +1,18 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "type": "object", + "required": [ + "coconut_bandwidth_address", + "coconut_dkg_address" + ], + "properties": { + "coconut_bandwidth_address": { + "type": "string" + }, + "coconut_dkg_address": { + "type": "string" + } + }, + "additionalProperties": false +} diff --git a/contracts/multisig/cw3-flex-multisig/schema/raw/query.json b/contracts/multisig/cw3-flex-multisig/schema/raw/query.json new file mode 100644 index 0000000000..570a727999 --- /dev/null +++ b/contracts/multisig/cw3-flex-multisig/schema/raw/query.json @@ -0,0 +1,232 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "threshold" + ], + "properties": { + "threshold": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "proposal" + ], + "properties": { + "proposal": { + "type": "object", + "required": [ + "proposal_id" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "list_proposals" + ], + "properties": { + "list_proposals": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "reverse_proposals" + ], + "properties": { + "reverse_proposals": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_before": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "vote" + ], + "properties": { + "vote": { + "type": "object", + "required": [ + "proposal_id", + "voter" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "voter": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "list_votes" + ], + "properties": { + "list_votes": { + "type": "object", + "required": [ + "proposal_id" + ], + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "voter" + ], + "properties": { + "voter": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "list_voters" + ], + "properties": { + "list_voters": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the current configuration.", + "type": "object", + "required": [ + "config" + ], + "properties": { + "config": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] +} diff --git a/contracts/multisig/cw3-flex-multisig/schema/raw/response_to_config.json b/contracts/multisig/cw3-flex-multisig/schema/raw/response_to_config.json new file mode 100644 index 0000000000..b5388ddae1 --- /dev/null +++ b/contracts/multisig/cw3-flex-multisig/schema/raw/response_to_config.json @@ -0,0 +1,269 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Config", + "type": "object", + "required": [ + "coconut_bandwidth_addr", + "coconut_dkg_addr", + "group_addr", + "max_voting_period", + "threshold" + ], + "properties": { + "coconut_bandwidth_addr": { + "$ref": "#/definitions/Addr" + }, + "coconut_dkg_addr": { + "$ref": "#/definitions/Addr" + }, + "executor": { + "anyOf": [ + { + "$ref": "#/definitions/Executor" + }, + { + "type": "null" + } + ] + }, + "group_addr": { + "$ref": "#/definitions/Cw4Contract" + }, + "max_voting_period": { + "$ref": "#/definitions/Duration" + }, + "proposal_deposit": { + "description": "The price, if any, of creating a new proposal.", + "anyOf": [ + { + "$ref": "#/definitions/DepositInfo" + }, + { + "type": "null" + } + ] + }, + "threshold": { + "$ref": "#/definitions/Threshold" + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Cw4Contract": { + "description": "Cw4Contract is a wrapper around Addr that provides a lot of helpers for working with cw4 contracts\n\nIf you wish to persist this, convert to Cw4CanonicalContract via .canonical()", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Denom": { + "oneOf": [ + { + "type": "object", + "required": [ + "native" + ], + "properties": { + "native": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "cw20" + ], + "properties": { + "cw20": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + ] + }, + "DepositInfo": { + "description": "Information about the deposit required to create a proposal.", + "type": "object", + "required": [ + "amount", + "denom", + "refund_failed_proposals" + ], + "properties": { + "amount": { + "description": "The number tokens required for payment.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "denom": { + "description": "The denom of the deposit payment.", + "allOf": [ + { + "$ref": "#/definitions/Denom" + } + ] + }, + "refund_failed_proposals": { + "description": "Should failed proposals have their deposits refunded?", + "type": "boolean" + } + }, + "additionalProperties": false + }, + "Duration": { + "description": "Duration is a delta of time. You can add it to a BlockInfo or Expiration to move that further in the future. Note that an height-based Duration and a time-based Expiration cannot be combined", + "oneOf": [ + { + "type": "object", + "required": [ + "height" + ], + "properties": { + "height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "Time in seconds", + "type": "object", + "required": [ + "time" + ], + "properties": { + "time": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + ] + }, + "Executor": { + "description": "Defines who is able to execute proposals once passed", + "oneOf": [ + { + "description": "Any member of the voting group, even with 0 points", + "type": "string", + "enum": [ + "member" + ] + }, + { + "description": "Only the given address", + "type": "object", + "required": [ + "only" + ], + "properties": { + "only": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + ] + }, + "Threshold": { + "description": "This defines the different ways tallies can happen.\n\nThe total_weight used for calculating success as well as the weights of each individual voter used in tallying should be snapshotted at the beginning of the block at which the proposal starts (this is likely the responsibility of a correct cw4 implementation). See also `ThresholdResponse` in the cw3 spec.", + "oneOf": [ + { + "description": "Declares that a fixed weight of Yes votes is needed to pass. See `ThresholdResponse.AbsoluteCount` in the cw3 spec for details.", + "type": "object", + "required": [ + "absolute_count" + ], + "properties": { + "absolute_count": { + "type": "object", + "required": [ + "weight" + ], + "properties": { + "weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Declares a percentage of the total weight that must cast Yes votes in order for a proposal to pass. See `ThresholdResponse.AbsolutePercentage` in the cw3 spec for details.", + "type": "object", + "required": [ + "absolute_percentage" + ], + "properties": { + "absolute_percentage": { + "type": "object", + "required": [ + "percentage" + ], + "properties": { + "percentage": { + "$ref": "#/definitions/Decimal" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Declares a `quorum` of the total votes that must participate in the election in order for the vote to be considered at all. See `ThresholdResponse.ThresholdQuorum` in the cw3 spec for details.", + "type": "object", + "required": [ + "threshold_quorum" + ], + "properties": { + "threshold_quorum": { + "type": "object", + "required": [ + "quorum", + "threshold" + ], + "properties": { + "quorum": { + "$ref": "#/definitions/Decimal" + }, + "threshold": { + "$ref": "#/definitions/Decimal" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/multisig/cw3-flex-multisig/schema/raw/response_to_list_proposals.json b/contracts/multisig/cw3-flex-multisig/schema/raw/response_to_list_proposals.json new file mode 100644 index 0000000000..0012bec80b --- /dev/null +++ b/contracts/multisig/cw3-flex-multisig/schema/raw/response_to_list_proposals.json @@ -0,0 +1,1045 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ProposalListResponse_for_Empty", + "type": "object", + "required": [ + "proposals" + ], + "properties": { + "proposals": { + "type": "array", + "items": { + "$ref": "#/definitions/ProposalResponse_for_Empty" + } + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "BankMsg": { + "description": "The message types of the bank module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto", + "oneOf": [ + { + "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "send" + ], + "properties": { + "send": { + "type": "object", + "required": [ + "amount", + "to_address" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "to_address": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", + "type": "object", + "required": [ + "burn" + ], + "properties": { + "burn": { + "type": "object", + "required": [ + "amount" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "CosmosMsg_for_Empty": { + "oneOf": [ + { + "type": "object", + "required": [ + "bank" + ], + "properties": { + "bank": { + "$ref": "#/definitions/BankMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "custom" + ], + "properties": { + "custom": { + "$ref": "#/definitions/Empty" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "staking" + ], + "properties": { + "staking": { + "$ref": "#/definitions/StakingMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "distribution" + ], + "properties": { + "distribution": { + "$ref": "#/definitions/DistributionMsg" + } + }, + "additionalProperties": false + }, + { + "description": "A Stargate message encoded the same way as a protobuf [Any](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto). This is the same structure as messages in `TxBody` from [ADR-020](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-020-protobuf-transaction-encoding.md)", + "type": "object", + "required": [ + "stargate" + ], + "properties": { + "stargate": { + "type": "object", + "required": [ + "type_url", + "value" + ], + "properties": { + "type_url": { + "type": "string" + }, + "value": { + "$ref": "#/definitions/Binary" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "ibc" + ], + "properties": { + "ibc": { + "$ref": "#/definitions/IbcMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "wasm" + ], + "properties": { + "wasm": { + "$ref": "#/definitions/WasmMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "gov" + ], + "properties": { + "gov": { + "$ref": "#/definitions/GovMsg" + } + }, + "additionalProperties": false + } + ] + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Denom": { + "oneOf": [ + { + "type": "object", + "required": [ + "native" + ], + "properties": { + "native": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "cw20" + ], + "properties": { + "cw20": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + ] + }, + "DepositInfo": { + "description": "Information about the deposit required to create a proposal.", + "type": "object", + "required": [ + "amount", + "denom", + "refund_failed_proposals" + ], + "properties": { + "amount": { + "description": "The number tokens required for payment.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "denom": { + "description": "The denom of the deposit payment.", + "allOf": [ + { + "$ref": "#/definitions/Denom" + } + ] + }, + "refund_failed_proposals": { + "description": "Should failed proposals have their deposits refunded?", + "type": "boolean" + } + }, + "additionalProperties": false + }, + "DistributionMsg": { + "description": "The message types of the distribution module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto", + "oneOf": [ + { + "description": "This is translated to a [MsgSetWithdrawAddress](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L29-L37). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "set_withdraw_address" + ], + "properties": { + "set_withdraw_address": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "The `withdraw_address`", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [[MsgWithdrawDelegatorReward](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L42-L50). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "withdraw_delegator_reward" + ], + "properties": { + "withdraw_delegator_reward": { + "type": "object", + "required": [ + "validator" + ], + "properties": { + "validator": { + "description": "The `validator_address`", + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Empty": { + "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", + "type": "object" + }, + "Expiration": { + "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", + "oneOf": [ + { + "description": "AtHeight will expire when `env.block.height` >= height", + "type": "object", + "required": [ + "at_height" + ], + "properties": { + "at_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "AtTime will expire when `env.block.time` >= time", + "type": "object", + "required": [ + "at_time" + ], + "properties": { + "at_time": { + "$ref": "#/definitions/Timestamp" + } + }, + "additionalProperties": false + }, + { + "description": "Never will never expire. Used to express the empty variant", + "type": "object", + "required": [ + "never" + ], + "properties": { + "never": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "GovMsg": { + "description": "This message type allows the contract interact with the [x/gov] module in order to cast votes.\n\n[x/gov]: https://github.com/cosmos/cosmos-sdk/tree/v0.45.12/x/gov\n\n## Examples\n\nCast a simple vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); use cosmwasm_std::{GovMsg, VoteOption};\n\n#[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::Vote { proposal_id: 4, vote: VoteOption::Yes, })) } ```\n\nCast a weighted vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); # #[cfg(feature = \"cosmwasm_1_2\")] use cosmwasm_std::{Decimal, GovMsg, VoteOption, WeightedVoteOption};\n\n# #[cfg(feature = \"cosmwasm_1_2\")] #[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::VoteWeighted { proposal_id: 4, options: vec![ WeightedVoteOption { option: VoteOption::Yes, weight: Decimal::percent(65), }, WeightedVoteOption { option: VoteOption::Abstain, weight: Decimal::percent(35), }, ], })) } ```", + "oneOf": [ + { + "description": "This maps directly to [MsgVote](https://github.com/cosmos/cosmos-sdk/blob/v0.42.5/proto/cosmos/gov/v1beta1/tx.proto#L46-L56) in the Cosmos SDK with voter set to the contract address.", + "type": "object", + "required": [ + "vote" + ], + "properties": { + "vote": { + "type": "object", + "required": [ + "proposal_id", + "vote" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "vote": { + "description": "The vote option.\n\nThis should be called \"option\" for consistency with Cosmos SDK. Sorry for that. See .", + "allOf": [ + { + "$ref": "#/definitions/VoteOption" + } + ] + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcMsg": { + "description": "These are messages in the IBC lifecycle. Only usable by IBC-enabled contracts (contracts that directly speak the IBC protocol via 6 entry points)", + "oneOf": [ + { + "description": "Sends bank tokens owned by the contract to the given address on another chain. The channel must already be established between the ibctransfer module on this chain and a matching module on the remote chain. We cannot select the port_id, this is whatever the local chain has bound the ibctransfer module to.", + "type": "object", + "required": [ + "transfer" + ], + "properties": { + "transfer": { + "type": "object", + "required": [ + "amount", + "channel_id", + "timeout", + "to_address" + ], + "properties": { + "amount": { + "description": "packet data only supports one coin https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/ibc/applications/transfer/v1/transfer.proto#L11-L20", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "channel_id": { + "description": "exisiting channel to send the tokens over", + "type": "string" + }, + "timeout": { + "description": "when packet times out, measured on remote chain", + "allOf": [ + { + "$ref": "#/definitions/IbcTimeout" + } + ] + }, + "to_address": { + "description": "address on the remote chain to receive these tokens", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Sends an IBC packet with given data over the existing channel. Data should be encoded in a format defined by the channel version, and the module on the other side should know how to parse this.", + "type": "object", + "required": [ + "send_packet" + ], + "properties": { + "send_packet": { + "type": "object", + "required": [ + "channel_id", + "data", + "timeout" + ], + "properties": { + "channel_id": { + "type": "string" + }, + "data": { + "$ref": "#/definitions/Binary" + }, + "timeout": { + "description": "when packet times out, measured on remote chain", + "allOf": [ + { + "$ref": "#/definitions/IbcTimeout" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This will close an existing channel that is owned by this contract. Port is auto-assigned to the contract's IBC port", + "type": "object", + "required": [ + "close_channel" + ], + "properties": { + "close_channel": { + "type": "object", + "required": [ + "channel_id" + ], + "properties": { + "channel_id": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcTimeout": { + "description": "In IBC each package must set at least one type of timeout: the timestamp or the block height. Using this rather complex enum instead of two timeout fields we ensure that at least one timeout is set.", + "type": "object", + "properties": { + "block": { + "anyOf": [ + { + "$ref": "#/definitions/IbcTimeoutBlock" + }, + { + "type": "null" + } + ] + }, + "timestamp": { + "anyOf": [ + { + "$ref": "#/definitions/Timestamp" + }, + { + "type": "null" + } + ] + } + } + }, + "IbcTimeoutBlock": { + "description": "IBCTimeoutHeight Height is a monotonically increasing data type that can be compared against another Height for the purposes of updating and freezing clients. Ordering is (revision_number, timeout_height)", + "type": "object", + "required": [ + "height", + "revision" + ], + "properties": { + "height": { + "description": "block height after which the packet times out. the height within the given revision", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "revision": { + "description": "the version that the client is currently on (eg. after reseting the chain this could increment 1 as height drops to 0)", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + }, + "ProposalResponse_for_Empty": { + "description": "Note, if you are storing custom messages in the proposal, the querier needs to know what possible custom message types those are in order to parse the response", + "type": "object", + "required": [ + "description", + "expires", + "id", + "msgs", + "proposer", + "status", + "threshold", + "title" + ], + "properties": { + "deposit": { + "anyOf": [ + { + "$ref": "#/definitions/DepositInfo" + }, + { + "type": "null" + } + ] + }, + "description": { + "type": "string" + }, + "expires": { + "$ref": "#/definitions/Expiration" + }, + "id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "msgs": { + "type": "array", + "items": { + "$ref": "#/definitions/CosmosMsg_for_Empty" + } + }, + "proposer": { + "$ref": "#/definitions/Addr" + }, + "status": { + "$ref": "#/definitions/Status" + }, + "threshold": { + "description": "This is the threshold that is applied to this proposal. Both the rules of the voting contract, as well as the total_weight of the voting group may have changed since this time. That means that the generic `Threshold{}` query does not provide valid information for existing proposals.", + "allOf": [ + { + "$ref": "#/definitions/ThresholdResponse" + } + ] + }, + "title": { + "type": "string" + } + }, + "additionalProperties": false + }, + "StakingMsg": { + "description": "The message types of the staking module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto", + "oneOf": [ + { + "description": "This is translated to a [MsgDelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L81-L90). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "delegate" + ], + "properties": { + "delegate": { + "type": "object", + "required": [ + "amount", + "validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [MsgUndelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L112-L121). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "undelegate" + ], + "properties": { + "undelegate": { + "type": "object", + "required": [ + "amount", + "validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [MsgBeginRedelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L95-L105). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "redelegate" + ], + "properties": { + "redelegate": { + "type": "object", + "required": [ + "amount", + "dst_validator", + "src_validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "dst_validator": { + "type": "string" + }, + "src_validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Status": { + "oneOf": [ + { + "description": "proposal was created, but voting has not yet begun for whatever reason", + "type": "string", + "enum": [ + "pending" + ] + }, + { + "description": "you can vote on this", + "type": "string", + "enum": [ + "open" + ] + }, + { + "description": "voting is over and it did not pass", + "type": "string", + "enum": [ + "rejected" + ] + }, + { + "description": "voting is over and it did pass, but has not yet executed", + "type": "string", + "enum": [ + "passed" + ] + }, + { + "description": "voting is over it passed, and the proposal was executed", + "type": "string", + "enum": [ + "executed" + ] + } + ] + }, + "ThresholdResponse": { + "description": "This defines the different ways tallies can happen. Every contract should support a subset of these, ideally all.\n\nThe total_weight used for calculating success as well as the weights of each individual voter used in tallying should be snapshotted at the beginning of the block at which the proposal starts (this is likely the responsibility of a correct cw4 implementation).", + "oneOf": [ + { + "description": "Declares that a fixed weight of yes votes is needed to pass. It does not matter how many no votes are cast, or how many do not vote, as long as `weight` yes votes are cast.\n\nThis is the simplest format and usually suitable for small multisigs of trusted parties, like 3 of 5. (weight: 3, total_weight: 5)\n\nA proposal of this type can pass early as soon as the needed weight of yes votes has been cast.", + "type": "object", + "required": [ + "absolute_count" + ], + "properties": { + "absolute_count": { + "type": "object", + "required": [ + "total_weight", + "weight" + ], + "properties": { + "total_weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Declares a percentage of the total weight that must cast Yes votes, in order for a proposal to pass. The passing weight is computed over the total weight minus the weight of the abstained votes.\n\nThis is useful for similar circumstances as `AbsoluteCount`, where we have a relatively small set of voters, and participation is required. It is understood that if the voting set (group) changes between different proposals that refer to the same group, each proposal will work with a different set of voter weights (the ones snapshotted at proposal creation), and the passing weight for each proposal will be computed based on the absolute percentage, times the total weights of the members at the time of each proposal creation.\n\nExample: we set `percentage` to 51%. Proposal 1 starts when there is a `total_weight` of 5. This will require 3 weight of Yes votes in order to pass. Later, the Proposal 2 starts but the `total_weight` of the group has increased to 9. That proposal will then automatically require 5 Yes of 9 to pass, rather than 3 yes of 9 as would be the case with `AbsoluteCount`.", + "type": "object", + "required": [ + "absolute_percentage" + ], + "properties": { + "absolute_percentage": { + "type": "object", + "required": [ + "percentage", + "total_weight" + ], + "properties": { + "percentage": { + "$ref": "#/definitions/Decimal" + }, + "total_weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "In addition to a `threshold`, declares a `quorum` of the total votes that must participate in the election in order for the vote to be considered at all. Within the votes that were cast, it requires `threshold` votes in favor. That is calculated by ignoring the Abstain votes (they count towards `quorum`, but do not influence `threshold`). That is, we calculate `Yes / (Yes + No + Veto)` and compare it with `threshold` to consider if the proposal was passed.\n\nIt is rather difficult for a proposal of this type to pass early. That can only happen if the required quorum has been already met, and there are already enough Yes votes for the proposal to pass.\n\n30% Yes votes, 10% No votes, and 20% Abstain would pass early if quorum <= 60% (who has cast votes) and if the threshold is <= 37.5% (the remaining 40% voting no => 30% yes + 50% no). Once the voting period has passed with no additional votes, that same proposal would be considered successful if quorum <= 60% and threshold <= 75% (percent in favor if we ignore abstain votes).\n\nThis type is more common in general elections, where participation is often expected to be low, and `AbsolutePercentage` would either be too high to pass anything, or allow low percentages to pass, independently of if there was high participation in the election or not.", + "type": "object", + "required": [ + "threshold_quorum" + ], + "properties": { + "threshold_quorum": { + "type": "object", + "required": [ + "quorum", + "threshold", + "total_weight" + ], + "properties": { + "quorum": { + "$ref": "#/definitions/Decimal" + }, + "threshold": { + "$ref": "#/definitions/Decimal" + }, + "total_weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + }, + "VoteOption": { + "type": "string", + "enum": [ + "yes", + "no", + "abstain", + "no_with_veto" + ] + }, + "WasmMsg": { + "description": "The message types of the wasm module.\n\nSee https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto", + "oneOf": [ + { + "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L68-L78). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "execute" + ], + "properties": { + "execute": { + "type": "object", + "required": [ + "contract_addr", + "funds", + "msg" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "msg": { + "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThe contract address is non-predictable. But it is guaranteed that when emitting the same Instantiate message multiple times, multiple instances on different addresses will be generated. See also Instantiate2.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/CosmWasm/wasmd/blob/v0.29.2/proto/cosmwasm/wasm/v1/tx.proto#L53-L71). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "instantiate" + ], + "properties": { + "instantiate": { + "type": "object", + "required": [ + "code_id", + "funds", + "label", + "msg" + ], + "properties": { + "admin": { + "type": [ + "string", + "null" + ] + }, + "code_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "label": { + "description": "A human-readbale label for the contract", + "type": "string" + }, + "msg": { + "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "migrate" + ], + "properties": { + "migrate": { + "type": "object", + "required": [ + "contract_addr", + "msg", + "new_code_id" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "msg": { + "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + }, + "new_code_id": { + "description": "the code_id of the new logic to place in the given contract", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", + "type": "object", + "required": [ + "update_admin" + ], + "properties": { + "update_admin": { + "type": "object", + "required": [ + "admin", + "contract_addr" + ], + "properties": { + "admin": { + "type": "string" + }, + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", + "type": "object", + "required": [ + "clear_admin" + ], + "properties": { + "clear_admin": { + "type": "object", + "required": [ + "contract_addr" + ], + "properties": { + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + } + } +} diff --git a/contracts/multisig/cw3-flex-multisig/schema/raw/response_to_list_voters.json b/contracts/multisig/cw3-flex-multisig/schema/raw/response_to_list_voters.json new file mode 100644 index 0000000000..9e337d64ea --- /dev/null +++ b/contracts/multisig/cw3-flex-multisig/schema/raw/response_to_list_voters.json @@ -0,0 +1,37 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "VoterListResponse", + "type": "object", + "required": [ + "voters" + ], + "properties": { + "voters": { + "type": "array", + "items": { + "$ref": "#/definitions/VoterDetail" + } + } + }, + "additionalProperties": false, + "definitions": { + "VoterDetail": { + "type": "object", + "required": [ + "addr", + "weight" + ], + "properties": { + "addr": { + "type": "string" + }, + "weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/multisig/cw3-flex-multisig/schema/raw/response_to_list_votes.json b/contracts/multisig/cw3-flex-multisig/schema/raw/response_to_list_votes.json new file mode 100644 index 0000000000..90a4c459b0 --- /dev/null +++ b/contracts/multisig/cw3-flex-multisig/schema/raw/response_to_list_votes.json @@ -0,0 +1,80 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "VoteListResponse", + "type": "object", + "required": [ + "votes" + ], + "properties": { + "votes": { + "type": "array", + "items": { + "$ref": "#/definitions/VoteInfo" + } + } + }, + "additionalProperties": false, + "definitions": { + "Vote": { + "oneOf": [ + { + "description": "Marks support for the proposal.", + "type": "string", + "enum": [ + "yes" + ] + }, + { + "description": "Marks opposition to the proposal.", + "type": "string", + "enum": [ + "no" + ] + }, + { + "description": "Marks participation but does not count towards the ratio of support / opposed", + "type": "string", + "enum": [ + "abstain" + ] + }, + { + "description": "Veto is generally to be treated as a No vote. Some implementations may allow certain voters to be able to Veto, or them to be counted stronger than No in some way.", + "type": "string", + "enum": [ + "veto" + ] + } + ] + }, + "VoteInfo": { + "description": "Returns the vote (opinion as well as weight counted) as well as the address of the voter who submitted it", + "type": "object", + "required": [ + "proposal_id", + "vote", + "voter", + "weight" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "vote": { + "$ref": "#/definitions/Vote" + }, + "voter": { + "type": "string" + }, + "weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/multisig/cw3-flex-multisig/schema/raw/response_to_proposal.json b/contracts/multisig/cw3-flex-multisig/schema/raw/response_to_proposal.json new file mode 100644 index 0000000000..751ed3c7bc --- /dev/null +++ b/contracts/multisig/cw3-flex-multisig/schema/raw/response_to_proposal.json @@ -0,0 +1,1030 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ProposalResponse_for_Empty", + "description": "Note, if you are storing custom messages in the proposal, the querier needs to know what possible custom message types those are in order to parse the response", + "type": "object", + "required": [ + "description", + "expires", + "id", + "msgs", + "proposer", + "status", + "threshold", + "title" + ], + "properties": { + "deposit": { + "anyOf": [ + { + "$ref": "#/definitions/DepositInfo" + }, + { + "type": "null" + } + ] + }, + "description": { + "type": "string" + }, + "expires": { + "$ref": "#/definitions/Expiration" + }, + "id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "msgs": { + "type": "array", + "items": { + "$ref": "#/definitions/CosmosMsg_for_Empty" + } + }, + "proposer": { + "$ref": "#/definitions/Addr" + }, + "status": { + "$ref": "#/definitions/Status" + }, + "threshold": { + "description": "This is the threshold that is applied to this proposal. Both the rules of the voting contract, as well as the total_weight of the voting group may have changed since this time. That means that the generic `Threshold{}` query does not provide valid information for existing proposals.", + "allOf": [ + { + "$ref": "#/definitions/ThresholdResponse" + } + ] + }, + "title": { + "type": "string" + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "BankMsg": { + "description": "The message types of the bank module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto", + "oneOf": [ + { + "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "send" + ], + "properties": { + "send": { + "type": "object", + "required": [ + "amount", + "to_address" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "to_address": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", + "type": "object", + "required": [ + "burn" + ], + "properties": { + "burn": { + "type": "object", + "required": [ + "amount" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "CosmosMsg_for_Empty": { + "oneOf": [ + { + "type": "object", + "required": [ + "bank" + ], + "properties": { + "bank": { + "$ref": "#/definitions/BankMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "custom" + ], + "properties": { + "custom": { + "$ref": "#/definitions/Empty" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "staking" + ], + "properties": { + "staking": { + "$ref": "#/definitions/StakingMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "distribution" + ], + "properties": { + "distribution": { + "$ref": "#/definitions/DistributionMsg" + } + }, + "additionalProperties": false + }, + { + "description": "A Stargate message encoded the same way as a protobuf [Any](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto). This is the same structure as messages in `TxBody` from [ADR-020](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-020-protobuf-transaction-encoding.md)", + "type": "object", + "required": [ + "stargate" + ], + "properties": { + "stargate": { + "type": "object", + "required": [ + "type_url", + "value" + ], + "properties": { + "type_url": { + "type": "string" + }, + "value": { + "$ref": "#/definitions/Binary" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "ibc" + ], + "properties": { + "ibc": { + "$ref": "#/definitions/IbcMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "wasm" + ], + "properties": { + "wasm": { + "$ref": "#/definitions/WasmMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "gov" + ], + "properties": { + "gov": { + "$ref": "#/definitions/GovMsg" + } + }, + "additionalProperties": false + } + ] + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Denom": { + "oneOf": [ + { + "type": "object", + "required": [ + "native" + ], + "properties": { + "native": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "cw20" + ], + "properties": { + "cw20": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + ] + }, + "DepositInfo": { + "description": "Information about the deposit required to create a proposal.", + "type": "object", + "required": [ + "amount", + "denom", + "refund_failed_proposals" + ], + "properties": { + "amount": { + "description": "The number tokens required for payment.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "denom": { + "description": "The denom of the deposit payment.", + "allOf": [ + { + "$ref": "#/definitions/Denom" + } + ] + }, + "refund_failed_proposals": { + "description": "Should failed proposals have their deposits refunded?", + "type": "boolean" + } + }, + "additionalProperties": false + }, + "DistributionMsg": { + "description": "The message types of the distribution module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto", + "oneOf": [ + { + "description": "This is translated to a [MsgSetWithdrawAddress](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L29-L37). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "set_withdraw_address" + ], + "properties": { + "set_withdraw_address": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "The `withdraw_address`", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [[MsgWithdrawDelegatorReward](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L42-L50). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "withdraw_delegator_reward" + ], + "properties": { + "withdraw_delegator_reward": { + "type": "object", + "required": [ + "validator" + ], + "properties": { + "validator": { + "description": "The `validator_address`", + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Empty": { + "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", + "type": "object" + }, + "Expiration": { + "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", + "oneOf": [ + { + "description": "AtHeight will expire when `env.block.height` >= height", + "type": "object", + "required": [ + "at_height" + ], + "properties": { + "at_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "AtTime will expire when `env.block.time` >= time", + "type": "object", + "required": [ + "at_time" + ], + "properties": { + "at_time": { + "$ref": "#/definitions/Timestamp" + } + }, + "additionalProperties": false + }, + { + "description": "Never will never expire. Used to express the empty variant", + "type": "object", + "required": [ + "never" + ], + "properties": { + "never": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "GovMsg": { + "description": "This message type allows the contract interact with the [x/gov] module in order to cast votes.\n\n[x/gov]: https://github.com/cosmos/cosmos-sdk/tree/v0.45.12/x/gov\n\n## Examples\n\nCast a simple vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); use cosmwasm_std::{GovMsg, VoteOption};\n\n#[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::Vote { proposal_id: 4, vote: VoteOption::Yes, })) } ```\n\nCast a weighted vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); # #[cfg(feature = \"cosmwasm_1_2\")] use cosmwasm_std::{Decimal, GovMsg, VoteOption, WeightedVoteOption};\n\n# #[cfg(feature = \"cosmwasm_1_2\")] #[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::VoteWeighted { proposal_id: 4, options: vec![ WeightedVoteOption { option: VoteOption::Yes, weight: Decimal::percent(65), }, WeightedVoteOption { option: VoteOption::Abstain, weight: Decimal::percent(35), }, ], })) } ```", + "oneOf": [ + { + "description": "This maps directly to [MsgVote](https://github.com/cosmos/cosmos-sdk/blob/v0.42.5/proto/cosmos/gov/v1beta1/tx.proto#L46-L56) in the Cosmos SDK with voter set to the contract address.", + "type": "object", + "required": [ + "vote" + ], + "properties": { + "vote": { + "type": "object", + "required": [ + "proposal_id", + "vote" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "vote": { + "description": "The vote option.\n\nThis should be called \"option\" for consistency with Cosmos SDK. Sorry for that. See .", + "allOf": [ + { + "$ref": "#/definitions/VoteOption" + } + ] + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcMsg": { + "description": "These are messages in the IBC lifecycle. Only usable by IBC-enabled contracts (contracts that directly speak the IBC protocol via 6 entry points)", + "oneOf": [ + { + "description": "Sends bank tokens owned by the contract to the given address on another chain. The channel must already be established between the ibctransfer module on this chain and a matching module on the remote chain. We cannot select the port_id, this is whatever the local chain has bound the ibctransfer module to.", + "type": "object", + "required": [ + "transfer" + ], + "properties": { + "transfer": { + "type": "object", + "required": [ + "amount", + "channel_id", + "timeout", + "to_address" + ], + "properties": { + "amount": { + "description": "packet data only supports one coin https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/ibc/applications/transfer/v1/transfer.proto#L11-L20", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "channel_id": { + "description": "exisiting channel to send the tokens over", + "type": "string" + }, + "timeout": { + "description": "when packet times out, measured on remote chain", + "allOf": [ + { + "$ref": "#/definitions/IbcTimeout" + } + ] + }, + "to_address": { + "description": "address on the remote chain to receive these tokens", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Sends an IBC packet with given data over the existing channel. Data should be encoded in a format defined by the channel version, and the module on the other side should know how to parse this.", + "type": "object", + "required": [ + "send_packet" + ], + "properties": { + "send_packet": { + "type": "object", + "required": [ + "channel_id", + "data", + "timeout" + ], + "properties": { + "channel_id": { + "type": "string" + }, + "data": { + "$ref": "#/definitions/Binary" + }, + "timeout": { + "description": "when packet times out, measured on remote chain", + "allOf": [ + { + "$ref": "#/definitions/IbcTimeout" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This will close an existing channel that is owned by this contract. Port is auto-assigned to the contract's IBC port", + "type": "object", + "required": [ + "close_channel" + ], + "properties": { + "close_channel": { + "type": "object", + "required": [ + "channel_id" + ], + "properties": { + "channel_id": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcTimeout": { + "description": "In IBC each package must set at least one type of timeout: the timestamp or the block height. Using this rather complex enum instead of two timeout fields we ensure that at least one timeout is set.", + "type": "object", + "properties": { + "block": { + "anyOf": [ + { + "$ref": "#/definitions/IbcTimeoutBlock" + }, + { + "type": "null" + } + ] + }, + "timestamp": { + "anyOf": [ + { + "$ref": "#/definitions/Timestamp" + }, + { + "type": "null" + } + ] + } + } + }, + "IbcTimeoutBlock": { + "description": "IBCTimeoutHeight Height is a monotonically increasing data type that can be compared against another Height for the purposes of updating and freezing clients. Ordering is (revision_number, timeout_height)", + "type": "object", + "required": [ + "height", + "revision" + ], + "properties": { + "height": { + "description": "block height after which the packet times out. the height within the given revision", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "revision": { + "description": "the version that the client is currently on (eg. after reseting the chain this could increment 1 as height drops to 0)", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + }, + "StakingMsg": { + "description": "The message types of the staking module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto", + "oneOf": [ + { + "description": "This is translated to a [MsgDelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L81-L90). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "delegate" + ], + "properties": { + "delegate": { + "type": "object", + "required": [ + "amount", + "validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [MsgUndelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L112-L121). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "undelegate" + ], + "properties": { + "undelegate": { + "type": "object", + "required": [ + "amount", + "validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [MsgBeginRedelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L95-L105). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "redelegate" + ], + "properties": { + "redelegate": { + "type": "object", + "required": [ + "amount", + "dst_validator", + "src_validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "dst_validator": { + "type": "string" + }, + "src_validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Status": { + "oneOf": [ + { + "description": "proposal was created, but voting has not yet begun for whatever reason", + "type": "string", + "enum": [ + "pending" + ] + }, + { + "description": "you can vote on this", + "type": "string", + "enum": [ + "open" + ] + }, + { + "description": "voting is over and it did not pass", + "type": "string", + "enum": [ + "rejected" + ] + }, + { + "description": "voting is over and it did pass, but has not yet executed", + "type": "string", + "enum": [ + "passed" + ] + }, + { + "description": "voting is over it passed, and the proposal was executed", + "type": "string", + "enum": [ + "executed" + ] + } + ] + }, + "ThresholdResponse": { + "description": "This defines the different ways tallies can happen. Every contract should support a subset of these, ideally all.\n\nThe total_weight used for calculating success as well as the weights of each individual voter used in tallying should be snapshotted at the beginning of the block at which the proposal starts (this is likely the responsibility of a correct cw4 implementation).", + "oneOf": [ + { + "description": "Declares that a fixed weight of yes votes is needed to pass. It does not matter how many no votes are cast, or how many do not vote, as long as `weight` yes votes are cast.\n\nThis is the simplest format and usually suitable for small multisigs of trusted parties, like 3 of 5. (weight: 3, total_weight: 5)\n\nA proposal of this type can pass early as soon as the needed weight of yes votes has been cast.", + "type": "object", + "required": [ + "absolute_count" + ], + "properties": { + "absolute_count": { + "type": "object", + "required": [ + "total_weight", + "weight" + ], + "properties": { + "total_weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Declares a percentage of the total weight that must cast Yes votes, in order for a proposal to pass. The passing weight is computed over the total weight minus the weight of the abstained votes.\n\nThis is useful for similar circumstances as `AbsoluteCount`, where we have a relatively small set of voters, and participation is required. It is understood that if the voting set (group) changes between different proposals that refer to the same group, each proposal will work with a different set of voter weights (the ones snapshotted at proposal creation), and the passing weight for each proposal will be computed based on the absolute percentage, times the total weights of the members at the time of each proposal creation.\n\nExample: we set `percentage` to 51%. Proposal 1 starts when there is a `total_weight` of 5. This will require 3 weight of Yes votes in order to pass. Later, the Proposal 2 starts but the `total_weight` of the group has increased to 9. That proposal will then automatically require 5 Yes of 9 to pass, rather than 3 yes of 9 as would be the case with `AbsoluteCount`.", + "type": "object", + "required": [ + "absolute_percentage" + ], + "properties": { + "absolute_percentage": { + "type": "object", + "required": [ + "percentage", + "total_weight" + ], + "properties": { + "percentage": { + "$ref": "#/definitions/Decimal" + }, + "total_weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "In addition to a `threshold`, declares a `quorum` of the total votes that must participate in the election in order for the vote to be considered at all. Within the votes that were cast, it requires `threshold` votes in favor. That is calculated by ignoring the Abstain votes (they count towards `quorum`, but do not influence `threshold`). That is, we calculate `Yes / (Yes + No + Veto)` and compare it with `threshold` to consider if the proposal was passed.\n\nIt is rather difficult for a proposal of this type to pass early. That can only happen if the required quorum has been already met, and there are already enough Yes votes for the proposal to pass.\n\n30% Yes votes, 10% No votes, and 20% Abstain would pass early if quorum <= 60% (who has cast votes) and if the threshold is <= 37.5% (the remaining 40% voting no => 30% yes + 50% no). Once the voting period has passed with no additional votes, that same proposal would be considered successful if quorum <= 60% and threshold <= 75% (percent in favor if we ignore abstain votes).\n\nThis type is more common in general elections, where participation is often expected to be low, and `AbsolutePercentage` would either be too high to pass anything, or allow low percentages to pass, independently of if there was high participation in the election or not.", + "type": "object", + "required": [ + "threshold_quorum" + ], + "properties": { + "threshold_quorum": { + "type": "object", + "required": [ + "quorum", + "threshold", + "total_weight" + ], + "properties": { + "quorum": { + "$ref": "#/definitions/Decimal" + }, + "threshold": { + "$ref": "#/definitions/Decimal" + }, + "total_weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + }, + "VoteOption": { + "type": "string", + "enum": [ + "yes", + "no", + "abstain", + "no_with_veto" + ] + }, + "WasmMsg": { + "description": "The message types of the wasm module.\n\nSee https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto", + "oneOf": [ + { + "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L68-L78). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "execute" + ], + "properties": { + "execute": { + "type": "object", + "required": [ + "contract_addr", + "funds", + "msg" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "msg": { + "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThe contract address is non-predictable. But it is guaranteed that when emitting the same Instantiate message multiple times, multiple instances on different addresses will be generated. See also Instantiate2.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/CosmWasm/wasmd/blob/v0.29.2/proto/cosmwasm/wasm/v1/tx.proto#L53-L71). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "instantiate" + ], + "properties": { + "instantiate": { + "type": "object", + "required": [ + "code_id", + "funds", + "label", + "msg" + ], + "properties": { + "admin": { + "type": [ + "string", + "null" + ] + }, + "code_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "label": { + "description": "A human-readbale label for the contract", + "type": "string" + }, + "msg": { + "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "migrate" + ], + "properties": { + "migrate": { + "type": "object", + "required": [ + "contract_addr", + "msg", + "new_code_id" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "msg": { + "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + }, + "new_code_id": { + "description": "the code_id of the new logic to place in the given contract", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", + "type": "object", + "required": [ + "update_admin" + ], + "properties": { + "update_admin": { + "type": "object", + "required": [ + "admin", + "contract_addr" + ], + "properties": { + "admin": { + "type": "string" + }, + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", + "type": "object", + "required": [ + "clear_admin" + ], + "properties": { + "clear_admin": { + "type": "object", + "required": [ + "contract_addr" + ], + "properties": { + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + } + } +} diff --git a/contracts/multisig/cw3-flex-multisig/schema/raw/response_to_reverse_proposals.json b/contracts/multisig/cw3-flex-multisig/schema/raw/response_to_reverse_proposals.json new file mode 100644 index 0000000000..0012bec80b --- /dev/null +++ b/contracts/multisig/cw3-flex-multisig/schema/raw/response_to_reverse_proposals.json @@ -0,0 +1,1045 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ProposalListResponse_for_Empty", + "type": "object", + "required": [ + "proposals" + ], + "properties": { + "proposals": { + "type": "array", + "items": { + "$ref": "#/definitions/ProposalResponse_for_Empty" + } + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "BankMsg": { + "description": "The message types of the bank module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto", + "oneOf": [ + { + "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "send" + ], + "properties": { + "send": { + "type": "object", + "required": [ + "amount", + "to_address" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "to_address": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", + "type": "object", + "required": [ + "burn" + ], + "properties": { + "burn": { + "type": "object", + "required": [ + "amount" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "CosmosMsg_for_Empty": { + "oneOf": [ + { + "type": "object", + "required": [ + "bank" + ], + "properties": { + "bank": { + "$ref": "#/definitions/BankMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "custom" + ], + "properties": { + "custom": { + "$ref": "#/definitions/Empty" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "staking" + ], + "properties": { + "staking": { + "$ref": "#/definitions/StakingMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "distribution" + ], + "properties": { + "distribution": { + "$ref": "#/definitions/DistributionMsg" + } + }, + "additionalProperties": false + }, + { + "description": "A Stargate message encoded the same way as a protobuf [Any](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto). This is the same structure as messages in `TxBody` from [ADR-020](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-020-protobuf-transaction-encoding.md)", + "type": "object", + "required": [ + "stargate" + ], + "properties": { + "stargate": { + "type": "object", + "required": [ + "type_url", + "value" + ], + "properties": { + "type_url": { + "type": "string" + }, + "value": { + "$ref": "#/definitions/Binary" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "ibc" + ], + "properties": { + "ibc": { + "$ref": "#/definitions/IbcMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "wasm" + ], + "properties": { + "wasm": { + "$ref": "#/definitions/WasmMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "gov" + ], + "properties": { + "gov": { + "$ref": "#/definitions/GovMsg" + } + }, + "additionalProperties": false + } + ] + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Denom": { + "oneOf": [ + { + "type": "object", + "required": [ + "native" + ], + "properties": { + "native": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "cw20" + ], + "properties": { + "cw20": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + ] + }, + "DepositInfo": { + "description": "Information about the deposit required to create a proposal.", + "type": "object", + "required": [ + "amount", + "denom", + "refund_failed_proposals" + ], + "properties": { + "amount": { + "description": "The number tokens required for payment.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "denom": { + "description": "The denom of the deposit payment.", + "allOf": [ + { + "$ref": "#/definitions/Denom" + } + ] + }, + "refund_failed_proposals": { + "description": "Should failed proposals have their deposits refunded?", + "type": "boolean" + } + }, + "additionalProperties": false + }, + "DistributionMsg": { + "description": "The message types of the distribution module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto", + "oneOf": [ + { + "description": "This is translated to a [MsgSetWithdrawAddress](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L29-L37). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "set_withdraw_address" + ], + "properties": { + "set_withdraw_address": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "The `withdraw_address`", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [[MsgWithdrawDelegatorReward](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L42-L50). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "withdraw_delegator_reward" + ], + "properties": { + "withdraw_delegator_reward": { + "type": "object", + "required": [ + "validator" + ], + "properties": { + "validator": { + "description": "The `validator_address`", + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Empty": { + "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", + "type": "object" + }, + "Expiration": { + "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", + "oneOf": [ + { + "description": "AtHeight will expire when `env.block.height` >= height", + "type": "object", + "required": [ + "at_height" + ], + "properties": { + "at_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "AtTime will expire when `env.block.time` >= time", + "type": "object", + "required": [ + "at_time" + ], + "properties": { + "at_time": { + "$ref": "#/definitions/Timestamp" + } + }, + "additionalProperties": false + }, + { + "description": "Never will never expire. Used to express the empty variant", + "type": "object", + "required": [ + "never" + ], + "properties": { + "never": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "GovMsg": { + "description": "This message type allows the contract interact with the [x/gov] module in order to cast votes.\n\n[x/gov]: https://github.com/cosmos/cosmos-sdk/tree/v0.45.12/x/gov\n\n## Examples\n\nCast a simple vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); use cosmwasm_std::{GovMsg, VoteOption};\n\n#[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::Vote { proposal_id: 4, vote: VoteOption::Yes, })) } ```\n\nCast a weighted vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); # #[cfg(feature = \"cosmwasm_1_2\")] use cosmwasm_std::{Decimal, GovMsg, VoteOption, WeightedVoteOption};\n\n# #[cfg(feature = \"cosmwasm_1_2\")] #[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::VoteWeighted { proposal_id: 4, options: vec![ WeightedVoteOption { option: VoteOption::Yes, weight: Decimal::percent(65), }, WeightedVoteOption { option: VoteOption::Abstain, weight: Decimal::percent(35), }, ], })) } ```", + "oneOf": [ + { + "description": "This maps directly to [MsgVote](https://github.com/cosmos/cosmos-sdk/blob/v0.42.5/proto/cosmos/gov/v1beta1/tx.proto#L46-L56) in the Cosmos SDK with voter set to the contract address.", + "type": "object", + "required": [ + "vote" + ], + "properties": { + "vote": { + "type": "object", + "required": [ + "proposal_id", + "vote" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "vote": { + "description": "The vote option.\n\nThis should be called \"option\" for consistency with Cosmos SDK. Sorry for that. See .", + "allOf": [ + { + "$ref": "#/definitions/VoteOption" + } + ] + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcMsg": { + "description": "These are messages in the IBC lifecycle. Only usable by IBC-enabled contracts (contracts that directly speak the IBC protocol via 6 entry points)", + "oneOf": [ + { + "description": "Sends bank tokens owned by the contract to the given address on another chain. The channel must already be established between the ibctransfer module on this chain and a matching module on the remote chain. We cannot select the port_id, this is whatever the local chain has bound the ibctransfer module to.", + "type": "object", + "required": [ + "transfer" + ], + "properties": { + "transfer": { + "type": "object", + "required": [ + "amount", + "channel_id", + "timeout", + "to_address" + ], + "properties": { + "amount": { + "description": "packet data only supports one coin https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/ibc/applications/transfer/v1/transfer.proto#L11-L20", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "channel_id": { + "description": "exisiting channel to send the tokens over", + "type": "string" + }, + "timeout": { + "description": "when packet times out, measured on remote chain", + "allOf": [ + { + "$ref": "#/definitions/IbcTimeout" + } + ] + }, + "to_address": { + "description": "address on the remote chain to receive these tokens", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Sends an IBC packet with given data over the existing channel. Data should be encoded in a format defined by the channel version, and the module on the other side should know how to parse this.", + "type": "object", + "required": [ + "send_packet" + ], + "properties": { + "send_packet": { + "type": "object", + "required": [ + "channel_id", + "data", + "timeout" + ], + "properties": { + "channel_id": { + "type": "string" + }, + "data": { + "$ref": "#/definitions/Binary" + }, + "timeout": { + "description": "when packet times out, measured on remote chain", + "allOf": [ + { + "$ref": "#/definitions/IbcTimeout" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This will close an existing channel that is owned by this contract. Port is auto-assigned to the contract's IBC port", + "type": "object", + "required": [ + "close_channel" + ], + "properties": { + "close_channel": { + "type": "object", + "required": [ + "channel_id" + ], + "properties": { + "channel_id": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcTimeout": { + "description": "In IBC each package must set at least one type of timeout: the timestamp or the block height. Using this rather complex enum instead of two timeout fields we ensure that at least one timeout is set.", + "type": "object", + "properties": { + "block": { + "anyOf": [ + { + "$ref": "#/definitions/IbcTimeoutBlock" + }, + { + "type": "null" + } + ] + }, + "timestamp": { + "anyOf": [ + { + "$ref": "#/definitions/Timestamp" + }, + { + "type": "null" + } + ] + } + } + }, + "IbcTimeoutBlock": { + "description": "IBCTimeoutHeight Height is a monotonically increasing data type that can be compared against another Height for the purposes of updating and freezing clients. Ordering is (revision_number, timeout_height)", + "type": "object", + "required": [ + "height", + "revision" + ], + "properties": { + "height": { + "description": "block height after which the packet times out. the height within the given revision", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "revision": { + "description": "the version that the client is currently on (eg. after reseting the chain this could increment 1 as height drops to 0)", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + }, + "ProposalResponse_for_Empty": { + "description": "Note, if you are storing custom messages in the proposal, the querier needs to know what possible custom message types those are in order to parse the response", + "type": "object", + "required": [ + "description", + "expires", + "id", + "msgs", + "proposer", + "status", + "threshold", + "title" + ], + "properties": { + "deposit": { + "anyOf": [ + { + "$ref": "#/definitions/DepositInfo" + }, + { + "type": "null" + } + ] + }, + "description": { + "type": "string" + }, + "expires": { + "$ref": "#/definitions/Expiration" + }, + "id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "msgs": { + "type": "array", + "items": { + "$ref": "#/definitions/CosmosMsg_for_Empty" + } + }, + "proposer": { + "$ref": "#/definitions/Addr" + }, + "status": { + "$ref": "#/definitions/Status" + }, + "threshold": { + "description": "This is the threshold that is applied to this proposal. Both the rules of the voting contract, as well as the total_weight of the voting group may have changed since this time. That means that the generic `Threshold{}` query does not provide valid information for existing proposals.", + "allOf": [ + { + "$ref": "#/definitions/ThresholdResponse" + } + ] + }, + "title": { + "type": "string" + } + }, + "additionalProperties": false + }, + "StakingMsg": { + "description": "The message types of the staking module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto", + "oneOf": [ + { + "description": "This is translated to a [MsgDelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L81-L90). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "delegate" + ], + "properties": { + "delegate": { + "type": "object", + "required": [ + "amount", + "validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [MsgUndelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L112-L121). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "undelegate" + ], + "properties": { + "undelegate": { + "type": "object", + "required": [ + "amount", + "validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [MsgBeginRedelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L95-L105). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "redelegate" + ], + "properties": { + "redelegate": { + "type": "object", + "required": [ + "amount", + "dst_validator", + "src_validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "dst_validator": { + "type": "string" + }, + "src_validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Status": { + "oneOf": [ + { + "description": "proposal was created, but voting has not yet begun for whatever reason", + "type": "string", + "enum": [ + "pending" + ] + }, + { + "description": "you can vote on this", + "type": "string", + "enum": [ + "open" + ] + }, + { + "description": "voting is over and it did not pass", + "type": "string", + "enum": [ + "rejected" + ] + }, + { + "description": "voting is over and it did pass, but has not yet executed", + "type": "string", + "enum": [ + "passed" + ] + }, + { + "description": "voting is over it passed, and the proposal was executed", + "type": "string", + "enum": [ + "executed" + ] + } + ] + }, + "ThresholdResponse": { + "description": "This defines the different ways tallies can happen. Every contract should support a subset of these, ideally all.\n\nThe total_weight used for calculating success as well as the weights of each individual voter used in tallying should be snapshotted at the beginning of the block at which the proposal starts (this is likely the responsibility of a correct cw4 implementation).", + "oneOf": [ + { + "description": "Declares that a fixed weight of yes votes is needed to pass. It does not matter how many no votes are cast, or how many do not vote, as long as `weight` yes votes are cast.\n\nThis is the simplest format and usually suitable for small multisigs of trusted parties, like 3 of 5. (weight: 3, total_weight: 5)\n\nA proposal of this type can pass early as soon as the needed weight of yes votes has been cast.", + "type": "object", + "required": [ + "absolute_count" + ], + "properties": { + "absolute_count": { + "type": "object", + "required": [ + "total_weight", + "weight" + ], + "properties": { + "total_weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Declares a percentage of the total weight that must cast Yes votes, in order for a proposal to pass. The passing weight is computed over the total weight minus the weight of the abstained votes.\n\nThis is useful for similar circumstances as `AbsoluteCount`, where we have a relatively small set of voters, and participation is required. It is understood that if the voting set (group) changes between different proposals that refer to the same group, each proposal will work with a different set of voter weights (the ones snapshotted at proposal creation), and the passing weight for each proposal will be computed based on the absolute percentage, times the total weights of the members at the time of each proposal creation.\n\nExample: we set `percentage` to 51%. Proposal 1 starts when there is a `total_weight` of 5. This will require 3 weight of Yes votes in order to pass. Later, the Proposal 2 starts but the `total_weight` of the group has increased to 9. That proposal will then automatically require 5 Yes of 9 to pass, rather than 3 yes of 9 as would be the case with `AbsoluteCount`.", + "type": "object", + "required": [ + "absolute_percentage" + ], + "properties": { + "absolute_percentage": { + "type": "object", + "required": [ + "percentage", + "total_weight" + ], + "properties": { + "percentage": { + "$ref": "#/definitions/Decimal" + }, + "total_weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "In addition to a `threshold`, declares a `quorum` of the total votes that must participate in the election in order for the vote to be considered at all. Within the votes that were cast, it requires `threshold` votes in favor. That is calculated by ignoring the Abstain votes (they count towards `quorum`, but do not influence `threshold`). That is, we calculate `Yes / (Yes + No + Veto)` and compare it with `threshold` to consider if the proposal was passed.\n\nIt is rather difficult for a proposal of this type to pass early. That can only happen if the required quorum has been already met, and there are already enough Yes votes for the proposal to pass.\n\n30% Yes votes, 10% No votes, and 20% Abstain would pass early if quorum <= 60% (who has cast votes) and if the threshold is <= 37.5% (the remaining 40% voting no => 30% yes + 50% no). Once the voting period has passed with no additional votes, that same proposal would be considered successful if quorum <= 60% and threshold <= 75% (percent in favor if we ignore abstain votes).\n\nThis type is more common in general elections, where participation is often expected to be low, and `AbsolutePercentage` would either be too high to pass anything, or allow low percentages to pass, independently of if there was high participation in the election or not.", + "type": "object", + "required": [ + "threshold_quorum" + ], + "properties": { + "threshold_quorum": { + "type": "object", + "required": [ + "quorum", + "threshold", + "total_weight" + ], + "properties": { + "quorum": { + "$ref": "#/definitions/Decimal" + }, + "threshold": { + "$ref": "#/definitions/Decimal" + }, + "total_weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + }, + "VoteOption": { + "type": "string", + "enum": [ + "yes", + "no", + "abstain", + "no_with_veto" + ] + }, + "WasmMsg": { + "description": "The message types of the wasm module.\n\nSee https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto", + "oneOf": [ + { + "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L68-L78). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "execute" + ], + "properties": { + "execute": { + "type": "object", + "required": [ + "contract_addr", + "funds", + "msg" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "msg": { + "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThe contract address is non-predictable. But it is guaranteed that when emitting the same Instantiate message multiple times, multiple instances on different addresses will be generated. See also Instantiate2.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/CosmWasm/wasmd/blob/v0.29.2/proto/cosmwasm/wasm/v1/tx.proto#L53-L71). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "instantiate" + ], + "properties": { + "instantiate": { + "type": "object", + "required": [ + "code_id", + "funds", + "label", + "msg" + ], + "properties": { + "admin": { + "type": [ + "string", + "null" + ] + }, + "code_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "label": { + "description": "A human-readbale label for the contract", + "type": "string" + }, + "msg": { + "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "migrate" + ], + "properties": { + "migrate": { + "type": "object", + "required": [ + "contract_addr", + "msg", + "new_code_id" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "msg": { + "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + }, + "new_code_id": { + "description": "the code_id of the new logic to place in the given contract", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", + "type": "object", + "required": [ + "update_admin" + ], + "properties": { + "update_admin": { + "type": "object", + "required": [ + "admin", + "contract_addr" + ], + "properties": { + "admin": { + "type": "string" + }, + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", + "type": "object", + "required": [ + "clear_admin" + ], + "properties": { + "clear_admin": { + "type": "object", + "required": [ + "contract_addr" + ], + "properties": { + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + } + } +} diff --git a/contracts/multisig/cw3-flex-multisig/schema/raw/response_to_threshold.json b/contracts/multisig/cw3-flex-multisig/schema/raw/response_to_threshold.json new file mode 100644 index 0000000000..3c7dae60fe --- /dev/null +++ b/contracts/multisig/cw3-flex-multisig/schema/raw/response_to_threshold.json @@ -0,0 +1,103 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ThresholdResponse", + "description": "This defines the different ways tallies can happen. Every contract should support a subset of these, ideally all.\n\nThe total_weight used for calculating success as well as the weights of each individual voter used in tallying should be snapshotted at the beginning of the block at which the proposal starts (this is likely the responsibility of a correct cw4 implementation).", + "oneOf": [ + { + "description": "Declares that a fixed weight of yes votes is needed to pass. It does not matter how many no votes are cast, or how many do not vote, as long as `weight` yes votes are cast.\n\nThis is the simplest format and usually suitable for small multisigs of trusted parties, like 3 of 5. (weight: 3, total_weight: 5)\n\nA proposal of this type can pass early as soon as the needed weight of yes votes has been cast.", + "type": "object", + "required": [ + "absolute_count" + ], + "properties": { + "absolute_count": { + "type": "object", + "required": [ + "total_weight", + "weight" + ], + "properties": { + "total_weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Declares a percentage of the total weight that must cast Yes votes, in order for a proposal to pass. The passing weight is computed over the total weight minus the weight of the abstained votes.\n\nThis is useful for similar circumstances as `AbsoluteCount`, where we have a relatively small set of voters, and participation is required. It is understood that if the voting set (group) changes between different proposals that refer to the same group, each proposal will work with a different set of voter weights (the ones snapshotted at proposal creation), and the passing weight for each proposal will be computed based on the absolute percentage, times the total weights of the members at the time of each proposal creation.\n\nExample: we set `percentage` to 51%. Proposal 1 starts when there is a `total_weight` of 5. This will require 3 weight of Yes votes in order to pass. Later, the Proposal 2 starts but the `total_weight` of the group has increased to 9. That proposal will then automatically require 5 Yes of 9 to pass, rather than 3 yes of 9 as would be the case with `AbsoluteCount`.", + "type": "object", + "required": [ + "absolute_percentage" + ], + "properties": { + "absolute_percentage": { + "type": "object", + "required": [ + "percentage", + "total_weight" + ], + "properties": { + "percentage": { + "$ref": "#/definitions/Decimal" + }, + "total_weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "In addition to a `threshold`, declares a `quorum` of the total votes that must participate in the election in order for the vote to be considered at all. Within the votes that were cast, it requires `threshold` votes in favor. That is calculated by ignoring the Abstain votes (they count towards `quorum`, but do not influence `threshold`). That is, we calculate `Yes / (Yes + No + Veto)` and compare it with `threshold` to consider if the proposal was passed.\n\nIt is rather difficult for a proposal of this type to pass early. That can only happen if the required quorum has been already met, and there are already enough Yes votes for the proposal to pass.\n\n30% Yes votes, 10% No votes, and 20% Abstain would pass early if quorum <= 60% (who has cast votes) and if the threshold is <= 37.5% (the remaining 40% voting no => 30% yes + 50% no). Once the voting period has passed with no additional votes, that same proposal would be considered successful if quorum <= 60% and threshold <= 75% (percent in favor if we ignore abstain votes).\n\nThis type is more common in general elections, where participation is often expected to be low, and `AbsolutePercentage` would either be too high to pass anything, or allow low percentages to pass, independently of if there was high participation in the election or not.", + "type": "object", + "required": [ + "threshold_quorum" + ], + "properties": { + "threshold_quorum": { + "type": "object", + "required": [ + "quorum", + "threshold", + "total_weight" + ], + "properties": { + "quorum": { + "$ref": "#/definitions/Decimal" + }, + "threshold": { + "$ref": "#/definitions/Decimal" + }, + "total_weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + } + } +} diff --git a/contracts/multisig/cw3-flex-multisig/schema/raw/response_to_vote.json b/contracts/multisig/cw3-flex-multisig/schema/raw/response_to_vote.json new file mode 100644 index 0000000000..ba779b7a0d --- /dev/null +++ b/contracts/multisig/cw3-flex-multisig/schema/raw/response_to_vote.json @@ -0,0 +1,81 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "VoteResponse", + "type": "object", + "properties": { + "vote": { + "anyOf": [ + { + "$ref": "#/definitions/VoteInfo" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Vote": { + "oneOf": [ + { + "description": "Marks support for the proposal.", + "type": "string", + "enum": [ + "yes" + ] + }, + { + "description": "Marks opposition to the proposal.", + "type": "string", + "enum": [ + "no" + ] + }, + { + "description": "Marks participation but does not count towards the ratio of support / opposed", + "type": "string", + "enum": [ + "abstain" + ] + }, + { + "description": "Veto is generally to be treated as a No vote. Some implementations may allow certain voters to be able to Veto, or them to be counted stronger than No in some way.", + "type": "string", + "enum": [ + "veto" + ] + } + ] + }, + "VoteInfo": { + "description": "Returns the vote (opinion as well as weight counted) as well as the address of the voter who submitted it", + "type": "object", + "required": [ + "proposal_id", + "vote", + "voter", + "weight" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "vote": { + "$ref": "#/definitions/Vote" + }, + "voter": { + "type": "string" + }, + "weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/multisig/cw3-flex-multisig/schema/raw/response_to_voter.json b/contracts/multisig/cw3-flex-multisig/schema/raw/response_to_voter.json new file mode 100644 index 0000000000..125b4e1430 --- /dev/null +++ b/contracts/multisig/cw3-flex-multisig/schema/raw/response_to_voter.json @@ -0,0 +1,16 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "VoterResponse", + "type": "object", + "properties": { + "weight": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false +} diff --git a/contracts/multisig/cw3-flex-multisig/src/bin/schema.rs b/contracts/multisig/cw3-flex-multisig/src/bin/schema.rs new file mode 100644 index 0000000000..869f53b3a6 --- /dev/null +++ b/contracts/multisig/cw3-flex-multisig/src/bin/schema.rs @@ -0,0 +1,14 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use cosmwasm_schema::write_api; +use nym_multisig_contract_common::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + query: QueryMsg, + execute: ExecuteMsg, + migrate: MigrateMsg, + } +} diff --git a/contracts/multisig/cw4-group/Cargo.toml b/contracts/multisig/cw4-group/Cargo.toml index 180ee66b9d..a2897779b9 100644 --- a/contracts/multisig/cw4-group/Cargo.toml +++ b/contracts/multisig/cw4-group/Cargo.toml @@ -16,6 +16,9 @@ exclude = [ # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[[bin]] +name = "schema" + [lib] crate-type = ["cdylib", "rlib"] @@ -25,6 +28,7 @@ backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] + [dependencies] nym-group-contract-common = { path = "../../../common/cosmwasm-smart-contracts/group-contract" } @@ -38,3 +42,4 @@ cosmwasm-std = { workspace = true } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } + diff --git a/contracts/multisig/cw4-group/Makefile b/contracts/multisig/cw4-group/Makefile new file mode 100644 index 0000000000..f138e2c879 --- /dev/null +++ b/contracts/multisig/cw4-group/Makefile @@ -0,0 +1,2 @@ +generate-schema: + cargo schema \ No newline at end of file diff --git a/contracts/multisig/cw4-group/schema/cw4-group.json b/contracts/multisig/cw4-group/schema/cw4-group.json new file mode 100644 index 0000000000..5e0f5af99b --- /dev/null +++ b/contracts/multisig/cw4-group/schema/cw4-group.json @@ -0,0 +1,395 @@ +{ + "contract_name": "cw4-group", + "contract_version": "1.0.0", + "idl_version": "1.0.0", + "instantiate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "members" + ], + "properties": { + "admin": { + "description": "The admin is the only account that can update the group state. Omit it to make the group immutable.", + "type": [ + "string", + "null" + ] + }, + "members": { + "type": "array", + "items": { + "$ref": "#/definitions/Member" + } + } + }, + "additionalProperties": false, + "definitions": { + "Member": { + "description": "A group member has a weight associated with them. This may all be equal, or may have meaning in the app that makes use of the group (eg. voting power)", + "type": "object", + "required": [ + "addr", + "weight" + ], + "properties": { + "addr": { + "type": "string" + }, + "weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } + }, + "execute": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Change the admin", + "type": "object", + "required": [ + "update_admin" + ], + "properties": { + "update_admin": { + "type": "object", + "properties": { + "admin": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "apply a diff to the existing members. remove is applied after add, so if an address is in both, it is removed", + "type": "object", + "required": [ + "update_members" + ], + "properties": { + "update_members": { + "type": "object", + "required": [ + "add", + "remove" + ], + "properties": { + "add": { + "type": "array", + "items": { + "$ref": "#/definitions/Member" + } + }, + "remove": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Add a new hook to be informed of all membership changes. Must be called by Admin", + "type": "object", + "required": [ + "add_hook" + ], + "properties": { + "add_hook": { + "type": "object", + "required": [ + "addr" + ], + "properties": { + "addr": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Remove a hook. Must be called by Admin", + "type": "object", + "required": [ + "remove_hook" + ], + "properties": { + "remove_hook": { + "type": "object", + "required": [ + "addr" + ], + "properties": { + "addr": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Member": { + "description": "A group member has a weight associated with them. This may all be equal, or may have meaning in the app that makes use of the group (eg. voting power)", + "type": "object", + "required": [ + "addr", + "weight" + ], + "properties": { + "addr": { + "type": "string" + }, + "weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } + }, + "query": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "admin" + ], + "properties": { + "admin": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "total_weight" + ], + "properties": { + "total_weight": { + "type": "object", + "properties": { + "at_height": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "list_members" + ], + "properties": { + "list_members": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "member" + ], + "properties": { + "member": { + "type": "object", + "required": [ + "addr" + ], + "properties": { + "addr": { + "type": "string" + }, + "at_height": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Shows all registered hooks.", + "type": "object", + "required": [ + "hooks" + ], + "properties": { + "hooks": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "migrate": null, + "sudo": null, + "responses": { + "admin": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AdminResponse", + "description": "Returned from Admin.query_admin()", + "type": "object", + "properties": { + "admin": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + }, + "hooks": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "HooksResponse", + "type": "object", + "required": [ + "hooks" + ], + "properties": { + "hooks": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "list_members": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MemberListResponse", + "type": "object", + "required": [ + "members" + ], + "properties": { + "members": { + "type": "array", + "items": { + "$ref": "#/definitions/Member" + } + } + }, + "additionalProperties": false, + "definitions": { + "Member": { + "description": "A group member has a weight associated with them. This may all be equal, or may have meaning in the app that makes use of the group (eg. voting power)", + "type": "object", + "required": [ + "addr", + "weight" + ], + "properties": { + "addr": { + "type": "string" + }, + "weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } + }, + "member": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MemberResponse", + "type": "object", + "properties": { + "weight": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "total_weight": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "TotalWeightResponse", + "type": "object", + "required": [ + "weight" + ], + "properties": { + "weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/multisig/cw4-group/schema/raw/execute.json b/contracts/multisig/cw4-group/schema/raw/execute.json new file mode 100644 index 0000000000..526169f1bf --- /dev/null +++ b/contracts/multisig/cw4-group/schema/raw/execute.json @@ -0,0 +1,125 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Change the admin", + "type": "object", + "required": [ + "update_admin" + ], + "properties": { + "update_admin": { + "type": "object", + "properties": { + "admin": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "apply a diff to the existing members. remove is applied after add, so if an address is in both, it is removed", + "type": "object", + "required": [ + "update_members" + ], + "properties": { + "update_members": { + "type": "object", + "required": [ + "add", + "remove" + ], + "properties": { + "add": { + "type": "array", + "items": { + "$ref": "#/definitions/Member" + } + }, + "remove": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Add a new hook to be informed of all membership changes. Must be called by Admin", + "type": "object", + "required": [ + "add_hook" + ], + "properties": { + "add_hook": { + "type": "object", + "required": [ + "addr" + ], + "properties": { + "addr": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Remove a hook. Must be called by Admin", + "type": "object", + "required": [ + "remove_hook" + ], + "properties": { + "remove_hook": { + "type": "object", + "required": [ + "addr" + ], + "properties": { + "addr": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Member": { + "description": "A group member has a weight associated with them. This may all be equal, or may have meaning in the app that makes use of the group (eg. voting power)", + "type": "object", + "required": [ + "addr", + "weight" + ], + "properties": { + "addr": { + "type": "string" + }, + "weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/multisig/cw4-group/schema/raw/instantiate.json b/contracts/multisig/cw4-group/schema/raw/instantiate.json new file mode 100644 index 0000000000..bba7b445a7 --- /dev/null +++ b/contracts/multisig/cw4-group/schema/raw/instantiate.json @@ -0,0 +1,45 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "members" + ], + "properties": { + "admin": { + "description": "The admin is the only account that can update the group state. Omit it to make the group immutable.", + "type": [ + "string", + "null" + ] + }, + "members": { + "type": "array", + "items": { + "$ref": "#/definitions/Member" + } + } + }, + "additionalProperties": false, + "definitions": { + "Member": { + "description": "A group member has a weight associated with them. This may all be equal, or may have meaning in the app that makes use of the group (eg. voting power)", + "type": "object", + "required": [ + "addr", + "weight" + ], + "properties": { + "addr": { + "type": "string" + }, + "weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/multisig/cw4-group/schema/raw/query.json b/contracts/multisig/cw4-group/schema/raw/query.json new file mode 100644 index 0000000000..ec6abedb8d --- /dev/null +++ b/contracts/multisig/cw4-group/schema/raw/query.json @@ -0,0 +1,114 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "admin" + ], + "properties": { + "admin": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "total_weight" + ], + "properties": { + "total_weight": { + "type": "object", + "properties": { + "at_height": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "list_members" + ], + "properties": { + "list_members": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "member" + ], + "properties": { + "member": { + "type": "object", + "required": [ + "addr" + ], + "properties": { + "addr": { + "type": "string" + }, + "at_height": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Shows all registered hooks.", + "type": "object", + "required": [ + "hooks" + ], + "properties": { + "hooks": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] +} diff --git a/contracts/multisig/cw4-group/schema/raw/response_to_admin.json b/contracts/multisig/cw4-group/schema/raw/response_to_admin.json new file mode 100644 index 0000000000..c73969ab04 --- /dev/null +++ b/contracts/multisig/cw4-group/schema/raw/response_to_admin.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AdminResponse", + "description": "Returned from Admin.query_admin()", + "type": "object", + "properties": { + "admin": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false +} diff --git a/contracts/multisig/cw4-group/schema/raw/response_to_hooks.json b/contracts/multisig/cw4-group/schema/raw/response_to_hooks.json new file mode 100644 index 0000000000..6d46524400 --- /dev/null +++ b/contracts/multisig/cw4-group/schema/raw/response_to_hooks.json @@ -0,0 +1,17 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "HooksResponse", + "type": "object", + "required": [ + "hooks" + ], + "properties": { + "hooks": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false +} diff --git a/contracts/multisig/cw4-group/schema/raw/response_to_list_members.json b/contracts/multisig/cw4-group/schema/raw/response_to_list_members.json new file mode 100644 index 0000000000..39617c0538 --- /dev/null +++ b/contracts/multisig/cw4-group/schema/raw/response_to_list_members.json @@ -0,0 +1,38 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MemberListResponse", + "type": "object", + "required": [ + "members" + ], + "properties": { + "members": { + "type": "array", + "items": { + "$ref": "#/definitions/Member" + } + } + }, + "additionalProperties": false, + "definitions": { + "Member": { + "description": "A group member has a weight associated with them. This may all be equal, or may have meaning in the app that makes use of the group (eg. voting power)", + "type": "object", + "required": [ + "addr", + "weight" + ], + "properties": { + "addr": { + "type": "string" + }, + "weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/multisig/cw4-group/schema/raw/response_to_member.json b/contracts/multisig/cw4-group/schema/raw/response_to_member.json new file mode 100644 index 0000000000..0de8fdcfde --- /dev/null +++ b/contracts/multisig/cw4-group/schema/raw/response_to_member.json @@ -0,0 +1,16 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MemberResponse", + "type": "object", + "properties": { + "weight": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false +} diff --git a/contracts/multisig/cw4-group/schema/raw/response_to_total_weight.json b/contracts/multisig/cw4-group/schema/raw/response_to_total_weight.json new file mode 100644 index 0000000000..9b1f597629 --- /dev/null +++ b/contracts/multisig/cw4-group/schema/raw/response_to_total_weight.json @@ -0,0 +1,16 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "TotalWeightResponse", + "type": "object", + "required": [ + "weight" + ], + "properties": { + "weight": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false +} diff --git a/contracts/multisig/cw4-group/src/bin/schema.rs b/contracts/multisig/cw4-group/src/bin/schema.rs new file mode 100644 index 0000000000..a46ff6cf2e --- /dev/null +++ b/contracts/multisig/cw4-group/src/bin/schema.rs @@ -0,0 +1,13 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use cosmwasm_schema::write_api; +use nym_group_contract_common::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + query: QueryMsg, + execute: ExecuteMsg, + } +} diff --git a/contracts/name-service/.cargo/config b/contracts/name-service/.cargo/config new file mode 100644 index 0000000000..2fb2c1afdb --- /dev/null +++ b/contracts/name-service/.cargo/config @@ -0,0 +1,4 @@ +[alias] +wasm = "build --release --lib --target wasm32-unknown-unknown" +unit-test = "test --lib" +schema = "run --bin schema --features=schema-gen" \ No newline at end of file diff --git a/contracts/name-service/Cargo.toml b/contracts/name-service/Cargo.toml index 56fe0145cf..7bbacf8ba1 100644 --- a/contracts/name-service/Cargo.toml +++ b/contracts/name-service/Cargo.toml @@ -3,11 +3,16 @@ name = "nym-name-service" version = "0.1.0" edition = "2021" +[[bin]] +name = "schema" +required-features = ["schema-gen"] + [lib] crate-type = ["cdylib", "rlib"] [dependencies] bs58 = "0.4.0" +cosmwasm-schema = { workspace = true, optional = true } cosmwasm-std = { workspace = true } cw-controllers = { workspace = true } cw-storage-plus = { workspace = true } @@ -29,3 +34,6 @@ nym-crypto = { path = "../../common/crypto", features = ["asymmetric", "rand"] } rand = "0.8.5" rand_chacha = "0.2" rstest = "0.17.0" + +[features] +schema-gen = ["nym-name-service-common/schema", "cosmwasm-schema"] diff --git a/contracts/name-service/Makefile b/contracts/name-service/Makefile new file mode 100644 index 0000000000..f138e2c879 --- /dev/null +++ b/contracts/name-service/Makefile @@ -0,0 +1,2 @@ +generate-schema: + cargo schema \ No newline at end of file diff --git a/contracts/name-service/schema/nym-name-service.json b/contracts/name-service/schema/nym-name-service.json new file mode 100644 index 0000000000..f9da4f3cf8 --- /dev/null +++ b/contracts/name-service/schema/nym-name-service.json @@ -0,0 +1,1242 @@ +{ + "contract_name": "nym-name-service", + "contract_version": "0.1.0", + "idl_version": "1.0.0", + "instantiate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "deposit_required" + ], + "properties": { + "deposit_required": { + "$ref": "#/definitions/Coin" + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "execute": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Announcing a name pointing to a nym-address", + "type": "object", + "required": [ + "register" + ], + "properties": { + "register": { + "type": "object", + "required": [ + "name", + "owner_signature" + ], + "properties": { + "name": { + "$ref": "#/definitions/NameDetails" + }, + "owner_signature": { + "$ref": "#/definitions/MessageSignature" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Delete a name entry by id", + "type": "object", + "required": [ + "delete_id" + ], + "properties": { + "delete_id": { + "type": "object", + "required": [ + "name_id" + ], + "properties": { + "name_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Delete a name entry by name", + "type": "object", + "required": [ + "delete_name" + ], + "properties": { + "delete_name": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "$ref": "#/definitions/NymName" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Change the deposit required for announcing a name", + "type": "object", + "required": [ + "update_deposit_required" + ], + "properties": { + "update_deposit_required": { + "type": "object", + "required": [ + "deposit_required" + ], + "properties": { + "deposit_required": { + "$ref": "#/definitions/Coin" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Address": { + "description": "String representation of a nym address, which is of the form client_id.client_enc@gateway_id. NOTE: entirely unvalidated.", + "oneOf": [ + { + "type": "object", + "required": [ + "nym_address" + ], + "properties": { + "nym_address": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "MessageSignature": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + }, + "NameDetails": { + "type": "object", + "required": [ + "address", + "identity_key", + "name" + ], + "properties": { + "address": { + "description": "The address of the name alias.", + "allOf": [ + { + "$ref": "#/definitions/Address" + } + ] + }, + "identity_key": { + "description": "The identity key of the registered name.", + "type": "string" + }, + "name": { + "description": "The name pointing to the nym address", + "allOf": [ + { + "$ref": "#/definitions/NymName" + } + ] + } + }, + "additionalProperties": false + }, + "NymName": { + "description": "Name stored and pointing a to a nym-address", + "type": "string" + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "query": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "description": "Query the name by it's assigned id", + "type": "object", + "required": [ + "name_id" + ], + "properties": { + "name_id": { + "type": "object", + "required": [ + "name_id" + ], + "properties": { + "name_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Query the names by the registrator", + "type": "object", + "required": [ + "by_owner" + ], + "properties": { + "by_owner": { + "type": "object", + "required": [ + "owner" + ], + "properties": { + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "by_name" + ], + "properties": { + "by_name": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "$ref": "#/definitions/NymName" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "by_address" + ], + "properties": { + "by_address": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "$ref": "#/definitions/Address" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "all" + ], + "properties": { + "all": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "signing_nonce" + ], + "properties": { + "signing_nonce": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "config" + ], + "properties": { + "config": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets build information of this contract, such as the commit hash used for the build or rustc version.", + "type": "object", + "required": [ + "get_contract_version" + ], + "properties": { + "get_contract_version": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the stored contract version information that's required by the CW2 spec interface for migrations.", + "type": "object", + "required": [ + "get_cw2_contract_version" + ], + "properties": { + "get_cw2_contract_version": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Address": { + "description": "String representation of a nym address, which is of the form client_id.client_enc@gateway_id. NOTE: entirely unvalidated.", + "oneOf": [ + { + "type": "object", + "required": [ + "nym_address" + ], + "properties": { + "nym_address": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "NymName": { + "description": "Name stored and pointing a to a nym-address", + "type": "string" + } + } + }, + "migrate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "type": "object", + "additionalProperties": false + }, + "sudo": null, + "responses": { + "all": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedNamesListResponse", + "type": "object", + "required": [ + "names", + "per_page" + ], + "properties": { + "names": { + "type": "array", + "items": { + "$ref": "#/definitions/RegisteredName" + } + }, + "per_page": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Address": { + "description": "String representation of a nym address, which is of the form client_id.client_enc@gateway_id. NOTE: entirely unvalidated.", + "oneOf": [ + { + "type": "object", + "required": [ + "nym_address" + ], + "properties": { + "nym_address": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "NameDetails": { + "type": "object", + "required": [ + "address", + "identity_key", + "name" + ], + "properties": { + "address": { + "description": "The address of the name alias.", + "allOf": [ + { + "$ref": "#/definitions/Address" + } + ] + }, + "identity_key": { + "description": "The identity key of the registered name.", + "type": "string" + }, + "name": { + "description": "The name pointing to the nym address", + "allOf": [ + { + "$ref": "#/definitions/NymName" + } + ] + } + }, + "additionalProperties": false + }, + "NymName": { + "description": "Name stored and pointing a to a nym-address", + "type": "string" + }, + "RegisteredName": { + "type": "object", + "required": [ + "block_height", + "deposit", + "id", + "name", + "owner" + ], + "properties": { + "block_height": { + "description": "Block height at which the name was added.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "deposit": { + "description": "The deposit used to announce the name.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "id": { + "description": "Unique id assigned to the registerd name.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "name": { + "description": "The registerd name details.", + "allOf": [ + { + "$ref": "#/definitions/NameDetails" + } + ] + }, + "owner": { + "description": "name owner.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "by_address": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "NamesListResponse", + "type": "object", + "required": [ + "names" + ], + "properties": { + "names": { + "type": "array", + "items": { + "$ref": "#/definitions/RegisteredName" + } + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Address": { + "description": "String representation of a nym address, which is of the form client_id.client_enc@gateway_id. NOTE: entirely unvalidated.", + "oneOf": [ + { + "type": "object", + "required": [ + "nym_address" + ], + "properties": { + "nym_address": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "NameDetails": { + "type": "object", + "required": [ + "address", + "identity_key", + "name" + ], + "properties": { + "address": { + "description": "The address of the name alias.", + "allOf": [ + { + "$ref": "#/definitions/Address" + } + ] + }, + "identity_key": { + "description": "The identity key of the registered name.", + "type": "string" + }, + "name": { + "description": "The name pointing to the nym address", + "allOf": [ + { + "$ref": "#/definitions/NymName" + } + ] + } + }, + "additionalProperties": false + }, + "NymName": { + "description": "Name stored and pointing a to a nym-address", + "type": "string" + }, + "RegisteredName": { + "type": "object", + "required": [ + "block_height", + "deposit", + "id", + "name", + "owner" + ], + "properties": { + "block_height": { + "description": "Block height at which the name was added.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "deposit": { + "description": "The deposit used to announce the name.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "id": { + "description": "Unique id assigned to the registerd name.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "name": { + "description": "The registerd name details.", + "allOf": [ + { + "$ref": "#/definitions/NameDetails" + } + ] + }, + "owner": { + "description": "name owner.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "by_name": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "RegisteredName", + "type": "object", + "required": [ + "block_height", + "deposit", + "id", + "name", + "owner" + ], + "properties": { + "block_height": { + "description": "Block height at which the name was added.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "deposit": { + "description": "The deposit used to announce the name.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "id": { + "description": "Unique id assigned to the registerd name.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "name": { + "description": "The registerd name details.", + "allOf": [ + { + "$ref": "#/definitions/NameDetails" + } + ] + }, + "owner": { + "description": "name owner.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Address": { + "description": "String representation of a nym address, which is of the form client_id.client_enc@gateway_id. NOTE: entirely unvalidated.", + "oneOf": [ + { + "type": "object", + "required": [ + "nym_address" + ], + "properties": { + "nym_address": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "NameDetails": { + "type": "object", + "required": [ + "address", + "identity_key", + "name" + ], + "properties": { + "address": { + "description": "The address of the name alias.", + "allOf": [ + { + "$ref": "#/definitions/Address" + } + ] + }, + "identity_key": { + "description": "The identity key of the registered name.", + "type": "string" + }, + "name": { + "description": "The name pointing to the nym address", + "allOf": [ + { + "$ref": "#/definitions/NymName" + } + ] + } + }, + "additionalProperties": false + }, + "NymName": { + "description": "Name stored and pointing a to a nym-address", + "type": "string" + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "by_owner": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "NamesListResponse", + "type": "object", + "required": [ + "names" + ], + "properties": { + "names": { + "type": "array", + "items": { + "$ref": "#/definitions/RegisteredName" + } + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Address": { + "description": "String representation of a nym address, which is of the form client_id.client_enc@gateway_id. NOTE: entirely unvalidated.", + "oneOf": [ + { + "type": "object", + "required": [ + "nym_address" + ], + "properties": { + "nym_address": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "NameDetails": { + "type": "object", + "required": [ + "address", + "identity_key", + "name" + ], + "properties": { + "address": { + "description": "The address of the name alias.", + "allOf": [ + { + "$ref": "#/definitions/Address" + } + ] + }, + "identity_key": { + "description": "The identity key of the registered name.", + "type": "string" + }, + "name": { + "description": "The name pointing to the nym address", + "allOf": [ + { + "$ref": "#/definitions/NymName" + } + ] + } + }, + "additionalProperties": false + }, + "NymName": { + "description": "Name stored and pointing a to a nym-address", + "type": "string" + }, + "RegisteredName": { + "type": "object", + "required": [ + "block_height", + "deposit", + "id", + "name", + "owner" + ], + "properties": { + "block_height": { + "description": "Block height at which the name was added.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "deposit": { + "description": "The deposit used to announce the name.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "id": { + "description": "Unique id assigned to the registerd name.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "name": { + "description": "The registerd name details.", + "allOf": [ + { + "$ref": "#/definitions/NameDetails" + } + ] + }, + "owner": { + "description": "name owner.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "config": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ConfigResponse", + "type": "object", + "required": [ + "deposit_required" + ], + "properties": { + "deposit_required": { + "$ref": "#/definitions/Coin" + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_c_w2_contract_version": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ContractVersion", + "type": "object", + "required": [ + "contract", + "version" + ], + "properties": { + "contract": { + "description": "contract is the crate name of the implementing contract, eg. `crate:cw20-base` we will use other prefixes for other languages, and their standard global namespacing", + "type": "string" + }, + "version": { + "description": "version is any string that this implementation knows. It may be simple counter \"1\", \"2\". or semantic version on release tags \"v0.7.0\", or some custom feature flag list. the only code that needs to understand the version parsing is code that knows how to migrate from the given contract (and is tied to it's implementation somehow)", + "type": "string" + } + }, + "additionalProperties": false + }, + "get_contract_version": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ContractBuildInformation", + "type": "object", + "required": [ + "build_timestamp", + "build_version", + "commit_branch", + "commit_sha", + "commit_timestamp", + "rustc_version" + ], + "properties": { + "build_timestamp": { + "description": "Provides the build timestamp, for example `2021-02-23T20:14:46.558472672+00:00`.", + "type": "string" + }, + "build_version": { + "description": "Provides the build version, for example `0.1.0-9-g46f83e1`.", + "type": "string" + }, + "commit_branch": { + "description": "Provides the name of the git branch that was used for the build, for example `master`.", + "type": "string" + }, + "commit_sha": { + "description": "Provides the hash of the commit that was used for the build, for example `46f83e112520533338245862d366f6a02cef07d4`.", + "type": "string" + }, + "commit_timestamp": { + "description": "Provides the timestamp of the commit that was used for the build, for example `2021-02-23T08:08:02-05:00`.", + "type": "string" + }, + "rustc_version": { + "description": "Provides the rustc version that was used for the build, for example `1.52.0-nightly`.", + "type": "string" + } + }, + "additionalProperties": false + }, + "name_id": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "RegisteredName", + "type": "object", + "required": [ + "block_height", + "deposit", + "id", + "name", + "owner" + ], + "properties": { + "block_height": { + "description": "Block height at which the name was added.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "deposit": { + "description": "The deposit used to announce the name.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "id": { + "description": "Unique id assigned to the registerd name.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "name": { + "description": "The registerd name details.", + "allOf": [ + { + "$ref": "#/definitions/NameDetails" + } + ] + }, + "owner": { + "description": "name owner.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Address": { + "description": "String representation of a nym address, which is of the form client_id.client_enc@gateway_id. NOTE: entirely unvalidated.", + "oneOf": [ + { + "type": "object", + "required": [ + "nym_address" + ], + "properties": { + "nym_address": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "NameDetails": { + "type": "object", + "required": [ + "address", + "identity_key", + "name" + ], + "properties": { + "address": { + "description": "The address of the name alias.", + "allOf": [ + { + "$ref": "#/definitions/Address" + } + ] + }, + "identity_key": { + "description": "The identity key of the registered name.", + "type": "string" + }, + "name": { + "description": "The name pointing to the nym address", + "allOf": [ + { + "$ref": "#/definitions/NymName" + } + ] + } + }, + "additionalProperties": false + }, + "NymName": { + "description": "Name stored and pointing a to a nym-address", + "type": "string" + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "signing_nonce": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "uint32", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + } +} diff --git a/contracts/name-service/schema/raw/execute.json b/contracts/name-service/schema/raw/execute.json new file mode 100644 index 0000000000..c902157b43 --- /dev/null +++ b/contracts/name-service/schema/raw/execute.json @@ -0,0 +1,181 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Announcing a name pointing to a nym-address", + "type": "object", + "required": [ + "register" + ], + "properties": { + "register": { + "type": "object", + "required": [ + "name", + "owner_signature" + ], + "properties": { + "name": { + "$ref": "#/definitions/NameDetails" + }, + "owner_signature": { + "$ref": "#/definitions/MessageSignature" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Delete a name entry by id", + "type": "object", + "required": [ + "delete_id" + ], + "properties": { + "delete_id": { + "type": "object", + "required": [ + "name_id" + ], + "properties": { + "name_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Delete a name entry by name", + "type": "object", + "required": [ + "delete_name" + ], + "properties": { + "delete_name": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "$ref": "#/definitions/NymName" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Change the deposit required for announcing a name", + "type": "object", + "required": [ + "update_deposit_required" + ], + "properties": { + "update_deposit_required": { + "type": "object", + "required": [ + "deposit_required" + ], + "properties": { + "deposit_required": { + "$ref": "#/definitions/Coin" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Address": { + "description": "String representation of a nym address, which is of the form client_id.client_enc@gateway_id. NOTE: entirely unvalidated.", + "oneOf": [ + { + "type": "object", + "required": [ + "nym_address" + ], + "properties": { + "nym_address": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "MessageSignature": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + }, + "NameDetails": { + "type": "object", + "required": [ + "address", + "identity_key", + "name" + ], + "properties": { + "address": { + "description": "The address of the name alias.", + "allOf": [ + { + "$ref": "#/definitions/Address" + } + ] + }, + "identity_key": { + "description": "The identity key of the registered name.", + "type": "string" + }, + "name": { + "description": "The name pointing to the nym address", + "allOf": [ + { + "$ref": "#/definitions/NymName" + } + ] + } + }, + "additionalProperties": false + }, + "NymName": { + "description": "Name stored and pointing a to a nym-address", + "type": "string" + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/name-service/schema/raw/instantiate.json b/contracts/name-service/schema/raw/instantiate.json new file mode 100644 index 0000000000..73867fda63 --- /dev/null +++ b/contracts/name-service/schema/raw/instantiate.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "deposit_required" + ], + "properties": { + "deposit_required": { + "$ref": "#/definitions/Coin" + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/name-service/schema/raw/migrate.json b/contracts/name-service/schema/raw/migrate.json new file mode 100644 index 0000000000..7fbe8c5708 --- /dev/null +++ b/contracts/name-service/schema/raw/migrate.json @@ -0,0 +1,6 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "type": "object", + "additionalProperties": false +} diff --git a/contracts/name-service/schema/raw/query.json b/contracts/name-service/schema/raw/query.json new file mode 100644 index 0000000000..1c4efca8df --- /dev/null +++ b/contracts/name-service/schema/raw/query.json @@ -0,0 +1,210 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "description": "Query the name by it's assigned id", + "type": "object", + "required": [ + "name_id" + ], + "properties": { + "name_id": { + "type": "object", + "required": [ + "name_id" + ], + "properties": { + "name_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Query the names by the registrator", + "type": "object", + "required": [ + "by_owner" + ], + "properties": { + "by_owner": { + "type": "object", + "required": [ + "owner" + ], + "properties": { + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "by_name" + ], + "properties": { + "by_name": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "$ref": "#/definitions/NymName" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "by_address" + ], + "properties": { + "by_address": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "$ref": "#/definitions/Address" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "all" + ], + "properties": { + "all": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "signing_nonce" + ], + "properties": { + "signing_nonce": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "config" + ], + "properties": { + "config": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets build information of this contract, such as the commit hash used for the build or rustc version.", + "type": "object", + "required": [ + "get_contract_version" + ], + "properties": { + "get_contract_version": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the stored contract version information that's required by the CW2 spec interface for migrations.", + "type": "object", + "required": [ + "get_cw2_contract_version" + ], + "properties": { + "get_cw2_contract_version": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Address": { + "description": "String representation of a nym address, which is of the form client_id.client_enc@gateway_id. NOTE: entirely unvalidated.", + "oneOf": [ + { + "type": "object", + "required": [ + "nym_address" + ], + "properties": { + "nym_address": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "NymName": { + "description": "Name stored and pointing a to a nym-address", + "type": "string" + } + } +} diff --git a/contracts/name-service/schema/raw/response_to_all.json b/contracts/name-service/schema/raw/response_to_all.json new file mode 100644 index 0000000000..5d4ab85d35 --- /dev/null +++ b/contracts/name-service/schema/raw/response_to_all.json @@ -0,0 +1,158 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedNamesListResponse", + "type": "object", + "required": [ + "names", + "per_page" + ], + "properties": { + "names": { + "type": "array", + "items": { + "$ref": "#/definitions/RegisteredName" + } + }, + "per_page": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Address": { + "description": "String representation of a nym address, which is of the form client_id.client_enc@gateway_id. NOTE: entirely unvalidated.", + "oneOf": [ + { + "type": "object", + "required": [ + "nym_address" + ], + "properties": { + "nym_address": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "NameDetails": { + "type": "object", + "required": [ + "address", + "identity_key", + "name" + ], + "properties": { + "address": { + "description": "The address of the name alias.", + "allOf": [ + { + "$ref": "#/definitions/Address" + } + ] + }, + "identity_key": { + "description": "The identity key of the registered name.", + "type": "string" + }, + "name": { + "description": "The name pointing to the nym address", + "allOf": [ + { + "$ref": "#/definitions/NymName" + } + ] + } + }, + "additionalProperties": false + }, + "NymName": { + "description": "Name stored and pointing a to a nym-address", + "type": "string" + }, + "RegisteredName": { + "type": "object", + "required": [ + "block_height", + "deposit", + "id", + "name", + "owner" + ], + "properties": { + "block_height": { + "description": "Block height at which the name was added.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "deposit": { + "description": "The deposit used to announce the name.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "id": { + "description": "Unique id assigned to the registerd name.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "name": { + "description": "The registerd name details.", + "allOf": [ + { + "$ref": "#/definitions/NameDetails" + } + ] + }, + "owner": { + "description": "name owner.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/name-service/schema/raw/response_to_by_address.json b/contracts/name-service/schema/raw/response_to_by_address.json new file mode 100644 index 0000000000..0e44754b87 --- /dev/null +++ b/contracts/name-service/schema/raw/response_to_by_address.json @@ -0,0 +1,143 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "NamesListResponse", + "type": "object", + "required": [ + "names" + ], + "properties": { + "names": { + "type": "array", + "items": { + "$ref": "#/definitions/RegisteredName" + } + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Address": { + "description": "String representation of a nym address, which is of the form client_id.client_enc@gateway_id. NOTE: entirely unvalidated.", + "oneOf": [ + { + "type": "object", + "required": [ + "nym_address" + ], + "properties": { + "nym_address": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "NameDetails": { + "type": "object", + "required": [ + "address", + "identity_key", + "name" + ], + "properties": { + "address": { + "description": "The address of the name alias.", + "allOf": [ + { + "$ref": "#/definitions/Address" + } + ] + }, + "identity_key": { + "description": "The identity key of the registered name.", + "type": "string" + }, + "name": { + "description": "The name pointing to the nym address", + "allOf": [ + { + "$ref": "#/definitions/NymName" + } + ] + } + }, + "additionalProperties": false + }, + "NymName": { + "description": "Name stored and pointing a to a nym-address", + "type": "string" + }, + "RegisteredName": { + "type": "object", + "required": [ + "block_height", + "deposit", + "id", + "name", + "owner" + ], + "properties": { + "block_height": { + "description": "Block height at which the name was added.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "deposit": { + "description": "The deposit used to announce the name.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "id": { + "description": "Unique id assigned to the registerd name.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "name": { + "description": "The registerd name details.", + "allOf": [ + { + "$ref": "#/definitions/NameDetails" + } + ] + }, + "owner": { + "description": "name owner.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/name-service/schema/raw/response_to_by_name.json b/contracts/name-service/schema/raw/response_to_by_name.json new file mode 100644 index 0000000000..4dfc8752ee --- /dev/null +++ b/contracts/name-service/schema/raw/response_to_by_name.json @@ -0,0 +1,128 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "RegisteredName", + "type": "object", + "required": [ + "block_height", + "deposit", + "id", + "name", + "owner" + ], + "properties": { + "block_height": { + "description": "Block height at which the name was added.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "deposit": { + "description": "The deposit used to announce the name.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "id": { + "description": "Unique id assigned to the registerd name.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "name": { + "description": "The registerd name details.", + "allOf": [ + { + "$ref": "#/definitions/NameDetails" + } + ] + }, + "owner": { + "description": "name owner.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Address": { + "description": "String representation of a nym address, which is of the form client_id.client_enc@gateway_id. NOTE: entirely unvalidated.", + "oneOf": [ + { + "type": "object", + "required": [ + "nym_address" + ], + "properties": { + "nym_address": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "NameDetails": { + "type": "object", + "required": [ + "address", + "identity_key", + "name" + ], + "properties": { + "address": { + "description": "The address of the name alias.", + "allOf": [ + { + "$ref": "#/definitions/Address" + } + ] + }, + "identity_key": { + "description": "The identity key of the registered name.", + "type": "string" + }, + "name": { + "description": "The name pointing to the nym address", + "allOf": [ + { + "$ref": "#/definitions/NymName" + } + ] + } + }, + "additionalProperties": false + }, + "NymName": { + "description": "Name stored and pointing a to a nym-address", + "type": "string" + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/name-service/schema/raw/response_to_by_owner.json b/contracts/name-service/schema/raw/response_to_by_owner.json new file mode 100644 index 0000000000..0e44754b87 --- /dev/null +++ b/contracts/name-service/schema/raw/response_to_by_owner.json @@ -0,0 +1,143 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "NamesListResponse", + "type": "object", + "required": [ + "names" + ], + "properties": { + "names": { + "type": "array", + "items": { + "$ref": "#/definitions/RegisteredName" + } + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Address": { + "description": "String representation of a nym address, which is of the form client_id.client_enc@gateway_id. NOTE: entirely unvalidated.", + "oneOf": [ + { + "type": "object", + "required": [ + "nym_address" + ], + "properties": { + "nym_address": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "NameDetails": { + "type": "object", + "required": [ + "address", + "identity_key", + "name" + ], + "properties": { + "address": { + "description": "The address of the name alias.", + "allOf": [ + { + "$ref": "#/definitions/Address" + } + ] + }, + "identity_key": { + "description": "The identity key of the registered name.", + "type": "string" + }, + "name": { + "description": "The name pointing to the nym address", + "allOf": [ + { + "$ref": "#/definitions/NymName" + } + ] + } + }, + "additionalProperties": false + }, + "NymName": { + "description": "Name stored and pointing a to a nym-address", + "type": "string" + }, + "RegisteredName": { + "type": "object", + "required": [ + "block_height", + "deposit", + "id", + "name", + "owner" + ], + "properties": { + "block_height": { + "description": "Block height at which the name was added.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "deposit": { + "description": "The deposit used to announce the name.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "id": { + "description": "Unique id assigned to the registerd name.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "name": { + "description": "The registerd name details.", + "allOf": [ + { + "$ref": "#/definitions/NameDetails" + } + ] + }, + "owner": { + "description": "name owner.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/name-service/schema/raw/response_to_config.json b/contracts/name-service/schema/raw/response_to_config.json new file mode 100644 index 0000000000..16420c1130 --- /dev/null +++ b/contracts/name-service/schema/raw/response_to_config.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ConfigResponse", + "type": "object", + "required": [ + "deposit_required" + ], + "properties": { + "deposit_required": { + "$ref": "#/definitions/Coin" + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/name-service/schema/raw/response_to_get_c_w2_contract_version.json b/contracts/name-service/schema/raw/response_to_get_c_w2_contract_version.json new file mode 100644 index 0000000000..3ded8c84d9 --- /dev/null +++ b/contracts/name-service/schema/raw/response_to_get_c_w2_contract_version.json @@ -0,0 +1,20 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ContractVersion", + "type": "object", + "required": [ + "contract", + "version" + ], + "properties": { + "contract": { + "description": "contract is the crate name of the implementing contract, eg. `crate:cw20-base` we will use other prefixes for other languages, and their standard global namespacing", + "type": "string" + }, + "version": { + "description": "version is any string that this implementation knows. It may be simple counter \"1\", \"2\". or semantic version on release tags \"v0.7.0\", or some custom feature flag list. the only code that needs to understand the version parsing is code that knows how to migrate from the given contract (and is tied to it's implementation somehow)", + "type": "string" + } + }, + "additionalProperties": false +} diff --git a/contracts/name-service/schema/raw/response_to_get_contract_version.json b/contracts/name-service/schema/raw/response_to_get_contract_version.json new file mode 100644 index 0000000000..60ae65f3d1 --- /dev/null +++ b/contracts/name-service/schema/raw/response_to_get_contract_version.json @@ -0,0 +1,40 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ContractBuildInformation", + "type": "object", + "required": [ + "build_timestamp", + "build_version", + "commit_branch", + "commit_sha", + "commit_timestamp", + "rustc_version" + ], + "properties": { + "build_timestamp": { + "description": "Provides the build timestamp, for example `2021-02-23T20:14:46.558472672+00:00`.", + "type": "string" + }, + "build_version": { + "description": "Provides the build version, for example `0.1.0-9-g46f83e1`.", + "type": "string" + }, + "commit_branch": { + "description": "Provides the name of the git branch that was used for the build, for example `master`.", + "type": "string" + }, + "commit_sha": { + "description": "Provides the hash of the commit that was used for the build, for example `46f83e112520533338245862d366f6a02cef07d4`.", + "type": "string" + }, + "commit_timestamp": { + "description": "Provides the timestamp of the commit that was used for the build, for example `2021-02-23T08:08:02-05:00`.", + "type": "string" + }, + "rustc_version": { + "description": "Provides the rustc version that was used for the build, for example `1.52.0-nightly`.", + "type": "string" + } + }, + "additionalProperties": false +} diff --git a/contracts/name-service/schema/raw/response_to_name_id.json b/contracts/name-service/schema/raw/response_to_name_id.json new file mode 100644 index 0000000000..4dfc8752ee --- /dev/null +++ b/contracts/name-service/schema/raw/response_to_name_id.json @@ -0,0 +1,128 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "RegisteredName", + "type": "object", + "required": [ + "block_height", + "deposit", + "id", + "name", + "owner" + ], + "properties": { + "block_height": { + "description": "Block height at which the name was added.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "deposit": { + "description": "The deposit used to announce the name.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "id": { + "description": "Unique id assigned to the registerd name.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "name": { + "description": "The registerd name details.", + "allOf": [ + { + "$ref": "#/definitions/NameDetails" + } + ] + }, + "owner": { + "description": "name owner.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Address": { + "description": "String representation of a nym address, which is of the form client_id.client_enc@gateway_id. NOTE: entirely unvalidated.", + "oneOf": [ + { + "type": "object", + "required": [ + "nym_address" + ], + "properties": { + "nym_address": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "NameDetails": { + "type": "object", + "required": [ + "address", + "identity_key", + "name" + ], + "properties": { + "address": { + "description": "The address of the name alias.", + "allOf": [ + { + "$ref": "#/definitions/Address" + } + ] + }, + "identity_key": { + "description": "The identity key of the registered name.", + "type": "string" + }, + "name": { + "description": "The name pointing to the nym address", + "allOf": [ + { + "$ref": "#/definitions/NymName" + } + ] + } + }, + "additionalProperties": false + }, + "NymName": { + "description": "Name stored and pointing a to a nym-address", + "type": "string" + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/name-service/schema/raw/response_to_signing_nonce.json b/contracts/name-service/schema/raw/response_to_signing_nonce.json new file mode 100644 index 0000000000..de85c3e56e --- /dev/null +++ b/contracts/name-service/schema/raw/response_to_signing_nonce.json @@ -0,0 +1,7 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "uint32", + "type": "integer", + "format": "uint32", + "minimum": 0.0 +} diff --git a/contracts/name-service/src/bin/schema.rs b/contracts/name-service/src/bin/schema.rs new file mode 100644 index 0000000000..92f8f3f6ab --- /dev/null +++ b/contracts/name-service/src/bin/schema.rs @@ -0,0 +1,14 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use cosmwasm_schema::write_api; +use nym_name_service_common::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + query: QueryMsg, + execute: ExecuteMsg, + migrate: MigrateMsg, + } +} diff --git a/contracts/name-service/src/state/names.rs b/contracts/name-service/src/state/names.rs index 3b2b02f82d..41c68bf714 100644 --- a/contracts/name-service/src/state/names.rs +++ b/contracts/name-service/src/state/names.rs @@ -120,6 +120,8 @@ pub fn load_owner(store: &dyn Storage, owner: Addr) -> Result, pub limit: usize, + + /// Field indicating paging information for the following queries if the caller wishes to get further entries. pub start_next_after: Option, } diff --git a/contracts/service-provider-directory/.cargo/config b/contracts/service-provider-directory/.cargo/config index 4fa7f37d4a..2f698e22b3 100644 --- a/contracts/service-provider-directory/.cargo/config +++ b/contracts/service-provider-directory/.cargo/config @@ -2,4 +2,4 @@ wasm = "build --release --lib --target wasm32-unknown-unknown" wasm-debug = "build --target wasm32-unknown-unknown" unit-test = "test --lib" -schema = "run --bin schema" +schema = "run --bin schema --features=schema-gen" \ No newline at end of file diff --git a/contracts/service-provider-directory/Cargo.toml b/contracts/service-provider-directory/Cargo.toml index cadc17d708..39ffcaf6f7 100644 --- a/contracts/service-provider-directory/Cargo.toml +++ b/contracts/service-provider-directory/Cargo.toml @@ -3,11 +3,16 @@ name = "nym-service-provider-directory" version = "0.1.0" edition = "2021" +[[bin]] +name = "schema" +required-features = ["schema-gen"] + [lib] crate-type = ["cdylib", "rlib"] [dependencies] bs58 = "0.4.0" +cosmwasm-schema = { workspace = true, optional = true } cosmwasm-std = { workspace = true } cw-controllers = { workspace = true } cw-storage-plus = { workspace = true } @@ -28,3 +33,6 @@ cw-multi-test = { workspace = true } nym-crypto = { path = "../../common/crypto", features = ["asymmetric", "rand"] } rand_chacha = "0.2" rstest = "0.17.0" + +[features] +schema-gen = ["nym-service-provider-directory-common/schema", "cosmwasm-schema"] diff --git a/contracts/service-provider-directory/Makefile b/contracts/service-provider-directory/Makefile new file mode 100644 index 0000000000..f138e2c879 --- /dev/null +++ b/contracts/service-provider-directory/Makefile @@ -0,0 +1,2 @@ +generate-schema: + cargo schema \ No newline at end of file diff --git a/contracts/service-provider-directory/schema/nym-service-provider-directory.json b/contracts/service-provider-directory/schema/nym-service-provider-directory.json new file mode 100644 index 0000000000..d923ef3f99 --- /dev/null +++ b/contracts/service-provider-directory/schema/nym-service-provider-directory.json @@ -0,0 +1,1104 @@ +{ + "contract_name": "nym-service-provider-directory", + "contract_version": "0.1.0", + "idl_version": "1.0.0", + "instantiate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "deposit_required" + ], + "properties": { + "deposit_required": { + "$ref": "#/definitions/Coin" + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "execute": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "announce" + ], + "properties": { + "announce": { + "type": "object", + "required": [ + "owner_signature", + "service" + ], + "properties": { + "owner_signature": { + "$ref": "#/definitions/MessageSignature" + }, + "service": { + "$ref": "#/definitions/ServiceDetails" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "delete_id" + ], + "properties": { + "delete_id": { + "type": "object", + "required": [ + "service_id" + ], + "properties": { + "service_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "delete_nym_address" + ], + "properties": { + "delete_nym_address": { + "type": "object", + "required": [ + "nym_address" + ], + "properties": { + "nym_address": { + "$ref": "#/definitions/NymAddress" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_deposit_required" + ], + "properties": { + "update_deposit_required": { + "type": "object", + "required": [ + "deposit_required" + ], + "properties": { + "deposit_required": { + "$ref": "#/definitions/Coin" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "MessageSignature": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + }, + "NymAddress": { + "description": "The types of addresses supported.", + "oneOf": [ + { + "description": "String representation of a nym address, which is of the form client_id.client_enc@gateway_id.", + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "ServiceDetails": { + "type": "object", + "required": [ + "identity_key", + "nym_address", + "service_type" + ], + "properties": { + "identity_key": { + "description": "The identity key of the service.", + "type": "string" + }, + "nym_address": { + "description": "The address of the service.", + "allOf": [ + { + "$ref": "#/definitions/NymAddress" + } + ] + }, + "service_type": { + "description": "The service type.", + "allOf": [ + { + "$ref": "#/definitions/ServiceType" + } + ] + } + }, + "additionalProperties": false + }, + "ServiceType": { + "description": "The type of services provider supported", + "type": "string", + "enum": [ + "network_requester" + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "query": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "service_id" + ], + "properties": { + "service_id": { + "type": "object", + "required": [ + "service_id" + ], + "properties": { + "service_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "by_announcer" + ], + "properties": { + "by_announcer": { + "type": "object", + "required": [ + "announcer" + ], + "properties": { + "announcer": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "by_nym_address" + ], + "properties": { + "by_nym_address": { + "type": "object", + "required": [ + "nym_address" + ], + "properties": { + "nym_address": { + "$ref": "#/definitions/NymAddress" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "all" + ], + "properties": { + "all": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "signing_nonce" + ], + "properties": { + "signing_nonce": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "config" + ], + "properties": { + "config": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets build information of this contract, such as the commit hash used for the build or rustc version.", + "type": "object", + "required": [ + "get_contract_version" + ], + "properties": { + "get_contract_version": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the stored contract version information that's required by the CW2 spec interface for migrations.", + "type": "object", + "required": [ + "get_cw2_contract_version" + ], + "properties": { + "get_cw2_contract_version": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "NymAddress": { + "description": "The types of addresses supported.", + "oneOf": [ + { + "description": "String representation of a nym address, which is of the form client_id.client_enc@gateway_id.", + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + } + } + }, + "migrate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "type": "object", + "additionalProperties": false + }, + "sudo": null, + "responses": { + "all": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedServicesListResponse", + "type": "object", + "required": [ + "per_page", + "services" + ], + "properties": { + "per_page": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "services": { + "type": "array", + "items": { + "$ref": "#/definitions/Service" + } + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "NymAddress": { + "description": "The types of addresses supported.", + "oneOf": [ + { + "description": "String representation of a nym address, which is of the form client_id.client_enc@gateway_id.", + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "Service": { + "type": "object", + "required": [ + "announcer", + "block_height", + "deposit", + "service", + "service_id" + ], + "properties": { + "announcer": { + "description": "Address of the service owner.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "block_height": { + "description": "Block height at which the service was added.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "deposit": { + "description": "The deposit used to announce the service.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "service": { + "description": "The announced service.", + "allOf": [ + { + "$ref": "#/definitions/ServiceDetails" + } + ] + }, + "service_id": { + "description": "Unique id assigned to the anounced service.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "ServiceDetails": { + "type": "object", + "required": [ + "identity_key", + "nym_address", + "service_type" + ], + "properties": { + "identity_key": { + "description": "The identity key of the service.", + "type": "string" + }, + "nym_address": { + "description": "The address of the service.", + "allOf": [ + { + "$ref": "#/definitions/NymAddress" + } + ] + }, + "service_type": { + "description": "The service type.", + "allOf": [ + { + "$ref": "#/definitions/ServiceType" + } + ] + } + }, + "additionalProperties": false + }, + "ServiceType": { + "description": "The type of services provider supported", + "type": "string", + "enum": [ + "network_requester" + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "by_announcer": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ServicesListResponse", + "type": "object", + "required": [ + "services" + ], + "properties": { + "services": { + "type": "array", + "items": { + "$ref": "#/definitions/Service" + } + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "NymAddress": { + "description": "The types of addresses supported.", + "oneOf": [ + { + "description": "String representation of a nym address, which is of the form client_id.client_enc@gateway_id.", + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "Service": { + "type": "object", + "required": [ + "announcer", + "block_height", + "deposit", + "service", + "service_id" + ], + "properties": { + "announcer": { + "description": "Address of the service owner.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "block_height": { + "description": "Block height at which the service was added.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "deposit": { + "description": "The deposit used to announce the service.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "service": { + "description": "The announced service.", + "allOf": [ + { + "$ref": "#/definitions/ServiceDetails" + } + ] + }, + "service_id": { + "description": "Unique id assigned to the anounced service.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "ServiceDetails": { + "type": "object", + "required": [ + "identity_key", + "nym_address", + "service_type" + ], + "properties": { + "identity_key": { + "description": "The identity key of the service.", + "type": "string" + }, + "nym_address": { + "description": "The address of the service.", + "allOf": [ + { + "$ref": "#/definitions/NymAddress" + } + ] + }, + "service_type": { + "description": "The service type.", + "allOf": [ + { + "$ref": "#/definitions/ServiceType" + } + ] + } + }, + "additionalProperties": false + }, + "ServiceType": { + "description": "The type of services provider supported", + "type": "string", + "enum": [ + "network_requester" + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "by_nym_address": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ServicesListResponse", + "type": "object", + "required": [ + "services" + ], + "properties": { + "services": { + "type": "array", + "items": { + "$ref": "#/definitions/Service" + } + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "NymAddress": { + "description": "The types of addresses supported.", + "oneOf": [ + { + "description": "String representation of a nym address, which is of the form client_id.client_enc@gateway_id.", + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "Service": { + "type": "object", + "required": [ + "announcer", + "block_height", + "deposit", + "service", + "service_id" + ], + "properties": { + "announcer": { + "description": "Address of the service owner.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "block_height": { + "description": "Block height at which the service was added.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "deposit": { + "description": "The deposit used to announce the service.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "service": { + "description": "The announced service.", + "allOf": [ + { + "$ref": "#/definitions/ServiceDetails" + } + ] + }, + "service_id": { + "description": "Unique id assigned to the anounced service.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "ServiceDetails": { + "type": "object", + "required": [ + "identity_key", + "nym_address", + "service_type" + ], + "properties": { + "identity_key": { + "description": "The identity key of the service.", + "type": "string" + }, + "nym_address": { + "description": "The address of the service.", + "allOf": [ + { + "$ref": "#/definitions/NymAddress" + } + ] + }, + "service_type": { + "description": "The service type.", + "allOf": [ + { + "$ref": "#/definitions/ServiceType" + } + ] + } + }, + "additionalProperties": false + }, + "ServiceType": { + "description": "The type of services provider supported", + "type": "string", + "enum": [ + "network_requester" + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "config": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ConfigResponse", + "type": "object", + "required": [ + "deposit_required" + ], + "properties": { + "deposit_required": { + "$ref": "#/definitions/Coin" + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_c_w2_contract_version": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ContractVersion", + "type": "object", + "required": [ + "contract", + "version" + ], + "properties": { + "contract": { + "description": "contract is the crate name of the implementing contract, eg. `crate:cw20-base` we will use other prefixes for other languages, and their standard global namespacing", + "type": "string" + }, + "version": { + "description": "version is any string that this implementation knows. It may be simple counter \"1\", \"2\". or semantic version on release tags \"v0.7.0\", or some custom feature flag list. the only code that needs to understand the version parsing is code that knows how to migrate from the given contract (and is tied to it's implementation somehow)", + "type": "string" + } + }, + "additionalProperties": false + }, + "get_contract_version": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ContractBuildInformation", + "type": "object", + "required": [ + "build_timestamp", + "build_version", + "commit_branch", + "commit_sha", + "commit_timestamp", + "rustc_version" + ], + "properties": { + "build_timestamp": { + "description": "Provides the build timestamp, for example `2021-02-23T20:14:46.558472672+00:00`.", + "type": "string" + }, + "build_version": { + "description": "Provides the build version, for example `0.1.0-9-g46f83e1`.", + "type": "string" + }, + "commit_branch": { + "description": "Provides the name of the git branch that was used for the build, for example `master`.", + "type": "string" + }, + "commit_sha": { + "description": "Provides the hash of the commit that was used for the build, for example `46f83e112520533338245862d366f6a02cef07d4`.", + "type": "string" + }, + "commit_timestamp": { + "description": "Provides the timestamp of the commit that was used for the build, for example `2021-02-23T08:08:02-05:00`.", + "type": "string" + }, + "rustc_version": { + "description": "Provides the rustc version that was used for the build, for example `1.52.0-nightly`.", + "type": "string" + } + }, + "additionalProperties": false + }, + "service_id": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Service", + "type": "object", + "required": [ + "announcer", + "block_height", + "deposit", + "service", + "service_id" + ], + "properties": { + "announcer": { + "description": "Address of the service owner.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "block_height": { + "description": "Block height at which the service was added.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "deposit": { + "description": "The deposit used to announce the service.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "service": { + "description": "The announced service.", + "allOf": [ + { + "$ref": "#/definitions/ServiceDetails" + } + ] + }, + "service_id": { + "description": "Unique id assigned to the anounced service.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "NymAddress": { + "description": "The types of addresses supported.", + "oneOf": [ + { + "description": "String representation of a nym address, which is of the form client_id.client_enc@gateway_id.", + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "ServiceDetails": { + "type": "object", + "required": [ + "identity_key", + "nym_address", + "service_type" + ], + "properties": { + "identity_key": { + "description": "The identity key of the service.", + "type": "string" + }, + "nym_address": { + "description": "The address of the service.", + "allOf": [ + { + "$ref": "#/definitions/NymAddress" + } + ] + }, + "service_type": { + "description": "The service type.", + "allOf": [ + { + "$ref": "#/definitions/ServiceType" + } + ] + } + }, + "additionalProperties": false + }, + "ServiceType": { + "description": "The type of services provider supported", + "type": "string", + "enum": [ + "network_requester" + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "signing_nonce": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "uint32", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + } +} diff --git a/contracts/service-provider-directory/schema/raw/execute.json b/contracts/service-provider-directory/schema/raw/execute.json new file mode 100644 index 0000000000..995ede2a3a --- /dev/null +++ b/contracts/service-provider-directory/schema/raw/execute.json @@ -0,0 +1,181 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "announce" + ], + "properties": { + "announce": { + "type": "object", + "required": [ + "owner_signature", + "service" + ], + "properties": { + "owner_signature": { + "$ref": "#/definitions/MessageSignature" + }, + "service": { + "$ref": "#/definitions/ServiceDetails" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "delete_id" + ], + "properties": { + "delete_id": { + "type": "object", + "required": [ + "service_id" + ], + "properties": { + "service_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "delete_nym_address" + ], + "properties": { + "delete_nym_address": { + "type": "object", + "required": [ + "nym_address" + ], + "properties": { + "nym_address": { + "$ref": "#/definitions/NymAddress" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_deposit_required" + ], + "properties": { + "update_deposit_required": { + "type": "object", + "required": [ + "deposit_required" + ], + "properties": { + "deposit_required": { + "$ref": "#/definitions/Coin" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "MessageSignature": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + }, + "NymAddress": { + "description": "The types of addresses supported.", + "oneOf": [ + { + "description": "String representation of a nym address, which is of the form client_id.client_enc@gateway_id.", + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "ServiceDetails": { + "type": "object", + "required": [ + "identity_key", + "nym_address", + "service_type" + ], + "properties": { + "identity_key": { + "description": "The identity key of the service.", + "type": "string" + }, + "nym_address": { + "description": "The address of the service.", + "allOf": [ + { + "$ref": "#/definitions/NymAddress" + } + ] + }, + "service_type": { + "description": "The service type.", + "allOf": [ + { + "$ref": "#/definitions/ServiceType" + } + ] + } + }, + "additionalProperties": false + }, + "ServiceType": { + "description": "The type of services provider supported", + "type": "string", + "enum": [ + "network_requester" + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/service-provider-directory/schema/raw/instantiate.json b/contracts/service-provider-directory/schema/raw/instantiate.json new file mode 100644 index 0000000000..73867fda63 --- /dev/null +++ b/contracts/service-provider-directory/schema/raw/instantiate.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "deposit_required" + ], + "properties": { + "deposit_required": { + "$ref": "#/definitions/Coin" + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/service-provider-directory/schema/raw/migrate.json b/contracts/service-provider-directory/schema/raw/migrate.json new file mode 100644 index 0000000000..7fbe8c5708 --- /dev/null +++ b/contracts/service-provider-directory/schema/raw/migrate.json @@ -0,0 +1,6 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "type": "object", + "additionalProperties": false +} diff --git a/contracts/service-provider-directory/schema/raw/query.json b/contracts/service-provider-directory/schema/raw/query.json new file mode 100644 index 0000000000..f6abe3d45e --- /dev/null +++ b/contracts/service-provider-directory/schema/raw/query.json @@ -0,0 +1,184 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "service_id" + ], + "properties": { + "service_id": { + "type": "object", + "required": [ + "service_id" + ], + "properties": { + "service_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "by_announcer" + ], + "properties": { + "by_announcer": { + "type": "object", + "required": [ + "announcer" + ], + "properties": { + "announcer": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "by_nym_address" + ], + "properties": { + "by_nym_address": { + "type": "object", + "required": [ + "nym_address" + ], + "properties": { + "nym_address": { + "$ref": "#/definitions/NymAddress" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "all" + ], + "properties": { + "all": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "signing_nonce" + ], + "properties": { + "signing_nonce": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "config" + ], + "properties": { + "config": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets build information of this contract, such as the commit hash used for the build or rustc version.", + "type": "object", + "required": [ + "get_contract_version" + ], + "properties": { + "get_contract_version": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the stored contract version information that's required by the CW2 spec interface for migrations.", + "type": "object", + "required": [ + "get_cw2_contract_version" + ], + "properties": { + "get_cw2_contract_version": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "NymAddress": { + "description": "The types of addresses supported.", + "oneOf": [ + { + "description": "String representation of a nym address, which is of the form client_id.client_enc@gateway_id.", + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + } + } +} diff --git a/contracts/service-provider-directory/schema/raw/response_to_all.json b/contracts/service-provider-directory/schema/raw/response_to_all.json new file mode 100644 index 0000000000..e9d7c842dd --- /dev/null +++ b/contracts/service-provider-directory/schema/raw/response_to_all.json @@ -0,0 +1,162 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedServicesListResponse", + "type": "object", + "required": [ + "per_page", + "services" + ], + "properties": { + "per_page": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "services": { + "type": "array", + "items": { + "$ref": "#/definitions/Service" + } + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "NymAddress": { + "description": "The types of addresses supported.", + "oneOf": [ + { + "description": "String representation of a nym address, which is of the form client_id.client_enc@gateway_id.", + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "Service": { + "type": "object", + "required": [ + "announcer", + "block_height", + "deposit", + "service", + "service_id" + ], + "properties": { + "announcer": { + "description": "Address of the service owner.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "block_height": { + "description": "Block height at which the service was added.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "deposit": { + "description": "The deposit used to announce the service.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "service": { + "description": "The announced service.", + "allOf": [ + { + "$ref": "#/definitions/ServiceDetails" + } + ] + }, + "service_id": { + "description": "Unique id assigned to the anounced service.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "ServiceDetails": { + "type": "object", + "required": [ + "identity_key", + "nym_address", + "service_type" + ], + "properties": { + "identity_key": { + "description": "The identity key of the service.", + "type": "string" + }, + "nym_address": { + "description": "The address of the service.", + "allOf": [ + { + "$ref": "#/definitions/NymAddress" + } + ] + }, + "service_type": { + "description": "The service type.", + "allOf": [ + { + "$ref": "#/definitions/ServiceType" + } + ] + } + }, + "additionalProperties": false + }, + "ServiceType": { + "description": "The type of services provider supported", + "type": "string", + "enum": [ + "network_requester" + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/service-provider-directory/schema/raw/response_to_by_announcer.json b/contracts/service-provider-directory/schema/raw/response_to_by_announcer.json new file mode 100644 index 0000000000..a0092cef6b --- /dev/null +++ b/contracts/service-provider-directory/schema/raw/response_to_by_announcer.json @@ -0,0 +1,147 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ServicesListResponse", + "type": "object", + "required": [ + "services" + ], + "properties": { + "services": { + "type": "array", + "items": { + "$ref": "#/definitions/Service" + } + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "NymAddress": { + "description": "The types of addresses supported.", + "oneOf": [ + { + "description": "String representation of a nym address, which is of the form client_id.client_enc@gateway_id.", + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "Service": { + "type": "object", + "required": [ + "announcer", + "block_height", + "deposit", + "service", + "service_id" + ], + "properties": { + "announcer": { + "description": "Address of the service owner.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "block_height": { + "description": "Block height at which the service was added.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "deposit": { + "description": "The deposit used to announce the service.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "service": { + "description": "The announced service.", + "allOf": [ + { + "$ref": "#/definitions/ServiceDetails" + } + ] + }, + "service_id": { + "description": "Unique id assigned to the anounced service.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "ServiceDetails": { + "type": "object", + "required": [ + "identity_key", + "nym_address", + "service_type" + ], + "properties": { + "identity_key": { + "description": "The identity key of the service.", + "type": "string" + }, + "nym_address": { + "description": "The address of the service.", + "allOf": [ + { + "$ref": "#/definitions/NymAddress" + } + ] + }, + "service_type": { + "description": "The service type.", + "allOf": [ + { + "$ref": "#/definitions/ServiceType" + } + ] + } + }, + "additionalProperties": false + }, + "ServiceType": { + "description": "The type of services provider supported", + "type": "string", + "enum": [ + "network_requester" + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/service-provider-directory/schema/raw/response_to_by_nym_address.json b/contracts/service-provider-directory/schema/raw/response_to_by_nym_address.json new file mode 100644 index 0000000000..a0092cef6b --- /dev/null +++ b/contracts/service-provider-directory/schema/raw/response_to_by_nym_address.json @@ -0,0 +1,147 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ServicesListResponse", + "type": "object", + "required": [ + "services" + ], + "properties": { + "services": { + "type": "array", + "items": { + "$ref": "#/definitions/Service" + } + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "NymAddress": { + "description": "The types of addresses supported.", + "oneOf": [ + { + "description": "String representation of a nym address, which is of the form client_id.client_enc@gateway_id.", + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "Service": { + "type": "object", + "required": [ + "announcer", + "block_height", + "deposit", + "service", + "service_id" + ], + "properties": { + "announcer": { + "description": "Address of the service owner.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "block_height": { + "description": "Block height at which the service was added.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "deposit": { + "description": "The deposit used to announce the service.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "service": { + "description": "The announced service.", + "allOf": [ + { + "$ref": "#/definitions/ServiceDetails" + } + ] + }, + "service_id": { + "description": "Unique id assigned to the anounced service.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "ServiceDetails": { + "type": "object", + "required": [ + "identity_key", + "nym_address", + "service_type" + ], + "properties": { + "identity_key": { + "description": "The identity key of the service.", + "type": "string" + }, + "nym_address": { + "description": "The address of the service.", + "allOf": [ + { + "$ref": "#/definitions/NymAddress" + } + ] + }, + "service_type": { + "description": "The service type.", + "allOf": [ + { + "$ref": "#/definitions/ServiceType" + } + ] + } + }, + "additionalProperties": false + }, + "ServiceType": { + "description": "The type of services provider supported", + "type": "string", + "enum": [ + "network_requester" + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/service-provider-directory/schema/raw/response_to_config.json b/contracts/service-provider-directory/schema/raw/response_to_config.json new file mode 100644 index 0000000000..16420c1130 --- /dev/null +++ b/contracts/service-provider-directory/schema/raw/response_to_config.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ConfigResponse", + "type": "object", + "required": [ + "deposit_required" + ], + "properties": { + "deposit_required": { + "$ref": "#/definitions/Coin" + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/service-provider-directory/schema/raw/response_to_get_c_w2_contract_version.json b/contracts/service-provider-directory/schema/raw/response_to_get_c_w2_contract_version.json new file mode 100644 index 0000000000..3ded8c84d9 --- /dev/null +++ b/contracts/service-provider-directory/schema/raw/response_to_get_c_w2_contract_version.json @@ -0,0 +1,20 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ContractVersion", + "type": "object", + "required": [ + "contract", + "version" + ], + "properties": { + "contract": { + "description": "contract is the crate name of the implementing contract, eg. `crate:cw20-base` we will use other prefixes for other languages, and their standard global namespacing", + "type": "string" + }, + "version": { + "description": "version is any string that this implementation knows. It may be simple counter \"1\", \"2\". or semantic version on release tags \"v0.7.0\", or some custom feature flag list. the only code that needs to understand the version parsing is code that knows how to migrate from the given contract (and is tied to it's implementation somehow)", + "type": "string" + } + }, + "additionalProperties": false +} diff --git a/contracts/service-provider-directory/schema/raw/response_to_get_contract_version.json b/contracts/service-provider-directory/schema/raw/response_to_get_contract_version.json new file mode 100644 index 0000000000..60ae65f3d1 --- /dev/null +++ b/contracts/service-provider-directory/schema/raw/response_to_get_contract_version.json @@ -0,0 +1,40 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ContractBuildInformation", + "type": "object", + "required": [ + "build_timestamp", + "build_version", + "commit_branch", + "commit_sha", + "commit_timestamp", + "rustc_version" + ], + "properties": { + "build_timestamp": { + "description": "Provides the build timestamp, for example `2021-02-23T20:14:46.558472672+00:00`.", + "type": "string" + }, + "build_version": { + "description": "Provides the build version, for example `0.1.0-9-g46f83e1`.", + "type": "string" + }, + "commit_branch": { + "description": "Provides the name of the git branch that was used for the build, for example `master`.", + "type": "string" + }, + "commit_sha": { + "description": "Provides the hash of the commit that was used for the build, for example `46f83e112520533338245862d366f6a02cef07d4`.", + "type": "string" + }, + "commit_timestamp": { + "description": "Provides the timestamp of the commit that was used for the build, for example `2021-02-23T08:08:02-05:00`.", + "type": "string" + }, + "rustc_version": { + "description": "Provides the rustc version that was used for the build, for example `1.52.0-nightly`.", + "type": "string" + } + }, + "additionalProperties": false +} diff --git a/contracts/service-provider-directory/schema/raw/response_to_service_id.json b/contracts/service-provider-directory/schema/raw/response_to_service_id.json new file mode 100644 index 0000000000..68f5ff143b --- /dev/null +++ b/contracts/service-provider-directory/schema/raw/response_to_service_id.json @@ -0,0 +1,132 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Service", + "type": "object", + "required": [ + "announcer", + "block_height", + "deposit", + "service", + "service_id" + ], + "properties": { + "announcer": { + "description": "Address of the service owner.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "block_height": { + "description": "Block height at which the service was added.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "deposit": { + "description": "The deposit used to announce the service.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "service": { + "description": "The announced service.", + "allOf": [ + { + "$ref": "#/definitions/ServiceDetails" + } + ] + }, + "service_id": { + "description": "Unique id assigned to the anounced service.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "NymAddress": { + "description": "The types of addresses supported.", + "oneOf": [ + { + "description": "String representation of a nym address, which is of the form client_id.client_enc@gateway_id.", + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "ServiceDetails": { + "type": "object", + "required": [ + "identity_key", + "nym_address", + "service_type" + ], + "properties": { + "identity_key": { + "description": "The identity key of the service.", + "type": "string" + }, + "nym_address": { + "description": "The address of the service.", + "allOf": [ + { + "$ref": "#/definitions/NymAddress" + } + ] + }, + "service_type": { + "description": "The service type.", + "allOf": [ + { + "$ref": "#/definitions/ServiceType" + } + ] + } + }, + "additionalProperties": false + }, + "ServiceType": { + "description": "The type of services provider supported", + "type": "string", + "enum": [ + "network_requester" + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/service-provider-directory/schema/raw/response_to_signing_nonce.json b/contracts/service-provider-directory/schema/raw/response_to_signing_nonce.json new file mode 100644 index 0000000000..de85c3e56e --- /dev/null +++ b/contracts/service-provider-directory/schema/raw/response_to_signing_nonce.json @@ -0,0 +1,7 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "uint32", + "type": "integer", + "format": "uint32", + "minimum": 0.0 +} diff --git a/contracts/service-provider-directory/src/bin/schema.rs b/contracts/service-provider-directory/src/bin/schema.rs new file mode 100644 index 0000000000..0adf4b8827 --- /dev/null +++ b/contracts/service-provider-directory/src/bin/schema.rs @@ -0,0 +1,16 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use cosmwasm_schema::write_api; +use nym_service_provider_directory_common::msg::{ + ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg, +}; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + query: QueryMsg, + execute: ExecuteMsg, + migrate: MigrateMsg, + } +} diff --git a/contracts/service-provider-directory/src/state/services.rs b/contracts/service-provider-directory/src/state/services.rs index e5e68a21ff..d88ebf6722 100644 --- a/contracts/service-provider-directory/src/state/services.rs +++ b/contracts/service-provider-directory/src/state/services.rs @@ -88,6 +88,8 @@ pub fn load_nym_address(store: &dyn Storage, nym_address: NymAddress) -> Result< pub struct PagedLoad { pub services: Vec, pub limit: usize, + + /// Field indicating paging information for the following queries if the caller wishes to get further entries. pub start_next_after: Option, } diff --git a/contracts/vesting/.cargo/config b/contracts/vesting/.cargo/config new file mode 100644 index 0000000000..2c25b8a87e --- /dev/null +++ b/contracts/vesting/.cargo/config @@ -0,0 +1,4 @@ +[alias] +wasm = "build --release --target wasm32-unknown-unknown" +unit-test = "test --lib" +schema = "run --bin schema --features=schema-gen" \ No newline at end of file diff --git a/contracts/vesting/Cargo.toml b/contracts/vesting/Cargo.toml index 5f988b6431..5998e5d773 100644 --- a/contracts/vesting/Cargo.toml +++ b/contracts/vesting/Cargo.toml @@ -15,6 +15,10 @@ exclude = [ "artifacts", ] +[[bin]] +name = "schema" +required-features = ["schema-gen"] + [lib] name = "vesting_contract" crate-type = ["cdylib", "rlib"] @@ -24,12 +28,12 @@ mixnet-contract-common = { path = "../../common/cosmwasm-smart-contracts/mixnet- contracts-common = { path = "../../common/cosmwasm-smart-contracts/contracts-common", package = "nym-contracts-common", version = "0.5.0" } vesting-contract-common = { path = "../../common/cosmwasm-smart-contracts/vesting-contract", package = "nym-vesting-contract-common", version = "0.7.0" } +cosmwasm-schema = { workspace = true, optional = true } cosmwasm-std = { workspace = true } cosmwasm-derive = { workspace = true } cw2 = { workspace = true } cw-storage-plus = { workspace = true, features = ["iterator"] } -schemars = "0.8" serde = { version = "1.0", default-features = false, features = ["derive"] } thiserror = { version = "1.0" } semver = { version = "1.0.16", default-features = false } @@ -46,3 +50,6 @@ vergen = { version = "=7.4.3", default-features = false, features = ["build", "g [profile.release] overflow-checks = true + +[features] +schema-gen = ["vesting-contract-common/schema", "cosmwasm-schema"] \ No newline at end of file diff --git a/contracts/vesting/Makefile b/contracts/vesting/Makefile index a00097bc65..8ca651ccec 100644 --- a/contracts/vesting/Makefile +++ b/contracts/vesting/Makefile @@ -1,2 +1,5 @@ wasm: - RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown \ No newline at end of file + RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown + +generate-schema: + cargo schema \ No newline at end of file diff --git a/contracts/vesting/schema/nym-vesting-contract.json b/contracts/vesting/schema/nym-vesting-contract.json new file mode 100644 index 0000000000..87967fb410 --- /dev/null +++ b/contracts/vesting/schema/nym-vesting-contract.json @@ -0,0 +1,2841 @@ +{ + "contract_name": "nym-vesting-contract", + "contract_version": "1.4.0", + "idl_version": "1.0.0", + "instantiate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "mix_denom", + "mixnet_contract_address" + ], + "properties": { + "mix_denom": { + "type": "string" + }, + "mixnet_contract_address": { + "type": "string" + } + }, + "additionalProperties": false + }, + "execute": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Only owner of the node can crate the family with node as head", + "type": "object", + "required": [ + "create_family" + ], + "properties": { + "create_family": { + "type": "object", + "required": [ + "label" + ], + "properties": { + "label": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Family head needs to sign the joining node IdentityKey, the Node provides its signature signaling consent to join the family", + "type": "object", + "required": [ + "join_family" + ], + "properties": { + "join_family": { + "type": "object", + "required": [ + "family_head", + "join_permit" + ], + "properties": { + "family_head": { + "$ref": "#/definitions/FamilyHead" + }, + "join_permit": { + "$ref": "#/definitions/MessageSignature" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "leave_family" + ], + "properties": { + "leave_family": { + "type": "object", + "required": [ + "family_head" + ], + "properties": { + "family_head": { + "$ref": "#/definitions/FamilyHead" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "kick_family_member" + ], + "properties": { + "kick_family_member": { + "type": "object", + "required": [ + "member" + ], + "properties": { + "member": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "track_reward" + ], + "properties": { + "track_reward": { + "type": "object", + "required": [ + "address", + "amount" + ], + "properties": { + "address": { + "type": "string" + }, + "amount": { + "$ref": "#/definitions/Coin" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "claim_operator_reward" + ], + "properties": { + "claim_operator_reward": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "claim_delegator_reward" + ], + "properties": { + "claim_delegator_reward": { + "type": "object", + "required": [ + "mix_id" + ], + "properties": { + "mix_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_mixnode_cost_params" + ], + "properties": { + "update_mixnode_cost_params": { + "type": "object", + "required": [ + "new_costs" + ], + "properties": { + "new_costs": { + "$ref": "#/definitions/MixNodeCostParams" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_mixnode_config" + ], + "properties": { + "update_mixnode_config": { + "type": "object", + "required": [ + "new_config" + ], + "properties": { + "new_config": { + "$ref": "#/definitions/MixNodeConfigUpdate" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_mixnet_address" + ], + "properties": { + "update_mixnet_address": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "delegate_to_mixnode" + ], + "properties": { + "delegate_to_mixnode": { + "type": "object", + "required": [ + "amount", + "mix_id" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "mix_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "on_behalf_of": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "undelegate_from_mixnode" + ], + "properties": { + "undelegate_from_mixnode": { + "type": "object", + "required": [ + "mix_id" + ], + "properties": { + "mix_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "on_behalf_of": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "create_account" + ], + "properties": { + "create_account": { + "type": "object", + "required": [ + "owner_address" + ], + "properties": { + "cap": { + "anyOf": [ + { + "$ref": "#/definitions/PledgeCap" + }, + { + "type": "null" + } + ] + }, + "owner_address": { + "type": "string" + }, + "staking_address": { + "type": [ + "string", + "null" + ] + }, + "vesting_spec": { + "anyOf": [ + { + "$ref": "#/definitions/VestingSpecification" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "withdraw_vested_coins" + ], + "properties": { + "withdraw_vested_coins": { + "type": "object", + "required": [ + "amount" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "track_undelegation" + ], + "properties": { + "track_undelegation": { + "type": "object", + "required": [ + "amount", + "mix_id", + "owner" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "mix_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "bond_mixnode" + ], + "properties": { + "bond_mixnode": { + "type": "object", + "required": [ + "amount", + "cost_params", + "mix_node", + "owner_signature" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "cost_params": { + "$ref": "#/definitions/MixNodeCostParams" + }, + "mix_node": { + "$ref": "#/definitions/MixNode" + }, + "owner_signature": { + "$ref": "#/definitions/MessageSignature" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "pledge_more" + ], + "properties": { + "pledge_more": { + "type": "object", + "required": [ + "amount" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "decrease_pledge" + ], + "properties": { + "decrease_pledge": { + "type": "object", + "required": [ + "amount" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "unbond_mixnode" + ], + "properties": { + "unbond_mixnode": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "track_unbond_mixnode" + ], + "properties": { + "track_unbond_mixnode": { + "type": "object", + "required": [ + "amount", + "owner" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "track_decrease_pledge" + ], + "properties": { + "track_decrease_pledge": { + "type": "object", + "required": [ + "amount", + "owner" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "bond_gateway" + ], + "properties": { + "bond_gateway": { + "type": "object", + "required": [ + "amount", + "gateway", + "owner_signature" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "gateway": { + "$ref": "#/definitions/Gateway" + }, + "owner_signature": { + "$ref": "#/definitions/MessageSignature" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "unbond_gateway" + ], + "properties": { + "unbond_gateway": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "track_unbond_gateway" + ], + "properties": { + "track_unbond_gateway": { + "type": "object", + "required": [ + "amount", + "owner" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_gateway_config" + ], + "properties": { + "update_gateway_config": { + "type": "object", + "required": [ + "new_config" + ], + "properties": { + "new_config": { + "$ref": "#/definitions/GatewayConfigUpdate" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "transfer_ownership" + ], + "properties": { + "transfer_ownership": { + "type": "object", + "required": [ + "to_address" + ], + "properties": { + "to_address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_staking_address" + ], + "properties": { + "update_staking_address": { + "type": "object", + "properties": { + "to_address": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_locked_pledge_cap" + ], + "properties": { + "update_locked_pledge_cap": { + "type": "object", + "required": [ + "address", + "cap" + ], + "properties": { + "address": { + "type": "string" + }, + "cap": { + "$ref": "#/definitions/PledgeCap" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "FamilyHead": { + "description": "Head of particular family as identified by its identity key (i.e. public component of its ed25519 keypair stringified into base58).", + "type": "string" + }, + "Gateway": { + "description": "Information provided by the node operator during bonding that are used to allow other entities to use the services of this node.", + "type": "object", + "required": [ + "clients_port", + "host", + "identity_key", + "location", + "mix_port", + "sphinx_key", + "version" + ], + "properties": { + "clients_port": { + "description": "Port used by this gateway for listening for client requests.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "host": { + "description": "Network address of this gateway, for example 1.1.1.1 or foo.gateway.com", + "type": "string" + }, + "identity_key": { + "description": "Base58 encoded ed25519 EdDSA public key of the gateway used to derive shared keys with clients", + "type": "string" + }, + "location": { + "description": "The physical, self-reported, location of this gateway.", + "type": "string" + }, + "mix_port": { + "description": "Port used by this gateway for listening for mix packets.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "sphinx_key": { + "description": "Base58-encoded x25519 public key used for sphinx key derivation.", + "type": "string" + }, + "version": { + "description": "The self-reported semver version of this gateway.", + "type": "string" + } + }, + "additionalProperties": false + }, + "GatewayConfigUpdate": { + "type": "object", + "required": [ + "clients_port", + "host", + "location", + "mix_port", + "version" + ], + "properties": { + "clients_port": { + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "host": { + "type": "string" + }, + "location": { + "type": "string" + }, + "mix_port": { + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "version": { + "type": "string" + } + }, + "additionalProperties": false + }, + "MessageSignature": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + }, + "MixNode": { + "description": "Information provided by the node operator during bonding that are used to allow other entities to use the services of this node.", + "type": "object", + "required": [ + "host", + "http_api_port", + "identity_key", + "mix_port", + "sphinx_key", + "verloc_port", + "version" + ], + "properties": { + "host": { + "description": "Network address of this mixnode, for example 1.1.1.1 or foo.mixnode.com", + "type": "string" + }, + "http_api_port": { + "description": "Port used by this mixnode for its http(s) API", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "identity_key": { + "description": "Base58-encoded ed25519 EdDSA public key.", + "type": "string" + }, + "mix_port": { + "description": "Port used by this mixnode for listening for mix packets.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "sphinx_key": { + "description": "Base58-encoded x25519 public key used for sphinx key derivation.", + "type": "string" + }, + "verloc_port": { + "description": "Port used by this mixnode for listening for verloc requests.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "version": { + "description": "The self-reported semver version of this mixnode.", + "type": "string" + } + }, + "additionalProperties": false + }, + "MixNodeConfigUpdate": { + "type": "object", + "required": [ + "host", + "http_api_port", + "mix_port", + "verloc_port", + "version" + ], + "properties": { + "host": { + "type": "string" + }, + "http_api_port": { + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "mix_port": { + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "verloc_port": { + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "version": { + "type": "string" + } + }, + "additionalProperties": false + }, + "MixNodeCostParams": { + "description": "The cost parameters, or the cost function, defined for the particular mixnode that influences how the rewards should be split between the node operator and its delegators.", + "type": "object", + "required": [ + "interval_operating_cost", + "profit_margin_percent" + ], + "properties": { + "interval_operating_cost": { + "description": "Operating cost of the associated mixnode per the entire interval.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "profit_margin_percent": { + "description": "The profit margin of the associated mixnode, i.e. the desired percent of the reward to be distributed to the operator.", + "allOf": [ + { + "$ref": "#/definitions/Percent" + } + ] + } + }, + "additionalProperties": false + }, + "Percent": { + "description": "Percent represents a value between 0 and 100% (i.e. between 0.0 and 1.0)", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "PledgeCap": { + "description": "Defines cap for pleding/staking tokens.", + "oneOf": [ + { + "description": "Specifies a percent-based pledge cap, i.e. only given % of tokens could be pledged/staked.", + "type": "object", + "required": [ + "percent" + ], + "properties": { + "percent": { + "$ref": "#/definitions/Percent" + } + }, + "additionalProperties": false + }, + { + "description": "Specifies an absolute pledge cap, i.e. an explicit value that could be pledged/staked.", + "type": "object", + "required": [ + "absolute" + ], + "properties": { + "absolute": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "VestingSpecification": { + "type": "object", + "properties": { + "num_periods": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + }, + "period_seconds": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + }, + "start_time": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } + }, + "query": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "description": "Queries exposed by this contract.", + "oneOf": [ + { + "description": "Gets build information of this contract, such as the commit hash used for the build or rustc version.", + "type": "object", + "required": [ + "get_contract_version" + ], + "properties": { + "get_contract_version": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the stored contract version information that's required by the CW2 spec interface for migrations.", + "type": "object", + "required": [ + "get_cw2_contract_version" + ], + "properties": { + "get_cw2_contract_version": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the list of vesting accounts held in this contract.", + "type": "object", + "required": [ + "get_accounts_paged" + ], + "properties": { + "get_accounts_paged": { + "type": "object", + "properties": { + "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the list of coins that are still vesting for each account held in this contract.", + "type": "object", + "required": [ + "get_accounts_vesting_coins_paged" + ], + "properties": { + "get_accounts_vesting_coins_paged": { + "type": "object", + "properties": { + "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the amount of locked coins for the provided vesting account, i.e. coins that are still vesting but have not been staked. `locked_coins = vesting_coins - staked_coins`", + "type": "object", + "required": [ + "locked_coins" + ], + "properties": { + "locked_coins": { + "type": "object", + "required": [ + "vesting_account_address" + ], + "properties": { + "block_time": { + "description": "(deprecated) Optional argument specifying that the query should be performed against non-current block.", + "anyOf": [ + { + "$ref": "#/definitions/Timestamp" + }, + { + "type": "null" + } + ] + }, + "vesting_account_address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the amount of spendable coins for the provided vesting account, i.e. coins that could be withdrawn. `spendable_coins = account_balance - locked_coins` note: `account_balance` is the amount of coins still physically present in this contract, i.e. not withdrawn or staked.", + "type": "object", + "required": [ + "spendable_coins" + ], + "properties": { + "spendable_coins": { + "type": "object", + "required": [ + "vesting_account_address" + ], + "properties": { + "block_time": { + "description": "(deprecated) Optional argument specifying that the query should be performed against non-current block.", + "anyOf": [ + { + "$ref": "#/definitions/Timestamp" + }, + { + "type": "null" + } + ] + }, + "vesting_account_address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the amount of coins that have already vested for the provided vesting account address.", + "type": "object", + "required": [ + "get_vested_coins" + ], + "properties": { + "get_vested_coins": { + "type": "object", + "required": [ + "vesting_account_address" + ], + "properties": { + "block_time": { + "description": "(deprecated) Optional argument specifying that the query should be performed against non-current block.", + "anyOf": [ + { + "$ref": "#/definitions/Timestamp" + }, + { + "type": "null" + } + ] + }, + "vesting_account_address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the amount of coins that are still vesting for the provided vesting account address.", + "type": "object", + "required": [ + "get_vesting_coins" + ], + "properties": { + "get_vesting_coins": { + "type": "object", + "required": [ + "vesting_account_address" + ], + "properties": { + "block_time": { + "description": "(deprecated) Optional argument specifying that the query should be performed against non-current block.", + "anyOf": [ + { + "$ref": "#/definitions/Timestamp" + }, + { + "type": "null" + } + ] + }, + "vesting_account_address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the starting vesting time for the provided vesting account, i.e. the beginning of the first vesting period.", + "type": "object", + "required": [ + "get_start_time" + ], + "properties": { + "get_start_time": { + "type": "object", + "required": [ + "vesting_account_address" + ], + "properties": { + "vesting_account_address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the ending vesting time for the provided vesting account, i.e. the end of the last vesting period.", + "type": "object", + "required": [ + "get_end_time" + ], + "properties": { + "get_end_time": { + "type": "object", + "required": [ + "vesting_account_address" + ], + "properties": { + "vesting_account_address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the initial vesting specification used for the provided vesting account address.", + "type": "object", + "required": [ + "get_original_vesting" + ], + "properties": { + "get_original_vesting": { + "type": "object", + "required": [ + "vesting_account_address" + ], + "properties": { + "vesting_account_address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the total amount of coins accrued through claimed staking rewards by the provided vesting account.", + "type": "object", + "required": [ + "get_historical_vesting_staking_reward" + ], + "properties": { + "get_historical_vesting_staking_reward": { + "type": "object", + "required": [ + "vesting_account_address" + ], + "properties": { + "vesting_account_address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the amount of spendable vesting coins for the provided vesting account, i.e. coins that could be withdrawn that originated from the vesting specification.", + "type": "object", + "required": [ + "get_spendable_vested_coins" + ], + "properties": { + "get_spendable_vested_coins": { + "type": "object", + "required": [ + "vesting_account_address" + ], + "properties": { + "vesting_account_address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the amount of spendable reward coins for the provided vesting account, i.e. coins that could be withdrawn that originated from the claimed staking rewards.", + "type": "object", + "required": [ + "get_spendable_reward_coins" + ], + "properties": { + "get_spendable_reward_coins": { + "type": "object", + "required": [ + "vesting_account_address" + ], + "properties": { + "vesting_account_address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the amount of coins that are currently delegated for the provided vesting account address.", + "type": "object", + "required": [ + "get_delegated_coins" + ], + "properties": { + "get_delegated_coins": { + "type": "object", + "required": [ + "vesting_account_address" + ], + "properties": { + "vesting_account_address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the amount of coins that are currently pledged for the provided vesting account address.", + "type": "object", + "required": [ + "get_pledged_coins" + ], + "properties": { + "get_pledged_coins": { + "type": "object", + "required": [ + "vesting_account_address" + ], + "properties": { + "vesting_account_address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the amount of coins that are currently staked (i.e. delegations + pledges) for the provided vesting account address.", + "type": "object", + "required": [ + "get_staked_coins" + ], + "properties": { + "get_staked_coins": { + "type": "object", + "required": [ + "vesting_account_address" + ], + "properties": { + "vesting_account_address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the amount of coins that got withdrawn for the provided vesting account address.", + "type": "object", + "required": [ + "get_withdrawn_coins" + ], + "properties": { + "get_withdrawn_coins": { + "type": "object", + "required": [ + "vesting_account_address" + ], + "properties": { + "vesting_account_address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns detailed information associated with the account for the provided vesting account address.", + "type": "object", + "required": [ + "get_account" + ], + "properties": { + "get_account": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns pledge information (if applicable) for bonded mixnode for the provided vesting account address.", + "type": "object", + "required": [ + "get_mixnode" + ], + "properties": { + "get_mixnode": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns pledge information (if applicable) for bonded gateway for the provided vesting account address.", + "type": "object", + "required": [ + "get_gateway" + ], + "properties": { + "get_gateway": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the current vesting period for the provided vesting account address.", + "type": "object", + "required": [ + "get_current_vesting_period" + ], + "properties": { + "get_current_vesting_period": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the information about particular vesting delegation.", + "type": "object", + "required": [ + "get_delegation" + ], + "properties": { + "get_delegation": { + "type": "object", + "required": [ + "address", + "block_timestamp_secs", + "mix_id" + ], + "properties": { + "address": { + "description": "Address of the vesting account in question.", + "type": "string" + }, + "block_timestamp_secs": { + "description": "Block timestamp of the delegation.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "mix_id": { + "description": "Id of the mixnode towards which the delegation has been made.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the total amount of coins delegated towards particular mixnode by the provided vesting account address.", + "type": "object", + "required": [ + "get_total_delegation_amount" + ], + "properties": { + "get_total_delegation_amount": { + "type": "object", + "required": [ + "address", + "mix_id" + ], + "properties": { + "address": { + "description": "Address of the vesting account in question.", + "type": "string" + }, + "mix_id": { + "description": "Id of the mixnode towards which the delegations have been made.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns timestamps of delegations made towards particular mixnode by the provided vesting account address.", + "type": "object", + "required": [ + "get_delegation_times" + ], + "properties": { + "get_delegation_times": { + "type": "object", + "required": [ + "address", + "mix_id" + ], + "properties": { + "address": { + "description": "Address of the vesting account in question.", + "type": "string" + }, + "mix_id": { + "description": "Id of the mixnode towards which the delegations have been made.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns all active delegations made with vesting tokens stored in this contract.", + "type": "object", + "required": [ + "get_all_delegations" + ], + "properties": { + "get_all_delegations": { + "type": "object", + "properties": { + "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + ], + "maxItems": 3, + "minItems": 3 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + } + } + }, + "migrate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "type": "object", + "additionalProperties": false + }, + "sudo": null, + "responses": { + "get_account": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Account", + "description": "Vesting account information.", + "type": "object", + "required": [ + "coin", + "owner_address", + "periods", + "start_time", + "storage_key" + ], + "properties": { + "coin": { + "description": "The initial amount of coins used creation of this account.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "owner_address": { + "description": "Address of the owner of the vesting account.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "periods": { + "description": "All vesting periods for this account.", + "type": "array", + "items": { + "$ref": "#/definitions/VestingPeriod" + } + }, + "pledge_cap": { + "description": "Optional custom pledge cap of this vesting account.", + "default": null, + "anyOf": [ + { + "$ref": "#/definitions/PledgeCap" + }, + { + "type": "null" + } + ] + }, + "staking_address": { + "description": "Optional address of an account allowed to perform staking on behalf of the owner.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + }, + "start_time": { + "description": "The starting vesting time.", + "allOf": [ + { + "$ref": "#/definitions/Timestamp" + } + ] + }, + "storage_key": { + "description": "The id/storage_key of this vesting account.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Percent": { + "description": "Percent represents a value between 0 and 100% (i.e. between 0.0 and 1.0)", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "PledgeCap": { + "description": "Defines cap for pleding/staking tokens.", + "oneOf": [ + { + "description": "Specifies a percent-based pledge cap, i.e. only given % of tokens could be pledged/staked.", + "type": "object", + "required": [ + "percent" + ], + "properties": { + "percent": { + "$ref": "#/definitions/Percent" + } + }, + "additionalProperties": false + }, + { + "description": "Specifies an absolute pledge cap, i.e. an explicit value that could be pledged/staked.", + "type": "object", + "required": [ + "absolute" + ], + "properties": { + "absolute": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + } + ] + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + }, + "VestingPeriod": { + "description": "Vesting period details.", + "type": "object", + "required": [ + "period_seconds", + "start_time" + ], + "properties": { + "period_seconds": { + "description": "The duration (in seconds) of the vesting period.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "start_time": { + "description": "The start time of this vesting period, as unix timestamp.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } + }, + "get_accounts_paged": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AccountsResponse", + "description": "Response containing basic vesting account information", + "type": "object", + "required": [ + "accounts" + ], + "properties": { + "accounts": { + "description": "The actual accounts returned by the query.", + "type": "array", + "items": { + "$ref": "#/definitions/BaseVestingAccountInfo" + } + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "BaseVestingAccountInfo": { + "description": "Basic information regarding particular vesting account", + "type": "object", + "required": [ + "account_id", + "owner" + ], + "properties": { + "account_id": { + "description": "Id associated with this account", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "description": "Address of this account's owner", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + }, + "additionalProperties": false + } + } + }, + "get_accounts_vesting_coins_paged": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "VestingCoinsResponse", + "description": "Response containing vesting coins held in this contract", + "type": "object", + "required": [ + "accounts" + ], + "properties": { + "accounts": { + "description": "The actual accounts, and their vesting coins, returned by the query.", + "type": "array", + "items": { + "$ref": "#/definitions/AccountVestingCoins" + } + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "AccountVestingCoins": { + "description": "Basic information regarding particular vesting account alongside the amount of vesting coins.", + "type": "object", + "required": [ + "account_id", + "owner", + "still_vesting" + ], + "properties": { + "account_id": { + "description": "Id associated with this account", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "description": "Address of this account's owner", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "still_vesting": { + "description": "Coins that are still vesting belonging to this account.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + } + }, + "additionalProperties": false + }, + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_all_delegations": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AllDelegationsResponse", + "description": "Response containing paged list of all vesting delegations made using vesting coins.", + "type": "object", + "required": [ + "delegations" + ], + "properties": { + "delegations": { + "description": "The actual vesting delegations made.", + "type": "array", + "items": { + "$ref": "#/definitions/VestingDelegation" + } + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + ], + "maxItems": 3, + "minItems": 3 + } + }, + "additionalProperties": false, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "VestingDelegation": { + "description": "Details about particular vesting delegation.", + "type": "object", + "required": [ + "account_id", + "amount", + "block_timestamp", + "mix_id" + ], + "properties": { + "account_id": { + "description": "The id of the vesting account that has made the delegation.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "amount": { + "description": "The raw amount delegated (interpreted to be in the same denom as the underlying vesting specification)", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "block_timestamp": { + "description": "The block timestamp when the delegation has been made.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "mix_id": { + "description": "The id of the mixnode towards which the delegation has been made.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } + }, + "get_c_w2_contract_version": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ContractVersion", + "type": "object", + "required": [ + "contract", + "version" + ], + "properties": { + "contract": { + "description": "contract is the crate name of the implementing contract, eg. `crate:cw20-base` we will use other prefixes for other languages, and their standard global namespacing", + "type": "string" + }, + "version": { + "description": "version is any string that this implementation knows. It may be simple counter \"1\", \"2\". or semantic version on release tags \"v0.7.0\", or some custom feature flag list. the only code that needs to understand the version parsing is code that knows how to migrate from the given contract (and is tied to it's implementation somehow)", + "type": "string" + } + }, + "additionalProperties": false + }, + "get_contract_version": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ContractBuildInformation", + "type": "object", + "required": [ + "build_timestamp", + "build_version", + "commit_branch", + "commit_sha", + "commit_timestamp", + "rustc_version" + ], + "properties": { + "build_timestamp": { + "description": "Provides the build timestamp, for example `2021-02-23T20:14:46.558472672+00:00`.", + "type": "string" + }, + "build_version": { + "description": "Provides the build version, for example `0.1.0-9-g46f83e1`.", + "type": "string" + }, + "commit_branch": { + "description": "Provides the name of the git branch that was used for the build, for example `master`.", + "type": "string" + }, + "commit_sha": { + "description": "Provides the hash of the commit that was used for the build, for example `46f83e112520533338245862d366f6a02cef07d4`.", + "type": "string" + }, + "commit_timestamp": { + "description": "Provides the timestamp of the commit that was used for the build, for example `2021-02-23T08:08:02-05:00`.", + "type": "string" + }, + "rustc_version": { + "description": "Provides the rustc version that was used for the build, for example `1.52.0-nightly`.", + "type": "string" + } + }, + "additionalProperties": false + }, + "get_current_vesting_period": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Period", + "description": "The vesting period.", + "oneOf": [ + { + "description": "Defines a pre-vesting period.", + "type": "string", + "enum": [ + "before" + ] + }, + { + "description": "Defines currently active vesting period.", + "type": "object", + "required": [ + "in" + ], + "properties": { + "in": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "Defines a post-vesting period.", + "type": "string", + "enum": [ + "after" + ] + } + ] + }, + "get_delegated_coins": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Coin", + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_delegation": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "VestingDelegation", + "description": "Details about particular vesting delegation.", + "type": "object", + "required": [ + "account_id", + "amount", + "block_timestamp", + "mix_id" + ], + "properties": { + "account_id": { + "description": "The id of the vesting account that has made the delegation.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "amount": { + "description": "The raw amount delegated (interpreted to be in the same denom as the underlying vesting specification)", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "block_timestamp": { + "description": "The block timestamp when the delegation has been made.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "mix_id": { + "description": "The id of the mixnode towards which the delegation has been made.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_delegation_times": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "DelegationTimesResponse", + "description": "Response containing timestamps of all delegations made towards particular mixnode by given vesting account.", + "type": "object", + "required": [ + "account_id", + "delegation_timestamps", + "mix_id", + "owner" + ], + "properties": { + "account_id": { + "description": "Id associated with this account", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "delegation_timestamps": { + "description": "All timestamps where a delegation was made", + "type": "array", + "items": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "mix_id": { + "description": "Id of the mixnode towards which the delegation was made", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "description": "Address of this account's owner", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + } + } + }, + "get_end_time": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Timestamp", + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ], + "definitions": { + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + } + } + }, + "get_gateway": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Nullable_PledgeData", + "anyOf": [ + { + "$ref": "#/definitions/PledgeData" + }, + { + "type": "null" + } + ], + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "PledgeData": { + "description": "Information regarding pledge (i.e. mixnode or gateway bonding) made with vesting tokens.", + "type": "object", + "required": [ + "amount", + "block_time" + ], + "properties": { + "amount": { + "description": "The amount pledged.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "block_time": { + "description": "The block timestamp where the pledge occurred.", + "allOf": [ + { + "$ref": "#/definitions/Timestamp" + } + ] + } + }, + "additionalProperties": false + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + } + } + }, + "get_historical_vesting_staking_reward": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Coin", + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_mixnode": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Nullable_PledgeData", + "anyOf": [ + { + "$ref": "#/definitions/PledgeData" + }, + { + "type": "null" + } + ], + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "PledgeData": { + "description": "Information regarding pledge (i.e. mixnode or gateway bonding) made with vesting tokens.", + "type": "object", + "required": [ + "amount", + "block_time" + ], + "properties": { + "amount": { + "description": "The amount pledged.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "block_time": { + "description": "The block timestamp where the pledge occurred.", + "allOf": [ + { + "$ref": "#/definitions/Timestamp" + } + ] + } + }, + "additionalProperties": false + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + } + } + }, + "get_original_vesting": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "OriginalVestingResponse", + "description": "Details about the original vesting specification used when the account was created.", + "type": "object", + "required": [ + "amount", + "number_of_periods", + "period_duration" + ], + "properties": { + "amount": { + "description": "The original amount that was used for the creation of this vesting account", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "number_of_periods": { + "description": "The number of vesting periods that the account was created with", + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "period_duration": { + "description": "Duration of each vesting period in seconds", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_pledged_coins": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Coin", + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_spendable_reward_coins": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Coin", + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_spendable_vested_coins": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Coin", + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_staked_coins": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Coin", + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_start_time": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Timestamp", + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ], + "definitions": { + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + } + } + }, + "get_total_delegation_amount": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Coin", + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_vested_coins": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Coin", + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_vesting_coins": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Coin", + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_withdrawn_coins": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Coin", + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "locked_coins": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Coin", + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "spendable_coins": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Coin", + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + } + } +} diff --git a/contracts/vesting/schema/raw/execute.json b/contracts/vesting/schema/raw/execute.json new file mode 100644 index 0000000000..be6d6a73ff --- /dev/null +++ b/contracts/vesting/schema/raw/execute.json @@ -0,0 +1,971 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Only owner of the node can crate the family with node as head", + "type": "object", + "required": [ + "create_family" + ], + "properties": { + "create_family": { + "type": "object", + "required": [ + "label" + ], + "properties": { + "label": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Family head needs to sign the joining node IdentityKey, the Node provides its signature signaling consent to join the family", + "type": "object", + "required": [ + "join_family" + ], + "properties": { + "join_family": { + "type": "object", + "required": [ + "family_head", + "join_permit" + ], + "properties": { + "family_head": { + "$ref": "#/definitions/FamilyHead" + }, + "join_permit": { + "$ref": "#/definitions/MessageSignature" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "leave_family" + ], + "properties": { + "leave_family": { + "type": "object", + "required": [ + "family_head" + ], + "properties": { + "family_head": { + "$ref": "#/definitions/FamilyHead" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "kick_family_member" + ], + "properties": { + "kick_family_member": { + "type": "object", + "required": [ + "member" + ], + "properties": { + "member": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "track_reward" + ], + "properties": { + "track_reward": { + "type": "object", + "required": [ + "address", + "amount" + ], + "properties": { + "address": { + "type": "string" + }, + "amount": { + "$ref": "#/definitions/Coin" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "claim_operator_reward" + ], + "properties": { + "claim_operator_reward": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "claim_delegator_reward" + ], + "properties": { + "claim_delegator_reward": { + "type": "object", + "required": [ + "mix_id" + ], + "properties": { + "mix_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_mixnode_cost_params" + ], + "properties": { + "update_mixnode_cost_params": { + "type": "object", + "required": [ + "new_costs" + ], + "properties": { + "new_costs": { + "$ref": "#/definitions/MixNodeCostParams" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_mixnode_config" + ], + "properties": { + "update_mixnode_config": { + "type": "object", + "required": [ + "new_config" + ], + "properties": { + "new_config": { + "$ref": "#/definitions/MixNodeConfigUpdate" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_mixnet_address" + ], + "properties": { + "update_mixnet_address": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "delegate_to_mixnode" + ], + "properties": { + "delegate_to_mixnode": { + "type": "object", + "required": [ + "amount", + "mix_id" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "mix_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "on_behalf_of": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "undelegate_from_mixnode" + ], + "properties": { + "undelegate_from_mixnode": { + "type": "object", + "required": [ + "mix_id" + ], + "properties": { + "mix_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "on_behalf_of": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "create_account" + ], + "properties": { + "create_account": { + "type": "object", + "required": [ + "owner_address" + ], + "properties": { + "cap": { + "anyOf": [ + { + "$ref": "#/definitions/PledgeCap" + }, + { + "type": "null" + } + ] + }, + "owner_address": { + "type": "string" + }, + "staking_address": { + "type": [ + "string", + "null" + ] + }, + "vesting_spec": { + "anyOf": [ + { + "$ref": "#/definitions/VestingSpecification" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "withdraw_vested_coins" + ], + "properties": { + "withdraw_vested_coins": { + "type": "object", + "required": [ + "amount" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "track_undelegation" + ], + "properties": { + "track_undelegation": { + "type": "object", + "required": [ + "amount", + "mix_id", + "owner" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "mix_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "bond_mixnode" + ], + "properties": { + "bond_mixnode": { + "type": "object", + "required": [ + "amount", + "cost_params", + "mix_node", + "owner_signature" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "cost_params": { + "$ref": "#/definitions/MixNodeCostParams" + }, + "mix_node": { + "$ref": "#/definitions/MixNode" + }, + "owner_signature": { + "$ref": "#/definitions/MessageSignature" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "pledge_more" + ], + "properties": { + "pledge_more": { + "type": "object", + "required": [ + "amount" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "decrease_pledge" + ], + "properties": { + "decrease_pledge": { + "type": "object", + "required": [ + "amount" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "unbond_mixnode" + ], + "properties": { + "unbond_mixnode": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "track_unbond_mixnode" + ], + "properties": { + "track_unbond_mixnode": { + "type": "object", + "required": [ + "amount", + "owner" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "track_decrease_pledge" + ], + "properties": { + "track_decrease_pledge": { + "type": "object", + "required": [ + "amount", + "owner" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "bond_gateway" + ], + "properties": { + "bond_gateway": { + "type": "object", + "required": [ + "amount", + "gateway", + "owner_signature" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "gateway": { + "$ref": "#/definitions/Gateway" + }, + "owner_signature": { + "$ref": "#/definitions/MessageSignature" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "unbond_gateway" + ], + "properties": { + "unbond_gateway": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "track_unbond_gateway" + ], + "properties": { + "track_unbond_gateway": { + "type": "object", + "required": [ + "amount", + "owner" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_gateway_config" + ], + "properties": { + "update_gateway_config": { + "type": "object", + "required": [ + "new_config" + ], + "properties": { + "new_config": { + "$ref": "#/definitions/GatewayConfigUpdate" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "transfer_ownership" + ], + "properties": { + "transfer_ownership": { + "type": "object", + "required": [ + "to_address" + ], + "properties": { + "to_address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_staking_address" + ], + "properties": { + "update_staking_address": { + "type": "object", + "properties": { + "to_address": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_locked_pledge_cap" + ], + "properties": { + "update_locked_pledge_cap": { + "type": "object", + "required": [ + "address", + "cap" + ], + "properties": { + "address": { + "type": "string" + }, + "cap": { + "$ref": "#/definitions/PledgeCap" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "FamilyHead": { + "description": "Head of particular family as identified by its identity key (i.e. public component of its ed25519 keypair stringified into base58).", + "type": "string" + }, + "Gateway": { + "description": "Information provided by the node operator during bonding that are used to allow other entities to use the services of this node.", + "type": "object", + "required": [ + "clients_port", + "host", + "identity_key", + "location", + "mix_port", + "sphinx_key", + "version" + ], + "properties": { + "clients_port": { + "description": "Port used by this gateway for listening for client requests.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "host": { + "description": "Network address of this gateway, for example 1.1.1.1 or foo.gateway.com", + "type": "string" + }, + "identity_key": { + "description": "Base58 encoded ed25519 EdDSA public key of the gateway used to derive shared keys with clients", + "type": "string" + }, + "location": { + "description": "The physical, self-reported, location of this gateway.", + "type": "string" + }, + "mix_port": { + "description": "Port used by this gateway for listening for mix packets.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "sphinx_key": { + "description": "Base58-encoded x25519 public key used for sphinx key derivation.", + "type": "string" + }, + "version": { + "description": "The self-reported semver version of this gateway.", + "type": "string" + } + }, + "additionalProperties": false + }, + "GatewayConfigUpdate": { + "type": "object", + "required": [ + "clients_port", + "host", + "location", + "mix_port", + "version" + ], + "properties": { + "clients_port": { + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "host": { + "type": "string" + }, + "location": { + "type": "string" + }, + "mix_port": { + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "version": { + "type": "string" + } + }, + "additionalProperties": false + }, + "MessageSignature": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + }, + "MixNode": { + "description": "Information provided by the node operator during bonding that are used to allow other entities to use the services of this node.", + "type": "object", + "required": [ + "host", + "http_api_port", + "identity_key", + "mix_port", + "sphinx_key", + "verloc_port", + "version" + ], + "properties": { + "host": { + "description": "Network address of this mixnode, for example 1.1.1.1 or foo.mixnode.com", + "type": "string" + }, + "http_api_port": { + "description": "Port used by this mixnode for its http(s) API", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "identity_key": { + "description": "Base58-encoded ed25519 EdDSA public key.", + "type": "string" + }, + "mix_port": { + "description": "Port used by this mixnode for listening for mix packets.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "sphinx_key": { + "description": "Base58-encoded x25519 public key used for sphinx key derivation.", + "type": "string" + }, + "verloc_port": { + "description": "Port used by this mixnode for listening for verloc requests.", + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "version": { + "description": "The self-reported semver version of this mixnode.", + "type": "string" + } + }, + "additionalProperties": false + }, + "MixNodeConfigUpdate": { + "type": "object", + "required": [ + "host", + "http_api_port", + "mix_port", + "verloc_port", + "version" + ], + "properties": { + "host": { + "type": "string" + }, + "http_api_port": { + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "mix_port": { + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "verloc_port": { + "type": "integer", + "format": "uint16", + "minimum": 0.0 + }, + "version": { + "type": "string" + } + }, + "additionalProperties": false + }, + "MixNodeCostParams": { + "description": "The cost parameters, or the cost function, defined for the particular mixnode that influences how the rewards should be split between the node operator and its delegators.", + "type": "object", + "required": [ + "interval_operating_cost", + "profit_margin_percent" + ], + "properties": { + "interval_operating_cost": { + "description": "Operating cost of the associated mixnode per the entire interval.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "profit_margin_percent": { + "description": "The profit margin of the associated mixnode, i.e. the desired percent of the reward to be distributed to the operator.", + "allOf": [ + { + "$ref": "#/definitions/Percent" + } + ] + } + }, + "additionalProperties": false + }, + "Percent": { + "description": "Percent represents a value between 0 and 100% (i.e. between 0.0 and 1.0)", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "PledgeCap": { + "description": "Defines cap for pleding/staking tokens.", + "oneOf": [ + { + "description": "Specifies a percent-based pledge cap, i.e. only given % of tokens could be pledged/staked.", + "type": "object", + "required": [ + "percent" + ], + "properties": { + "percent": { + "$ref": "#/definitions/Percent" + } + }, + "additionalProperties": false + }, + { + "description": "Specifies an absolute pledge cap, i.e. an explicit value that could be pledged/staked.", + "type": "object", + "required": [ + "absolute" + ], + "properties": { + "absolute": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "VestingSpecification": { + "type": "object", + "properties": { + "num_periods": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + }, + "period_seconds": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + }, + "start_time": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/vesting/schema/raw/instantiate.json b/contracts/vesting/schema/raw/instantiate.json new file mode 100644 index 0000000000..09b7526278 --- /dev/null +++ b/contracts/vesting/schema/raw/instantiate.json @@ -0,0 +1,18 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "mix_denom", + "mixnet_contract_address" + ], + "properties": { + "mix_denom": { + "type": "string" + }, + "mixnet_contract_address": { + "type": "string" + } + }, + "additionalProperties": false +} diff --git a/contracts/vesting/schema/raw/migrate.json b/contracts/vesting/schema/raw/migrate.json new file mode 100644 index 0000000000..7fbe8c5708 --- /dev/null +++ b/contracts/vesting/schema/raw/migrate.json @@ -0,0 +1,6 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "type": "object", + "additionalProperties": false +} diff --git a/contracts/vesting/schema/raw/query.json b/contracts/vesting/schema/raw/query.json new file mode 100644 index 0000000000..42b1cd94ea --- /dev/null +++ b/contracts/vesting/schema/raw/query.json @@ -0,0 +1,719 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "description": "Queries exposed by this contract.", + "oneOf": [ + { + "description": "Gets build information of this contract, such as the commit hash used for the build or rustc version.", + "type": "object", + "required": [ + "get_contract_version" + ], + "properties": { + "get_contract_version": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the stored contract version information that's required by the CW2 spec interface for migrations.", + "type": "object", + "required": [ + "get_cw2_contract_version" + ], + "properties": { + "get_cw2_contract_version": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the list of vesting accounts held in this contract.", + "type": "object", + "required": [ + "get_accounts_paged" + ], + "properties": { + "get_accounts_paged": { + "type": "object", + "properties": { + "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets the list of coins that are still vesting for each account held in this contract.", + "type": "object", + "required": [ + "get_accounts_vesting_coins_paged" + ], + "properties": { + "get_accounts_vesting_coins_paged": { + "type": "object", + "properties": { + "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the amount of locked coins for the provided vesting account, i.e. coins that are still vesting but have not been staked. `locked_coins = vesting_coins - staked_coins`", + "type": "object", + "required": [ + "locked_coins" + ], + "properties": { + "locked_coins": { + "type": "object", + "required": [ + "vesting_account_address" + ], + "properties": { + "block_time": { + "description": "(deprecated) Optional argument specifying that the query should be performed against non-current block.", + "anyOf": [ + { + "$ref": "#/definitions/Timestamp" + }, + { + "type": "null" + } + ] + }, + "vesting_account_address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the amount of spendable coins for the provided vesting account, i.e. coins that could be withdrawn. `spendable_coins = account_balance - locked_coins` note: `account_balance` is the amount of coins still physically present in this contract, i.e. not withdrawn or staked.", + "type": "object", + "required": [ + "spendable_coins" + ], + "properties": { + "spendable_coins": { + "type": "object", + "required": [ + "vesting_account_address" + ], + "properties": { + "block_time": { + "description": "(deprecated) Optional argument specifying that the query should be performed against non-current block.", + "anyOf": [ + { + "$ref": "#/definitions/Timestamp" + }, + { + "type": "null" + } + ] + }, + "vesting_account_address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the amount of coins that have already vested for the provided vesting account address.", + "type": "object", + "required": [ + "get_vested_coins" + ], + "properties": { + "get_vested_coins": { + "type": "object", + "required": [ + "vesting_account_address" + ], + "properties": { + "block_time": { + "description": "(deprecated) Optional argument specifying that the query should be performed against non-current block.", + "anyOf": [ + { + "$ref": "#/definitions/Timestamp" + }, + { + "type": "null" + } + ] + }, + "vesting_account_address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the amount of coins that are still vesting for the provided vesting account address.", + "type": "object", + "required": [ + "get_vesting_coins" + ], + "properties": { + "get_vesting_coins": { + "type": "object", + "required": [ + "vesting_account_address" + ], + "properties": { + "block_time": { + "description": "(deprecated) Optional argument specifying that the query should be performed against non-current block.", + "anyOf": [ + { + "$ref": "#/definitions/Timestamp" + }, + { + "type": "null" + } + ] + }, + "vesting_account_address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the starting vesting time for the provided vesting account, i.e. the beginning of the first vesting period.", + "type": "object", + "required": [ + "get_start_time" + ], + "properties": { + "get_start_time": { + "type": "object", + "required": [ + "vesting_account_address" + ], + "properties": { + "vesting_account_address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the ending vesting time for the provided vesting account, i.e. the end of the last vesting period.", + "type": "object", + "required": [ + "get_end_time" + ], + "properties": { + "get_end_time": { + "type": "object", + "required": [ + "vesting_account_address" + ], + "properties": { + "vesting_account_address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the initial vesting specification used for the provided vesting account address.", + "type": "object", + "required": [ + "get_original_vesting" + ], + "properties": { + "get_original_vesting": { + "type": "object", + "required": [ + "vesting_account_address" + ], + "properties": { + "vesting_account_address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the total amount of coins accrued through claimed staking rewards by the provided vesting account.", + "type": "object", + "required": [ + "get_historical_vesting_staking_reward" + ], + "properties": { + "get_historical_vesting_staking_reward": { + "type": "object", + "required": [ + "vesting_account_address" + ], + "properties": { + "vesting_account_address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the amount of spendable vesting coins for the provided vesting account, i.e. coins that could be withdrawn that originated from the vesting specification.", + "type": "object", + "required": [ + "get_spendable_vested_coins" + ], + "properties": { + "get_spendable_vested_coins": { + "type": "object", + "required": [ + "vesting_account_address" + ], + "properties": { + "vesting_account_address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the amount of spendable reward coins for the provided vesting account, i.e. coins that could be withdrawn that originated from the claimed staking rewards.", + "type": "object", + "required": [ + "get_spendable_reward_coins" + ], + "properties": { + "get_spendable_reward_coins": { + "type": "object", + "required": [ + "vesting_account_address" + ], + "properties": { + "vesting_account_address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the amount of coins that are currently delegated for the provided vesting account address.", + "type": "object", + "required": [ + "get_delegated_coins" + ], + "properties": { + "get_delegated_coins": { + "type": "object", + "required": [ + "vesting_account_address" + ], + "properties": { + "vesting_account_address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the amount of coins that are currently pledged for the provided vesting account address.", + "type": "object", + "required": [ + "get_pledged_coins" + ], + "properties": { + "get_pledged_coins": { + "type": "object", + "required": [ + "vesting_account_address" + ], + "properties": { + "vesting_account_address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the amount of coins that are currently staked (i.e. delegations + pledges) for the provided vesting account address.", + "type": "object", + "required": [ + "get_staked_coins" + ], + "properties": { + "get_staked_coins": { + "type": "object", + "required": [ + "vesting_account_address" + ], + "properties": { + "vesting_account_address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the amount of coins that got withdrawn for the provided vesting account address.", + "type": "object", + "required": [ + "get_withdrawn_coins" + ], + "properties": { + "get_withdrawn_coins": { + "type": "object", + "required": [ + "vesting_account_address" + ], + "properties": { + "vesting_account_address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns detailed information associated with the account for the provided vesting account address.", + "type": "object", + "required": [ + "get_account" + ], + "properties": { + "get_account": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns pledge information (if applicable) for bonded mixnode for the provided vesting account address.", + "type": "object", + "required": [ + "get_mixnode" + ], + "properties": { + "get_mixnode": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns pledge information (if applicable) for bonded gateway for the provided vesting account address.", + "type": "object", + "required": [ + "get_gateway" + ], + "properties": { + "get_gateway": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the current vesting period for the provided vesting account address.", + "type": "object", + "required": [ + "get_current_vesting_period" + ], + "properties": { + "get_current_vesting_period": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "Address of the vesting account in question.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the information about particular vesting delegation.", + "type": "object", + "required": [ + "get_delegation" + ], + "properties": { + "get_delegation": { + "type": "object", + "required": [ + "address", + "block_timestamp_secs", + "mix_id" + ], + "properties": { + "address": { + "description": "Address of the vesting account in question.", + "type": "string" + }, + "block_timestamp_secs": { + "description": "Block timestamp of the delegation.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "mix_id": { + "description": "Id of the mixnode towards which the delegation has been made.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the total amount of coins delegated towards particular mixnode by the provided vesting account address.", + "type": "object", + "required": [ + "get_total_delegation_amount" + ], + "properties": { + "get_total_delegation_amount": { + "type": "object", + "required": [ + "address", + "mix_id" + ], + "properties": { + "address": { + "description": "Address of the vesting account in question.", + "type": "string" + }, + "mix_id": { + "description": "Id of the mixnode towards which the delegations have been made.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns timestamps of delegations made towards particular mixnode by the provided vesting account address.", + "type": "object", + "required": [ + "get_delegation_times" + ], + "properties": { + "get_delegation_times": { + "type": "object", + "required": [ + "address", + "mix_id" + ], + "properties": { + "address": { + "description": "Address of the vesting account in question.", + "type": "string" + }, + "mix_id": { + "description": "Id of the mixnode towards which the delegations have been made.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns all active delegations made with vesting tokens stored in this contract.", + "type": "object", + "required": [ + "get_all_delegations" + ], + "properties": { + "get_all_delegations": { + "type": "object", + "properties": { + "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + ], + "maxItems": 3, + "minItems": 3 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/vesting/schema/raw/response_to_get_account.json b/contracts/vesting/schema/raw/response_to_get_account.json new file mode 100644 index 0000000000..7d8544539b --- /dev/null +++ b/contracts/vesting/schema/raw/response_to_get_account.json @@ -0,0 +1,179 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Account", + "description": "Vesting account information.", + "type": "object", + "required": [ + "coin", + "owner_address", + "periods", + "start_time", + "storage_key" + ], + "properties": { + "coin": { + "description": "The initial amount of coins used creation of this account.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "owner_address": { + "description": "Address of the owner of the vesting account.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "periods": { + "description": "All vesting periods for this account.", + "type": "array", + "items": { + "$ref": "#/definitions/VestingPeriod" + } + }, + "pledge_cap": { + "description": "Optional custom pledge cap of this vesting account.", + "default": null, + "anyOf": [ + { + "$ref": "#/definitions/PledgeCap" + }, + { + "type": "null" + } + ] + }, + "staking_address": { + "description": "Optional address of an account allowed to perform staking on behalf of the owner.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + }, + "start_time": { + "description": "The starting vesting time.", + "allOf": [ + { + "$ref": "#/definitions/Timestamp" + } + ] + }, + "storage_key": { + "description": "The id/storage_key of this vesting account.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Percent": { + "description": "Percent represents a value between 0 and 100% (i.e. between 0.0 and 1.0)", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "PledgeCap": { + "description": "Defines cap for pleding/staking tokens.", + "oneOf": [ + { + "description": "Specifies a percent-based pledge cap, i.e. only given % of tokens could be pledged/staked.", + "type": "object", + "required": [ + "percent" + ], + "properties": { + "percent": { + "$ref": "#/definitions/Percent" + } + }, + "additionalProperties": false + }, + { + "description": "Specifies an absolute pledge cap, i.e. an explicit value that could be pledged/staked.", + "type": "object", + "required": [ + "absolute" + ], + "properties": { + "absolute": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + } + ] + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + }, + "VestingPeriod": { + "description": "Vesting period details.", + "type": "object", + "required": [ + "period_seconds", + "start_time" + ], + "properties": { + "period_seconds": { + "description": "The duration (in seconds) of the vesting period.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "start_time": { + "description": "The start time of this vesting period, as unix timestamp.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/vesting/schema/raw/response_to_get_accounts_paged.json b/contracts/vesting/schema/raw/response_to_get_accounts_paged.json new file mode 100644 index 0000000000..f84ed729b8 --- /dev/null +++ b/contracts/vesting/schema/raw/response_to_get_accounts_paged.json @@ -0,0 +1,61 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AccountsResponse", + "description": "Response containing basic vesting account information", + "type": "object", + "required": [ + "accounts" + ], + "properties": { + "accounts": { + "description": "The actual accounts returned by the query.", + "type": "array", + "items": { + "$ref": "#/definitions/BaseVestingAccountInfo" + } + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "BaseVestingAccountInfo": { + "description": "Basic information regarding particular vesting account", + "type": "object", + "required": [ + "account_id", + "owner" + ], + "properties": { + "account_id": { + "description": "Id associated with this account", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "description": "Address of this account's owner", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/vesting/schema/raw/response_to_get_accounts_vesting_coins_paged.json b/contracts/vesting/schema/raw/response_to_get_accounts_vesting_coins_paged.json new file mode 100644 index 0000000000..6647e14194 --- /dev/null +++ b/contracts/vesting/schema/raw/response_to_get_accounts_vesting_coins_paged.json @@ -0,0 +1,89 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "VestingCoinsResponse", + "description": "Response containing vesting coins held in this contract", + "type": "object", + "required": [ + "accounts" + ], + "properties": { + "accounts": { + "description": "The actual accounts, and their vesting coins, returned by the query.", + "type": "array", + "items": { + "$ref": "#/definitions/AccountVestingCoins" + } + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "AccountVestingCoins": { + "description": "Basic information regarding particular vesting account alongside the amount of vesting coins.", + "type": "object", + "required": [ + "account_id", + "owner", + "still_vesting" + ], + "properties": { + "account_id": { + "description": "Id associated with this account", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "description": "Address of this account's owner", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "still_vesting": { + "description": "Coins that are still vesting belonging to this account.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + } + }, + "additionalProperties": false + }, + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/vesting/schema/raw/response_to_get_all_delegations.json b/contracts/vesting/schema/raw/response_to_get_all_delegations.json new file mode 100644 index 0000000000..89de917311 --- /dev/null +++ b/contracts/vesting/schema/raw/response_to_get_all_delegations.json @@ -0,0 +1,90 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AllDelegationsResponse", + "description": "Response containing paged list of all vesting delegations made using vesting coins.", + "type": "object", + "required": [ + "delegations" + ], + "properties": { + "delegations": { + "description": "The actual vesting delegations made.", + "type": "array", + "items": { + "$ref": "#/definitions/VestingDelegation" + } + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + ], + "maxItems": 3, + "minItems": 3 + } + }, + "additionalProperties": false, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "VestingDelegation": { + "description": "Details about particular vesting delegation.", + "type": "object", + "required": [ + "account_id", + "amount", + "block_timestamp", + "mix_id" + ], + "properties": { + "account_id": { + "description": "The id of the vesting account that has made the delegation.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "amount": { + "description": "The raw amount delegated (interpreted to be in the same denom as the underlying vesting specification)", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "block_timestamp": { + "description": "The block timestamp when the delegation has been made.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "mix_id": { + "description": "The id of the mixnode towards which the delegation has been made.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/vesting/schema/raw/response_to_get_c_w2_contract_version.json b/contracts/vesting/schema/raw/response_to_get_c_w2_contract_version.json new file mode 100644 index 0000000000..3ded8c84d9 --- /dev/null +++ b/contracts/vesting/schema/raw/response_to_get_c_w2_contract_version.json @@ -0,0 +1,20 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ContractVersion", + "type": "object", + "required": [ + "contract", + "version" + ], + "properties": { + "contract": { + "description": "contract is the crate name of the implementing contract, eg. `crate:cw20-base` we will use other prefixes for other languages, and their standard global namespacing", + "type": "string" + }, + "version": { + "description": "version is any string that this implementation knows. It may be simple counter \"1\", \"2\". or semantic version on release tags \"v0.7.0\", or some custom feature flag list. the only code that needs to understand the version parsing is code that knows how to migrate from the given contract (and is tied to it's implementation somehow)", + "type": "string" + } + }, + "additionalProperties": false +} diff --git a/contracts/vesting/schema/raw/response_to_get_contract_version.json b/contracts/vesting/schema/raw/response_to_get_contract_version.json new file mode 100644 index 0000000000..60ae65f3d1 --- /dev/null +++ b/contracts/vesting/schema/raw/response_to_get_contract_version.json @@ -0,0 +1,40 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ContractBuildInformation", + "type": "object", + "required": [ + "build_timestamp", + "build_version", + "commit_branch", + "commit_sha", + "commit_timestamp", + "rustc_version" + ], + "properties": { + "build_timestamp": { + "description": "Provides the build timestamp, for example `2021-02-23T20:14:46.558472672+00:00`.", + "type": "string" + }, + "build_version": { + "description": "Provides the build version, for example `0.1.0-9-g46f83e1`.", + "type": "string" + }, + "commit_branch": { + "description": "Provides the name of the git branch that was used for the build, for example `master`.", + "type": "string" + }, + "commit_sha": { + "description": "Provides the hash of the commit that was used for the build, for example `46f83e112520533338245862d366f6a02cef07d4`.", + "type": "string" + }, + "commit_timestamp": { + "description": "Provides the timestamp of the commit that was used for the build, for example `2021-02-23T08:08:02-05:00`.", + "type": "string" + }, + "rustc_version": { + "description": "Provides the rustc version that was used for the build, for example `1.52.0-nightly`.", + "type": "string" + } + }, + "additionalProperties": false +} diff --git a/contracts/vesting/schema/raw/response_to_get_current_vesting_period.json b/contracts/vesting/schema/raw/response_to_get_current_vesting_period.json new file mode 100644 index 0000000000..e001a46a2c --- /dev/null +++ b/contracts/vesting/schema/raw/response_to_get_current_vesting_period.json @@ -0,0 +1,36 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Period", + "description": "The vesting period.", + "oneOf": [ + { + "description": "Defines a pre-vesting period.", + "type": "string", + "enum": [ + "before" + ] + }, + { + "description": "Defines currently active vesting period.", + "type": "object", + "required": [ + "in" + ], + "properties": { + "in": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "Defines a post-vesting period.", + "type": "string", + "enum": [ + "after" + ] + } + ] +} diff --git a/contracts/vesting/schema/raw/response_to_get_delegated_coins.json b/contracts/vesting/schema/raw/response_to_get_delegated_coins.json new file mode 100644 index 0000000000..6e18ef9a9b --- /dev/null +++ b/contracts/vesting/schema/raw/response_to_get_delegated_coins.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Coin", + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/vesting/schema/raw/response_to_get_delegation.json b/contracts/vesting/schema/raw/response_to_get_delegation.json new file mode 100644 index 0000000000..75c770ef66 --- /dev/null +++ b/contracts/vesting/schema/raw/response_to_get_delegation.json @@ -0,0 +1,47 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "VestingDelegation", + "description": "Details about particular vesting delegation.", + "type": "object", + "required": [ + "account_id", + "amount", + "block_timestamp", + "mix_id" + ], + "properties": { + "account_id": { + "description": "The id of the vesting account that has made the delegation.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "amount": { + "description": "The raw amount delegated (interpreted to be in the same denom as the underlying vesting specification)", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "block_timestamp": { + "description": "The block timestamp when the delegation has been made.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "mix_id": { + "description": "The id of the mixnode towards which the delegation has been made.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/vesting/schema/raw/response_to_get_delegation_times.json b/contracts/vesting/schema/raw/response_to_get_delegation_times.json new file mode 100644 index 0000000000..0ac43e6513 --- /dev/null +++ b/contracts/vesting/schema/raw/response_to_get_delegation_times.json @@ -0,0 +1,50 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "DelegationTimesResponse", + "description": "Response containing timestamps of all delegations made towards particular mixnode by given vesting account.", + "type": "object", + "required": [ + "account_id", + "delegation_timestamps", + "mix_id", + "owner" + ], + "properties": { + "account_id": { + "description": "Id associated with this account", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "delegation_timestamps": { + "description": "All timestamps where a delegation was made", + "type": "array", + "items": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "mix_id": { + "description": "Id of the mixnode towards which the delegation was made", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "description": "Address of this account's owner", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + } + } +} diff --git a/contracts/vesting/schema/raw/response_to_get_end_time.json b/contracts/vesting/schema/raw/response_to_get_end_time.json new file mode 100644 index 0000000000..6dd9971a14 --- /dev/null +++ b/contracts/vesting/schema/raw/response_to_get_end_time.json @@ -0,0 +1,16 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Timestamp", + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ], + "definitions": { + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/vesting/schema/raw/response_to_get_gateway.json b/contracts/vesting/schema/raw/response_to_get_gateway.json new file mode 100644 index 0000000000..1a18cd9f84 --- /dev/null +++ b/contracts/vesting/schema/raw/response_to_get_gateway.json @@ -0,0 +1,72 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Nullable_PledgeData", + "anyOf": [ + { + "$ref": "#/definitions/PledgeData" + }, + { + "type": "null" + } + ], + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "PledgeData": { + "description": "Information regarding pledge (i.e. mixnode or gateway bonding) made with vesting tokens.", + "type": "object", + "required": [ + "amount", + "block_time" + ], + "properties": { + "amount": { + "description": "The amount pledged.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "block_time": { + "description": "The block timestamp where the pledge occurred.", + "allOf": [ + { + "$ref": "#/definitions/Timestamp" + } + ] + } + }, + "additionalProperties": false + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/vesting/schema/raw/response_to_get_historical_vesting_staking_reward.json b/contracts/vesting/schema/raw/response_to_get_historical_vesting_staking_reward.json new file mode 100644 index 0000000000..6e18ef9a9b --- /dev/null +++ b/contracts/vesting/schema/raw/response_to_get_historical_vesting_staking_reward.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Coin", + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/vesting/schema/raw/response_to_get_mixnode.json b/contracts/vesting/schema/raw/response_to_get_mixnode.json new file mode 100644 index 0000000000..1a18cd9f84 --- /dev/null +++ b/contracts/vesting/schema/raw/response_to_get_mixnode.json @@ -0,0 +1,72 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Nullable_PledgeData", + "anyOf": [ + { + "$ref": "#/definitions/PledgeData" + }, + { + "type": "null" + } + ], + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "PledgeData": { + "description": "Information regarding pledge (i.e. mixnode or gateway bonding) made with vesting tokens.", + "type": "object", + "required": [ + "amount", + "block_time" + ], + "properties": { + "amount": { + "description": "The amount pledged.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "block_time": { + "description": "The block timestamp where the pledge occurred.", + "allOf": [ + { + "$ref": "#/definitions/Timestamp" + } + ] + } + }, + "additionalProperties": false + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/vesting/schema/raw/response_to_get_original_vesting.json b/contracts/vesting/schema/raw/response_to_get_original_vesting.json new file mode 100644 index 0000000000..0b0ced2dec --- /dev/null +++ b/contracts/vesting/schema/raw/response_to_get_original_vesting.json @@ -0,0 +1,55 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "OriginalVestingResponse", + "description": "Details about the original vesting specification used when the account was created.", + "type": "object", + "required": [ + "amount", + "number_of_periods", + "period_duration" + ], + "properties": { + "amount": { + "description": "The original amount that was used for the creation of this vesting account", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "number_of_periods": { + "description": "The number of vesting periods that the account was created with", + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "period_duration": { + "description": "Duration of each vesting period in seconds", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/vesting/schema/raw/response_to_get_pledged_coins.json b/contracts/vesting/schema/raw/response_to_get_pledged_coins.json new file mode 100644 index 0000000000..6e18ef9a9b --- /dev/null +++ b/contracts/vesting/schema/raw/response_to_get_pledged_coins.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Coin", + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/vesting/schema/raw/response_to_get_spendable_reward_coins.json b/contracts/vesting/schema/raw/response_to_get_spendable_reward_coins.json new file mode 100644 index 0000000000..6e18ef9a9b --- /dev/null +++ b/contracts/vesting/schema/raw/response_to_get_spendable_reward_coins.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Coin", + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/vesting/schema/raw/response_to_get_spendable_vested_coins.json b/contracts/vesting/schema/raw/response_to_get_spendable_vested_coins.json new file mode 100644 index 0000000000..6e18ef9a9b --- /dev/null +++ b/contracts/vesting/schema/raw/response_to_get_spendable_vested_coins.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Coin", + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/vesting/schema/raw/response_to_get_staked_coins.json b/contracts/vesting/schema/raw/response_to_get_staked_coins.json new file mode 100644 index 0000000000..6e18ef9a9b --- /dev/null +++ b/contracts/vesting/schema/raw/response_to_get_staked_coins.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Coin", + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/vesting/schema/raw/response_to_get_start_time.json b/contracts/vesting/schema/raw/response_to_get_start_time.json new file mode 100644 index 0000000000..6dd9971a14 --- /dev/null +++ b/contracts/vesting/schema/raw/response_to_get_start_time.json @@ -0,0 +1,16 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Timestamp", + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ], + "definitions": { + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/vesting/schema/raw/response_to_get_total_delegation_amount.json b/contracts/vesting/schema/raw/response_to_get_total_delegation_amount.json new file mode 100644 index 0000000000..6e18ef9a9b --- /dev/null +++ b/contracts/vesting/schema/raw/response_to_get_total_delegation_amount.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Coin", + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/vesting/schema/raw/response_to_get_vested_coins.json b/contracts/vesting/schema/raw/response_to_get_vested_coins.json new file mode 100644 index 0000000000..6e18ef9a9b --- /dev/null +++ b/contracts/vesting/schema/raw/response_to_get_vested_coins.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Coin", + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/vesting/schema/raw/response_to_get_vesting_coins.json b/contracts/vesting/schema/raw/response_to_get_vesting_coins.json new file mode 100644 index 0000000000..6e18ef9a9b --- /dev/null +++ b/contracts/vesting/schema/raw/response_to_get_vesting_coins.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Coin", + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/vesting/schema/raw/response_to_get_withdrawn_coins.json b/contracts/vesting/schema/raw/response_to_get_withdrawn_coins.json new file mode 100644 index 0000000000..6e18ef9a9b --- /dev/null +++ b/contracts/vesting/schema/raw/response_to_get_withdrawn_coins.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Coin", + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/vesting/schema/raw/response_to_locked_coins.json b/contracts/vesting/schema/raw/response_to_locked_coins.json new file mode 100644 index 0000000000..6e18ef9a9b --- /dev/null +++ b/contracts/vesting/schema/raw/response_to_locked_coins.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Coin", + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/vesting/schema/raw/response_to_spendable_coins.json b/contracts/vesting/schema/raw/response_to_spendable_coins.json new file mode 100644 index 0000000000..6e18ef9a9b --- /dev/null +++ b/contracts/vesting/schema/raw/response_to_spendable_coins.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Coin", + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/vesting/src/bin/schema.rs b/contracts/vesting/src/bin/schema.rs new file mode 100644 index 0000000000..fc95866f6d --- /dev/null +++ b/contracts/vesting/src/bin/schema.rs @@ -0,0 +1,14 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use cosmwasm_schema::write_api; +use vesting_contract_common::{ExecuteMsg, InitMsg, MigrateMsg, QueryMsg}; + +fn main() { + write_api! { + instantiate: InitMsg, + query: QueryMsg, + execute: ExecuteMsg, + migrate: MigrateMsg, + } +} diff --git a/contracts/vesting/src/contract.rs b/contracts/vesting/src/contract.rs index 54db2d9464..31d3c21b06 100644 --- a/contracts/vesting/src/contract.rs +++ b/contracts/vesting/src/contract.rs @@ -1,14 +1,13 @@ -use crate::errors::ContractError; pub use crate::queries::*; use crate::storage::{ADMIN, MIXNET_CONTRACT_ADDRESS, MIX_DENOM}; pub use crate::transactions::*; -use crate::vesting::Account; use cosmwasm_std::{ entry_point, to_binary, Addr, Coin, Deps, DepsMut, Env, MessageInfo, QueryResponse, Response, Uint128, }; use semver::Version; use vesting_contract_common::messages::{ExecuteMsg, InitMsg, MigrateMsg, QueryMsg}; +use vesting_contract_common::{Account, VestingContractError}; // version info for migration info const CONTRACT_NAME: &str = "crate:nym-vesting-contract"; @@ -36,7 +35,7 @@ pub fn instantiate( _env: Env, info: MessageInfo, msg: InitMsg, -) -> Result { +) -> Result { // validate the received mixnet contract address let mixnet_contract_address = deps.api.addr_validate(&msg.mixnet_contract_address)?; @@ -51,21 +50,24 @@ pub fn instantiate( } #[entry_point] -pub fn migrate(deps: DepsMut<'_>, _env: Env, _msg: MigrateMsg) -> Result { +pub fn migrate( + deps: DepsMut<'_>, + _env: Env, + _msg: MigrateMsg, +) -> Result { // note: don't remove this particular bit of code as we have to ALWAYS check whether we have to update the stored version - let version: Version = - CONTRACT_VERSION - .parse() - .map_err(|error: semver::Error| ContractError::SemVerFailure { - value: CONTRACT_VERSION.to_string(), - error_message: error.to_string(), - })?; + let version: Version = CONTRACT_VERSION.parse().map_err(|error: semver::Error| { + VestingContractError::SemVerFailure { + value: CONTRACT_VERSION.to_string(), + error_message: error.to_string(), + } + })?; let storage_version_raw = cw2::get_contract_version(deps.storage)?.version; let storage_version: Version = storage_version_raw .parse() - .map_err(|error: semver::Error| ContractError::SemVerFailure { + .map_err(|error: semver::Error| VestingContractError::SemVerFailure { value: storage_version_raw, error_message: error.to_string(), })?; @@ -86,7 +88,7 @@ pub fn execute( env: Env, info: MessageInfo, msg: ExecuteMsg, -) -> Result { +) -> Result { match msg { ExecuteMsg::CreateFamily { label } => try_create_family(info, deps, label), ExecuteMsg::JoinFamily { @@ -190,7 +192,11 @@ pub fn execute( } #[entry_point] -pub fn query(deps: Deps<'_>, env: Env, msg: QueryMsg) -> Result { +pub fn query( + deps: Deps<'_>, + env: Env, + msg: QueryMsg, +) -> Result { let query_res = match msg { QueryMsg::GetContractVersion {} => to_binary(&get_contract_version()), QueryMsg::GetCW2ContractVersion {} => to_binary(&cw2::get_contract_version(deps.storage)?), @@ -314,17 +320,23 @@ pub fn query(deps: Deps<'_>, env: Env, msg: QueryMsg) -> Result Result { +pub(crate) fn validate_funds( + funds: &[Coin], + mix_denom: String, +) -> Result { if funds.is_empty() || funds[0].amount.is_zero() { - return Err(ContractError::EmptyFunds); + return Err(VestingContractError::EmptyFunds); } if funds.len() > 1 { - return Err(ContractError::MultipleDenoms); + return Err(VestingContractError::MultipleDenoms); } if funds[0].denom != mix_denom { - return Err(ContractError::WrongDenom(funds[0].denom.clone(), mix_denom)); + return Err(VestingContractError::WrongDenom( + funds[0].denom.clone(), + mix_denom, + )); } Ok(funds[0].clone()) @@ -333,13 +345,13 @@ pub(crate) fn validate_funds(funds: &[Coin], mix_denom: String) -> Result Result<(), ContractError> { +) -> Result<(), VestingContractError> { if let Some(staking_address) = account.staking_address() { if staking_address == addr { return Ok(()); } } - Err(ContractError::InvalidStakingAccount { + Err(VestingContractError::InvalidStakingAccount { address: addr.clone(), for_account: account.owner_address(), }) diff --git a/contracts/vesting/src/lib.rs b/contracts/vesting/src/lib.rs index d2238d4d15..527a9ffa53 100644 --- a/contracts/vesting/src/lib.rs +++ b/contracts/vesting/src/lib.rs @@ -5,7 +5,6 @@ #![warn(clippy::unwrap_used)] pub mod contract; -pub mod errors; mod queries; mod queued_migrations; mod storage; diff --git a/contracts/vesting/src/queries.rs b/contracts/vesting/src/queries.rs index a33bb84256..c3c9c0d99d 100644 --- a/contracts/vesting/src/queries.rs +++ b/contracts/vesting/src/queries.rs @@ -1,19 +1,18 @@ // Copyright 2021-2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::errors::ContractError; use crate::storage; use crate::storage::{account_from_address, BlockTimestampSecs, ACCOUNTS, DELEGATIONS, MIX_DENOM}; use crate::traits::VestingAccount; -use crate::vesting::Account; +use crate::vesting::StorableVestingAccountExt; use contracts_common::ContractBuildInformation; use cosmwasm_std::{Coin, Deps, Env, Order, StdResult, Timestamp, Uint128}; use cw_storage_plus::Bound; use mixnet_contract_common::MixId; use vesting_contract_common::{ - AccountVestingCoins, AccountsResponse, AllDelegationsResponse, BaseVestingAccountInfo, + Account, AccountVestingCoins, AccountsResponse, AllDelegationsResponse, BaseVestingAccountInfo, DelegationTimesResponse, OriginalVestingResponse, Period, PledgeData, VestingCoinsResponse, - VestingDelegation, + VestingContractError, VestingDelegation, }; /// Get current vesting period for a given [crate::vesting::Account]. @@ -21,24 +20,30 @@ pub fn try_get_current_vesting_period( address: &str, deps: Deps<'_>, env: Env, -) -> Result { +) -> Result { let account = account_from_address(address, deps.storage, deps.api)?; account.get_current_vesting_period(env.block.time) } /// Loads mixnode bond from vesting contract storage. -pub fn try_get_mixnode(address: &str, deps: Deps<'_>) -> Result, ContractError> { +pub fn try_get_mixnode( + address: &str, + deps: Deps<'_>, +) -> Result, VestingContractError> { let account = account_from_address(address, deps.storage, deps.api)?; account.load_mixnode_pledge(deps.storage) } /// Loads gateway bond from vesting contract storage. -pub fn try_get_gateway(address: &str, deps: Deps<'_>) -> Result, ContractError> { +pub fn try_get_gateway( + address: &str, + deps: Deps<'_>, +) -> Result, VestingContractError> { let account = account_from_address(address, deps.storage, deps.api)?; account.load_gateway_pledge(deps.storage) } -pub fn try_get_account(address: &str, deps: Deps<'_>) -> Result { +pub fn try_get_account(address: &str, deps: Deps<'_>) -> Result { account_from_address(address, deps.storage, deps.api) } @@ -65,7 +70,7 @@ pub fn try_get_all_accounts( deps: Deps<'_>, start_after: Option, limit: Option, -) -> Result { +) -> Result { let limit = limit.unwrap_or(150).min(250) as usize; let start = start_after @@ -96,7 +101,7 @@ pub fn try_get_all_accounts_vesting_coins( env: Env, start_after: Option, limit: Option, -) -> Result { +) -> Result { let limit = limit.unwrap_or(150).min(250) as usize; let start = start_after @@ -133,7 +138,7 @@ pub fn try_get_locked_coins( block_time: Option, env: Env, deps: Deps<'_>, -) -> Result { +) -> Result { let account = account_from_address(vesting_account_address, deps.storage, deps.api)?; account.locked_coins(block_time, &env, deps.storage) } @@ -144,7 +149,7 @@ pub fn try_get_spendable_coins( block_time: Option, env: Env, deps: Deps<'_>, -) -> Result { +) -> Result { let account = account_from_address(vesting_account_address, deps.storage, deps.api)?; account.spendable_coins(block_time, &env, deps.storage) } @@ -155,7 +160,7 @@ pub fn try_get_vested_coins( block_time: Option, env: Env, deps: Deps<'_>, -) -> Result { +) -> Result { let account = account_from_address(vesting_account_address, deps.storage, deps.api)?; account.get_vested_coins(block_time, &env, deps.storage) } @@ -166,7 +171,7 @@ pub fn try_get_vesting_coins( block_time: Option, env: Env, deps: Deps<'_>, -) -> Result { +) -> Result { let account = account_from_address(vesting_account_address, deps.storage, deps.api)?; account.get_vesting_coins(block_time, &env, deps.storage) } @@ -175,7 +180,7 @@ pub fn try_get_vesting_coins( pub fn try_get_start_time( vesting_account_address: &str, deps: Deps<'_>, -) -> Result { +) -> Result { let account = account_from_address(vesting_account_address, deps.storage, deps.api)?; Ok(account.get_start_time()) } @@ -184,7 +189,7 @@ pub fn try_get_start_time( pub fn try_get_end_time( vesting_account_address: &str, deps: Deps<'_>, -) -> Result { +) -> Result { let account = account_from_address(vesting_account_address, deps.storage, deps.api)?; Ok(account.get_end_time()) } @@ -193,7 +198,7 @@ pub fn try_get_end_time( pub fn try_get_original_vesting( vesting_account_address: &str, deps: Deps<'_>, -) -> Result { +) -> Result { let account = account_from_address(vesting_account_address, deps.storage, deps.api)?; account.get_original_vesting() } @@ -201,7 +206,7 @@ pub fn try_get_original_vesting( pub fn try_get_historical_vesting_staking_reward( vesting_account_address: &str, deps: Deps<'_>, -) -> Result { +) -> Result { let account = account_from_address(vesting_account_address, deps.storage, deps.api)?; account.get_historical_vested_staking_rewards(deps.storage) } @@ -210,7 +215,7 @@ pub fn try_get_spendable_vested_coins( vesting_account_address: &str, deps: Deps<'_>, env: Env, -) -> Result { +) -> Result { let account = account_from_address(vesting_account_address, deps.storage, deps.api)?; account.spendable_vested_coins(None, &env, deps.storage) } @@ -219,7 +224,7 @@ pub fn try_get_spendable_reward_coins( vesting_account_address: &str, deps: Deps<'_>, env: Env, -) -> Result { +) -> Result { let account = account_from_address(vesting_account_address, deps.storage, deps.api)?; account.spendable_reward_coins(None, &env, deps.storage) } @@ -227,7 +232,7 @@ pub fn try_get_spendable_reward_coins( pub fn try_get_delegated_coins( vesting_account_address: &str, deps: Deps<'_>, -) -> Result { +) -> Result { let account = account_from_address(vesting_account_address, deps.storage, deps.api)?; let denom = MIX_DENOM.load(deps.storage)?; let amount = account.total_delegations(deps.storage)?; @@ -237,7 +242,7 @@ pub fn try_get_delegated_coins( pub fn try_get_pledged_coins( vesting_account_address: &str, deps: Deps<'_>, -) -> Result { +) -> Result { let account = account_from_address(vesting_account_address, deps.storage, deps.api)?; let denom = MIX_DENOM.load(deps.storage)?; let amount = account.total_pledged(deps.storage)?; @@ -247,7 +252,7 @@ pub fn try_get_pledged_coins( pub fn try_get_staked_coins( vesting_account_address: &str, deps: Deps<'_>, -) -> Result { +) -> Result { let account = account_from_address(vesting_account_address, deps.storage, deps.api)?; let denom = MIX_DENOM.load(deps.storage)?; let amount = account.total_staked(deps.storage)?; @@ -257,7 +262,7 @@ pub fn try_get_staked_coins( pub fn try_get_withdrawn_coins( vesting_account_address: &str, deps: Deps<'_>, -) -> Result { +) -> Result { let account = account_from_address(vesting_account_address, deps.storage, deps.api)?; let denom = MIX_DENOM.load(deps.storage)?; let amount = account.load_withdrawn(deps.storage)?; @@ -269,7 +274,7 @@ pub fn try_get_delegation_times( deps: Deps<'_>, vesting_account_address: &str, mix_id: MixId, -) -> Result { +) -> Result { let owner = deps.api.addr_validate(vesting_account_address)?; let account = account_from_address(vesting_account_address, deps.storage, deps.api)?; @@ -288,7 +293,7 @@ pub fn try_get_all_delegations( deps: Deps<'_>, start_after: Option<(u32, MixId, BlockTimestampSecs)>, limit: Option, -) -> Result { +) -> Result { let limit = limit.unwrap_or(100).min(200) as usize; let start = start_after.map(Bound::exclusive); @@ -325,7 +330,7 @@ pub fn try_get_delegation( vesting_account_address: &str, mix_id: MixId, block_timestamp_secs: BlockTimestampSecs, -) -> Result { +) -> Result { let account = account_from_address(vesting_account_address, deps.storage, deps.api)?; let storage_key = (account.storage_key(), mix_id, block_timestamp_secs); @@ -343,7 +348,7 @@ pub fn try_get_delegation_amount( deps: Deps<'_>, vesting_account_address: &str, mix_id: MixId, -) -> Result { +) -> Result { let account = account_from_address(vesting_account_address, deps.storage, deps.api)?; let amount = DELEGATIONS diff --git a/contracts/vesting/src/storage.rs b/contracts/vesting/src/storage.rs index eb49d3c434..d6d363d36f 100644 --- a/contracts/vesting/src/storage.rs +++ b/contracts/vesting/src/storage.rs @@ -1,16 +1,14 @@ -use crate::errors::ContractError; -use crate::vesting::Account; use cosmwasm_std::{Addr, Api, Storage, Uint128}; use cosmwasm_std::{Coin, Order}; use cw_storage_plus::{Item, Map}; use mixnet_contract_common::{IdentityKey, MixId}; -use vesting_contract_common::PledgeData; +use vesting_contract_common::account::VestingAccountStorageKey; +use vesting_contract_common::{Account, PledgeData, VestingContractError}; pub(crate) type BlockTimestampSecs = u64; -pub(crate) type AccountStorageKey = u32; /// Counter for the unique, monotonically increasing storage key id for the vesting account data. -pub const KEY: Item<'_, AccountStorageKey> = Item::new("key"); +pub const KEY: Item<'_, VestingAccountStorageKey> = Item::new("key"); /// Storage map containing vesting account information associated with particular owner address. pub const ACCOUNTS: Map<'_, Addr, Account> = Map::new("acc"); @@ -18,28 +16,31 @@ pub const ACCOUNTS: Map<'_, Addr, Account> = Map::new("acc"); /// Storage map containing information about amount of tokens associated with particular vesting account /// that are currently present in the contract (and have not been withdrawn or staked in the mixnet contract) // note: this assumes I understood the intent behind this correctly -const BALANCES: Map<'_, AccountStorageKey, Uint128> = Map::new("blc"); +const BALANCES: Map<'_, VestingAccountStorageKey, Uint128> = Map::new("blc"); /// Storage map containing information about amount of tokens withdrawn from the contract by a particular vesting account. -const WITHDRAWNS: Map<'_, AccountStorageKey, Uint128> = Map::new("wthd"); +const WITHDRAWNS: Map<'_, VestingAccountStorageKey, Uint128> = Map::new("wthd"); /// Storage map containing information about amount of tokens pledged towards bonding mixnodes /// in the mixnet contract using a particular vesting account. -const BOND_PLEDGES: Map<'_, AccountStorageKey, PledgeData> = Map::new("bnd"); +const BOND_PLEDGES: Map<'_, VestingAccountStorageKey, PledgeData> = Map::new("bnd"); /// Storage map containing information about amount of tokens pledged towards bonding gateways /// in the mixnet contract using a particular vesting account. -const GATEWAY_PLEDGES: Map<'_, AccountStorageKey, PledgeData> = Map::new("gtw"); +const GATEWAY_PLEDGES: Map<'_, VestingAccountStorageKey, PledgeData> = Map::new("gtw"); /// Old, pre-v2 migration, storage map that used to contain information about tokens delegated /// towards particular mixnodes in the mixnet contract with given vesting account. /// It should be completely empty. -pub const _OLD_DELEGATIONS: Map<'_, (AccountStorageKey, IdentityKey, BlockTimestampSecs), Uint128> = - Map::new("dlg"); +pub const _OLD_DELEGATIONS: Map< + '_, + (VestingAccountStorageKey, IdentityKey, BlockTimestampSecs), + Uint128, +> = Map::new("dlg"); /// Storage map containing information about tokens delegated towards particular mixnodes /// in the mixnet contract with given vesting account. -pub const DELEGATIONS: Map<'_, (AccountStorageKey, MixId, BlockTimestampSecs), Uint128> = +pub const DELEGATIONS: Map<'_, (VestingAccountStorageKey, MixId, BlockTimestampSecs), Uint128> = Map::new("dlg_v2"); /// Explicit contract admin that is allowed, among other things, to create new vesting accounts. @@ -52,10 +53,10 @@ pub const MIXNET_CONTRACT_ADDRESS: Item<'_, Addr> = Item::new("mix"); pub const MIX_DENOM: Item<'_, String> = Item::new("den"); pub fn save_delegation( - key: (AccountStorageKey, MixId, BlockTimestampSecs), + key: (VestingAccountStorageKey, MixId, BlockTimestampSecs), amount: Uint128, storage: &mut dyn Storage, -) -> Result<(), ContractError> { +) -> Result<(), VestingContractError> { let existing_delegation_amount = if let Some(delegation) = DELEGATIONS.may_load(storage, key)? { delegation } else { @@ -67,17 +68,17 @@ pub fn save_delegation( } pub fn remove_delegation( - key: (AccountStorageKey, MixId, BlockTimestampSecs), + key: (VestingAccountStorageKey, MixId, BlockTimestampSecs), storage: &mut dyn Storage, -) -> Result<(), ContractError> { +) -> Result<(), VestingContractError> { DELEGATIONS.remove(storage, key); Ok(()) } pub fn load_delegation_timestamps( - prefix: (AccountStorageKey, MixId), + prefix: (VestingAccountStorageKey, MixId), storage: &dyn Storage, -) -> Result, ContractError> { +) -> Result, VestingContractError> { let block_timestamps = DELEGATIONS .prefix(prefix) .keys(storage, None, None, Order::Ascending) @@ -86,7 +87,7 @@ pub fn load_delegation_timestamps( } pub fn count_subdelegations_for_mix( - prefix: (AccountStorageKey, MixId), + prefix: (VestingAccountStorageKey, MixId), storage: &dyn Storage, ) -> u32 { DELEGATIONS @@ -96,9 +97,9 @@ pub fn count_subdelegations_for_mix( } pub fn load_withdrawn( - key: AccountStorageKey, + key: VestingAccountStorageKey, storage: &dyn Storage, -) -> Result { +) -> Result { Ok(WITHDRAWNS .may_load(storage, key) .unwrap_or(None) @@ -106,9 +107,9 @@ pub fn load_withdrawn( } pub fn load_balance( - key: AccountStorageKey, + key: VestingAccountStorageKey, storage: &dyn Storage, -) -> Result { +) -> Result { Ok(BALANCES .may_load(storage, key) .unwrap_or(None) @@ -116,57 +117,57 @@ pub fn load_balance( } pub fn save_balance( - key: AccountStorageKey, + key: VestingAccountStorageKey, value: Uint128, storage: &mut dyn Storage, -) -> Result<(), ContractError> { +) -> Result<(), VestingContractError> { BALANCES.save(storage, key, &value)?; Ok(()) } pub fn save_withdrawn( - key: AccountStorageKey, + key: VestingAccountStorageKey, value: Uint128, storage: &mut dyn Storage, -) -> Result<(), ContractError> { +) -> Result<(), VestingContractError> { WITHDRAWNS.save(storage, key, &value)?; Ok(()) } pub fn load_bond_pledge( - key: AccountStorageKey, + key: VestingAccountStorageKey, storage: &dyn Storage, -) -> Result, ContractError> { +) -> Result, VestingContractError> { Ok(BOND_PLEDGES.may_load(storage, key).unwrap_or(None)) } pub fn remove_bond_pledge( - key: AccountStorageKey, + key: VestingAccountStorageKey, storage: &mut dyn Storage, -) -> Result<(), ContractError> { +) -> Result<(), VestingContractError> { BOND_PLEDGES.remove(storage, key); Ok(()) } pub fn save_bond_pledge( - key: AccountStorageKey, + key: VestingAccountStorageKey, value: &PledgeData, storage: &mut dyn Storage, -) -> Result<(), ContractError> { +) -> Result<(), VestingContractError> { BOND_PLEDGES.save(storage, key, value)?; Ok(()) } pub fn decrease_bond_pledge( - key: AccountStorageKey, + key: VestingAccountStorageKey, amount: Coin, storage: &mut dyn Storage, -) -> Result<(), ContractError> { +) -> Result<(), VestingContractError> { let mut existing = BOND_PLEDGES.load(storage, key)?; if existing.amount.amount <= amount.amount { // this shouldn't be possible! // (but check for it anyway... just in case) - return Err(ContractError::InvalidBondPledgeReduction { + return Err(VestingContractError::InvalidBondPledgeReduction { current: existing.amount, decrease_by: amount, }); @@ -176,30 +177,33 @@ pub fn decrease_bond_pledge( } pub fn load_gateway_pledge( - key: AccountStorageKey, + key: VestingAccountStorageKey, storage: &dyn Storage, -) -> Result, ContractError> { +) -> Result, VestingContractError> { Ok(GATEWAY_PLEDGES.may_load(storage, key).unwrap_or(None)) } pub fn save_gateway_pledge( - key: AccountStorageKey, + key: VestingAccountStorageKey, value: &PledgeData, storage: &mut dyn Storage, -) -> Result<(), ContractError> { +) -> Result<(), VestingContractError> { GATEWAY_PLEDGES.save(storage, key, value)?; Ok(()) } pub fn remove_gateway_pledge( - key: AccountStorageKey, + key: VestingAccountStorageKey, storage: &mut dyn Storage, -) -> Result<(), ContractError> { +) -> Result<(), VestingContractError> { GATEWAY_PLEDGES.remove(storage, key); Ok(()) } -pub fn save_account(account: &Account, storage: &mut dyn Storage) -> Result<(), ContractError> { +pub fn save_account( + account: &Account, + storage: &mut dyn Storage, +) -> Result<(), VestingContractError> { ACCOUNTS.save(storage, account.owner_address(), account)?; Ok(()) } @@ -207,24 +211,27 @@ pub fn save_account(account: &Account, storage: &mut dyn Storage) -> Result<(), pub fn load_account( address: Addr, storage: &dyn Storage, -) -> Result, ContractError> { +) -> Result, VestingContractError> { Ok(ACCOUNTS.may_load(storage, address).unwrap_or(None)) } -pub fn delete_account(address: Addr, storage: &mut dyn Storage) -> Result<(), ContractError> { +pub fn delete_account( + address: Addr, + storage: &mut dyn Storage, +) -> Result<(), VestingContractError> { ACCOUNTS.remove(storage, address); Ok(()) } -fn validate_account(address: Addr, storage: &dyn Storage) -> Result { +fn validate_account(address: Addr, storage: &dyn Storage) -> Result { load_account(address.clone(), storage)? - .ok_or_else(|| ContractError::NoAccountForAddress(address.into_string())) + .ok_or_else(|| VestingContractError::NoAccountForAddress(address.into_string())) } pub fn account_from_address( address: &str, storage: &dyn Storage, api: &dyn Api, -) -> Result { +) -> Result { validate_account(api.addr_validate(address)?, storage) } diff --git a/contracts/vesting/src/support/tests.rs b/contracts/vesting/src/support/tests.rs index 6f48fe6940..98995b1c8e 100644 --- a/contracts/vesting/src/support/tests.rs +++ b/contracts/vesting/src/support/tests.rs @@ -72,7 +72,7 @@ pub mod helpers { use crate::storage::{ACCOUNTS, ADMIN, MIXNET_CONTRACT_ADDRESS, MIX_DENOM}; use crate::support::tests::helpers::state_dump_decoder::RawState; use crate::traits::VestingAccount; - use crate::vesting::{populate_vesting_periods, Account}; + use crate::vesting::{populate_vesting_periods, StorableVestingAccountExt}; use contracts_common::Percent; use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info, MockApi, MockQuerier}; use cosmwasm_std::{ @@ -83,8 +83,8 @@ pub mod helpers { use rand_chacha::ChaCha20Rng; use std::path::Path; use std::str::FromStr; - use vesting_contract_common::messages::{InitMsg, VestingSpecification}; - use vesting_contract_common::PledgeCap; + use vesting_contract_common::messages::InitMsg; + use vesting_contract_common::{Account, PledgeCap, VestingSpecification}; // use rng with constant seed for all tests so that they would be deterministic #[allow(unused)] @@ -337,7 +337,7 @@ pub mod helpers { VestingSpecification::new(None, Some(3600), None), ); - Account::new( + Account::save_new( Addr::unchecked("owner"), Some(Addr::unchecked("staking")), Coin { @@ -357,7 +357,7 @@ pub mod helpers { let periods = populate_vesting_periods(start_time.seconds(), VestingSpecification::default()); - Account::new( + Account::save_new( Addr::unchecked("owner"), Some(Addr::unchecked("staking")), Coin { @@ -377,7 +377,7 @@ pub mod helpers { let periods = populate_vesting_periods(start_time.seconds(), VestingSpecification::default()); - Account::new( + Account::save_new( Addr::unchecked("owner"), Some(Addr::unchecked("staking")), Coin { diff --git a/contracts/vesting/src/traits/bonding_account.rs b/contracts/vesting/src/traits/bonding_account.rs index bf5cac3bf5..e5e415e30c 100644 --- a/contracts/vesting/src/traits/bonding_account.rs +++ b/contracts/vesting/src/traits/bonding_account.rs @@ -1,4 +1,3 @@ -use crate::errors::ContractError; use contracts_common::signing::MessageSignature; use cosmwasm_std::{Coin, Env, Response, Storage}; use mixnet_contract_common::{ @@ -6,9 +5,13 @@ use mixnet_contract_common::{ mixnode::{MixNodeConfigUpdate, MixNodeCostParams}, Gateway, MixNode, }; +use vesting_contract_common::VestingContractError; pub trait MixnodeBondingAccount { - fn try_claim_operator_reward(&self, storage: &dyn Storage) -> Result; + fn try_claim_operator_reward( + &self, + storage: &dyn Storage, + ) -> Result; fn try_bond_mixnode( &self, @@ -18,46 +21,46 @@ pub trait MixnodeBondingAccount { pledge: Coin, env: &Env, storage: &mut dyn Storage, - ) -> Result; + ) -> Result; fn try_pledge_additional_tokens( &self, additional_pledge: Coin, env: &Env, storage: &mut dyn Storage, - ) -> Result; + ) -> Result; fn try_decrease_mixnode_pledge( &self, amount: Coin, storage: &mut dyn Storage, - ) -> Result; + ) -> Result; - fn try_unbond_mixnode(&self, storage: &dyn Storage) -> Result; + fn try_unbond_mixnode(&self, storage: &dyn Storage) -> Result; fn try_track_unbond_mixnode( &self, amount: Coin, storage: &mut dyn Storage, - ) -> Result<(), ContractError>; + ) -> Result<(), VestingContractError>; fn try_track_decrease_mixnode_pledge( &self, amount: Coin, storage: &mut dyn Storage, - ) -> Result<(), ContractError>; + ) -> Result<(), VestingContractError>; fn try_update_mixnode_config( &self, new_config: MixNodeConfigUpdate, storage: &mut dyn Storage, - ) -> Result; + ) -> Result; fn try_update_mixnode_cost_params( &self, new_costs: MixNodeCostParams, storage: &mut dyn Storage, - ) -> Result; + ) -> Result; } pub trait GatewayBondingAccount { @@ -68,19 +71,19 @@ pub trait GatewayBondingAccount { pledge: Coin, env: &Env, storage: &mut dyn Storage, - ) -> Result; + ) -> Result; - fn try_unbond_gateway(&self, storage: &dyn Storage) -> Result; + fn try_unbond_gateway(&self, storage: &dyn Storage) -> Result; fn try_track_unbond_gateway( &self, amount: Coin, storage: &mut dyn Storage, - ) -> Result<(), ContractError>; + ) -> Result<(), VestingContractError>; fn try_update_gateway_config( &self, new_config: GatewayConfigUpdate, storage: &mut dyn Storage, - ) -> Result; + ) -> Result; } diff --git a/contracts/vesting/src/traits/delegating_account.rs b/contracts/vesting/src/traits/delegating_account.rs index 4beefabe28..629cfee050 100644 --- a/contracts/vesting/src/traits/delegating_account.rs +++ b/contracts/vesting/src/traits/delegating_account.rs @@ -1,13 +1,13 @@ -use crate::errors::ContractError; use cosmwasm_std::{Coin, Env, Response, Storage, Uint128}; use mixnet_contract_common::MixId; +use vesting_contract_common::VestingContractError; pub trait DelegatingAccount { fn try_claim_delegator_reward( &self, mix_id: MixId, storage: &dyn Storage, - ) -> Result; + ) -> Result; fn try_delegate_to_mixnode( &self, @@ -15,13 +15,13 @@ pub trait DelegatingAccount { amount: Coin, env: &Env, storage: &mut dyn Storage, - ) -> Result; + ) -> Result; fn try_undelegate_from_mixnode( &self, mix_id: MixId, storage: &dyn Storage, - ) -> Result; + ) -> Result; // track_delegation performs internal vesting accounting necessary when // delegating from a vesting account. It accepts the current block height, the @@ -35,7 +35,7 @@ pub trait DelegatingAccount { current_balance: Uint128, delegation: Coin, storage: &mut dyn Storage, - ) -> Result<(), ContractError>; + ) -> Result<(), VestingContractError>; // track_undelegation performs internal vesting accounting necessary when a // vesting account performs an undelegation. fn track_undelegation( @@ -43,5 +43,5 @@ pub trait DelegatingAccount { mix_id: MixId, amount: Coin, storage: &mut dyn Storage, - ) -> Result<(), ContractError>; + ) -> Result<(), VestingContractError>; } diff --git a/contracts/vesting/src/traits/node_families.rs b/contracts/vesting/src/traits/node_families.rs index 163308d30a..f5af460d17 100644 --- a/contracts/vesting/src/traits/node_families.rs +++ b/contracts/vesting/src/traits/node_families.rs @@ -1,32 +1,32 @@ -use crate::errors::ContractError; use contracts_common::signing::MessageSignature; use cosmwasm_std::{Response, Storage}; use mixnet_contract_common::families::FamilyHead; use mixnet_contract_common::IdentityKeyRef; +use vesting_contract_common::VestingContractError; pub trait NodeFamilies { fn try_create_family( &self, storage: &dyn Storage, label: String, - ) -> Result; + ) -> Result; fn try_join_family( &self, storage: &dyn Storage, join_permit: MessageSignature, family_head: FamilyHead, - ) -> Result; + ) -> Result; fn try_leave_family( &self, storage: &dyn Storage, family_head: FamilyHead, - ) -> Result; + ) -> Result; fn try_head_kick_member( &self, storage: &dyn Storage, member: IdentityKeyRef<'_>, - ) -> Result; + ) -> Result; } diff --git a/contracts/vesting/src/traits/vesting_account.rs b/contracts/vesting/src/traits/vesting_account.rs index 258a750492..3699f282ea 100644 --- a/contracts/vesting/src/traits/vesting_account.rs +++ b/contracts/vesting/src/traits/vesting_account.rs @@ -1,9 +1,8 @@ -use crate::errors::ContractError; use cosmwasm_std::{Addr, Coin, Env, Storage, Timestamp, Uint128}; -use vesting_contract_common::OriginalVestingResponse; +use vesting_contract_common::{OriginalVestingResponse, VestingContractError}; pub trait VestingAccount { - fn total_staked(&self, storage: &dyn Storage) -> Result; + fn total_staked(&self, storage: &dyn Storage) -> Result; /// Returns the set of coins that are not spendable (can still be delegated tough) (i.e. locked), /// defined as vesting coins that are not delegated or pledged. @@ -17,7 +16,7 @@ pub trait VestingAccount { block_time: Option, env: &Env, storage: &dyn Storage, - ) -> Result; + ) -> Result; /// Calculated as current_balance minus [crate::traits::VestingAccount::locked_coins] /// See [/vesting-contract/struct.Account.html/method.spendable_coins] for impl @@ -26,21 +25,21 @@ pub trait VestingAccount { block_time: Option, env: &Env, storage: &dyn Storage, - ) -> Result; + ) -> Result; fn spendable_vested_coins( &self, block_time: Option, env: &Env, storage: &dyn Storage, - ) -> Result; + ) -> Result; fn spendable_reward_coins( &self, block_time: Option, env: &Env, storage: &dyn Storage, - ) -> Result; + ) -> Result; /// See [/vesting-contract/struct.Account.html/method.get_vested_coins] for impl fn get_vested_coins( @@ -48,7 +47,7 @@ pub trait VestingAccount { block_time: Option, env: &Env, storage: &dyn Storage, - ) -> Result; + ) -> Result; /// See [/vesting-contract/struct.Account.html/method.get_vesting_coins] for impl fn get_vesting_coins( @@ -56,7 +55,7 @@ pub trait VestingAccount { block_time: Option, env: &Env, storage: &dyn Storage, - ) -> Result; + ) -> Result; /// See [/vesting-contract/struct.Account.html/method.get_start_time] for impl fn get_start_time(&self) -> Timestamp; @@ -65,23 +64,27 @@ pub trait VestingAccount { /// Returns amount of coins set at account creation /// See [/vesting-contract/struct.Account.html/method.get_original_vesting] for impl - fn get_original_vesting(&self) -> Result; + fn get_original_vesting(&self) -> Result; /// See [/vesting-contract/struct.Account.html/method.transfer_ownership] for impl fn transfer_ownership( &mut self, to_address: &Addr, storage: &mut dyn Storage, - ) -> Result<(), ContractError>; + ) -> Result<(), VestingContractError>; /// See [/vesting-contract/struct.Account.html/method.update_staking_address] for impl fn update_staking_address( &mut self, to_address: Option, storage: &mut dyn Storage, - ) -> Result<(), ContractError>; - fn track_reward(&self, amount: Coin, storage: &mut dyn Storage) -> Result<(), ContractError>; + ) -> Result<(), VestingContractError>; + fn track_reward( + &self, + amount: Coin, + storage: &mut dyn Storage, + ) -> Result<(), VestingContractError>; fn get_historical_vested_staking_rewards( &self, storage: &dyn Storage, - ) -> Result; + ) -> Result; } diff --git a/contracts/vesting/src/transactions.rs b/contracts/vesting/src/transactions.rs index bab50ec369..adbfe39436 100644 --- a/contracts/vesting/src/transactions.rs +++ b/contracts/vesting/src/transactions.rs @@ -2,14 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 use crate::contract::{ensure_staking_permission, validate_funds}; -use crate::errors::ContractError; use crate::storage::{ account_from_address, save_account, ADMIN, MIXNET_CONTRACT_ADDRESS, MIX_DENOM, }; use crate::traits::{ DelegatingAccount, GatewayBondingAccount, MixnodeBondingAccount, NodeFamilies, VestingAccount, }; -use crate::vesting::{populate_vesting_periods, Account}; +use crate::vesting::{populate_vesting_periods, StorableVestingAccountExt}; use contracts_common::signing::MessageSignature; use cosmwasm_std::{coin, BankMsg, Coin, DepsMut, Env, MessageInfo, Response, Timestamp}; use mixnet_contract_common::families::FamilyHead; @@ -22,14 +21,13 @@ use vesting_contract_common::events::{ new_track_mixnode_pledge_decrease_event, new_track_mixnode_unbond_event, new_track_reward_event, new_track_undelegation_event, new_vested_coins_withdraw_event, }; -use vesting_contract_common::messages::VestingSpecification; -use vesting_contract_common::PledgeCap; +use vesting_contract_common::{Account, PledgeCap, VestingContractError, VestingSpecification}; pub fn try_create_family( info: MessageInfo, deps: DepsMut, label: String, -) -> Result { +) -> Result { let account = account_from_address(info.sender.as_ref(), deps.storage, deps.api)?; account.try_create_family(deps.storage, label) } @@ -38,7 +36,7 @@ pub fn try_join_family( deps: DepsMut, join_permit: MessageSignature, family_head: FamilyHead, -) -> Result { +) -> Result { let account = account_from_address(info.sender.as_ref(), deps.storage, deps.api)?; account.try_join_family(deps.storage, join_permit, family_head) } @@ -46,7 +44,7 @@ pub fn try_leave_family( info: MessageInfo, deps: DepsMut, family_head: FamilyHead, -) -> Result { +) -> Result { let account = account_from_address(info.sender.as_ref(), deps.storage, deps.api)?; account.try_leave_family(deps.storage, family_head) } @@ -54,7 +52,7 @@ pub fn try_kick_family_member( info: MessageInfo, deps: DepsMut, member: String, -) -> Result { +) -> Result { let account = account_from_address(info.sender.as_ref(), deps.storage, deps.api)?; account.try_head_kick_member(deps.storage, &member) } @@ -67,9 +65,11 @@ pub fn try_update_locked_pledge_cap( cap: PledgeCap, info: MessageInfo, deps: DepsMut, -) -> Result { +) -> Result { if info.sender != ADMIN.load(deps.storage)? { - return Err(ContractError::NotAdmin(info.sender.as_str().to_string())); + return Err(VestingContractError::NotAdmin( + info.sender.as_str().to_string(), + )); } let mut account = account_from_address(&address, deps.storage, deps.api)?; @@ -83,7 +83,7 @@ pub fn try_update_mixnode_config( new_config: MixNodeConfigUpdate, info: MessageInfo, deps: DepsMut, -) -> Result { +) -> Result { let account = account_from_address(info.sender.as_str(), deps.storage, deps.api)?; account.try_update_mixnode_config(new_config, deps.storage) } @@ -92,7 +92,7 @@ pub fn try_update_gateway_config( new_config: GatewayConfigUpdate, info: MessageInfo, deps: DepsMut, -) -> Result { +) -> Result { let account = account_from_address(info.sender.as_str(), deps.storage, deps.api)?; account.try_update_gateway_config(new_config, deps.storage) } @@ -101,7 +101,7 @@ pub fn try_update_mixnode_cost_params( new_costs: MixNodeCostParams, info: MessageInfo, deps: DepsMut, -) -> Result { +) -> Result { let account = account_from_address(info.sender.as_str(), deps.storage, deps.api)?; account.try_update_mixnode_cost_params(new_costs, deps.storage) } @@ -113,9 +113,11 @@ pub fn try_update_mixnet_address( address: String, info: MessageInfo, deps: DepsMut<'_>, -) -> Result { +) -> Result { if info.sender != ADMIN.load(deps.storage)? { - return Err(ContractError::NotAdmin(info.sender.as_str().to_string())); + return Err(VestingContractError::NotAdmin( + info.sender.as_str().to_string(), + )); } let mixnet_contract_address = deps.api.addr_validate(&address)?; @@ -129,16 +131,18 @@ pub fn try_withdraw_vested_coins( env: Env, info: MessageInfo, deps: DepsMut<'_>, -) -> Result { +) -> Result { let mix_denom = MIX_DENOM.load(deps.storage)?; if amount.denom != mix_denom { - return Err(ContractError::WrongDenom(amount.denom, mix_denom)); + return Err(VestingContractError::WrongDenom(amount.denom, mix_denom)); } let address = info.sender; let account = account_from_address(address.as_str(), deps.storage, deps.api)?; if address != account.owner_address() { - return Err(ContractError::NotOwner(account.owner_address().to_string())); + return Err(VestingContractError::NotOwner( + account.owner_address().to_string(), + )); } let spendable_coins = account.spendable_coins(None, &env, deps.storage)?; if amount.amount <= spendable_coins.amount { @@ -157,7 +161,7 @@ pub fn try_withdraw_vested_coins( &coin(new_balance, &amount.denom), ))) } else { - Err(ContractError::InsufficientSpendable( + Err(VestingContractError::InsufficientSpendable( account.owner_address().as_str().to_string(), spendable_coins.amount.u128(), )) @@ -169,7 +173,7 @@ pub fn try_transfer_ownership( to_address: String, info: MessageInfo, deps: DepsMut<'_>, -) -> Result { +) -> Result { let address = info.sender; let to_address = deps.api.addr_validate(&to_address)?; let mut account = account_from_address(address.as_str(), deps.storage, deps.api)?; @@ -177,7 +181,9 @@ pub fn try_transfer_ownership( account.transfer_ownership(&to_address, deps.storage)?; Ok(Response::new().add_event(new_ownership_transfer_event(&address, &to_address))) } else { - Err(ContractError::NotOwner(account.owner_address().to_string())) + Err(VestingContractError::NotOwner( + account.owner_address().to_string(), + )) } } @@ -186,11 +192,13 @@ pub fn try_update_staking_address( to_address: Option, info: MessageInfo, deps: DepsMut<'_>, -) -> Result { +) -> Result { if let Some(ref to_address) = to_address { if account_from_address(to_address, deps.storage, deps.api).is_ok() { // do not allow setting staking address to an existing account's address - return Err(ContractError::StakingAccountExists(to_address.to_string())); + return Err(VestingContractError::StakingAccountExists( + to_address.to_string(), + )); } } @@ -202,7 +210,9 @@ pub fn try_update_staking_address( account.update_staking_address(to_address.clone(), deps.storage)?; Ok(Response::new().add_event(new_staking_address_update_event(&old, &to_address))) } else { - Err(ContractError::NotOwner(account.owner_address().to_string())) + Err(VestingContractError::NotOwner( + account.owner_address().to_string(), + )) } } @@ -214,7 +224,7 @@ pub fn try_bond_gateway( info: MessageInfo, env: Env, deps: DepsMut<'_>, -) -> Result { +) -> Result { let mix_denom = MIX_DENOM.load(deps.storage)?; let pledge = validate_funds(&[amount], mix_denom)?; let account = account_from_address(info.sender.as_str(), deps.storage, deps.api)?; @@ -222,7 +232,10 @@ pub fn try_bond_gateway( } /// Unbond a gateway, sends [mixnet_contract_common::ExecuteMsg::UnbondGatewayOnBehalf] to [crate::storage::MIXNET_CONTRACT_ADDRESS]. -pub fn try_unbond_gateway(info: MessageInfo, deps: DepsMut<'_>) -> Result { +pub fn try_unbond_gateway( + info: MessageInfo, + deps: DepsMut<'_>, +) -> Result { let account = account_from_address(info.sender.as_str(), deps.storage, deps.api)?; account.try_unbond_gateway(deps.storage) } @@ -233,9 +246,9 @@ pub fn try_track_unbond_gateway( amount: Coin, info: MessageInfo, deps: DepsMut<'_>, -) -> Result { +) -> Result { if info.sender != MIXNET_CONTRACT_ADDRESS.load(deps.storage)? { - return Err(ContractError::NotMixnetContract(info.sender)); + return Err(VestingContractError::NotMixnetContract(info.sender)); } let account = account_from_address(owner, deps.storage, deps.api)?; account.try_track_unbond_gateway(amount, deps.storage)?; @@ -251,7 +264,7 @@ pub fn try_bond_mixnode( info: MessageInfo, env: Env, deps: DepsMut<'_>, -) -> Result { +) -> Result { let mix_denom = MIX_DENOM.load(deps.storage)?; let pledge = validate_funds(&[amount], mix_denom)?; let account = account_from_address(info.sender.as_str(), deps.storage, deps.api)?; @@ -270,7 +283,7 @@ pub fn try_pledge_more( env: Env, info: MessageInfo, amount: Coin, -) -> Result { +) -> Result { let mix_denom = MIX_DENOM.load(deps.storage)?; let additional_pledge = validate_funds(&[amount], mix_denom)?; @@ -282,7 +295,7 @@ pub fn try_decrease_pledge( deps: DepsMut<'_>, info: MessageInfo, amount: Coin, -) -> Result { +) -> Result { let mix_denom = MIX_DENOM.load(deps.storage)?; // perform basic validation - is it correct demon, is it non-zero, etc. let decrease = validate_funds(&[amount], mix_denom)?; @@ -292,7 +305,10 @@ pub fn try_decrease_pledge( } /// Unbond a mixnode, sends [mixnet_contract_common::ExecuteMsg::UnbondMixnodeOnBehalf] to [crate::storage::MIXNET_CONTRACT_ADDRESS]. -pub fn try_unbond_mixnode(info: MessageInfo, deps: DepsMut<'_>) -> Result { +pub fn try_unbond_mixnode( + info: MessageInfo, + deps: DepsMut<'_>, +) -> Result { let account = account_from_address(info.sender.as_str(), deps.storage, deps.api)?; account.try_unbond_mixnode(deps.storage) } @@ -303,9 +319,9 @@ pub fn try_track_unbond_mixnode( amount: Coin, info: MessageInfo, deps: DepsMut<'_>, -) -> Result { +) -> Result { if info.sender != MIXNET_CONTRACT_ADDRESS.load(deps.storage)? { - return Err(ContractError::NotMixnetContract(info.sender)); + return Err(VestingContractError::NotMixnetContract(info.sender)); } let account = account_from_address(owner, deps.storage, deps.api)?; account.try_track_unbond_mixnode(amount, deps.storage)?; @@ -319,9 +335,9 @@ pub fn try_track_decrease_mixnode_pledge( amount: Coin, info: MessageInfo, deps: DepsMut<'_>, -) -> Result { +) -> Result { if info.sender != MIXNET_CONTRACT_ADDRESS.load(deps.storage)? { - return Err(ContractError::NotMixnetContract(info.sender)); + return Err(VestingContractError::NotMixnetContract(info.sender)); } let account = account_from_address(owner, deps.storage, deps.api)?; account.try_track_decrease_mixnode_pledge(amount, deps.storage)?; @@ -334,9 +350,9 @@ pub fn try_track_reward( info: MessageInfo, amount: Coin, address: &str, -) -> Result { +) -> Result { if info.sender != MIXNET_CONTRACT_ADDRESS.load(deps.storage)? { - return Err(ContractError::NotMixnetContract(info.sender)); + return Err(VestingContractError::NotMixnetContract(info.sender)); } let account = account_from_address(address, deps.storage, deps.api)?; account.track_reward(amount, deps.storage)?; @@ -350,9 +366,9 @@ pub fn try_track_undelegation( amount: Coin, info: MessageInfo, deps: DepsMut<'_>, -) -> Result { +) -> Result { if info.sender != MIXNET_CONTRACT_ADDRESS.load(deps.storage)? { - return Err(ContractError::NotMixnetContract(info.sender)); + return Err(VestingContractError::NotMixnetContract(info.sender)); } let account = account_from_address(address, deps.storage, deps.api)?; @@ -368,7 +384,7 @@ pub fn try_delegate_to_mixnode( info: MessageInfo, env: Env, deps: DepsMut<'_>, -) -> Result { +) -> Result { // TODO // as of 01.02.23 // thus restricting it to 25, which is more than double of that, doesn't seem too unreasonable. @@ -397,7 +413,7 @@ pub fn try_delegate_to_mixnode( pub fn try_claim_operator_reward( deps: DepsMut<'_>, info: MessageInfo, -) -> Result { +) -> Result { let account = account_from_address(info.sender.as_str(), deps.storage, deps.api)?; account.try_claim_operator_reward(deps.storage) } @@ -407,7 +423,7 @@ pub fn try_claim_delegator_reward( deps: DepsMut<'_>, info: MessageInfo, mix_id: MixId, -) -> Result { +) -> Result { let account = account_from_address(info.sender.as_str(), deps.storage, deps.api)?; account.try_claim_delegator_reward(mix_id, deps.storage) @@ -419,7 +435,7 @@ pub fn try_undelegate_from_mixnode( on_behalf_of: Option, info: MessageInfo, deps: DepsMut<'_>, -) -> Result { +) -> Result { let account = match on_behalf_of { Some(account_owner) => { let account = account_from_address(&account_owner, deps.storage, deps.api)?; @@ -444,16 +460,18 @@ pub fn try_create_periodic_vesting_account( info: MessageInfo, env: Env, deps: DepsMut<'_>, -) -> Result { +) -> Result { if info.sender != ADMIN.load(deps.storage)? { - return Err(ContractError::NotAdmin(info.sender.as_str().to_string())); + return Err(VestingContractError::NotAdmin( + info.sender.as_str().to_string(), + )); } let mix_denom = MIX_DENOM.load(deps.storage)?; let account_exists = account_from_address(owner_address, deps.storage, deps.api).is_ok(); if account_exists { - return Err(ContractError::AccountAlreadyExists( + return Err(VestingContractError::AccountAlreadyExists( owner_address.to_string(), )); } @@ -467,7 +485,9 @@ pub fn try_create_periodic_vesting_account( let staking_account_exists = account_from_address(&staking_address, deps.storage, deps.api).is_ok(); if staking_account_exists { - return Err(ContractError::StakingAccountAlreadyExists(staking_address)); + return Err(VestingContractError::StakingAccountAlreadyExists( + staking_address, + )); } Some(deps.api.addr_validate(&staking_address)?) } else { @@ -483,7 +503,7 @@ pub fn try_create_periodic_vesting_account( let response = Response::new(); - Account::new( + Account::save_new( owner_address.clone(), staking_address.clone(), coin.clone(), diff --git a/contracts/vesting/src/vesting/account/delegating_account.rs b/contracts/vesting/src/vesting/account/delegating_account.rs index beaedf2be2..0371bc7cc3 100644 --- a/contracts/vesting/src/vesting/account/delegating_account.rs +++ b/contracts/vesting/src/vesting/account/delegating_account.rs @@ -1,14 +1,15 @@ use crate::contract::MAX_PER_MIX_DELEGATIONS; -use crate::errors::ContractError; use crate::storage::save_delegation; use crate::storage::MIXNET_CONTRACT_ADDRESS; use crate::traits::DelegatingAccount; +use crate::vesting::account::StorableVestingAccountExt; use cosmwasm_std::{wasm_execute, Coin, Env, Response, Storage, Uint128}; use mixnet_contract_common::ExecuteMsg as MixnetExecuteMsg; use mixnet_contract_common::MixId; use vesting_contract_common::events::{ new_vesting_delegation_event, new_vesting_undelegation_event, }; +use vesting_contract_common::VestingContractError; use super::Account; @@ -17,7 +18,7 @@ impl DelegatingAccount for Account { &self, mix_id: MixId, storage: &dyn Storage, - ) -> Result { + ) -> Result { let msg = MixnetExecuteMsg::WithdrawDelegatorRewardOnBehalf { owner: self.owner_address().to_string(), mix_id, @@ -35,12 +36,12 @@ impl DelegatingAccount for Account { coin: Coin, env: &Env, storage: &mut dyn Storage, - ) -> Result { + ) -> Result { let current_balance = self.ensure_valid_additional_stake(&coin, storage)?; let num_subdelegations = self.num_subdelegations_for_mix(mix_id, storage); if num_subdelegations >= MAX_PER_MIX_DELEGATIONS { - return Err(ContractError::TooManyDelegations { + return Err(VestingContractError::TooManyDelegations { address: self.owner_address.clone(), acc_id: self.storage_key(), mix_id, @@ -75,9 +76,9 @@ impl DelegatingAccount for Account { &self, mix_id: MixId, storage: &dyn Storage, - ) -> Result { + ) -> Result { if !self.any_delegation_for_mix(mix_id, storage) { - return Err(ContractError::NoSuchDelegation( + return Err(VestingContractError::NoSuchDelegation( self.owner_address(), mix_id, )); @@ -102,7 +103,7 @@ impl DelegatingAccount for Account { current_balance: Uint128, delegation: Coin, storage: &mut dyn Storage, - ) -> Result<(), ContractError> { + ) -> Result<(), VestingContractError> { save_delegation( (self.storage_key(), mix_id, block_timestamp_secs), delegation.amount, @@ -118,7 +119,7 @@ impl DelegatingAccount for Account { mix_id: MixId, amount: Coin, storage: &mut dyn Storage, - ) -> Result<(), ContractError> { + ) -> Result<(), VestingContractError> { self.remove_delegations_for_mix(mix_id, storage)?; let new_balance = Uint128::new(self.load_balance(storage)?.u128() + amount.amount.u128()); self.save_balance(new_balance, storage)?; diff --git a/contracts/vesting/src/vesting/account/gateway_bonding_account.rs b/contracts/vesting/src/vesting/account/gateway_bonding_account.rs index 12910acbcc..e63b0d1d09 100644 --- a/contracts/vesting/src/vesting/account/gateway_bonding_account.rs +++ b/contracts/vesting/src/vesting/account/gateway_bonding_account.rs @@ -1,7 +1,7 @@ use super::PledgeData; -use crate::errors::ContractError; use crate::storage::MIXNET_CONTRACT_ADDRESS; use crate::traits::GatewayBondingAccount; +use crate::vesting::account::StorableVestingAccountExt; use contracts_common::signing::MessageSignature; use cosmwasm_std::{wasm_execute, Coin, Env, Response, Storage, Uint128}; use mixnet_contract_common::{ @@ -11,6 +11,7 @@ use vesting_contract_common::events::{ new_vesting_gateway_bonding_event, new_vesting_gateway_unbonding_event, new_vesting_update_gateway_config_event, }; +use vesting_contract_common::VestingContractError; use super::Account; @@ -22,11 +23,11 @@ impl GatewayBondingAccount for Account { pledge: Coin, env: &Env, storage: &mut dyn Storage, - ) -> Result { + ) -> Result { let current_balance = self.ensure_valid_additional_stake(&pledge, storage)?; let pledge_data = if self.load_gateway_pledge(storage)?.is_some() { - return Err(ContractError::AlreadyBonded( + return Err(VestingContractError::AlreadyBonded( self.owner_address().as_str().to_string(), )); } else { @@ -52,7 +53,7 @@ impl GatewayBondingAccount for Account { .add_event(new_vesting_gateway_bonding_event())) } - fn try_unbond_gateway(&self, storage: &dyn Storage) -> Result { + fn try_unbond_gateway(&self, storage: &dyn Storage) -> Result { let msg = MixnetExecuteMsg::UnbondGatewayOnBehalf { owner: self.owner_address().into_string(), }; @@ -64,7 +65,7 @@ impl GatewayBondingAccount for Account { .add_message(unbond_msg) .add_event(new_vesting_gateway_unbonding_event())) } else { - Err(ContractError::NoBondFound( + Err(VestingContractError::NoBondFound( self.owner_address().as_str().to_string(), )) } @@ -74,7 +75,7 @@ impl GatewayBondingAccount for Account { &self, amount: Coin, storage: &mut dyn Storage, - ) -> Result<(), ContractError> { + ) -> Result<(), VestingContractError> { let new_balance = Uint128::new(self.load_balance(storage)?.u128() + amount.amount.u128()); self.save_balance(new_balance, storage)?; @@ -86,7 +87,7 @@ impl GatewayBondingAccount for Account { &self, new_config: GatewayConfigUpdate, storage: &mut dyn Storage, - ) -> Result { + ) -> Result { let msg = MixnetExecuteMsg::UpdateGatewayConfigOnBehalf { new_config, owner: self.owner_address().into_string(), diff --git a/contracts/vesting/src/vesting/account/mixnode_bonding_account.rs b/contracts/vesting/src/vesting/account/mixnode_bonding_account.rs index 6986ac8793..29ee780ff9 100644 --- a/contracts/vesting/src/vesting/account/mixnode_bonding_account.rs +++ b/contracts/vesting/src/vesting/account/mixnode_bonding_account.rs @@ -2,9 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 use super::Account; -use crate::errors::ContractError; use crate::storage::MIXNET_CONTRACT_ADDRESS; use crate::traits::MixnodeBondingAccount; +use crate::vesting::account::StorableVestingAccountExt; use contracts_common::signing::MessageSignature; use cosmwasm_std::{wasm_execute, Coin, Env, Response, Storage, Uint128}; use mixnet_contract_common::mixnode::MixNodeConfigUpdate; @@ -15,10 +15,13 @@ use vesting_contract_common::events::{ new_vesting_mixnode_unbonding_event, new_vesting_pledge_more_event, new_vesting_update_mixnode_config_event, new_vesting_update_mixnode_cost_params_event, }; -use vesting_contract_common::PledgeData; +use vesting_contract_common::{PledgeData, VestingContractError}; impl MixnodeBondingAccount for Account { - fn try_claim_operator_reward(&self, storage: &dyn Storage) -> Result { + fn try_claim_operator_reward( + &self, + storage: &dyn Storage, + ) -> Result { let msg = MixnetExecuteMsg::WithdrawOperatorRewardOnBehalf { owner: self.owner_address().into_string(), }; @@ -37,11 +40,11 @@ impl MixnodeBondingAccount for Account { pledge: Coin, env: &Env, storage: &mut dyn Storage, - ) -> Result { + ) -> Result { let current_balance = self.ensure_valid_additional_stake(&pledge, storage)?; let pledge_data = if self.load_mixnode_pledge(storage)?.is_some() { - return Err(ContractError::AlreadyBonded( + return Err(VestingContractError::AlreadyBonded( self.owner_address().as_str().to_string(), )); } else { @@ -73,13 +76,13 @@ impl MixnodeBondingAccount for Account { additional_pledge: Coin, env: &Env, storage: &mut dyn Storage, - ) -> Result { + ) -> Result { let current_balance = self.ensure_valid_additional_stake(&additional_pledge, storage)?; let mut pledge_data = if let Some(pledge_data) = self.load_mixnode_pledge(storage)? { pledge_data } else { - return Err(ContractError::NoBondFound( + return Err(VestingContractError::NoBondFound( self.owner_address().as_str().to_string(), )); }; @@ -113,18 +116,18 @@ impl MixnodeBondingAccount for Account { &self, amount: Coin, storage: &mut dyn Storage, - ) -> Result { + ) -> Result { match self.load_mixnode_pledge(storage)? { Some(pledge) => { if pledge.amount.amount <= amount.amount { - return Err(ContractError::InvalidBondPledgeReduction { + return Err(VestingContractError::InvalidBondPledgeReduction { current: pledge.amount, decrease_by: amount, }); } } None => { - return Err(ContractError::NoBondFound( + return Err(VestingContractError::NoBondFound( self.owner_address().as_str().to_string(), )); } @@ -147,14 +150,14 @@ impl MixnodeBondingAccount for Account { &self, amount: Coin, storage: &mut dyn Storage, - ) -> Result<(), ContractError> { + ) -> Result<(), VestingContractError> { let new_balance = Uint128::new(self.load_balance(storage)?.u128() + amount.amount.u128()); self.save_balance(new_balance, storage)?; self.decrease_mixnode_pledge(amount, storage) } - fn try_unbond_mixnode(&self, storage: &dyn Storage) -> Result { + fn try_unbond_mixnode(&self, storage: &dyn Storage) -> Result { let msg = MixnetExecuteMsg::UnbondMixnodeOnBehalf { owner: self.owner_address().into_string(), }; @@ -166,7 +169,7 @@ impl MixnodeBondingAccount for Account { .add_message(unbond_msg) .add_event(new_vesting_mixnode_unbonding_event())) } else { - Err(ContractError::NoBondFound( + Err(VestingContractError::NoBondFound( self.owner_address().as_str().to_string(), )) } @@ -176,7 +179,7 @@ impl MixnodeBondingAccount for Account { &self, amount: Coin, storage: &mut dyn Storage, - ) -> Result<(), ContractError> { + ) -> Result<(), VestingContractError> { let new_balance = Uint128::new(self.load_balance(storage)?.u128() + amount.amount.u128()); self.save_balance(new_balance, storage)?; @@ -187,7 +190,7 @@ impl MixnodeBondingAccount for Account { &self, new_config: MixNodeConfigUpdate, storage: &mut dyn Storage, - ) -> Result { + ) -> Result { let msg = MixnetExecuteMsg::UpdateMixnodeConfigOnBehalf { new_config, owner: self.owner_address().into_string(), @@ -205,7 +208,7 @@ impl MixnodeBondingAccount for Account { &self, new_costs: MixNodeCostParams, storage: &mut dyn Storage, - ) -> Result { + ) -> Result { let msg = MixnetExecuteMsg::UpdateMixnodeCostParamsOnBehalf { new_costs, owner: self.owner_address().into_string(), diff --git a/contracts/vesting/src/vesting/account/mod.rs b/contracts/vesting/src/vesting/account/mod.rs index e59f27d1a2..7d016fd130 100644 --- a/contracts/vesting/src/vesting/account/mod.rs +++ b/contracts/vesting/src/vesting/account/mod.rs @@ -1,17 +1,18 @@ +// Copyright 2021-2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + use super::VestingPeriod; -use crate::errors::ContractError; use crate::storage::{ count_subdelegations_for_mix, decrease_bond_pledge, load_balance, load_bond_pledge, load_delegation_timestamps, load_gateway_pledge, load_withdrawn, remove_bond_pledge, remove_delegation, remove_gateway_pledge, save_account, save_balance, save_bond_pledge, - save_gateway_pledge, save_withdrawn, AccountStorageKey, BlockTimestampSecs, DELEGATIONS, KEY, + save_gateway_pledge, save_withdrawn, BlockTimestampSecs, DELEGATIONS, KEY, }; use crate::traits::VestingAccount; use cosmwasm_std::{Addr, Coin, Order, Storage, Timestamp, Uint128}; use mixnet_contract_common::MixId; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; -use vesting_contract_common::{Period, PledgeCap, PledgeData}; +use vesting_contract_common::account::VestingAccountStorageKey; +use vesting_contract_common::{Account, PledgeCap, PledgeData, VestingContractError}; mod delegating_account; mod gateway_bonding_account; @@ -19,26 +20,17 @@ mod mixnode_bonding_account; mod node_families; mod vesting_account; -fn generate_storage_key(storage: &mut dyn Storage) -> Result { +fn generate_storage_key( + storage: &mut dyn Storage, +) -> Result { let key = KEY.may_load(storage)?.unwrap_or(0) + 1; KEY.save(storage, &key)?; Ok(key) } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub struct Account { - pub owner_address: Addr, - pub staking_address: Option, - pub start_time: Timestamp, - pub periods: Vec, - pub coin: Coin, - storage_key: AccountStorageKey, - #[serde(default)] - pub pledge_cap: Option, -} - -impl Account { - pub fn new( +/// Helper trait to extend the `Account` type with methods that require access to the underlying storage +pub(crate) trait StorableVestingAccountExt: VestingAccount { + fn save_new( owner_address: Addr, staking_address: Option, coin: Coin, @@ -46,7 +38,7 @@ impl Account { periods: Vec, pledge_cap: Option, storage: &mut dyn Storage, - ) -> Result { + ) -> Result { let storage_key = generate_storage_key(storage)?; let amount = coin.amount; let account = Account { @@ -63,29 +55,31 @@ impl Account { Ok(account) } + fn owner_address(&self) -> Addr; + /// Checks whether the additional stake would be within the cap associated with the account /// and whether the account has enough tokens for staking. /// Returns the value of the current balance of the account. - pub fn ensure_valid_additional_stake( + fn ensure_valid_additional_stake( &self, additional_stake: &Coin, storage: &dyn Storage, - ) -> Result { + ) -> Result { let current_balance = self.load_balance(storage)?; let current_total_staked = self.total_staked(storage)?; let total_staked_after = current_total_staked + additional_stake.amount; let locked_pledge_cap = self.absolute_pledge_cap()?; if locked_pledge_cap < total_staked_after { - return Err(ContractError::LockedPledgeCapReached { + return Err(VestingContractError::LockedPledgeCapReached { current: total_staked_after, cap: locked_pledge_cap, }); } if current_balance < additional_stake.amount { - return Err(ContractError::InsufficientBalance( - self.owner_address().as_str().to_string(), + return Err(VestingContractError::InsufficientBalance( + self.owner_address().into_string(), current_balance.u128(), )); } @@ -93,107 +87,13 @@ impl Account { Ok(current_balance) } - pub fn pledge_cap(&self) -> PledgeCap { - self.pledge_cap.clone().unwrap_or_default() - } + fn absolute_pledge_cap(&self) -> Result; - pub fn absolute_pledge_cap(&self) -> Result { - match self.pledge_cap() { - PledgeCap::Absolute(cap) => Ok(cap), - PledgeCap::Percent(p) => Ok(p * self.get_original_vesting()?.amount.amount), - } - } - - pub fn coin(&self) -> Coin { - self.coin.clone() - } - - pub fn num_vesting_periods(&self) -> usize { - self.periods.len() - } - - pub fn period_duration(&self) -> Result { - self.periods - .get(0) - .ok_or(ContractError::UnpopulatedVestingPeriods { - owner: self.owner_address.clone(), - }) - .map(|p| p.period_seconds) - } - - pub fn storage_key(&self) -> u32 { - self.storage_key - } - - pub fn owner_address(&self) -> Addr { - self.owner_address.clone() - } - - pub fn staking_address(&self) -> Option<&Addr> { - self.staking_address.as_ref() - } - - #[allow(dead_code)] - pub fn periods(&self) -> Vec { - self.periods.clone() - } - - #[allow(dead_code)] - pub fn start_time(&self) -> Timestamp { - self.start_time - } - - pub fn tokens_per_period(&self) -> Result { - let amount = self.coin.amount.u128(); - if amount < self.num_vesting_periods() as u128 { - Err(ContractError::ImprobableVestingAmount(amount)) - } else { - // Remainder tokens will be lumped into the last period. - Ok(amount / self.num_vesting_periods() as u128) - } - } - - /// Returns the index of the next vesting period. Unless the current time is somehow in the past or vesting has not started yet. - /// In case vesting is over it will always return NUM_VESTING_PERIODS. - pub fn get_current_vesting_period( - &self, - block_time: Timestamp, - ) -> Result { - let first_period = - self.periods - .first() - .ok_or(ContractError::UnpopulatedVestingPeriods { - owner: self.owner_address.clone(), - })?; - - let last_period = self - .periods - .last() - .ok_or(ContractError::UnpopulatedVestingPeriods { - owner: self.owner_address.clone(), - })?; - - if block_time.seconds() < first_period.start_time { - Ok(Period::Before) - } else if last_period.end_time() < block_time { - Ok(Period::After) - } else { - let mut index = 0; - for period in &self.periods { - if block_time < period.end_time() { - break; - } - index += 1; - } - Ok(Period::In(index)) - } - } - - pub fn withdraw( + fn withdraw( &self, amount: &Coin, storage: &mut dyn Storage, - ) -> Result { + ) -> Result { let new_balance = self .load_balance(storage)? .u128() @@ -204,127 +104,73 @@ impl Account { Ok(new_balance) } - pub fn load_withdrawn(&self, storage: &dyn Storage) -> Result { - load_withdrawn(self.storage_key, storage) - } + fn load_withdrawn(&self, storage: &dyn Storage) -> Result; - pub fn save_withdrawn( + fn save_withdrawn( &self, withdrawn: Uint128, storage: &mut dyn Storage, - ) -> Result<(), ContractError> { - save_withdrawn(self.storage_key, withdrawn, storage) - } + ) -> Result<(), VestingContractError>; - pub fn load_balance(&self, storage: &dyn Storage) -> Result { - load_balance(self.storage_key(), storage) - } + fn load_balance(&self, storage: &dyn Storage) -> Result; - pub fn save_balance( + fn save_balance( &self, amount: Uint128, storage: &mut dyn Storage, - ) -> Result<(), ContractError> { - save_balance(self.storage_key(), amount, storage) - } + ) -> Result<(), VestingContractError>; - pub fn load_mixnode_pledge( + fn load_mixnode_pledge( &self, storage: &dyn Storage, - ) -> Result, ContractError> { - load_bond_pledge(self.storage_key(), storage) - } + ) -> Result, VestingContractError>; - pub fn save_mixnode_pledge( + fn save_mixnode_pledge( &self, pledge: PledgeData, storage: &mut dyn Storage, - ) -> Result<(), ContractError> { - save_bond_pledge(self.storage_key(), &pledge, storage) - } + ) -> Result<(), VestingContractError>; - pub fn remove_mixnode_pledge(&self, storage: &mut dyn Storage) -> Result<(), ContractError> { - remove_bond_pledge(self.storage_key(), storage) - } + fn remove_mixnode_pledge(&self, storage: &mut dyn Storage) -> Result<(), VestingContractError>; - pub fn decrease_mixnode_pledge( + fn decrease_mixnode_pledge( &self, amount: Coin, storage: &mut dyn Storage, - ) -> Result<(), ContractError> { - decrease_bond_pledge(self.storage_key, amount, storage) - } + ) -> Result<(), VestingContractError>; - pub fn load_gateway_pledge( + fn load_gateway_pledge( &self, storage: &dyn Storage, - ) -> Result, ContractError> { - load_gateway_pledge(self.storage_key(), storage) - } + ) -> Result, VestingContractError>; - pub fn save_gateway_pledge( + fn save_gateway_pledge( &self, pledge: PledgeData, storage: &mut dyn Storage, - ) -> Result<(), ContractError> { - save_gateway_pledge(self.storage_key(), &pledge, storage) - } + ) -> Result<(), VestingContractError>; - pub fn remove_gateway_pledge(&self, storage: &mut dyn Storage) -> Result<(), ContractError> { - remove_gateway_pledge(self.storage_key(), storage) - } + fn remove_gateway_pledge(&self, storage: &mut dyn Storage) -> Result<(), VestingContractError>; - pub fn any_delegation_for_mix(&self, mix_id: MixId, storage: &dyn Storage) -> bool { - DELEGATIONS - .prefix((self.storage_key(), mix_id)) - .range(storage, None, None, Order::Ascending) - .next() - .is_some() - } + fn any_delegation_for_mix(&self, mix_id: MixId, storage: &dyn Storage) -> bool; - pub fn num_subdelegations_for_mix(&self, mix_id: MixId, storage: &dyn Storage) -> u32 { - count_subdelegations_for_mix((self.storage_key(), mix_id), storage) - } + fn num_subdelegations_for_mix(&self, mix_id: MixId, storage: &dyn Storage) -> u32; - pub fn remove_delegations_for_mix( + fn remove_delegations_for_mix( &self, mix_id: MixId, storage: &mut dyn Storage, - ) -> Result<(), ContractError> { - // note that the limit is implicitly set to `MAX_PER_MIX_DELEGATIONS` - // as it should be impossible to create more delegations than that. - let block_timestamps = load_delegation_timestamps((self.storage_key(), mix_id), storage)?; + ) -> Result<(), VestingContractError>; - for block_timestamp in block_timestamps { - remove_delegation((self.storage_key(), mix_id, block_timestamp), storage)?; - } - Ok(()) - } - - pub fn total_delegations_for_mix( + fn total_delegations_for_mix( &self, mix_id: MixId, storage: &dyn Storage, - ) -> Result { - Ok(DELEGATIONS - .prefix((self.storage_key(), mix_id)) - .range(storage, None, None, Order::Ascending) - .filter_map(|x| x.ok()) - .fold(Uint128::zero(), |acc, (_key, val)| acc + val)) - } + ) -> Result; - // TODO: this should get reworked... somehow... (maybe with a memoized value?) - // as it's an unbounded iteration that could fail if an account has made a lot of delegations - // (I guess in order of thousands) - pub fn total_delegations(&self, storage: &dyn Storage) -> Result { - Ok(DELEGATIONS - .sub_prefix(self.storage_key()) - .range(storage, None, None, Order::Ascending) - .filter_map(|x| x.ok()) - .fold(Uint128::zero(), |acc, (_key, val)| acc + val)) - } + fn total_delegations(&self, storage: &dyn Storage) -> Result; - pub fn total_pledged(&self, storage: &dyn Storage) -> Result { + fn total_pledged(&self, storage: &dyn Storage) -> Result { let amount = if let Some(bond) = self .load_mixnode_pledge(storage)? .or(self.load_gateway_pledge(storage)?) @@ -336,11 +182,147 @@ impl Account { Ok(amount) } - pub fn total_delegations_at_timestamp( + fn total_delegations_at_timestamp( &self, storage: &dyn Storage, start_time: BlockTimestampSecs, - ) -> Result { + ) -> Result; +} + +impl StorableVestingAccountExt for Account { + fn owner_address(&self) -> Addr { + self.owner_address.clone() + } + + fn absolute_pledge_cap(&self) -> Result { + match self.pledge_cap() { + PledgeCap::Absolute(cap) => Ok(cap), + PledgeCap::Percent(p) => Ok(p * self.get_original_vesting()?.amount.amount), + } + } + + fn load_withdrawn(&self, storage: &dyn Storage) -> Result { + load_withdrawn(self.storage_key, storage) + } + + fn save_withdrawn( + &self, + withdrawn: Uint128, + storage: &mut dyn Storage, + ) -> Result<(), VestingContractError> { + save_withdrawn(self.storage_key, withdrawn, storage) + } + + fn load_balance(&self, storage: &dyn Storage) -> Result { + load_balance(self.storage_key(), storage) + } + + fn save_balance( + &self, + amount: Uint128, + storage: &mut dyn Storage, + ) -> Result<(), VestingContractError> { + save_balance(self.storage_key(), amount, storage) + } + + fn load_mixnode_pledge( + &self, + storage: &dyn Storage, + ) -> Result, VestingContractError> { + load_bond_pledge(self.storage_key(), storage) + } + + fn save_mixnode_pledge( + &self, + pledge: PledgeData, + storage: &mut dyn Storage, + ) -> Result<(), VestingContractError> { + save_bond_pledge(self.storage_key(), &pledge, storage) + } + + fn remove_mixnode_pledge(&self, storage: &mut dyn Storage) -> Result<(), VestingContractError> { + remove_bond_pledge(self.storage_key(), storage) + } + + fn decrease_mixnode_pledge( + &self, + amount: Coin, + storage: &mut dyn Storage, + ) -> Result<(), VestingContractError> { + decrease_bond_pledge(self.storage_key(), amount, storage) + } + + fn load_gateway_pledge( + &self, + storage: &dyn Storage, + ) -> Result, VestingContractError> { + load_gateway_pledge(self.storage_key(), storage) + } + + fn save_gateway_pledge( + &self, + pledge: PledgeData, + storage: &mut dyn Storage, + ) -> Result<(), VestingContractError> { + save_gateway_pledge(self.storage_key(), &pledge, storage) + } + + fn remove_gateway_pledge(&self, storage: &mut dyn Storage) -> Result<(), VestingContractError> { + remove_gateway_pledge(self.storage_key(), storage) + } + + fn any_delegation_for_mix(&self, mix_id: MixId, storage: &dyn Storage) -> bool { + DELEGATIONS + .prefix((self.storage_key(), mix_id)) + .range(storage, None, None, Order::Ascending) + .next() + .is_some() + } + + fn num_subdelegations_for_mix(&self, mix_id: MixId, storage: &dyn Storage) -> u32 { + count_subdelegations_for_mix((self.storage_key(), mix_id), storage) + } + + fn remove_delegations_for_mix( + &self, + mix_id: MixId, + storage: &mut dyn Storage, + ) -> Result<(), VestingContractError> { + // note that the limit is implicitly set to `MAX_PER_MIX_DELEGATIONS` + // as it should be impossible to create more delegations than that. + let block_timestamps = load_delegation_timestamps((self.storage_key(), mix_id), storage)?; + + for block_timestamp in block_timestamps { + remove_delegation((self.storage_key(), mix_id, block_timestamp), storage)?; + } + Ok(()) + } + + fn total_delegations_for_mix( + &self, + mix_id: MixId, + storage: &dyn Storage, + ) -> Result { + Ok(DELEGATIONS + .prefix((self.storage_key(), mix_id)) + .range(storage, None, None, Order::Ascending) + .filter_map(|x| x.ok()) + .fold(Uint128::zero(), |acc, (_key, val)| acc + val)) + } + + fn total_delegations(&self, storage: &dyn Storage) -> Result { + Ok(DELEGATIONS + .sub_prefix(self.storage_key()) + .range(storage, None, None, Order::Ascending) + .filter_map(|x| x.ok()) + .fold(Uint128::zero(), |acc, (_key, val)| acc + val)) + } + + fn total_delegations_at_timestamp( + &self, + storage: &dyn Storage, + start_time: BlockTimestampSecs, + ) -> Result { Ok(DELEGATIONS .sub_prefix(self.storage_key()) .range(storage, None, None, Order::Ascending) diff --git a/contracts/vesting/src/vesting/account/node_families.rs b/contracts/vesting/src/vesting/account/node_families.rs index 2d6c4ce436..649531688b 100644 --- a/contracts/vesting/src/vesting/account/node_families.rs +++ b/contracts/vesting/src/vesting/account/node_families.rs @@ -1,16 +1,17 @@ use super::Account; -use crate::{errors::ContractError, storage::MIXNET_CONTRACT_ADDRESS, traits::NodeFamilies}; +use crate::{storage::MIXNET_CONTRACT_ADDRESS, traits::NodeFamilies}; use contracts_common::signing::MessageSignature; use cosmwasm_std::{wasm_execute, Response, Storage}; use mixnet_contract_common::families::FamilyHead; use mixnet_contract_common::{ExecuteMsg as MixnetExecuteMsg, IdentityKeyRef}; +use vesting_contract_common::VestingContractError; impl NodeFamilies for Account { fn try_create_family( &self, storage: &dyn Storage, label: String, - ) -> Result { + ) -> Result { let msg = MixnetExecuteMsg::CreateFamilyOnBehalf { owner_address: self.owner_address().into_string(), label, @@ -26,7 +27,7 @@ impl NodeFamilies for Account { storage: &dyn Storage, join_permit: MessageSignature, family_head: FamilyHead, - ) -> Result { + ) -> Result { let msg = MixnetExecuteMsg::JoinFamilyOnBehalf { member_address: self.owner_address().to_string(), join_permit, @@ -42,7 +43,7 @@ impl NodeFamilies for Account { &self, storage: &dyn Storage, family_head: FamilyHead, - ) -> Result { + ) -> Result { let msg = MixnetExecuteMsg::LeaveFamilyOnBehalf { member_address: self.owner_address().to_string(), family_head, @@ -57,7 +58,7 @@ impl NodeFamilies for Account { &self, storage: &dyn Storage, member: IdentityKeyRef<'_>, - ) -> Result { + ) -> Result { let msg = MixnetExecuteMsg::KickFamilyMemberOnBehalf { head_address: self.owner_address().to_string(), member: member.to_string(), diff --git a/contracts/vesting/src/vesting/account/vesting_account.rs b/contracts/vesting/src/vesting/account/vesting_account.rs index 5b64b9896e..1cb51aae19 100644 --- a/contracts/vesting/src/vesting/account/vesting_account.rs +++ b/contracts/vesting/src/vesting/account/vesting_account.rs @@ -1,14 +1,14 @@ -use crate::errors::ContractError; use crate::storage::{delete_account, save_account, MIX_DENOM}; use crate::traits::VestingAccount; +use crate::vesting::account::StorableVestingAccountExt; use cosmwasm_std::{Addr, Coin, Env, Storage, Timestamp, Uint128}; use std::cmp::min; -use vesting_contract_common::{OriginalVestingResponse, Period}; +use vesting_contract_common::{OriginalVestingResponse, Period, VestingContractError}; use super::Account; impl VestingAccount for Account { - fn total_staked(&self, storage: &dyn Storage) -> Result { + fn total_staked(&self, storage: &dyn Storage) -> Result { Ok(self.total_delegations(storage)? + self.total_pledged(storage)?) } @@ -21,7 +21,7 @@ impl VestingAccount for Account { block_time: Option, env: &Env, storage: &dyn Storage, - ) -> Result { + ) -> Result { let still_vesting = self.get_vesting_coins(block_time, env, storage)?.amount; let staked = self.total_staked(storage)?; let locked_amount = still_vesting.saturating_sub(staked); @@ -37,7 +37,7 @@ impl VestingAccount for Account { block_time: Option, env: &Env, storage: &dyn Storage, - ) -> Result { + ) -> Result { Ok(Coin { amount: self .load_balance(storage)? @@ -51,7 +51,7 @@ impl VestingAccount for Account { block_time: Option, env: &Env, storage: &dyn Storage, - ) -> Result { + ) -> Result { let vested = self.get_vested_coins(block_time, env, storage)?; let withdrawn = self.load_withdrawn(storage)?; @@ -76,7 +76,7 @@ impl VestingAccount for Account { block_time: Option, env: &Env, storage: &dyn Storage, - ) -> Result { + ) -> Result { let spendable = self.spendable_coins(block_time, env, storage)?; let spendable_vested = self.spendable_vested_coins(block_time, env, storage)?; @@ -92,7 +92,7 @@ impl VestingAccount for Account { block_time: Option, env: &Env, storage: &dyn Storage, - ) -> Result { + ) -> Result { let block_time = block_time.unwrap_or(env.block.time); let period = self.get_current_vesting_period(block_time)?; let denom = MIX_DENOM.load(storage)?; @@ -119,7 +119,7 @@ impl VestingAccount for Account { block_time: Option, env: &Env, storage: &dyn Storage, - ) -> Result { + ) -> Result { Ok(Coin { amount: self.get_original_vesting()?.amount().amount - self.get_vested_coins(block_time, env, storage)?.amount, @@ -135,7 +135,7 @@ impl VestingAccount for Account { self.periods[self.num_vesting_periods() - 1].end_time() } - fn get_original_vesting(&self) -> Result { + fn get_original_vesting(&self) -> Result { Ok(OriginalVestingResponse::new( self.coin.clone(), self.num_vesting_periods(), @@ -147,7 +147,7 @@ impl VestingAccount for Account { &mut self, to_address: &Addr, storage: &mut dyn Storage, - ) -> Result<(), ContractError> { + ) -> Result<(), VestingContractError> { delete_account(self.owner_address(), storage)?; self.owner_address = to_address.to_owned(); save_account(self, storage)?; @@ -158,7 +158,7 @@ impl VestingAccount for Account { &mut self, to_address: Option, storage: &mut dyn Storage, - ) -> Result<(), ContractError> { + ) -> Result<(), VestingContractError> { if let Some(staking_address) = self.staking_address() { delete_account(staking_address.to_owned(), storage)?; } @@ -167,7 +167,11 @@ impl VestingAccount for Account { Ok(()) } - fn track_reward(&self, amount: Coin, storage: &mut dyn Storage) -> Result<(), ContractError> { + fn track_reward( + &self, + amount: Coin, + storage: &mut dyn Storage, + ) -> Result<(), VestingContractError> { let current_balance = self.load_balance(storage)?; let new_balance = current_balance + amount.amount; self.save_balance(new_balance, storage)?; @@ -183,7 +187,7 @@ impl VestingAccount for Account { fn get_historical_vested_staking_rewards( &self, storage: &dyn Storage, - ) -> Result { + ) -> Result { let balance = self.load_balance(storage)?; let withdrawn = self.load_withdrawn(storage)?; let staked = self.total_staked(storage)?; diff --git a/contracts/vesting/src/vesting/mod.rs b/contracts/vesting/src/vesting/mod.rs index 56a02928d7..b16efbdd23 100644 --- a/contracts/vesting/src/vesting/mod.rs +++ b/contracts/vesting/src/vesting/mod.rs @@ -1,43 +1,18 @@ -use cosmwasm_std::Timestamp; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - mod account; -pub use account::*; -use vesting_contract_common::messages::VestingSpecification; - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub struct VestingPeriod { - pub start_time: u64, - pub period_seconds: u64, -} - -impl VestingPeriod { - pub fn end_time(&self) -> Timestamp { - Timestamp::from_seconds(self.start_time + self.period_seconds) - } -} +pub(crate) use account::StorableVestingAccountExt; +use vesting_contract_common::{VestingPeriod, VestingSpecification}; pub fn populate_vesting_periods( start_time: u64, vesting_spec: VestingSpecification, ) -> Vec { - let mut periods = Vec::with_capacity(vesting_spec.num_periods() as usize); - for i in 0..vesting_spec.num_periods() { - let period = VestingPeriod { - start_time: start_time + i * vesting_spec.period_seconds(), - period_seconds: vesting_spec.period_seconds(), - }; - periods.push(period); - } - periods + vesting_spec.populate_vesting_periods(start_time) } #[cfg(test)] mod tests { use crate::contract::*; - use crate::errors::ContractError; use crate::storage::*; use crate::support::tests::helpers::vesting_account_percent_fixture; use crate::support::tests::helpers::{ @@ -46,15 +21,16 @@ mod tests { use crate::traits::DelegatingAccount; use crate::traits::VestingAccount; use crate::traits::{GatewayBondingAccount, MixnodeBondingAccount}; - use crate::vesting::{populate_vesting_periods, Account}; + use crate::vesting::account::StorableVestingAccountExt; + use crate::vesting::populate_vesting_periods; use contracts_common::signing::MessageSignature; use cosmwasm_std::testing::{mock_env, mock_info}; use cosmwasm_std::{coin, coins, Addr, Coin, Timestamp, Uint128}; use mixnet_contract_common::mixnode::MixNodeCostParams; use mixnet_contract_common::{Gateway, MixNode, Percent}; - use vesting_contract_common::messages::{ExecuteMsg, VestingSpecification}; - use vesting_contract_common::Period; - use vesting_contract_common::PledgeCap; + use vesting_contract_common::messages::ExecuteMsg; + use vesting_contract_common::{Account, PledgeCap, VestingSpecification}; + use vesting_contract_common::{Period, VestingContractError}; #[test] fn test_account_creation() { @@ -317,7 +293,9 @@ mod tests { staking_address_change, ); assert_eq!( - Err(ContractError::StakingAccountExists("vesting1".to_string())), + Err(VestingContractError::StakingAccountExists( + "vesting1".to_string() + )), res ); @@ -802,7 +780,7 @@ mod tests { VestingSpecification::new(None, Some(vesting_period_length_secs), None), ); - let vesting_account = Account::new( + let vesting_account = Account::save_new( Addr::unchecked("owner"), Some(Addr::unchecked("staking")), Coin { @@ -842,7 +820,7 @@ mod tests { assert_eq!( res, - ContractError::TooManyDelegations { + VestingContractError::TooManyDelegations { address: vesting_account.owner_address(), acc_id: vesting_account.storage_key(), mix_id, diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 1b9ca04b31..c1acf4ee4e 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -284,8 +284,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" dependencies = [ "bitcoin_hashes", - "rand 0.7.3", - "rand_core 0.5.1", + "rand 0.8.5", + "rand_core 0.6.4", "serde", "unicode-normalization", "zeroize", @@ -399,6 +399,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "bnum" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "845141a4fade3f790628b7daaaa298a25b204fb28907eb54febe5142db6ce653" + [[package]] name = "brotli" version = "3.3.4" @@ -833,9 +839,9 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.2.5" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75836a10cb9654c54e77ee56da94d592923092a10b369cdb0dbd56acefc16340" +checksum = "0d076a08ec01ed23c4396aca98ec73a38fa1fee5f310465add52b4108181c7a8" dependencies = [ "digest 0.10.7", "ed25519-zebra", @@ -846,18 +852,18 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.2.5" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c9f7f0e51bfc7295f7b2664fe8513c966428642aa765dad8a74acdab5e0c773" +checksum = "dec361f3c09d7b41221948fc17be9b3c96cb58e55a02f82da36f888a651f2584" dependencies = [ "syn 1.0.109", ] [[package]] name = "cosmwasm-schema" -version = "1.2.5" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f00b363610218eea83f24bbab09e1a7c3920b79f068334fdfcc62f6129ef9fc" +checksum = "bb6b2fb76758ef59cddc77f2e2ae91c22f77da49037e9f182e9c2833f0e959b1" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -868,9 +874,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.2.5" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae38f909b2822d32b275c9e2db9728497aa33ffe67dd463bc67c6a3b7092785c" +checksum = "2bfa39422f0d9f1c9a6fd3711573258495314dfa3aae738ea825ecd9964bc659" dependencies = [ "proc-macro2", "quote", @@ -879,11 +885,12 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.2.5" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a49b85345e811c8e80ec55d0d091e4fcb4f00f97ab058f9be5f614c444a730cb" +checksum = "1f6dc2ee23313add5ecacc3ccac217b9967ad9d2d11bd56e5da6aa65a9da6138" dependencies = [ "base64 0.13.1", + "bnum", "cosmwasm-crypto", "cosmwasm-derive", "derivative", @@ -891,10 +898,9 @@ dependencies = [ "hex", "schemars", "serde", - "serde-json-wasm 0.5.1", + "serde-json-wasm", "sha2 0.10.6", "thiserror", - "uint", ] [[package]] @@ -998,12 +1004,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - [[package]] name = "crypto-bigint" version = "0.4.9" @@ -1151,9 +1151,9 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91440ce8ec4f0642798bc8c8cb6b9b53c1926c6dadaf0eed267a5145cd529071" +checksum = "d5d8edce4b78785f36413f67387e4be7d0cb7d032b5d4164bcc024f9c3f3f2ea" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1166,9 +1166,9 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053a5083c258acd68386734f428a5a171b29f7d733151ae83090c6fcc9417ffa" +checksum = "3f0e92a069d62067f3472c62e30adedb4cab1754725c0f2a682b3128d2bf3c79" dependencies = [ "cosmwasm-std", "schemars", @@ -1192,22 +1192,23 @@ dependencies = [ [[package]] name = "cw2" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fb70cee2cf0b4a8ff7253e6bc6647107905e8eb37208f87d54f67810faa62f8" +checksum = "29ac2dc7a55ad64173ca1e0a46697c31b7a5c51342f55a1e84a724da4eb99908" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", "serde", + "thiserror", ] [[package]] name = "cw20" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91666da6c7b40c8dd5ff94df655a28114efc10c79b70b4d06f13c31e37d60609" +checksum = "011c45920f8200bd5d32d4fe52502506f64f2f75651ab408054d4cfc75ca3a9b" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1218,9 +1219,9 @@ dependencies = [ [[package]] name = "cw3" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fe0b587008aa221cd2a2579a21990a28c4347dc53ad43167c68ad765f5b6efa" +checksum = "171af3d9127de6805a7dd819fb070c7d2f6c3ea85f4193f42cef259f0a7f33d5" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1233,9 +1234,9 @@ dependencies = [ [[package]] name = "cw4" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c236e0bae02ce97e89235a681dd0e07d099524b369f1ef908d704db3e6b049b" +checksum = "a398696307efadaaa2d0850076f865fa706c959d493cb4203314f72be6b77a64" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -3614,22 +3615,20 @@ dependencies = [ name = "nym-coconut-bandwidth-contract-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "nym-multisig-contract-common", - "schemars", - "serde", ] [[package]] name = "nym-coconut-dkg-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-utils", "nym-contracts-common", "nym-multisig-contract-common", - "schemars", - "serde", ] [[package]] @@ -3709,6 +3708,7 @@ name = "nym-contracts-common" version = "0.5.0" dependencies = [ "bs58 0.4.0", + "cosmwasm-schema", "cosmwasm-std", "schemars", "serde", @@ -3851,13 +3851,14 @@ name = "nym-mixnet-contract-common" version = "0.6.0" dependencies = [ "bs58 0.4.0", + "cosmwasm-schema", "cosmwasm-std", "humantime-serde", "log", "nym-contracts-common", "schemars", "serde", - "serde-json-wasm 0.4.1", + "serde-json-wasm", "serde_repr", "thiserror", "time", @@ -3882,11 +3883,11 @@ dependencies = [ name = "nym-name-service-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-controllers", "cw-utils", "nym-contracts-common", - "schemars", "serde", "thiserror", ] @@ -3952,12 +3953,11 @@ dependencies = [ name = "nym-service-provider-directory-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-controllers", "cw-utils", "nym-contracts-common", - "schemars", - "serde", "thiserror", ] @@ -4231,7 +4231,6 @@ dependencies = [ "nym-name-service-common", "nym-network-defaults", "nym-service-provider-directory-common", - "nym-vesting-contract", "nym-vesting-contract-common", "openssl", "prost", @@ -4246,33 +4245,16 @@ dependencies = [ "zeroize", ] -[[package]] -name = "nym-vesting-contract" -version = "1.4.0" -dependencies = [ - "cosmwasm-derive", - "cosmwasm-std", - "cw-storage-plus", - "cw2", - "nym-contracts-common", - "nym-mixnet-contract-common", - "nym-vesting-contract-common", - "schemars", - "semver 1.0.17", - "serde", - "thiserror", - "vergen", -] - [[package]] name = "nym-vesting-contract-common" version = "0.7.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "nym-contracts-common", "nym-mixnet-contract-common", - "schemars", "serde", + "thiserror", ] [[package]] @@ -5691,18 +5673,9 @@ dependencies = [ [[package]] name = "serde-json-wasm" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" -dependencies = [ - "serde", -] - -[[package]] -name = "serde-json-wasm" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" +checksum = "a15bee9b04dd165c3f4e142628982ddde884c2022a89e8ddf99c4829bf2c3a58" dependencies = [ "serde", ] @@ -6247,12 +6220,6 @@ dependencies = [ "loom", ] -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "string_cache" version = "0.8.7" @@ -7173,18 +7140,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" -[[package]] -name = "uint" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - [[package]] name = "uname" version = "0.1.1" diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index 050930055a..2e7df7a43e 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -302,6 +302,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "bnum" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "845141a4fade3f790628b7daaaa298a25b204fb28907eb54febe5142db6ce653" + [[package]] name = "brotli" version = "3.3.4" @@ -680,9 +686,9 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.2.5" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75836a10cb9654c54e77ee56da94d592923092a10b369cdb0dbd56acefc16340" +checksum = "0d076a08ec01ed23c4396aca98ec73a38fa1fee5f310465add52b4108181c7a8" dependencies = [ "digest 0.10.7", "ed25519-zebra", @@ -693,18 +699,18 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.2.5" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c9f7f0e51bfc7295f7b2664fe8513c966428642aa765dad8a74acdab5e0c773" +checksum = "dec361f3c09d7b41221948fc17be9b3c96cb58e55a02f82da36f888a651f2584" dependencies = [ "syn 1.0.107", ] [[package]] name = "cosmwasm-schema" -version = "1.2.5" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f00b363610218eea83f24bbab09e1a7c3920b79f068334fdfcc62f6129ef9fc" +checksum = "bb6b2fb76758ef59cddc77f2e2ae91c22f77da49037e9f182e9c2833f0e959b1" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -715,9 +721,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.2.5" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae38f909b2822d32b275c9e2db9728497aa33ffe67dd463bc67c6a3b7092785c" +checksum = "2bfa39422f0d9f1c9a6fd3711573258495314dfa3aae738ea825ecd9964bc659" dependencies = [ "proc-macro2", "quote", @@ -726,11 +732,12 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.2.5" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a49b85345e811c8e80ec55d0d091e4fcb4f00f97ab058f9be5f614c444a730cb" +checksum = "1f6dc2ee23313add5ecacc3ccac217b9967ad9d2d11bd56e5da6aa65a9da6138" dependencies = [ "base64 0.13.1", + "bnum", "cosmwasm-crypto", "cosmwasm-derive", "derivative", @@ -738,10 +745,9 @@ dependencies = [ "hex", "schemars", "serde", - "serde-json-wasm 0.5.1", + "serde-json-wasm", "sha2 0.10.6", "thiserror", - "uint", ] [[package]] @@ -781,12 +787,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - [[package]] name = "crypto-bigint" version = "0.4.9" @@ -911,9 +911,9 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91440ce8ec4f0642798bc8c8cb6b9b53c1926c6dadaf0eed267a5145cd529071" +checksum = "d5d8edce4b78785f36413f67387e4be7d0cb7d032b5d4164bcc024f9c3f3f2ea" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -926,9 +926,9 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053a5083c258acd68386734f428a5a171b29f7d733151ae83090c6fcc9417ffa" +checksum = "3f0e92a069d62067f3472c62e30adedb4cab1754725c0f2a682b3128d2bf3c79" dependencies = [ "cosmwasm-std", "schemars", @@ -952,22 +952,23 @@ dependencies = [ [[package]] name = "cw2" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fb70cee2cf0b4a8ff7253e6bc6647107905e8eb37208f87d54f67810faa62f8" +checksum = "29ac2dc7a55ad64173ca1e0a46697c31b7a5c51342f55a1e84a724da4eb99908" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", "serde", + "thiserror", ] [[package]] name = "cw20" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91666da6c7b40c8dd5ff94df655a28114efc10c79b70b4d06f13c31e37d60609" +checksum = "011c45920f8200bd5d32d4fe52502506f64f2f75651ab408054d4cfc75ca3a9b" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -978,9 +979,9 @@ dependencies = [ [[package]] name = "cw3" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fe0b587008aa221cd2a2579a21990a28c4347dc53ad43167c68ad765f5b6efa" +checksum = "171af3d9127de6805a7dd819fb070c7d2f6c3ea85f4193f42cef259f0a7f33d5" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -993,9 +994,9 @@ dependencies = [ [[package]] name = "cw4" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c236e0bae02ce97e89235a681dd0e07d099524b369f1ef908d704db3e6b049b" +checksum = "a398696307efadaaa2d0850076f865fa706c959d493cb4203314f72be6b77a64" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -2937,22 +2938,20 @@ dependencies = [ name = "nym-coconut-bandwidth-contract-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "nym-multisig-contract-common", - "schemars", - "serde", ] [[package]] name = "nym-coconut-dkg-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-utils", "nym-contracts-common", "nym-multisig-contract-common", - "schemars", - "serde", ] [[package]] @@ -2984,6 +2983,7 @@ name = "nym-contracts-common" version = "0.5.0" dependencies = [ "bs58 0.4.0", + "cosmwasm-schema", "cosmwasm-std", "schemars", "serde", @@ -3042,13 +3042,14 @@ name = "nym-mixnet-contract-common" version = "0.6.0" dependencies = [ "bs58 0.4.0", + "cosmwasm-schema", "cosmwasm-std", "humantime-serde", "log", "nym-contracts-common", "schemars", "serde", - "serde-json-wasm 0.4.1", + "serde-json-wasm", "serde_repr", "thiserror", "time", @@ -3074,11 +3075,11 @@ dependencies = [ name = "nym-name-service-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-controllers", "cw-utils", "nym-contracts-common", - "schemars", "serde", "thiserror", ] @@ -3107,12 +3108,11 @@ dependencies = [ name = "nym-service-provider-directory-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-controllers", "cw-utils", "nym-contracts-common", - "schemars", - "serde", "thiserror", ] @@ -3151,7 +3151,6 @@ dependencies = [ "nym-config", "nym-mixnet-contract-common", "nym-validator-client", - "nym-vesting-contract", "nym-vesting-contract-common", "reqwest", "schemars", @@ -3192,7 +3191,6 @@ dependencies = [ "nym-name-service-common", "nym-network-defaults", "nym-service-provider-directory-common", - "nym-vesting-contract", "nym-vesting-contract-common", "openssl", "prost", @@ -3207,33 +3205,16 @@ dependencies = [ "zeroize", ] -[[package]] -name = "nym-vesting-contract" -version = "1.4.0" -dependencies = [ - "cosmwasm-derive", - "cosmwasm-std", - "cw-storage-plus", - "cw2", - "nym-contracts-common", - "nym-mixnet-contract-common", - "nym-vesting-contract-common", - "schemars", - "semver 1.0.16", - "serde", - "thiserror", - "vergen", -] - [[package]] name = "nym-vesting-contract-common" version = "0.7.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "nym-contracts-common", "nym-mixnet-contract-common", - "schemars", "serde", + "thiserror", ] [[package]] @@ -3263,7 +3244,6 @@ dependencies = [ "nym-network-defaults", "nym-types", "nym-validator-client", - "nym-vesting-contract", "nym-vesting-contract-common", "serde", "serde_json", @@ -3298,7 +3278,6 @@ dependencies = [ "nym-store-cipher", "nym-types", "nym-validator-client", - "nym-vesting-contract", "nym-vesting-contract-common", "nym-wallet-types", "once_cell", @@ -4468,18 +4447,9 @@ dependencies = [ [[package]] name = "serde-json-wasm" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" -dependencies = [ - "serde", -] - -[[package]] -name = "serde-json-wasm" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" +checksum = "a15bee9b04dd165c3f4e142628982ddde884c2022a89e8ddf99c4829bf2c3a58" dependencies = [ "serde", ] @@ -4785,12 +4755,6 @@ dependencies = [ "loom", ] -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "string_cache" version = "0.8.4" @@ -5622,18 +5586,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" -[[package]] -name = "uint" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - [[package]] name = "unicode-bidi" version = "0.3.10" diff --git a/nym-wallet/nym-wallet-types/Cargo.toml b/nym-wallet/nym-wallet-types/Cargo.toml index 63a4aa5daf..670739ad5f 100644 --- a/nym-wallet/nym-wallet-types/Cargo.toml +++ b/nym-wallet/nym-wallet-types/Cargo.toml @@ -11,7 +11,7 @@ serde_json = "1.0" strum = { version = "0.23", features = ["derive"] } ts-rs = "6.1.2" -cosmwasm-std = "1.2.0" +cosmwasm-std = "1.3.0" cosmrs = "=0.14.0" nym-config = { path = "../../common/config" } @@ -19,8 +19,6 @@ nym-network-defaults = { path = "../../common/network-defaults" } nym-mixnet-contract-common = { path = "../../common/cosmwasm-smart-contracts/mixnet-contract" } nym-validator-client = { path = "../../common/client-libs/validator-client" } nym-vesting-contract-common = { path = "../../common/cosmwasm-smart-contracts/vesting-contract" } -# Used for Type conversion, can be extracted but its a lot of work -nym-vesting-contract = { path = "../../contracts/vesting" } nym-types = { path = "../../common/types" } diff --git a/nym-wallet/src-tauri/Cargo.toml b/nym-wallet/src-tauri/Cargo.toml index 19b5f0e3c9..8c96f181f1 100644 --- a/nym-wallet/src-tauri/Cargo.toml +++ b/nym-wallet/src-tauri/Cargo.toml @@ -48,7 +48,7 @@ k256 = { version = "0.13", features = ["ecdsa", "sha256"] } base64 = "0.13" zeroize = { version = "1.5", features = ["zeroize_derive", "serde"] } -cosmwasm-std = "1.2.0" +cosmwasm-std = "1.3.0" cosmrs = "=0.14.0" nym-validator-client = { path = "../../common/client-libs/validator-client", features = [ @@ -60,8 +60,6 @@ nym-mixnet-contract-common = { path = "../../common/cosmwasm-smart-contracts/mix nym-vesting-contract-common = { path = "../../common/cosmwasm-smart-contracts/vesting-contract" } nym-config = { path = "../../common/config" } nym-coconut-interface = { path = "../../common/coconut-interface" } -# Used for Type conversion, can be extracted but its a lot of work -nym-vesting-contract = { path = "../../contracts/vesting" } nym-types = { path = "../../common/types" } nym-wallet-types = { path = "../nym-wallet-types" } nym-store-cipher = { path = "../../common/store-cipher", features = ["json"] } diff --git a/nym-wallet/src-tauri/src/utils.rs b/nym-wallet/src-tauri/src/utils.rs index e5aed4e092..579ccc5add 100644 --- a/nym-wallet/src-tauri/src/utils.rs +++ b/nym-wallet/src-tauri/src/utils.rs @@ -53,7 +53,9 @@ pub async fn try_convert_pubkey_to_mix_id( let res = nyxd_client!(state) .get_mixnode_details_by_identity(mix_identity) .await?; - Ok(res.map(|mixnode_details| mixnode_details.mix_id())) + Ok(res + .mixnode_details + .map(|mixnode_details| mixnode_details.mix_id())) } #[tauri::command] From 1b1f0293ec13e5db3078854750cb081dae0e52d1 Mon Sep 17 00:00:00 2001 From: pierre Date: Fri, 4 Aug 2023 15:36:06 +0200 Subject: [PATCH 27/46] fix(nc-android): text colors --- .../main/java/net/nymtech/nyms5/MainActivity.kt | 14 ++++++++++++-- .../main/java/net/nymtech/nyms5/ui/theme/Color.kt | 10 +++++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/MainActivity.kt b/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/MainActivity.kt index 3530d6db81..d01672cc4d 100644 --- a/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/MainActivity.kt +++ b/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/MainActivity.kt @@ -6,6 +6,7 @@ import android.util.Log import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.viewModels +import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -66,6 +67,8 @@ import androidx.work.WorkInfo import androidx.work.WorkManager import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.map +import net.nymtech.nyms5.ui.theme.darkYellow +import net.nymtech.nyms5.ui.theme.lightYellow class MainActivity : ComponentActivity() { private val tag = "MainActivity" @@ -309,6 +312,10 @@ fun Monitoring( onSwitch: (value: Boolean) -> Unit, ) { var monitoring by remember { mutableStateOf(initialValue) } + val yellowColor = when (isSystemInDarkTheme()) { + true -> darkYellow + false -> lightYellow + } Column( modifier = modifier @@ -330,10 +337,13 @@ fun Monitoring( Icon( painter = painterResource(R.drawable.warning_24), contentDescription = "copy to clipboard", - tint = Color.Yellow + tint = yellowColor ) Spacer(modifier = modifier.width(16.dp)) - Text(stringResource(R.string.monitoring_desc_2), color = Color.Yellow) + Text( + stringResource(R.string.monitoring_desc_2), + color = yellowColor + ) } Spacer(modifier = modifier.height(18.dp)) Text(stringResource(R.string.monitoring_desc_1)) diff --git a/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/ui/theme/Color.kt b/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/ui/theme/Color.kt index 1667a76208..85daf1ecf4 100644 --- a/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/ui/theme/Color.kt +++ b/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/ui/theme/Color.kt @@ -8,4 +8,12 @@ val Pink80 = Color(0xFFEFB8C8) val Purple40 = Color(0xFF6650a4) val PurpleGrey40 = Color(0xFF625b71) -val Pink40 = Color(0xFF7D5260) \ No newline at end of file +val Pink40 = Color(0xFF7D5260) + +// Custom colors +// generated from https://m3.material.io/theme-builder#/custom +val yellow = Color(0xFFD3B919) +val lightYellow = Color(0xFF6D5E00) +val lightOnYellow = Color(0xFFFFFFFF) +val darkYellow = Color(0xFFE1C62A) +val darkOnYellow = Color(0xFF393000) From 5711bbd0c1c3e2fe003b3be5968bd5e1e66106d6 Mon Sep 17 00:00:00 2001 From: pierre Date: Fri, 4 Aug 2023 17:15:01 +0200 Subject: [PATCH 28/46] feat(nc-android): add runtime permission request --- .../java/net/nymtech/nyms5/MainActivity.kt | 320 ++---------------- .../nyms5/ui/composables/HomeScreen.kt | 113 +++++++ .../nyms5/ui/composables/Monitoring.kt | 93 +++++ .../nyms5/ui/composables/S5ClientSwitch.kt | 142 ++++++++ 4 files changed, 376 insertions(+), 292 deletions(-) create mode 100644 nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/ui/composables/HomeScreen.kt create mode 100644 nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/ui/composables/Monitoring.kt create mode 100644 nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/ui/composables/S5ClientSwitch.kt diff --git a/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/MainActivity.kt b/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/MainActivity.kt index d01672cc4d..962e2c3760 100644 --- a/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/MainActivity.kt +++ b/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/MainActivity.kt @@ -1,74 +1,23 @@ package net.nymtech.nyms5 +import android.Manifest.permission.POST_NOTIFICATIONS +import android.content.pm.PackageManager import android.os.Build import android.os.Bundle import android.util.Log import androidx.activity.ComponentActivity import androidx.activity.compose.setContent +import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.viewModels -import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.verticalScroll -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.ArrowBack -import androidx.compose.material.icons.filled.Menu -import androidx.compose.material3.CenterAlignedTopAppBar -import androidx.compose.material3.DropdownMenu -import androidx.compose.material3.DropdownMenuItem -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.LinearProgressIndicator -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Scaffold -import androidx.compose.material3.Surface -import androidx.compose.material3.Switch -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.setValue -import androidx.compose.ui.Modifier -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import kotlinx.coroutines.launch import net.nymtech.nyms5.ui.theme.NymTheme -import androidx.compose.runtime.getValue -import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.ui.Alignment -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalClipboardManager -import androidx.compose.ui.platform.testTag -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.font.FontStyle -import androidx.datastore.core.DataStore -import androidx.datastore.preferences.core.Preferences -import androidx.datastore.preferences.core.edit -import androidx.navigation.compose.NavHost -import androidx.navigation.compose.composable -import androidx.navigation.compose.currentBackStackEntryAsState -import androidx.navigation.compose.rememberNavController import androidx.work.WorkInfo import androidx.work.WorkManager -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.map -import net.nymtech.nyms5.ui.theme.darkYellow -import net.nymtech.nyms5.ui.theme.lightYellow +import net.nymtech.nyms5.ui.composables.HomeScreen class MainActivity : ComponentActivity() { private val tag = "MainActivity" @@ -80,11 +29,24 @@ class MainActivity : ComponentActivity() { ) } + private val requestPermissionLauncher = + registerForActivityResult( + ActivityResultContracts.RequestPermission() + ) { isGranted: Boolean -> + if (isGranted) { + Log.d(tag, "permission POST_NOTIFICATIONS has been granted") + } else { + Log.d(tag, "permission POST_NOTIFICATIONS has NOT been granted") + } + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) Log.d(tag, "____onCreate") Log.i(tag, "device SDK [${Build.VERSION.SDK_INT}]") + checkPermission() + // observe proxy work progress WorkManager.getInstance(applicationContext) .getWorkInfoByIdLiveData(ProxyWorker.workId) @@ -142,248 +104,22 @@ class MainActivity : ComponentActivity() { super.onStart() viewModel.checkStateSync() } -} -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun HomeScreen( - proxyState: MainViewModel.ProxyState, - monitoring: Boolean, - dataStore: DataStore, - onSwitch: (value: Boolean) -> Unit, -) { - val navController = rememberNavController() - var expanded by remember { mutableStateOf(false) } - val scope = rememberCoroutineScope() - - Scaffold(topBar = { - CenterAlignedTopAppBar( - title = { - Text(stringResource(R.string.app_name)) - }, - navigationIcon = { - val navBackStackEntry by navController.currentBackStackEntryAsState() - val currentRoute = navBackStackEntry?.destination?.route - - if (currentRoute === "proxy") { - IconButton(onClick = { expanded = true }) { - Icon( - imageVector = Icons.Filled.Menu, - contentDescription = "Main menu" - ) - } - DropdownMenu( - expanded = expanded, - onDismissRequest = { expanded = false } - ) { - DropdownMenuItem(onClick = { - navController.navigate("monitoring") { - popUpTo("proxy") - } - expanded = false - }, text = { - Text("Error reporting") - }) - } - } else { - IconButton(onClick = { - navController.navigate("proxy") { - popUpTo("proxy") - } - }) { - Icon( - imageVector = Icons.Filled.ArrowBack, - contentDescription = "Back home" - ) - } + private fun checkPermission() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + // POST_NOTIFICATIONS is needed for the notification displayed + // when socks5 proxy client is running + when (checkSelfPermission(POST_NOTIFICATIONS)) { + PackageManager.PERMISSION_GRANTED -> { + Log.d(tag, "check permission POST_NOTIFICATIONS: granted") } - }, - ) - }) { contentPadding -> - NavHost( - navController = navController, - startDestination = "proxy", - modifier = Modifier.padding(contentPadding) - ) { - composable("proxy") { - S5ClientSwitch( - connected = proxyState.connected, - loading = proxyState.loading, - onSwitch = onSwitch - ) - } - composable("monitoring") { - Monitoring(initialValue = monitoring) { - scope.launch(Dispatchers.IO) { - dataStore.edit { settings -> settings[monitoringKey] = it } - } + + else -> { + Log.d(tag, "check permission POST_NOTIFICATIONS: not granted") + requestPermissionLauncher.launch(POST_NOTIFICATIONS) } } } } } -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun S5ClientSwitch( - connected: Boolean, - loading: Boolean, - onSwitch: (value: Boolean) -> Unit, - modifier: Modifier = Modifier -) { - val clipboardManager = LocalClipboardManager.current - val host = stringResource(R.string.proxy_host) - val port = stringResource(R.string.proxy_port) - if (loading) { - Row { - LinearProgressIndicator( - modifier = modifier.fillMaxWidth(), - color = MaterialTheme.colorScheme.secondary - ) - } - } else { - Spacer(modifier = modifier.height(2.dp)) - } - Column(modifier = modifier.padding(16.dp)) { - Row( - modifier = modifier.padding(16.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Text("Nym proxy") - Spacer(modifier = modifier.width(14.dp)) - Switch(checked = connected, enabled = !loading, onCheckedChange = { - onSwitch(!connected) - }, modifier = Modifier.testTag("switch_connect")) - } - if (connected && !loading) { - Column(modifier = modifier.padding(16.dp)) { - Text( - color = Color.Green, - fontStyle = FontStyle.Italic, - text = stringResource(R.string.connected_text) - ) - Spacer(modifier = modifier.height(10.dp)) - Row( - verticalAlignment = Alignment.CenterVertically - ) { - Surface( - onClick = { clipboardManager.setText(AnnotatedString(host)) }, - shape = RoundedCornerShape(6.dp), - ) { - Row( - modifier = modifier.padding(8.dp), - verticalAlignment = Alignment.CenterVertically, - ) { - Text(host) - Spacer(modifier = modifier.width(8.dp)) - Icon( - painter = painterResource(R.drawable.copy_24), - contentDescription = "copy to clipboard" - ) - } - } - Spacer(modifier = modifier.width(12.dp)) - Surface( - onClick = { clipboardManager.setText(AnnotatedString(port)) }, - shape = RoundedCornerShape(6.dp), - ) { - Row( - modifier = modifier.padding(8.dp), - verticalAlignment = Alignment.CenterVertically, - ) { - Text(port) - Spacer(modifier = modifier.width(8.dp)) - Icon( - painter = painterResource(R.drawable.copy_24), - contentDescription = "copy to clipboard" - ) - } - } - } - } - } - } -} - -@Composable -fun Monitoring( - modifier: Modifier = Modifier, - initialValue: Boolean, - onSwitch: (value: Boolean) -> Unit, -) { - var monitoring by remember { mutableStateOf(initialValue) } - val yellowColor = when (isSystemInDarkTheme()) { - true -> darkYellow - false -> lightYellow - } - - Column( - modifier = modifier - .padding(16.dp) - .verticalScroll(rememberScrollState()) - ) { - Row( - verticalAlignment = Alignment.CenterVertically - ) { - Text("Enable error reporting") - Spacer(modifier = modifier.width(16.dp)) - Switch(checked = monitoring, onCheckedChange = { - monitoring = it - onSwitch(it) - }) - } - Spacer(modifier = modifier.height(18.dp)) - Row(verticalAlignment = Alignment.CenterVertically) { - Icon( - painter = painterResource(R.drawable.warning_24), - contentDescription = "copy to clipboard", - tint = yellowColor - ) - Spacer(modifier = modifier.width(16.dp)) - Text( - stringResource(R.string.monitoring_desc_2), - color = yellowColor - ) - } - Spacer(modifier = modifier.height(18.dp)) - Text(stringResource(R.string.monitoring_desc_1)) - } -} - -@Preview -@Composable -fun PreviewSocks5Client() { - val tag = "UI" - var connected by rememberSaveable { mutableStateOf(false) } - var loading by rememberSaveable { mutableStateOf(false) } - NymTheme { - Surface( - modifier = Modifier.fillMaxSize(), - color = MaterialTheme.colorScheme.background - ) { - S5ClientSwitch(connected, loading, { - when { - it -> Log.d(tag, "switch ON") - else -> Log.d(tag, "switch OFF") - } - connected = it - loading = false - }) - } - } -} - -@Preview -@Composable -fun PreviewMonitoring() { - NymTheme { - Surface( - modifier = Modifier.fillMaxSize(), - color = MaterialTheme.colorScheme.background - ) { - Monitoring(initialValue = false) { - Log.d("Monitoring", "switch $it") - } - } - } -} diff --git a/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/ui/composables/HomeScreen.kt b/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/ui/composables/HomeScreen.kt new file mode 100644 index 0000000000..898c7613fe --- /dev/null +++ b/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/ui/composables/HomeScreen.kt @@ -0,0 +1,113 @@ +package net.nymtech.nyms5.ui.composables + +import androidx.compose.foundation.layout.padding +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material.icons.filled.Menu +import androidx.compose.material3.CenterAlignedTopAppBar +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.datastore.core.DataStore +import androidx.datastore.preferences.core.Preferences +import androidx.datastore.preferences.core.edit +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.currentBackStackEntryAsState +import androidx.navigation.compose.rememberNavController +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import net.nymtech.nyms5.MainViewModel +import net.nymtech.nyms5.R +import net.nymtech.nyms5.monitoringKey + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun HomeScreen( + proxyState: MainViewModel.ProxyState, + monitoring: Boolean, + dataStore: DataStore, + onSwitch: (value: Boolean) -> Unit, +) { + val navController = rememberNavController() + var expanded by remember { mutableStateOf(false) } + val scope = rememberCoroutineScope() + + Scaffold(topBar = { + CenterAlignedTopAppBar( + title = { + Text(stringResource(R.string.app_name)) + }, + navigationIcon = { + val navBackStackEntry by navController.currentBackStackEntryAsState() + val currentRoute = navBackStackEntry?.destination?.route + + if (currentRoute === "proxy") { + IconButton(onClick = { expanded = true }) { + Icon( + imageVector = Icons.Filled.Menu, + contentDescription = "Main menu" + ) + } + DropdownMenu( + expanded = expanded, + onDismissRequest = { expanded = false } + ) { + DropdownMenuItem(onClick = { + navController.navigate("monitoring") { + popUpTo("proxy") + } + expanded = false + }, text = { + Text("Error reporting") + }) + } + } else { + IconButton(onClick = { + navController.navigate("proxy") { + popUpTo("proxy") + } + }) { + Icon( + imageVector = Icons.Filled.ArrowBack, + contentDescription = "Back home" + ) + } + } + }, + ) + }) { contentPadding -> + NavHost( + navController = navController, + startDestination = "proxy", + modifier = Modifier.padding(contentPadding) + ) { + composable("proxy") { + S5ClientSwitch( + connected = proxyState.connected, + loading = proxyState.loading, + onSwitch = onSwitch + ) + } + composable("monitoring") { + Monitoring(initialValue = monitoring) { + scope.launch(Dispatchers.IO) { + dataStore.edit { settings -> settings[monitoringKey] = it } + } + } + } + } + } +} \ No newline at end of file diff --git a/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/ui/composables/Monitoring.kt b/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/ui/composables/Monitoring.kt new file mode 100644 index 0000000000..4195647891 --- /dev/null +++ b/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/ui/composables/Monitoring.kt @@ -0,0 +1,93 @@ +package net.nymtech.nyms5.ui.composables + +import android.util.Log +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Switch +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import net.nymtech.nyms5.R +import net.nymtech.nyms5.ui.theme.NymTheme +import net.nymtech.nyms5.ui.theme.darkYellow +import net.nymtech.nyms5.ui.theme.lightYellow + +@Composable +fun Monitoring( + modifier: Modifier = Modifier, + initialValue: Boolean, + onSwitch: (value: Boolean) -> Unit, +) { + var monitoring by remember { mutableStateOf(initialValue) } + val yellowColor = when (isSystemInDarkTheme()) { + true -> darkYellow + false -> lightYellow + } + + Column( + modifier = modifier + .padding(16.dp) + .verticalScroll(rememberScrollState()) + ) { + Row( + verticalAlignment = Alignment.CenterVertically + ) { + Text("Enable error reporting") + Spacer(modifier = modifier.width(16.dp)) + Switch(checked = monitoring, onCheckedChange = { + monitoring = it + onSwitch(it) + }) + } + Spacer(modifier = modifier.height(18.dp)) + Row(verticalAlignment = Alignment.CenterVertically) { + Icon( + painter = painterResource(R.drawable.warning_24), + contentDescription = "copy to clipboard", + tint = yellowColor + ) + Spacer(modifier = modifier.width(16.dp)) + Text( + stringResource(R.string.monitoring_desc_2), + color = yellowColor + ) + } + Spacer(modifier = modifier.height(18.dp)) + Text(stringResource(R.string.monitoring_desc_1)) + } +} + +@Preview +@Composable +fun PreviewMonitoring() { + NymTheme { + Surface( + modifier = Modifier.fillMaxSize(), + color = MaterialTheme.colorScheme.background + ) { + Monitoring(initialValue = false) { + Log.d("Monitoring", "switch $it") + } + } + } +} \ No newline at end of file diff --git a/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/ui/composables/S5ClientSwitch.kt b/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/ui/composables/S5ClientSwitch.kt new file mode 100644 index 0000000000..3361e6fc8a --- /dev/null +++ b/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/ui/composables/S5ClientSwitch.kt @@ -0,0 +1,142 @@ +package net.nymtech.nyms5.ui.composables + +import android.util.Log +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.LinearProgressIndicator +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Switch +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalClipboardManager +import androidx.compose.ui.platform.testTag +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.AnnotatedString +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import net.nymtech.nyms5.R +import net.nymtech.nyms5.ui.theme.NymTheme + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun S5ClientSwitch( + connected: Boolean, + loading: Boolean, + onSwitch: (value: Boolean) -> Unit, + modifier: Modifier = Modifier +) { + val clipboardManager = LocalClipboardManager.current + val host = stringResource(R.string.proxy_host) + val port = stringResource(R.string.proxy_port) + if (loading) { + Row { + LinearProgressIndicator( + modifier = modifier.fillMaxWidth(), + color = MaterialTheme.colorScheme.secondary + ) + } + } else { + Spacer(modifier = modifier.height(2.dp)) + } + Column(modifier = modifier.padding(16.dp)) { + Row( + modifier = modifier.padding(16.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Text("Nym proxy") + Spacer(modifier = modifier.width(14.dp)) + Switch(checked = connected, enabled = !loading, onCheckedChange = { + onSwitch(!connected) + }, modifier = Modifier.testTag("switch_connect")) + } + if (connected && !loading) { + Column(modifier = modifier.padding(16.dp)) { + Text( + color = Color.Green, + fontStyle = FontStyle.Italic, + text = stringResource(R.string.connected_text) + ) + Spacer(modifier = modifier.height(10.dp)) + Row( + verticalAlignment = Alignment.CenterVertically + ) { + Surface( + onClick = { clipboardManager.setText(AnnotatedString(host)) }, + shape = RoundedCornerShape(6.dp), + ) { + Row( + modifier = modifier.padding(8.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Text(host) + Spacer(modifier = modifier.width(8.dp)) + Icon( + painter = painterResource(R.drawable.copy_24), + contentDescription = "copy to clipboard" + ) + } + } + Spacer(modifier = modifier.width(12.dp)) + Surface( + onClick = { clipboardManager.setText(AnnotatedString(port)) }, + shape = RoundedCornerShape(6.dp), + ) { + Row( + modifier = modifier.padding(8.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Text(port) + Spacer(modifier = modifier.width(8.dp)) + Icon( + painter = painterResource(R.drawable.copy_24), + contentDescription = "copy to clipboard" + ) + } + } + } + } + } + } +} + +@Preview +@Composable +fun PreviewSocks5Client() { + val tag = "UI" + var connected by rememberSaveable { mutableStateOf(false) } + var loading by rememberSaveable { mutableStateOf(false) } + NymTheme { + Surface( + modifier = Modifier.fillMaxSize(), + color = MaterialTheme.colorScheme.background + ) { + S5ClientSwitch(connected, loading, { + when { + it -> Log.d(tag, "switch ON") + else -> Log.d(tag, "switch OFF") + } + connected = it + loading = false + }) + } + } +} \ No newline at end of file From 4a23729a6ad968f539252c070763277437d83a22 Mon Sep 17 00:00:00 2001 From: Mark Sinclair <14054343+mmsinclair@users.noreply.github.com> Date: Fri, 4 Aug 2023 16:31:21 +0100 Subject: [PATCH 29/46] Add GitHub Action to build Typescript SDK docs --- .github/workflows/sdk-docs-typescript.yml | 50 +++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 .github/workflows/sdk-docs-typescript.yml diff --git a/.github/workflows/sdk-docs-typescript.yml b/.github/workflows/sdk-docs-typescript.yml new file mode 100644 index 0000000000..2df60dcc0b --- /dev/null +++ b/.github/workflows/sdk-docs-typescript.yml @@ -0,0 +1,50 @@ +name: Typescript SDK docs + +on: + push: + paths: + - "sdk/typescript/**" + pull_request: + paths: + - "sdk/typescript/**" + +jobs: + build: + runs-on: custom-runner-linux + steps: + - uses: actions/checkout@v2 + - name: Install rsync + run: sudo apt-get install rsync + continue-on-error: true + - uses: rlespinasse/github-slug-action@v3.x + - uses: actions/setup-node@v3 + with: + node-version: 18 + - name: Install Rust stable + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + - name: Setup yarn + run: npm install -g yarn + - name: Install + run: yarn + - name: Matrix - Node Install + run: npm install + working-directory: .github/workflows/support-files + - name: Matrix - Send Notification + env: + NYM_NOTIFICATION_KIND: ts-packages + NYM_PROJECT_NAME: "ts-packages" + NYM_CI_WWW_BASE: "${{ secrets.NYM_CI_WWW_BASE }}" + NYM_CI_WWW_LOCATION: "ts-${{ env.GITHUB_REF_SLUG }}" + GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}" + GIT_BRANCH: "${GITHUB_REF##*/}" + IS_SUCCESS: "${{ job.status == 'success' }}" + MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}" + MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}" + MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}" + MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}" + MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}" + uses: docker://keybaseio/client:stable-node + with: + args: .github/workflows/support-files/notifications/entry_point.sh From b3b43b56bef751705897c392baf801d4676f9c34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 7 Aug 2023 10:15:15 +0100 Subject: [PATCH 30/46] added --version command to explorer-api --- Cargo.lock | 1 + explorer-api/Cargo.toml | 1 + explorer-api/src/commands/mod.rs | 15 +++++++++++++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 43b8e6eff2..c2eadc94b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1904,6 +1904,7 @@ dependencies = [ "humantime-serde", "isocountry", "itertools", + "lazy_static", "log", "maxminddb", "nym-bin-common", diff --git a/explorer-api/Cargo.toml b/explorer-api/Cargo.toml index 5e1dec9f48..ab0a56612b 100644 --- a/explorer-api/Cargo.toml +++ b/explorer-api/Cargo.toml @@ -11,6 +11,7 @@ clap = { version = "4.0", features = ["cargo", "derive"] } humantime-serde = "1.0" isocountry = "0.3.2" itertools = "0.10.3" +lazy_static = "1.4.0" log = { workspace = true } okapi = { version = "0.7.0-rc.1", features = ["impl_json_schema"] } pretty_env_logger = "0.4.0" diff --git a/explorer-api/src/commands/mod.rs b/explorer-api/src/commands/mod.rs index ee20748fd0..1e19d2efce 100644 --- a/explorer-api/src/commands/mod.rs +++ b/explorer-api/src/commands/mod.rs @@ -1,10 +1,21 @@ -// Copyright 2022 - Nym Technologies SA +// Copyright 2022-2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 use clap::Parser; +use lazy_static::lazy_static; +use nym_bin_common::bin_info; + +lazy_static! { + pub static ref PRETTY_BUILD_INFORMATION: String = bin_info!().pretty_print(); +} + +// Helper for passing LONG_VERSION to clap +fn pretty_build_info_static() -> &'static str { + &PRETTY_BUILD_INFORMATION +} #[derive(Parser)] -#[clap(author = "Nymtech", version, about)] +#[clap(author = "Nymtech", version, about, long_version = pretty_build_info_static())] pub(crate) struct Cli { /// Path pointing to an env file that configures the explorer api. #[clap(short, long)] From 49440bf60e752a1b30219103474055f2ff6f13cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogdan-=C8=98tefan=20Neac=C5=9Fu?= Date: Mon, 7 Aug 2023 12:27:31 +0300 Subject: [PATCH 31/46] Apply fix from feature/ephemera to develop too (#3698) (#3742) --- common/crypto/Cargo.toml | 4 +- .../crypto/src/asymmetric/encryption/mod.rs | 6 + common/crypto/src/asymmetric/identity/mod.rs | 2 + common/nymsphinx/acknowledgements/Cargo.toml | 2 +- common/nymsphinx/addressing/Cargo.toml | 2 +- common/nymsphinx/forwarding/Cargo.toml | 2 +- common/nymsphinx/params/Cargo.toml | 4 + common/nymsphinx/params/src/packet_sizes.rs | 43 +- common/nymsphinx/routing/Cargo.toml | 4 +- common/nymsphinx/types/Cargo.toml | 8 +- common/nymsphinx/types/src/lib.rs | 28 ++ common/topology/Cargo.toml | 4 +- common/topology/src/error.rs | 1 + contracts/Cargo.lock | 448 +----------------- nym-connect/desktop/Cargo.lock | 2 - nym-wallet/Cargo.lock | 137 +----- 16 files changed, 112 insertions(+), 585 deletions(-) diff --git a/common/crypto/Cargo.toml b/common/crypto/Cargo.toml index c6521d9056..27702da016 100644 --- a/common/crypto/Cargo.toml +++ b/common/crypto/Cargo.toml @@ -27,7 +27,7 @@ thiserror = "1.0.37" zeroize = { workspace = true, optional = true, features = ["zeroize_derive"] } # internal -nym-sphinx-types = { path = "../nymsphinx/types", version = "0.2.0" } +nym-sphinx-types = { path = "../nymsphinx/types", version = "0.2.0", default-features = false } nym-pemstore = { path = "../../common/pemstore", version = "0.3.0" } [dev-dependencies] @@ -38,3 +38,5 @@ serde = ["serde_crate", "serde_bytes", "ed25519-dalek/serde", "x25519-dalek/serd asymmetric = ["x25519-dalek", "ed25519-dalek", "zeroize"] hashing = ["blake3", "digest", "hkdf", "hmac", "generic-array"] symmetric = ["aes", "ctr", "cipher", "generic-array"] +sphinx = ["nym-sphinx-types/sphinx"] +outfox = ["nym-sphinx-types/outfox"] diff --git a/common/crypto/src/asymmetric/encryption/mod.rs b/common/crypto/src/asymmetric/encryption/mod.rs index 5052e785a0..6c45d41d60 100644 --- a/common/crypto/src/asymmetric/encryption/mod.rs +++ b/common/crypto/src/asymmetric/encryption/mod.rs @@ -273,36 +273,42 @@ impl PemStorableKey for PrivateKey { } // compatibility with sphinx keys: +#[cfg(feature = "sphinx")] impl From for nym_sphinx_types::PublicKey { fn from(key: PublicKey) -> Self { nym_sphinx_types::PublicKey::from(key.to_bytes()) } } +#[cfg(feature = "sphinx")] impl<'a> From<&'a PublicKey> for nym_sphinx_types::PublicKey { fn from(key: &'a PublicKey) -> Self { nym_sphinx_types::PublicKey::from((*key).to_bytes()) } } +#[cfg(feature = "sphinx")] impl From for PublicKey { fn from(pub_key: nym_sphinx_types::PublicKey) -> Self { Self(x25519_dalek::PublicKey::from(*pub_key.as_bytes())) } } +#[cfg(feature = "sphinx")] impl From for nym_sphinx_types::PrivateKey { fn from(key: PrivateKey) -> Self { nym_sphinx_types::PrivateKey::from(key.to_bytes()) } } +#[cfg(feature = "sphinx")] impl<'a> From<&'a PrivateKey> for nym_sphinx_types::PrivateKey { fn from(key: &'a PrivateKey) -> Self { nym_sphinx_types::PrivateKey::from(key.to_bytes()) } } +#[cfg(feature = "sphinx")] impl From for PrivateKey { fn from(private_key: nym_sphinx_types::PrivateKey) -> Self { let private_key_bytes = private_key.to_bytes(); diff --git a/common/crypto/src/asymmetric/identity/mod.rs b/common/crypto/src/asymmetric/identity/mod.rs index c552206da3..efe11acf4f 100644 --- a/common/crypto/src/asymmetric/identity/mod.rs +++ b/common/crypto/src/asymmetric/identity/mod.rs @@ -5,6 +5,7 @@ pub use ed25519_dalek::ed25519::signature::Signature as SignatureTrait; pub use ed25519_dalek::SignatureError; pub use ed25519_dalek::{Verifier, PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, SIGNATURE_LENGTH}; use nym_pemstore::traits::{PemStorableKey, PemStorableKeyPair}; +#[cfg(feature = "sphinx")] use nym_sphinx_types::{DestinationAddressBytes, DESTINATION_ADDRESS_LENGTH}; use std::fmt::{self, Display, Formatter}; use std::str::FromStr; @@ -113,6 +114,7 @@ impl Display for PublicKey { } impl PublicKey { + #[cfg(feature = "sphinx")] pub fn derive_destination_address(&self) -> DestinationAddressBytes { let mut temporary_address = [0u8; DESTINATION_ADDRESS_LENGTH]; let public_key_bytes = self.to_bytes(); diff --git a/common/nymsphinx/acknowledgements/Cargo.toml b/common/nymsphinx/acknowledgements/Cargo.toml index 95b3d8b30c..da9977d1f3 100644 --- a/common/nymsphinx/acknowledgements/Cargo.toml +++ b/common/nymsphinx/acknowledgements/Cargo.toml @@ -19,7 +19,7 @@ nym-pemstore = { path = "../../pemstore" } nym-sphinx-addressing = { path = "../addressing" } nym-sphinx-params = { path = "../params" } nym-sphinx-routing = { path = "../routing" } -nym-sphinx-types = { path = "../types" } +nym-sphinx-types = { path = "../types", features = ["sphinx"] } nym-topology = { path = "../../topology" } [features] diff --git a/common/nymsphinx/addressing/Cargo.toml b/common/nymsphinx/addressing/Cargo.toml index f9c646e04b..c6bc2856e3 100644 --- a/common/nymsphinx/addressing/Cargo.toml +++ b/common/nymsphinx/addressing/Cargo.toml @@ -9,7 +9,7 @@ repository = { workspace = true } [dependencies] nym-crypto = { path = "../../crypto", features = ["asymmetric"] } # all addresses are expressed in terms on their crypto keys -nym-sphinx-types = { path = "../types" } # we need to be able to refer to some types defined inside sphinx crate +nym-sphinx-types = { path = "../types", features = ["sphinx"] } # we need to be able to refer to some types defined inside sphinx crate serde = "1.0" # implementing serialization/deserialization for some types, like `Recipient` thiserror = "1.0.37" diff --git a/common/nymsphinx/forwarding/Cargo.toml b/common/nymsphinx/forwarding/Cargo.toml index 6509098398..4060cbf076 100644 --- a/common/nymsphinx/forwarding/Cargo.toml +++ b/common/nymsphinx/forwarding/Cargo.toml @@ -10,6 +10,6 @@ repository = { workspace = true } [dependencies] nym-sphinx-addressing = { path = "../addressing" } nym-sphinx-params = { path = "../params" } -nym-sphinx-types = { path = "../types" } +nym-sphinx-types = { path = "../types", features = ["sphinx", "outfox"] } nym-outfox = { path = "../../../nym-outfox" } thiserror = "1" diff --git a/common/nymsphinx/params/Cargo.toml b/common/nymsphinx/params/Cargo.toml index bc9b40b9a8..57872bb0ca 100644 --- a/common/nymsphinx/params/Cargo.toml +++ b/common/nymsphinx/params/Cargo.toml @@ -13,3 +13,7 @@ serde = { workspace = true, features = ["derive"] } nym-crypto = { path = "../../crypto", features = ["hashing", "symmetric"] } nym-sphinx-types = { path = "../types" } + +[features] +sphinx = ["nym-crypto/sphinx", "nym-sphinx-types/outfox"] +outfox = ["nym-crypto/outfox", "nym-sphinx-types/outfox"] diff --git a/common/nymsphinx/params/src/packet_sizes.rs b/common/nymsphinx/params/src/packet_sizes.rs index a6613f3024..58d9681efc 100644 --- a/common/nymsphinx/params/src/packet_sizes.rs +++ b/common/nymsphinx/params/src/packet_sizes.rs @@ -1,11 +1,11 @@ // Copyright 2021-2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::{PacketType, FRAG_ID_LEN}; -use nym_sphinx_types::header::HEADER_SIZE; -use nym_sphinx_types::{ - MIN_PACKET_SIZE, MIX_PARAMS_LEN, OUTFOX_PACKET_OVERHEAD, PAYLOAD_OVERHEAD_SIZE, -}; +use crate::PacketType; +#[cfg(feature = "sphinx")] +use nym_sphinx_types::{header::HEADER_SIZE, PAYLOAD_OVERHEAD_SIZE}; +#[cfg(feature = "outfox")] +use nym_sphinx_types::{MIN_PACKET_SIZE, MIX_PARAMS_LEN, OUTFOX_PACKET_OVERHEAD}; use serde::{Deserialize, Serialize}; use std::cmp::Ordering; use std::convert::TryFrom; @@ -14,6 +14,7 @@ use std::str::FromStr; use thiserror::Error; // each sphinx packet contains mandatory header and payload padding + markers +#[cfg(feature = "sphinx")] const SPHINX_PACKET_OVERHEAD: usize = HEADER_SIZE + PAYLOAD_OVERHEAD_SIZE; // it's up to the smart people to figure those values out : ) @@ -22,15 +23,23 @@ const SPHINX_PACKET_OVERHEAD: usize = HEADER_SIZE + PAYLOAD_OVERHEAD_SIZE; // TODO: I'm not entirely sure if we can easily extract `::NonceSize` // into a const usize before relevant stuff is stabilised in rust... +#[cfg(feature = "sphinx")] const ACK_IV_SIZE: usize = 16; -const ACK_PACKET_SIZE: usize = ACK_IV_SIZE + FRAG_ID_LEN + SPHINX_PACKET_OVERHEAD; +#[cfg(feature = "sphinx")] +const ACK_PACKET_SIZE: usize = ACK_IV_SIZE + crate::FRAG_ID_LEN + SPHINX_PACKET_OVERHEAD; +#[cfg(feature = "sphinx")] const REGULAR_PACKET_SIZE: usize = 2 * 1024 + SPHINX_PACKET_OVERHEAD; +#[cfg(feature = "sphinx")] const EXTENDED_PACKET_SIZE_8: usize = 8 * 1024 + SPHINX_PACKET_OVERHEAD; +#[cfg(feature = "sphinx")] const EXTENDED_PACKET_SIZE_16: usize = 16 * 1024 + SPHINX_PACKET_OVERHEAD; +#[cfg(feature = "sphinx")] const EXTENDED_PACKET_SIZE_32: usize = 32 * 1024 + SPHINX_PACKET_OVERHEAD; +#[cfg(feature = "outfox")] const OUTFOX_ACK_PACKET_SIZE: usize = MIN_PACKET_SIZE + OUTFOX_PACKET_OVERHEAD; +#[cfg(feature = "outfox")] const OUTFOX_REGULAR_PACKET_SIZE: usize = 2 * 1024 + OUTFOX_PACKET_OVERHEAD; #[derive(Debug, Error)] @@ -153,38 +162,55 @@ impl TryFrom for PacketSize { impl PacketSize { pub const fn size(self) -> usize { + #[allow(unreachable_patterns)] match self { + #[cfg(feature = "sphinx")] PacketSize::RegularPacket => REGULAR_PACKET_SIZE, + #[cfg(feature = "sphinx")] PacketSize::AckPacket => ACK_PACKET_SIZE, + #[cfg(feature = "sphinx")] PacketSize::ExtendedPacket8 => EXTENDED_PACKET_SIZE_8, + #[cfg(feature = "sphinx")] PacketSize::ExtendedPacket16 => EXTENDED_PACKET_SIZE_16, + #[cfg(feature = "sphinx")] PacketSize::ExtendedPacket32 => EXTENDED_PACKET_SIZE_32, + #[cfg(feature = "outfox")] PacketSize::OutfoxRegularPacket => OUTFOX_REGULAR_PACKET_SIZE, + #[cfg(feature = "outfox")] PacketSize::OutfoxAckPacket => OUTFOX_ACK_PACKET_SIZE, + _ => 0, } } pub const fn header_size(&self) -> usize { + #[allow(unreachable_patterns)] match self { + #[cfg(feature = "sphinx")] PacketSize::RegularPacket | PacketSize::AckPacket | PacketSize::ExtendedPacket8 | PacketSize::ExtendedPacket16 | PacketSize::ExtendedPacket32 => HEADER_SIZE, + #[cfg(feature = "outfox")] PacketSize::OutfoxRegularPacket | PacketSize::OutfoxAckPacket => MIX_PARAMS_LEN, + _ => 0, } } pub const fn payload_overhead(&self) -> usize { + #[allow(unreachable_patterns)] match self { + #[cfg(feature = "sphinx")] PacketSize::RegularPacket | PacketSize::AckPacket | PacketSize::ExtendedPacket8 | PacketSize::ExtendedPacket16 | PacketSize::ExtendedPacket32 => PAYLOAD_OVERHEAD_SIZE, + #[cfg(feature = "outfox")] PacketSize::OutfoxRegularPacket | PacketSize::OutfoxAckPacket => { OUTFOX_PACKET_OVERHEAD - MIX_PARAMS_LEN // Mix params are calculated into the total overhead so we take them out here } + _ => 0, } } @@ -242,11 +268,16 @@ impl PacketSize { plaintext_size: usize, packet_type: PacketType, ) -> Result { + #[allow(unreachable_patterns)] let overhead = match packet_type { + #[cfg(feature = "sphinx")] PacketType::Mix => SPHINX_PACKET_OVERHEAD, #[allow(deprecated)] + #[cfg(feature = "sphinx")] PacketType::Vpn => SPHINX_PACKET_OVERHEAD, + #[cfg(feature = "outfox")] PacketType::Outfox => OUTFOX_PACKET_OVERHEAD, + _ => 0, }; let packet_size = plaintext_size + overhead; Self::get_type(packet_size) diff --git a/common/nymsphinx/routing/Cargo.toml b/common/nymsphinx/routing/Cargo.toml index c0f7cf7628..37b8d5a4dc 100644 --- a/common/nymsphinx/routing/Cargo.toml +++ b/common/nymsphinx/routing/Cargo.toml @@ -11,4 +11,6 @@ repository = { workspace = true } thiserror = { workspace = true } nym-sphinx-addressing = { path = "../addressing" } -nym-sphinx-types = { path = "../types" } \ No newline at end of file +nym-sphinx-types = { path = "../types", features = ["sphinx"] } + +[features] \ No newline at end of file diff --git a/common/nymsphinx/types/Cargo.toml b/common/nymsphinx/types/Cargo.toml index 2c52ef03d9..0569ef1406 100644 --- a/common/nymsphinx/types/Cargo.toml +++ b/common/nymsphinx/types/Cargo.toml @@ -8,6 +8,10 @@ license = { workspace = true } repository = { workspace = true } [dependencies] -sphinx-packet = { version = "0.1.0" } -nym-outfox = { path = "../../../nym-outfox" } +sphinx-packet = { version = "0.1.0", optional = true } +nym-outfox = { path = "../../../nym-outfox", optional = true } thiserror = "1" + +[features] +sphinx = ["sphinx-packet"] +outfox = ["nym-outfox"] diff --git a/common/nymsphinx/types/src/lib.rs b/common/nymsphinx/types/src/lib.rs index bd3063f939..d75060e9b0 100644 --- a/common/nymsphinx/types/src/lib.rs +++ b/common/nymsphinx/types/src/lib.rs @@ -1,12 +1,15 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +#[cfg(feature = "outfox")] pub use nym_outfox::{ constants::MIN_PACKET_SIZE, constants::MIX_PARAMS_LEN, constants::OUTFOX_PACKET_OVERHEAD, error::OutfoxError, }; // re-exporting types and constants available in sphinx +#[cfg(feature = "outfox")] use nym_outfox::packet::{OutfoxPacket, OutfoxProcessedPacket}; +#[cfg(feature = "sphinx")] pub use sphinx_packet::{ constants::{ self, DESTINATION_ADDRESS_LENGTH, IDENTIFIER_LENGTH, MAX_PATH_LENGTH, NODE_ADDRESS_LENGTH, @@ -20,6 +23,7 @@ pub use sphinx_packet::{ surb::{SURBMaterial, SURB}, Error as SphinxError, ProcessedPacket, }; +#[cfg(feature = "sphinx")] use sphinx_packet::{SphinxPacket, SphinxPacketBuilder}; use std::{array::TryFromSliceError, fmt}; use thiserror::Error; @@ -27,9 +31,11 @@ use thiserror::Error; #[derive(Error, Debug)] pub enum NymPacketError { #[error("Sphinx error: {0}")] + #[cfg(feature = "sphinx")] Sphinx(#[from] sphinx_packet::Error), #[error("Outfox error: {0}")] + #[cfg(feature = "outfox")] Outfox(#[from] nym_outfox::error::OutfoxError), #[error("{0}")] @@ -38,31 +44,40 @@ pub enum NymPacketError { #[allow(clippy::large_enum_variant)] pub enum NymPacket { + #[cfg(feature = "sphinx")] Sphinx(SphinxPacket), + #[cfg(feature = "outfox")] Outfox(OutfoxPacket), } pub enum NymProcessedPacket { + #[cfg(feature = "sphinx")] Sphinx(ProcessedPacket), + #[cfg(feature = "outfox")] Outfox(OutfoxProcessedPacket), } impl fmt::Debug for NymPacket { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + #[allow(unreachable_patterns)] match &self { + #[cfg(feature = "sphinx")] NymPacket::Sphinx(packet) => f .debug_struct("NymPacket::Sphinx") .field("len", &packet.len()) .finish(), + #[cfg(feature = "outfox")] NymPacket::Outfox(packet) => f .debug_struct("NymPacket::Outfox") .field("len", &packet.len()) .finish(), + _ => write!(f, ""), } } } impl NymPacket { + #[cfg(feature = "sphinx")] pub fn sphinx_build>( size: usize, message: M, @@ -76,10 +91,12 @@ impl NymPacket { .build_packet(message, route, destination, delays)?, )) } + #[cfg(feature = "sphinx")] pub fn sphinx_from_bytes(bytes: &[u8]) -> Result { Ok(NymPacket::Sphinx(SphinxPacket::from_bytes(bytes)?)) } + #[cfg(feature = "outfox")] pub fn outfox_build>( payload: M, route: &[Node], @@ -94,14 +111,19 @@ impl NymPacket { )?)) } + #[cfg(feature = "outfox")] pub fn outfox_from_bytes(bytes: &[u8]) -> Result { Ok(NymPacket::Outfox(OutfoxPacket::try_from(bytes)?)) } pub fn len(&self) -> usize { + #[allow(unreachable_patterns)] match self { + #[cfg(feature = "sphinx")] NymPacket::Sphinx(packet) => packet.len(), + #[cfg(feature = "outfox")] NymPacket::Outfox(packet) => packet.len(), + _ => 0, } } @@ -110,12 +132,17 @@ impl NymPacket { } pub fn to_bytes(&self) -> Result, NymPacketError> { + #[allow(unreachable_patterns)] match self { + #[cfg(feature = "sphinx")] NymPacket::Sphinx(packet) => Ok(packet.to_bytes()), + #[cfg(feature = "outfox")] NymPacket::Outfox(packet) => Ok(packet.to_bytes()?), + _ => Ok(vec![]), } } + #[cfg(feature = "sphinx")] pub fn process( self, node_secret_key: &PrivateKey, @@ -124,6 +151,7 @@ impl NymPacket { NymPacket::Sphinx(packet) => { Ok(NymProcessedPacket::Sphinx(packet.process(node_secret_key)?)) } + #[cfg(feature = "outfox")] NymPacket::Outfox(mut packet) => { let next_address = packet.decode_next_layer(node_secret_key)?; Ok(NymProcessedPacket::Outfox(OutfoxProcessedPacket::new( diff --git a/common/topology/Cargo.toml b/common/topology/Cargo.toml index 1d41a93ee4..bfe2c98573 100644 --- a/common/topology/Cargo.toml +++ b/common/topology/Cargo.toml @@ -19,10 +19,10 @@ thiserror = "1.0.37" async-trait = { workspace = true, optional = true } ## internal -nym-crypto = { path = "../crypto" } +nym-crypto = { path = "../crypto", features = ["sphinx", "outfox"] } nym-mixnet-contract-common = { path = "../cosmwasm-smart-contracts/mixnet-contract" } nym-sphinx-addressing = { path = "../nymsphinx/addressing" } -nym-sphinx-types = { path = "../nymsphinx/types" } +nym-sphinx-types = { path = "../nymsphinx/types", features = ["sphinx", "outfox"] } nym-sphinx-routing = { path = "../nymsphinx/routing" } nym-bin-common = { path = "../bin-common" } diff --git a/common/topology/src/error.rs b/common/topology/src/error.rs index bb36b42886..3f2523576f 100644 --- a/common/topology/src/error.rs +++ b/common/topology/src/error.rs @@ -41,6 +41,7 @@ pub enum NymTopologyError { PayloadBuilder, #[error("Outfox: {0}")] + #[cfg(feature = "outfox")] Outfox(#[from] nym_sphinx_types::OutfoxError), #[error("{0}")] diff --git a/contracts/Cargo.lock b/contracts/Cargo.lock index 0c3efd0a24..3d719dd6dc 100644 --- a/contracts/Cargo.lock +++ b/contracts/Cargo.lock @@ -2,29 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "aead" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" -dependencies = [ - "crypto-common", - "generic-array 0.14.6", -] - -[[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", - "opaque-debug 0.3.0", -] - [[package]] name = "ahash" version = "0.7.6" @@ -42,18 +19,6 @@ version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" -[[package]] -name = "arrayref" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" - -[[package]] -name = "arrayvec" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" - [[package]] name = "autocfg" version = "1.1.0" @@ -90,39 +55,13 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "blake2" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330" -dependencies = [ - "byte-tools", - "crypto-mac 0.7.0", - "digest 0.8.1", - "opaque-debug 0.2.3", -] - -[[package]] -name = "blake3" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "199c42ab6972d92c9f8995f086273d25c42fc0f7b2a1fcefba465c1352d25ba5" -dependencies = [ - "arrayref", - "arrayvec", - "cc", - "cfg-if", - "constant_time_eq", - "digest 0.10.7", -] - [[package]] name = "block-buffer" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "generic-array 0.14.6", + "generic-array", ] [[package]] @@ -131,7 +70,7 @@ version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "generic-array 0.14.6", + "generic-array", ] [[package]] @@ -146,12 +85,6 @@ version = "3.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b1ce199063694f33ffb7dd4e0ee620741495c32833cde5aa08f02a0bf96f0c8" -[[package]] -name = "byte-tools" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" - [[package]] name = "byteorder" version = "1.4.3" @@ -179,60 +112,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "chacha" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddf3c081b5fba1e5615640aae998e0fbd10c24cbd897ee39ed754a77601a4862" -dependencies = [ - "byteorder", - "keystream", -] - -[[package]] -name = "chacha20" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" -dependencies = [ - "cfg-if", - "cipher 0.4.4", - "cpufeatures", -] - -[[package]] -name = "chacha20poly1305" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" -dependencies = [ - "aead", - "chacha20", - "cipher 0.4.4", - "poly1305", - "zeroize", -] - -[[package]] -name = "cipher" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" -dependencies = [ - "generic-array 0.14.6", -] - -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", - "zeroize", -] - [[package]] name = "coconut-test" version = "0.1.0" @@ -264,12 +143,6 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" -[[package]] -name = "constant_time_eq" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" - [[package]] name = "cosmwasm-crypto" version = "1.2.5" @@ -355,49 +228,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crossbeam-channel" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" -dependencies = [ - "cfg-if", -] - [[package]] name = "crunchy" version = "0.2.2" @@ -410,9 +240,9 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ - "generic-array 0.14.6", + "generic-array", "rand_core 0.6.4", - "subtle 2.4.1", + "subtle", "zeroize", ] @@ -422,40 +252,10 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "generic-array 0.14.6", - "rand_core 0.6.4", + "generic-array", "typenum", ] -[[package]] -name = "crypto-mac" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" -dependencies = [ - "generic-array 0.12.4", - "subtle 1.0.0", -] - -[[package]] -name = "crypto-mac" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" -dependencies = [ - "generic-array 0.14.6", - "subtle 2.4.1", -] - -[[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 = "curve25519-dalek" version = "3.2.0" @@ -465,7 +265,7 @@ dependencies = [ "byteorder", "digest 0.9.0", "rand_core 0.5.1", - "subtle 2.4.1", + "subtle", "zeroize", ] @@ -676,22 +476,13 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "digest" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" -dependencies = [ - "generic-array 0.12.4", -] - [[package]] name = "digest" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array 0.14.6", + "generic-array", ] [[package]] @@ -702,7 +493,7 @@ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", "crypto-common", - "subtle 2.4.1", + "subtle", ] [[package]] @@ -778,12 +569,12 @@ dependencies = [ "der", "digest 0.10.7", "ff", - "generic-array 0.14.6", + "generic-array", "group", "pkcs8", "rand_core 0.6.4", "sec1", - "subtle 2.4.1", + "subtle", "zeroize", ] @@ -844,7 +635,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" dependencies = [ "rand_core 0.6.4", - "subtle 2.4.1", + "subtle", ] [[package]] @@ -963,15 +754,6 @@ dependencies = [ "slab", ] -[[package]] -name = "generic-array" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" -dependencies = [ - "typenum", -] - [[package]] name = "generic-array" version = "0.14.6" @@ -1002,10 +784,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", - "js-sys", "libc", "wasi 0.11.0+wasi-snapshot-preview1", - "wasm-bindgen", ] [[package]] @@ -1041,7 +821,7 @@ checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" dependencies = [ "ff", "rand_core 0.6.4", - "subtle 2.4.1", + "subtle", ] [[package]] @@ -1065,26 +845,6 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[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 = "hmac" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" -dependencies = [ - "crypto-mac 0.11.1", - "digest 0.9.0", -] - [[package]] name = "hmac" version = "0.12.1" @@ -1120,15 +880,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "generic-array 0.14.6", -] - [[package]] name = "instant" version = "0.1.12" @@ -1194,12 +945,6 @@ dependencies = [ "sha2 0.10.6", ] -[[package]] -name = "keystream" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33070833c9ee02266356de0c43f723152bd38bd96ddf52c82b3af10c9138b28" - [[package]] name = "lazy_static" version = "1.4.0" @@ -1224,12 +969,6 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "libm" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" - [[package]] name = "libz-sys" version = "1.1.8" @@ -1248,18 +987,6 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" -[[package]] -name = "lioness" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae926706ba42c425c9457121178330d75e273df2e82e28b758faf3de3a9acb9" -dependencies = [ - "arrayref", - "blake2", - "chacha", - "keystream", -] - [[package]] name = "log" version = "0.4.17" @@ -1275,15 +1002,6 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - [[package]] name = "mixnet-vesting-integration-tests" version = "0.1.0" @@ -1300,26 +1018,6 @@ dependencies = [ "rand_chacha 0.2.2", ] -[[package]] -name = "num-traits" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" -dependencies = [ - "autocfg", - "libm", -] - -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - [[package]] name = "nym-coconut-bandwidth" version = "0.1.0" @@ -1507,23 +1205,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "nym-outfox" -version = "0.1.0" -dependencies = [ - "blake3", - "chacha20", - "chacha20poly1305", - "curve25519-dalek", - "getrandom 0.2.10", - "log", - "rand 0.7.3", - "rayon", - "sphinx-packet", - "thiserror", - "zeroize", -] - [[package]] name = "nym-pemstore" version = "0.3.0" @@ -1571,8 +1252,6 @@ dependencies = [ name = "nym-sphinx-types" version = "0.2.0" dependencies = [ - "nym-outfox", - "sphinx-packet", "thiserror", ] @@ -1616,12 +1295,6 @@ version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" -[[package]] -name = "opaque-debug" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" - [[package]] name = "opaque-debug" version = "0.3.0" @@ -1673,17 +1346,6 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" -[[package]] -name = "poly1305" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" -dependencies = [ - "cpufeatures", - "opaque-debug 0.3.0", - "universal-hash", -] - [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1823,16 +1485,6 @@ dependencies = [ "getrandom 0.2.10", ] -[[package]] -name = "rand_distr" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e9532ada3929fb8b2e9dbe28d1e06c9b2cc65813f074fcb6bd5fbefeff9d56" -dependencies = [ - "num-traits", - "rand 0.7.3", -] - [[package]] name = "rand_hc" version = "0.2.0" @@ -1842,28 +1494,6 @@ dependencies = [ "rand_core 0.5.1", ] -[[package]] -name = "rayon" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "num_cpus", -] - [[package]] name = "redox_syscall" version = "0.3.5" @@ -1895,7 +1525,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ "crypto-bigint", - "hmac 0.12.1", + "hmac", "zeroize", ] @@ -1996,12 +1626,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - [[package]] name = "sec1" version = "0.3.0" @@ -2010,9 +1634,9 @@ checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ "base16ct", "der", - "generic-array 0.14.6", + "generic-array", "pkcs8", - "subtle 2.4.1", + "subtle", "zeroize", ] @@ -2103,7 +1727,7 @@ dependencies = [ "cfg-if", "cpufeatures", "digest 0.9.0", - "opaque-debug 0.3.0", + "opaque-debug", ] [[package]] @@ -2136,30 +1760,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "sphinx-packet" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc43eda802856ee82a7555c7b75ceb9e07451741c7a2f5f23d036020e01189d4" -dependencies = [ - "aes", - "arrayref", - "blake2", - "bs58", - "byteorder", - "chacha", - "curve25519-dalek", - "digest 0.9.0", - "hkdf", - "hmac 0.11.0", - "lioness", - "log", - "rand 0.7.3", - "rand_distr", - "sha2 0.9.9", - "subtle 2.4.1", -] - [[package]] name = "spki" version = "0.6.0" @@ -2176,12 +1776,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "subtle" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" - [[package]] name = "subtle" version = "2.4.1" @@ -2333,16 +1927,6 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "universal-hash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" -dependencies = [ - "crypto-common", - "subtle 2.4.1", -] - [[package]] name = "url" version = "2.3.1" diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 3f657d5852..fc3dba557f 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -4186,8 +4186,6 @@ dependencies = [ name = "nym-sphinx-types" version = "0.2.0" dependencies = [ - "nym-outfox", - "sphinx-packet", "thiserror", ] diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index 2da872c4fc..5768438108 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -120,12 +120,6 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" -[[package]] -name = "arrayvec" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" - [[package]] name = "async-trait" version = "0.1.64" @@ -301,20 +295,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "blake3" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "199c42ab6972d92c9f8995f086273d25c42fc0f7b2a1fcefba465c1352d25ba5" -dependencies = [ - "arrayref", - "arrayvec", - "cc", - "cfg-if", - "constant_time_eq", - "digest 0.10.7", -] - [[package]] name = "block" version = "0.1.6" @@ -525,30 +505,6 @@ dependencies = [ "keystream", ] -[[package]] -name = "chacha20" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" -dependencies = [ - "cfg-if", - "cipher 0.4.4", - "cpufeatures", -] - -[[package]] -name = "chacha20poly1305" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" -dependencies = [ - "aead", - "chacha20", - "cipher 0.4.4", - "poly1305", - "zeroize", -] - [[package]] name = "cipher" version = "0.3.0" @@ -566,7 +522,6 @@ checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ "crypto-common", "inout", - "zeroize", ] [[package]] @@ -700,12 +655,6 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" -[[package]] -name = "constant_time_eq" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" - [[package]] name = "convert_case" version = "0.4.0" @@ -879,30 +828,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "crossbeam-deque" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset 0.9.0", - "scopeguard", -] - [[package]] name = "crossbeam-utils" version = "0.8.14" @@ -1640,7 +1565,7 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e1c54951450cbd39f3dbcf1005ac413b49487dabf18a720ad2383eccfeffb92" dependencies = [ - "memoffset 0.6.5", + "memoffset", "rustc_version 0.3.3", ] @@ -2915,15 +2840,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - [[package]] name = "mime" version = "0.3.16" @@ -3328,23 +3244,6 @@ dependencies = [ "url", ] -[[package]] -name = "nym-outfox" -version = "0.1.0" -dependencies = [ - "blake3", - "chacha20", - "chacha20poly1305", - "curve25519-dalek", - "getrandom 0.2.10", - "log", - "rand 0.7.3", - "rayon", - "sphinx-packet", - "thiserror", - "zeroize", -] - [[package]] name = "nym-pemstore" version = "0.3.0" @@ -3369,7 +3268,6 @@ dependencies = [ name = "nym-sphinx-types" version = "0.2.0" dependencies = [ - "nym-outfox", "sphinx-packet", "thiserror", ] @@ -4074,17 +3972,6 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "poly1305" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" -dependencies = [ - "cpufeatures", - "opaque-debug 0.3.0", - "universal-hash", -] - [[package]] name = "polyval" version = "0.6.0" @@ -4336,28 +4223,6 @@ dependencies = [ "cty", ] -[[package]] -name = "rayon" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "num_cpus", -] - [[package]] name = "redox_syscall" version = "0.2.16" From 7ad2865250e8216754c6af0749207b2e6aa6775b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogdan-=C8=98tefan=20Neac=C5=9Fu?= Date: Mon, 7 Aug 2023 12:32:20 +0300 Subject: [PATCH 32/46] Add empty migration to group contract (#3740) --- .../group-contract/src/msg.rs | 2 + .../multisig/cw4-group/schema/cw4-group.json | 7 +++- .../cw4-group/schema/raw/migrate.json | 6 +++ .../multisig/cw4-group/src/bin/schema.rs | 3 +- contracts/multisig/cw4-group/src/contract.rs | 7 +++- nym-connect/desktop/Cargo.lock | 39 ++++++++----------- 6 files changed, 39 insertions(+), 25 deletions(-) create mode 100644 contracts/multisig/cw4-group/schema/raw/migrate.json diff --git a/common/cosmwasm-smart-contracts/group-contract/src/msg.rs b/common/cosmwasm-smart-contracts/group-contract/src/msg.rs index 3f95227492..84674946b1 100644 --- a/common/cosmwasm-smart-contracts/group-contract/src/msg.rs +++ b/common/cosmwasm-smart-contracts/group-contract/src/msg.rs @@ -46,3 +46,5 @@ pub enum QueryMsg { #[returns(cw_controllers::HooksResponse)] Hooks {}, } +#[cw_serde] +pub struct MigrateMsg {} diff --git a/contracts/multisig/cw4-group/schema/cw4-group.json b/contracts/multisig/cw4-group/schema/cw4-group.json index 5e0f5af99b..b6c6f5df44 100644 --- a/contracts/multisig/cw4-group/schema/cw4-group.json +++ b/contracts/multisig/cw4-group/schema/cw4-group.json @@ -286,7 +286,12 @@ } ] }, - "migrate": null, + "migrate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "type": "object", + "additionalProperties": false + }, "sudo": null, "responses": { "admin": { diff --git a/contracts/multisig/cw4-group/schema/raw/migrate.json b/contracts/multisig/cw4-group/schema/raw/migrate.json new file mode 100644 index 0000000000..7fbe8c5708 --- /dev/null +++ b/contracts/multisig/cw4-group/schema/raw/migrate.json @@ -0,0 +1,6 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "type": "object", + "additionalProperties": false +} diff --git a/contracts/multisig/cw4-group/src/bin/schema.rs b/contracts/multisig/cw4-group/src/bin/schema.rs index a46ff6cf2e..7340a28e6a 100644 --- a/contracts/multisig/cw4-group/src/bin/schema.rs +++ b/contracts/multisig/cw4-group/src/bin/schema.rs @@ -2,12 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 use cosmwasm_schema::write_api; -use nym_group_contract_common::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use nym_group_contract_common::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; fn main() { write_api! { instantiate: InstantiateMsg, query: QueryMsg, execute: ExecuteMsg, + migrate: MigrateMsg, } } diff --git a/contracts/multisig/cw4-group/src/contract.rs b/contracts/multisig/cw4-group/src/contract.rs index a6069f3b23..c5c039658c 100644 --- a/contracts/multisig/cw4-group/src/contract.rs +++ b/contracts/multisig/cw4-group/src/contract.rs @@ -15,7 +15,7 @@ use cw_utils::maybe_addr; use crate::error::ContractError; use crate::helpers::validate_unique_members; use crate::state::{ADMIN, HOOKS, MEMBERS, TOTAL}; -use nym_group_contract_common::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use nym_group_contract_common::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; // version info for migration info const CONTRACT_NAME: &str = "crates.io:cw4-group"; @@ -219,3 +219,8 @@ pub fn query_list_members( Ok(MemberListResponse { members }) } + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate(_deps: DepsMut<'_>, _env: Env, _msg: MigrateMsg) -> Result { + Ok(Default::default()) +} diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index c1acf4ee4e..5897f51672 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -2868,9 +2868,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", ] [[package]] @@ -3586,8 +3583,8 @@ dependencies = [ "url", "wasm-bindgen", "wasm-bindgen-futures", - "wasm-timer", "wasm-utils", + "wasmtimer", "zeroize", ] @@ -3810,8 +3807,8 @@ dependencies = [ "url", "wasm-bindgen", "wasm-bindgen-futures", - "wasm-timer", "wasm-utils", + "wasmtimer", ] [[package]] @@ -3909,12 +3906,10 @@ dependencies = [ name = "nym-nonexhaustive-delayqueue" version = "0.1.0" dependencies = [ - "futures-core", - "slab", "tokio", "tokio-stream", "tokio-util", - "wasm-timer", + "wasmtimer", ] [[package]] @@ -7423,20 +7418,6 @@ version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" -[[package]] -name = "wasm-timer" -version = "0.2.5" -source = "git+https://github.com/mmsinclair/wasm-timer?rev=b9d1a54ad514c2f230a026afe0dde341e98cd7b6#b9d1a54ad514c2f230a026afe0dde341e98cd7b6" -dependencies = [ - "futures", - "js-sys", - "parking_lot 0.11.2", - "pin-utils", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - [[package]] name = "wasm-utils" version = "0.1.0" @@ -7450,6 +7431,20 @@ dependencies = [ "web-sys", ] +[[package]] +name = "wasmtimer" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f656cd8858a5164932d8a90f936700860976ec21eb00e0fe2aa8cab13f6b4cf" +dependencies = [ + "futures", + "js-sys", + "parking_lot 0.12.1", + "pin-utils", + "slab", + "wasm-bindgen", +] + [[package]] name = "web-sys" version = "0.3.60" From 314d7a7526da84b14db9c6cf024e43c2a5ab4d22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogdan-=C8=98tefan=20Neac=C8=99u?= Date: Mon, 7 Aug 2023 15:52:03 +0300 Subject: [PATCH 33/46] Set sphinx as default packet type --- common/crypto/Cargo.toml | 1 + common/nymsphinx/Cargo.toml | 5 + common/nymsphinx/framing/Cargo.toml | 5 +- common/nymsphinx/params/Cargo.toml | 1 + common/nymsphinx/types/Cargo.toml | 1 + contracts/Cargo.lock | 236 ++++++++++++++++++++++++++-- nym-connect/desktop/Cargo.lock | 2 + 7 files changed, 233 insertions(+), 18 deletions(-) diff --git a/common/crypto/Cargo.toml b/common/crypto/Cargo.toml index 27702da016..992005f2d4 100644 --- a/common/crypto/Cargo.toml +++ b/common/crypto/Cargo.toml @@ -34,6 +34,7 @@ nym-pemstore = { path = "../../common/pemstore", version = "0.3.0" } rand_chacha = "0.2" [features] +default = ["sphinx"] serde = ["serde_crate", "serde_bytes", "ed25519-dalek/serde", "x25519-dalek/serde"] asymmetric = ["x25519-dalek", "ed25519-dalek", "zeroize"] hashing = ["blake3", "digest", "hkdf", "hmac", "generic-array"] diff --git a/common/nymsphinx/Cargo.toml b/common/nymsphinx/Cargo.toml index df93301876..955051b267 100644 --- a/common/nymsphinx/Cargo.toml +++ b/common/nymsphinx/Cargo.toml @@ -40,3 +40,8 @@ path = "framing" [target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio] version = "1.24.1" features = ["sync"] + +[features] +default = ["sphinx"] +sphinx = ["nym-crypto/sphinx", "nym-sphinx-params/sphinx", "nym-sphinx-types/sphinx"] +outfox = ["nym-crypto/outfox", "nym-sphinx-params/outfox", "nym-sphinx-types/outfox"] diff --git a/common/nymsphinx/framing/Cargo.toml b/common/nymsphinx/framing/Cargo.toml index b510926555..3915f204a2 100644 --- a/common/nymsphinx/framing/Cargo.toml +++ b/common/nymsphinx/framing/Cargo.toml @@ -12,5 +12,6 @@ bytes = "1.0" tokio-util = { version = "0.7.4", features = ["codec"] } thiserror = "1.0.37" -nym-sphinx-types = { path = "../types" } -nym-sphinx-params = { path = "../params" } +nym-sphinx-types = { path = "../types", features = ["sphinx", "outfox"] } +nym-sphinx-params = { path = "../params", features = ["sphinx", "outfox"] } + diff --git a/common/nymsphinx/params/Cargo.toml b/common/nymsphinx/params/Cargo.toml index 57872bb0ca..9d9a5a24e2 100644 --- a/common/nymsphinx/params/Cargo.toml +++ b/common/nymsphinx/params/Cargo.toml @@ -15,5 +15,6 @@ nym-crypto = { path = "../../crypto", features = ["hashing", "symmetric"] } nym-sphinx-types = { path = "../types" } [features] +default = ["sphinx"] sphinx = ["nym-crypto/sphinx", "nym-sphinx-types/outfox"] outfox = ["nym-crypto/outfox", "nym-sphinx-types/outfox"] diff --git a/common/nymsphinx/types/Cargo.toml b/common/nymsphinx/types/Cargo.toml index 0569ef1406..ae348113a0 100644 --- a/common/nymsphinx/types/Cargo.toml +++ b/common/nymsphinx/types/Cargo.toml @@ -13,5 +13,6 @@ nym-outfox = { path = "../../../nym-outfox", optional = true } thiserror = "1" [features] +default = ["sphinx"] sphinx = ["sphinx-packet"] outfox = ["nym-outfox"] diff --git a/contracts/Cargo.lock b/contracts/Cargo.lock index 3d719dd6dc..c30bb959e8 100644 --- a/contracts/Cargo.lock +++ b/contracts/Cargo.lock @@ -2,6 +2,19 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "aes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", + "ctr", + "opaque-debug 0.3.0", +] + [[package]] name = "ahash" version = "0.7.6" @@ -19,6 +32,12 @@ version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + [[package]] name = "autocfg" version = "1.1.0" @@ -55,13 +74,25 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "blake2" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330" +dependencies = [ + "byte-tools", + "crypto-mac 0.7.0", + "digest 0.8.1", + "opaque-debug 0.2.3", +] + [[package]] name = "block-buffer" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "generic-array", + "generic-array 0.14.6", ] [[package]] @@ -70,7 +101,7 @@ version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "generic-array", + "generic-array 0.14.6", ] [[package]] @@ -85,6 +116,12 @@ version = "3.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b1ce199063694f33ffb7dd4e0ee620741495c32833cde5aa08f02a0bf96f0c8" +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + [[package]] name = "byteorder" version = "1.4.3" @@ -112,6 +149,25 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddf3c081b5fba1e5615640aae998e0fbd10c24cbd897ee39ed754a77601a4862" +dependencies = [ + "byteorder", + "keystream", +] + +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array 0.14.6", +] + [[package]] name = "coconut-test" version = "0.1.0" @@ -240,9 +296,9 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ - "generic-array", + "generic-array 0.14.6", "rand_core 0.6.4", - "subtle", + "subtle 2.4.1", "zeroize", ] @@ -252,10 +308,39 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "generic-array", + "generic-array 0.14.6", "typenum", ] +[[package]] +name = "crypto-mac" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" +dependencies = [ + "generic-array 0.12.4", + "subtle 1.0.0", +] + +[[package]] +name = "crypto-mac" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +dependencies = [ + "generic-array 0.14.6", + "subtle 2.4.1", +] + +[[package]] +name = "ctr" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" +dependencies = [ + "cipher", +] + [[package]] name = "curve25519-dalek" version = "3.2.0" @@ -265,7 +350,7 @@ dependencies = [ "byteorder", "digest 0.9.0", "rand_core 0.5.1", - "subtle", + "subtle 2.4.1", "zeroize", ] @@ -476,13 +561,22 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array 0.12.4", +] + [[package]] name = "digest" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array", + "generic-array 0.14.6", ] [[package]] @@ -493,7 +587,7 @@ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", "crypto-common", - "subtle", + "subtle 2.4.1", ] [[package]] @@ -569,12 +663,12 @@ dependencies = [ "der", "digest 0.10.7", "ff", - "generic-array", + "generic-array 0.14.6", "group", "pkcs8", "rand_core 0.6.4", "sec1", - "subtle", + "subtle 2.4.1", "zeroize", ] @@ -635,7 +729,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" dependencies = [ "rand_core 0.6.4", - "subtle", + "subtle 2.4.1", ] [[package]] @@ -754,6 +848,15 @@ dependencies = [ "slab", ] +[[package]] +name = "generic-array" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +dependencies = [ + "typenum", +] + [[package]] name = "generic-array" version = "0.14.6" @@ -821,7 +924,7 @@ checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" dependencies = [ "ff", "rand_core 0.6.4", - "subtle", + "subtle 2.4.1", ] [[package]] @@ -845,6 +948,26 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[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 = "hmac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +dependencies = [ + "crypto-mac 0.11.1", + "digest 0.9.0", +] + [[package]] name = "hmac" version = "0.12.1" @@ -945,6 +1068,12 @@ dependencies = [ "sha2 0.10.6", ] +[[package]] +name = "keystream" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33070833c9ee02266356de0c43f723152bd38bd96ddf52c82b3af10c9138b28" + [[package]] name = "lazy_static" version = "1.4.0" @@ -969,6 +1098,12 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "libm" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" + [[package]] name = "libz-sys" version = "1.1.8" @@ -987,6 +1122,18 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" +[[package]] +name = "lioness" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae926706ba42c425c9457121178330d75e273df2e82e28b758faf3de3a9acb9" +dependencies = [ + "arrayref", + "blake2", + "chacha", + "keystream", +] + [[package]] name = "log" version = "0.4.17" @@ -1018,6 +1165,16 @@ dependencies = [ "rand_chacha 0.2.2", ] +[[package]] +name = "num-traits" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +dependencies = [ + "autocfg", + "libm", +] + [[package]] name = "nym-coconut-bandwidth" version = "0.1.0" @@ -1252,6 +1409,7 @@ dependencies = [ name = "nym-sphinx-types" version = "0.2.0" dependencies = [ + "sphinx-packet", "thiserror", ] @@ -1295,6 +1453,12 @@ version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + [[package]] name = "opaque-debug" version = "0.3.0" @@ -1485,6 +1649,16 @@ dependencies = [ "getrandom 0.2.10", ] +[[package]] +name = "rand_distr" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e9532ada3929fb8b2e9dbe28d1e06c9b2cc65813f074fcb6bd5fbefeff9d56" +dependencies = [ + "num-traits", + "rand 0.7.3", +] + [[package]] name = "rand_hc" version = "0.2.0" @@ -1525,7 +1699,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ "crypto-bigint", - "hmac", + "hmac 0.12.1", "zeroize", ] @@ -1634,9 +1808,9 @@ checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ "base16ct", "der", - "generic-array", + "generic-array 0.14.6", "pkcs8", - "subtle", + "subtle 2.4.1", "zeroize", ] @@ -1727,7 +1901,7 @@ dependencies = [ "cfg-if", "cpufeatures", "digest 0.9.0", - "opaque-debug", + "opaque-debug 0.3.0", ] [[package]] @@ -1760,6 +1934,30 @@ dependencies = [ "autocfg", ] +[[package]] +name = "sphinx-packet" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc43eda802856ee82a7555c7b75ceb9e07451741c7a2f5f23d036020e01189d4" +dependencies = [ + "aes", + "arrayref", + "blake2", + "bs58", + "byteorder", + "chacha", + "curve25519-dalek", + "digest 0.9.0", + "hkdf", + "hmac 0.11.0", + "lioness", + "log", + "rand 0.7.3", + "rand_distr", + "sha2 0.9.9", + "subtle 2.4.1", +] + [[package]] name = "spki" version = "0.6.0" @@ -1776,6 +1974,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "subtle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" + [[package]] name = "subtle" version = "2.4.1" diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index fc3dba557f..3f657d5852 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -4186,6 +4186,8 @@ dependencies = [ name = "nym-sphinx-types" version = "0.2.0" dependencies = [ + "nym-outfox", + "sphinx-packet", "thiserror", ] From 795efb9f0b68d194cdb9bfd7e07c8d9bc373eb46 Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Tue, 8 Aug 2023 11:15:30 +0200 Subject: [PATCH 34/46] Update changelog and versions for release v1.1.26 --- CHANGELOG.md | 22 +++++++++++++++++++ Cargo.lock | 18 +++++++-------- clients/native/Cargo.toml | 2 +- clients/socks5/Cargo.toml | 2 +- explorer-api/Cargo.toml | 2 +- gateway/Cargo.toml | 2 +- mixnode/Cargo.toml | 2 +- nym-api/Cargo.toml | 2 +- nym-connect/desktop/CHANGELOG.md | 6 +++++ nym-connect/desktop/package.json | 2 +- nym-connect/desktop/src-tauri/Cargo.toml | 2 +- nym-connect/desktop/src-tauri/tauri.conf.json | 2 +- .../network-requester/Cargo.toml | 2 +- .../network-statistics/Cargo.toml | 2 +- tools/nym-cli/Cargo.toml | 2 +- 15 files changed, 49 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f938c81fe3..1ec4a60145 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,28 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https:// ## [Unreleased] +## [v1.1.24] (2023-08-08) + +- Latency based gateway selection is serial and slow ([#3710]) +- Network-requester: strip comments from allow lists ([#3625]) +- Remove (or start maintaining) `upgrade` commands from all binaries ([#3600]) +- Set sphinx as default packet type ([#3748]) +- Apply fix from feature/ephemera to develop too (#3698) ([#3742]) +- Feature/coco demos ([#3732]) +- Add updates to community list projects ([#3722]) +- Add geo-aware mixnet topology provider ([#3713]) +- Add updates to community list projects ([#3711]) + +[#3710]: https://github.com/nymtech/nym/issues/3710 +[#3625]: https://github.com/nymtech/nym/issues/3625 +[#3600]: https://github.com/nymtech/nym/issues/3600 +[#3748]: https://github.com/nymtech/nym/pull/3748 +[#3742]: https://github.com/nymtech/nym/pull/3742 +[#3732]: https://github.com/nymtech/nym/pull/3732 +[#3722]: https://github.com/nymtech/nym/pull/3722 +[#3713]: https://github.com/nymtech/nym/pull/3713 +[#3711]: https://github.com/nymtech/nym/pull/3711 + ## [v1.1.23] (2023-07-04) - nym-cli: add client identity key signing support ([#3576]) diff --git a/Cargo.lock b/Cargo.lock index f7ba594a47..dc276f492c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1895,7 +1895,7 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "explorer-api" -version = "1.1.23" +version = "1.1.24" dependencies = [ "chrono", "clap 4.2.7", @@ -3531,7 +3531,7 @@ dependencies = [ [[package]] name = "nym-api" -version = "1.1.24" +version = "1.1.25" dependencies = [ "anyhow", "async-trait", @@ -3668,7 +3668,7 @@ dependencies = [ [[package]] name = "nym-cli" -version = "1.1.23" +version = "1.1.24" dependencies = [ "anyhow", "base64 0.13.1", @@ -3734,7 +3734,7 @@ dependencies = [ [[package]] name = "nym-client" -version = "1.1.23" +version = "1.1.24" dependencies = [ "clap 4.2.7", "dirs 4.0.0", @@ -4022,7 +4022,7 @@ dependencies = [ [[package]] name = "nym-gateway" -version = "1.1.23" +version = "1.1.24" dependencies = [ "anyhow", "async-trait", @@ -4175,7 +4175,7 @@ dependencies = [ [[package]] name = "nym-mixnode" -version = "1.1.24" +version = "1.1.25" dependencies = [ "anyhow", "bs58 0.4.0", @@ -4291,7 +4291,7 @@ dependencies = [ [[package]] name = "nym-network-requester" -version = "1.1.23" +version = "1.1.24" dependencies = [ "anyhow", "async-file-watcher", @@ -4338,7 +4338,7 @@ dependencies = [ [[package]] name = "nym-network-statistics" -version = "1.1.23" +version = "1.1.24" dependencies = [ "dirs 4.0.0", "log", @@ -4497,7 +4497,7 @@ dependencies = [ [[package]] name = "nym-socks5-client" -version = "1.1.23" +version = "1.1.24" dependencies = [ "clap 4.2.7", "lazy_static", diff --git a/clients/native/Cargo.toml b/clients/native/Cargo.toml index 6064304a90..2135883752 100644 --- a/clients/native/Cargo.toml +++ b/clients/native/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-client" -version = "1.1.23" +version = "1.1.24" authors = ["Dave Hrycyszyn ", "Jędrzej Stuczyński "] description = "Implementation of the Nym Client" edition = "2021" diff --git a/clients/socks5/Cargo.toml b/clients/socks5/Cargo.toml index 658d52a047..afbf36178f 100644 --- a/clients/socks5/Cargo.toml +++ b/clients/socks5/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-socks5-client" -version = "1.1.23" +version = "1.1.24" authors = ["Dave Hrycyszyn "] description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address" edition = "2021" diff --git a/explorer-api/Cargo.toml b/explorer-api/Cargo.toml index c4c7b345bc..6dfd65903f 100644 --- a/explorer-api/Cargo.toml +++ b/explorer-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "explorer-api" -version = "1.1.23" +version = "1.1.24" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index 763b3ab676..007fcca40d 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-gateway" -version = "1.1.23" +version = "1.1.24" authors = [ "Dave Hrycyszyn ", "Jędrzej Stuczyński ", diff --git a/mixnode/Cargo.toml b/mixnode/Cargo.toml index 9f512f0d85..8421bebb3a 100644 --- a/mixnode/Cargo.toml +++ b/mixnode/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-mixnode" -version = "1.1.24" +version = "1.1.25" authors = [ "Dave Hrycyszyn ", "Jędrzej Stuczyński ", diff --git a/nym-api/Cargo.toml b/nym-api/Cargo.toml index f9b378f59d..50568b440a 100644 --- a/nym-api/Cargo.toml +++ b/nym-api/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-api" -version = "1.1.24" +version = "1.1.25" authors = [ "Dave Hrycyszyn ", "Jędrzej Stuczyński ", diff --git a/nym-connect/desktop/CHANGELOG.md b/nym-connect/desktop/CHANGELOG.md index 1149c3b227..8a0b86151a 100644 --- a/nym-connect/desktop/CHANGELOG.md +++ b/nym-connect/desktop/CHANGELOG.md @@ -2,6 +2,12 @@ ## [Unreleased] +## [v1.1.16] (2023-08-08) + +- Uncouple network-requester <-> gateway in nym-connect and harbourmaster ([#3472]) + +[#3472]: https://github.com/nymtech/nym/issues/3472 + ## [v1.1.15] (2023-07-25) - NC Desktop - remove sentry DSN from code ([#3694]) diff --git a/nym-connect/desktop/package.json b/nym-connect/desktop/package.json index 626b415b8f..96d9e83438 100644 --- a/nym-connect/desktop/package.json +++ b/nym-connect/desktop/package.json @@ -1,6 +1,6 @@ { "name": "@nym/nym-connect", - "version": "1.1.15", + "version": "1.1.16", "main": "index.js", "license": "MIT", "scripts": { diff --git a/nym-connect/desktop/src-tauri/Cargo.toml b/nym-connect/desktop/src-tauri/Cargo.toml index e3bd49cb41..0d1089132d 100644 --- a/nym-connect/desktop/src-tauri/Cargo.toml +++ b/nym-connect/desktop/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-connect" -version = "1.1.15" +version = "1.1.16" description = "nym-connect" authors = ["Nym Technologies SA"] license = "" diff --git a/nym-connect/desktop/src-tauri/tauri.conf.json b/nym-connect/desktop/src-tauri/tauri.conf.json index b95859ca53..5f5e86bec0 100644 --- a/nym-connect/desktop/src-tauri/tauri.conf.json +++ b/nym-connect/desktop/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "package": { "productName": "nym-connect", - "version": "1.1.15" + "version": "1.1.16" }, "build": { "distDir": "../dist", diff --git a/service-providers/network-requester/Cargo.toml b/service-providers/network-requester/Cargo.toml index 5b80088b30..d1d7367d85 100644 --- a/service-providers/network-requester/Cargo.toml +++ b/service-providers/network-requester/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-network-requester" -version = "1.1.23" +version = "1.1.24" authors.workspace = true edition.workspace = true rust-version = "1.65" diff --git a/service-providers/network-statistics/Cargo.toml b/service-providers/network-statistics/Cargo.toml index cc7024c545..7c0138ca8f 100644 --- a/service-providers/network-statistics/Cargo.toml +++ b/service-providers/network-statistics/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-network-statistics" -version = "1.1.23" +version = "1.1.24" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/tools/nym-cli/Cargo.toml b/tools/nym-cli/Cargo.toml index ea5cad9e65..9f3c0d6a2a 100644 --- a/tools/nym-cli/Cargo.toml +++ b/tools/nym-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-cli" -version = "1.1.23" +version = "1.1.24" authors.workspace = true edition = "2021" From 2d60a9da3f9ae671e0fcc8192bfe4ddca5cc2c30 Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Tue, 8 Aug 2023 11:24:08 +0200 Subject: [PATCH 35/46] Temporary update to fix windows build --- package.json | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 523db5363f..cad6eaf88d 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,6 @@ "ts-packages/*", "nym-wallet", "nym-connect/**", - "nym-browser-extension", "explorer", "types", "clients/validator" @@ -29,9 +28,8 @@ "tsc": "lerna run tsc --stream", "types:lint:fix": "lerna run lint:fix --scope @nymproject/types --scope @nymproject/nym-wallet-app", "audit:fix": "npm_config_yes=true npx yarn-audit-fix -- --dry-run", - "preinstall": "yarn install:copy-placeholders && yarn install:copy-storage-placeholders", - "install:copy-placeholders": "cp scripts/build/yarn/wasm-placeholder/package.json sdk/typescript/packages/nym-client-wasm", - "install:copy-storage-placeholders": "mkdir -p nym-browser-extension/storage/pkg && cp scripts/build/yarn/storage-placeholder/package.json nym-browser-extension/storage/pkg" + "preinstall": "yarn install:copy-placeholders", + "install:copy-placeholders": "cp scripts/build/yarn/wasm-placeholder/package.json sdk/typescript/packages/nym-client-wasm" }, "devDependencies": { "lerna": "^6.6.2", From 0af9b3c6c87cb92cd789c65238ac4752c320ec39 Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Tue, 8 Aug 2023 14:17:55 +0200 Subject: [PATCH 36/46] Revert package.json changes needed temporary build --- package.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index cad6eaf88d..523db5363f 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "ts-packages/*", "nym-wallet", "nym-connect/**", + "nym-browser-extension", "explorer", "types", "clients/validator" @@ -28,8 +29,9 @@ "tsc": "lerna run tsc --stream", "types:lint:fix": "lerna run lint:fix --scope @nymproject/types --scope @nymproject/nym-wallet-app", "audit:fix": "npm_config_yes=true npx yarn-audit-fix -- --dry-run", - "preinstall": "yarn install:copy-placeholders", - "install:copy-placeholders": "cp scripts/build/yarn/wasm-placeholder/package.json sdk/typescript/packages/nym-client-wasm" + "preinstall": "yarn install:copy-placeholders && yarn install:copy-storage-placeholders", + "install:copy-placeholders": "cp scripts/build/yarn/wasm-placeholder/package.json sdk/typescript/packages/nym-client-wasm", + "install:copy-storage-placeholders": "mkdir -p nym-browser-extension/storage/pkg && cp scripts/build/yarn/storage-placeholder/package.json nym-browser-extension/storage/pkg" }, "devDependencies": { "lerna": "^6.6.2", From e00910bcb8088e694586c24b964fb244ecee2d97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Fri, 28 Jul 2023 14:48:33 +0200 Subject: [PATCH 37/46] Add geo-aware mixnet topology provider (#3713) * WIP: initial work * wupwup * WIP: experiments * Move topology provider and requests to own crate * Make sure we use the new crate everywhere * Sort Cargo.toml * Extract out some functions in geo_aware_provider * rustfmt * Add CountryGroup type * Assign unknown as well * wipwip * Add command line flag to socks5-client * Use geo-aware mixnode selection in nym-connect when in medium mode * rustfmt * clippy * Fix nym-connect build * wasm fix * Spelling --- Cargo.lock | 20 ++ Cargo.toml | 5 +- clients/socks5/src/commands/init.rs | 1 + clients/socks5/src/commands/mod.rs | 15 +- clients/socks5/src/commands/run.rs | 13 + clients/webassembly/Cargo.lock | 13 + clients/webassembly/src/client/config.rs | 1 + common/client-core/Cargo.toml | 10 +- .../client-core/src/client/base_client/mod.rs | 15 +- .../topology_control/geo_aware_provider.rs | 319 ++++++++++++++++++ .../src/client/topology_control/mod.rs | 1 + common/client-core/src/config/mod.rs | 22 +- .../src/config/old_config_v1_1_20_2.rs | 1 + .../mixnet-contract/src/mixnode.rs | 4 + common/socks5-client-core/Cargo.toml | 13 +- common/socks5-client-core/src/lib.rs | 1 + explorer-api/Cargo.toml | 17 +- explorer-api/explorer-api-requests/Cargo.toml | 12 + explorer-api/explorer-api-requests/src/lib.rs | 44 +++ .../src/country_statistics/geolocate.rs | 4 +- explorer-api/src/geo_ip/location.rs | 12 + explorer-api/src/mix_node/http.rs | 3 +- explorer-api/src/mix_node/mod.rs | 2 +- explorer-api/src/mix_node/models.rs | 38 +-- explorer-api/src/mix_nodes/http.rs | 2 +- explorer-api/src/mix_nodes/location.rs | 23 +- explorer-api/src/mix_nodes/models.rs | 4 +- nym-connect/desktop/Cargo.lock | 22 +- nym-connect/desktop/src-tauri/src/tasks.rs | 26 +- .../src/allowed_hosts/hosts.rs | 1 - 30 files changed, 568 insertions(+), 96 deletions(-) create mode 100644 common/client-core/src/client/topology_control/geo_aware_provider.rs create mode 100644 explorer-api/explorer-api-requests/Cargo.toml create mode 100644 explorer-api/explorer-api-requests/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index c2eadc94b5..1dcf4528bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1909,6 +1909,7 @@ dependencies = [ "maxminddb", "nym-bin-common", "nym-contracts-common", + "nym-explorer-api-requests", "nym-mixnet-contract-common", "nym-network-defaults", "nym-task", @@ -3782,6 +3783,7 @@ dependencies = [ "nym-config", "nym-credential-storage", "nym-crypto", + "nym-explorer-api-requests", "nym-gateway-client", "nym-gateway-requests", "nym-network-defaults", @@ -3792,6 +3794,7 @@ dependencies = [ "nym-topology", "nym-validator-client", "rand 0.7.3", + "reqwest", "serde", "serde_json", "sha2 0.10.6", @@ -4004,6 +4007,18 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "nym-explorer-api-requests" +version = "0.1.0" +dependencies = [ + "nym-contracts-common", + "nym-mixnet-contract-common", + "nym-validator-client", + "schemars", + "serde", + "ts-rs", +] + [[package]] name = "nym-gateway" version = "1.1.23" @@ -4520,7 +4535,9 @@ dependencies = [ "nym-bandwidth-controller", "nym-client-core", "nym-config", + "nym-contracts-common", "nym-credential-storage", + "nym-mixnet-contract-common", "nym-network-defaults", "nym-service-providers-common", "nym-socks5-proxy-helpers", @@ -4530,10 +4547,13 @@ dependencies = [ "nym-validator-client", "pin-project", "rand 0.7.3", + "reqwest", + "schemars", "serde", "tap", "thiserror", "tokio", + "url", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 666d1f76fc..198f37890e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -74,6 +74,7 @@ members = [ "common/types", "common/wasm-utils", "explorer-api", + "explorer-api/explorer-api-requests", "gateway", "gateway/gateway-requests", "integrations/bity", @@ -135,15 +136,17 @@ cw4 = { version = "=1.1.0" } cw-controllers = { version = "=1.1.0" } dotenvy = "0.15.6" generic-array = "0.14.7" -k256 = "0.13" getrandom = "0.2.10" +k256 = "0.13" lazy_static = "1.4.0" log = "0.4" once_cell = "1.7.2" rand = "0.8.5" +reqwest = "0.11.18" serde = "1.0.152" serde_json = "1.0.91" tap = "1.0.1" +tendermint-rpc = "=0.32" # same version as used by cosmrs thiserror = "1.0.38" tokio = "1.24.1" url = "2.2" diff --git a/clients/socks5/src/commands/init.rs b/clients/socks5/src/commands/init.rs index 76337b84ac..ef370c54b8 100644 --- a/clients/socks5/src/commands/init.rs +++ b/clients/socks5/src/commands/init.rs @@ -94,6 +94,7 @@ impl From for OverrideConfig { use_anonymous_replies: init_config.use_reply_surbs, fastmode: init_config.fastmode, no_cover: init_config.no_cover, + geo_routing: None, medium_toggle: false, nyxd_urls: init_config.nyxd_urls, enabled_credentials_mode: init_config.enabled_credentials_mode, diff --git a/clients/socks5/src/commands/mod.rs b/clients/socks5/src/commands/mod.rs index 5ef887a3a2..393429246d 100644 --- a/clients/socks5/src/commands/mod.rs +++ b/clients/socks5/src/commands/mod.rs @@ -16,7 +16,8 @@ use nym_client_core::client::base_client::storage::gateway_details::{ OnDiskGatewayDetails, PersistedGatewayDetails, }; use nym_client_core::client::key_manager::persistence::OnDiskKeys; -use nym_client_core::config::GatewayEndpointConfig; +use nym_client_core::client::topology_control::geo_aware_provider::CountryGroup; +use nym_client_core::config::{GatewayEndpointConfig, TopologyStructure}; use nym_client_core::error::ClientCoreError; use nym_config::OptionalSet; use nym_sphinx::params::{PacketSize, PacketType}; @@ -75,6 +76,7 @@ pub(crate) struct OverrideConfig { use_anonymous_replies: Option, fastmode: bool, no_cover: bool, + geo_routing: Option, medium_toggle: bool, nyxd_urls: Option>, enabled_credentials_mode: Option, @@ -99,6 +101,13 @@ pub(crate) fn override_config(config: Config, args: OverrideConfig) -> Config { let secondary_packet_size = args.medium_toggle.then_some(PacketSize::ExtendedPacket16); let no_per_hop_delays = args.medium_toggle; + let topology_structure = if args.medium_toggle || args.geo_routing.is_some() { + // TODO: rethink the default group. I just picked one for now. + TopologyStructure::GeoAware(args.geo_routing.unwrap_or(CountryGroup::Europe)) + } else { + TopologyStructure::default() + }; + let packet_type = if args.outfox { PacketType::Outfox } else { @@ -122,6 +131,10 @@ pub(crate) fn override_config(config: Config, args: OverrideConfig) -> Config { // NOTE: see comment above about the order of the other disble cover traffic config .with_base(BaseClientConfig::with_disabled_cover_traffic, args.no_cover) .with_base(BaseClientConfig::with_packet_type, packet_type) + .with_base( + BaseClientConfig::with_topology_structure, + topology_structure, + ) .with_optional(Config::with_anonymous_replies, args.use_anonymous_replies) .with_optional(Config::with_port, args.port) .with_optional_base_custom_env( diff --git a/clients/socks5/src/commands/run.rs b/clients/socks5/src/commands/run.rs index 5d54038c06..8dd289e2bf 100644 --- a/clients/socks5/src/commands/run.rs +++ b/clients/socks5/src/commands/run.rs @@ -11,6 +11,7 @@ use clap::Args; use log::*; use nym_bin_common::version_checker::is_minor_version_compatible; use nym_client_core::client::base_client::storage::OnDiskPersistent; +use nym_client_core::client::topology_control::geo_aware_provider::CountryGroup; use nym_crypto::asymmetric::identity; use nym_socks5_client_core::NymClient; use nym_sphinx::addressing::clients::Recipient; @@ -60,6 +61,10 @@ pub(crate) struct Run { #[clap(long, hide = true)] no_cover: bool, + /// Set geo-aware mixnode selection when sending mixnet traffic, for experiments only. + #[clap(long, hide = true, value_parser = validate_country_group)] + geo_routing: Option, + /// Enable medium mixnet traffic, for experiments only. /// This includes things like disabling cover traffic, no per hop delays, etc. #[clap(long, hide = true)] @@ -82,6 +87,7 @@ impl From for OverrideConfig { use_anonymous_replies: run_config.use_anonymous_replies, fastmode: run_config.fastmode, no_cover: run_config.no_cover, + geo_routing: run_config.geo_routing, medium_toggle: run_config.medium_toggle, nyxd_urls: run_config.nyxd_urls, enabled_credentials_mode: run_config.enabled_credentials_mode, @@ -90,6 +96,13 @@ impl From for OverrideConfig { } } +fn validate_country_group(s: &str) -> Result { + match s.parse() { + Ok(cg) => Ok(cg), + Err(_) => Err(format!("failed to parse country group: {}", s)), + } +} + // this only checks compatibility between config the binary. It does not take into consideration // network version. It might do so in the future. fn version_check(cfg: &Config) -> bool { diff --git a/clients/webassembly/Cargo.lock b/clients/webassembly/Cargo.lock index 793f321a97..0ea047444e 100644 --- a/clients/webassembly/Cargo.lock +++ b/clients/webassembly/Cargo.lock @@ -2475,6 +2475,7 @@ dependencies = [ "nym-config", "nym-credential-storage", "nym-crypto", + "nym-explorer-api-requests", "nym-gateway-client", "nym-gateway-requests", "nym-network-defaults", @@ -2485,6 +2486,7 @@ dependencies = [ "nym-topology", "nym-validator-client", "rand 0.7.3", + "reqwest", "serde", "serde_json", "sha2 0.10.6", @@ -2689,6 +2691,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "nym-explorer-api-requests" +version = "0.1.0" +dependencies = [ + "nym-contracts-common", + "nym-mixnet-contract-common", + "nym-validator-client", + "schemars", + "serde", +] + [[package]] name = "nym-gateway-client" version = "0.1.0" diff --git a/clients/webassembly/src/client/config.rs b/clients/webassembly/src/client/config.rs index 07d9ab5f5f..f63d1456ac 100644 --- a/clients/webassembly/src/client/config.rs +++ b/clients/webassembly/src/client/config.rs @@ -246,6 +246,7 @@ impl From for ConfigTopology { topology.topology_resolution_timeout_ms, ), disable_refreshing: topology.disable_refreshing, + topology_structure: Default::default(), } } } diff --git a/common/client-core/Cargo.toml b/common/client-core/Cargo.toml index ab1c9b8c04..0811b08add 100644 --- a/common/client-core/Cargo.toml +++ b/common/client-core/Cargo.toml @@ -10,27 +10,29 @@ rust-version = "1.66" [dependencies] async-trait = { workspace = true } base64 = "0.21.2" -dirs = "4.0" dashmap = "5.4.0" +dirs = "4.0" futures = "0.3" humantime-serde = "1.0" log = { workspace = true } rand = { version = "0.7.3", features = ["wasm-bindgen"] } +reqwest = { workspace = true } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } sha2 = "0.10.6" tap = "1.0.1" thiserror = "1.0.34" -url = { version ="2.2", features = ["serde"] } -tungstenite = { version = "0.13.0", default-features = false } -tokio = { version = "1.24.1", features = ["macros"]} time = "0.3.17" +tokio = { version = "1.24.1", features = ["macros"]} +tungstenite = { version = "0.13.0", default-features = false } +url = { version ="2.2", features = ["serde"] } zeroize = { workspace = true } # internal nym-bandwidth-controller = { path = "../bandwidth-controller" } nym-config = { path = "../config" } nym-crypto = { path = "../crypto" } +nym-explorer-api-requests = { path = "../../explorer-api/explorer-api-requests" } nym-gateway-client = { path = "../client-libs/gateway-client" } #gateway-client = { path = "../../common/client-libs/gateway-client", default-features = false, features = ["wasm", "coconut"] } nym-gateway-requests = { path = "../../gateway/gateway-requests" } diff --git a/common/client-core/src/client/base_client/mod.rs b/common/client-core/src/client/base_client/mod.rs index aecb7eb5c1..a934793953 100644 --- a/common/client-core/src/client/base_client/mod.rs +++ b/common/client-core/src/client/base_client/mod.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use super::received_buffer::ReceivedBufferMessage; +use super::topology_control::geo_aware_provider::GeoAwareTopologyProvider; use crate::client::base_client::storage::MixnetClientStorage; use crate::client::cover_traffic_stream::LoopCoverTrafficStream; use crate::client::inbound_messages::{InputMessage, InputMessageReceiver, InputMessageSender}; @@ -339,14 +340,20 @@ where fn setup_topology_provider( custom_provider: Option>, + provider_from_config: config::TopologyStructure, nym_api_urls: Vec, ) -> Box { // if no custom provider was ... provided ..., create one using nym-api - custom_provider.unwrap_or_else(|| { - Box::new(NymApiTopologyProvider::new( + custom_provider.unwrap_or_else(|| match provider_from_config { + config::TopologyStructure::NymApi => Box::new(NymApiTopologyProvider::new( nym_api_urls, env!("CARGO_PKG_VERSION").to_string(), - )) + )), + config::TopologyStructure::GeoAware(group) => Box::new(GeoAwareTopologyProvider::new( + nym_api_urls, + env!("CARGO_PKG_VERSION").to_string(), + group, + )), }) } @@ -521,8 +528,10 @@ where let topology_provider = Self::setup_topology_provider( self.custom_topology_provider.take(), + self.config.debug.topology.topology_structure, self.config.get_nym_api_endpoints(), ); + Self::start_topology_refresher( topology_provider, self.config.debug.topology, diff --git a/common/client-core/src/client/topology_control/geo_aware_provider.rs b/common/client-core/src/client/topology_control/geo_aware_provider.rs new file mode 100644 index 0000000000..268f6612e0 --- /dev/null +++ b/common/client-core/src/client/topology_control/geo_aware_provider.rs @@ -0,0 +1,319 @@ +use std::{collections::HashMap, fmt}; + +use log::{debug, error, info}; +use nym_explorer_api_requests::PrettyDetailedMixNodeBond; +use nym_topology::{ + nym_topology_from_detailed, + provider_trait::{async_trait, TopologyProvider}, + NymTopology, +}; +use nym_validator_client::client::MixId; +use rand::{prelude::SliceRandom, thread_rng}; +use serde::{Deserialize, Serialize}; +use url::Url; + +const MIN_NODES_PER_LAYER: usize = 1; +const EXPLORER_API_MIXNODES_URL: &str = "https://explorer.nymtech.net/api/v1/mix-nodes"; + +// TODO: create a explorer-api-client +async fn fetch_mixnodes_from_explorer_api() -> Option> { + reqwest::get(EXPLORER_API_MIXNODES_URL) + .await + .ok()? + .json::>() + .await + .ok() +} + +#[derive(Copy, Clone, Hash, PartialEq, Eq, Serialize, Deserialize, Debug)] +pub enum CountryGroup { + Europe, + NorthAmerica, + SouthAmerica, + Oceania, + Asia, + Africa, + Unknown, +} + +impl CountryGroup { + // We map contry codes into group, which initially are continent codes to a first approximation, + // but we do it manually to reserve the right to tweak this distribution for our purposes. + fn new(country_code: &str) -> Self { + let country_code = country_code.to_uppercase(); + use CountryGroup::*; + match country_code.as_ref() { + // Europe + "AT" => Europe, + "BG" => Europe, + "CH" => Europe, + "CY" => Europe, + "CZ" => Europe, + "DE" => Europe, + "DK" => Europe, + "ES" => Europe, + "FI" => Europe, + "FR" => Europe, + "GB" => Europe, + "GR" => Europe, + "IE" => Europe, + "IT" => Europe, + "LT" => Europe, + "LU" => Europe, + "LV" => Europe, + "MD" => Europe, + "MT" => Europe, + "NL" => Europe, + "NO" => Europe, + "PL" => Europe, + "RO" => Europe, + "SE" => Europe, + "SK" => Europe, + "TR" => Europe, + "UA" => Europe, + + // North America + "CA" => NorthAmerica, + "MX" => NorthAmerica, + "US" => NorthAmerica, + + // South America + "AR" => SouthAmerica, + "BR" => SouthAmerica, + "CL" => SouthAmerica, + "CO" => SouthAmerica, + "CR" => SouthAmerica, + "GT" => SouthAmerica, + + // Oceania + "AU" => Oceania, + + // Asia + "AM" => Asia, + "BH" => Asia, + "CN" => Asia, + "GE" => Asia, + "HK" => Asia, + "ID" => Asia, + "IL" => Asia, + "IN" => Asia, + "JP" => Asia, + "KH" => Asia, + "KR" => Asia, + "KZ" => Asia, + "MY" => Asia, + "RU" => Asia, + "SG" => Asia, + "TH" => Asia, + "VN" => Asia, + + // Africa + "SC" => Africa, + "UG" => Africa, + "ZA" => Africa, + + // And group level codes work too + "EU" => Europe, + "NA" => NorthAmerica, + "SA" => SouthAmerica, + "OC" => Oceania, + "AS" => Asia, + "AF" => Africa, + + // And some aliases + "EUROPE" => Europe, + "NORTHAMERICA" => NorthAmerica, + "SOUTHAMERICA" => SouthAmerica, + "OCEANIA" => Oceania, + "ASIA" => Asia, + "AFRICA" => Africa, + + _ => { + info!("Unknown country code: {}", country_code); + Unknown + } + } + } +} + +impl fmt::Display for CountryGroup { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use CountryGroup::*; + match self { + Europe => write!(f, "EU"), + NorthAmerica => write!(f, "NA"), + SouthAmerica => write!(f, "SA"), + Oceania => write!(f, "OC"), + Asia => write!(f, "AS"), + Africa => write!(f, "AF"), + Unknown => write!(f, "Unknown"), + } + } +} + +impl std::str::FromStr for CountryGroup { + type Err = (); + + fn from_str(s: &str) -> Result { + let group = CountryGroup::new(s); + if group == CountryGroup::Unknown { + Err(()) + } else { + Ok(group) + } + } +} + +impl CountryGroup { + #[allow(unused)] + fn known(self) -> Option { + use CountryGroup::*; + match self { + Europe | NorthAmerica | SouthAmerica | Oceania | Asia | Africa => Some(self), + Unknown => None, + } + } +} + +fn group_mixnodes_by_country_code( + mixnodes: Vec, +) -> HashMap> { + mixnodes + .into_iter() + .fold(HashMap::>::new(), |mut acc, m| { + if let Some(ref location) = m.location { + let country_code = location.two_letter_iso_country_code.clone(); + let group_code = CountryGroup::new(country_code.as_str()); + let mixnodes = acc.entry(group_code).or_insert_with(Vec::new); + mixnodes.push(m.mix_id); + } + acc + }) +} + +fn log_mixnode_distribution(mixnodes: &HashMap>) { + let mixnode_distribution = mixnodes + .iter() + .map(|(k, v)| format!("{}: {}", k, v.len())) + .collect::>() + .join(", "); + debug!("Mixnode distribution - {}", mixnode_distribution); +} + +fn check_layer_integrity(topology: NymTopology) -> Result<(), ()> { + let mixes = topology.mixes(); + if mixes.keys().len() < 3 { + error!("Layer is missing in topology!"); + return Err(()); + } + for (layer, mixnodes) in mixes { + debug!("Layer {:?} has {} mixnodes", layer, mixnodes.len()); + if mixnodes.len() < MIN_NODES_PER_LAYER { + error!( + "There are only {} mixnodes in layer {:?}", + mixnodes.len(), + layer + ); + return Err(()); + } + } + Ok(()) +} + +pub struct GeoAwareTopologyProvider { + validator_client: nym_validator_client::client::NymApiClient, + filter_on: CountryGroup, + client_version: String, +} + +impl GeoAwareTopologyProvider { + pub fn new( + mut nym_api_urls: Vec, + client_version: String, + filter_on: CountryGroup, + ) -> GeoAwareTopologyProvider { + log::info!( + "Creating geo-aware topology provider with filter on {:?}", + filter_on + ); + nym_api_urls.shuffle(&mut thread_rng()); + + GeoAwareTopologyProvider { + validator_client: nym_validator_client::client::NymApiClient::new( + nym_api_urls[0].clone(), + ), + filter_on, + client_version, + } + } + + async fn get_topology(&self) -> Option { + let mixnodes = match self.validator_client.get_cached_active_mixnodes().await { + Err(err) => { + error!("failed to get network mixnodes - {err}"); + return None; + } + Ok(mixes) => mixes, + }; + + let gateways = match self.validator_client.get_cached_gateways().await { + Err(err) => { + error!("failed to get network gateways - {err}"); + return None; + } + Ok(gateways) => gateways, + }; + + // Also fetch mixnodes cached by explorer-api, with the purpose of getting their + // geolocation. + debug!("Fetching mixnodes from explorer-api..."); + let Some(mixnodes_from_explorer_api) = fetch_mixnodes_from_explorer_api().await else { + error!("failed to get mixnodes from explorer-api"); + return None; + }; + + // Partition mixnodes_from_explorer_api according to the value of + // two_letter_iso_country_code. + // NOTE: we construct the full distribution here, but only use the one we're interested in. + // The reason we this instead of a straight filter is that this opens up the possibility to + // complement a small grouping with mixnodes from adjecent countries. + let mixnode_distribution = group_mixnodes_by_country_code(mixnodes_from_explorer_api); + log_mixnode_distribution(&mixnode_distribution); + + let Some(filtered_mixnode_ids) = mixnode_distribution.get(&self.filter_on) else { + error!("no mixnodes found for: {}", self.filter_on); + return None; + }; + + let mixnodes = mixnodes + .into_iter() + .filter(|m| filtered_mixnode_ids.contains(&m.mix_id())) + .collect::>(); + + let topology = nym_topology_from_detailed(mixnodes, gateways) + .filter_system_version(&self.client_version); + + // TODO: return real error type + check_layer_integrity(topology.clone()).ok()?; + + Some(topology) + } +} + +#[cfg(not(target_arch = "wasm32"))] +#[async_trait] +impl TopologyProvider for GeoAwareTopologyProvider { + // this will be manually refreshed on a timer specified inside mixnet client config + async fn get_new_topology(&mut self) -> Option { + self.get_topology().await + } +} + +#[cfg(target_arch = "wasm32")] +#[async_trait(?Send)] +impl TopologyProvider for GeoAwareTopologyProvider { + // this will be manually refreshed on a timer specified inside mixnet client config + async fn get_new_topology(&mut self) -> Option { + self.get_topology().await + } +} diff --git a/common/client-core/src/client/topology_control/mod.rs b/common/client-core/src/client/topology_control/mod.rs index 0fef523b1e..ed426dde50 100644 --- a/common/client-core/src/client/topology_control/mod.rs +++ b/common/client-core/src/client/topology_control/mod.rs @@ -10,6 +10,7 @@ use nym_topology::NymTopologyError; use std::time::Duration; mod accessor; +pub mod geo_aware_provider; pub(crate) mod nym_api_provider; // TODO: move it to config later diff --git a/common/client-core/src/config/mod.rs b/common/client-core/src/config/mod.rs index e8f08adfaa..465c227e19 100644 --- a/common/client-core/src/config/mod.rs +++ b/common/client-core/src/config/mod.rs @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize}; use std::time::Duration; use url::Url; -use crate::error::ClientCoreError; +use crate::{client::topology_control::geo_aware_provider::CountryGroup, error::ClientCoreError}; #[cfg(target_arch = "wasm32")] use wasm_bindgen::prelude::*; @@ -158,6 +158,15 @@ impl Config { self } + pub fn with_topology_structure(mut self, topology_structure: TopologyStructure) -> Self { + self.set_topology_structure(topology_structure); + self + } + + pub fn set_topology_structure(&mut self, topology_structure: TopologyStructure) { + self.debug.topology.topology_structure = topology_structure; + } + pub fn with_no_per_hop_delays(mut self, no_per_hop_delays: bool) -> Self { if no_per_hop_delays { self.set_no_per_hop_delays() @@ -466,6 +475,16 @@ pub struct Topology { /// the first valid instance. /// Supersedes `topology_refresh_rate_ms`. pub disable_refreshing: bool, + + /// Specifies the mixnode topology to be used for sending packets. + pub topology_structure: TopologyStructure, +} + +#[derive(Default, Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] +pub enum TopologyStructure { + #[default] + NymApi, + GeoAware(CountryGroup), } impl Default for Topology { @@ -474,6 +493,7 @@ impl Default for Topology { topology_refresh_rate: DEFAULT_TOPOLOGY_REFRESH_RATE, topology_resolution_timeout: DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT, disable_refreshing: false, + topology_structure: TopologyStructure::default(), } } } diff --git a/common/client-core/src/config/old_config_v1_1_20_2.rs b/common/client-core/src/config/old_config_v1_1_20_2.rs index ed0cd0356a..a097b55f2a 100644 --- a/common/client-core/src/config/old_config_v1_1_20_2.rs +++ b/common/client-core/src/config/old_config_v1_1_20_2.rs @@ -267,6 +267,7 @@ impl From for Topology { topology_refresh_rate: value.topology_refresh_rate, topology_resolution_timeout: value.topology_resolution_timeout, disable_refreshing: value.disable_refreshing, + topology_structure: Default::default(), } } } diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs index 248bc7e143..676098fce6 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs @@ -69,6 +69,10 @@ impl MixNodeDetails { self.bond_information.mix_id } + pub fn layer(&self) -> Layer { + self.bond_information.layer + } + pub fn is_unbonding(&self) -> bool { self.bond_information.is_unbonding } diff --git a/common/socks5-client-core/Cargo.toml b/common/socks5-client-core/Cargo.toml index 9ca792f8b1..2e1aa52b32 100644 --- a/common/socks5-client-core/Cargo.toml +++ b/common/socks5-client-core/Cargo.toml @@ -7,22 +7,27 @@ edition = "2021" [dependencies] dirs = "4.0" +futures = "0.3" log = { workspace = true } pin-project = "1.0" rand = { version = "0.7.3", features = ["wasm-bindgen"] } +reqwest = "0.11.4" +schemars = { version = "0.8", features = ["preserve_order"] } serde = { workspace = true, features = ["derive"] } # for config serialization/deserialization -thiserror = "1.0.34" tap = "1.0.1" +thiserror = "1.0.34" tokio = { version = "1.24.1", features = ["rt-multi-thread", "net", "signal"] } -futures = "0.3" +url = "2.2" -nym-client-core = { path = "../client-core", features = ["fs-surb-storage"] } nym-bandwidth-controller = { path = "../../common/bandwidth-controller" } +nym-client-core = { path = "../client-core", features = ["fs-surb-storage"] } nym-config = { path = "../config" } +nym-contracts-common = { path = "../cosmwasm-smart-contracts/contracts-common" } nym-credential-storage = { path = "../credential-storage" } +nym-mixnet-contract-common = { path = "../cosmwasm-smart-contracts/mixnet-contract" } nym-network-defaults = { path = "../network-defaults" } -nym-socks5-proxy-helpers = { path = "../socks5/proxy-helpers" } nym-service-providers-common = { path = "../../service-providers/common" } +nym-socks5-proxy-helpers = { path = "../socks5/proxy-helpers" } nym-socks5-requests = { path = "../socks5/requests" } nym-sphinx = { path = "../nymsphinx" } nym-task = { path = "../task" } diff --git a/common/socks5-client-core/src/lib.rs b/common/socks5-client-core/src/lib.rs index 2070eeaf71..74d27b69ed 100644 --- a/common/socks5-client-core/src/lib.rs +++ b/common/socks5-client-core/src/lib.rs @@ -24,6 +24,7 @@ use nym_credential_storage::storage::Storage as CredentialStorage; use nym_sphinx::addressing::clients::Recipient; use nym_sphinx::params::PacketType; use nym_task::{TaskClient, TaskManager}; + use std::error::Error; pub mod config; diff --git a/explorer-api/Cargo.toml b/explorer-api/Cargo.toml index ab0a56612b..d6941a19e1 100644 --- a/explorer-api/Cargo.toml +++ b/explorer-api/Cargo.toml @@ -8,13 +8,18 @@ edition = "2021" [dependencies] chrono = { version = "0.4.19", features = ["serde"] } clap = { version = "4.0", features = ["cargo", "derive"] } +dotenvy = "0.15.6" humantime-serde = "1.0" isocountry = "0.3.2" itertools = "0.10.3" lazy_static = "1.4.0" log = { workspace = true } +maxminddb = "0.23.0" okapi = { version = "0.7.0-rc.1", features = ["impl_json_schema"] } pretty_env_logger = "0.4.0" +rand = "0.8.5" +rand_pcg = "0.3.1" +rand_seeder = "0.2.3" reqwest = "0.11.4" rocket = { version = "0.5.0-rc.2", features = ["json"] } rocket_cors = { git="https://github.com/lawliet89/rocket_cors", rev="dfd3662c49e2f6fc37df35091cb94d82f7fb5915" } @@ -24,15 +29,11 @@ serde = "1.0.126" serde_json = "1.0.66" thiserror = "1.0.29" tokio = {version = "1.21.2", features = ["full"] } -maxminddb = "0.23.0" -dotenvy = "0.15.6" -rand = "0.8.5" -rand_seeder = "0.2.3" -rand_pcg = "0.3.1" -nym-mixnet-contract-common = { path = "../common/cosmwasm-smart-contracts/mixnet-contract" } -nym-contracts-common = { path = "../common/cosmwasm-smart-contracts/contracts-common" } -nym-network-defaults = { path = "../common/network-defaults" } nym-bin-common = { path = "../common/bin-common"} +nym-contracts-common = { path = "../common/cosmwasm-smart-contracts/contracts-common" } +nym-explorer-api-requests = { path = "explorer-api-requests" } +nym-mixnet-contract-common = { path = "../common/cosmwasm-smart-contracts/mixnet-contract" } +nym-network-defaults = { path = "../common/network-defaults" } nym-task = { path = "../common/task" } nym-validator-client = { path = "../common/client-libs/validator-client", features=["http-client"] } diff --git a/explorer-api/explorer-api-requests/Cargo.toml b/explorer-api/explorer-api-requests/Cargo.toml new file mode 100644 index 0000000000..93c8faaada --- /dev/null +++ b/explorer-api/explorer-api-requests/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "nym-explorer-api-requests" +version = "0.1.0" +edition = "2021" + +[dependencies] +nym-contracts-common = { path = "../../common/cosmwasm-smart-contracts/contracts-common" } +nym-mixnet-contract-common = { path = "../../common/cosmwasm-smart-contracts/mixnet-contract" } +nym-validator-client = { path = "../../common/client-libs/validator-client" } +schemars = { version = "0.8", features = ["preserve_order"] } +serde = { version = "1.0", features = ["derive"] } +ts-rs = { version = "6.1.2", optional = true } diff --git a/explorer-api/explorer-api-requests/src/lib.rs b/explorer-api/explorer-api-requests/src/lib.rs new file mode 100644 index 0000000000..bfcafa2860 --- /dev/null +++ b/explorer-api/explorer-api-requests/src/lib.rs @@ -0,0 +1,44 @@ +use nym_contracts_common::Percent; +use nym_mixnet_contract_common::{Addr, Coin, Layer, MixId, MixNode}; +use nym_validator_client::models::NodePerformance; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)] +#[serde(rename_all = "snake_case")] +pub enum MixnodeStatus { + Active, // in both the active set and the rewarded set + Standby, // only in the rewarded set + Inactive, // in neither the rewarded set nor the active set +} + +#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] +pub struct PrettyDetailedMixNodeBond { + pub mix_id: MixId, + pub location: Option, + pub status: MixnodeStatus, + pub pledge_amount: Coin, + pub total_delegation: Coin, + pub owner: Addr, + pub layer: Layer, + pub mix_node: MixNode, + pub stake_saturation: f32, + pub uncapped_saturation: f32, + pub avg_uptime: u8, + pub node_performance: NodePerformance, + pub estimated_operator_apy: f64, + pub estimated_delegators_apy: f64, + pub operating_cost: Coin, + pub profit_margin_percent: Percent, + pub family_id: Option, + pub blacklisted: bool, +} + +#[derive(Clone, Debug, JsonSchema, Serialize, Deserialize)] +pub struct Location { + pub two_letter_iso_country_code: String, + pub three_letter_iso_country_code: String, + pub country_name: String, + pub latitude: Option, + pub longitude: Option, +} diff --git a/explorer-api/src/country_statistics/geolocate.rs b/explorer-api/src/country_statistics/geolocate.rs index 8158c6e65e..a80ebc28e4 100644 --- a/explorer-api/src/country_statistics/geolocate.rs +++ b/explorer-api/src/country_statistics/geolocate.rs @@ -1,9 +1,9 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::mix_nodes::location::Location; use crate::state::ExplorerApiStateContext; use log::{info, warn}; +use nym_explorer_api_requests::Location; use nym_task::TaskClient; pub(crate) struct GeoLocateTask { @@ -64,7 +64,7 @@ impl GeoLocateTask { ) { Ok(opt) => match opt { Some(location) => { - let location = Location::new(location); + let location: Location = location.into(); trace!( "{} mix nodes already located. Ip {} is located in {:#?}", diff --git a/explorer-api/src/geo_ip/location.rs b/explorer-api/src/geo_ip/location.rs index adbdb6cef3..fdb8584938 100644 --- a/explorer-api/src/geo_ip/location.rs +++ b/explorer-api/src/geo_ip/location.rs @@ -42,6 +42,18 @@ pub(crate) struct Location { pub(crate) longitude: Option, } +impl From for nym_explorer_api_requests::Location { + fn from(location: Location) -> Self { + nym_explorer_api_requests::Location { + country_name: location.name, + two_letter_iso_country_code: location.iso_alpha2, + three_letter_iso_country_code: location.iso_alpha3, + latitude: location.latitude, + longitude: location.longitude, + } + } +} + impl GeoIp { pub fn new() -> Self { let db_path = std::env::var("GEOIP_DB_PATH").unwrap_or_else(|e| { diff --git a/explorer-api/src/mix_node/http.rs b/explorer-api/src/mix_node/http.rs index 137c6250ed..e00ed8ff82 100644 --- a/explorer-api/src/mix_node/http.rs +++ b/explorer-api/src/mix_node/http.rs @@ -6,9 +6,10 @@ use crate::mix_node::delegations::{ }; use crate::mix_node::econ_stats::retrieve_mixnode_econ_stats; use crate::mix_node::models::{ - EconomicDynamicsStats, NodeDescription, NodeStats, PrettyDetailedMixNodeBond, SummedDelegations, + EconomicDynamicsStats, NodeDescription, NodeStats, SummedDelegations, }; use crate::state::ExplorerApiStateContext; +use nym_explorer_api_requests::PrettyDetailedMixNodeBond; use nym_mixnet_contract_common::{Delegation, MixId}; use reqwest::Error as ReqwestError; use rocket::response::status::NotFound; diff --git a/explorer-api/src/mix_node/mod.rs b/explorer-api/src/mix_node/mod.rs index 88c3b1cd71..dac365c71d 100644 --- a/explorer-api/src/mix_node/mod.rs +++ b/explorer-api/src/mix_node/mod.rs @@ -1,4 +1,4 @@ pub(crate) mod delegations; pub(crate) mod econ_stats; pub(crate) mod http; -pub(crate) mod models; +pub mod models; diff --git a/explorer-api/src/mix_node/models.rs b/explorer-api/src/mix_node/models.rs index 94ae6558d0..4adfa6dd86 100644 --- a/explorer-api/src/mix_node/models.rs +++ b/explorer-api/src/mix_node/models.rs @@ -2,49 +2,15 @@ // SPDX-License-Identifier: Apache-2.0 use crate::cache::Cache; -use crate::mix_nodes::location::Location; -use nym_contracts_common::Percent; use nym_mixnet_contract_common::Delegation; -use nym_mixnet_contract_common::{Addr, Coin, Layer, MixId, MixNode}; -use nym_validator_client::models::{NodePerformance, SelectionChance}; +use nym_mixnet_contract_common::{Addr, Coin, MixId}; +use nym_validator_client::models::SelectionChance; use serde::Deserialize; use serde::Serialize; use std::sync::Arc; use std::time::SystemTime; use tokio::sync::RwLock; -#[derive(Clone, Debug, Serialize, JsonSchema, PartialEq)] -#[serde(rename_all = "snake_case")] -pub(crate) enum MixnodeStatus { - Active, // in both the active set and the rewarded set - Standby, // only in the rewarded set - Inactive, // in neither the rewarded set nor the active set -} - -#[derive(Clone, Debug, Serialize, JsonSchema)] -pub(crate) struct PrettyDetailedMixNodeBond { - // I leave this to @MS to refactor this type as a lot of things here are redundant thanks to - // the existence of `MixNodeDetails` - pub mix_id: MixId, - pub location: Option, - pub status: MixnodeStatus, - pub pledge_amount: Coin, - pub total_delegation: Coin, - pub owner: Addr, - pub layer: Layer, - pub mix_node: MixNode, - pub stake_saturation: f32, - pub uncapped_saturation: f32, - pub avg_uptime: u8, - pub node_performance: NodePerformance, - pub estimated_operator_apy: f64, - pub estimated_delegators_apy: f64, - pub operating_cost: Coin, - pub profit_margin_percent: Percent, - pub family_id: Option, - pub blacklisted: bool, -} - #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, JsonSchema)] pub struct SummedDelegations { pub owner: Addr, diff --git a/explorer-api/src/mix_nodes/http.rs b/explorer-api/src/mix_nodes/http.rs index ef5570e455..a36843b66f 100644 --- a/explorer-api/src/mix_nodes/http.rs +++ b/explorer-api/src/mix_nodes/http.rs @@ -1,6 +1,6 @@ -use crate::mix_node::models::{MixnodeStatus, PrettyDetailedMixNodeBond}; use crate::mix_nodes::models::{MixNodeActiveSetSummary, MixNodeSummary}; use crate::state::ExplorerApiStateContext; +use nym_explorer_api_requests::{MixnodeStatus, PrettyDetailedMixNodeBond}; use rocket::serde::json::Json; use rocket::{Route, State}; use rocket_okapi::okapi::openapi3::OpenApi; diff --git a/explorer-api/src/mix_nodes/location.rs b/explorer-api/src/mix_nodes/location.rs index b876cdc792..4908564697 100644 --- a/explorer-api/src/mix_nodes/location.rs +++ b/explorer-api/src/mix_nodes/location.rs @@ -1,7 +1,7 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::geo_ip::location; +use nym_explorer_api_requests::Location; use nym_mixnet_contract_common::MixId; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -31,27 +31,6 @@ pub(crate) struct LocationCacheItem { pub(crate) valid_until: SystemTime, } -#[derive(Clone, Debug, JsonSchema, Serialize, Deserialize)] -pub(crate) struct Location { - pub(crate) two_letter_iso_country_code: String, - pub(crate) three_letter_iso_country_code: String, - pub(crate) country_name: String, - pub(crate) latitude: Option, - pub(crate) longitude: Option, -} - -impl Location { - pub(crate) fn new(location: location::Location) -> Self { - Location { - country_name: location.name, - two_letter_iso_country_code: location.iso_alpha2, - three_letter_iso_country_code: location.iso_alpha3, - latitude: location.latitude, - longitude: location.longitude, - } - } -} - impl LocationCacheItem { pub(crate) fn new_from_location(location: Option) -> Self { LocationCacheItem { diff --git a/explorer-api/src/mix_nodes/models.rs b/explorer-api/src/mix_nodes/models.rs index bfead42c8c..b107bb2168 100644 --- a/explorer-api/src/mix_nodes/models.rs +++ b/explorer-api/src/mix_nodes/models.rs @@ -5,6 +5,7 @@ use std::collections::{HashMap, HashSet}; use std::sync::Arc; use std::time::{Duration, SystemTime}; +use nym_explorer_api_requests::{Location, MixnodeStatus, PrettyDetailedMixNodeBond}; use nym_mixnet_contract_common::rewarding::helpers::truncate_reward; use nym_mixnet_contract_common::MixId; use serde::Serialize; @@ -14,8 +15,7 @@ use crate::helpers::best_effort_small_dec_to_f64; use nym_validator_client::models::MixNodeBondAnnotated; use super::utils::family_numerical_id; -use crate::mix_node::models::{MixnodeStatus, PrettyDetailedMixNodeBond}; -use crate::mix_nodes::location::{Location, LocationCache, LocationCacheItem}; +use crate::mix_nodes::location::{LocationCache, LocationCacheItem}; use crate::mix_nodes::CACHE_ENTRY_TTL; #[derive(Clone, Debug, Serialize, JsonSchema)] diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 5897f51672..c522d297d1 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -3559,6 +3559,7 @@ dependencies = [ "nym-config", "nym-credential-storage", "nym-crypto", + "nym-explorer-api-requests", "nym-gateway-client", "nym-gateway-requests", "nym-network-defaults", @@ -3569,6 +3570,7 @@ dependencies = [ "nym-topology", "nym-validator-client", "rand 0.7.3", + "reqwest", "serde", "serde_json", "sha2 0.10.6", @@ -3780,6 +3782,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "nym-explorer-api-requests" +version = "0.1.0" +dependencies = [ + "nym-contracts-common", + "nym-mixnet-contract-common", + "nym-validator-client", + "schemars", + "serde", +] + [[package]] name = "nym-gateway-client" version = "0.1.0" @@ -3979,7 +3992,9 @@ dependencies = [ "nym-bandwidth-controller", "nym-client-core", "nym-config", + "nym-contracts-common", "nym-credential-storage", + "nym-mixnet-contract-common", "nym-network-defaults", "nym-service-providers-common", "nym-socks5-proxy-helpers", @@ -3989,10 +4004,13 @@ dependencies = [ "nym-validator-client", "pin-project", "rand 0.7.3", + "reqwest", + "schemars", "serde", "tap", "thiserror", "tokio", + "url", ] [[package]] @@ -5121,9 +5139,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "reqwest" -version = "0.11.15" +version = "0.11.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ba30cc2c0cd02af1222ed216ba659cdb2f879dfe3181852fe7c50b1d0005949" +checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" dependencies = [ "base64 0.21.2", "bytes", diff --git a/nym-connect/desktop/src-tauri/src/tasks.rs b/nym-connect/desktop/src-tauri/src/tasks.rs index 8c69b1be7e..06b0809c2f 100644 --- a/nym-connect/desktop/src-tauri/src/tasks.rs +++ b/nym-connect/desktop/src-tauri/src/tasks.rs @@ -1,17 +1,23 @@ use futures::{channel::mpsc, StreamExt}; -use nym_client_core::client::base_client::storage::gateway_details::GatewayDetailsStore; -use nym_client_core::client::base_client::storage::{MixnetClientStorage, OnDiskPersistent}; -use nym_client_core::{config::GatewayEndpointConfig, error::ClientCoreStatusMessage}; -use nym_socks5_client_core::NymClient as Socks5NymClient; -use nym_socks5_client_core::Socks5ControlMessageSender; +use nym_client_core::{ + client::{ + base_client::storage::{ + gateway_details::GatewayDetailsStore, MixnetClientStorage, OnDiskPersistent, + }, + topology_control::geo_aware_provider::CountryGroup, + }, + config::{GatewayEndpointConfig, TopologyStructure}, + error::ClientCoreStatusMessage, +}; +use nym_socks5_client_core::{NymClient as Socks5NymClient, Socks5ControlMessageSender}; use nym_sphinx::params::PacketSize; use nym_task::manager::TaskStatus; use std::sync::Arc; use tap::TapFallible; use tokio::sync::RwLock; -use crate::config::{Config, PrivacyLevel}; use crate::{ + config::{Config, PrivacyLevel}, error::Result, events::{self, emit_event, emit_status_event}, models::{ConnectionStatusKind, ConnectivityTestResult}, @@ -46,6 +52,14 @@ fn override_config_from_env(config: &mut Config, privacy_level: &PrivacyLevel) { log::warn!("Disabling per-hop delay"); config.core.base.set_no_per_hop_delays(); + + // TODO: selectable in the UI + let default_country_group = CountryGroup::Europe; + log::warn!("Using geo-aware mixnode selection: {default_country_group}"); + config + .core + .base + .set_topology_structure(TopologyStructure::GeoAware(default_country_group)); } } diff --git a/service-providers/network-requester/src/allowed_hosts/hosts.rs b/service-providers/network-requester/src/allowed_hosts/hosts.rs index 5c48369d0d..11aa3dd276 100644 --- a/service-providers/network-requester/src/allowed_hosts/hosts.rs +++ b/service-providers/network-requester/src/allowed_hosts/hosts.rs @@ -136,7 +136,6 @@ impl HostsStore { }) .map(Host::from) .collect(); - dbg!(&hosts); Ok(hosts) } } From 53db18df2c4e29359daef186f9cdb51c6e02f2ca Mon Sep 17 00:00:00 2001 From: mfahampshire Date: Wed, 2 Aug 2023 16:26:41 +0200 Subject: [PATCH 38/46] rephrased intro --- documentation/dev-portal/src/SUMMARY.md | 2 ++ documentation/dev-portal/src/introduction.md | 4 ++-- documentation/dev-portal/src/quickstart/chat-demo.md | 5 +++++ .../dev-portal/src/quickstart/cred-playground.md | 5 +++++ documentation/dev-portal/src/quickstart/overview.md | 12 +++--------- 5 files changed, 17 insertions(+), 11 deletions(-) create mode 100644 documentation/dev-portal/src/quickstart/chat-demo.md create mode 100644 documentation/dev-portal/src/quickstart/cred-playground.md diff --git a/documentation/dev-portal/src/SUMMARY.md b/documentation/dev-portal/src/SUMMARY.md index aeae804662..0e0c02bc58 100644 --- a/documentation/dev-portal/src/SUMMARY.md +++ b/documentation/dev-portal/src/SUMMARY.md @@ -11,6 +11,8 @@ # Quickstart - [Overview](quickstart/overview.md) +- [Chat demo (webapp)](quickstart/chat-demo.md) +- [Coconut Credential Playground (webapp)](quickstart/cred-playground.md) - [SOCKS Proxy (CLI)](quickstart/socks-proxy.md) - [NymConnect Beta (GUI)](quickstart/nymconnect-gui.md) diff --git a/documentation/dev-portal/src/introduction.md b/documentation/dev-portal/src/introduction.md index d679a77c53..7335fab32b 100644 --- a/documentation/dev-portal/src/introduction.md +++ b/documentation/dev-portal/src/introduction.md @@ -1,5 +1,5 @@ # Introduction -Welcome to the Nym Developer Portal, containing the resources and tools needed to build privacy enhanced apps (PEApps) with Nym's technology. Whether you're a seasoned developer or just getting started, our portal is designed to help you create decentralized applications and services utilising the Nym mixnet. +Welcome to the Nym Developer Portal, containing quickstart resources, user manuals, integration information, and tutorials outlining to start building privacy enhanced apps. -Join our community of developers and start building the decentralized future today! +For more in-depth information about nodes, network traffic flows, etc check out the [docs](https://nymtech.net/docs). diff --git a/documentation/dev-portal/src/quickstart/chat-demo.md b/documentation/dev-portal/src/quickstart/chat-demo.md new file mode 100644 index 0000000000..6e2f5c244a --- /dev/null +++ b/documentation/dev-portal/src/quickstart/chat-demo.md @@ -0,0 +1,5 @@ +# Chat demo (webapp) + +You can find a browser-based 'hello world' chat app [here](https://chat-demo.nymtech.net). + +Either open in two browser windows and send messages to yourself, or share with a friend and send messages to each other through the mixnet. diff --git a/documentation/dev-portal/src/quickstart/cred-playground.md b/documentation/dev-portal/src/quickstart/cred-playground.md new file mode 100644 index 0000000000..aa2220940c --- /dev/null +++ b/documentation/dev-portal/src/quickstart/cred-playground.md @@ -0,0 +1,5 @@ +# Coconut Credential Playground (webapp) + +There is a coconut-scheme based Credential Library playground [here](https://coco-demo.nymtech.net/). This is a WASM implementation of our Coconut libraries which generate raw Coconut credentials. Test it to create and re-randomize your own credentials. + +For more information on what is happening here check out the [Coconut docs](https://nymtech.net/docs/coconut.html). diff --git a/documentation/dev-portal/src/quickstart/overview.md b/documentation/dev-portal/src/quickstart/overview.md index b2ac4199c9..534ed60fe5 100644 --- a/documentation/dev-portal/src/quickstart/overview.md +++ b/documentation/dev-portal/src/quickstart/overview.md @@ -1,13 +1,7 @@ # Overview -There are multiple options to quickly connect to Nym and see the network in action without the need for any code changes to your application. At most, these involve running Nym as a second process alongside an existing application in order to send traffic through the mixnet. +There are multiple options to quickly connect to Nym and play with both the mixnet and credentials on the Sandbox testnet. -Demo applications: -* a browser-based 'hello world' [chat application](https://chat-demo.nymtech.net). Either open in two browser windows and send messages to yourself, or share with a friend and send messages to each other through the mixnet! -* a Coconut-scheme based [Credential Library](https://coco-demo.nymtech.net/). This is a WASM implementation of our Coconut libraries which generate raw Coconut credentials. Test it to create and re-randomize your own credentials! -
-Proxy traffic with the Nym Socks5 client: -* set up a plug-and-play connection with the [NymConnect](./nymconnect-gui.md) GUI for proxying Telegram, Electrum, Keybase or Blockstream Green traffic through the mixnet (~2 minutes). -* [Download and run](./socks-proxy.md) the Nym Socks5 client via the CLI, for other desktop applications with SOCKS5 connection options (~30 minutes). +At most, these involve running Nym as a second process alongside an existing application in order to send traffic through the mixnet, most are either interact webpages or a standalone app. -If you've already covered the information in this section, or want to jump straight into integrating/ a Nym connection into an existing application, head to the [Integrations](../integrations/integration-options.md) section. +If you've already covered the information in this section, or want to jump straight into integrating/ a Nym connection into an existing application, head to the [Integrations](../integrations/integration-options.md) section. From 122612fa03441c5758c154a94b4d3b0656189580 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogdan-=C8=98tefan=20Neac=C5=9Fu?= Date: Mon, 7 Aug 2023 12:27:31 +0300 Subject: [PATCH 39/46] Apply fix from feature/ephemera to develop too (#3698) (#3742) --- common/nymsphinx/params/src/packet_sizes.rs | 39 ++++++++++++++++++--- contracts/Cargo.lock | 6 ++++ nym-connect/desktop/Cargo.lock | 2 -- nym-wallet/Cargo.lock | 17 +++++++++ 4 files changed, 57 insertions(+), 7 deletions(-) diff --git a/common/nymsphinx/params/src/packet_sizes.rs b/common/nymsphinx/params/src/packet_sizes.rs index ecae71993d..58d9681efc 100644 --- a/common/nymsphinx/params/src/packet_sizes.rs +++ b/common/nymsphinx/params/src/packet_sizes.rs @@ -2,10 +2,10 @@ // SPDX-License-Identifier: Apache-2.0 use crate::PacketType; -use nym_sphinx_types::{ - header::HEADER_SIZE, MIN_PACKET_SIZE, MIX_PARAMS_LEN, OUTFOX_PACKET_OVERHEAD, - PAYLOAD_OVERHEAD_SIZE, -}; +#[cfg(feature = "sphinx")] +use nym_sphinx_types::{header::HEADER_SIZE, PAYLOAD_OVERHEAD_SIZE}; +#[cfg(feature = "outfox")] +use nym_sphinx_types::{MIN_PACKET_SIZE, MIX_PARAMS_LEN, OUTFOX_PACKET_OVERHEAD}; use serde::{Deserialize, Serialize}; use std::cmp::Ordering; use std::convert::TryFrom; @@ -14,6 +14,7 @@ use std::str::FromStr; use thiserror::Error; // each sphinx packet contains mandatory header and payload padding + markers +#[cfg(feature = "sphinx")] const SPHINX_PACKET_OVERHEAD: usize = HEADER_SIZE + PAYLOAD_OVERHEAD_SIZE; // it's up to the smart people to figure those values out : ) @@ -22,16 +23,23 @@ const SPHINX_PACKET_OVERHEAD: usize = HEADER_SIZE + PAYLOAD_OVERHEAD_SIZE; // TODO: I'm not entirely sure if we can easily extract `::NonceSize` // into a const usize before relevant stuff is stabilised in rust... - +#[cfg(feature = "sphinx")] const ACK_IV_SIZE: usize = 16; +#[cfg(feature = "sphinx")] const ACK_PACKET_SIZE: usize = ACK_IV_SIZE + crate::FRAG_ID_LEN + SPHINX_PACKET_OVERHEAD; +#[cfg(feature = "sphinx")] const REGULAR_PACKET_SIZE: usize = 2 * 1024 + SPHINX_PACKET_OVERHEAD; +#[cfg(feature = "sphinx")] const EXTENDED_PACKET_SIZE_8: usize = 8 * 1024 + SPHINX_PACKET_OVERHEAD; +#[cfg(feature = "sphinx")] const EXTENDED_PACKET_SIZE_16: usize = 16 * 1024 + SPHINX_PACKET_OVERHEAD; +#[cfg(feature = "sphinx")] const EXTENDED_PACKET_SIZE_32: usize = 32 * 1024 + SPHINX_PACKET_OVERHEAD; +#[cfg(feature = "outfox")] const OUTFOX_ACK_PACKET_SIZE: usize = MIN_PACKET_SIZE + OUTFOX_PACKET_OVERHEAD; +#[cfg(feature = "outfox")] const OUTFOX_REGULAR_PACKET_SIZE: usize = 2 * 1024 + OUTFOX_PACKET_OVERHEAD; #[derive(Debug, Error)] @@ -154,39 +162,55 @@ impl TryFrom for PacketSize { impl PacketSize { pub const fn size(self) -> usize { + #[allow(unreachable_patterns)] match self { + #[cfg(feature = "sphinx")] PacketSize::RegularPacket => REGULAR_PACKET_SIZE, + #[cfg(feature = "sphinx")] PacketSize::AckPacket => ACK_PACKET_SIZE, + #[cfg(feature = "sphinx")] PacketSize::ExtendedPacket8 => EXTENDED_PACKET_SIZE_8, + #[cfg(feature = "sphinx")] PacketSize::ExtendedPacket16 => EXTENDED_PACKET_SIZE_16, + #[cfg(feature = "sphinx")] PacketSize::ExtendedPacket32 => EXTENDED_PACKET_SIZE_32, + #[cfg(feature = "outfox")] PacketSize::OutfoxRegularPacket => OUTFOX_REGULAR_PACKET_SIZE, + #[cfg(feature = "outfox")] PacketSize::OutfoxAckPacket => OUTFOX_ACK_PACKET_SIZE, + _ => 0, } } pub const fn header_size(&self) -> usize { + #[allow(unreachable_patterns)] match self { + #[cfg(feature = "sphinx")] PacketSize::RegularPacket | PacketSize::AckPacket | PacketSize::ExtendedPacket8 | PacketSize::ExtendedPacket16 | PacketSize::ExtendedPacket32 => HEADER_SIZE, + #[cfg(feature = "outfox")] PacketSize::OutfoxRegularPacket | PacketSize::OutfoxAckPacket => MIX_PARAMS_LEN, + _ => 0, } } pub const fn payload_overhead(&self) -> usize { #[allow(unreachable_patterns)] match self { + #[cfg(feature = "sphinx")] PacketSize::RegularPacket | PacketSize::AckPacket | PacketSize::ExtendedPacket8 | PacketSize::ExtendedPacket16 | PacketSize::ExtendedPacket32 => PAYLOAD_OVERHEAD_SIZE, + #[cfg(feature = "outfox")] PacketSize::OutfoxRegularPacket | PacketSize::OutfoxAckPacket => { OUTFOX_PACKET_OVERHEAD - MIX_PARAMS_LEN // Mix params are calculated into the total overhead so we take them out here } + _ => 0, } } @@ -244,11 +268,16 @@ impl PacketSize { plaintext_size: usize, packet_type: PacketType, ) -> Result { + #[allow(unreachable_patterns)] let overhead = match packet_type { + #[cfg(feature = "sphinx")] PacketType::Mix => SPHINX_PACKET_OVERHEAD, #[allow(deprecated)] + #[cfg(feature = "sphinx")] PacketType::Vpn => SPHINX_PACKET_OVERHEAD, + #[cfg(feature = "outfox")] PacketType::Outfox => OUTFOX_PACKET_OVERHEAD, + _ => 0, }; let packet_size = plaintext_size + overhead; Self::get_type(packet_size) diff --git a/contracts/Cargo.lock b/contracts/Cargo.lock index 1a87652242..ebeae6d7ea 100644 --- a/contracts/Cargo.lock +++ b/contracts/Cargo.lock @@ -234,6 +234,12 @@ dependencies = [ "libc", ] +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "crypto-bigint" version = "0.4.9" diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index c522d297d1..947ecbf73c 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -4181,8 +4181,6 @@ dependencies = [ name = "nym-sphinx-types" version = "0.2.0" dependencies = [ - "nym-outfox", - "sphinx-packet", "thiserror", ] diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index 2e7df7a43e..b9d551fd84 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -101,6 +101,12 @@ dependencies = [ "password-hash", ] +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + [[package]] name = "async-trait" version = "0.1.64" @@ -464,6 +470,16 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddf3c081b5fba1e5615640aae998e0fbd10c24cbd897ee39ed754a77601a4862" +dependencies = [ + "byteorder", + "keystream", +] + [[package]] name = "cipher" version = "0.4.4" @@ -3120,6 +3136,7 @@ dependencies = [ name = "nym-sphinx-types" version = "0.2.0" dependencies = [ + "sphinx-packet", "thiserror", ] From 5620fd7009e8b4dd54c25ca6fac59ee53c4021da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogdan-=C8=98tefan=20Neac=C8=99u?= Date: Mon, 7 Aug 2023 15:52:03 +0300 Subject: [PATCH 40/46] Set sphinx as default packet type --- common/crypto/Cargo.toml | 1 + common/nymsphinx/Cargo.toml | 5 + common/nymsphinx/framing/Cargo.toml | 5 +- common/nymsphinx/params/Cargo.toml | 1 + common/nymsphinx/types/Cargo.toml | 1 + contracts/Cargo.lock | 236 ++++++++++++++++++++++++++-- nym-connect/desktop/Cargo.lock | 2 + 7 files changed, 233 insertions(+), 18 deletions(-) diff --git a/common/crypto/Cargo.toml b/common/crypto/Cargo.toml index 27702da016..992005f2d4 100644 --- a/common/crypto/Cargo.toml +++ b/common/crypto/Cargo.toml @@ -34,6 +34,7 @@ nym-pemstore = { path = "../../common/pemstore", version = "0.3.0" } rand_chacha = "0.2" [features] +default = ["sphinx"] serde = ["serde_crate", "serde_bytes", "ed25519-dalek/serde", "x25519-dalek/serde"] asymmetric = ["x25519-dalek", "ed25519-dalek", "zeroize"] hashing = ["blake3", "digest", "hkdf", "hmac", "generic-array"] diff --git a/common/nymsphinx/Cargo.toml b/common/nymsphinx/Cargo.toml index df93301876..955051b267 100644 --- a/common/nymsphinx/Cargo.toml +++ b/common/nymsphinx/Cargo.toml @@ -40,3 +40,8 @@ path = "framing" [target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio] version = "1.24.1" features = ["sync"] + +[features] +default = ["sphinx"] +sphinx = ["nym-crypto/sphinx", "nym-sphinx-params/sphinx", "nym-sphinx-types/sphinx"] +outfox = ["nym-crypto/outfox", "nym-sphinx-params/outfox", "nym-sphinx-types/outfox"] diff --git a/common/nymsphinx/framing/Cargo.toml b/common/nymsphinx/framing/Cargo.toml index b510926555..3915f204a2 100644 --- a/common/nymsphinx/framing/Cargo.toml +++ b/common/nymsphinx/framing/Cargo.toml @@ -12,5 +12,6 @@ bytes = "1.0" tokio-util = { version = "0.7.4", features = ["codec"] } thiserror = "1.0.37" -nym-sphinx-types = { path = "../types" } -nym-sphinx-params = { path = "../params" } +nym-sphinx-types = { path = "../types", features = ["sphinx", "outfox"] } +nym-sphinx-params = { path = "../params", features = ["sphinx", "outfox"] } + diff --git a/common/nymsphinx/params/Cargo.toml b/common/nymsphinx/params/Cargo.toml index 57872bb0ca..9d9a5a24e2 100644 --- a/common/nymsphinx/params/Cargo.toml +++ b/common/nymsphinx/params/Cargo.toml @@ -15,5 +15,6 @@ nym-crypto = { path = "../../crypto", features = ["hashing", "symmetric"] } nym-sphinx-types = { path = "../types" } [features] +default = ["sphinx"] sphinx = ["nym-crypto/sphinx", "nym-sphinx-types/outfox"] outfox = ["nym-crypto/outfox", "nym-sphinx-types/outfox"] diff --git a/common/nymsphinx/types/Cargo.toml b/common/nymsphinx/types/Cargo.toml index 0569ef1406..ae348113a0 100644 --- a/common/nymsphinx/types/Cargo.toml +++ b/common/nymsphinx/types/Cargo.toml @@ -13,5 +13,6 @@ nym-outfox = { path = "../../../nym-outfox", optional = true } thiserror = "1" [features] +default = ["sphinx"] sphinx = ["sphinx-packet"] outfox = ["nym-outfox"] diff --git a/contracts/Cargo.lock b/contracts/Cargo.lock index ebeae6d7ea..0f56b6f7a9 100644 --- a/contracts/Cargo.lock +++ b/contracts/Cargo.lock @@ -2,6 +2,19 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "aes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", + "ctr", + "opaque-debug 0.3.0", +] + [[package]] name = "ahash" version = "0.7.6" @@ -19,6 +32,12 @@ version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + [[package]] name = "autocfg" version = "1.1.0" @@ -55,13 +74,25 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "blake2" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330" +dependencies = [ + "byte-tools", + "crypto-mac 0.7.0", + "digest 0.8.1", + "opaque-debug 0.2.3", +] + [[package]] name = "block-buffer" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "generic-array", + "generic-array 0.14.6", ] [[package]] @@ -70,7 +101,7 @@ version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "generic-array", + "generic-array 0.14.6", ] [[package]] @@ -91,6 +122,12 @@ version = "3.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b1ce199063694f33ffb7dd4e0ee620741495c32833cde5aa08f02a0bf96f0c8" +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + [[package]] name = "byteorder" version = "1.4.3" @@ -118,6 +155,25 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddf3c081b5fba1e5615640aae998e0fbd10c24cbd897ee39ed754a77601a4862" +dependencies = [ + "byteorder", + "keystream", +] + +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array 0.14.6", +] + [[package]] name = "coconut-test" version = "0.1.0" @@ -246,9 +302,9 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ - "generic-array", + "generic-array 0.14.6", "rand_core 0.6.4", - "subtle", + "subtle 2.4.1", "zeroize", ] @@ -258,10 +314,39 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "generic-array", + "generic-array 0.14.6", "typenum", ] +[[package]] +name = "crypto-mac" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" +dependencies = [ + "generic-array 0.12.4", + "subtle 1.0.0", +] + +[[package]] +name = "crypto-mac" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +dependencies = [ + "generic-array 0.14.6", + "subtle 2.4.1", +] + +[[package]] +name = "ctr" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" +dependencies = [ + "cipher", +] + [[package]] name = "curve25519-dalek" version = "3.2.0" @@ -271,7 +356,7 @@ dependencies = [ "byteorder", "digest 0.9.0", "rand_core 0.5.1", - "subtle", + "subtle 2.4.1", "zeroize", ] @@ -483,13 +568,22 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array 0.12.4", +] + [[package]] name = "digest" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array", + "generic-array 0.14.6", ] [[package]] @@ -500,7 +594,7 @@ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", "crypto-common", - "subtle", + "subtle 2.4.1", ] [[package]] @@ -576,12 +670,12 @@ dependencies = [ "der", "digest 0.10.7", "ff", - "generic-array", + "generic-array 0.14.6", "group", "pkcs8", "rand_core 0.6.4", "sec1", - "subtle", + "subtle 2.4.1", "zeroize", ] @@ -642,7 +736,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" dependencies = [ "rand_core 0.6.4", - "subtle", + "subtle 2.4.1", ] [[package]] @@ -761,6 +855,15 @@ dependencies = [ "slab", ] +[[package]] +name = "generic-array" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +dependencies = [ + "typenum", +] + [[package]] name = "generic-array" version = "0.14.6" @@ -828,7 +931,7 @@ checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" dependencies = [ "ff", "rand_core 0.6.4", - "subtle", + "subtle 2.4.1", ] [[package]] @@ -852,6 +955,26 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[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 = "hmac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +dependencies = [ + "crypto-mac 0.11.1", + "digest 0.9.0", +] + [[package]] name = "hmac" version = "0.12.1" @@ -952,6 +1075,12 @@ dependencies = [ "sha2 0.10.6", ] +[[package]] +name = "keystream" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33070833c9ee02266356de0c43f723152bd38bd96ddf52c82b3af10c9138b28" + [[package]] name = "lazy_static" version = "1.4.0" @@ -976,6 +1105,12 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "libm" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" + [[package]] name = "libz-sys" version = "1.1.8" @@ -994,6 +1129,18 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" +[[package]] +name = "lioness" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae926706ba42c425c9457121178330d75e273df2e82e28b758faf3de3a9acb9" +dependencies = [ + "arrayref", + "blake2", + "chacha", + "keystream", +] + [[package]] name = "log" version = "0.4.17" @@ -1025,6 +1172,16 @@ dependencies = [ "rand_chacha 0.2.2", ] +[[package]] +name = "num-traits" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +dependencies = [ + "autocfg", + "libm", +] + [[package]] name = "nym-coconut-bandwidth" version = "0.1.0" @@ -1263,6 +1420,7 @@ dependencies = [ name = "nym-sphinx-types" version = "0.2.0" dependencies = [ + "sphinx-packet", "thiserror", ] @@ -1308,6 +1466,12 @@ version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + [[package]] name = "opaque-debug" version = "0.3.0" @@ -1498,6 +1662,16 @@ dependencies = [ "getrandom 0.2.10", ] +[[package]] +name = "rand_distr" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e9532ada3929fb8b2e9dbe28d1e06c9b2cc65813f074fcb6bd5fbefeff9d56" +dependencies = [ + "num-traits", + "rand 0.7.3", +] + [[package]] name = "rand_hc" version = "0.2.0" @@ -1538,7 +1712,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ "crypto-bigint", - "hmac", + "hmac 0.12.1", "zeroize", ] @@ -1647,9 +1821,9 @@ checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ "base16ct", "der", - "generic-array", + "generic-array 0.14.6", "pkcs8", - "subtle", + "subtle 2.4.1", "zeroize", ] @@ -1731,7 +1905,7 @@ dependencies = [ "cfg-if", "cpufeatures", "digest 0.9.0", - "opaque-debug", + "opaque-debug 0.3.0", ] [[package]] @@ -1764,6 +1938,30 @@ dependencies = [ "autocfg", ] +[[package]] +name = "sphinx-packet" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc43eda802856ee82a7555c7b75ceb9e07451741c7a2f5f23d036020e01189d4" +dependencies = [ + "aes", + "arrayref", + "blake2", + "bs58", + "byteorder", + "chacha", + "curve25519-dalek", + "digest 0.9.0", + "hkdf", + "hmac 0.11.0", + "lioness", + "log", + "rand 0.7.3", + "rand_distr", + "sha2 0.9.9", + "subtle 2.4.1", +] + [[package]] name = "spki" version = "0.6.0" @@ -1774,6 +1972,12 @@ dependencies = [ "der", ] +[[package]] +name = "subtle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" + [[package]] name = "subtle" version = "2.4.1" diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 947ecbf73c..c522d297d1 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -4181,6 +4181,8 @@ dependencies = [ name = "nym-sphinx-types" version = "0.2.0" dependencies = [ + "nym-outfox", + "sphinx-packet", "thiserror", ] From 8fda246a3c94aecc46aeb51ff32c0a06f06b2143 Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Tue, 8 Aug 2023 11:15:30 +0200 Subject: [PATCH 41/46] Update changelog and versions for release v1.1.26 --- CHANGELOG.md | 22 +++++++++++++++++++ Cargo.lock | 18 +++++++-------- clients/native/Cargo.toml | 2 +- clients/socks5/Cargo.toml | 2 +- explorer-api/Cargo.toml | 2 +- gateway/Cargo.toml | 2 +- mixnode/Cargo.toml | 2 +- nym-api/Cargo.toml | 2 +- nym-connect/desktop/CHANGELOG.md | 6 +++++ nym-connect/desktop/package.json | 2 +- nym-connect/desktop/src-tauri/Cargo.toml | 2 +- nym-connect/desktop/src-tauri/tauri.conf.json | 2 +- .../network-requester/Cargo.toml | 2 +- .../network-statistics/Cargo.toml | 2 +- tools/nym-cli/Cargo.toml | 2 +- 15 files changed, 49 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f938c81fe3..1ec4a60145 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,28 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https:// ## [Unreleased] +## [v1.1.24] (2023-08-08) + +- Latency based gateway selection is serial and slow ([#3710]) +- Network-requester: strip comments from allow lists ([#3625]) +- Remove (or start maintaining) `upgrade` commands from all binaries ([#3600]) +- Set sphinx as default packet type ([#3748]) +- Apply fix from feature/ephemera to develop too (#3698) ([#3742]) +- Feature/coco demos ([#3732]) +- Add updates to community list projects ([#3722]) +- Add geo-aware mixnet topology provider ([#3713]) +- Add updates to community list projects ([#3711]) + +[#3710]: https://github.com/nymtech/nym/issues/3710 +[#3625]: https://github.com/nymtech/nym/issues/3625 +[#3600]: https://github.com/nymtech/nym/issues/3600 +[#3748]: https://github.com/nymtech/nym/pull/3748 +[#3742]: https://github.com/nymtech/nym/pull/3742 +[#3732]: https://github.com/nymtech/nym/pull/3732 +[#3722]: https://github.com/nymtech/nym/pull/3722 +[#3713]: https://github.com/nymtech/nym/pull/3713 +[#3711]: https://github.com/nymtech/nym/pull/3711 + ## [v1.1.23] (2023-07-04) - nym-cli: add client identity key signing support ([#3576]) diff --git a/Cargo.lock b/Cargo.lock index 1dcf4528bf..85ff104b27 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1896,7 +1896,7 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "explorer-api" -version = "1.1.23" +version = "1.1.24" dependencies = [ "chrono", "clap 4.2.7", @@ -3530,7 +3530,7 @@ dependencies = [ [[package]] name = "nym-api" -version = "1.1.24" +version = "1.1.25" dependencies = [ "anyhow", "async-trait", @@ -3667,7 +3667,7 @@ dependencies = [ [[package]] name = "nym-cli" -version = "1.1.23" +version = "1.1.24" dependencies = [ "anyhow", "base64 0.13.1", @@ -3733,7 +3733,7 @@ dependencies = [ [[package]] name = "nym-client" -version = "1.1.23" +version = "1.1.24" dependencies = [ "clap 4.2.7", "dirs 4.0.0", @@ -4021,7 +4021,7 @@ dependencies = [ [[package]] name = "nym-gateway" -version = "1.1.23" +version = "1.1.24" dependencies = [ "anyhow", "async-trait", @@ -4176,7 +4176,7 @@ dependencies = [ [[package]] name = "nym-mixnode" -version = "1.1.24" +version = "1.1.25" dependencies = [ "anyhow", "bs58 0.4.0", @@ -4293,7 +4293,7 @@ dependencies = [ [[package]] name = "nym-network-requester" -version = "1.1.23" +version = "1.1.24" dependencies = [ "anyhow", "async-file-watcher", @@ -4340,7 +4340,7 @@ dependencies = [ [[package]] name = "nym-network-statistics" -version = "1.1.23" +version = "1.1.24" dependencies = [ "dirs 4.0.0", "log", @@ -4497,7 +4497,7 @@ dependencies = [ [[package]] name = "nym-socks5-client" -version = "1.1.23" +version = "1.1.24" dependencies = [ "clap 4.2.7", "lazy_static", diff --git a/clients/native/Cargo.toml b/clients/native/Cargo.toml index 6064304a90..2135883752 100644 --- a/clients/native/Cargo.toml +++ b/clients/native/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-client" -version = "1.1.23" +version = "1.1.24" authors = ["Dave Hrycyszyn ", "Jędrzej Stuczyński "] description = "Implementation of the Nym Client" edition = "2021" diff --git a/clients/socks5/Cargo.toml b/clients/socks5/Cargo.toml index 658d52a047..afbf36178f 100644 --- a/clients/socks5/Cargo.toml +++ b/clients/socks5/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-socks5-client" -version = "1.1.23" +version = "1.1.24" authors = ["Dave Hrycyszyn "] description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address" edition = "2021" diff --git a/explorer-api/Cargo.toml b/explorer-api/Cargo.toml index d6941a19e1..04e7255d01 100644 --- a/explorer-api/Cargo.toml +++ b/explorer-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "explorer-api" -version = "1.1.23" +version = "1.1.24" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index 763b3ab676..007fcca40d 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-gateway" -version = "1.1.23" +version = "1.1.24" authors = [ "Dave Hrycyszyn ", "Jędrzej Stuczyński ", diff --git a/mixnode/Cargo.toml b/mixnode/Cargo.toml index 9f512f0d85..8421bebb3a 100644 --- a/mixnode/Cargo.toml +++ b/mixnode/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-mixnode" -version = "1.1.24" +version = "1.1.25" authors = [ "Dave Hrycyszyn ", "Jędrzej Stuczyński ", diff --git a/nym-api/Cargo.toml b/nym-api/Cargo.toml index f9b378f59d..50568b440a 100644 --- a/nym-api/Cargo.toml +++ b/nym-api/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-api" -version = "1.1.24" +version = "1.1.25" authors = [ "Dave Hrycyszyn ", "Jędrzej Stuczyński ", diff --git a/nym-connect/desktop/CHANGELOG.md b/nym-connect/desktop/CHANGELOG.md index 1149c3b227..8a0b86151a 100644 --- a/nym-connect/desktop/CHANGELOG.md +++ b/nym-connect/desktop/CHANGELOG.md @@ -2,6 +2,12 @@ ## [Unreleased] +## [v1.1.16] (2023-08-08) + +- Uncouple network-requester <-> gateway in nym-connect and harbourmaster ([#3472]) + +[#3472]: https://github.com/nymtech/nym/issues/3472 + ## [v1.1.15] (2023-07-25) - NC Desktop - remove sentry DSN from code ([#3694]) diff --git a/nym-connect/desktop/package.json b/nym-connect/desktop/package.json index 626b415b8f..96d9e83438 100644 --- a/nym-connect/desktop/package.json +++ b/nym-connect/desktop/package.json @@ -1,6 +1,6 @@ { "name": "@nym/nym-connect", - "version": "1.1.15", + "version": "1.1.16", "main": "index.js", "license": "MIT", "scripts": { diff --git a/nym-connect/desktop/src-tauri/Cargo.toml b/nym-connect/desktop/src-tauri/Cargo.toml index e3bd49cb41..0d1089132d 100644 --- a/nym-connect/desktop/src-tauri/Cargo.toml +++ b/nym-connect/desktop/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-connect" -version = "1.1.15" +version = "1.1.16" description = "nym-connect" authors = ["Nym Technologies SA"] license = "" diff --git a/nym-connect/desktop/src-tauri/tauri.conf.json b/nym-connect/desktop/src-tauri/tauri.conf.json index b95859ca53..5f5e86bec0 100644 --- a/nym-connect/desktop/src-tauri/tauri.conf.json +++ b/nym-connect/desktop/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "package": { "productName": "nym-connect", - "version": "1.1.15" + "version": "1.1.16" }, "build": { "distDir": "../dist", diff --git a/service-providers/network-requester/Cargo.toml b/service-providers/network-requester/Cargo.toml index 5b80088b30..d1d7367d85 100644 --- a/service-providers/network-requester/Cargo.toml +++ b/service-providers/network-requester/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-network-requester" -version = "1.1.23" +version = "1.1.24" authors.workspace = true edition.workspace = true rust-version = "1.65" diff --git a/service-providers/network-statistics/Cargo.toml b/service-providers/network-statistics/Cargo.toml index cc7024c545..7c0138ca8f 100644 --- a/service-providers/network-statistics/Cargo.toml +++ b/service-providers/network-statistics/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-network-statistics" -version = "1.1.23" +version = "1.1.24" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/tools/nym-cli/Cargo.toml b/tools/nym-cli/Cargo.toml index ea5cad9e65..9f3c0d6a2a 100644 --- a/tools/nym-cli/Cargo.toml +++ b/tools/nym-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-cli" -version = "1.1.23" +version = "1.1.24" authors.workspace = true edition = "2021" From a26c6d7a29c6f6935fac0dc4e894358ed6253726 Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Tue, 8 Aug 2023 11:24:08 +0200 Subject: [PATCH 42/46] Temporary update to fix windows build --- package.json | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 523db5363f..cad6eaf88d 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,6 @@ "ts-packages/*", "nym-wallet", "nym-connect/**", - "nym-browser-extension", "explorer", "types", "clients/validator" @@ -29,9 +28,8 @@ "tsc": "lerna run tsc --stream", "types:lint:fix": "lerna run lint:fix --scope @nymproject/types --scope @nymproject/nym-wallet-app", "audit:fix": "npm_config_yes=true npx yarn-audit-fix -- --dry-run", - "preinstall": "yarn install:copy-placeholders && yarn install:copy-storage-placeholders", - "install:copy-placeholders": "cp scripts/build/yarn/wasm-placeholder/package.json sdk/typescript/packages/nym-client-wasm", - "install:copy-storage-placeholders": "mkdir -p nym-browser-extension/storage/pkg && cp scripts/build/yarn/storage-placeholder/package.json nym-browser-extension/storage/pkg" + "preinstall": "yarn install:copy-placeholders", + "install:copy-placeholders": "cp scripts/build/yarn/wasm-placeholder/package.json sdk/typescript/packages/nym-client-wasm" }, "devDependencies": { "lerna": "^6.6.2", From 62316244d9222ea695387426bf5ed926c0b7dc5f Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Tue, 8 Aug 2023 14:17:55 +0200 Subject: [PATCH 43/46] Revert package.json changes needed temporary build --- package.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index cad6eaf88d..523db5363f 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "ts-packages/*", "nym-wallet", "nym-connect/**", + "nym-browser-extension", "explorer", "types", "clients/validator" @@ -28,8 +29,9 @@ "tsc": "lerna run tsc --stream", "types:lint:fix": "lerna run lint:fix --scope @nymproject/types --scope @nymproject/nym-wallet-app", "audit:fix": "npm_config_yes=true npx yarn-audit-fix -- --dry-run", - "preinstall": "yarn install:copy-placeholders", - "install:copy-placeholders": "cp scripts/build/yarn/wasm-placeholder/package.json sdk/typescript/packages/nym-client-wasm" + "preinstall": "yarn install:copy-placeholders && yarn install:copy-storage-placeholders", + "install:copy-placeholders": "cp scripts/build/yarn/wasm-placeholder/package.json sdk/typescript/packages/nym-client-wasm", + "install:copy-storage-placeholders": "mkdir -p nym-browser-extension/storage/pkg && cp scripts/build/yarn/storage-placeholder/package.json nym-browser-extension/storage/pkg" }, "devDependencies": { "lerna": "^6.6.2", From 191aa149df2c698427a3bbdcf1d4387f9bc74731 Mon Sep 17 00:00:00 2001 From: benedetta davico <46782255+benedettadavico@users.noreply.github.com> Date: Tue, 8 Aug 2023 15:37:16 +0200 Subject: [PATCH 44/46] Update Cargo.toml --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 198f37890e..2e9a393993 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -146,11 +146,11 @@ reqwest = "0.11.18" serde = "1.0.152" serde_json = "1.0.91" tap = "1.0.1" -tendermint-rpc = "=0.32" # same version as used by cosmrs +tendermint-rpc = "0.32" # same version as used by cosmrs thiserror = "1.0.38" tokio = "1.24.1" url = "2.2" zeroize = "1.6.0" # wasm-related dependencies -wasmtimer = "0.2.0" \ No newline at end of file +wasmtimer = "0.2.0" From d8a95d3810ddea730ad5b3e1e1ffe6fb9e80ee3d Mon Sep 17 00:00:00 2001 From: benedetta davico <46782255+benedettadavico@users.noreply.github.com> Date: Tue, 8 Aug 2023 15:42:05 +0200 Subject: [PATCH 45/46] Update Cargo.toml --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 2e9a393993..9d609443f0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -127,7 +127,6 @@ serde-json-wasm = "=0.5.0" cosmwasm-storage = "=1.3.0" cosmrs = "=0.14.0" # same version as used by cosmrs -tendermint-rpc = "=0.32" cw-utils = "=1.0.1" cw-storage-plus = "=1.1.0" cw2 = { version = "=1.1.0" } From be88a9b2774ce9649a999dddfa18aeea28306a2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogdan-=C8=98tefan=20Neac=C5=9Fu?= Date: Tue, 8 Aug 2023 18:33:50 +0300 Subject: [PATCH 46/46] Remove stale BBC env var (#3720) --- .../validator-client/src/nyxd/mod.rs | 20 ------------------- common/network-defaults/src/lib.rs | 14 ------------- common/network-defaults/src/mainnet.rs | 10 ---------- common/network-defaults/src/var_names.rs | 1 - .../docs/src/bandwidth-credentials.md | 1 - envs/local.env | 1 - envs/mainnet.env | 1 - envs/qa-qwerty.env | 1 - envs/qa.env | 1 - envs/sandbox.env | 1 - nym-wallet/nym-wallet-types/src/network/qa.rs | 3 --- .../nym-wallet-types/src/network/sandbox.rs | 3 --- nym-wallet/src-tauri/src/config/mod.rs | 20 ------------------- .../src/operations/mixnet/account.rs | 7 +------ 14 files changed, 1 insertion(+), 83 deletions(-) diff --git a/common/client-libs/validator-client/src/nyxd/mod.rs b/common/client-libs/validator-client/src/nyxd/mod.rs index 404124df8d..9a4ee1eba4 100644 --- a/common/client-libs/validator-client/src/nyxd/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/mod.rs @@ -78,7 +78,6 @@ pub struct Config { // however, I'd really prefer to use something more strongly typed (i.e. AccountId vs String) pub(crate) mixnet_contract_address: Option, pub(crate) vesting_contract_address: Option, - pub(crate) bandwidth_claim_contract_address: Option, pub(crate) coconut_bandwidth_contract_address: Option, pub(crate) group_contract_address: Option, pub(crate) multisig_contract_address: Option, @@ -126,10 +125,6 @@ impl Config { details.contracts.vesting_contract_address.as_ref(), prefix, )?, - bandwidth_claim_contract_address: Self::parse_optional_account( - details.contracts.bandwidth_claim_contract_address.as_ref(), - prefix, - )?, coconut_bandwidth_contract_address: Self::parse_optional_account( details .contracts @@ -548,10 +543,6 @@ impl NyxdClient { self.config.vesting_contract_address = Some(address); } - pub fn set_bandwidth_claim_contract_address(&mut self, address: AccountId) { - self.config.bandwidth_claim_contract_address = Some(address); - } - pub fn set_coconut_bandwidth_contract_address(&mut self, address: AccountId) { self.config.coconut_bandwidth_contract_address = Some(address); } @@ -580,17 +571,6 @@ impl NyxdClient { self.config.vesting_contract_address.as_ref().unwrap() } - // TODO: this should get changed into Result<&AccountId, NyxdError> (or Option<&AccountId> in future commits - // note: what unwrap is doing here is just moving a failure that would have normally - // occurred in `connect` when attempting to parse an empty address, - // so it's not introducing new source of failure (just moves it) - pub fn bandwidth_claim_contract_address(&self) -> &AccountId { - self.config - .bandwidth_claim_contract_address - .as_ref() - .unwrap() - } - // TODO: this should get changed into Result<&AccountId, NyxdError> (or Option<&AccountId> in future commits // note: what unwrap is doing here is just moving a failure that would have normally // occurred in `connect` when attempting to parse an empty address, diff --git a/common/network-defaults/src/lib.rs b/common/network-defaults/src/lib.rs index a84175af1e..019c894f96 100644 --- a/common/network-defaults/src/lib.rs +++ b/common/network-defaults/src/lib.rs @@ -25,7 +25,6 @@ pub struct ChainDetails { pub struct NymContracts { pub mixnet_contract_address: Option, pub vesting_contract_address: Option, - pub bandwidth_claim_contract_address: Option, pub coconut_bandwidth_contract_address: Option, pub group_contract_address: Option, pub multisig_contract_address: Option, @@ -112,10 +111,6 @@ impl NymNetworkDetails { .with_vesting_contract(Some( var(var_names::VESTING_CONTRACT_ADDRESS).expect("vesting contract not set"), )) - .with_bandwidth_claim_contract(Some( - var(var_names::BANDWIDTH_CLAIM_CONTRACT_ADDRESS) - .expect("bandwidth claim contract not set"), - )) .with_coconut_bandwidth_contract(Some( var(var_names::COCONUT_BANDWIDTH_CONTRACT_ADDRESS) .expect("coconut bandwidth contract not set"), @@ -151,9 +146,6 @@ impl NymNetworkDetails { contracts: NymContracts { mixnet_contract_address: parse_optional_str(mainnet::MIXNET_CONTRACT_ADDRESS), vesting_contract_address: parse_optional_str(mainnet::VESTING_CONTRACT_ADDRESS), - bandwidth_claim_contract_address: parse_optional_str( - mainnet::BANDWIDTH_CLAIM_CONTRACT_ADDRESS, - ), coconut_bandwidth_contract_address: parse_optional_str( mainnet::COCONUT_BANDWIDTH_CONTRACT_ADDRESS, ), @@ -216,12 +208,6 @@ impl NymNetworkDetails { self } - #[must_use] - pub fn with_bandwidth_claim_contract>(mut self, contract: Option) -> Self { - self.contracts.bandwidth_claim_contract_address = contract.map(Into::into); - self - } - #[must_use] pub fn with_coconut_bandwidth_contract>(mut self, contract: Option) -> Self { self.contracts.coconut_bandwidth_contract_address = contract.map(Into::into); diff --git a/common/network-defaults/src/mainnet.rs b/common/network-defaults/src/mainnet.rs index dc35157435..453f6695ec 100644 --- a/common/network-defaults/src/mainnet.rs +++ b/common/network-defaults/src/mainnet.rs @@ -13,8 +13,6 @@ pub const MIXNET_CONTRACT_ADDRESS: &str = "n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr"; pub const VESTING_CONTRACT_ADDRESS: &str = "n1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrq73f2nw"; -pub(crate) const BANDWIDTH_CLAIM_CONTRACT_ADDRESS: &str = - "n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0"; pub(crate) const COCONUT_BANDWIDTH_CONTRACT_ADDRESS: &str = "n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0"; pub(crate) const GROUP_CONTRACT_ADDRESS: &str = "n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0"; @@ -70,10 +68,6 @@ pub fn export_to_env() { var_names::VESTING_CONTRACT_ADDRESS, VESTING_CONTRACT_ADDRESS, ); - set_var_to_default( - var_names::BANDWIDTH_CLAIM_CONTRACT_ADDRESS, - BANDWIDTH_CLAIM_CONTRACT_ADDRESS, - ); set_var_to_default( var_names::COCONUT_BANDWIDTH_CONTRACT_ADDRESS, COCONUT_BANDWIDTH_CONTRACT_ADDRESS, @@ -115,10 +109,6 @@ pub fn export_to_env_if_not_set() { var_names::VESTING_CONTRACT_ADDRESS, VESTING_CONTRACT_ADDRESS, ); - set_var_conditionally_to_default( - var_names::BANDWIDTH_CLAIM_CONTRACT_ADDRESS, - BANDWIDTH_CLAIM_CONTRACT_ADDRESS, - ); set_var_conditionally_to_default( var_names::COCONUT_BANDWIDTH_CONTRACT_ADDRESS, COCONUT_BANDWIDTH_CONTRACT_ADDRESS, diff --git a/common/network-defaults/src/var_names.rs b/common/network-defaults/src/var_names.rs index ee7b1c9a2a..c7ff9bb680 100644 --- a/common/network-defaults/src/var_names.rs +++ b/common/network-defaults/src/var_names.rs @@ -12,7 +12,6 @@ pub const STAKE_DENOM_DISPLAY: &str = "STAKE_DENOM_DISPLAY"; pub const DENOMS_EXPONENT: &str = "DENOMS_EXPONENT"; pub const MIXNET_CONTRACT_ADDRESS: &str = "MIXNET_CONTRACT_ADDRESS"; pub const VESTING_CONTRACT_ADDRESS: &str = "VESTING_CONTRACT_ADDRESS"; -pub const BANDWIDTH_CLAIM_CONTRACT_ADDRESS: &str = "BANDWIDTH_CLAIM_CONTRACT_ADDRESS"; pub const COCONUT_BANDWIDTH_CONTRACT_ADDRESS: &str = "COCONUT_BANDWIDTH_CONTRACT_ADDRESS"; pub const GROUP_CONTRACT_ADDRESS: &str = "GROUP_CONTRACT_ADDRESS"; pub const MULTISIG_CONTRACT_ADDRESS: &str = "MULTISIG_CONTRACT_ADDRESS"; diff --git a/documentation/docs/src/bandwidth-credentials.md b/documentation/docs/src/bandwidth-credentials.md index 4bbe6c3a79..6423dcf035 100644 --- a/documentation/docs/src/bandwidth-credentials.md +++ b/documentation/docs/src/bandwidth-credentials.md @@ -20,7 +20,6 @@ DENOMS_EXPONENT=6 REWARDING_VALIDATOR_ADDRESS="nymt1mxuweurc066kprnngtm8zmvam7m2nw26yatpmv" MIXNET_CONTRACT_ADDRESS="nymt1dlsvvgey26ernlj0sq2afjluh3qd4ap0k9eerekfkw5algqrwqksaf2qf7" VESTING_CONTRACT_ADDRESS="nymt19g9xuqrvz2frv905v3fc7puryfypluhg383q9zwsmedrlqekfgys62ykm4" -BANDWIDTH_CLAIM_CONTRACT_ADDRESS="nymt1rhmk9udessnv3r8f3eh2s03f45svnjaczpmcqz" MULTISIG_CONTRACT_ADDRESS="nymt142dkm8xe9f0ytyarp7ww4kvclva65705jphxsk9exn3nqdsm8jkqnp06ac" COCONUT_BANDWIDTH_CONTRACT_ADDRESS="nymt1ty0frysegskh6ndm3v96z5xdq66qzcu0aw7xcxlgp54jg0mjwlgqplc6v0" COCONUT_DKG_CONTRACT_ADDRESS="nymt1gwk6muhmzeuxje7df7rjvqwl2vex0kj4t2hwuzmyx5k62kfusu5qk4k5z4" diff --git a/envs/local.env b/envs/local.env index c7121762d0..7c450b8aec 100644 --- a/envs/local.env +++ b/envs/local.env @@ -11,7 +11,6 @@ STAKE_DENOM_DISPLAY=nyx DENOMS_EXPONENT=6 MIXNET_CONTRACT_ADDRESS=n1xsml6tm6pnx8nsuz3a54cznh55g6nuwu9ug9t92ucjkq5ewp5w9syxeqsv VESTING_CONTRACT_ADDRESS=n1xr3rq8yvd7qplsw5yx90ftsr2zdhg4e9z60h5duusgxpv72hud3sjkxkav -BANDWIDTH_CLAIM_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0 COCONUT_BANDWIDTH_CONTRACT_ADDRESS=n1lp5zex6685kd22agzskhqsylpnssxnweyuvsz4edr4p4ta92qf3q3dhmsx GROUP_CONTRACT_ADDRESS=n1rw8fw2mpcpzzq3jpa4e52ufawnmj5a4u68p35umvgskewuw0nlzsaa5w4m MULTISIG_CONTRACT_ADDRESS=n1rw8fw2mpcpzzq3jpa4e52ufawnmj5a4u68p35umvgskewuw0nlzsaa5w4m diff --git a/envs/mainnet.env b/envs/mainnet.env index 967534f006..3ace54478b 100644 --- a/envs/mainnet.env +++ b/envs/mainnet.env @@ -11,7 +11,6 @@ STAKE_DENOM_DISPLAY=nyx DENOMS_EXPONENT=6 MIXNET_CONTRACT_ADDRESS=n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr VESTING_CONTRACT_ADDRESS=n1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrq73f2nw -BANDWIDTH_CLAIM_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0 COCONUT_BANDWIDTH_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0 GROUP_CONTRACT_ADDRESS=n1rw8fw2mpcpzzq3jpa4e52ufawnmj5a4u68p35umvgskewuw0nlzsaa5w4m MULTISIG_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0 diff --git a/envs/qa-qwerty.env b/envs/qa-qwerty.env index 2a6a5da732..aba57bb0ed 100644 --- a/envs/qa-qwerty.env +++ b/envs/qa-qwerty.env @@ -11,7 +11,6 @@ STAKE_DENOM_DISPLAY=nyx DENOMS_EXPONENT=6 MIXNET_CONTRACT_ADDRESS=n14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sjyvg3g VESTING_CONTRACT_ADDRESS=n1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrq73f2nw -BANDWIDTH_CLAIM_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0 COCONUT_BANDWIDTH_CONTRACT_ADDRESS=n19d2nwj7fdhxqmyvgy8lf3ad49a6vmww4shryhrkj2mqk36att66s6xzszw GROUP_CONTRACT_ADDRESS=n1fqquzw4mk0pkamgr2ywt2v7h2j9nuyjjn4gvpy8zlpp6xn0uyuzqfm28l5 MULTISIG_CONTRACT_ADDRESS=n1gaq3666chd5348apj8cka8t2mckv7azp9espyr7wgpxyuzur5d0sazpysy diff --git a/envs/qa.env b/envs/qa.env index a5442b7600..f09ee6baf1 100644 --- a/envs/qa.env +++ b/envs/qa.env @@ -11,7 +11,6 @@ STAKE_DENOM_DISPLAY=nyx DENOMS_EXPONENT=6 MIXNET_CONTRACT_ADDRESS=n1rjzps6qrmdqmf0xz4cn4x4rcmqeqzq6hnzqg4wcvd0r2lyasdq5sepn5s8 VESTING_CONTRACT_ADDRESS=n1xr3rq8yvd7qplsw5yx90ftsr2zdhg4e9z60h5duusgxpv72hud3sjkxkav -BANDWIDTH_CLAIM_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0 COCONUT_BANDWIDTH_CONTRACT_ADDRESS=n1ghd753shjuwexxywmgs4xz7x2q732vcn7ty4yw GROUP_CONTRACT_ADDRESS=n1rw8fw2mpcpzzq3jpa4e52ufawnmj5a4u68p35umvgskewuw0nlzsaa5w4m MULTISIG_CONTRACT_ADDRESS=n17p9rzwnnfxcjp32un9ug7yhhzgtkhvl988qccs diff --git a/envs/sandbox.env b/envs/sandbox.env index f42a91a97d..70aa96ff42 100644 --- a/envs/sandbox.env +++ b/envs/sandbox.env @@ -13,7 +13,6 @@ DENOMS_EXPONENT=6 REWARDING_VALIDATOR_ADDRESS=n1pefc2utwpy5w78p2kqdsfmpjxfwmn9d39k5mqa MIXNET_CONTRACT_ADDRESS=n1xr3rq8yvd7qplsw5yx90ftsr2zdhg4e9z60h5duusgxpv72hud3sjkxkav VESTING_CONTRACT_ADDRESS=n1unyuj8qnmygvzuex3dwmg9yzt9alhvyeat0uu0jedg2wj33efl5qackslz -BANDWIDTH_CLAIM_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0 COCONUT_BANDWIDTH_CONTRACT_ADDRESS=n16a32stm6kknhq5cc8rx77elr66pygf2hfszw7wvpq746x3uffylqkjar4l GROUP_CONTRACT_ADDRESS=n1pd7kfgvr5tpcv0xnlv46c4jsq9jg2r799xxrcwqdm4l2jhq2pjwqrmz5ju MULTISIG_CONTRACT_ADDRESS=n14ph4e660eyqz0j36zlkaey4zgzexm5twkmjlqaequxr2cjm9eprqsmad6k diff --git a/nym-wallet/nym-wallet-types/src/network/qa.rs b/nym-wallet/nym-wallet-types/src/network/qa.rs index 1d298de8dd..d333d71067 100644 --- a/nym-wallet/nym-wallet-types/src/network/qa.rs +++ b/nym-wallet/nym-wallet-types/src/network/qa.rs @@ -13,8 +13,6 @@ pub(crate) const MIXNET_CONTRACT_ADDRESS: &str = "n10qt8wg0n7z740ssvf3urmvgtjhxpyp74hxqvqt7z226gykuus7eq5u9pvq"; pub(crate) const VESTING_CONTRACT_ADDRESS: &str = "n1vguuxez2h5ekltfj9gjd62fs5k4rl2zy5hfrncasykzw08rezpfstk9xtk"; -pub(crate) const BANDWIDTH_CLAIM_CONTRACT_ADDRESS: &str = - "n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0"; pub(crate) const COCONUT_BANDWIDTH_CONTRACT_ADDRESS: &str = "n1ghd753shjuwexxywmgs4xz7x2q732vcn7ty4yw"; pub(crate) const GROUP_CONTRACT_ADDRESS: &str = @@ -48,7 +46,6 @@ pub(crate) fn network_details() -> nym_network_defaults::NymNetworkDetails { contracts: NymContracts { mixnet_contract_address: parse_optional_str(MIXNET_CONTRACT_ADDRESS), vesting_contract_address: parse_optional_str(VESTING_CONTRACT_ADDRESS), - bandwidth_claim_contract_address: parse_optional_str(BANDWIDTH_CLAIM_CONTRACT_ADDRESS), coconut_bandwidth_contract_address: parse_optional_str( COCONUT_BANDWIDTH_CONTRACT_ADDRESS, ), diff --git a/nym-wallet/nym-wallet-types/src/network/sandbox.rs b/nym-wallet/nym-wallet-types/src/network/sandbox.rs index 169c058c3c..aefbcc73b3 100644 --- a/nym-wallet/nym-wallet-types/src/network/sandbox.rs +++ b/nym-wallet/nym-wallet-types/src/network/sandbox.rs @@ -11,8 +11,6 @@ pub(crate) const STAKE_DENOM: DenomDetails = DenomDetails::new("unyxt", "nyxt", pub(crate) const MIXNET_CONTRACT_ADDRESS: &str = "nymt1ghd753shjuwexxywmgs4xz7x2q732vcnstz02j"; pub(crate) const VESTING_CONTRACT_ADDRESS: &str = "nymt14ejqjyq8um4p3xfqj74yld5waqljf88fn549lh"; -pub(crate) const BANDWIDTH_CLAIM_CONTRACT_ADDRESS: &str = - "nymt17p9rzwnnfxcjp32un9ug7yhhzgtkhvl9f8xzkv"; pub(crate) const COCONUT_BANDWIDTH_CONTRACT_ADDRESS: &str = "nymt1nz0r0au8aj6dc00wmm3ufy4g4k86rjzlgq608r"; pub(crate) const GROUP_CONTRACT_ADDRESS: &str = "nymt1k8re7jwz6rnnwrktnejdwkwnncte7ek7kk6fvg"; @@ -39,7 +37,6 @@ pub(crate) fn network_details() -> nym_network_defaults::NymNetworkDetails { contracts: NymContracts { mixnet_contract_address: parse_optional_str(MIXNET_CONTRACT_ADDRESS), vesting_contract_address: parse_optional_str(VESTING_CONTRACT_ADDRESS), - bandwidth_claim_contract_address: parse_optional_str(BANDWIDTH_CLAIM_CONTRACT_ADDRESS), coconut_bandwidth_contract_address: parse_optional_str( COCONUT_BANDWIDTH_CONTRACT_ADDRESS, ), diff --git a/nym-wallet/src-tauri/src/config/mod.rs b/nym-wallet/src-tauri/src/config/mod.rs index 24e8a7d03a..bdb369ade6 100644 --- a/nym-wallet/src-tauri/src/config/mod.rs +++ b/nym-wallet/src-tauri/src/config/mod.rs @@ -237,15 +237,6 @@ impl Config { .expect("Wrong format for vesting contract address") } - pub fn get_bandwidth_claim_contract_address(&self, network: WalletNetwork) -> CosmosAccountId { - self.base - .networks - .bandwidth_claim_contract_address(&network) - .expect("No bandwidth claim contract address found in config") - .parse() - .expect("Wrong format for bandwidth claim contract address") - } - pub fn set_default_nyxd_urls(&mut self, urls: &HashMap) { for (network, url) in urls { self.set_default_nyxd_url(url.to_owned(), network); @@ -499,12 +490,6 @@ impl SupportedNetworks { .map(|network_details| network_details.vesting_contract_address.as_str()) } - fn bandwidth_claim_contract_address(&self, network: &WalletNetwork) -> Option<&str> { - self.networks - .get(network) - .map(|network_details| network_details.bandwidth_claim_contract_address.as_str()) - } - fn validators(&self, network: &WalletNetwork) -> impl Iterator { self.networks .get(network) @@ -522,7 +507,6 @@ struct NetworkDetails { stake_denom: DenomDetailsOwned, mixnet_contract_address: String, vesting_contract_address: String, - bandwidth_claim_contract_address: String, statistics_service_url: String, validators: Vec, } @@ -543,10 +527,6 @@ impl From for NetworkDetails { .contracts .vesting_contract_address .unwrap_or_default(), - bandwidth_claim_contract_address: details - .contracts - .bandwidth_claim_contract_address - .unwrap_or_default(), statistics_service_url: "".to_string(), validators: details.endpoints, } diff --git a/nym-wallet/src-tauri/src/operations/mixnet/account.rs b/nym-wallet/src-tauri/src/operations/mixnet/account.rs index a15732e5ee..07f939ce95 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/account.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/account.rs @@ -282,12 +282,7 @@ fn create_clients( let network_details = NymNetworkDetails::from(network) .clone() .with_mixnet_contract(Some(config.get_mixnet_contract_address(network).as_ref())) - .with_vesting_contract(Some(config.get_vesting_contract_address(network).as_ref())) - .with_bandwidth_claim_contract(Some( - config - .get_bandwidth_claim_contract_address(network) - .as_ref(), - )); + .with_vesting_contract(Some(config.get_vesting_contract_address(network).as_ref())); let config = nym_validator_client::Config::try_from_nym_network_details(&network_details)? .with_urls(nyxd_url, api_url);