wip in removing the Credential type for more strongly typed alternative
This commit is contained in:
@@ -56,7 +56,7 @@ impl<C, St: Storage> BandwidthController<C, St> {
|
||||
Ok(obtain_aggregate_verification_key(&coconut_api_clients).await?)
|
||||
}
|
||||
|
||||
pub async fn prepare_coconut_credential(
|
||||
pub async fn prepare_bandwidth_credential(
|
||||
&self,
|
||||
) -> Result<PreparedCredential, BandwidthControllerError>
|
||||
where
|
||||
|
||||
@@ -574,7 +574,7 @@ impl<C, St> GatewayClient<C, St> {
|
||||
.bandwidth_controller
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.prepare_coconut_credential()
|
||||
.prepare_bandwidth_credential()
|
||||
.await?;
|
||||
|
||||
self.claim_coconut_bandwidth(prepared_credential.data, prepared_credential.epoch_id)
|
||||
|
||||
@@ -11,4 +11,4 @@ getset = "0.1.1"
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
thiserror = { workspace = true }
|
||||
|
||||
nym-coconut = {path = "../nymcoconut" }
|
||||
nym-coconut = { path = "../nymcoconut" }
|
||||
|
||||
@@ -12,6 +12,7 @@ thiserror = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
|
||||
nym-bandwidth-controller = { path = "../../common/bandwidth-controller" }
|
||||
nym-coconut = { path = "../nymcoconut" }
|
||||
nym-credentials = { path = "../../common/credentials" }
|
||||
nym-credential-storage = { path = "../../common/credential-storage" }
|
||||
nym-validator-client = { path = "../../common/client-libs/validator-client" }
|
||||
|
||||
@@ -17,10 +17,10 @@ zeroize = { workspace = true }
|
||||
|
||||
# I guess temporarily until we get serde support in coconut up and running
|
||||
nym-coconut-interface = { path = "../coconut-interface" }
|
||||
nym-crypto = { path = "../crypto", features = ["rand", "asymmetric"] }
|
||||
nym-crypto = { path = "../crypto", features = ["rand", "asymmetric", "serde"] }
|
||||
nym-api-requests = { path = "../../nym-api/nym-api-requests" }
|
||||
nym-validator-client = { path = "../client-libs/validator-client", default-features = false }
|
||||
serde = { version = "1.0.189", features = ["derive"] }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
|
||||
[dev-dependencies]
|
||||
rand = "0.7.3"
|
||||
|
||||
@@ -27,7 +27,7 @@ pub fn bandwidth_credential_params() -> &'static Parameters {
|
||||
BANDWIDTH_CREDENTIAL_PARAMS.get_or_init(IssuanceBandwidthCredential::default_parameters)
|
||||
}
|
||||
|
||||
#[derive(Zeroize, ZeroizeOnDrop, Clone, Debug, Serialize, Deserialize)]
|
||||
#[derive(Zeroize, Copy, Clone, Debug, Serialize, Deserialize)]
|
||||
pub enum CredentialType {
|
||||
Voucher,
|
||||
FreePass,
|
||||
@@ -37,6 +37,10 @@ impl CredentialType {
|
||||
pub fn is_free_pass(&self) -> bool {
|
||||
matches!(self, CredentialType::FreePass)
|
||||
}
|
||||
|
||||
pub fn is_voucher(&self) -> bool {
|
||||
matches!(self, CredentialType::Voucher)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for CredentialType {
|
||||
@@ -50,24 +54,24 @@ impl Display for CredentialType {
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CredentialSigningData {
|
||||
pub(crate) pedersen_commitments_openings: Vec<Scalar>,
|
||||
pub pedersen_commitments_openings: Vec<Scalar>,
|
||||
|
||||
pub(crate) blind_sign_request: BlindSignRequest,
|
||||
pub blind_sign_request: BlindSignRequest,
|
||||
|
||||
pub(crate) public_attributes_plain: Vec<String>,
|
||||
pub public_attributes_plain: Vec<String>,
|
||||
|
||||
pub(crate) typ: CredentialType,
|
||||
pub typ: CredentialType,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct CredentialSpendingData {
|
||||
pub(crate) embedded_private_attributes: usize,
|
||||
pub embedded_private_attributes: usize,
|
||||
|
||||
pub(crate) verify_credential_request: VerifyCredentialRequest,
|
||||
pub verify_credential_request: VerifyCredentialRequest,
|
||||
|
||||
pub(crate) public_attributes_plain: Vec<String>,
|
||||
pub public_attributes_plain: Vec<String>,
|
||||
|
||||
pub(crate) typ: CredentialType,
|
||||
pub typ: CredentialType,
|
||||
}
|
||||
|
||||
impl CredentialSpendingData {
|
||||
@@ -90,4 +94,21 @@ impl CredentialSpendingData {
|
||||
&public_attributes,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn validate_type_attribute(&self) -> bool {
|
||||
// the first attribute is variant specific bandwidth encoding, the second one should be the type
|
||||
let Some(type_plain) = self.public_attributes_plain.get(1) else {
|
||||
return false;
|
||||
};
|
||||
|
||||
match self.typ {
|
||||
CredentialType::Voucher => type_plain == VOUCHER_INFO_TYPE,
|
||||
CredentialType::FreePass => type_plain == FREE_PASS_INFO_TYPE,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_bandwidth_attribute(&self) -> Option<&String> {
|
||||
// the first attribute is variant specific bandwidth encoding, the second one should be the type
|
||||
self.public_attributes_plain.first()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,5 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
pub trait NymCredential {
|
||||
fn prove_credential(&self);
|
||||
|
||||
// pub attr
|
||||
// hashed
|
||||
// private
|
||||
fn prove_credential(&self) -> Result<(), ()>;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ pub use types::*;
|
||||
|
||||
pub mod authentication;
|
||||
pub mod iv;
|
||||
mod models;
|
||||
pub mod models;
|
||||
pub mod registration;
|
||||
pub mod types;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::GatewayRequestsError;
|
||||
use nym_coconut_interface::CoconutError;
|
||||
use nym_credentials::coconut::bandwidth::CredentialSpendingData;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@@ -20,6 +21,23 @@ impl CredentialSpendingWithEpoch {
|
||||
CredentialSpendingWithEpoch { data, epoch_id }
|
||||
}
|
||||
|
||||
pub fn matches_blinded_serial_number(
|
||||
&self,
|
||||
blinded_serial_number_bs58: &str,
|
||||
) -> Result<bool, CoconutError> {
|
||||
self.data
|
||||
.verify_credential_request
|
||||
.has_blinded_serial_number(blinded_serial_number_bs58)
|
||||
}
|
||||
|
||||
pub fn unchecked_voucher_value(&self) -> u64 {
|
||||
self.data
|
||||
.get_bandwidth_attribute()
|
||||
.expect("failed to extract bandwidth attribute")
|
||||
.parse()
|
||||
.expect("failed to parse voucher value")
|
||||
}
|
||||
|
||||
pub fn to_bytes(&self) -> Vec<u8> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
@@ -1,13 +1,49 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use log::error;
|
||||
use nym_coconut_interface::Credential;
|
||||
use nym_credentials::coconut::bandwidth::CredentialType;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum BandwidthError {}
|
||||
|
||||
pub struct Bandwidth {
|
||||
value: u64,
|
||||
}
|
||||
|
||||
impl Bandwidth {
|
||||
pub const fn new(value: u64) -> Bandwidth {
|
||||
Bandwidth { value }
|
||||
}
|
||||
|
||||
pub fn try_from_raw_value(value: &String, typ: CredentialType) -> Result<Self, BandwidthError> {
|
||||
// let bandwidth_value = match credential.data.typ {
|
||||
// CredentialType::Voucher => {
|
||||
// todo!()
|
||||
// }
|
||||
// CredentialType::FreePass => {
|
||||
// error!("unimplemented handling of free pass credential");
|
||||
// return Err(());
|
||||
// }
|
||||
// };
|
||||
|
||||
/*
|
||||
if bandwidth_value > i64::MAX as u64 {
|
||||
// note that this would have represented more than 1 exabyte,
|
||||
// which is like 125,000 worth of hard drives so I don't think we have
|
||||
// to worry about it for now...
|
||||
warn!("Somehow we received bandwidth value higher than 9223372036854775807. We don't really want to deal with this now");
|
||||
return Err(RequestHandlingError::UnsupportedBandwidthValue(
|
||||
bandwidth_value,
|
||||
));
|
||||
}
|
||||
*/
|
||||
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn value(&self) -> u64 {
|
||||
self.value
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2020-2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::node::client_handling::bandwidth::Bandwidth;
|
||||
|
||||
pub(crate) mod active_clients;
|
||||
mod bandwidth;
|
||||
pub(crate) mod embedded_network_requester;
|
||||
pub(crate) mod websocket;
|
||||
|
||||
pub(crate) const FREE_TESTNET_BANDWIDTH_VALUE: i64 = 64 * 1024 * 1024 * 1024; // 64GB
|
||||
pub(crate) const FREE_TESTNET_BANDWIDTH_VALUE: Bandwidth = Bandwidth::new(64 * 1024 * 1024 * 1024); // 64GB
|
||||
|
||||
@@ -19,8 +19,11 @@ use thiserror::Error;
|
||||
use tokio::io::{AsyncRead, AsyncWrite};
|
||||
use tokio_tungstenite::tungstenite::{protocol::Message, Error as WsError};
|
||||
|
||||
use nym_coconut_interface::CoconutError;
|
||||
use nym_credentials::coconut::bandwidth::CredentialType;
|
||||
use std::{convert::TryFrom, process, time::Duration};
|
||||
|
||||
use crate::node::client_handling::bandwidth::BandwidthError;
|
||||
use crate::node::{
|
||||
client_handling::{
|
||||
bandwidth::Bandwidth,
|
||||
@@ -76,11 +79,20 @@ pub(crate) enum RequestHandlingError {
|
||||
#[error("Coconut interface error - {0}")]
|
||||
CoconutInterfaceError(#[from] nym_coconut_interface::error::CoconutInterfaceError),
|
||||
|
||||
#[error("coconut failure: {0}")]
|
||||
CoconutError(#[from] CoconutError),
|
||||
|
||||
#[error("coconut api query failure: {0}")]
|
||||
CoconutApiError(#[from] CoconutApiError),
|
||||
|
||||
#[error("Credential error - {0}")]
|
||||
CredentialError(#[from] nym_credentials::error::Error),
|
||||
|
||||
#[error("failed to recover bandwidth value: {0}")]
|
||||
BandwidthRecoveryFailure(#[from] BandwidthError),
|
||||
|
||||
#[error("free pass credentials haven't been implemented yet")]
|
||||
UnimplementedFreePass,
|
||||
}
|
||||
|
||||
impl RequestHandlingError {
|
||||
@@ -177,10 +189,10 @@ where
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `amount`: amount to increase the available bandwidth by.
|
||||
async fn increase_bandwidth(&self, amount: i64) -> Result<(), RequestHandlingError> {
|
||||
async fn increase_bandwidth(&self, bandwidth: Bandwidth) -> Result<(), RequestHandlingError> {
|
||||
self.inner
|
||||
.storage
|
||||
.increase_bandwidth(self.client.address, amount)
|
||||
.increase_bandwidth(self.client.address, bandwidth.value() as i64)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -232,40 +244,45 @@ where
|
||||
let aggregated_verification_key = self
|
||||
.inner
|
||||
.coconut_verifier
|
||||
.verification_key(*credential.epoch_id())
|
||||
.verification_key(credential.epoch_id)
|
||||
.await?;
|
||||
|
||||
if !credential.verify(&aggregated_verification_key) {
|
||||
if !credential.data.validate_type_attribute() {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
let Some(bandwidth_attribute) = credential.data.get_bandwidth_attribute() else {
|
||||
unimplemented!()
|
||||
};
|
||||
|
||||
let bandwidth = Bandwidth::try_from_raw_value(bandwidth_attribute, credential.data.typ)?;
|
||||
|
||||
if !credential.data.verify(&aggregated_verification_key) {
|
||||
return Err(RequestHandlingError::InvalidBandwidthCredential(
|
||||
String::from("credential failed to verify on gateway"),
|
||||
));
|
||||
}
|
||||
|
||||
let api_clients = self
|
||||
.inner
|
||||
.coconut_verifier
|
||||
.api_clients(*credential.epoch_id())
|
||||
.await?;
|
||||
match credential.data.typ {
|
||||
CredentialType::Voucher => {
|
||||
let api_clients = self
|
||||
.inner
|
||||
.coconut_verifier
|
||||
.api_clients(credential.epoch_id)
|
||||
.await?;
|
||||
|
||||
self.inner
|
||||
.coconut_verifier
|
||||
.release_funds(&api_clients, &credential)
|
||||
.await?;
|
||||
|
||||
let bandwidth = Bandwidth::from(credential);
|
||||
let bandwidth_value = bandwidth.value();
|
||||
|
||||
if bandwidth_value > i64::MAX as u64 {
|
||||
// note that this would have represented more than 1 exabyte,
|
||||
// which is like 125,000 worth of hard drives so I don't think we have
|
||||
// to worry about it for now...
|
||||
warn!("Somehow we received bandwidth value higher than 9223372036854775807. We don't really want to deal with this now");
|
||||
return Err(RequestHandlingError::UnsupportedBandwidthValue(
|
||||
bandwidth_value,
|
||||
));
|
||||
self.inner
|
||||
.coconut_verifier
|
||||
.release_bandwidth_voucher_funds(&api_clients, credential)
|
||||
.await?;
|
||||
}
|
||||
CredentialType::FreePass => {
|
||||
error!("unimplemented handling of free pass credential");
|
||||
return Err(RequestHandlingError::UnimplementedFreePass);
|
||||
}
|
||||
}
|
||||
|
||||
self.increase_bandwidth(bandwidth_value as i64).await?;
|
||||
self.increase_bandwidth(bandwidth).await?;
|
||||
let available_total = self.get_available_bandwidth().await?;
|
||||
|
||||
Ok(ServerResponse::Bandwidth { available_total })
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
use super::authenticated::RequestHandlingError;
|
||||
use log::*;
|
||||
use nym_coconut_interface::{Credential, VerificationKey};
|
||||
use nym_gateway_requests::models::CredentialSpendingWithEpoch;
|
||||
use nym_validator_client::coconut::all_coconut_api_clients;
|
||||
use nym_validator_client::nym_api::EpochId;
|
||||
use nym_validator_client::nyxd::contract_traits::MultisigQueryClient;
|
||||
@@ -151,21 +152,31 @@ impl CoconutVerifier {
|
||||
Ok(all_coconut_api_clients(self.nyxd_client.read().await.deref(), epoch_id).await?)
|
||||
}
|
||||
|
||||
pub async fn release_funds(
|
||||
pub async fn release_bandwidth_voucher_funds(
|
||||
&self,
|
||||
api_clients: &[CoconutApiClient],
|
||||
credential: &Credential,
|
||||
credential: CredentialSpendingWithEpoch,
|
||||
) -> Result<(), RequestHandlingError> {
|
||||
if !credential.data.typ.is_voucher() {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// safety: the voucher funds are released after the credential has already been verified locally
|
||||
// and the underlying bandwidth value has been extracted, so the below MUST succeed
|
||||
let voucher_amount = credential.unchecked_voucher_value() as u128;
|
||||
|
||||
let blinded_serial_number = credential
|
||||
.data
|
||||
.verify_credential_request
|
||||
.blinded_serial_number_bs58();
|
||||
|
||||
let res = self
|
||||
.nyxd_client
|
||||
.write()
|
||||
.await
|
||||
.spend_credential(
|
||||
Coin::new(
|
||||
credential.voucher_value().into(),
|
||||
self.mix_denom_base.clone(),
|
||||
),
|
||||
credential.blinded_serial_number(),
|
||||
Coin::new(voucher_amount, &self.mix_denom_base),
|
||||
blinded_serial_number,
|
||||
self.address.to_string(),
|
||||
None,
|
||||
)
|
||||
@@ -186,27 +197,28 @@ impl CoconutVerifier {
|
||||
.await
|
||||
.query_proposal(proposal_id)
|
||||
.await?;
|
||||
if !credential.has_blinded_serial_number(&proposal.description)? {
|
||||
if !credential.matches_blinded_serial_number(&proposal.description)? {
|
||||
return Err(RequestHandlingError::ProposalIdError {
|
||||
reason: String::from("proposal has different serial number"),
|
||||
});
|
||||
}
|
||||
|
||||
let req = nym_api_requests::coconut::VerifyCredentialBody::new(
|
||||
credential.clone(),
|
||||
credential,
|
||||
proposal_id,
|
||||
self.address.clone(),
|
||||
);
|
||||
for client in api_clients {
|
||||
let ret = client.api_client.verify_bandwidth_credential(&req).await;
|
||||
let client_url = client.api_client.nym_api.current_url();
|
||||
match ret {
|
||||
Ok(res) => {
|
||||
if !res.verification_result {
|
||||
debug!("Validator {} didn't accept the credential. It will probably vote No on the spending proposal", client.api_client.nym_api.current_url());
|
||||
warn!("Validator at {client_url} didn't accept the credential. It will probably vote No on the spending proposal");
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("Validator {} could not be reached. There might be a problem with the coconut endpoint - {:?}", client.api_client.nym_api.current_url(), e);
|
||||
Err(err) => {
|
||||
warn!("Validator at {client_url} could not be reached. There might be a problem with the coconut endpoint: {err}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,9 @@ serde = { workspace = true, features = ["derive"] }
|
||||
ts-rs = { workspace = true, optional = true }
|
||||
tendermint = { workspace = true }
|
||||
|
||||
nym-coconut = { path = "../../common/nymcoconut" }
|
||||
nym-coconut-interface = { path = "../../common/coconut-interface" }
|
||||
#nym-credentials = { path = "../../common/credentials" }
|
||||
nym-crypto = { path = "../../common/crypto", features = ["serde", "asymmetric"]}
|
||||
|
||||
nym-mixnet-contract-common = { path= "../../common/cosmwasm-smart-contracts/mixnet-contract" }
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::coconut::helpers::issued_credential_plaintext;
|
||||
use cosmrs::AccountId;
|
||||
use nym_coconut_interface::{
|
||||
error::CoconutInterfaceError, hash_to_scalar, Attribute, BlindSignRequest, BlindedSignature,
|
||||
Bytable, Credential, VerificationKey,
|
||||
use nym_coconut::{
|
||||
hash_to_scalar, Attribute, BlindSignRequest, BlindedSignature, Bytable, CoconutError,
|
||||
Signature, VerificationKey,
|
||||
};
|
||||
use nym_crypto::asymmetric::identity;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -14,21 +14,30 @@ use tendermint::hash::Hash;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct VerifyCredentialBody {
|
||||
pub credential: Credential,
|
||||
/// The cryptographic material required for spending the underlying credential.
|
||||
pub credential_data: (),
|
||||
|
||||
/// The (DKG) epoch id under which the credential has been issued so that the verifier
|
||||
/// could use correct verification key for validation.
|
||||
pub epoch_id: u64,
|
||||
|
||||
/// Multisig proposal for releasing funds for the provided bandwidth credential
|
||||
pub proposal_id: u64,
|
||||
|
||||
/// Cosmos address of the spender of the credential
|
||||
pub gateway_cosmos_addr: AccountId,
|
||||
}
|
||||
|
||||
impl VerifyCredentialBody {
|
||||
pub fn new(
|
||||
credential: Credential,
|
||||
credential_data: (),
|
||||
epoch_id: u64,
|
||||
proposal_id: u64,
|
||||
gateway_cosmos_addr: AccountId,
|
||||
) -> VerifyCredentialBody {
|
||||
VerifyCredentialBody {
|
||||
credential,
|
||||
credential_data,
|
||||
epoch_id,
|
||||
proposal_id,
|
||||
gateway_cosmos_addr,
|
||||
}
|
||||
@@ -115,7 +124,7 @@ impl BlindedSignatureResponse {
|
||||
bs58::encode(&self.to_bytes()).into_string()
|
||||
}
|
||||
|
||||
pub fn from_base58_string<I: AsRef<[u8]>>(val: I) -> Result<Self, CoconutInterfaceError> {
|
||||
pub fn from_base58_string<I: AsRef<[u8]>>(val: I) -> Result<Self, CoconutError> {
|
||||
let bytes = bs58::decode(val).into_vec()?;
|
||||
Self::from_bytes(&bytes)
|
||||
}
|
||||
@@ -124,7 +133,7 @@ impl BlindedSignatureResponse {
|
||||
self.blinded_signature.to_byte_vec()
|
||||
}
|
||||
|
||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self, CoconutInterfaceError> {
|
||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self, CoconutError> {
|
||||
Ok(BlindedSignatureResponse {
|
||||
blinded_signature: BlindedSignature::from_bytes(bytes)?,
|
||||
})
|
||||
|
||||
Generated
+16
@@ -958,6 +958,12 @@ version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f"
|
||||
|
||||
[[package]]
|
||||
name = "const-str"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aca749d3d3f5b87a0d6100509879f9cf486ab510803a4a4e1001da1ff61c2bd6"
|
||||
|
||||
[[package]]
|
||||
name = "constant_time_eq"
|
||||
version = "0.3.0"
|
||||
@@ -3688,6 +3694,7 @@ dependencies = [
|
||||
"cosmrs",
|
||||
"cosmwasm-std",
|
||||
"getset",
|
||||
"nym-coconut",
|
||||
"nym-coconut-interface",
|
||||
"nym-crypto",
|
||||
"nym-mixnet-contract-common",
|
||||
@@ -3723,6 +3730,7 @@ dependencies = [
|
||||
"clap",
|
||||
"clap_complete",
|
||||
"clap_complete_fig",
|
||||
"const-str",
|
||||
"log",
|
||||
"pretty_env_logger",
|
||||
"schemars",
|
||||
@@ -3763,6 +3771,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2 0.10.8",
|
||||
"si-scale",
|
||||
"sqlx",
|
||||
"tap",
|
||||
"thiserror",
|
||||
@@ -4142,6 +4151,7 @@ dependencies = [
|
||||
"cfg-if",
|
||||
"dotenvy",
|
||||
"hex-literal",
|
||||
"log",
|
||||
"once_cell",
|
||||
"schemars",
|
||||
"serde",
|
||||
@@ -6225,6 +6235,12 @@ dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "si-scale"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44beb68bf488343b13ddbd74d1d5d5e6559a58b6dfaee74eb8d5ed4f7ed7666f"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.3.17"
|
||||
|
||||
Generated
+9
@@ -750,6 +750,12 @@ version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f"
|
||||
|
||||
[[package]]
|
||||
name = "const-str"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aca749d3d3f5b87a0d6100509879f9cf486ab510803a4a4e1001da1ff61c2bd6"
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.4.0"
|
||||
@@ -3092,6 +3098,7 @@ dependencies = [
|
||||
"cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)",
|
||||
"cosmwasm-std",
|
||||
"getset",
|
||||
"nym-coconut",
|
||||
"nym-coconut-interface",
|
||||
"nym-crypto",
|
||||
"nym-mixnet-contract-common",
|
||||
@@ -3109,6 +3116,7 @@ dependencies = [
|
||||
"clap",
|
||||
"clap_complete",
|
||||
"clap_complete_fig",
|
||||
"const-str",
|
||||
"log",
|
||||
"pretty_env_logger",
|
||||
"schemars",
|
||||
@@ -3317,6 +3325,7 @@ dependencies = [
|
||||
"cfg-if",
|
||||
"dotenvy",
|
||||
"hex-literal",
|
||||
"log",
|
||||
"once_cell",
|
||||
"schemars",
|
||||
"serde",
|
||||
|
||||
Reference in New Issue
Block a user