nym_credential_proxy_lib/shared_state/
required_deposit_cache.rs

1// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
2// SPDX-License-Identifier: GPL-3.0-only
3
4use crate::error::CredentialProxyError;
5use crate::shared_state::nyxd_client::ChainClient;
6use nym_validator_client::nyxd::Coin;
7use nym_validator_client::nyxd::contract_traits::EcashQueryClient;
8use std::sync::Arc;
9use time::OffsetDateTime;
10use tokio::sync::RwLock;
11
12pub struct CachedDeposit {
13    valid_until: OffsetDateTime,
14    required_amount: Coin,
15}
16
17impl CachedDeposit {
18    const MAX_VALIDITY: time::Duration = time::Duration::MINUTE;
19
20    fn is_valid(&self) -> bool {
21        self.valid_until > OffsetDateTime::now_utc()
22    }
23
24    fn update(&mut self, required_amount: Coin) {
25        self.valid_until = OffsetDateTime::now_utc() + Self::MAX_VALIDITY;
26        self.required_amount = required_amount;
27    }
28}
29
30impl Default for CachedDeposit {
31    fn default() -> Self {
32        CachedDeposit {
33            valid_until: OffsetDateTime::UNIX_EPOCH,
34            required_amount: Coin {
35                amount: u128::MAX,
36                denom: "unym".to_string(),
37            },
38        }
39    }
40}
41
42#[derive(Clone, Default)]
43pub struct RequiredDepositCache {
44    inner: Arc<RwLock<CachedDeposit>>,
45}
46
47impl RequiredDepositCache {
48    pub async fn get_or_update(
49        &self,
50        chain_client: &ChainClient,
51    ) -> Result<Coin, CredentialProxyError> {
52        let read_guard = self.inner.read().await;
53        if read_guard.is_valid() {
54            return Ok(read_guard.required_amount.clone());
55        }
56
57        // update cache
58        drop(read_guard);
59        let mut write_guard = self.inner.write().await;
60        let deposit_amount = chain_client
61            .query_chain()
62            .await
63            .get_required_deposit_amount()
64            .await?;
65
66        let nym_coin: Coin = deposit_amount.into();
67
68        write_guard.update(nym_coin.clone());
69        Ok(nym_coin)
70    }
71}