diff --git a/Cargo.lock b/Cargo.lock index dcc8435b29..6b7c4a23a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6508,6 +6508,7 @@ dependencies = [ "log", "nym-bandwidth-controller", "nym-client-core", + "nym-compact-ecash", "nym-config", "nym-credential-storage", "nym-credentials", @@ -7229,6 +7230,7 @@ dependencies = [ "nym-bandwidth-controller", "nym-bin-common", "nym-client-core", + "nym-compact-ecash", "nym-credential-storage", "nym-credential-utils", "nym-credentials", diff --git a/common/bandwidth-controller/src/acquire/mod.rs b/common/bandwidth-controller/src/acquire/mod.rs index 50455be9a5..8724a74304 100644 --- a/common/bandwidth-controller/src/acquire/mod.rs +++ b/common/bandwidth-controller/src/acquire/mod.rs @@ -2,8 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 use crate::error::BandwidthControllerError; +use nym_compact_ecash::scheme::keygen::KeyPairUser; use nym_compact_ecash::setup::GroupParameters; -use nym_compact_ecash::{generate_keypair_user, Base58}; +use nym_compact_ecash::Base58; use nym_credential_storage::storage::Storage; use nym_credentials::coconut::bandwidth::BandwidthVoucher; use nym_credentials::coconut::utils::obtain_aggregate_signature; @@ -20,7 +21,11 @@ use std::str::FromStr; pub mod state; -pub async fn deposit(client: &C, amount: Coin) -> Result +pub async fn deposit( + client: &C, + amount: Coin, + ecash_keypair: KeyPairUser, +) -> Result where C: CoconutBandwidthSigningClient + Sync, { @@ -28,7 +33,6 @@ where let signing_keypair = KeyPair::from(identity::KeyPair::new(&mut rng)); let encryption_keypair = KeyPair::from(encryption::KeyPair::new(&mut rng)); let params = GroupParameters::new().unwrap(); - let ecash_keypair = generate_keypair_user(¶ms); let voucher_value = amount.amount.to_string(); let tx_hash = client diff --git a/common/commands/src/coconut/issue_credentials.rs b/common/commands/src/coconut/issue_credentials.rs index cd8a9b5f36..65eee3e9e3 100644 --- a/common/commands/src/coconut/issue_credentials.rs +++ b/common/commands/src/coconut/issue_credentials.rs @@ -36,6 +36,14 @@ pub async fn execute(args: Args, client: SigningClient) -> anyhow::Result<()> { bail!("the loaded config does not have a credentials store information") }; + let Ok(ecash_key_path) = loaded.try_get_ecash_key() else { + bail!("the loaded config does not have an ecash key path information") + }; + + let Ok(ecash_keypair) = nym_pemstore::load_keypair(&ecash_key_path) else { + bail!("invalid secret key in the config path") + }; + println!( "using credentials store at '{}'", credentials_store.display() @@ -45,7 +53,14 @@ pub async fn execute(args: Args, client: SigningClient) -> anyhow::Result<()> { let coin = Coin::new(args.amount as u128, denom); let persistent_storage = initialise_persistent_storage(credentials_store).await; - utils::issue_credential(&client, coin, &persistent_storage, args.recovery_dir).await?; + utils::issue_credential( + &client, + coin, + ecash_keypair, + &persistent_storage, + args.recovery_dir, + ) + .await?; Ok(()) } diff --git a/common/commands/src/utils.rs b/common/commands/src/utils.rs index 25797c71e9..0b858321a4 100644 --- a/common/commands/src/utils.rs +++ b/common/commands/src/utils.rs @@ -123,6 +123,18 @@ impl CommonConfigsWrapper { } } + pub(crate) fn try_get_ecash_key(&self) -> anyhow::Result { + match self { + CommonConfigsWrapper::NymClients(cfg) => { + Ok(cfg.storage_paths.inner.keys.ecash_key_pair_path()) + } + CommonConfigsWrapper::NymApi(cfg) => { + todo!() //SW implement ecash key for nym-api + } + CommonConfigsWrapper::Unknown(cfg) => cfg.try_get_ecash_key(), + } + } + pub(crate) fn try_get_credentials_store(&self) -> anyhow::Result { match self { CommonConfigsWrapper::NymClients(cfg) => { @@ -215,6 +227,10 @@ impl UnknownConfigWrapper { } } + pub(crate) fn try_get_ecash_key(&self) -> anyhow::Result { + todo!() + } + pub(crate) fn try_get_credentials_store(&self) -> anyhow::Result { let id_val = self .find_value("credentials_database_path") diff --git a/common/credential-utils/Cargo.toml b/common/credential-utils/Cargo.toml index 1949107036..994dc7edf1 100644 --- a/common/credential-utils/Cargo.toml +++ b/common/credential-utils/Cargo.toml @@ -16,3 +16,4 @@ nym-credential-storage = { path = "../../common/credential-storage" } nym-validator-client = { path = "../../common/client-libs/validator-client" } nym-config = { path = "../../common/config" } nym-client-core = { path = "../../common/client-core" } +nym-compact-ecash = { path = "../../common/nym_offline_compact_ecash" } diff --git a/common/credential-utils/src/utils.rs b/common/credential-utils/src/utils.rs index b58211eba0..c603a1b3c3 100644 --- a/common/credential-utils/src/utils.rs +++ b/common/credential-utils/src/utils.rs @@ -3,6 +3,7 @@ use crate::recovery_storage::RecoveryStorage; use log::*; use nym_bandwidth_controller::acquire::state::State; use nym_client_core::config::disk_persistence::CommonClientPaths; +use nym_compact_ecash::scheme::keygen::KeyPairUser; use nym_config::DEFAULT_DATA_DIR; use nym_credential_storage::persistent_storage::PersistentStorage; use nym_validator_client::nyxd::contract_traits::{CoconutBandwidthSigningClient, DkgQueryClient}; @@ -16,6 +17,7 @@ const SAFETY_BUFFER_SECS: u64 = 60; // 1 minute pub async fn issue_credential( client: &C, amount: Coin, + ecash_keypair: KeyPairUser, persistent_storage: &PersistentStorage, recovery_storage_path: PathBuf, ) -> Result<()> @@ -39,7 +41,8 @@ where } }; - let state = nym_bandwidth_controller::acquire::deposit(client, amount.clone()).await?; + let state = + nym_bandwidth_controller::acquire::deposit(client, amount.clone(), ecash_keypair).await?; if nym_bandwidth_controller::acquire::get_credential(&state, client, persistent_storage) .await diff --git a/common/nym_offline_compact_ecash/src/scheme/keygen.rs b/common/nym_offline_compact_ecash/src/scheme/keygen.rs index a7316d6a87..28dd4e388d 100644 --- a/common/nym_offline_compact_ecash/src/scheme/keygen.rs +++ b/common/nym_offline_compact_ecash/src/scheme/keygen.rs @@ -467,7 +467,7 @@ impl KeyPairAuth { } } -#[derive(Zeroize, ZeroizeOnDrop)] +#[derive(Zeroize, ZeroizeOnDrop, Debug, Clone, PartialEq)] pub struct KeyPairUser { secret_key: SecretKeyUser, #[zeroize(skip)] diff --git a/sdk/rust/nym-sdk/Cargo.toml b/sdk/rust/nym-sdk/Cargo.toml index fb5cbf4ac8..33bdf34a76 100644 --- a/sdk/rust/nym-sdk/Cargo.toml +++ b/sdk/rust/nym-sdk/Cargo.toml @@ -24,6 +24,7 @@ nym-validator-client = { path = "../../../common/client-libs/validator-client", nym-socks5-requests = { path = "../../../common/socks5/requests" } nym-ordered-buffer = { path = "../../../common/socks5/ordered-buffer" } nym-service-providers-common = { path = "../../../service-providers/common" } +nym-compact-ecash = { path = "../../../common/nym_offline_compact_ecash" } bytecodec = "0.4.15" httpcodec = "0.2.3" bytes = "1" diff --git a/sdk/rust/nym-sdk/src/bandwidth/client.rs b/sdk/rust/nym-sdk/src/bandwidth/client.rs index 7171282a71..9ccbe6d761 100644 --- a/sdk/rust/nym-sdk/src/bandwidth/client.rs +++ b/sdk/rust/nym-sdk/src/bandwidth/client.rs @@ -3,6 +3,9 @@ use crate::error::{Error, Result}; use nym_bandwidth_controller::acquire::state::State; +use nym_compact_ecash::generate_keypair_user; +use nym_compact_ecash::scheme::keygen::KeyPairUser; +use nym_compact_ecash::setup::GroupParameters; use nym_credential_storage::storage::Storage; use nym_credentials::coconut::bandwidth::BandwidthVoucher; use nym_network_defaults::NymNetworkDetails; @@ -22,6 +25,7 @@ pub type VoucherBlob = Vec; pub struct BandwidthAcquireClient<'a, St: Storage> { network_details: NymNetworkDetails, client: DirectSigningHttpRpcNyxdClient, + ecash_keypair: KeyPairUser, storage: &'a St, } @@ -43,9 +47,11 @@ where nyxd_url, mnemonic.parse()?, )?; + let ecash_keypair = generate_keypair_user(&GroupParameters::new().unwrap()); Ok(Self { network_details, client, + ecash_keypair, storage, }) } @@ -56,7 +62,12 @@ where /// associated bandwidth credential, using [`Self::recover`]. pub async fn acquire(&self, amount: u128) -> Result<()> { let amount = Coin::new(amount, &self.network_details.chain_details.mix_denom.base); - let state = nym_bandwidth_controller::acquire::deposit(&self.client, amount).await?; + let state = nym_bandwidth_controller::acquire::deposit( + &self.client, + amount, + self.ecash_keypair.clone(), + ) + .await?; nym_bandwidth_controller::acquire::get_credential(&state, &self.client, self.storage) .await .map_err(|reason| Error::UnconvertedDeposit {