Compare commits
224 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5c35fa4514 | |||
| 279e19ee85 | |||
| 5e59dfa90c | |||
| bc3f0821da | |||
| b8b64feaec | |||
| 79d3930db5 | |||
| 5b8fcf4dbc | |||
| 2b5dde28d3 | |||
| d6890a9c39 | |||
| 0a5bca8e17 | |||
| 5dc3e1f898 | |||
| 51254fce71 | |||
| 2701ec663a | |||
| 0600c9fbc7 | |||
| ccf6bcae87 | |||
| 5d384bbbf5 | |||
| 4b805882bc | |||
| c06d52f2d7 | |||
| 9695ce89a6 | |||
| 5d3fa6d211 | |||
| d676f6c63d | |||
| b6ac5fe260 | |||
| 29854e24b6 | |||
| 773bceb96f | |||
| c9b4309044 | |||
| aa26ba5da1 | |||
| 3531f74110 | |||
| ede37aa332 | |||
| adef085a2c | |||
| bc7deb7ea8 | |||
| 144cec707e | |||
| 2995528818 | |||
| 6efef16916 | |||
| 8491fd9dfa | |||
| bb3e103418 | |||
| 09d1ac69bf | |||
| deaf57be93 | |||
| c883992758 | |||
| c98089611b | |||
| a7bb87d396 | |||
| 27f9409ae1 | |||
| bbe7336092 | |||
| 9458c994e3 | |||
| 777bd45318 | |||
| f3d630a16f | |||
| c92304ea22 | |||
| 48b893e578 | |||
| 0e9fd10691 | |||
| 3ef38613f0 | |||
| 2eef8e781b | |||
| 9a860934ea | |||
| 01b5d8bb38 | |||
| 2d6ed2ac9e | |||
| 9ce2cc0218 | |||
| ac205c05cf | |||
| 75e4a7ba72 | |||
| 83060e614f | |||
| bf05930fa8 | |||
| c1659a235e | |||
| 586a701bd0 | |||
| 9dc4889995 | |||
| dd5838cecb | |||
| 13a7651cd6 | |||
| a82e62782a | |||
| cba35a7523 | |||
| 7ab0a383b4 | |||
| 726c1e3a0c | |||
| 9cd8bae4da | |||
| cd5ebf3b17 | |||
| e5c16d13c5 | |||
| 1672c589a7 | |||
| 50fef1ec0c | |||
| 5265bef6d5 | |||
| bb81c5d471 | |||
| 0db1975aff | |||
| 9f08983077 | |||
| 66c9948a7a | |||
| f2cdb2d08d | |||
| dd1cef8dfc | |||
| ce991ebe9f | |||
| ebc8a216f1 | |||
| 4aab07fb81 | |||
| 51ec06e170 | |||
| 584b4061dc | |||
| 01ce8f5f3f | |||
| f2c3ee19cc | |||
| 5fbca5ceae | |||
| 5b909b27e4 | |||
| 2fa1232420 | |||
| 1dfc69b9b8 | |||
| d907165ff1 | |||
| 3fcd2191ee | |||
| 3638ddf398 | |||
| 3028419e87 | |||
| 36e6470f34 | |||
| 1cf3366423 | |||
| f603c144c6 | |||
| 28486cc58b | |||
| d85e4f15f7 | |||
| a36d8cd1e8 | |||
| 2aa94ac744 | |||
| f1d9f339b9 | |||
| f5a327c486 | |||
| c84e4f8b10 | |||
| 7ed6925b07 | |||
| c09a8b69cb | |||
| 951a7652c0 | |||
| 4a57986412 | |||
| 8ea100dbc4 | |||
| 7cb3149f7b | |||
| f113a9fe32 | |||
| 645ff76445 | |||
| 4d53250f08 | |||
| 6b861d0de2 | |||
| fa43524145 | |||
| 4ff6dcfce1 | |||
| 9e8f0434a4 | |||
| d38fb728b6 | |||
| a745e6bc56 | |||
| 0bc9af5c55 | |||
| 54f754852b | |||
| dfb6dca965 | |||
| 1b1415c60a | |||
| c65640bf9a | |||
| 85106f22ce | |||
| 8f0014780e | |||
| d0c0e64a83 | |||
| 6f6127859f | |||
| 429c700705 | |||
| 38cf1b7a38 | |||
| e9c0a22928 | |||
| 13b29fd5e1 | |||
| 918b06a93d | |||
| b82962d858 | |||
| b55e710680 | |||
| 015127ad29 | |||
| 6a279d5952 | |||
| a4844be9c5 | |||
| 5d101c1db0 | |||
| 29e7e798e5 | |||
| 7e15eedd04 | |||
| a2b479b728 | |||
| 9d79d11ceb | |||
| 0be3f3159e | |||
| 77dd52074e | |||
| bbdd4bb79f | |||
| 03d3105c00 | |||
| 018ec13189 | |||
| ba6aafce5c | |||
| 26548667c6 | |||
| 5e3a16265a | |||
| 5f61eff284 | |||
| 922d7dc11b | |||
| c05df8f60a | |||
| 456c178578 | |||
| 6991086560 | |||
| 5f27775f4c | |||
| 6a67275b44 | |||
| b577fd7a29 | |||
| 859e8aecf8 | |||
| 9b0db3bcb1 | |||
| 03f27dc94b | |||
| 6aa18b969a | |||
| 5b68e4aa95 | |||
| 2ea0a2f3c3 | |||
| e395c00e90 | |||
| 00dcec178e | |||
| bf2472c608 | |||
| 40d0a20d75 | |||
| c9debc4209 | |||
| 3bbeacaf5e | |||
| 2ef4c89f2b | |||
| 283efa7d71 | |||
| 2cecbe3a9f | |||
| 6f55e0d24e | |||
| fd1b152b8e | |||
| d113158447 | |||
| 8799ee1393 | |||
| 22fbccbffc | |||
| 7a84bea603 | |||
| 657de6f4fb | |||
| 7a29c58aba | |||
| 678eb4b2cd | |||
| 8db2afaa16 | |||
| e5ba1a15b2 | |||
| c85b100517 | |||
| fc8275c372 | |||
| 07140ab586 | |||
| a37e0d40df | |||
| 98fa8f2106 | |||
| 00b53445d9 | |||
| f6c089bd22 | |||
| 3318ad525c | |||
| df93426a3d | |||
| 0523746a16 | |||
| 6d121de507 | |||
| f54621600a | |||
| 80da4aa2e4 | |||
| 620bbdd204 | |||
| 0d515e598e | |||
| c24b937d4e | |||
| 54a3fe082e | |||
| b8e23de4e6 | |||
| b9a2b1b1a9 | |||
| b9afdf32ad | |||
| ab1cf1e67d | |||
| 6f5231421b | |||
| 95caf0e07d | |||
| fbcaf7a47b | |||
| 1df8252f80 | |||
| 28e1002cfa | |||
| c39e226dd0 | |||
| 8cac6d9847 | |||
| c67cf86ed6 | |||
| b34c099278 | |||
| ee383e7b17 | |||
| dc800aee08 | |||
| 7b986b6b09 | |||
| 5629a6c898 | |||
| 341337fc80 | |||
| f1d754a1cb | |||
| 2ccbabce73 | |||
| 44997cff5a | |||
| bb6144b3bd |
Generated
+23
-4
@@ -430,6 +430,14 @@ version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
||||
|
||||
[[package]]
|
||||
name = "autodoc"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"env_logger 0.11.5",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "axum"
|
||||
version = "0.6.20"
|
||||
@@ -2354,6 +2362,19 @@ dependencies = [
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.11.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"env_filter",
|
||||
"humantime 2.1.0",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "envy"
|
||||
version = "0.4.2"
|
||||
@@ -5080,7 +5101,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-credential-proxy"
|
||||
version = "0.1.3"
|
||||
version = "0.1.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -5460,7 +5481,6 @@ dependencies = [
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2 0.10.8",
|
||||
"si-scale",
|
||||
"sqlx",
|
||||
"subtle-encoding",
|
||||
@@ -7468,7 +7488,7 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d"
|
||||
dependencies = [
|
||||
"env_logger",
|
||||
"env_logger 0.7.1",
|
||||
"log",
|
||||
]
|
||||
|
||||
@@ -10684,7 +10704,6 @@ dependencies = [
|
||||
"quote",
|
||||
"regex",
|
||||
"syn 2.0.82",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# Nym Desktop Client
|
||||
|
||||
The Nym Desktop Client communicates with the remote, decentralised nodes which make up the Nym system as a whole.
|
||||
|
||||
TEST CI PICKUP
|
||||
The Nym Desktop Client communicates with the remote, decentralised nodes which make up the Nym system as a whole.
|
||||
|
||||
@@ -18,7 +18,7 @@ use nym_api_requests::ecash::{
|
||||
PartialExpirationDateSignatureResponse, VerificationKeyResponse,
|
||||
};
|
||||
use nym_api_requests::models::{
|
||||
ApiHealthResponse, GatewayCoreStatusResponse, MixnodeCoreStatusResponse, MixnodeStatusResponse,
|
||||
GatewayCoreStatusResponse, MixnodeCoreStatusResponse, MixnodeStatusResponse,
|
||||
NymNodeDescription, RewardEstimationResponse, StakeSaturationResponse,
|
||||
};
|
||||
use nym_api_requests::models::{LegacyDescribedGateway, MixNodeBondAnnotated};
|
||||
@@ -192,8 +192,6 @@ impl<C, S> Client<C, S> {
|
||||
}
|
||||
|
||||
// validator-api wrappers
|
||||
// we have to allow the use of deprecated method here as they're calling the deprecated trait methods
|
||||
#[allow(deprecated)]
|
||||
impl<C, S> Client<C, S> {
|
||||
pub fn api_url(&self) -> &Url {
|
||||
self.nym_api.current_url()
|
||||
@@ -203,54 +201,46 @@ impl<C, S> Client<C, S> {
|
||||
self.nym_api.change_base_url(new_endpoint)
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
pub async fn get_cached_mixnodes(&self) -> Result<Vec<MixNodeDetails>, ValidatorClientError> {
|
||||
Ok(self.nym_api.get_mixnodes().await?)
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
pub async fn get_cached_mixnodes_detailed(
|
||||
&self,
|
||||
) -> Result<Vec<MixNodeBondAnnotated>, ValidatorClientError> {
|
||||
Ok(self.nym_api.get_mixnodes_detailed().await?)
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
pub async fn get_cached_mixnodes_detailed_unfiltered(
|
||||
&self,
|
||||
) -> Result<Vec<MixNodeBondAnnotated>, ValidatorClientError> {
|
||||
Ok(self.nym_api.get_mixnodes_detailed_unfiltered().await?)
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
pub async fn get_cached_rewarded_mixnodes(
|
||||
&self,
|
||||
) -> Result<Vec<MixNodeDetails>, ValidatorClientError> {
|
||||
Ok(self.nym_api.get_rewarded_mixnodes().await?)
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
pub async fn get_cached_rewarded_mixnodes_detailed(
|
||||
&self,
|
||||
) -> Result<Vec<MixNodeBondAnnotated>, ValidatorClientError> {
|
||||
Ok(self.nym_api.get_rewarded_mixnodes_detailed().await?)
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
pub async fn get_cached_active_mixnodes(
|
||||
&self,
|
||||
) -> Result<Vec<MixNodeDetails>, ValidatorClientError> {
|
||||
Ok(self.nym_api.get_active_mixnodes().await?)
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
pub async fn get_cached_active_mixnodes_detailed(
|
||||
&self,
|
||||
) -> Result<Vec<MixNodeBondAnnotated>, ValidatorClientError> {
|
||||
Ok(self.nym_api.get_active_mixnodes_detailed().await?)
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
pub async fn get_cached_gateways(&self) -> Result<Vec<GatewayBond>, ValidatorClientError> {
|
||||
Ok(self.nym_api.get_gateways().await?)
|
||||
}
|
||||
@@ -314,8 +304,6 @@ pub struct NymApiClient {
|
||||
// we could re-implement the communication with the REST API on port 1317
|
||||
}
|
||||
|
||||
// we have to allow the use of deprecated method here as they're calling the deprecated trait methods
|
||||
#[allow(deprecated)]
|
||||
impl NymApiClient {
|
||||
pub fn new(api_url: Url) -> Self {
|
||||
let nym_api = nym_api::Client::new(api_url, None);
|
||||
@@ -436,38 +424,6 @@ impl NymApiClient {
|
||||
Ok(nodes)
|
||||
}
|
||||
|
||||
/// retrieve basic information for nodes are capable of operating as a mixnode
|
||||
/// this includes legacy mixnodes and nym-nodes
|
||||
pub async fn get_all_basic_mixing_capable_nodes(
|
||||
&self,
|
||||
semver_compatibility: Option<String>,
|
||||
) -> Result<Vec<SkimmedNode>, ValidatorClientError> {
|
||||
// TODO: deal with paging in macro or some helper function or something, because it's the same pattern everywhere
|
||||
let mut page = 0;
|
||||
let mut nodes = Vec::new();
|
||||
|
||||
loop {
|
||||
let mut res = self
|
||||
.nym_api
|
||||
.get_basic_mixing_capable_nodes(
|
||||
semver_compatibility.clone(),
|
||||
false,
|
||||
Some(page),
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
|
||||
nodes.append(&mut res.nodes.data);
|
||||
if nodes.len() < res.nodes.pagination.total {
|
||||
page += 1
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(nodes)
|
||||
}
|
||||
|
||||
/// retrieve basic information for all bonded nodes on the network
|
||||
pub async fn get_all_basic_nodes(
|
||||
&self,
|
||||
@@ -494,35 +450,26 @@ impl NymApiClient {
|
||||
Ok(nodes)
|
||||
}
|
||||
|
||||
pub async fn health(&self) -> Result<ApiHealthResponse, ValidatorClientError> {
|
||||
Ok(self.nym_api.health().await?)
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
pub async fn get_cached_active_mixnodes(
|
||||
&self,
|
||||
) -> Result<Vec<MixNodeDetails>, ValidatorClientError> {
|
||||
Ok(self.nym_api.get_active_mixnodes().await?)
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
pub async fn get_cached_rewarded_mixnodes(
|
||||
&self,
|
||||
) -> Result<Vec<MixNodeDetails>, ValidatorClientError> {
|
||||
Ok(self.nym_api.get_rewarded_mixnodes().await?)
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
pub async fn get_cached_mixnodes(&self) -> Result<Vec<MixNodeDetails>, ValidatorClientError> {
|
||||
Ok(self.nym_api.get_mixnodes().await?)
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
pub async fn get_cached_gateways(&self) -> Result<Vec<GatewayBond>, ValidatorClientError> {
|
||||
Ok(self.nym_api.get_gateways().await?)
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
pub async fn get_cached_described_gateways(
|
||||
&self,
|
||||
) -> Result<Vec<LegacyDescribedGateway>, ValidatorClientError> {
|
||||
@@ -571,7 +518,6 @@ impl NymApiClient {
|
||||
Ok(bonds)
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
pub async fn get_gateway_core_status_count(
|
||||
&self,
|
||||
identity: IdentityKeyRef<'_>,
|
||||
@@ -583,7 +529,6 @@ impl NymApiClient {
|
||||
.await?)
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
pub async fn get_mixnode_core_status_count(
|
||||
&self,
|
||||
mix_id: NodeId,
|
||||
@@ -595,7 +540,6 @@ impl NymApiClient {
|
||||
.await?)
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
pub async fn get_mixnode_status(
|
||||
&self,
|
||||
mix_id: NodeId,
|
||||
@@ -603,7 +547,6 @@ impl NymApiClient {
|
||||
Ok(self.nym_api.get_mixnode_status(mix_id).await?)
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
pub async fn get_mixnode_reward_estimation(
|
||||
&self,
|
||||
mix_id: NodeId,
|
||||
@@ -611,7 +554,6 @@ impl NymApiClient {
|
||||
Ok(self.nym_api.get_mixnode_reward_estimation(mix_id).await?)
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
pub async fn get_mixnode_stake_saturation(
|
||||
&self,
|
||||
mix_id: NodeId,
|
||||
@@ -643,7 +585,6 @@ impl NymApiClient {
|
||||
.await?)
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
pub async fn spent_credentials_filter(
|
||||
&self,
|
||||
) -> Result<SpentCredentialsResponse, ValidatorClientError> {
|
||||
|
||||
@@ -164,7 +164,7 @@ async fn test_nym_api_connection(
|
||||
) -> ConnectionResult {
|
||||
let result = match timeout(
|
||||
Duration::from_secs(CONNECTION_TEST_TIMEOUT_SEC),
|
||||
client.health(),
|
||||
client.get_cached_mixnodes(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
|
||||
@@ -11,8 +11,7 @@ use nym_api_requests::ecash::models::{
|
||||
};
|
||||
use nym_api_requests::ecash::VerificationKeyResponse;
|
||||
use nym_api_requests::models::{
|
||||
AnnotationResponse, ApiHealthResponse, LegacyDescribedMixNode, NodePerformanceResponse,
|
||||
NymNodeDescription,
|
||||
AnnotationResponse, LegacyDescribedMixNode, NodePerformanceResponse, NymNodeDescription,
|
||||
};
|
||||
use nym_api_requests::nym_nodes::PaginatedCachedNodesResponse;
|
||||
use nym_api_requests::pagination::PaginatedResponse;
|
||||
@@ -55,26 +54,12 @@ pub fn rfc_3339_date() -> Vec<BorrowedFormatItem<'static>> {
|
||||
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
|
||||
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
|
||||
pub trait NymApiClientExt: ApiClient {
|
||||
async fn health(&self) -> Result<ApiHealthResponse, NymAPIError> {
|
||||
self.get_json(
|
||||
&[
|
||||
routes::API_VERSION,
|
||||
routes::API_STATUS_ROUTES,
|
||||
routes::HEALTH,
|
||||
],
|
||||
NO_PARAMS,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn get_mixnodes(&self) -> Result<Vec<MixNodeDetails>, NymAPIError> {
|
||||
self.get_json(&[routes::API_VERSION, routes::MIXNODES], NO_PARAMS)
|
||||
.await
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn get_mixnodes_detailed(&self) -> Result<Vec<MixNodeBondAnnotated>, NymAPIError> {
|
||||
self.get_json(
|
||||
@@ -89,7 +74,6 @@ pub trait NymApiClientExt: ApiClient {
|
||||
.await
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn get_gateways_detailed(&self) -> Result<Vec<GatewayBondAnnotated>, NymAPIError> {
|
||||
self.get_json(
|
||||
@@ -104,7 +88,6 @@ pub trait NymApiClientExt: ApiClient {
|
||||
.await
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn get_mixnodes_detailed_unfiltered(
|
||||
&self,
|
||||
@@ -121,14 +104,12 @@ pub trait NymApiClientExt: ApiClient {
|
||||
.await
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn get_gateways(&self) -> Result<Vec<GatewayBond>, NymAPIError> {
|
||||
self.get_json(&[routes::API_VERSION, routes::GATEWAYS], NO_PARAMS)
|
||||
.await
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn get_gateways_described(&self) -> Result<Vec<LegacyDescribedGateway>, NymAPIError> {
|
||||
self.get_json(
|
||||
@@ -138,7 +119,6 @@ pub trait NymApiClientExt: ApiClient {
|
||||
.await
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn get_mixnodes_described(&self) -> Result<Vec<LegacyDescribedMixNode>, NymAPIError> {
|
||||
self.get_json(
|
||||
@@ -148,7 +128,6 @@ pub trait NymApiClientExt: ApiClient {
|
||||
.await
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip_all)]
|
||||
async fn get_nodes_described(
|
||||
&self,
|
||||
page: Option<u32>,
|
||||
@@ -168,7 +147,6 @@ pub trait NymApiClientExt: ApiClient {
|
||||
.await
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip_all)]
|
||||
async fn get_nym_nodes(
|
||||
&self,
|
||||
page: Option<u32>,
|
||||
@@ -188,7 +166,6 @@ pub trait NymApiClientExt: ApiClient {
|
||||
.await
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[tracing::instrument(level = "debug", skip_all)]
|
||||
async fn get_basic_mixnodes(
|
||||
&self,
|
||||
@@ -213,7 +190,6 @@ pub trait NymApiClientExt: ApiClient {
|
||||
.await
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn get_basic_gateways(
|
||||
&self,
|
||||
@@ -322,49 +298,6 @@ pub trait NymApiClientExt: ApiClient {
|
||||
.await
|
||||
}
|
||||
|
||||
/// retrieve basic information for nodes that got assigned 'mixing' node in this epoch
|
||||
/// this includes legacy mixnodes and nym-nodes
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn get_basic_mixing_capable_nodes(
|
||||
&self,
|
||||
semver_compatibility: Option<String>,
|
||||
no_legacy: bool,
|
||||
page: Option<u32>,
|
||||
per_page: Option<u32>,
|
||||
) -> Result<PaginatedCachedNodesResponse<SkimmedNode>, NymAPIError> {
|
||||
let mut params = Vec::new();
|
||||
|
||||
if let Some(arg) = &semver_compatibility {
|
||||
params.push(("semver_compatibility", arg.clone()))
|
||||
}
|
||||
|
||||
if no_legacy {
|
||||
params.push(("no_legacy", "true".to_string()))
|
||||
}
|
||||
|
||||
if let Some(page) = page {
|
||||
params.push(("page", page.to_string()))
|
||||
}
|
||||
|
||||
if let Some(per_page) = per_page {
|
||||
params.push(("per_page", per_page.to_string()))
|
||||
}
|
||||
|
||||
self.get_json(
|
||||
&[
|
||||
routes::API_VERSION,
|
||||
"unstable",
|
||||
"nym-nodes",
|
||||
"skimmed",
|
||||
"mixnodes",
|
||||
"all",
|
||||
],
|
||||
¶ms,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn get_basic_nodes(
|
||||
&self,
|
||||
semver_compatibility: Option<String>,
|
||||
@@ -397,7 +330,6 @@ pub trait NymApiClientExt: ApiClient {
|
||||
.await
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn get_active_mixnodes(&self) -> Result<Vec<MixNodeDetails>, NymAPIError> {
|
||||
self.get_json(
|
||||
@@ -407,7 +339,6 @@ pub trait NymApiClientExt: ApiClient {
|
||||
.await
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn get_active_mixnodes_detailed(&self) -> Result<Vec<MixNodeBondAnnotated>, NymAPIError> {
|
||||
self.get_json(
|
||||
@@ -423,7 +354,6 @@ pub trait NymApiClientExt: ApiClient {
|
||||
.await
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn get_rewarded_mixnodes(&self) -> Result<Vec<MixNodeDetails>, NymAPIError> {
|
||||
self.get_json(
|
||||
@@ -433,7 +363,6 @@ pub trait NymApiClientExt: ApiClient {
|
||||
.await
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn get_mixnode_report(
|
||||
&self,
|
||||
@@ -452,7 +381,6 @@ pub trait NymApiClientExt: ApiClient {
|
||||
.await
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn get_gateway_report(
|
||||
&self,
|
||||
@@ -471,7 +399,6 @@ pub trait NymApiClientExt: ApiClient {
|
||||
.await
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn get_mixnode_history(
|
||||
&self,
|
||||
@@ -490,7 +417,6 @@ pub trait NymApiClientExt: ApiClient {
|
||||
.await
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn get_gateway_history(
|
||||
&self,
|
||||
@@ -509,7 +435,6 @@ pub trait NymApiClientExt: ApiClient {
|
||||
.await
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn get_rewarded_mixnodes_detailed(
|
||||
&self,
|
||||
@@ -527,7 +452,6 @@ pub trait NymApiClientExt: ApiClient {
|
||||
.await
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn get_gateway_core_status_count(
|
||||
&self,
|
||||
@@ -560,7 +484,6 @@ pub trait NymApiClientExt: ApiClient {
|
||||
}
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn get_mixnode_core_status_count(
|
||||
&self,
|
||||
@@ -594,7 +517,6 @@ pub trait NymApiClientExt: ApiClient {
|
||||
}
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn get_mixnode_status(
|
||||
&self,
|
||||
@@ -613,7 +535,6 @@ pub trait NymApiClientExt: ApiClient {
|
||||
.await
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn get_mixnode_reward_estimation(
|
||||
&self,
|
||||
@@ -632,7 +553,6 @@ pub trait NymApiClientExt: ApiClient {
|
||||
.await
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn compute_mixnode_reward_estimation(
|
||||
&self,
|
||||
@@ -653,7 +573,6 @@ pub trait NymApiClientExt: ApiClient {
|
||||
.await
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn get_mixnode_stake_saturation(
|
||||
&self,
|
||||
@@ -672,7 +591,6 @@ pub trait NymApiClientExt: ApiClient {
|
||||
.await
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn get_mixnode_inclusion_probability(
|
||||
&self,
|
||||
@@ -708,7 +626,6 @@ pub trait NymApiClientExt: ApiClient {
|
||||
.await
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
async fn get_mixnode_avg_uptime(&self, mix_id: NodeId) -> Result<UptimeResponse, NymAPIError> {
|
||||
self.get_json(
|
||||
&[
|
||||
@@ -723,7 +640,6 @@ pub trait NymApiClientExt: ApiClient {
|
||||
.await
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn get_mixnodes_blacklisted(&self) -> Result<Vec<NodeId>, NymAPIError> {
|
||||
self.get_json(
|
||||
@@ -733,7 +649,6 @@ pub trait NymApiClientExt: ApiClient {
|
||||
.await
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn get_gateways_blacklisted(&self) -> Result<Vec<IdentityKey>, NymAPIError> {
|
||||
self.get_json(
|
||||
@@ -794,7 +709,6 @@ pub trait NymApiClientExt: ApiClient {
|
||||
.await
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn double_spending_filter_v1(&self) -> Result<SpentCredentialsResponse, NymAPIError> {
|
||||
self.get_json(
|
||||
|
||||
@@ -36,8 +36,6 @@ pub mod ecash {
|
||||
}
|
||||
|
||||
pub const STATUS_ROUTES: &str = "status";
|
||||
pub const API_STATUS_ROUTES: &str = "api-status";
|
||||
pub const HEALTH: &str = "health";
|
||||
pub const MIXNODE: &str = "mixnode";
|
||||
pub const GATEWAY: &str = "gateway";
|
||||
pub const NYM_NODES: &str = "nym-nodes";
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::context::QueryClientWithNyxd;
|
||||
use crate::utils::show_error;
|
||||
use crate::utils::{pretty_cosmwasm_coin, show_error};
|
||||
use clap::Parser;
|
||||
use comfy_table::Table;
|
||||
use nym_validator_client::client::NymApiClientExt;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct Args {
|
||||
@@ -14,11 +15,12 @@ pub struct Args {
|
||||
}
|
||||
|
||||
pub async fn query(args: Args, client: &QueryClientWithNyxd) {
|
||||
match client.get_all_cached_described_nodes().await {
|
||||
match client.nym_api.get_gateways().await {
|
||||
Ok(res) => match args.identity_key {
|
||||
Some(identity_key) => {
|
||||
let node = res.iter().find(|node| {
|
||||
node.ed25519_identity_key()
|
||||
node.gateway
|
||||
.identity_key
|
||||
.to_string()
|
||||
.eq_ignore_ascii_case(&identity_key)
|
||||
});
|
||||
@@ -30,16 +32,14 @@ pub async fn query(args: Args, client: &QueryClientWithNyxd) {
|
||||
None => {
|
||||
let mut table = Table::new();
|
||||
|
||||
table.set_header(vec!["Node Id", "Identity Key", "Version", "Is Legacy"]);
|
||||
for node in res
|
||||
.into_iter()
|
||||
.filter(|node| node.description.declared_role.entry)
|
||||
{
|
||||
table.set_header(vec!["Identity Key", "Owner", "Host", "Bond", "Version"]);
|
||||
for node in res {
|
||||
table.add_row(vec![
|
||||
node.node_id.to_string(),
|
||||
node.ed25519_identity_key().to_base58_string(),
|
||||
node.description.build_information.build_version,
|
||||
(!node.contract_node_type.is_nym_node()).to_string(),
|
||||
node.gateway.identity_key.to_string(),
|
||||
node.owner.to_string(),
|
||||
node.gateway.host.to_string(),
|
||||
pretty_cosmwasm_coin(&node.pledge_amount),
|
||||
node.gateway.version.clone(),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::context::QueryClientWithNyxd;
|
||||
use crate::utils::show_error;
|
||||
use crate::utils::{pretty_decimal_with_denom, show_error};
|
||||
use clap::Parser;
|
||||
use comfy_table::Table;
|
||||
use nym_validator_client::client::NymApiClientExt;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct Args {
|
||||
@@ -14,11 +15,13 @@ pub struct Args {
|
||||
}
|
||||
|
||||
pub async fn query(args: Args, client: &QueryClientWithNyxd) {
|
||||
match client.get_all_cached_described_nodes().await {
|
||||
match client.nym_api.get_mixnodes().await {
|
||||
Ok(res) => match args.identity_key {
|
||||
Some(identity_key) => {
|
||||
let node = res.iter().find(|node| {
|
||||
node.ed25519_identity_key()
|
||||
node.bond_information
|
||||
.mix_node
|
||||
.identity_key
|
||||
.to_string()
|
||||
.eq_ignore_ascii_case(&identity_key)
|
||||
});
|
||||
@@ -30,16 +33,25 @@ pub async fn query(args: Args, client: &QueryClientWithNyxd) {
|
||||
None => {
|
||||
let mut table = Table::new();
|
||||
|
||||
table.set_header(vec!["Node Id", "Identity Key", "Version", "Is Legacy"]);
|
||||
for node in res
|
||||
.into_iter()
|
||||
.filter(|node| node.description.declared_role.mixnode)
|
||||
{
|
||||
table.set_header(vec![
|
||||
"Mix id",
|
||||
"Identity Key",
|
||||
"Owner",
|
||||
"Host",
|
||||
"Bond",
|
||||
"Total Delegations",
|
||||
"Version",
|
||||
]);
|
||||
for node in res {
|
||||
let denom = &node.bond_information.original_pledge().denom;
|
||||
table.add_row(vec![
|
||||
node.node_id.to_string(),
|
||||
node.ed25519_identity_key().to_base58_string(),
|
||||
node.description.build_information.build_version,
|
||||
(!node.contract_node_type.is_nym_node()).to_string(),
|
||||
node.mix_id().to_string(),
|
||||
node.bond_information.mix_node.identity_key.clone(),
|
||||
node.bond_information.owner.clone().into_string(),
|
||||
node.bond_information.mix_node.host.clone(),
|
||||
pretty_decimal_with_denom(node.rewarding_details.operator, denom),
|
||||
pretty_decimal_with_denom(node.rewarding_details.delegates, denom),
|
||||
node.bond_information.mix_node.version,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ use std::sync::Arc;
|
||||
use time::{Date, OffsetDateTime};
|
||||
use tracing::*;
|
||||
|
||||
use nym_credentials::ecash::utils::{cred_exp_date, ecash_today, EcashTime};
|
||||
use nym_credentials::ecash::utils::{ecash_today, EcashTime};
|
||||
use nym_credentials_interface::{Bandwidth, ClientTicket, TicketType};
|
||||
use nym_gateway_requests::models::CredentialSpendingRequest;
|
||||
use nym_gateway_storage::Storage;
|
||||
@@ -131,7 +131,7 @@ impl<S: Storage + Clone + 'static> CredentialVerifier<S> {
|
||||
let bandwidth = Bandwidth::ticket_amount(credential_type.into());
|
||||
|
||||
self.bandwidth_storage_manager
|
||||
.increase_bandwidth(bandwidth, cred_exp_date())
|
||||
.increase_bandwidth(bandwidth, spend_date)
|
||||
.await?;
|
||||
|
||||
Ok(self
|
||||
|
||||
@@ -104,8 +104,8 @@ impl PersistentStatsStorage {
|
||||
.await?)
|
||||
}
|
||||
|
||||
pub async fn get_unique_users(&self, date: Date) -> Result<Vec<String>, StatsStorageError> {
|
||||
Ok(self.session_manager.get_unique_users(date).await?)
|
||||
pub async fn get_unique_users_count(&self, date: Date) -> Result<i32, StatsStorageError> {
|
||||
Ok(self.session_manager.get_unique_users_count(date).await?)
|
||||
}
|
||||
|
||||
pub async fn delete_unique_users(&self, before_date: Date) -> Result<(), StatsStorageError> {
|
||||
|
||||
@@ -71,13 +71,14 @@ impl SessionManager {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn get_unique_users(&self, date: Date) -> Result<Vec<String>> {
|
||||
sqlx::query_scalar!(
|
||||
"SELECT client_address as count FROM sessions_unique_users WHERE day = ?",
|
||||
pub(crate) async fn get_unique_users_count(&self, date: Date) -> Result<i32> {
|
||||
Ok(sqlx::query!(
|
||||
"SELECT COUNT(*) as count FROM sessions_unique_users WHERE day = ?",
|
||||
date
|
||||
)
|
||||
.fetch_all(&self.connection_pool)
|
||||
.await
|
||||
.fetch_one(&self.connection_pool)
|
||||
.await?
|
||||
.count)
|
||||
}
|
||||
|
||||
pub(crate) async fn delete_unique_users(&self, before_date: Date) -> Result<()> {
|
||||
|
||||
@@ -534,19 +534,17 @@ where
|
||||
}
|
||||
|
||||
if res.status().is_success() {
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
let text = res.text().await.inspect_err(|err| {
|
||||
tracing::error!("Couldn't even get response text: {err}");
|
||||
})?;
|
||||
tracing::trace!("Result:\n{:#?}", text);
|
||||
|
||||
serde_json::from_str(&text)
|
||||
.map_err(|err| HttpClientError::GenericRequestFailure(err.to_string()))
|
||||
let text = res.text().await?;
|
||||
match serde_json::from_str(&text) {
|
||||
Ok(res) => Ok(res),
|
||||
Err(source) => {
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
tracing::trace!("Result:\n{:#?}", text);
|
||||
}
|
||||
Err(HttpClientError::ResponseDeserialisationFailure { source })
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
Ok(res.json().await?)
|
||||
} else if res.status() == StatusCode::NOT_FOUND {
|
||||
Err(HttpClientError::NotFound)
|
||||
} else {
|
||||
|
||||
@@ -14,6 +14,7 @@ use nym_task::TaskClient;
|
||||
use rand::seq::SliceRandom;
|
||||
use rand::thread_rng;
|
||||
use std::net::SocketAddr;
|
||||
use std::net::ToSocketAddrs;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use tokio::task::JoinHandle;
|
||||
@@ -312,7 +313,7 @@ impl VerlocMeasurer {
|
||||
info!("Starting verloc measurements");
|
||||
// TODO: should we also measure gateways?
|
||||
|
||||
let all_mixes = match self.validator_client.get_all_described_nodes().await {
|
||||
let all_mixes = match self.validator_client.get_cached_mixnodes().await {
|
||||
Ok(nodes) => nodes,
|
||||
Err(err) => {
|
||||
error!(
|
||||
@@ -331,14 +332,22 @@ impl VerlocMeasurer {
|
||||
// we only care about address and identity
|
||||
let tested_nodes = all_mixes
|
||||
.into_iter()
|
||||
.filter(|n| n.description.declared_role.mixnode)
|
||||
.filter_map(|node| {
|
||||
// try to parse the identity and host
|
||||
let node_identity = node.ed25519_identity_key();
|
||||
let mix_node = node.bond_information.mix_node;
|
||||
// check if the node has sufficient version to be able to understand the packets
|
||||
let node_version = parse_version(&mix_node.version).ok()?;
|
||||
if node_version < self.config.minimum_compatible_node_version {
|
||||
return None;
|
||||
}
|
||||
|
||||
let ip = node.description.host_information.ip_address.first()?;
|
||||
let verloc_port = node.description.verloc_port();
|
||||
let verloc_host = SocketAddr::new(*ip, verloc_port);
|
||||
// try to parse the identity and host
|
||||
let node_identity =
|
||||
identity::PublicKey::from_base58_string(mix_node.identity_key).ok()?;
|
||||
|
||||
let verloc_host = (&*mix_node.host, mix_node.verloc_port)
|
||||
.to_socket_addrs()
|
||||
.ok()?
|
||||
.next()?;
|
||||
|
||||
// TODO: possible problem in the future, this does name resolution and theoretically
|
||||
// if a lot of nodes maliciously mis-configured themselves, it might take a while to resolve them all
|
||||
|
||||
@@ -99,25 +99,12 @@ pub async fn start_wireguard<St: nym_gateway_storage::Storage + Clone + 'static>
|
||||
let peers = all_peers
|
||||
.into_iter()
|
||||
.map(Peer::try_from)
|
||||
.collect::<Result<Vec<_>, _>>()?
|
||||
.into_iter()
|
||||
.map(|mut peer| {
|
||||
// since WGApi doesn't set those values on init, let's set them to 0
|
||||
peer.rx_bytes = 0;
|
||||
peer.tx_bytes = 0;
|
||||
peer
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
for peer in peers.iter() {
|
||||
let bandwidth_manager =
|
||||
PeerController::generate_bandwidth_manager(storage.clone(), &peer.public_key)
|
||||
.await?
|
||||
.map(|bw_m| Arc::new(RwLock::new(bw_m)));
|
||||
// Update storage with *x_bytes set to 0, as in kernel peers we can't set those values
|
||||
// so we need to restart counting. Hopefully the bandwidth was counted in available_bandwidth
|
||||
storage
|
||||
.insert_wireguard_peer(peer, bandwidth_manager.is_some())
|
||||
.await?;
|
||||
peer_bandwidth_managers.insert(peer.public_key.clone(), bandwidth_manager);
|
||||
}
|
||||
wg_api.create_interface()?;
|
||||
|
||||
@@ -75,8 +75,8 @@ impl<St: Storage + Clone + 'static> PeerHandle<St> {
|
||||
|
||||
async fn active_peer(
|
||||
&mut self,
|
||||
storage_peer: &WireguardPeer,
|
||||
kernel_peer: &Peer,
|
||||
storage_peer: WireguardPeer,
|
||||
kernel_peer: Peer,
|
||||
) -> Result<bool, Error> {
|
||||
if let Some(bandwidth_manager) = &self.bandwidth_storage_manager {
|
||||
let spent_bandwidth = (kernel_peer.rx_bytes + kernel_peer.tx_bytes)
|
||||
@@ -136,12 +136,9 @@ impl<St: Storage + Clone + 'static> PeerHandle<St> {
|
||||
log::debug!("Peer {:?} not in storage anymore, shutting down handle", self.public_key);
|
||||
return Ok(());
|
||||
};
|
||||
if !self.active_peer(&storage_peer, &kernel_peer).await? {
|
||||
if !self.active_peer(storage_peer, kernel_peer).await? {
|
||||
log::debug!("Peer {:?} doesn't have bandwidth anymore, shutting down handle", self.public_key);
|
||||
return Ok(());
|
||||
} else {
|
||||
// Update storage values
|
||||
self.storage.insert_wireguard_peer(&kernel_peer, self.bandwidth_storage_manager.is_some()).await?;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,9 @@ pnpm run build
|
||||
|
||||
> **Only run this script on branches where you want to push e.g. the build info of a binary to production docs**; it will build the monorepo binaries and use their command output for the produced markdown files.
|
||||
|
||||
## CI/CD
|
||||
TODO
|
||||
|
||||
## Licensing and copyright information
|
||||
This is a monorepo and components that make up Nym as a system are licensed individually, so for accurate information, please check individual files.
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
Wednesday, November 6th 2024, 10:18:58 UTC
|
||||
Tuesday, October 29th 2024, 09:51:52 UTC
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
```sh
|
||||
[2m2024-11-06T10:12:52.501648Z[0m [32m INFO[0m [2mnym-api/src/main.rs[0m[2m:[0m[2m41[0m[2m:[0m Starting nym api...
|
||||
[2m2024-10-29T09:51:53.363364Z[0m [32m INFO[0m [2mnym-api/src/main.rs[0m[2m:[0m[2m41[0m[2m:[0m Starting nym api...
|
||||
Usage: nym-api [OPTIONS] <COMMAND>
|
||||
|
||||
Commands:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,9 +8,6 @@ use nym_contracts_common::truncate_decimal;
|
||||
use nym_mixnet_contract_common::NodeId;
|
||||
use nym_validator_client::client::NymApiClientExt;
|
||||
|
||||
// use deprecated method as hopefully this whole API will be sunset soon-enough...
|
||||
// and we're only getting info for legacy node so the relevant data should still exist
|
||||
#[allow(deprecated)]
|
||||
pub(crate) async fn retrieve_mixnode_econ_stats(
|
||||
client: &ThreadsafeValidatorClient,
|
||||
mix_id: NodeId,
|
||||
|
||||
@@ -17,8 +17,6 @@ pub(crate) struct ExplorerApiTasks {
|
||||
shutdown: TaskClient,
|
||||
}
|
||||
|
||||
// allow usage of deprecated methods here as we actually want to be explicitly querying for legacy data
|
||||
#[allow(deprecated)]
|
||||
impl ExplorerApiTasks {
|
||||
pub(crate) fn new(state: ExplorerApiStateContext, shutdown: TaskClient) -> Self {
|
||||
ExplorerApiTasks { state, shutdown }
|
||||
|
||||
@@ -40,7 +40,6 @@ once_cell = { workspace = true }
|
||||
rand = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json = { workspace = true }
|
||||
sha2 = { workspace = true }
|
||||
si-scale = { workspace = true }
|
||||
subtle-encoding = { workspace = true, features = ["bech32-preview"] }
|
||||
thiserror = { workspace = true }
|
||||
|
||||
@@ -632,7 +632,7 @@ impl<St> Gateway<St> {
|
||||
// TODO: if anything, this should be getting data directly from the contract
|
||||
// as opposed to the validator API
|
||||
let validator_client = self.random_api_client()?;
|
||||
let existing_nodes = match validator_client.get_all_basic_nodes(None).await {
|
||||
let existing_nodes = match validator_client.get_cached_gateways().await {
|
||||
Ok(nodes) => nodes,
|
||||
Err(err) => {
|
||||
error!("failed to grab initial network gateways - {err}\n Please try to startup again in few minutes");
|
||||
@@ -640,9 +640,9 @@ impl<St> Gateway<St> {
|
||||
}
|
||||
};
|
||||
|
||||
Ok(existing_nodes
|
||||
.iter()
|
||||
.any(|node| &node.ed25519_identity_pubkey == self.identity_keypair.public_key()))
|
||||
Ok(existing_nodes.iter().any(|node| {
|
||||
node.gateway.identity_key == self.identity_keypair.public_key().to_base58_string()
|
||||
}))
|
||||
}
|
||||
|
||||
pub async fn run(mut self) -> Result<(), GatewayError>
|
||||
|
||||
@@ -7,7 +7,6 @@ use nym_gateway_stats_storage::PersistentStatsStorage;
|
||||
use nym_gateway_stats_storage::{error::StatsStorageError, models::ActiveSession};
|
||||
use nym_node_http_api::state::metrics::SharedSessionStats;
|
||||
use nym_sphinx::DestinationAddressBytes;
|
||||
use sha2::{Digest, Sha256};
|
||||
use time::{Date, Duration, OffsetDateTime};
|
||||
|
||||
use nym_statistics_common::events::SessionEvent;
|
||||
@@ -115,17 +114,12 @@ impl SessionStatsHandler {
|
||||
//update shared state once a day has passed, with data from the previous day
|
||||
async fn publish_stats(&mut self, stats_date: Date) -> Result<(), StatsStorageError> {
|
||||
let finished_sessions = self.storage.get_finished_sessions(stats_date).await?;
|
||||
let unique_users = self.storage.get_unique_users(stats_date).await?;
|
||||
let unique_users_hash = unique_users
|
||||
.into_iter()
|
||||
.map(|address| format!("{:x}", Sha256::digest(address)))
|
||||
.collect::<Vec<_>>();
|
||||
let user_count = self.storage.get_unique_users_count(stats_date).await?;
|
||||
let session_started = self.storage.get_started_sessions_count(stats_date).await? as u32;
|
||||
{
|
||||
let mut shared_state = self.shared_session_stats.write().await;
|
||||
shared_state.update_time = stats_date;
|
||||
shared_state.unique_active_users_count = unique_users_hash.len() as u32;
|
||||
shared_state.unique_active_users_hashes = unique_users_hash;
|
||||
shared_state.unique_active_users = user_count as u32;
|
||||
shared_state.session_started = session_started;
|
||||
shared_state.sessions = finished_sessions.iter().map(|s| s.serialize()).collect();
|
||||
}
|
||||
|
||||
@@ -234,7 +234,7 @@ impl MixNode {
|
||||
// TODO: if anything, this should be getting data directly from the contract
|
||||
// as opposed to the validator API
|
||||
let validator_client = self.random_api_client();
|
||||
let existing_nodes = match validator_client.get_all_basic_nodes(None).await {
|
||||
let existing_nodes = match validator_client.get_cached_mixnodes().await {
|
||||
Ok(nodes) => nodes,
|
||||
Err(err) => {
|
||||
error!(
|
||||
@@ -245,9 +245,10 @@ impl MixNode {
|
||||
}
|
||||
};
|
||||
|
||||
existing_nodes
|
||||
.iter()
|
||||
.any(|node| &node.ed25519_identity_pubkey == self.identity_keypair.public_key())
|
||||
existing_nodes.iter().any(|node| {
|
||||
node.bond_information.mix_node.identity_key
|
||||
== self.identity_keypair.public_key().to_base58_string()
|
||||
})
|
||||
}
|
||||
|
||||
async fn wait_for_interrupt(&self, shutdown: TaskHandle) {
|
||||
|
||||
@@ -897,12 +897,6 @@ pub enum DescribedNodeType {
|
||||
NymNode,
|
||||
}
|
||||
|
||||
impl DescribedNodeType {
|
||||
pub fn is_nym_node(&self) -> bool {
|
||||
matches!(self, DescribedNodeType::NymNode)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, schemars::JsonSchema, ToSchema)]
|
||||
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
|
||||
#[cfg_attr(
|
||||
|
||||
@@ -7,7 +7,7 @@ use crate::ecash::helpers::blind_sign;
|
||||
use crate::ecash::state::EcashState;
|
||||
use crate::node_status_api::models::AxumResult;
|
||||
use crate::support::http::state::AppState;
|
||||
use axum::extract::Query;
|
||||
use axum::extract::Path;
|
||||
use axum::{Json, Router};
|
||||
use nym_api_requests::ecash::{
|
||||
BlindSignRequestBody, BlindedSignatureResponse, PartialCoinIndicesSignatureResponse,
|
||||
@@ -134,7 +134,7 @@ struct ExpirationDateParam {
|
||||
)
|
||||
)]
|
||||
async fn partial_expiration_date_signatures(
|
||||
Query(ExpirationDateParam { expiration_date }): Query<ExpirationDateParam>,
|
||||
Path(ExpirationDateParam { expiration_date }): Path<ExpirationDateParam>,
|
||||
state: Arc<EcashState>,
|
||||
) -> AxumResult<Json<PartialExpirationDateSignatureResponse>> {
|
||||
state.ensure_signer().await?;
|
||||
@@ -172,7 +172,7 @@ async fn partial_expiration_date_signatures(
|
||||
)
|
||||
)]
|
||||
async fn partial_coin_indices_signatures(
|
||||
Query(EpochIdParam { epoch_id }): Query<EpochIdParam>,
|
||||
Path(EpochIdParam { epoch_id }): Path<EpochIdParam>,
|
||||
state: Arc<EcashState>,
|
||||
) -> AxumResult<Json<PartialCoinIndicesSignatureResponse>> {
|
||||
state.ensure_signer().await?;
|
||||
|
||||
Generated
-5417
File diff suppressed because it is too large
Load Diff
@@ -22,7 +22,7 @@ reqwest = { workspace = true, features = ["json"] }
|
||||
wasm-bindgen = { workspace = true, optional = true }
|
||||
|
||||
## openapi:
|
||||
utoipa = { workspace = true, optional = true, features = ["uuid"] }
|
||||
utoipa = { workspace = true, optional = true }
|
||||
|
||||
nym-credentials = { path = "../../common/credentials" }
|
||||
nym-credentials-interface = { path = "../../common/credentials-interface" }
|
||||
|
||||
@@ -10,7 +10,7 @@ use schemars::schema::Schema;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use time::{Date, OffsetDateTime};
|
||||
use time::Date;
|
||||
|
||||
#[cfg(feature = "query-types")]
|
||||
use nym_http_api_common::Output;
|
||||
@@ -40,7 +40,6 @@ pub struct TicketbookRequest {
|
||||
/// you **MUST** provide a valid value otherwise blacklisting won't work
|
||||
#[schemars(with = "String")]
|
||||
#[serde(with = "bs58_ecash")]
|
||||
#[cfg_attr(feature = "openapi", schema(value_type = String))]
|
||||
pub ecash_pubkey: PublicKeyUser,
|
||||
|
||||
// needs to be explicit in case user creates request at 23:59:59.999, but it reaches vpn-api at 00:00:00.001
|
||||
@@ -49,7 +48,6 @@ pub struct TicketbookRequest {
|
||||
pub expiration_date: Date,
|
||||
|
||||
#[schemars(with = "String")]
|
||||
#[cfg_attr(feature = "openapi", schema(value_type = String))]
|
||||
pub ticketbook_type: TicketType,
|
||||
|
||||
pub is_freepass_request: bool,
|
||||
@@ -236,28 +234,22 @@ pub struct TicketbookWalletSharesAsyncResponse {
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema)]
|
||||
#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WebhookTicketbookWalletShares {
|
||||
pub struct BlindedWalletSharesResponse {
|
||||
pub id: i64,
|
||||
pub status: String,
|
||||
pub device_id: String,
|
||||
pub credential_id: String,
|
||||
pub data: Option<TicketbookWalletSharesResponse>,
|
||||
pub error_message: Option<String>,
|
||||
|
||||
#[schemars(with = "String")]
|
||||
#[serde(with = "time::serde::rfc3339")]
|
||||
pub created: OffsetDateTime,
|
||||
|
||||
#[schemars(with = "String")]
|
||||
#[serde(with = "time::serde::rfc3339")]
|
||||
pub updated: OffsetDateTime,
|
||||
pub created: String,
|
||||
pub updated: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema)]
|
||||
#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WebhookTicketbookWalletSharesRequest {
|
||||
pub ticketbook_wallet_shares: WebhookTicketbookWalletShares,
|
||||
pub struct WebhookBlindedSharesResponse {
|
||||
pub blinded_shares: BlindedWalletSharesResponse,
|
||||
pub secret: String,
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-credential-proxy"
|
||||
version = "0.1.3"
|
||||
version = "0.1.1"
|
||||
authors.workspace = true
|
||||
repository.workspace = true
|
||||
homepage.workspace = true
|
||||
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
* Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
DROP TABLE blinded_shares;
|
||||
CREATE TABLE blinded_shares
|
||||
(
|
||||
id INTEGER NOT NULL PRIMARY KEY,
|
||||
-- removed reference to `ticketbook_deposit` as the deposit wouldn't actually have been made before the pending share is inserted
|
||||
request_uuid TEXT NOT NULL,
|
||||
status TEXT NOT NULL,
|
||||
device_id TEXT NOT NULL,
|
||||
credential_id TEXT NOT NULL,
|
||||
available_shares INTEGER NOT NULL DEFAULT 0,
|
||||
error_message TEXT DEFAULT NULL,
|
||||
created TIMESTAMP WITHOUT TIME ZONE NOT NULL,
|
||||
updated TIMESTAMP WITHOUT TIME ZONE NOT NULL
|
||||
);
|
||||
@@ -3,12 +3,10 @@
|
||||
|
||||
use crate::error::VpnApiError;
|
||||
use crate::http::state::ApiState;
|
||||
use crate::storage::models::BlindedShares;
|
||||
use futures::{stream, StreamExt};
|
||||
use nym_credential_proxy_requests::api::v1::ticketbook::models::{
|
||||
TicketbookAsyncRequest, TicketbookObtainQueryParams, TicketbookRequest,
|
||||
TicketbookWalletSharesResponse, WalletShare, WebhookTicketbookWalletShares,
|
||||
WebhookTicketbookWalletSharesRequest,
|
||||
TicketbookWalletSharesResponse, WalletShare,
|
||||
};
|
||||
use nym_credentials::IssuanceTicketBook;
|
||||
use nym_credentials_interface::Base58;
|
||||
@@ -219,13 +217,11 @@ async fn try_obtain_blinded_ticketbook_async_inner(
|
||||
requested_on: OffsetDateTime,
|
||||
request_data: TicketbookAsyncRequest,
|
||||
params: TicketbookObtainQueryParams,
|
||||
pending: &BlindedShares,
|
||||
) -> Result<(), VpnApiError> {
|
||||
let epoch_id = state.current_epoch_id().await?;
|
||||
|
||||
let device_id = &request_data.device_id;
|
||||
let credential_id = &request_data.credential_id;
|
||||
let secret = request_data.secret.clone();
|
||||
|
||||
// 1. try to obtain global data
|
||||
let (
|
||||
@@ -263,70 +259,19 @@ async fn try_obtain_blinded_ticketbook_async_inner(
|
||||
error!(uuid = %request, "failed to update db with issued information: {err}")
|
||||
}
|
||||
|
||||
// 4. build the webhook request body
|
||||
let data = Some(TicketbookWalletSharesResponse {
|
||||
// 4. build the response
|
||||
let response = TicketbookWalletSharesResponse {
|
||||
epoch_id,
|
||||
shares,
|
||||
master_verification_key,
|
||||
aggregated_coin_index_signatures,
|
||||
aggregated_expiration_date_signatures,
|
||||
});
|
||||
|
||||
let ticketbook_wallet_shares = WebhookTicketbookWalletShares {
|
||||
id: pending.id,
|
||||
status: pending.status.to_string(),
|
||||
device_id: device_id.clone(),
|
||||
credential_id: credential_id.clone(),
|
||||
data,
|
||||
error_message: None,
|
||||
created: pending.created,
|
||||
updated: pending.updated,
|
||||
};
|
||||
|
||||
let webhook_request = WebhookTicketbookWalletSharesRequest {
|
||||
ticketbook_wallet_shares,
|
||||
secret,
|
||||
};
|
||||
|
||||
// 5. call the webhook
|
||||
state
|
||||
.zk_nym_web_hook()
|
||||
.try_trigger(request, &webhook_request)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn try_trigger_webhook_request_for_error(
|
||||
state: &ApiState,
|
||||
request: Uuid,
|
||||
request_data: TicketbookAsyncRequest,
|
||||
pending: &BlindedShares,
|
||||
error_message: String,
|
||||
) -> Result<(), VpnApiError> {
|
||||
let device_id = &request_data.device_id;
|
||||
let credential_id = &request_data.credential_id;
|
||||
let secret = request_data.secret.clone();
|
||||
|
||||
let ticketbook_wallet_shares = WebhookTicketbookWalletShares {
|
||||
id: pending.id,
|
||||
status: "error".to_string(),
|
||||
device_id: device_id.clone(),
|
||||
credential_id: credential_id.clone(),
|
||||
data: None,
|
||||
error_message: Some(error_message),
|
||||
created: pending.created,
|
||||
updated: pending.updated,
|
||||
};
|
||||
|
||||
let webhook_request = WebhookTicketbookWalletSharesRequest {
|
||||
ticketbook_wallet_shares,
|
||||
secret,
|
||||
};
|
||||
|
||||
state
|
||||
.zk_nym_web_hook()
|
||||
.try_trigger(request, &webhook_request)
|
||||
.try_trigger(request, &response)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
@@ -340,30 +285,16 @@ pub(crate) async fn try_obtain_blinded_ticketbook_async(
|
||||
requested_on: OffsetDateTime,
|
||||
request_data: TicketbookAsyncRequest,
|
||||
params: TicketbookObtainQueryParams,
|
||||
pending: BlindedShares,
|
||||
) {
|
||||
if let Err(err) = try_obtain_blinded_ticketbook_async_inner(
|
||||
&state,
|
||||
request,
|
||||
requested_on,
|
||||
request_data.clone(),
|
||||
request_data,
|
||||
params,
|
||||
&pending,
|
||||
)
|
||||
.await
|
||||
{
|
||||
// post to the webhook to notify of errors on this side
|
||||
if let Err(webhook_err) = try_trigger_webhook_request_for_error(
|
||||
&state,
|
||||
request,
|
||||
request_data,
|
||||
&pending,
|
||||
format!("Failed to get ticketbook: {err}"),
|
||||
)
|
||||
.await
|
||||
{
|
||||
error!(uuid = %request, "failed to make webhook request to report error: {webhook_err}")
|
||||
}
|
||||
error!(uuid = %request, "failed to resolve the blinded ticketbook issuance: {err}")
|
||||
} else {
|
||||
info!(uuid = %request, "managed to resolve the blinded ticketbook issuance")
|
||||
|
||||
@@ -84,8 +84,8 @@ pub(crate) struct ApiDoc;
|
||||
api_requests::v1::ticketbook::models::WalletShare,
|
||||
api_requests::v1::ticketbook::models::TicketbookWalletSharesResponse,
|
||||
api_requests::v1::ticketbook::models::TicketbookWalletSharesAsyncResponse,
|
||||
api_requests::v1::ticketbook::models::WebhookTicketbookWalletShares,
|
||||
api_requests::v1::ticketbook::models::WebhookTicketbookWalletSharesRequest,
|
||||
api_requests::v1::ticketbook::models::BlindedWalletSharesResponse,
|
||||
api_requests::v1::ticketbook::models::WebhookBlindedSharesResponse,
|
||||
api_requests::v1::ticketbook::models::TicketbookObtainQueryParams,
|
||||
api_requests::v1::ticketbook::models::SharesQueryParams,
|
||||
api_requests::v1::ticketbook::models::PlaceholderJsonSchemaImpl,
|
||||
|
||||
@@ -192,7 +192,6 @@ pub(crate) async fn obtain_ticketbook_shares_async(
|
||||
}
|
||||
Ok(pending) => pending,
|
||||
};
|
||||
let id = pending.id;
|
||||
|
||||
// 3. try to spawn a new task attempting to resolve the request
|
||||
if state
|
||||
@@ -202,7 +201,6 @@ pub(crate) async fn obtain_ticketbook_shares_async(
|
||||
requested_on,
|
||||
payload,
|
||||
params,
|
||||
pending,
|
||||
))
|
||||
.is_none()
|
||||
{
|
||||
@@ -215,7 +213,10 @@ pub(crate) async fn obtain_ticketbook_shares_async(
|
||||
}
|
||||
|
||||
// 4. in the meantime, return the id to the user
|
||||
Ok(output.to_response(TicketbookWalletSharesAsyncResponse { id, uuid }))
|
||||
Ok(output.to_response(TicketbookWalletSharesAsyncResponse {
|
||||
id: pending.id,
|
||||
uuid,
|
||||
}))
|
||||
}
|
||||
|
||||
/// Obtain the current value of the bandwidth voucher deposit
|
||||
|
||||
+1
-1
@@ -149,7 +149,7 @@ pub(crate) async fn query_for_shares_by_id(
|
||||
(status = 401, description = "authentication token is missing or is invalid"),
|
||||
(status = 500, body = ErrorResponse, description = "failed to query for bandwidth blinded shares"),
|
||||
),
|
||||
params(SharesQueryParams),
|
||||
params(OutputParams),
|
||||
security(
|
||||
("auth_token" = [])
|
||||
)
|
||||
|
||||
@@ -83,11 +83,7 @@ impl SqliteStorageManager {
|
||||
sqlx::query_as!(
|
||||
MinimalWalletShare,
|
||||
r#"
|
||||
SELECT
|
||||
t1.node_id as "node_id!",
|
||||
t1.blinded_signature as "blinded_signature!",
|
||||
t1.epoch_id as "epoch_id!",
|
||||
t1.expiration_date as "expiration_date!: Date"
|
||||
SELECT t1.node_id, t1.blinded_signature, t1.epoch_id, t1.expiration_date as "expiration_date!: Date"
|
||||
FROM partial_blinded_wallet as t1
|
||||
JOIN ticketbook_deposit as t2
|
||||
on t1.corresponding_deposit = t2.deposit_id
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#![allow(deprecated)]
|
||||
|
||||
use crate::db::models::{
|
||||
gateway, mixnode, GatewayRecord, MixnodeRecord, NetworkSummary, GATEWAYS_BLACKLISTED_COUNT,
|
||||
GATEWAYS_BONDED_COUNT, GATEWAYS_EXPLORER_COUNT, GATEWAYS_HISTORICAL_COUNT,
|
||||
|
||||
@@ -159,8 +159,7 @@ type FinishedSessions = Vec<(u64, String)>;
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SessionStatsState {
|
||||
pub update_time: Date,
|
||||
pub unique_active_users_count: u32,
|
||||
pub unique_active_users_hashes: Vec<String>,
|
||||
pub unique_active_users: u32,
|
||||
pub session_started: u32,
|
||||
pub sessions: FinishedSessions,
|
||||
}
|
||||
@@ -175,8 +174,7 @@ impl SessionStatsState {
|
||||
.collect();
|
||||
SessionStats {
|
||||
update_time: self.update_time.with_time(time!(0:00)).assume_utc(),
|
||||
unique_active_users: self.unique_active_users_count,
|
||||
unique_active_users_hashes: self.unique_active_users_hashes.clone(),
|
||||
unique_active_users: self.unique_active_users,
|
||||
sessions,
|
||||
sessions_started: self.session_started,
|
||||
sessions_finished: self.sessions.len() as u32,
|
||||
@@ -188,8 +186,7 @@ impl Default for SessionStatsState {
|
||||
fn default() -> Self {
|
||||
SessionStatsState {
|
||||
update_time: OffsetDateTime::UNIX_EPOCH.date(),
|
||||
unique_active_users_count: 0,
|
||||
unique_active_users_hashes: Default::default(),
|
||||
unique_active_users: 0,
|
||||
session_started: 0,
|
||||
sessions: Default::default(),
|
||||
}
|
||||
|
||||
@@ -50,8 +50,6 @@ pub struct SessionStats {
|
||||
|
||||
pub unique_active_users: u32,
|
||||
|
||||
pub unique_active_users_hashes: Vec<String>,
|
||||
|
||||
pub sessions: Vec<Session>,
|
||||
|
||||
pub sessions_started: u32,
|
||||
|
||||
Generated
+35
-35
@@ -173,7 +173,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -658,7 +658,7 @@ dependencies = [
|
||||
"heck 0.4.1",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1022,7 +1022,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1083,7 +1083,7 @@ checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1751,7 +1751,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1931,7 +1931,7 @@ dependencies = [
|
||||
"proc-macro-error2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3428,6 +3428,7 @@ dependencies = [
|
||||
"flate2",
|
||||
"futures",
|
||||
"itertools 0.13.0",
|
||||
"log",
|
||||
"nym-api-requests",
|
||||
"nym-coconut-bandwidth-contract-common",
|
||||
"nym-coconut-dkg-common",
|
||||
@@ -3451,7 +3452,6 @@ dependencies = [
|
||||
"thiserror",
|
||||
"time",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"url",
|
||||
"wasmtimer",
|
||||
"zeroize",
|
||||
@@ -3667,7 +3667,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3854,7 +3854,7 @@ dependencies = [
|
||||
"pest_meta",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3983,7 +3983,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4140,7 +4140,7 @@ dependencies = [
|
||||
"proc-macro-error-attr2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4151,9 +4151,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.89"
|
||||
version = "1.0.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e"
|
||||
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@@ -4178,7 +4178,7 @@ dependencies = [
|
||||
"itertools 0.11.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4704,7 +4704,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde_derive_internals",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4798,9 +4798,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.214"
|
||||
version = "1.0.210"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5"
|
||||
checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
@@ -4825,13 +4825,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.214"
|
||||
version = "1.0.210"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766"
|
||||
checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4842,14 +4842,14 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.132"
|
||||
version = "1.0.128"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03"
|
||||
checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8"
|
||||
dependencies = [
|
||||
"itoa 1.0.9",
|
||||
"memchr",
|
||||
@@ -4865,7 +4865,7 @@ checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5219,7 +5219,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5262,9 +5262,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.85"
|
||||
version = "2.0.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56"
|
||||
checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -5769,7 +5769,7 @@ checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5856,7 +5856,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6021,7 +6021,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6097,7 +6097,7 @@ checksum = "0ea0b99e8ec44abd6f94a18f28f7934437809dd062820797c52401298116f70e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.55",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
@@ -6201,7 +6201,7 @@ dependencies = [
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6316,7 +6316,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.55",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@@ -6350,7 +6350,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.55",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
@@ -6979,7 +6979,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -115,7 +115,7 @@ fn main() {
|
||||
utils::owns_mixnode,
|
||||
utils::owns_nym_node,
|
||||
utils::get_env,
|
||||
utils::try_convert_pubkey_to_node_id,
|
||||
utils::try_convert_pubkey_to_mix_id,
|
||||
utils::default_mixnode_cost_params,
|
||||
nym_api::status::compute_mixnode_reward_estimation,
|
||||
nym_api::status::gateway_core_node_status,
|
||||
@@ -178,8 +178,8 @@ fn main() {
|
||||
simulate::mixnet::simulate_update_mixnode_config,
|
||||
simulate::mixnet::simulate_update_mixnode_cost_params,
|
||||
simulate::mixnet::simulate_update_gateway_config,
|
||||
simulate::mixnet::simulate_delegate_to_node,
|
||||
simulate::mixnet::simulate_undelegate_from_node,
|
||||
simulate::mixnet::simulate_delegate_to_mixnode,
|
||||
simulate::mixnet::simulate_undelegate_from_mixnode,
|
||||
simulate::vesting::simulate_vesting_delegate_to_mixnode,
|
||||
simulate::vesting::simulate_vesting_undelegate_from_mixnode,
|
||||
simulate::vesting::simulate_vesting_bond_gateway,
|
||||
|
||||
@@ -403,8 +403,6 @@ pub async fn update_gateway_config(
|
||||
)?)
|
||||
}
|
||||
|
||||
// TODO: fix later (yeah...)
|
||||
#[allow(deprecated)]
|
||||
#[tauri::command]
|
||||
pub async fn get_mixnode_avg_uptime(
|
||||
state: tauri::State<'_, WalletState>,
|
||||
@@ -607,8 +605,6 @@ pub async fn get_nym_node_description(
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: fix later (yeah...)
|
||||
#[allow(deprecated)]
|
||||
#[tauri::command]
|
||||
pub async fn get_mixnode_uptime(
|
||||
mix_id: NodeId,
|
||||
|
||||
@@ -141,8 +141,6 @@ pub async fn undelegate_all_from_mixnode(
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
// TODO: fix later (yeah...)
|
||||
#[allow(deprecated)]
|
||||
#[tauri::command]
|
||||
pub async fn get_all_mix_delegations(
|
||||
state: tauri::State<'_, WalletState>,
|
||||
|
||||
@@ -14,8 +14,6 @@ use nym_validator_client::models::{
|
||||
MixnodeStatusResponse, RewardEstimationResponse, StakeSaturationResponse,
|
||||
};
|
||||
|
||||
// TODO: fix later (yeah...)
|
||||
#[allow(deprecated)]
|
||||
#[tauri::command]
|
||||
pub async fn mixnode_core_node_status(
|
||||
mix_id: NodeId,
|
||||
@@ -27,8 +25,6 @@ pub async fn mixnode_core_node_status(
|
||||
.await?)
|
||||
}
|
||||
|
||||
// TODO: fix later (yeah...)
|
||||
#[allow(deprecated)]
|
||||
#[tauri::command]
|
||||
pub async fn gateway_core_node_status(
|
||||
identity: IdentityKeyRef<'_>,
|
||||
@@ -40,8 +36,6 @@ pub async fn gateway_core_node_status(
|
||||
.await?)
|
||||
}
|
||||
|
||||
// TODO: fix later (yeah...)
|
||||
#[allow(deprecated)]
|
||||
#[tauri::command]
|
||||
pub async fn gateway_report(
|
||||
identity: IdentityKeyRef<'_>,
|
||||
@@ -50,8 +44,6 @@ pub async fn gateway_report(
|
||||
Ok(api_client!(state).get_gateway_report(identity).await?)
|
||||
}
|
||||
|
||||
// TODO: fix later (yeah...)
|
||||
#[allow(deprecated)]
|
||||
#[tauri::command]
|
||||
pub async fn mixnode_status(
|
||||
mix_id: NodeId,
|
||||
@@ -60,8 +52,6 @@ pub async fn mixnode_status(
|
||||
Ok(api_client!(state).get_mixnode_status(mix_id).await?)
|
||||
}
|
||||
|
||||
// TODO: fix later (yeah...)
|
||||
#[allow(deprecated)]
|
||||
#[tauri::command]
|
||||
pub async fn mixnode_reward_estimation(
|
||||
mix_id: NodeId,
|
||||
@@ -72,8 +62,6 @@ pub async fn mixnode_reward_estimation(
|
||||
.await?)
|
||||
}
|
||||
|
||||
// TODO: fix later (yeah...)
|
||||
#[allow(deprecated)]
|
||||
#[tauri::command]
|
||||
pub async fn compute_mixnode_reward_estimation(
|
||||
mix_id: u32,
|
||||
@@ -97,8 +85,6 @@ pub async fn compute_mixnode_reward_estimation(
|
||||
.await?)
|
||||
}
|
||||
|
||||
// TODO: fix later (yeah...)
|
||||
#[allow(deprecated)]
|
||||
#[tauri::command]
|
||||
pub async fn mixnode_stake_saturation(
|
||||
mix_id: NodeId,
|
||||
@@ -109,8 +95,6 @@ pub async fn mixnode_stake_saturation(
|
||||
.await?)
|
||||
}
|
||||
|
||||
// TODO: fix later (yeah...)
|
||||
#[allow(deprecated)]
|
||||
#[tauri::command]
|
||||
pub async fn mixnode_inclusion_probability(
|
||||
mix_id: NodeId,
|
||||
|
||||
@@ -116,12 +116,12 @@ pub async fn generate_gateway_bonding_msg_payload(
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn generate_nym_node_bonding_msg_payload(
|
||||
nymnode: NymNode,
|
||||
nym_node: NymNode,
|
||||
cost_params: NodeCostParams,
|
||||
pledge: DecCoin,
|
||||
state: tauri::State<'_, WalletState>,
|
||||
) -> Result<String, BackendError> {
|
||||
nym_node_bonding_msg_payload(nymnode, cost_params, pledge, state).await
|
||||
nym_node_bonding_msg_payload(nym_node, cost_params, pledge, state).await
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
|
||||
@@ -184,7 +184,7 @@ pub async fn simulate_update_gateway_config(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn simulate_delegate_to_node(
|
||||
pub async fn simulate_delegate_to_mixnode(
|
||||
node_id: NodeId,
|
||||
amount: DecCoin,
|
||||
state: tauri::State<'_, WalletState>,
|
||||
@@ -193,7 +193,7 @@ pub async fn simulate_delegate_to_node(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn simulate_undelegate_from_node(
|
||||
pub async fn simulate_undelegate_from_mixnode(
|
||||
node_id: NodeId,
|
||||
state: tauri::State<'_, WalletState>,
|
||||
) -> Result<FeeDetails, BackendError> {
|
||||
|
||||
@@ -55,34 +55,16 @@ pub async fn owns_nym_node(state: tauri::State<'_, WalletState>) -> Result<bool,
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn try_convert_pubkey_to_node_id(
|
||||
pub async fn try_convert_pubkey_to_mix_id(
|
||||
state: tauri::State<'_, WalletState>,
|
||||
mix_identity: IdentityKey,
|
||||
) -> Result<Option<NodeId>, BackendError> {
|
||||
let guard = state.read().await;
|
||||
let client = guard.current_client()?;
|
||||
|
||||
// first try native nym-node
|
||||
if let Some(node) = client
|
||||
.nyxd
|
||||
.get_nymnode_details_by_identity(mix_identity.clone())
|
||||
.await?
|
||||
.details
|
||||
{
|
||||
return Ok(Some(node.node_id()));
|
||||
}
|
||||
|
||||
// fallback to legacy mixnode
|
||||
if let Some(node) = client
|
||||
.nyxd
|
||||
.get_mixnode_details_by_identity(mix_identity.clone())
|
||||
.await?
|
||||
let res = nyxd_client!(state)
|
||||
.get_mixnode_details_by_identity(mix_identity)
|
||||
.await?;
|
||||
Ok(res
|
||||
.mixnode_details
|
||||
{
|
||||
return Ok(Some(node.mix_id()));
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
.map(|mixnode_details| mixnode_details.mix_id()))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
|
||||
@@ -2,15 +2,15 @@ import React, { createContext, useContext, useMemo, useState } from 'react';
|
||||
import { CurrencyDenom } from '@nymproject/types';
|
||||
import { TBondNymNodeArgs, TBondMixNodeArgs } from 'src/types';
|
||||
|
||||
const defaultNymNodeValues: TBondNymNodeArgs['nymnode'] = {
|
||||
identity_key: '',
|
||||
custom_http_port: null,
|
||||
const defaultNymNodeValues: TBondNymNodeArgs['nymNode'] = {
|
||||
identity_key: 'H6rXWgsW89QsVyaNSS3qBe9zZFLhBS6Gn3YRkGFSoFW9',
|
||||
custom_http_port: 1,
|
||||
host: '1.1.1.1',
|
||||
};
|
||||
|
||||
const defaultCostParams = (denom: CurrencyDenom): TBondNymNodeArgs['costParams'] => ({
|
||||
interval_operating_cost: { amount: '40', denom },
|
||||
profit_margin_percent: '40',
|
||||
profit_margin_percent: '10',
|
||||
});
|
||||
|
||||
const defaultAmount = (denom: CurrencyDenom): TBondMixNodeArgs['pledge'] => ({
|
||||
@@ -21,14 +21,14 @@ const defaultAmount = (denom: CurrencyDenom): TBondMixNodeArgs['pledge'] => ({
|
||||
interface FormContextType {
|
||||
step: 1 | 2 | 3 | 4;
|
||||
setStep: React.Dispatch<React.SetStateAction<1 | 2 | 3 | 4>>;
|
||||
nymNodeData: TBondNymNodeArgs['nymnode'];
|
||||
setNymNodeData: React.Dispatch<React.SetStateAction<TBondNymNodeArgs['nymnode']>>;
|
||||
nymNodeData: TBondNymNodeArgs['nymNode'];
|
||||
setNymNodeData: React.Dispatch<React.SetStateAction<TBondNymNodeArgs['nymNode']>>;
|
||||
costParams: TBondNymNodeArgs['costParams'];
|
||||
setCostParams: React.Dispatch<React.SetStateAction<TBondNymNodeArgs['costParams']>>;
|
||||
amountData: TBondMixNodeArgs['pledge'];
|
||||
setAmountData: React.Dispatch<React.SetStateAction<TBondMixNodeArgs['pledge']>>;
|
||||
signature: string;
|
||||
setSignature: React.Dispatch<React.SetStateAction<string>>;
|
||||
signature?: string;
|
||||
setSignature: React.Dispatch<React.SetStateAction<string | undefined>>;
|
||||
onError: (e: string) => void;
|
||||
}
|
||||
|
||||
@@ -41,8 +41,9 @@ const FormContext = createContext<FormContextType>({
|
||||
setCostParams: () => {},
|
||||
amountData: defaultAmount('nym'),
|
||||
setAmountData: () => {},
|
||||
signature: '',
|
||||
signature: undefined,
|
||||
setSignature: () => {},
|
||||
|
||||
onError: () => {},
|
||||
});
|
||||
|
||||
@@ -51,10 +52,10 @@ const FormContextProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
const denom = 'nym';
|
||||
|
||||
const [step, setStep] = useState<1 | 2 | 3 | 4>(1);
|
||||
const [nymNodeData, setNymNodeData] = useState<TBondNymNodeArgs['nymnode']>(defaultNymNodeValues);
|
||||
const [nymNodeData, setNymNodeData] = useState<TBondNymNodeArgs['nymNode']>(defaultNymNodeValues);
|
||||
const [costParams, setCostParams] = useState<TBondNymNodeArgs['costParams']>(defaultCostParams(denom));
|
||||
const [amountData, setAmountData] = useState<TBondNymNodeArgs['pledge']>(defaultAmount(denom));
|
||||
const [signature, setSignature] = useState('');
|
||||
const [signature, setSignature] = useState<string>();
|
||||
|
||||
const onError = (e: string) => {
|
||||
console.error(e);
|
||||
|
||||
@@ -1,12 +1,22 @@
|
||||
import React from 'react';
|
||||
import { Stack, TextField, Box, FormHelperText } from '@mui/material';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { TBondNymNodeArgs } from 'src/types';
|
||||
import { yupResolver } from '@hookform/resolvers/yup';
|
||||
import { SimpleModal } from 'src/components/Modals/SimpleModal';
|
||||
import { CurrencyFormField } from '@nymproject/react/currency/CurrencyFormField';
|
||||
import { checkHasEnoughFunds } from 'src/utils';
|
||||
import { nymNodeAmountSchema } from './amountValidationSchema';
|
||||
import { useFormContext } from './FormContext';
|
||||
|
||||
const defaultNymNodeCostParamValues: TBondNymNodeArgs['costParams'] = {
|
||||
profit_margin_percent: '10',
|
||||
interval_operating_cost: { amount: '40', denom: 'nym' },
|
||||
};
|
||||
|
||||
const defaultNymNodePledgeValue: TBondNymNodeArgs['pledge'] = {
|
||||
amount: '100',
|
||||
denom: 'nym',
|
||||
};
|
||||
|
||||
type NymNodeDataProps = {
|
||||
onClose: () => void;
|
||||
@@ -16,7 +26,6 @@ type NymNodeDataProps = {
|
||||
};
|
||||
|
||||
const NymNodeAmount = ({ onClose, onBack, onNext, step }: NymNodeDataProps) => {
|
||||
const { setAmountData, setCostParams, amountData, costParams } = useFormContext();
|
||||
const {
|
||||
formState: { errors },
|
||||
register,
|
||||
@@ -27,26 +36,21 @@ const NymNodeAmount = ({ onClose, onBack, onNext, step }: NymNodeDataProps) => {
|
||||
} = useForm({
|
||||
mode: 'all',
|
||||
defaultValues: {
|
||||
pledge: amountData,
|
||||
...costParams,
|
||||
pledge: defaultNymNodePledgeValue,
|
||||
...defaultNymNodeCostParamValues,
|
||||
},
|
||||
resolver: yupResolver(nymNodeAmountSchema()),
|
||||
});
|
||||
|
||||
console.log(errors, 'errors');
|
||||
|
||||
const handleRequestValidation = async () => {
|
||||
const values = getValues();
|
||||
|
||||
const hasSufficientTokens = await checkHasEnoughFunds(values.pledge.amount);
|
||||
|
||||
if (hasSufficientTokens) {
|
||||
handleSubmit((args) => {
|
||||
setAmountData(args.pledge);
|
||||
setCostParams({
|
||||
profit_margin_percent: args.profit_margin_percent,
|
||||
interval_operating_cost: args.interval_operating_cost,
|
||||
});
|
||||
onNext();
|
||||
})();
|
||||
handleSubmit(onNext)();
|
||||
} else {
|
||||
setError('pledge.amount', { message: 'Not enough tokens' });
|
||||
}
|
||||
@@ -73,8 +77,8 @@ const NymNodeAmount = ({ onClose, onBack, onNext, step }: NymNodeDataProps) => {
|
||||
setValue('pledge.amount', newValue.amount, { shouldValidate: true });
|
||||
}}
|
||||
validationError={errors.pledge?.amount?.message}
|
||||
denom={amountData.denom}
|
||||
initialValue={amountData.amount}
|
||||
denom={defaultNymNodePledgeValue.denom}
|
||||
initialValue={defaultNymNodePledgeValue.amount}
|
||||
/>
|
||||
|
||||
<Box>
|
||||
@@ -86,8 +90,8 @@ const NymNodeAmount = ({ onClose, onBack, onNext, step }: NymNodeDataProps) => {
|
||||
setValue('interval_operating_cost', newValue, { shouldValidate: true });
|
||||
}}
|
||||
validationError={errors.interval_operating_cost?.amount?.message}
|
||||
denom={costParams.interval_operating_cost.denom}
|
||||
initialValue={costParams.interval_operating_cost.amount}
|
||||
denom={defaultNymNodeCostParamValues.interval_operating_cost.denom}
|
||||
initialValue={defaultNymNodeCostParamValues.interval_operating_cost.amount}
|
||||
/>
|
||||
<FormHelperText>
|
||||
Monthly operational costs of running your node. If your node is in the active set the amount will be paid
|
||||
|
||||
@@ -1,12 +1,32 @@
|
||||
import React from 'react';
|
||||
import * as Yup from 'yup';
|
||||
import { Stack, TextField, FormControlLabel, Checkbox } from '@mui/material';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { IdentityKeyFormField } from '@nymproject/react/mixnodes/IdentityKeyFormField';
|
||||
import { TBondNymNodeArgs } from 'src/types';
|
||||
import { yupResolver } from '@hookform/resolvers/yup';
|
||||
import * as yup from 'yup';
|
||||
import { isValidHostname, validateRawPort } from 'src/utils';
|
||||
import { SimpleModal } from 'src/components/Modals/SimpleModal';
|
||||
import { useFormContext } from './FormContext';
|
||||
import { settingsValidationSchema } from './settingsValidationSchema';
|
||||
|
||||
const defaultNymNodeValues: TBondNymNodeArgs['nymNode'] = {
|
||||
identity_key: 'H6rXWgsW89QsVyaNSS3qBe9zZFLhBS6Gn3YRkGFSoFW9',
|
||||
custom_http_port: 1,
|
||||
host: '1.1.1.1',
|
||||
};
|
||||
|
||||
const yupValidationSchema = yup.object().shape({
|
||||
identity_key: yup.string().required('Identity key is required'),
|
||||
host: yup
|
||||
.string()
|
||||
.required('A host is required')
|
||||
.test('no-whitespace', 'Host cannot contain whitespace', (value) => !/\s/.test(value || ''))
|
||||
.test('valid-host', 'A valid host is required', (value) => (value ? isValidHostname(value) : false)),
|
||||
|
||||
custom_http_port: yup
|
||||
.number()
|
||||
.required('A custom http port is required')
|
||||
.test('valid-http', 'A valid http port is required', (value) => (value ? validateRawPort(value) : false)),
|
||||
});
|
||||
|
||||
type NymNodeDataProps = {
|
||||
onClose: () => void;
|
||||
@@ -15,13 +35,7 @@ type NymNodeDataProps = {
|
||||
step: number;
|
||||
};
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
identity_key: Yup.string().required('Identity key is required'),
|
||||
...settingsValidationSchema.fields,
|
||||
});
|
||||
|
||||
const NymNodeData = ({ onClose, onNext, step }: NymNodeDataProps) => {
|
||||
const { setNymNodeData, nymNodeData } = useFormContext();
|
||||
const {
|
||||
formState: { errors },
|
||||
register,
|
||||
@@ -29,17 +43,14 @@ const NymNodeData = ({ onClose, onNext, step }: NymNodeDataProps) => {
|
||||
handleSubmit,
|
||||
} = useForm({
|
||||
mode: 'all',
|
||||
defaultValues: nymNodeData,
|
||||
resolver: yupResolver(validationSchema),
|
||||
defaultValues: defaultNymNodeValues,
|
||||
resolver: yupResolver(yupValidationSchema),
|
||||
});
|
||||
|
||||
const [showAdvancedOptions, setShowAdvancedOptions] = React.useState(false);
|
||||
|
||||
const handleNext = async () => {
|
||||
handleSubmit((args) => {
|
||||
setNymNodeData(args);
|
||||
onNext();
|
||||
})();
|
||||
handleSubmit(onNext)();
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -58,7 +69,7 @@ const NymNodeData = ({ onClose, onNext, step }: NymNodeDataProps) => {
|
||||
required
|
||||
fullWidth
|
||||
label="Identity Key"
|
||||
initialValue={nymNodeData.identity_key}
|
||||
initialValue={defaultNymNodeValues.identity_key}
|
||||
errorText={errors.identity_key?.message?.toString()}
|
||||
onChanged={(value) => setValue('identity_key', value, { shouldValidate: true })}
|
||||
showTickOnValid={false}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import * as yup from 'yup';
|
||||
import { Stack, TextField, Typography } from '@mui/material';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { CopyToClipboard } from 'src/components/CopyToClipboard';
|
||||
@@ -8,11 +7,9 @@ import { SimpleModal } from 'src/components/Modals/SimpleModal';
|
||||
import { useBondingContext } from 'src/context';
|
||||
import { TBondNymNodeArgs } from 'src/types';
|
||||
import { Signature } from 'src/pages/bonding/types';
|
||||
import { yupResolver } from '@hookform/resolvers/yup';
|
||||
import { useFormContext } from './FormContext';
|
||||
|
||||
const NymNodeSignature = ({
|
||||
nymnode,
|
||||
nymNode,
|
||||
pledge,
|
||||
costParams,
|
||||
step,
|
||||
@@ -20,38 +17,27 @@ const NymNodeSignature = ({
|
||||
onClose,
|
||||
onBack,
|
||||
}: {
|
||||
nymnode: TBondNymNodeArgs['nymnode'];
|
||||
nymNode: TBondNymNodeArgs['nymNode'];
|
||||
pledge: TBondNymNodeArgs['pledge'];
|
||||
costParams: TBondNymNodeArgs['costParams'];
|
||||
step: number;
|
||||
onNext: () => void;
|
||||
onNext: (data: Signature) => void;
|
||||
onClose: () => void;
|
||||
onBack: () => void;
|
||||
}) => {
|
||||
const [message, setMessage] = useState<string>('');
|
||||
const [error, setError] = useState<string>();
|
||||
const { generateNymNodeMsgPayload } = useBondingContext();
|
||||
const { signature, setSignature } = useFormContext();
|
||||
|
||||
const yupValidationSchema = yup.object().shape({
|
||||
signature: yup.string().required('Signature is required'),
|
||||
});
|
||||
|
||||
const {
|
||||
register,
|
||||
formState: { errors },
|
||||
handleSubmit,
|
||||
} = useForm<Signature>({
|
||||
defaultValues: {
|
||||
signature,
|
||||
},
|
||||
resolver: yupResolver(yupValidationSchema),
|
||||
});
|
||||
} = useForm<Signature>();
|
||||
|
||||
const generateMessage = async () => {
|
||||
try {
|
||||
const msg = await generateNymNodeMsgPayload({
|
||||
nymnode,
|
||||
nymNode,
|
||||
pledge,
|
||||
costParams,
|
||||
});
|
||||
@@ -67,10 +53,10 @@ const NymNodeSignature = ({
|
||||
|
||||
useEffect(() => {
|
||||
generateMessage();
|
||||
}, []);
|
||||
}, [nymNode, pledge, costParams]);
|
||||
|
||||
const handleNext = async () => {
|
||||
handleSubmit(onNext)();
|
||||
const onSubmit = async (data: Signature) => {
|
||||
onNext(data);
|
||||
};
|
||||
|
||||
if (error) {
|
||||
@@ -80,7 +66,11 @@ const NymNodeSignature = ({
|
||||
return (
|
||||
<SimpleModal
|
||||
open
|
||||
onOk={handleNext}
|
||||
onOk={() =>
|
||||
onSubmit({
|
||||
signature: 'signature',
|
||||
})
|
||||
}
|
||||
onClose={onClose}
|
||||
header="Bond Nym Node"
|
||||
subHeader={`Step ${step}/3`}
|
||||
@@ -105,13 +95,10 @@ const NymNodeSignature = ({
|
||||
</Stack>
|
||||
<TextField
|
||||
{...register('signature')}
|
||||
onChange={(e) => setSignature(e.target.value)}
|
||||
id="outlined-multiline-static"
|
||||
name="signature"
|
||||
rows={3}
|
||||
placeholder="Paste Signature"
|
||||
helperText={errors.signature?.message}
|
||||
error={Boolean(errors.signature)}
|
||||
multiline
|
||||
fullWidth
|
||||
required
|
||||
|
||||
@@ -5,8 +5,8 @@ import { isLessThan, isGreaterThan, validateAmount } from 'src/utils';
|
||||
const operatingCostAndPmValidation = (params?: TauriContractStateParams) => {
|
||||
const defaultParams = {
|
||||
profit_margin_percent: {
|
||||
minimum: parseFloat(params?.profit_margin.minimum || '20%'),
|
||||
maximum: parseFloat(params?.profit_margin.maximum || '50%'),
|
||||
minimum: parseFloat(params?.profit_margin.minimum || '0%'),
|
||||
maximum: parseFloat(params?.profit_margin.maximum || '100%'),
|
||||
},
|
||||
|
||||
interval_operating_cost: {
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
import { isValidHostname, validateRawPort } from 'src/utils';
|
||||
import * as Yup from 'yup';
|
||||
|
||||
const settingsValidationSchema = Yup.object().shape({
|
||||
host: Yup.string()
|
||||
.required('A host is required')
|
||||
.test('no-whitespace', 'Host cannot contain whitespace', (value) => !/\s/.test(value || ''))
|
||||
.test('valid-host', 'A valid host is required', (value) => (value ? isValidHostname(value) : false)),
|
||||
|
||||
custom_http_port: Yup.number()
|
||||
.nullable()
|
||||
.transform((numberVal, stringVal) => {
|
||||
if (stringVal === '') {
|
||||
return null;
|
||||
}
|
||||
if (!Number(stringVal)) {
|
||||
return stringVal;
|
||||
}
|
||||
return numberVal;
|
||||
})
|
||||
.test('valid-http', 'A valid http port is required', (value) => {
|
||||
if (value === null) {
|
||||
return true;
|
||||
}
|
||||
return value ? validateRawPort(value) : false;
|
||||
}),
|
||||
});
|
||||
|
||||
export { settingsValidationSchema };
|
||||
@@ -2,24 +2,18 @@ import React, { useContext, useEffect } from 'react';
|
||||
import { ConfirmTx } from 'src/components/ConfirmTX';
|
||||
import { ModalListItem } from 'src/components/Modals/ModalListItem';
|
||||
import { useGetFee } from 'src/hooks/useGetFee';
|
||||
import { Signature } from 'src/pages/bonding/types';
|
||||
import { BalanceWarning } from 'src/components/FeeWarning';
|
||||
import { AppContext } from 'src/context';
|
||||
import { TBondNymNodeArgs } from 'src/types';
|
||||
import FormContextProvider, { useFormContext } from '../forms/nym-node/FormContext';
|
||||
import NymNodeData from '../forms/nym-node/NymNodeData';
|
||||
import NymNodeAmount from '../forms/nym-node/NymNodeAmount';
|
||||
import NymNodeSignature from '../forms/nym-node/NymNodeSignature';
|
||||
|
||||
export const BondNymNodeModal = ({
|
||||
onClose,
|
||||
onBond,
|
||||
}: {
|
||||
onClose: () => void;
|
||||
onBond: (data: TBondNymNodeArgs) => Promise<void>;
|
||||
}) => {
|
||||
export const BondNymNodeModal = ({ onClose }: { onClose: () => void }) => {
|
||||
const { fee, resetFeeState, feeError } = useGetFee();
|
||||
const { userBalance } = useContext(AppContext);
|
||||
const { setStep, step, onError, signature, amountData, costParams, nymNodeData } = useFormContext();
|
||||
const { setStep, step, onError, setSignature, amountData, costParams, nymNodeData } = useFormContext();
|
||||
|
||||
useEffect(() => {
|
||||
if (feeError) {
|
||||
@@ -27,17 +21,12 @@ export const BondNymNodeModal = ({
|
||||
}
|
||||
}, [feeError]);
|
||||
|
||||
const handleUpdateNymnodeData = async () => {
|
||||
const handleUpdateMixnodeData = async () => {
|
||||
setStep(2);
|
||||
};
|
||||
|
||||
const handleBond = async () => {
|
||||
onBond({
|
||||
nymnode: nymNodeData,
|
||||
pledge: amountData,
|
||||
costParams,
|
||||
msgSignature: signature,
|
||||
});
|
||||
const handleUpdateSignature = async (data: Signature) => {
|
||||
setSignature(data.signature);
|
||||
};
|
||||
|
||||
const handleConfirm = async () => {};
|
||||
@@ -62,7 +51,7 @@ export const BondNymNodeModal = ({
|
||||
}
|
||||
|
||||
if (step === 1) {
|
||||
return <NymNodeData onClose={onClose} onBack={onClose} onNext={handleUpdateNymnodeData} step={step} />;
|
||||
return <NymNodeData onClose={onClose} onBack={onClose} onNext={handleUpdateMixnodeData} step={step} />;
|
||||
}
|
||||
|
||||
if (step === 2) {
|
||||
@@ -72,10 +61,10 @@ export const BondNymNodeModal = ({
|
||||
if (step === 3) {
|
||||
return (
|
||||
<NymNodeSignature
|
||||
nymnode={nymNodeData}
|
||||
nymNode={nymNodeData}
|
||||
pledge={amountData}
|
||||
costParams={costParams}
|
||||
onNext={handleBond}
|
||||
onNext={handleUpdateSignature}
|
||||
onClose={onClose}
|
||||
onBack={() => setStep(2)}
|
||||
step={step}
|
||||
@@ -86,22 +75,14 @@ export const BondNymNodeModal = ({
|
||||
return null;
|
||||
};
|
||||
|
||||
export const BondNymNode = ({
|
||||
open,
|
||||
onClose,
|
||||
onBond,
|
||||
}: {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
onBond: (data: TBondNymNodeArgs) => Promise<void>;
|
||||
}) => {
|
||||
export const BondNymNodeModalWithState = ({ open, onClose }: { open: boolean; onClose: () => void }) => {
|
||||
if (!open) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<FormContextProvider>
|
||||
<BondNymNodeModal onClose={onClose} onBond={onBond} />
|
||||
<BondNymNodeModal onClose={onClose} />
|
||||
</FormContextProvider>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import * as React from 'react';
|
||||
import { useEffect } from 'react';
|
||||
import { Typography } from '@mui/material';
|
||||
import { TBondedNode } from 'src/context';
|
||||
import { useGetFee } from 'src/hooks/useGetFee';
|
||||
import { isGateway, isMixnode } from 'src/types';
|
||||
import { TBondedGateway } from 'src/requests/gatewayDetails';
|
||||
import { TBondedMixnode } from 'src/requests/mixnodeDetails';
|
||||
import { ModalFee } from '../../Modals/ModalFee';
|
||||
import { ModalListItem } from '../../Modals/ModalListItem';
|
||||
import { SimpleModal } from '../../Modals/SimpleModal';
|
||||
@@ -15,7 +16,7 @@ import {
|
||||
} from '../../../requests';
|
||||
|
||||
interface Props {
|
||||
node: TBondedNode;
|
||||
node: TBondedMixnode | TBondedGateway;
|
||||
onConfirm: () => Promise<void>;
|
||||
onClose: () => void;
|
||||
onError: (e: string) => void;
|
||||
|
||||
@@ -5,7 +5,7 @@ import { CurrencyFormField } from '@nymproject/react/currency/CurrencyFormField'
|
||||
import { CurrencyDenom, FeeDetails, DecCoin, decimalToFloatApproximation } from '@nymproject/types';
|
||||
import { Console } from 'src/utils/console';
|
||||
import { useGetFee } from 'src/hooks/useGetFee';
|
||||
import { simulateDelegateToNode, simulateVestingDelegateToMixnode, tryConvertIdentityToNodeId } from 'src/requests';
|
||||
import { simulateDelegateToMixnode, simulateVestingDelegateToMixnode, tryConvertIdentityToMixId } from 'src/requests';
|
||||
import { debounce } from 'lodash';
|
||||
import { AppContext } from 'src/context';
|
||||
import { SimpleModal } from '../Modals/SimpleModal';
|
||||
@@ -152,7 +152,7 @@ export const DelegateModal: FCWithChildren<{
|
||||
}
|
||||
|
||||
if (tokenPool === 'balance') {
|
||||
getFee(simulateDelegateToNode, { nodeId: id, amount: value });
|
||||
getFee(simulateDelegateToMixnode, { mixId: id, amount: value });
|
||||
}
|
||||
|
||||
if (tokenPool === 'locked') {
|
||||
@@ -187,16 +187,16 @@ export const DelegateModal: FCWithChildren<{
|
||||
}
|
||||
let res;
|
||||
try {
|
||||
res = await tryConvertIdentityToNodeId(idKey);
|
||||
res = await tryConvertIdentityToMixId(idKey);
|
||||
} catch (e) {
|
||||
Console.warn(`failed to resolve node_id for "${idKey}": ${e}`);
|
||||
Console.warn(`failed to resolve mix_id for "${idKey}": ${e}`);
|
||||
return;
|
||||
}
|
||||
if (res) {
|
||||
setMixId(res);
|
||||
setMixIdError(undefined);
|
||||
} else {
|
||||
setMixIdError('Node with this identity does not seem to be currently bonded');
|
||||
setMixIdError('Mixnode with this identity does not seem to be currently bonded');
|
||||
}
|
||||
}, 500),
|
||||
[],
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { useContext, useEffect } from 'react';
|
||||
import { Box, SxProps } from '@mui/material';
|
||||
import { FeeDetails } from '@nymproject/types';
|
||||
import { useGetFee } from 'src/hooks/useGetFee';
|
||||
import { simulateUndelegateFromNode, simulateVestingUndelegateFromMixnode } from 'src/requests';
|
||||
import { simulateUndelegateFromMixnode, simulateVestingUndelegateFromMixnode } from 'src/requests';
|
||||
import { AppContext } from 'src/context';
|
||||
import { ModalFee } from '../Modals/ModalFee';
|
||||
import { ModalListItem } from '../Modals/ModalListItem';
|
||||
@@ -27,7 +27,7 @@ export const UndelegateModal: FCWithChildren<{
|
||||
useEffect(() => {
|
||||
if (usesVestingContractTokens) getFee(simulateVestingUndelegateFromMixnode, { mixId });
|
||||
else {
|
||||
getFee(simulateUndelegateFromNode, mixId);
|
||||
getFee(simulateUndelegateFromMixnode, mixId);
|
||||
}
|
||||
}, []);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
|
||||
import { FeeDetails, NodeConfigUpdate, TransactionExecuteResult } from '@nymproject/types';
|
||||
import { isGateway, isMixnode, TUpdateBondArgs, isNymNode, TNymNodeSignatureArgs, TBondNymNodeArgs } from 'src/types';
|
||||
import { FeeDetails, TransactionExecuteResult } from '@nymproject/types';
|
||||
import { isGateway, isMixnode, TUpdateBondArgs, isNymNode, TNymNodeSignatureArgs } from 'src/types';
|
||||
import { Console } from 'src/utils/console';
|
||||
import useGetNodeDetails from 'src/hooks/useGetNodeDetails';
|
||||
import { TBondedNymNode } from 'src/requests/nymNodeDetails';
|
||||
@@ -20,8 +20,6 @@ import {
|
||||
migrateVestedMixnode as tauriMigrateVestedMixnode,
|
||||
migrateLegacyMixnode as migrateLegacyMixnodeReq,
|
||||
migrateLegacyGateway as migrateLegacyGatewayReq,
|
||||
bondNymNode,
|
||||
updateNymNodeConfig as updateNymNodeConfigReq,
|
||||
} from '../requests';
|
||||
|
||||
export type TBondedNode = TBondedMixnode | TBondedGateway | TBondedNymNode;
|
||||
@@ -33,9 +31,7 @@ export type TBondingContext = {
|
||||
isVestingAccount: boolean;
|
||||
refresh: () => void;
|
||||
unbond: (fee?: FeeDetails) => Promise<TransactionExecuteResult | undefined>;
|
||||
bond: (args: TBondNymNodeArgs) => Promise<TransactionExecuteResult | undefined>;
|
||||
updateBondAmount: (data: TUpdateBondArgs) => Promise<TransactionExecuteResult | undefined>;
|
||||
updateNymNodeConfig: (data: NodeConfigUpdate) => Promise<TransactionExecuteResult | undefined>;
|
||||
redeemRewards: (fee?: FeeDetails) => Promise<TransactionExecuteResult | undefined>;
|
||||
generateNymNodeMsgPayload: (data: TNymNodeSignatureArgs) => Promise<string | undefined>;
|
||||
migrateVestedMixnode: () => Promise<TransactionExecuteResult | undefined>;
|
||||
@@ -45,18 +41,12 @@ export type TBondingContext = {
|
||||
export const BondingContext = createContext<TBondingContext>({
|
||||
isLoading: true,
|
||||
refresh: async () => undefined,
|
||||
bond: async () => {
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
unbond: async () => {
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
updateBondAmount: async () => {
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
updateNymNodeConfig: async () => {
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
redeemRewards: async () => {
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
@@ -80,11 +70,7 @@ export const BondingContextProvider: FCWithChildren = ({ children }): JSX.Elemen
|
||||
|
||||
const { userBalance, clientDetails, network } = useContext(AppContext);
|
||||
|
||||
const {
|
||||
bondedNode,
|
||||
isLoading: isBondedNodeLoading,
|
||||
getNodeDetails,
|
||||
} = useGetNodeDetails(clientDetails?.client_address, network);
|
||||
const { bondedNode, isLoading: isBondedNodeLoading } = useGetNodeDetails(clientDetails?.client_address, network);
|
||||
|
||||
useEffect(() => {
|
||||
userBalance.fetchBalance();
|
||||
@@ -105,30 +91,6 @@ export const BondingContextProvider: FCWithChildren = ({ children }): JSX.Elemen
|
||||
resetState();
|
||||
};
|
||||
|
||||
const bond = async (data: TBondNymNodeArgs) => {
|
||||
let tx;
|
||||
setIsLoading(true);
|
||||
|
||||
try {
|
||||
tx = await bondNymNode({
|
||||
...data,
|
||||
costParams: {
|
||||
...data.costParams,
|
||||
profit_margin_percent: toPercentFloatString(data.costParams.profit_margin_percent),
|
||||
},
|
||||
});
|
||||
if (clientDetails?.client_address) {
|
||||
await getNodeDetails(clientDetails?.client_address);
|
||||
}
|
||||
} catch (e) {
|
||||
Console.warn(e);
|
||||
setError(`an error occurred: ${e as string}`);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
return tx;
|
||||
};
|
||||
|
||||
const unbond = async (fee?: FeeDetails) => {
|
||||
let tx;
|
||||
setIsLoading(true);
|
||||
@@ -145,23 +107,6 @@ export const BondingContextProvider: FCWithChildren = ({ children }): JSX.Elemen
|
||||
return tx;
|
||||
};
|
||||
|
||||
const updateNymNodeConfig = async (data: NodeConfigUpdate) => {
|
||||
let tx;
|
||||
setIsLoading(true);
|
||||
try {
|
||||
tx = await updateNymNodeConfigReq(data);
|
||||
if (clientDetails?.client_address) {
|
||||
await getNodeDetails(clientDetails?.client_address);
|
||||
}
|
||||
} catch (e) {
|
||||
Console.warn(e);
|
||||
setError(`an error occurred: ${e}`);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
return tx;
|
||||
};
|
||||
|
||||
const redeemRewards = async (fee?: FeeDetails) => {
|
||||
let tx;
|
||||
setIsLoading(true);
|
||||
@@ -198,7 +143,7 @@ export const BondingContextProvider: FCWithChildren = ({ children }): JSX.Elemen
|
||||
|
||||
try {
|
||||
const message = await generateNymNodeMsgPayloadReq({
|
||||
nymnode: data.nymnode,
|
||||
nymNode: data.nymNode,
|
||||
pledge: data.pledge,
|
||||
costParams: {
|
||||
...data.costParams,
|
||||
@@ -242,12 +187,10 @@ export const BondingContextProvider: FCWithChildren = ({ children }): JSX.Elemen
|
||||
isLoading: isLoading || isBondedNodeLoading,
|
||||
error,
|
||||
bondedNode,
|
||||
bond,
|
||||
unbond,
|
||||
refresh,
|
||||
redeemRewards,
|
||||
updateBondAmount,
|
||||
updateNymNodeConfig,
|
||||
generateNymNodeMsgPayload,
|
||||
migrateVestedMixnode,
|
||||
migrateLegacyNode,
|
||||
|
||||
@@ -133,14 +133,6 @@ export const MockBondingContextProvider = ({
|
||||
return TxResultMock;
|
||||
};
|
||||
|
||||
const bond = async (): Promise<TransactionExecuteResult> => {
|
||||
setIsLoading(true);
|
||||
await mockSleep(SLEEP_MS);
|
||||
setBondedData(bondedMixnodeMock);
|
||||
setIsLoading(false);
|
||||
return TxResultMock;
|
||||
};
|
||||
|
||||
const unbond = async (): Promise<TransactionExecuteResult> => {
|
||||
setIsLoading(true);
|
||||
await mockSleep(SLEEP_MS);
|
||||
@@ -149,14 +141,6 @@ export const MockBondingContextProvider = ({
|
||||
return TxResultMock;
|
||||
};
|
||||
|
||||
const updateNymNodeConfig = async (): Promise<TransactionExecuteResult> => {
|
||||
setIsLoading(true);
|
||||
await mockSleep(SLEEP_MS);
|
||||
triggerStateUpdate();
|
||||
setIsLoading(false);
|
||||
return TxResultMock;
|
||||
};
|
||||
|
||||
const redeemRewards = async (): Promise<TransactionExecuteResult | undefined> => {
|
||||
setIsLoading(true);
|
||||
await mockSleep(SLEEP_MS);
|
||||
@@ -205,7 +189,6 @@ export const MockBondingContextProvider = ({
|
||||
error,
|
||||
bondMixnode,
|
||||
bondGateway,
|
||||
bond,
|
||||
unbond,
|
||||
refresh,
|
||||
redeemRewards,
|
||||
@@ -220,7 +203,6 @@ export const MockBondingContextProvider = ({
|
||||
isVestingAccount: false,
|
||||
migrateVestedMixnode: async () => undefined,
|
||||
migrateLegacyNode: async () => undefined,
|
||||
updateNymNodeConfig,
|
||||
}),
|
||||
[isLoading, error, bondedMixnode, bondedGateway, trigger, fee],
|
||||
);
|
||||
|
||||
@@ -63,7 +63,6 @@ const useGetNodeDetails = (clientAddress?: string, network?: string) => {
|
||||
bondedNode,
|
||||
isLoading,
|
||||
isError,
|
||||
getNodeDetails,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -11,14 +11,14 @@ import { ConfirmationDetailProps, ConfirmationDetailsModal } from 'src/component
|
||||
import { ErrorModal } from 'src/components/Modals/ErrorModal';
|
||||
import { LoadingModal } from 'src/components/Modals/LoadingModal';
|
||||
import { AppContext, urls } from 'src/context/main';
|
||||
import { isGateway, isMixnode, isNymNode, TBondNymNodeArgs, TUpdateBondArgs } from 'src/types';
|
||||
import { isGateway, isMixnode, isNymNode, TUpdateBondArgs } from 'src/types';
|
||||
import { BondedGateway } from 'src/components/Bonding/BondedGateway';
|
||||
import { RedeemRewardsModal } from 'src/components/Bonding/modals/RedeemRewardsModal';
|
||||
import { VestingWarningModal } from 'src/components/VestingWarningModal';
|
||||
import MigrateLegacyNode from 'src/components/Bonding/modals/MigrateLegacyNode';
|
||||
import { BondedNymNode } from 'src/components/Bonding/BondedNymNode';
|
||||
import { UpdateBondAmountNymNode } from 'src/components/Bonding/modals/UpdateBondAmountNymNode';
|
||||
import { BondNymNode } from 'src/components/Bonding/modals/BondNymNodeModal';
|
||||
import { BondNymNodeModalWithState } from 'src/components/Bonding/modals/BondNymNodeModal';
|
||||
import { BondingContextProvider, useBondingContext } from '../../context';
|
||||
|
||||
export const Bonding = () => {
|
||||
@@ -44,7 +44,6 @@ export const Bonding = () => {
|
||||
redeemRewards,
|
||||
updateBondAmount,
|
||||
refresh,
|
||||
bond,
|
||||
migrateVestedMixnode,
|
||||
migrateLegacyNode,
|
||||
} = useBondingContext();
|
||||
@@ -75,18 +74,6 @@ export const Bonding = () => {
|
||||
setShowMigrateLegacyNodeModal(shouldShowMigrateLegacyNodeModal());
|
||||
}, [bondedNode]);
|
||||
|
||||
const handleBondNymNode = async (data: TBondNymNodeArgs) => {
|
||||
setShowModal(undefined);
|
||||
const tx = await bond(data);
|
||||
if (tx) {
|
||||
setConfirmationDetails({
|
||||
status: 'success',
|
||||
title: 'Bonding successful',
|
||||
txUrl: `${urls(network).blockExplorer}/transaction/${tx?.transaction_hash}`,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleMigrateVestedMixnode = async () => {
|
||||
setShowMigrationModal(false);
|
||||
const tx = await migrateVestedMixnode();
|
||||
@@ -263,7 +250,7 @@ export const Bonding = () => {
|
||||
/>
|
||||
)}
|
||||
|
||||
<BondNymNode open={showModal === 'bond-nymnode'} onClose={handleCloseModal} onBond={handleBondNymNode} />
|
||||
<BondNymNodeModalWithState open={showModal === 'bond-nymnode'} onClose={handleCloseModal} />
|
||||
|
||||
{showModal === 'update-bond-oversaturated' && uncappedSaturation && (
|
||||
<BondOversaturatedModal
|
||||
|
||||
@@ -7,6 +7,7 @@ import { isMixnode, isNymNode } from 'src/types';
|
||||
|
||||
interface Props {
|
||||
bondedNode: TBondedNode;
|
||||
|
||||
onConfirm: () => Promise<void>;
|
||||
onError: (e: string) => void;
|
||||
}
|
||||
@@ -70,7 +71,7 @@ export const NodeUnbondPage = ({ bondedNode, onConfirm, onError }: Props) => {
|
||||
</Stack>
|
||||
</Grid>
|
||||
</Grid>
|
||||
{isConfirmed && (
|
||||
{isConfirmed && !isNymNode(bondedNode) && (
|
||||
<UnbondModal
|
||||
node={bondedNode}
|
||||
onConfirm={async () => {
|
||||
|
||||
+24
-22
@@ -3,21 +3,22 @@ import { useForm } from 'react-hook-form';
|
||||
import { yupResolver } from '@hookform/resolvers/yup';
|
||||
import { Box, Button, Divider, Grid, Stack, TextField, Typography } from '@mui/material';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import { updateNymNodeConfig } from 'src/requests';
|
||||
import { SimpleModal } from 'src/components/Modals/SimpleModal';
|
||||
import { bondedInfoParametersValidationSchema } from 'src/components/Bonding/forms/legacyForms/mixnodeValidationSchema';
|
||||
import { Console } from 'src/utils/console';
|
||||
import { Alert } from 'src/components/Alert';
|
||||
import { ConfirmTx } from 'src/components/ConfirmTX';
|
||||
import { useGetFee } from 'src/hooks/useGetFee';
|
||||
import { LoadingModal } from 'src/components/Modals/LoadingModal';
|
||||
import { BalanceWarning } from 'src/components/FeeWarning';
|
||||
import { AppContext, useBondingContext } from 'src/context';
|
||||
import { AppContext } from 'src/context';
|
||||
import { TBondedNymNode } from 'src/requests/nymNodeDetails';
|
||||
import { settingsValidationSchema } from 'src/components/Bonding/forms/nym-node/settingsValidationSchema';
|
||||
|
||||
export const GeneralNymNodeSettings = ({ bondedNode }: { bondedNode: TBondedNymNode }) => {
|
||||
const [openConfirmationModal, setOpenConfirmationModal] = useState<boolean>(false);
|
||||
const { fee, resetFeeState } = useGetFee();
|
||||
const { userBalance } = useContext(AppContext);
|
||||
const { updateNymNodeConfig } = useBondingContext();
|
||||
|
||||
const theme = useTheme();
|
||||
|
||||
@@ -26,28 +27,28 @@ export const GeneralNymNodeSettings = ({ bondedNode }: { bondedNode: TBondedNymN
|
||||
handleSubmit,
|
||||
formState: { errors, isSubmitting, isDirty, isValid },
|
||||
} = useForm({
|
||||
resolver: yupResolver(settingsValidationSchema),
|
||||
resolver: yupResolver(bondedInfoParametersValidationSchema),
|
||||
mode: 'onChange',
|
||||
defaultValues: {
|
||||
host: bondedNode.host,
|
||||
custom_http_port: bondedNode.customHttpPort,
|
||||
customHttpPort: bondedNode.customHttpPort,
|
||||
},
|
||||
});
|
||||
|
||||
const onSubmit = async ({ host, custom_http_port }: { host: string; custom_http_port: number | null }) => {
|
||||
const onSubmit = async (data: { host?: string; customHttpPort?: number | null }) => {
|
||||
resetFeeState();
|
||||
|
||||
try {
|
||||
const { host, customHttpPort } = data;
|
||||
if (host && customHttpPort) {
|
||||
const NymNodeConfigParams = {
|
||||
host,
|
||||
custom_http_port,
|
||||
restore_default_http_port: custom_http_port === null,
|
||||
custom_http_port: customHttpPort,
|
||||
};
|
||||
await updateNymNodeConfig(NymNodeConfigParams);
|
||||
|
||||
setOpenConfirmationModal(true);
|
||||
} catch (error) {
|
||||
Console.error(error);
|
||||
try {
|
||||
await updateNymNodeConfig(NymNodeConfigParams);
|
||||
setOpenConfirmationModal(true);
|
||||
} catch (error) {
|
||||
Console.error(error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -58,7 +59,7 @@ export const GeneralNymNodeSettings = ({ bondedNode }: { bondedNode: TBondedNymN
|
||||
open
|
||||
header="Update node settings"
|
||||
fee={fee}
|
||||
onConfirm={handleSubmit(onSubmit)}
|
||||
onConfirm={handleSubmit((d) => onSubmit(d))}
|
||||
onPrev={resetFeeState}
|
||||
onClose={resetFeeState}
|
||||
>
|
||||
@@ -69,6 +70,7 @@ export const GeneralNymNodeSettings = ({ bondedNode }: { bondedNode: TBondedNymN
|
||||
)}
|
||||
</ConfirmTx>
|
||||
)}
|
||||
{isSubmitting && <LoadingModal />}
|
||||
<Alert
|
||||
title={
|
||||
<Stack>
|
||||
@@ -91,12 +93,12 @@ export const GeneralNymNodeSettings = ({ bondedNode }: { bondedNode: TBondedNymN
|
||||
<Grid spacing={3} item container alignItems="center" xs={12} md={6}>
|
||||
<Grid item width={1}>
|
||||
<TextField
|
||||
{...register('custom_http_port')}
|
||||
name="custom_http_port"
|
||||
{...register('customHttpPort')}
|
||||
name="customHttpPort"
|
||||
label="Custom HTTP port"
|
||||
fullWidth
|
||||
error={!!errors.custom_http_port}
|
||||
helperText={errors.custom_http_port?.message}
|
||||
error={!!errors.customHttpPort}
|
||||
helperText={errors.customHttpPort?.message}
|
||||
InputLabelProps={{ shrink: true }}
|
||||
/>
|
||||
</Grid>
|
||||
@@ -132,7 +134,7 @@ export const GeneralNymNodeSettings = ({ bondedNode }: { bondedNode: TBondedNymN
|
||||
size="large"
|
||||
variant="contained"
|
||||
disabled={isSubmitting || !isDirty || !isValid}
|
||||
onClick={handleSubmit(onSubmit)}
|
||||
onClick={handleSubmit(() => undefined)}
|
||||
sx={{ m: 3, mr: 0 }}
|
||||
fullWidth
|
||||
>
|
||||
@@ -150,7 +152,7 @@ export const GeneralNymNodeSettings = ({ bondedNode }: { bondedNode: TBondedNymN
|
||||
hideCloseIcon
|
||||
displayInfoIcon
|
||||
onOk={async () => {
|
||||
setOpenConfirmationModal(false);
|
||||
await setOpenConfirmationModal(false);
|
||||
}}
|
||||
buttonFullWidth
|
||||
sx={{
|
||||
|
||||
@@ -4,7 +4,6 @@ import {
|
||||
SendTxResult,
|
||||
TransactionExecuteResult,
|
||||
MixNodeConfigUpdate,
|
||||
NodeConfigUpdate,
|
||||
GatewayConfigUpdate,
|
||||
} from '@nymproject/types';
|
||||
import { TBondGatewayArgs, TBondGatewaySignatureArgs, TNodeConfigUpdateArgs } from '../types';
|
||||
@@ -19,7 +18,7 @@ export const generateGatewayMsgPayload = async (args: Omit<TBondGatewaySignature
|
||||
export const updateMixnodeConfig = async (update: MixNodeConfigUpdate, fee?: Fee) =>
|
||||
invokeWrapper<TransactionExecuteResult>('update_mixnode_config', { update, fee });
|
||||
|
||||
export const updateNymNodeConfig = async (update: NodeConfigUpdate, fee?: Fee) =>
|
||||
export const updateNymNodeConfig = async (update: TNodeConfigUpdateArgs, fee?: Fee) =>
|
||||
invokeWrapper<TransactionExecuteResult>('update_nymnode_config', { update, fee });
|
||||
|
||||
export const updateGatewayConfig = async (update: GatewayConfigUpdate, fee?: Fee) =>
|
||||
|
||||
@@ -28,14 +28,14 @@ export const simulateUpdateMixnodeConfig = async (update: MixNodeConfigUpdate) =
|
||||
export const simulateUpdateGatewayConfig = async (update: GatewayConfigUpdate) =>
|
||||
invokeWrapper<FeeDetails>('simulate_update_gateway_config', { update });
|
||||
|
||||
export const simulateDelegateToNode = async (args: { nodeId: number; amount: DecCoin }) =>
|
||||
invokeWrapper<FeeDetails>('simulate_delegate_to_node', args);
|
||||
export const simulateDelegateToMixnode = async (args: { mixId: number; amount: DecCoin }) =>
|
||||
invokeWrapper<FeeDetails>('simulate_delegate_to_mixnode', args);
|
||||
|
||||
export const simulateUndelegateFromNode = async (nodeId: number) =>
|
||||
invokeWrapper<FeeDetails>('simulate_undelegate_from_node', { nodeId });
|
||||
export const simulateUndelegateFromMixnode = async (mixId: number) =>
|
||||
invokeWrapper<FeeDetails>('simulate_undelegate_from_mixnode', { mixId });
|
||||
|
||||
export const simulateClaimDelegatorReward = async (nodeId: number) =>
|
||||
invokeWrapper<FeeDetails>('simulate_claim_delegator_reward', { nodeId });
|
||||
export const simulateClaimDelegatorReward = async (mixId: number) =>
|
||||
invokeWrapper<FeeDetails>('simulate_claim_delegator_reward', { mixId });
|
||||
|
||||
export const simulateVestingClaimDelegatorReward = async (mixId: number) =>
|
||||
invokeWrapper<FeeDetails>('simulate_vesting_claim_delegator_reward', { mixId });
|
||||
|
||||
@@ -4,8 +4,8 @@ import { invokeWrapper } from './wrapper';
|
||||
|
||||
export const getEnv = async () => invokeWrapper<AppEnv>('get_env');
|
||||
|
||||
export const tryConvertIdentityToNodeId = async (mixIdentity: string) =>
|
||||
invokeWrapper<number | null>('try_convert_pubkey_to_node_id', { mixIdentity });
|
||||
export const tryConvertIdentityToMixId = async (mixIdentity: string) =>
|
||||
invokeWrapper<number | null>('try_convert_pubkey_to_mix_id', { mixIdentity });
|
||||
|
||||
export const getDefaultNodeCostParams = async (profitMarginPercent: string) =>
|
||||
invokeWrapper<NodeCostParams>('default_mixnode_cost_params', { profitMarginPercent });
|
||||
|
||||
@@ -36,7 +36,7 @@ export type TBondNymNodeArgs = TNymNodeSignatureArgs & {
|
||||
};
|
||||
|
||||
export type TNymNodeSignatureArgs = {
|
||||
nymnode: NymNode;
|
||||
nymNode: NymNode;
|
||||
costParams: NodeCostParams;
|
||||
pledge: DecCoin;
|
||||
};
|
||||
@@ -86,7 +86,7 @@ export type TNodeDescription = {
|
||||
|
||||
export type TNodeConfigUpdateArgs = {
|
||||
host: string;
|
||||
custom_http_port: number | null;
|
||||
custom_http_port: number;
|
||||
};
|
||||
|
||||
export type TDelegateArgs = {
|
||||
|
||||
@@ -27,7 +27,7 @@ use nym_credential_verification::{
|
||||
bandwidth_storage_manager::BandwidthStorageManager, ecash::EcashManager,
|
||||
BandwidthFlushingBehaviourConfig, ClientBandwidth, CredentialVerifier,
|
||||
};
|
||||
use nym_credentials_interface::CredentialSpendingData;
|
||||
use nym_credentials_interface::{CredentialSpendingData, TicketType};
|
||||
use nym_crypto::asymmetric::x25519::KeyPair;
|
||||
use nym_gateway_requests::models::CredentialSpendingRequest;
|
||||
use nym_gateway_storage::Storage;
|
||||
@@ -362,6 +362,7 @@ impl<S: Storage + Clone + 'static> MixnetListener<S> {
|
||||
"bandwidth entry should have just been created".to_string(),
|
||||
))?;
|
||||
|
||||
let t_type = credential.payment.t_type;
|
||||
let client_bandwidth = ClientBandwidth::new(bandwidth.into());
|
||||
let mut verifier = CredentialVerifier::new(
|
||||
CredentialSpendingRequest::new(credential),
|
||||
@@ -374,7 +375,20 @@ impl<S: Storage + Clone + 'static> MixnetListener<S> {
|
||||
true,
|
||||
),
|
||||
);
|
||||
let available_bandwidth = verifier.verify().await?;
|
||||
verifier.verify().await?;
|
||||
|
||||
let amount = TicketType::try_from_encoded(t_type)
|
||||
.map_err(|e| {
|
||||
AuthenticatorError::CredentialVerificationError(
|
||||
nym_credential_verification::Error::UnknownTicketType(e),
|
||||
)
|
||||
})?
|
||||
.to_repr()
|
||||
.bandwidth_value() as i64;
|
||||
let available_bandwidth = ecash_verifier
|
||||
.storage()
|
||||
.increase_bandwidth(client_id, amount)
|
||||
.await?;
|
||||
|
||||
Ok(AuthenticatorResponse::new_topup_bandwidth(
|
||||
RemainingBandwidthData {
|
||||
|
||||
@@ -7,6 +7,7 @@ use crate::manager::network::LoadedNetwork;
|
||||
use crate::manager::NetworkManager;
|
||||
use console::style;
|
||||
use nym_config::{must_get_home, DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILENAME, NYM_DIR};
|
||||
use nym_validator_client::client::NymApiClientExt;
|
||||
use nym_validator_client::NymApiClient;
|
||||
use rand::{thread_rng, RngCore};
|
||||
use std::fs;
|
||||
@@ -96,8 +97,8 @@ impl NetworkManager {
|
||||
let wait_fut = async {
|
||||
let inner_fut = async {
|
||||
loop {
|
||||
let mut nodes = match api_client.get_all_basic_nodes(None).await {
|
||||
Ok(nodes) => nodes,
|
||||
let mut gateways = match api_client.nym_api.get_basic_gateways(None).await {
|
||||
Ok(gateways) => gateways,
|
||||
Err(err) => {
|
||||
ctx.println(format!(
|
||||
"❌ {} {err}",
|
||||
@@ -109,7 +110,8 @@ impl NetworkManager {
|
||||
|
||||
// if we explicitly specified some identity, find THIS node
|
||||
if let Some(identity) = ctx.gateway.as_ref() {
|
||||
if let Some(node) = nodes
|
||||
if let Some(node) = gateways
|
||||
.nodes
|
||||
.iter()
|
||||
.find(|gw| &gw.ed25519_identity_pubkey.to_base58_string() == identity)
|
||||
{
|
||||
@@ -121,7 +123,7 @@ impl NetworkManager {
|
||||
}
|
||||
|
||||
// otherwise look for ANY node
|
||||
if let Some(node) = nodes.pop() {
|
||||
if let Some(node) = gateways.nodes.pop() {
|
||||
return SocketAddr::new(node.ip_addresses[0], node.entry.unwrap().ws_port);
|
||||
}
|
||||
sleep(Duration::from_secs(10)).await;
|
||||
|
||||
@@ -32,7 +32,6 @@ export * from './MixNodeDetails';
|
||||
export * from './MixNodeRewarding';
|
||||
export * from './MixnodeStatus';
|
||||
export * from './MixnodeStatusResponse';
|
||||
export * from './NodeConfigUpdate';
|
||||
export * from './NymNodeDetails';
|
||||
export * from './OriginalVestingResponse';
|
||||
export * from './PendingEpochEvent';
|
||||
|
||||
Reference in New Issue
Block a user