Merge pull request #3332 from nymtech/jon/feat/sp-integrations
Service provider directory support in nym-api, nym-cli, validator-client
This commit is contained in:
Generated
+4
@@ -3069,6 +3069,7 @@ dependencies = [
|
||||
"nym-multisig-contract-common",
|
||||
"nym-node-tester-utils",
|
||||
"nym-pemstore",
|
||||
"nym-service-provider-directory-common",
|
||||
"nym-sphinx",
|
||||
"nym-task",
|
||||
"nym-topology",
|
||||
@@ -3210,6 +3211,7 @@ dependencies = [
|
||||
"nym-mixnet-contract-common",
|
||||
"nym-multisig-contract-common",
|
||||
"nym-network-defaults",
|
||||
"nym-service-provider-directory-common",
|
||||
"nym-validator-client",
|
||||
"nym-vesting-contract-common",
|
||||
"rand 0.6.5",
|
||||
@@ -3898,6 +3900,7 @@ name = "nym-service-provider-directory-common"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cosmwasm-std",
|
||||
"schemars",
|
||||
"serde",
|
||||
]
|
||||
|
||||
@@ -4251,6 +4254,7 @@ dependencies = [
|
||||
"nym-mixnet-contract-common",
|
||||
"nym-multisig-contract-common",
|
||||
"nym-network-defaults",
|
||||
"nym-service-provider-directory-common",
|
||||
"nym-vesting-contract",
|
||||
"nym-vesting-contract-common",
|
||||
"prost 0.10.4",
|
||||
|
||||
@@ -18,6 +18,7 @@ nym-vesting-contract-common = { path = "../../cosmwasm-smart-contracts/vesting-c
|
||||
nym-coconut-bandwidth-contract-common = { path = "../../cosmwasm-smart-contracts/coconut-bandwidth-contract" }
|
||||
nym-multisig-contract-common = { path = "../../cosmwasm-smart-contracts/multisig-contract" }
|
||||
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 }
|
||||
@@ -63,6 +64,10 @@ name = "offline_signing"
|
||||
# (traits would need to be moved around and refactored themselves)
|
||||
required-features = ["nyxd-client"]
|
||||
|
||||
[[example]]
|
||||
name = "query_service_provider_directory"
|
||||
required-features = ["nyxd-client"]
|
||||
|
||||
[features]
|
||||
nyxd-client = [
|
||||
"async-trait",
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use cosmrs::AccountId;
|
||||
use nym_network_defaults::{setup_env, NymNetworkDetails};
|
||||
use nym_service_provider_directory_common::NymAddress;
|
||||
use nym_validator_client::nyxd::traits::SpDirectoryQueryClient;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
setup_env(Some(&"../../../envs/qa-qwerty.env".parse().unwrap()));
|
||||
let network_details = NymNetworkDetails::new_from_env();
|
||||
let config =
|
||||
nym_validator_client::Config::try_from_nym_network_details(&network_details).unwrap();
|
||||
let client = nym_validator_client::Client::new_query(config).unwrap();
|
||||
|
||||
let config = client.nyxd.get_service_config().await.unwrap();
|
||||
println!("config: {config:?}");
|
||||
|
||||
let services_paged = client.nyxd.get_services_paged(None, None).await.unwrap();
|
||||
println!("services (paged): {services_paged:#?}");
|
||||
|
||||
let services = client.nyxd.get_all_services().await.unwrap();
|
||||
println!("services: {services:#?}");
|
||||
|
||||
let announcer = AccountId::from_str("n1hmf957kc7arcd39rl7xq8l0a4zyg7kxnv7su87").unwrap();
|
||||
let services_by_announcer = client
|
||||
.nyxd
|
||||
.get_services_by_announcer(announcer)
|
||||
.await
|
||||
.unwrap();
|
||||
println!("services (by announcer): {services_by_announcer:#?}");
|
||||
|
||||
let nym_address = NymAddress::new("foo.bar@gateway");
|
||||
let services_by_nym_address = client
|
||||
.nyxd
|
||||
.get_services_by_nym_address(nym_address)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(services_by_announcer, services_by_nym_address);
|
||||
|
||||
let service_info = client.nyxd.get_service_info(1).await;
|
||||
println!("service info: {service_info:#?}");
|
||||
}
|
||||
@@ -117,7 +117,7 @@ async fn test_nyxd_connection(
|
||||
);
|
||||
code == 18
|
||||
}
|
||||
Ok(Err(error @ NyxdError::NoContractAddressAvailable)) => {
|
||||
Ok(Err(error @ NyxdError::NoContractAddressAvailable(_))) => {
|
||||
log::debug!("Checking: nyxd url: {url}: {}: {error}", "failed".red());
|
||||
false
|
||||
}
|
||||
|
||||
@@ -9,6 +9,9 @@ pub enum NymAPIError {
|
||||
source: reqwest::Error,
|
||||
},
|
||||
|
||||
#[error("Not found")]
|
||||
NotFound,
|
||||
|
||||
#[error("Request failed with error message - {0}")]
|
||||
GenericRequestFailure(String),
|
||||
|
||||
|
||||
@@ -15,7 +15,8 @@ use nym_api_requests::models::{
|
||||
};
|
||||
use nym_mixnet_contract_common::mixnode::MixNodeDetails;
|
||||
use nym_mixnet_contract_common::{GatewayBond, IdentityKeyRef, MixId};
|
||||
use reqwest::Response;
|
||||
use nym_service_provider_directory_common::ServiceInfo;
|
||||
use reqwest::{Response, StatusCode};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
|
||||
@@ -76,6 +77,8 @@ impl Client {
|
||||
let res = self.send_get_request(path, params).await?;
|
||||
if res.status().is_success() {
|
||||
Ok(res.json().await?)
|
||||
} else if res.status() == StatusCode::NOT_FOUND {
|
||||
Err(NymAPIError::NotFound)
|
||||
} else {
|
||||
Err(NymAPIError::GenericRequestFailure(res.text().await?))
|
||||
}
|
||||
@@ -480,6 +483,11 @@ impl Client {
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_service_providers(&self) -> Result<Vec<ServiceInfo>, NymAPIError> {
|
||||
self.query_nym_api(&[routes::API_VERSION, routes::SERVICE_PROVIDERS], NO_PARAMS)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
// utility function that should solve the double slash problem in validator API forever.
|
||||
|
||||
@@ -32,3 +32,5 @@ pub const COMPUTE_REWARD_ESTIMATION: &str = "compute-reward-estimation";
|
||||
pub const AVG_UPTIME: &str = "avg_uptime";
|
||||
pub const STAKE_SATURATION: &str = "stake-saturation";
|
||||
pub const INCLUSION_CHANCE: &str = "inclusion-probability";
|
||||
|
||||
pub const SERVICE_PROVIDERS: &str = "service-providers";
|
||||
|
||||
@@ -21,8 +21,8 @@ use std::{io, time::Duration};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum NyxdError {
|
||||
#[error("No contract address is available to perform the call")]
|
||||
NoContractAddressAvailable,
|
||||
#[error("No contract address is available to perform the call: {0}")]
|
||||
NoContractAddressAvailable(String),
|
||||
|
||||
#[error(transparent)]
|
||||
WalletError(#[from] DirectSecp256k1HdWalletError),
|
||||
|
||||
@@ -67,6 +67,7 @@ pub struct Config {
|
||||
pub(crate) group_contract_address: Option<AccountId>,
|
||||
pub(crate) multisig_contract_address: Option<AccountId>,
|
||||
pub(crate) coconut_dkg_contract_address: Option<AccountId>,
|
||||
pub(crate) service_provider_contract_address: Option<AccountId>,
|
||||
// TODO: add this in later commits
|
||||
// pub(crate) gas_price: GasPrice,
|
||||
}
|
||||
@@ -131,6 +132,13 @@ impl Config {
|
||||
details.contracts.coconut_dkg_contract_address.as_ref(),
|
||||
prefix,
|
||||
)?,
|
||||
service_provider_contract_address: Self::parse_optional_account(
|
||||
details
|
||||
.contracts
|
||||
.service_provider_directory_contract_address
|
||||
.as_ref(),
|
||||
prefix,
|
||||
)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -246,6 +254,10 @@ impl<C> NyxdClient<C> {
|
||||
self.config.multisig_contract_address = Some(address);
|
||||
}
|
||||
|
||||
pub fn set_service_provider_contract_address(&mut self, address: AccountId) {
|
||||
self.config.service_provider_contract_address = Some(address);
|
||||
}
|
||||
|
||||
// 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,
|
||||
@@ -304,6 +316,11 @@ impl<C> NyxdClient<C> {
|
||||
self.config.coconut_dkg_contract_address.as_ref().unwrap()
|
||||
}
|
||||
|
||||
// The service provider directory contract is optional, so we return an Option not a Result
|
||||
pub fn service_provider_contract_address(&self) -> Option<&AccountId> {
|
||||
self.config.service_provider_contract_address.as_ref()
|
||||
}
|
||||
|
||||
pub fn set_simulated_gas_multiplier(&mut self, multiplier: f32) {
|
||||
self.simulated_gas_multiplier = multiplier;
|
||||
}
|
||||
|
||||
@@ -16,15 +16,20 @@ mod mixnet_signing_client;
|
||||
mod multisig_signing_client;
|
||||
mod vesting_signing_client;
|
||||
|
||||
mod sp_directory_query_client;
|
||||
mod sp_directory_signing_client;
|
||||
|
||||
pub use coconut_bandwidth_query_client::CoconutBandwidthQueryClient;
|
||||
pub use dkg_query_client::DkgQueryClient;
|
||||
pub use group_query_client::GroupQueryClient;
|
||||
pub use mixnet_query_client::MixnetQueryClient;
|
||||
pub use multisig_query_client::MultisigQueryClient;
|
||||
pub use sp_directory_query_client::SpDirectoryQueryClient;
|
||||
pub use vesting_query_client::VestingQueryClient;
|
||||
|
||||
pub use coconut_bandwidth_signing_client::CoconutBandwidthSigningClient;
|
||||
pub use dkg_signing_client::DkgSigningClient;
|
||||
pub use mixnet_signing_client::MixnetSigningClient;
|
||||
pub use multisig_signing_client::MultisigSigningClient;
|
||||
pub use sp_directory_signing_client::SpDirectorySigningClient;
|
||||
pub use vesting_signing_client::VestingSigningClient;
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
use async_trait::async_trait;
|
||||
use cosmrs::AccountId;
|
||||
use nym_contracts_common::ContractBuildInformation;
|
||||
use nym_service_provider_directory_common::{
|
||||
msg::QueryMsg as SpQueryMsg,
|
||||
response::{
|
||||
ConfigResponse, PagedServicesListResponse, ServiceInfoResponse, ServicesListResponse,
|
||||
},
|
||||
NymAddress, ServiceId, ServiceInfo,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::nyxd::{error::NyxdError, CosmWasmClient, NyxdClient};
|
||||
|
||||
#[async_trait]
|
||||
pub trait SpDirectoryQueryClient {
|
||||
async fn query_service_provider_contract<T>(&self, query: SpQueryMsg) -> Result<T, NyxdError>
|
||||
where
|
||||
for<'a> T: Deserialize<'a>;
|
||||
|
||||
async fn get_service_config(&self) -> Result<ConfigResponse, NyxdError> {
|
||||
self.query_service_provider_contract(SpQueryMsg::Config {})
|
||||
.await
|
||||
}
|
||||
|
||||
async fn get_service_info(
|
||||
&self,
|
||||
service_id: ServiceId,
|
||||
) -> Result<ServiceInfoResponse, NyxdError> {
|
||||
self.query_service_provider_contract(SpQueryMsg::ServiceId { service_id })
|
||||
.await
|
||||
}
|
||||
|
||||
async fn get_services_paged(
|
||||
&self,
|
||||
start_after: Option<ServiceId>,
|
||||
limit: Option<u32>,
|
||||
) -> Result<PagedServicesListResponse, NyxdError> {
|
||||
self.query_service_provider_contract(SpQueryMsg::All { limit, start_after })
|
||||
.await
|
||||
}
|
||||
|
||||
async fn get_services_by_announcer(
|
||||
&self,
|
||||
announcer: AccountId,
|
||||
) -> Result<ServicesListResponse, NyxdError> {
|
||||
self.query_service_provider_contract(SpQueryMsg::ByAnnouncer {
|
||||
announcer: announcer.to_string(),
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
async fn get_services_by_nym_address(
|
||||
&self,
|
||||
nym_address: NymAddress,
|
||||
) -> Result<ServicesListResponse, NyxdError> {
|
||||
self.query_service_provider_contract(SpQueryMsg::ByNymAddress { nym_address })
|
||||
.await
|
||||
}
|
||||
|
||||
async fn get_sp_contract_version(&self) -> Result<ContractBuildInformation, NyxdError> {
|
||||
self.query_service_provider_contract(SpQueryMsg::GetContractVersion {})
|
||||
.await
|
||||
}
|
||||
|
||||
async fn get_all_services(&self) -> Result<Vec<ServiceInfo>, NyxdError> {
|
||||
let mut services = Vec::new();
|
||||
let mut start_after = None;
|
||||
|
||||
loop {
|
||||
let mut paged_response = self.get_services_paged(start_after.take(), None).await?;
|
||||
|
||||
let last_id = paged_response.services.last().map(|serv| serv.service_id);
|
||||
services.append(&mut paged_response.services);
|
||||
|
||||
if let Some(start_after_res) = last_id {
|
||||
start_after = Some(start_after_res)
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(services)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<C> SpDirectoryQueryClient for NyxdClient<C>
|
||||
where
|
||||
C: CosmWasmClient + Send + Sync,
|
||||
{
|
||||
async fn query_service_provider_contract<T>(&self, query: SpQueryMsg) -> Result<T, NyxdError>
|
||||
where
|
||||
for<'a> T: Deserialize<'a>,
|
||||
{
|
||||
self.client
|
||||
.query_contract_smart(
|
||||
self.service_provider_contract_address().ok_or(
|
||||
NyxdError::NoContractAddressAvailable(
|
||||
"service provider directory contract".to_string(),
|
||||
),
|
||||
)?,
|
||||
&query,
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<C> SpDirectoryQueryClient for crate::Client<C>
|
||||
where
|
||||
C: CosmWasmClient + Send + Sync,
|
||||
{
|
||||
async fn query_service_provider_contract<T>(&self, query: SpQueryMsg) -> Result<T, NyxdError>
|
||||
where
|
||||
for<'a> T: Deserialize<'a>,
|
||||
{
|
||||
self.nyxd.query_service_provider_contract(query).await
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use async_trait::async_trait;
|
||||
use nym_service_provider_directory_common::{
|
||||
msg::ExecuteMsg as SpExecuteMsg, NymAddress, ServiceId, ServiceType,
|
||||
};
|
||||
|
||||
use crate::nyxd::{
|
||||
coin::Coin, cosmwasm_client::types::ExecuteResult, error::NyxdError, Fee, NyxdClient,
|
||||
SigningCosmWasmClient,
|
||||
};
|
||||
|
||||
#[async_trait]
|
||||
pub trait SpDirectorySigningClient {
|
||||
async fn exectute_service_provider_directory_contract(
|
||||
&self,
|
||||
fee: Option<Fee>,
|
||||
msg: SpExecuteMsg,
|
||||
funds: Vec<Coin>,
|
||||
) -> Result<ExecuteResult, NyxdError>;
|
||||
|
||||
async fn announce_service_provider(
|
||||
&self,
|
||||
nym_address: NymAddress,
|
||||
service_type: ServiceType,
|
||||
deposit: Coin,
|
||||
fee: Option<Fee>,
|
||||
) -> Result<ExecuteResult, NyxdError> {
|
||||
self.exectute_service_provider_directory_contract(
|
||||
fee,
|
||||
SpExecuteMsg::Announce {
|
||||
nym_address,
|
||||
service_type,
|
||||
},
|
||||
vec![deposit],
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn delete_service_provider_by_id(
|
||||
&self,
|
||||
service_id: ServiceId,
|
||||
fee: Option<Fee>,
|
||||
) -> Result<ExecuteResult, NyxdError> {
|
||||
self.exectute_service_provider_directory_contract(
|
||||
fee,
|
||||
SpExecuteMsg::DeleteId { service_id },
|
||||
vec![],
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn delete_service_provider_by_nym_address(
|
||||
&self,
|
||||
nym_address: NymAddress,
|
||||
fee: Option<Fee>,
|
||||
) -> Result<ExecuteResult, NyxdError> {
|
||||
self.exectute_service_provider_directory_contract(
|
||||
fee,
|
||||
SpExecuteMsg::DeleteNymAddress { nym_address },
|
||||
vec![],
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn update_deposit_required(
|
||||
&self,
|
||||
deposit_required: Coin,
|
||||
fee: Option<Fee>,
|
||||
) -> Result<ExecuteResult, NyxdError> {
|
||||
self.exectute_service_provider_directory_contract(
|
||||
fee,
|
||||
SpExecuteMsg::UpdateDepositRequired {
|
||||
deposit_required: deposit_required.into(),
|
||||
},
|
||||
vec![],
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<C> SpDirectorySigningClient for NyxdClient<C>
|
||||
where
|
||||
C: SigningCosmWasmClient + Sync + Send,
|
||||
{
|
||||
async fn exectute_service_provider_directory_contract(
|
||||
&self,
|
||||
fee: Option<Fee>,
|
||||
msg: SpExecuteMsg,
|
||||
funds: Vec<Coin>,
|
||||
) -> Result<ExecuteResult, NyxdError> {
|
||||
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
|
||||
let memo = msg.default_memo();
|
||||
self.client
|
||||
.execute(
|
||||
self.address(),
|
||||
self.service_provider_contract_address().ok_or(
|
||||
NyxdError::NoContractAddressAvailable(
|
||||
"service provider directory contract".to_string(),
|
||||
),
|
||||
)?,
|
||||
&msg,
|
||||
fee,
|
||||
memo,
|
||||
funds,
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
@@ -38,3 +38,4 @@ nym-vesting-contract-common = { path = "../cosmwasm-smart-contracts/vesting-cont
|
||||
nym-coconut-bandwidth-contract-common = { path = "../cosmwasm-smart-contracts/coconut-bandwidth-contract" }
|
||||
nym-coconut-dkg-common = { path = "../cosmwasm-smart-contracts/coconut-dkg" }
|
||||
nym-multisig-contract-common = { path = "../cosmwasm-smart-contracts/multisig-contract" }
|
||||
nym-service-provider-directory-common = { path = "../cosmwasm-smart-contracts/service-provider-directory" }
|
||||
|
||||
@@ -5,6 +5,7 @@ use clap::{Args, Subcommand};
|
||||
|
||||
pub mod gateway;
|
||||
pub mod mixnode;
|
||||
pub mod service;
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)]
|
||||
@@ -19,4 +20,6 @@ pub enum MixnetOperatorsCommands {
|
||||
Mixnode(mixnode::MixnetOperatorsMixnode),
|
||||
/// Manage your gateway
|
||||
Gateway(gateway::MixnetOperatorsGateway),
|
||||
/// Manage your service
|
||||
ServiceProvider(service::MixnetOperatorsService),
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
use clap::Parser;
|
||||
use log::info;
|
||||
use nym_service_provider_directory_common::{Coin, NymAddress, ServiceType};
|
||||
use nym_validator_client::nyxd::traits::SpDirectorySigningClient;
|
||||
|
||||
use crate::context::SigningClient;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct Args {
|
||||
#[clap(long)]
|
||||
pub nym_address: String,
|
||||
|
||||
/// Deposit to be made to the service provider directory, in curent DENOMINATION (e.g. 'unym')
|
||||
#[clap(long)]
|
||||
pub deposit: u128,
|
||||
}
|
||||
|
||||
pub async fn announce(args: Args, client: SigningClient) {
|
||||
info!("Annoucing service provider");
|
||||
|
||||
let nym_address = NymAddress::Address(args.nym_address);
|
||||
let service_type = ServiceType::NetworkRequester;
|
||||
|
||||
let denom = client.current_chain_details().mix_denom.base.as_str();
|
||||
let deposit = Coin::new(args.deposit, denom);
|
||||
|
||||
let res = client
|
||||
.announce_service_provider(nym_address, service_type, deposit.into(), None)
|
||||
.await
|
||||
.expect("Failed to announce service provider");
|
||||
|
||||
info!("Announced service provider: {res:?}");
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
use clap::Parser;
|
||||
use log::info;
|
||||
use nym_service_provider_directory_common::ServiceId;
|
||||
use nym_validator_client::nyxd::traits::SpDirectorySigningClient;
|
||||
|
||||
use crate::context::SigningClient;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct Args {
|
||||
#[clap(long)]
|
||||
pub id: ServiceId,
|
||||
}
|
||||
|
||||
pub async fn delete(args: Args, client: SigningClient) {
|
||||
info!("Deleting service provider with id {}", args.id);
|
||||
|
||||
let res = client
|
||||
.delete_service_provider_by_id(args.id, None)
|
||||
.await
|
||||
.expect("Failed to delete service provider");
|
||||
|
||||
info!("Deleted: {res:?}");
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
use clap::{Args, Subcommand};
|
||||
|
||||
pub mod announce;
|
||||
pub mod delete;
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)]
|
||||
pub struct MixnetOperatorsService {
|
||||
#[clap(subcommand)]
|
||||
pub command: MixnetOperatorsServiceCommands,
|
||||
}
|
||||
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum MixnetOperatorsServiceCommands {
|
||||
/// Announce service provider to the world
|
||||
Announce(announce::Args),
|
||||
/// Delete entry for service provider from the directory
|
||||
Delete(delete::Args),
|
||||
}
|
||||
@@ -5,6 +5,7 @@ use clap::{Args, Subcommand};
|
||||
|
||||
pub mod query_all_gateways;
|
||||
pub mod query_all_mixnodes;
|
||||
pub mod query_all_service_providers;
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)]
|
||||
@@ -19,4 +20,6 @@ pub enum MixnetQueryCommands {
|
||||
Mixnodes(query_all_mixnodes::Args),
|
||||
/// Query gateways
|
||||
Gateways(query_all_gateways::Args),
|
||||
/// Query announced service-providers
|
||||
ServiceProviders(query_all_service_providers::Args),
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use clap::Parser;
|
||||
use comfy_table::Table;
|
||||
use nym_validator_client::nym_api::error::NymAPIError;
|
||||
|
||||
use crate::context::QueryClientWithNyxd;
|
||||
use crate::utils::show_error;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct Args {
|
||||
#[clap(value_parser)]
|
||||
#[clap(help = "Optionally, the service provider to display")]
|
||||
pub nym_address: Option<String>,
|
||||
}
|
||||
|
||||
pub async fn query(args: Args, client: &QueryClientWithNyxd) {
|
||||
match client.nym_api.get_service_providers().await {
|
||||
Ok(res) => {
|
||||
if let Some(nym_address) = args.nym_address {
|
||||
let service = res.iter().find(|service| {
|
||||
service
|
||||
.service
|
||||
.nym_address
|
||||
.to_string()
|
||||
.eq_ignore_ascii_case(&nym_address)
|
||||
});
|
||||
println!(
|
||||
"{}",
|
||||
::serde_json::to_string_pretty(&service).expect("json formatting error")
|
||||
);
|
||||
} else {
|
||||
let mut table = Table::new();
|
||||
|
||||
table.set_header(vec!["Service Id", "Announcer", "Nym Address"]);
|
||||
for service in res {
|
||||
table.add_row(vec![
|
||||
service.service_id.to_string(),
|
||||
service.service.announcer.to_string(),
|
||||
service.service.service_type.to_string(),
|
||||
service.service.nym_address.to_string(),
|
||||
]);
|
||||
}
|
||||
|
||||
println!("The service providers in the directory are:");
|
||||
println!("{table}");
|
||||
}
|
||||
}
|
||||
Err(NymAPIError::NotFound) => {
|
||||
println!("nym-api reports no service provider endpoint available");
|
||||
}
|
||||
Err(e) => show_error(e),
|
||||
}
|
||||
}
|
||||
@@ -7,4 +7,5 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
cosmwasm-std = { workspace = true }
|
||||
schemars = "0.8"
|
||||
serde = { workspace = true, default-features = false, features = ["derive"] }
|
||||
|
||||
@@ -5,3 +5,5 @@ pub mod types;
|
||||
|
||||
// Re-export all types at the top-level
|
||||
pub use types::*;
|
||||
|
||||
pub use cosmwasm_std::{Addr, Coin, Decimal, Fraction};
|
||||
|
||||
@@ -40,6 +40,24 @@ impl ExecuteMsg {
|
||||
pub fn delete_id(service_id: ServiceId) -> Self {
|
||||
ExecuteMsg::DeleteId { service_id }
|
||||
}
|
||||
|
||||
pub fn default_memo(&self) -> String {
|
||||
match self {
|
||||
ExecuteMsg::Announce {
|
||||
nym_address,
|
||||
service_type,
|
||||
} => format!("announcing {nym_address} as type {service_type}"),
|
||||
ExecuteMsg::DeleteId { service_id } => {
|
||||
format!("deleting service with service id {service_id}")
|
||||
}
|
||||
ExecuteMsg::DeleteNymAddress { nym_address } => {
|
||||
format!("deleting service with nym address {nym_address}")
|
||||
}
|
||||
ExecuteMsg::UpdateDepositRequired { deposit_required } => {
|
||||
format!("updating the deposit required to {deposit_required}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::{msg::ExecuteMsg, Service, ServiceId, ServiceInfo};
|
||||
use cosmwasm_std::Coin;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
|
||||
@@ -9,7 +10,7 @@ pub struct ServiceInfoResponse {
|
||||
pub service: Option<Service>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
|
||||
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct ServicesListResponse {
|
||||
pub services: Vec<ServiceInfo>,
|
||||
@@ -26,6 +27,14 @@ impl ServicesListResponse {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&[ServiceInfo]> for ServicesListResponse {
|
||||
fn from(services: &[ServiceInfo]) -> Self {
|
||||
Self {
|
||||
services: services.to_vec(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct PagedServicesListResponse {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
use cosmwasm_std::{Addr, Coin};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// The directory of services are indexed by [`ServiceId`].
|
||||
pub type ServiceId = u32;
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
|
||||
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, JsonSchema)]
|
||||
pub struct Service {
|
||||
/// The address of the service.
|
||||
pub nym_address: NymAddress,
|
||||
@@ -21,7 +22,7 @@ pub struct Service {
|
||||
}
|
||||
|
||||
/// The types of addresses supported.
|
||||
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
|
||||
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum NymAddress {
|
||||
/// String representation of a nym address, which is of the form
|
||||
@@ -51,7 +52,7 @@ impl Display for NymAddress {
|
||||
}
|
||||
|
||||
/// The type of services provider supported
|
||||
#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Debug)]
|
||||
#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Debug, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ServiceType {
|
||||
NetworkRequester,
|
||||
@@ -66,7 +67,7 @@ impl std::fmt::Display for ServiceType {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
|
||||
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct ServiceInfo {
|
||||
pub service_id: ServiceId,
|
||||
|
||||
@@ -3,7 +3,12 @@
|
||||
|
||||
use crate::var_names::{DEPRECATED_API_VALIDATOR, DEPRECATED_NYMD_VALIDATOR, NYM_API, NYXD};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{env::var, ops::Not, path::PathBuf};
|
||||
use std::{
|
||||
env::{var, VarError},
|
||||
ffi::OsStr,
|
||||
ops::Not,
|
||||
path::PathBuf,
|
||||
};
|
||||
use url::Url;
|
||||
|
||||
pub mod mainnet;
|
||||
@@ -28,6 +33,7 @@ pub struct NymContracts {
|
||||
pub group_contract_address: Option<String>,
|
||||
pub multisig_contract_address: Option<String>,
|
||||
pub coconut_dkg_contract_address: Option<String>,
|
||||
pub service_provider_directory_contract_address: Option<String>,
|
||||
}
|
||||
|
||||
// I wanted to use the simpler `NetworkDetails` name, but there's a clash
|
||||
@@ -68,6 +74,14 @@ impl NymNetworkDetails {
|
||||
}
|
||||
|
||||
pub fn new_from_env() -> Self {
|
||||
fn get_optional_env<K: AsRef<OsStr>>(env: K) -> Option<String> {
|
||||
match var(env) {
|
||||
Ok(var) => Some(var),
|
||||
Err(VarError::NotPresent) => None,
|
||||
err => panic!("Unable to set: {:?}", err),
|
||||
}
|
||||
}
|
||||
|
||||
NymNetworkDetails::new_empty()
|
||||
.with_bech32_account_prefix(
|
||||
var(var_names::BECH32_PREFIX).expect("bech32 prefix not set"),
|
||||
@@ -117,6 +131,9 @@ impl NymNetworkDetails {
|
||||
.with_coconut_dkg_contract(Some(
|
||||
var(var_names::COCONUT_DKG_CONTRACT_ADDRESS).expect("coconut dkg contract not set"),
|
||||
))
|
||||
.with_service_provider_directory_contract(get_optional_env(
|
||||
var_names::SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn new_mainnet() -> Self {
|
||||
@@ -146,6 +163,9 @@ impl NymNetworkDetails {
|
||||
coconut_dkg_contract_address: parse_optional_str(
|
||||
mainnet::COCONUT_DKG_CONTRACT_ADDRESS,
|
||||
),
|
||||
service_provider_directory_contract_address: parse_optional_str(
|
||||
mainnet::SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS,
|
||||
),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -227,6 +247,15 @@ impl NymNetworkDetails {
|
||||
self.contracts.coconut_dkg_contract_address = contract.map(Into::into);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_service_provider_directory_contract<S: Into<String>>(
|
||||
mut self,
|
||||
contract: Option<S>,
|
||||
) -> Self {
|
||||
self.contracts.service_provider_directory_contract_address = contract.map(Into::into);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Serialize, Deserialize, Clone, PartialEq, Eq)]
|
||||
|
||||
@@ -20,6 +20,8 @@ pub(crate) const COCONUT_BANDWIDTH_CONTRACT_ADDRESS: &str =
|
||||
pub(crate) const GROUP_CONTRACT_ADDRESS: &str = "n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0";
|
||||
pub(crate) const MULTISIG_CONTRACT_ADDRESS: &str = "n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0";
|
||||
pub(crate) const COCONUT_DKG_CONTRACT_ADDRESS: &str = "n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0";
|
||||
pub(crate) const SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS: &str =
|
||||
"n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0";
|
||||
pub(crate) const _ETH_CONTRACT_ADDRESS: [u8; 20] =
|
||||
hex_literal::hex!("0000000000000000000000000000000000000000");
|
||||
pub(crate) const _ETH_ERC20_CONTRACT_ADDRESS: [u8; 20] =
|
||||
|
||||
@@ -19,6 +19,8 @@ pub const MULTISIG_CONTRACT_ADDRESS: &str = "MULTISIG_CONTRACT_ADDRESS";
|
||||
pub const COCONUT_DKG_CONTRACT_ADDRESS: &str = "COCONUT_DKG_CONTRACT_ADDRESS";
|
||||
pub const REWARDING_VALIDATOR_ADDRESS: &str = "REWARDING_VALIDATOR_ADDRESS";
|
||||
pub const STATISTICS_SERVICE_DOMAIN_ADDRESS: &str = "STATISTICS_SERVICE_DOMAIN_ADDRESS";
|
||||
pub const SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS: &str =
|
||||
"SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS";
|
||||
pub const NYXD: &str = "NYXD";
|
||||
pub const NYM_API: &str = "NYM_API";
|
||||
|
||||
|
||||
Generated
+1
@@ -1152,6 +1152,7 @@ name = "nym-service-provider-directory-common"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cosmwasm-std",
|
||||
"schemars",
|
||||
"serde",
|
||||
]
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ GROUP_CONTRACT_ADDRESS=n1fqquzw4mk0pkamgr2ywt2v7h2j9nuyjjn4gvpy8zlpp6xn0uyuzqfm2
|
||||
MULTISIG_CONTRACT_ADDRESS=n1gaq3666chd5348apj8cka8t2mckv7azp9espyr7wgpxyuzur5d0sazpysy
|
||||
COCONUT_DKG_CONTRACT_ADDRESS=n18yadscxw8v35dds7ksv3j0svmjh3h6e7tmxpadk96mvgz27zygkshuf4vs
|
||||
REWARDING_VALIDATOR_ADDRESS=n10yyd98e2tuwu0f7ypz9dy3hhjw7v772q6287gy
|
||||
SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS=n1ryt076cufyddallg5x0gz3qjz0pd3wg0m4cwkg9njhmlnp6u88qq6nczgj
|
||||
STATISTICS_SERVICE_DOMAIN_ADDRESS="https://mainnet-stats.nymte.ch:8090"
|
||||
NYXD="https://qwerty-validator.qa.nymte.ch/"
|
||||
NYM_API="https://qwerty-validator-api.qa.nymte.ch/api"
|
||||
|
||||
@@ -82,6 +82,7 @@ nym-mixnet-contract-common = { path = "../common/cosmwasm-smart-contracts/mixnet
|
||||
nym-vesting-contract-common = { path = "../common/cosmwasm-smart-contracts/vesting-contract" }
|
||||
nym-contracts-common = { path = "../common/cosmwasm-smart-contracts/contracts-common" }
|
||||
nym-multisig-contract-common = { path = "../common/cosmwasm-smart-contracts/multisig-contract" }
|
||||
nym-service-provider-directory-common = { path = "../common/cosmwasm-smart-contracts/service-provider-directory" }
|
||||
nym-coconut = { path = "../common/nymcoconut" }
|
||||
nym-sphinx = { path = "../common/nymsphinx" }
|
||||
nym-pemstore = { path = "../common/pemstore" }
|
||||
|
||||
@@ -6,6 +6,7 @@ use nym_mixnet_contract_common::{
|
||||
families::FamilyHead, GatewayBond, IdentityKey, Interval, MixId, MixNodeDetails,
|
||||
RewardingParams,
|
||||
};
|
||||
use nym_service_provider_directory_common::ServiceInfo;
|
||||
use std::collections::HashSet;
|
||||
|
||||
pub(crate) struct ValidatorCacheData {
|
||||
@@ -22,6 +23,8 @@ pub(crate) struct ValidatorCacheData {
|
||||
pub(crate) current_interval: Cache<Option<Interval>>,
|
||||
|
||||
pub(crate) mix_to_family: Cache<Vec<(IdentityKey, FamilyHead)>>,
|
||||
|
||||
pub(crate) service_providers: Cache<Vec<ServiceInfo>>,
|
||||
}
|
||||
|
||||
impl ValidatorCacheData {
|
||||
@@ -36,6 +39,7 @@ impl ValidatorCacheData {
|
||||
current_interval: Cache::default(),
|
||||
current_reward_params: Cache::default(),
|
||||
mix_to_family: Cache::default(),
|
||||
service_providers: Cache::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
-1
@@ -5,6 +5,7 @@ use nym_mixnet_contract_common::{
|
||||
families::FamilyHead, GatewayBond, IdentityKey, Interval, MixId, MixNodeBond, MixNodeDetails,
|
||||
RewardingParams,
|
||||
};
|
||||
use nym_service_provider_directory_common::ServiceInfo;
|
||||
use rocket::fairing::AdHoc;
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
@@ -50,6 +51,7 @@ impl NymContractCache {
|
||||
rewarding_params: RewardingParams,
|
||||
current_interval: Interval,
|
||||
mix_to_family: Vec<(IdentityKey, FamilyHead)>,
|
||||
services: Option<Vec<ServiceInfo>>,
|
||||
) {
|
||||
match time::timeout(Duration::from_millis(100), self.inner.write()).await {
|
||||
Ok(mut cache) => {
|
||||
@@ -59,7 +61,8 @@ impl NymContractCache {
|
||||
cache.active_set.update(active_set);
|
||||
cache.current_reward_params.update(Some(rewarding_params));
|
||||
cache.current_interval.update(Some(current_interval));
|
||||
cache.mix_to_family.update(mix_to_family)
|
||||
cache.mix_to_family.update(mix_to_family);
|
||||
cache.service_providers.update(services.unwrap_or_default());
|
||||
}
|
||||
Err(err) => {
|
||||
error!("{err}");
|
||||
@@ -286,6 +289,16 @@ impl NymContractCache {
|
||||
self.mixnode_details(mix_id).await.1
|
||||
}
|
||||
|
||||
pub(crate) async fn services(&self) -> Cache<Vec<ServiceInfo>> {
|
||||
match time::timeout(Duration::from_millis(100), self.inner.read()).await {
|
||||
Ok(cache) => cache.service_providers.clone(),
|
||||
Err(err) => {
|
||||
error!("{err}");
|
||||
Cache::new(Vec::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn initialised(&self) -> bool {
|
||||
self.initialised.load(Ordering::Relaxed)
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ use crate::support::caching::CacheNotification;
|
||||
use anyhow::Result;
|
||||
use nym_mixnet_contract_common::{MixId, MixNodeDetails, RewardedSetNodeStatus};
|
||||
use nym_task::TaskClient;
|
||||
use nym_validator_client::nyxd::traits::SpDirectoryQueryClient;
|
||||
use std::{collections::HashMap, sync::atomic::Ordering, time::Duration};
|
||||
use tokio::sync::watch;
|
||||
use tokio::time;
|
||||
@@ -50,6 +51,9 @@ impl NymContractCacheRefresher {
|
||||
let (rewarded_set, active_set) =
|
||||
Self::collect_rewarded_and_active_set_details(&mixnodes, &rewarded_set_map);
|
||||
|
||||
// The service providers are optional
|
||||
let services = self.nyxd_client.get_all_services().await.ok();
|
||||
|
||||
info!(
|
||||
"Updating validator cache. There are {} mixnodes and {} gateways",
|
||||
mixnodes.len(),
|
||||
@@ -65,6 +69,7 @@ impl NymContractCacheRefresher {
|
||||
rewarding_params,
|
||||
current_interval,
|
||||
mix_to_family,
|
||||
services,
|
||||
)
|
||||
.await;
|
||||
|
||||
|
||||
@@ -27,7 +27,8 @@ pub(crate) fn nym_contract_cache_routes(settings: &OpenApiSettings) -> (Vec<Rout
|
||||
routes::get_blacklisted_mixnodes,
|
||||
routes::get_blacklisted_gateways,
|
||||
routes::get_interval_reward_params,
|
||||
routes::get_current_epoch
|
||||
routes::get_current_epoch,
|
||||
routes::get_services
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ use nym_mixnet_contract_common::{
|
||||
mixnode::MixNodeDetails, reward_params::RewardingParams, GatewayBond, Interval, MixId,
|
||||
};
|
||||
|
||||
use nym_service_provider_directory_common::response::ServicesListResponse;
|
||||
use rocket::{serde::json::Json, State};
|
||||
use rocket_okapi::openapi;
|
||||
use std::collections::HashSet;
|
||||
@@ -125,3 +126,10 @@ pub async fn get_interval_reward_params(
|
||||
pub async fn get_current_epoch(cache: &State<NymContractCache>) -> Json<Option<Interval>> {
|
||||
Json(cache.current_interval().await.value)
|
||||
}
|
||||
|
||||
#[openapi(tag = "contract-cache")]
|
||||
#[get("/services")]
|
||||
pub async fn get_services(cache: &State<NymContractCache>) -> Json<ServicesListResponse> {
|
||||
let services = cache.services().await.value;
|
||||
Json(services.as_slice().into())
|
||||
}
|
||||
|
||||
@@ -25,8 +25,11 @@ use nym_mixnet_contract_common::{
|
||||
CurrentIntervalResponse, EpochStatus, ExecuteMsg, GatewayBond, IdentityKey, LayerAssignment,
|
||||
MixId, RewardedSetNodeStatus,
|
||||
};
|
||||
use nym_service_provider_directory_common::msg::QueryMsg as SpQueryMsg;
|
||||
use nym_validator_client::nyxd::error::NyxdError;
|
||||
use nym_validator_client::nyxd::traits::{MixnetQueryClient, MixnetSigningClient};
|
||||
use nym_validator_client::nyxd::traits::{
|
||||
MixnetQueryClient, MixnetSigningClient, SpDirectoryQueryClient,
|
||||
};
|
||||
use nym_validator_client::nyxd::{
|
||||
cosmwasm_client::types::ExecuteResult,
|
||||
traits::{
|
||||
@@ -497,3 +500,21 @@ impl DkgQueryClient for Client {
|
||||
self.0.read().await.nyxd.query_dkg_contract(query).await
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl SpDirectoryQueryClient for Client {
|
||||
async fn query_service_provider_contract<T>(
|
||||
&self,
|
||||
query: SpQueryMsg,
|
||||
) -> std::result::Result<T, NyxdError>
|
||||
where
|
||||
for<'a> T: Deserialize<'a>,
|
||||
{
|
||||
self.0
|
||||
.read()
|
||||
.await
|
||||
.nyxd
|
||||
.query_service_provider_contract(query)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+10
@@ -3578,6 +3578,15 @@ dependencies = [
|
||||
"pem",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-service-provider-directory-common"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cosmwasm-std",
|
||||
"schemars",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-service-providers-common"
|
||||
version = "0.1.0"
|
||||
@@ -3826,6 +3835,7 @@ dependencies = [
|
||||
"nym-mixnet-contract-common",
|
||||
"nym-multisig-contract-common",
|
||||
"nym-network-defaults",
|
||||
"nym-service-provider-directory-common",
|
||||
"nym-vesting-contract",
|
||||
"nym-vesting-contract-common",
|
||||
"prost",
|
||||
|
||||
Generated
+10
@@ -2996,6 +2996,15 @@ dependencies = [
|
||||
"pem",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-service-provider-directory-common"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cosmwasm-std",
|
||||
"schemars",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-sphinx-types"
|
||||
version = "0.2.0"
|
||||
@@ -3069,6 +3078,7 @@ dependencies = [
|
||||
"nym-mixnet-contract-common",
|
||||
"nym-multisig-contract-common",
|
||||
"nym-network-defaults",
|
||||
"nym-service-provider-directory-common",
|
||||
"nym-vesting-contract",
|
||||
"nym-vesting-contract-common",
|
||||
"prost",
|
||||
|
||||
@@ -114,6 +114,8 @@ mod sandbox {
|
||||
"nymt1k8re7jwz6rnnwrktnejdwkwnncte7ek7kk6fvg";
|
||||
pub(crate) const COCONUT_DKG_CONTRACT_ADDRESS: &str =
|
||||
"nymt1k8re7jwz6rnnwrktnejdwkwnncte7ek7kk6fvg";
|
||||
pub(crate) const SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS: &str =
|
||||
"n1ryt076cufyddallg5x0gz3qjz0pd3wg0m4cwkg9njhmlnp6u88qq6nczgj";
|
||||
pub(crate) const _ETH_CONTRACT_ADDRESS: [u8; 20] =
|
||||
hex_literal::hex!("8e0DcFF7F3085235C32E845f3667aEB3f1e83133");
|
||||
pub(crate) const _ETH_ERC20_CONTRACT_ADDRESS: [u8; 20] =
|
||||
@@ -149,6 +151,9 @@ mod sandbox {
|
||||
group_contract_address: parse_optional_str(GROUP_CONTRACT_ADDRESS),
|
||||
multisig_contract_address: parse_optional_str(MULTISIG_CONTRACT_ADDRESS),
|
||||
coconut_dkg_contract_address: parse_optional_str(COCONUT_DKG_CONTRACT_ADDRESS),
|
||||
service_provider_directory_contract_address: parse_optional_str(
|
||||
SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS,
|
||||
),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -176,6 +181,8 @@ mod qa {
|
||||
pub(crate) const MULTISIG_CONTRACT_ADDRESS: &str = "n17p9rzwnnfxcjp32un9ug7yhhzgtkhvl988qccs";
|
||||
pub(crate) const COCONUT_DKG_CONTRACT_ADDRESS: &str =
|
||||
"n17p9rzwnnfxcjp32un9ug7yhhzgtkhvl988qccs";
|
||||
pub(crate) const SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS: &str =
|
||||
"n1ryt076cufyddallg5x0gz3qjz0pd3wg0m4cwkg9njhmlnp6u88qq6nczgj";
|
||||
pub(crate) const _ETH_CONTRACT_ADDRESS: [u8; 20] =
|
||||
hex_literal::hex!("0000000000000000000000000000000000000000");
|
||||
pub(crate) const _ETH_ERC20_CONTRACT_ADDRESS: [u8; 20] =
|
||||
@@ -210,6 +217,9 @@ mod qa {
|
||||
group_contract_address: parse_optional_str(GROUP_CONTRACT_ADDRESS),
|
||||
multisig_contract_address: parse_optional_str(MULTISIG_CONTRACT_ADDRESS),
|
||||
coconut_dkg_contract_address: parse_optional_str(COCONUT_DKG_CONTRACT_ADDRESS),
|
||||
service_provider_directory_contract_address: parse_optional_str(
|
||||
SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS,
|
||||
),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ use nym_network_defaults::NymNetworkDetails;
|
||||
|
||||
pub(crate) mod gateways;
|
||||
pub(crate) mod mixnodes;
|
||||
pub(crate) mod services;
|
||||
|
||||
pub(crate) async fn execute(
|
||||
global_args: ClientArgs,
|
||||
@@ -19,6 +20,7 @@ pub(crate) async fn execute(
|
||||
nym_cli_commands::validator::mixnet::operators::MixnetOperatorsCommands::Mixnode(
|
||||
mixnode,
|
||||
) => mixnodes::execute(global_args, mixnode, network_details).await?,
|
||||
nym_cli_commands::validator::mixnet::operators::MixnetOperatorsCommands::ServiceProvider(service) => services::execute(global_args, service, network_details).await?,
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
use nym_cli_commands::context::{create_signing_client, ClientArgs};
|
||||
use nym_network_defaults::NymNetworkDetails;
|
||||
|
||||
pub(crate) async fn execute(
|
||||
global_args: ClientArgs,
|
||||
service: nym_cli_commands::validator::mixnet::operators::service::MixnetOperatorsService,
|
||||
network_details: &NymNetworkDetails,
|
||||
) -> anyhow::Result<()> {
|
||||
match service.command {
|
||||
nym_cli_commands::validator::mixnet::operators::service::MixnetOperatorsServiceCommands::Announce(announce) => nym_cli_commands::validator::mixnet::operators::service::announce::announce(announce, create_signing_client(global_args, network_details)?).await,
|
||||
nym_cli_commands::validator::mixnet::operators::service::MixnetOperatorsServiceCommands::Delete(delete) => nym_cli_commands::validator::mixnet::operators::service::delete::delete(delete, create_signing_client(global_args, network_details)?).await,
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -23,6 +23,13 @@ pub(crate) async fn execute(
|
||||
)
|
||||
.await
|
||||
}
|
||||
nym_cli_commands::validator::mixnet::query::MixnetQueryCommands::ServiceProviders(args) => {
|
||||
nym_cli_commands::validator::mixnet::query::query_all_service_providers::query(
|
||||
args,
|
||||
&create_query_client_with_nym_api(network_details)?,
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user