Skip to content

Commit d04307d

Browse files
committed
wip
1 parent 1a4345d commit d04307d

File tree

12 files changed

+196
-67
lines changed

12 files changed

+196
-67
lines changed

common/client-core/src/client/packet_statistics_control.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::{
33
time::{Duration, Instant},
44
};
55

6+
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
67
use nym_metrics::{inc, inc_by};
78
use si_scale::helpers::bibytes2;
89

@@ -72,6 +73,11 @@ struct PacketStatistics {
7273
}
7374

7475
impl PacketStatistics {
76+
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
77+
fn handle_event(&mut self, event: crate::client::packet_statistics_control::PacketStatisticsEvent) {
78+
}
79+
80+
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
7581
fn handle_event(&mut self, event: PacketStatisticsEvent) {
7682
match event {
7783
PacketStatisticsEvent::RealPacketSent(packet_size) => {

common/credential-utils/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ license.workspace = true
99
[dependencies]
1010
log = { workspace = true }
1111
thiserror = { workspace = true }
12-
tokio = { workspace = true }
12+
tokio = { workspace = true, features = ["sync", "time"] }
1313
time.workspace = true
1414

1515
nym-bandwidth-controller = { path = "../../common/bandwidth-controller" }

common/credentials-interface/Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,15 @@ strum = { workspace = true, features = ["derive"] }
1818
time = { workspace = true, features = ["serde"] }
1919
rand = { workspace = true }
2020

21+
# 'wasm-serde-types' feature
22+
wasm-utils = { path = "../wasm/utils", default-features = false, optional = true }
23+
tsify = { workspace = true, features = ["js"], optional = true }
24+
wasm-bindgen = { workspace = true, optional = true }
25+
2126
nym-compact-ecash = { path = "../nym_offline_compact_ecash" }
2227
nym-ecash-time = { path = "../ecash-time" }
2328
nym-network-defaults = { path = "../network-defaults" }
29+
30+
[features]
31+
default = []
32+
wasm-serde-types = ["tsify", "wasm-bindgen", "wasm-utils"]

common/credentials-interface/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ pub use nym_compact_ecash::{
3030
};
3131
use nym_ecash_time::{ecash_today, EcashTime};
3232

33+
#[cfg(feature = "wasm-serde-types")]
34+
use tsify::Tsify;
35+
36+
#[cfg(feature = "wasm-serde-types")]
37+
use wasm_bindgen::{prelude::wasm_bindgen};
38+
3339
#[derive(Debug, Clone)]
3440
pub struct CredentialSigningData {
3541
pub withdrawal_request: WithdrawalRequest,
@@ -233,6 +239,8 @@ impl From<PayInfo> for NymPayInfo {
233239
)]
234240
#[serde(rename_all = "kebab-case")]
235241
#[strum(serialize_all = "kebab-case")]
242+
#[cfg_attr(feature = "wasm-serde-types", derive(Tsify))]
243+
#[cfg_attr(feature = "wasm-serde-types", tsify(into_wasm_abi, from_wasm_abi))]
236244
pub enum TicketType {
237245
#[default]
238246
V1MixnetEntry,

sdk/rust/nym-sdk/src/bandwidth/client.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ where
2626
St: Storage,
2727
<St as Storage>::StorageError: Send + Sync + 'static,
2828
{
29-
pub(crate) fn new(
29+
pub fn new(
3030
network_details: NymNetworkDetails,
3131
mnemonic: String,
3232
storage: &'a St,
33-
client_id: String,
33+
client_id_private_key_base58: String,
3434
ticketbook_type: TicketType,
3535
) -> Result<Self> {
3636
let nyxd_url = network_details.endpoints[0].nyxd_url.as_str();
@@ -44,7 +44,7 @@ where
4444
Ok(Self {
4545
client,
4646
storage,
47-
client_id: client_id.into(),
47+
client_id: client_id_private_key_base58.into(),
4848
ticketbook_type,
4949
})
5050
}

wasm/zk-nym-lib/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,11 @@ wasm-utils = { path = "../../common/wasm/utils" }
2828

2929
nym-bin-common = { path = "../../common/bin-common" }
3030
nym-credentials = { path = "../../common/credentials" }
31+
nym-credential-utils = { path = "../../common/credential-utils" }
3132
nym-credential-storage = { path = "../../common/credential-storage" }
3233
nym-bandwidth-controller = { path = "../../common/bandwidth-controller" }
3334
nym-validator-client = { path = "../../common/client-libs/validator-client", default-features = false }
34-
nym-credentials-interface = { path = "../../common/credentials-interface" }
35+
nym-credentials-interface = { path = "../../common/credentials-interface", features = ["wasm-serde-types"]}
3536
nym-network-defaults = { path = "../../common/network-defaults" }
3637

3738
[dev-dependencies]

wasm/zk-nym-lib/Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,7 @@ build:
44

55
# make my life easier so I wouldn't need to deal with any bundlers. sorry @MS : )
66
build-debug-dev:
7-
wasm-pack build --scope nymproject --target no-modules
7+
wasm-pack build --scope nymproject --target no-modules
8+
9+
clippy:
10+
cargo clippy --target wasm32-unknown-unknown -- -Dwarnings

wasm/zk-nym-lib/src/bandwidth.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Copyright 2022-2023 - Nym Technologies SA <[email protected]>
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
use crate::error::WasmCredentialClientError;
5+
use nym_credential_storage::storage::Storage;
6+
use nym_credential_utils::utils::issue_credential;
7+
use nym_credentials_interface::TicketType;
8+
use nym_network_defaults::NymNetworkDetails;
9+
use nym_validator_client::{nyxd, DirectSigningReqwestRpcValidatorClient};
10+
use zeroize::Zeroizing;
11+
12+
/// Represents a client that can be used to acquire bandwidth. You typically create one when you
13+
/// want to connect to the mixnet using paid coconut bandwidth credentials.
14+
/// The way to create this client is by calling
15+
/// [`crate::mixnet::DisconnectedMixnetClient::create_bandwidth_client`] on the associated mixnet
16+
/// client.
17+
pub struct BandwidthAcquireClient<'a, St: Storage> {
18+
client: DirectSigningReqwestRpcValidatorClient,
19+
storage: &'a St,
20+
client_id: Zeroizing<String>,
21+
ticketbook_type: TicketType,
22+
}
23+
24+
impl<'a, St> BandwidthAcquireClient<'a, St>
25+
where
26+
St: Storage,
27+
<St as Storage>::StorageError: Send + Sync + 'static,
28+
{
29+
pub fn new(
30+
network_details: NymNetworkDetails,
31+
mnemonic: String,
32+
storage: &'a St,
33+
client_id_private_key_base58: String,
34+
ticketbook_type: TicketType,
35+
) -> Result<Self, WasmCredentialClientError> {
36+
let nyxd_url = network_details.endpoints[0].nyxd_url.as_str();
37+
let config = nyxd::Config::try_from_nym_network_details(&network_details)?;
38+
39+
let client = DirectSigningReqwestRpcValidatorClient::connect_with_mnemonic(
40+
config,
41+
nyxd_url,
42+
mnemonic.parse()?,
43+
)?;
44+
Ok(Self {
45+
client,
46+
storage,
47+
client_id: client_id_private_key_base58.into(),
48+
ticketbook_type,
49+
})
50+
}
51+
52+
pub async fn acquire(&self) -> Result<(), WasmCredentialClientError> {
53+
issue_credential(
54+
&self.client,
55+
self.storage,
56+
self.client_id.as_bytes(),
57+
self.ticketbook_type,
58+
)
59+
.await?;
60+
Ok(())
61+
}
62+
}

wasm/zk-nym-lib/src/credential.rs

Lines changed: 95 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -5,37 +5,52 @@ use crate::error::WasmCredentialClientError;
55
use crate::opts::CredentialClientOpts;
66
use js_sys::Promise;
77
use nym_credential_storage::ephemeral_storage::EphemeralCredentialStorage;
8-
use nym_credential_storage::models::StoredIssuedCredential;
8+
use nym_credential_storage::storage::Storage;
9+
use nym_credentials_interface::TicketType;
910
use nym_network_defaults::NymNetworkDetails;
10-
use nym_validator_client::nyxd::{Config, CosmWasmCoin};
11-
use nym_validator_client::DirectSigningReqwestRpcNyxdClient;
11+
use crate::bandwidth::BandwidthAcquireClient;
12+
use nym_validator_client::nyxd::CosmWasmCoin;
1213
use serde::{Deserialize, Serialize};
1314
use tsify::Tsify;
1415
use wasm_bindgen::prelude::*;
1516
use wasm_bindgen_futures::future_to_promise;
16-
use wasm_utils::console_log;
1717
use wasm_utils::error::PromisableResult;
1818
use zeroize::{Zeroize, ZeroizeOnDrop};
19+
use nym_credentials::ecash::bandwidth::serialiser::VersionedSerialise;
1920

2021
#[wasm_bindgen(js_name = acquireCredential)]
21-
pub fn acquire_credential(mnemonic: String, amount: String, opts: CredentialClientOpts) -> Promise {
22+
pub fn acquire_credential(
23+
mnemonic: String,
24+
amount: String,
25+
client_id_private_key_base58: String,
26+
ticketbook_type: TicketType,
27+
opts: CredentialClientOpts,
28+
) -> Promise {
2229
future_to_promise(async move {
23-
acquire_credential_async(mnemonic, amount, opts)
24-
.await
25-
.map(|credential| {
26-
serde_wasm_bindgen::to_value(&credential).expect("this serialization can't fail")
27-
})
28-
.into_promise_result()
30+
acquire_credential_async(
31+
mnemonic,
32+
amount,
33+
client_id_private_key_base58,
34+
ticketbook_type,
35+
opts,
36+
)
37+
.await
38+
.map(|credential| {
39+
serde_wasm_bindgen::to_value(&credential).expect("this serialization can't fail")
40+
})
41+
.into_promise_result()
2942
})
3043
}
3144

3245
async fn acquire_credential_async(
3346
mnemonic: String,
3447
amount: String,
48+
client_id_private_key_base58: String,
49+
ticketbook_type: TicketType,
3550
opts: CredentialClientOpts,
3651
) -> Result<WasmIssuedCredential, WasmCredentialClientError> {
37-
// start by parsing mnemonic so that we could immediately move it into a Zeroizing wrapper
38-
let mnemonic = crate::helpers::parse_mnemonic(mnemonic)?;
52+
// // start by parsing mnemonic so that we could immediately move it into a Zeroizing wrapper
53+
// let mnemonic = crate::helpers::parse_mnemonic(mnemonic)?;
3954

4055
// why are we parsing into CosmWasmCoin and not "our" Coin?
4156
// simple. because it has the nicest 'FromStr' impl
@@ -61,44 +76,64 @@ async fn acquire_credential_async(
6176
}
6277
};
6378

64-
let config = Config::try_from_nym_network_details(&network)?;
65-
66-
// just get the first nyxd endpoint
67-
let nyxd_endpoint = network
68-
.endpoints
69-
.get(0)
70-
.ok_or(WasmCredentialClientError::NoNyxdEndpoints)?
71-
.try_nyxd_url()?;
72-
73-
let client = DirectSigningReqwestRpcNyxdClient::connect_reqwest_with_mnemonic(
74-
config,
75-
nyxd_endpoint,
76-
mnemonic,
77-
);
78-
79-
console_log!("starting the deposit...");
80-
let deposit_state = nym_bandwidth_controller::acquire::deposit(&client, amount).await?;
81-
let blinded_serial = deposit_state.voucher.blinded_serial_number_bs58();
82-
console_log!(
83-
"obtained bandwidth voucher with the following blinded serial number: {blinded_serial}"
84-
);
85-
86-
// TODO: use proper persistent storage here. probably indexeddb like we have for our 'normal' wasm client
8779
let ephemeral_storage = EphemeralCredentialStorage::default();
8880

89-
// store credential in the ephemeral storage...
90-
nym_bandwidth_controller::acquire::get_bandwidth_voucher(
91-
&deposit_state,
92-
&client,
81+
let client = BandwidthAcquireClient::new(
82+
network,
83+
mnemonic,
9384
&ephemeral_storage,
94-
)
95-
.await?;
96-
97-
// and immediately get it out!
98-
let mut credentials = ephemeral_storage.take_credentials().await;
99-
let cred = credentials.pop().expect("we just got a credential issued");
100-
101-
Ok(cred.into())
85+
client_id_private_key_base58,
86+
ticketbook_type,
87+
)?;
88+
89+
client.acquire().await?;
90+
91+
// let config = Config::try_from_nym_network_details(&network)?;
92+
//
93+
// // just get the first nyxd endpoint
94+
// let nyxd_endpoint = network
95+
// .endpoints
96+
// .get(0)
97+
// .ok_or(WasmCredentialClientError::NoNyxdEndpoints)?
98+
// .try_nyxd_url()?;
99+
//
100+
// let client = DirectSigningReqwestRpcNyxdClient::connect_reqwest_with_mnemonic(
101+
// config,
102+
// nyxd_endpoint,
103+
// mnemonic,
104+
// );
105+
//
106+
// console_log!("starting the deposit...");
107+
// let deposit_state = nym_bandwidth_controller::acquire::deposit(&client, amount).await?;
108+
// let blinded_serial = deposit_state.voucher.blinded_serial_number_bs58();
109+
// console_log!(
110+
// "obtained bandwidth voucher with the following blinded serial number: {blinded_serial}"
111+
// );
112+
//
113+
// // TODO: use proper persistent storage here. probably indexeddb like we have for our 'normal' wasm client
114+
// let ephemeral_storage = EphemeralCredentialStorage::default();
115+
//
116+
// // store credential in the ephemeral storage...
117+
// nym_bandwidth_controller::acquire::get_bandwidth_voucher(
118+
// &deposit_state,
119+
// &client,
120+
// &ephemeral_storage,
121+
// )
122+
// .await?;
123+
//
124+
125+
match ephemeral_storage.get_next_unspent_usable_ticketbook(1u32).await? {
126+
Some(ticket_book) => {
127+
let serialized = ticket_book.ticketbook.pack();
128+
129+
Ok(WasmIssuedCredential {
130+
serialization_revision: serialized.revision,
131+
credential_data: serialized.data,
132+
ticketbook_type: format!("{}", ticketbook_type),
133+
})
134+
},
135+
None => Err(WasmCredentialClientError::TicketbookCredentialStoreIsNone),
136+
}
102137
}
103138

104139
#[derive(Tsify, Debug, Clone, Serialize, Deserialize, Zeroize, ZeroizeOnDrop)]
@@ -107,17 +142,17 @@ async fn acquire_credential_async(
107142
pub struct WasmIssuedCredential {
108143
pub serialization_revision: u8,
109144
pub credential_data: Vec<u8>,
110-
pub credential_type: String,
111-
pub epoch_id: u32,
145+
pub ticketbook_type: String,
146+
// pub epoch_id: u32,
112147
}
113148

114-
impl From<StoredIssuedCredential> for WasmIssuedCredential {
115-
fn from(value: StoredIssuedCredential) -> Self {
116-
WasmIssuedCredential {
117-
serialization_revision: value.serialization_revision,
118-
credential_data: value.credential_data.clone(),
119-
credential_type: value.credential_type.clone(),
120-
epoch_id: value.epoch_id,
121-
}
122-
}
123-
}
149+
// impl From<StoredIssuedCredential> for WasmIssuedCredential {
150+
// fn from(value: StoredIssuedCredential) -> Self {
151+
// WasmIssuedCredential {
152+
// serialization_revision: value.serialization_revision,
153+
// credential_data: value.credential_data.clone(),
154+
// ticketbook_type: value.ticketbook_type.clone(),
155+
// // epoch_id: value.epoch_id,
156+
// }
157+
// }
158+
// }

wasm/zk-nym-lib/src/error.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
use nym_bandwidth_controller::error::BandwidthControllerError;
5-
use nym_network_defaults::UrlParseError;
65
use nym_validator_client::nyxd::error::NyxdError;
76
use thiserror::Error;
87
use wasm_utils::wasm_error;
@@ -55,6 +54,9 @@ pub enum WasmCredentialClientError {
5554
#[from]
5655
source: bip39::Error,
5756
},
57+
58+
#[error("The ticket book cannot be retrieved from the credential store")]
59+
TicketbookCredentialStoreIsNone,
5860
}
5961

6062
wasm_error!(WasmCredentialClientError);

wasm/zk-nym-lib/src/helpers.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,6 @@ pub(crate) fn minimal_coconut_sandbox() -> NymNetworkDetails {
3535
..Default::default()
3636
},
3737
explorer_api: None,
38+
nym_vpn_api_url: None,
3839
}
3940
}

0 commit comments

Comments
 (0)