Skip to main content

nym_bandwidth_controller/
traits.rs

1// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
2// SPDX-License-Identifier: Apache-2.0
3
4use async_trait::async_trait;
5
6use nym_credentials::ecash::bandwidth::serialiser::keys::EpochVerificationKey;
7use nym_credentials::ecash::bandwidth::serialiser::signatures::{
8    AggregatedCoinIndicesSignatures, AggregatedExpirationDateSignatures,
9};
10use nym_credentials_interface::TicketType;
11use nym_crypto::asymmetric::ed25519;
12use nym_ecash_time::{Date, OffsetDateTime};
13use nym_validator_client::nym_api::EpochId;
14
15use crate::{error::BandwidthControllerError, PreparedCredential, PreparedCredentialMetadata};
16
17#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
18#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
19pub trait BandwidthTicketProvider: Send + Sync {
20    async fn get_ecash_ticket(
21        &self,
22        ticket_type: TicketType,
23        gateway_id: ed25519::PublicKey,
24        tickets_to_spend: u32,
25        spend_time: OffsetDateTime,
26    ) -> Result<Option<PreparedCredential>, BandwidthControllerError>;
27
28    async fn get_upgrade_mode_token(&self) -> Result<Option<String>, BandwidthControllerError>;
29
30    async fn attempt_revert_spending(
31        &self,
32        metadata: PreparedCredentialMetadata,
33    ) -> Result<bool, BandwidthControllerError>;
34
35    async fn close(&self);
36}
37
38#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
39#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
40impl<T: BandwidthTicketProvider + ?Sized + Send> BandwidthTicketProvider for Box<T> {
41    async fn get_ecash_ticket(
42        &self,
43        ticket_type: TicketType,
44        gateway_id: ed25519::PublicKey,
45        tickets_to_spend: u32,
46        spend_time: OffsetDateTime,
47    ) -> Result<Option<PreparedCredential>, BandwidthControllerError> {
48        (**self)
49            .get_ecash_ticket(ticket_type, gateway_id, tickets_to_spend, spend_time)
50            .await
51    }
52
53    async fn get_upgrade_mode_token(&self) -> Result<Option<String>, BandwidthControllerError> {
54        (**self).get_upgrade_mode_token().await
55    }
56
57    async fn attempt_revert_spending(
58        &self,
59        metadata: PreparedCredentialMetadata,
60    ) -> Result<bool, BandwidthControllerError> {
61        (**self).attempt_revert_spending(metadata).await
62    }
63
64    // For compatibility for now. Remove once BC is properly implemented in client repo
65    async fn close(&self) {
66        (**self).close().await;
67    }
68}
69
70// This isn't an associated type because
71// a) it would make it dyn-incompatible and we want it
72// b) BandwidthController will pack everything its own variant anyway
73
74/// Error any fetcher implementation may return; the controller wraps it with context.
75pub type FetcherError = Box<dyn std::error::Error + Send + Sync + 'static>;
76
77#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
78#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
79pub trait CredentialPublicDataFetcher: Send + Sync {
80    async fn fetch_master_verification_key(
81        &self,
82        epoch_id: EpochId,
83    ) -> Result<EpochVerificationKey, FetcherError>;
84
85    async fn fetch_coin_index_signatures(
86        &self,
87        epoch_id: EpochId,
88    ) -> Result<AggregatedCoinIndicesSignatures, FetcherError>;
89
90    async fn fetch_expiration_date_signatures(
91        &self,
92        expiration_date: Date,
93        epoch_id: EpochId,
94    ) -> Result<AggregatedExpirationDateSignatures, FetcherError>;
95}