1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
use crate::errors::SimpleError;
use honeybadger::Auth;
use std::sync::Arc;
use std::time::SystemTime;

/// Exchange rate as sats per major unit accompanied by the specific currency code and time the rate was updated at.
#[derive(PartialEq, Eq, Debug, Clone)]
pub struct ExchangeRate {
    pub currency_code: String,
    pub rate: u32,
    pub updated_at: SystemTime,
}

pub trait ExchangeRateProvider: Send + Sync {
    fn query_all_exchange_rates(&self) -> Result<Vec<ExchangeRate>, SimpleError>;
}

pub(crate) struct ExchangeRateProviderImpl {
    provider: chameleon::ExchangeRateProvider,
}

impl ExchangeRateProviderImpl {
    pub fn new(graphql_url: String, auth: Arc<Auth>) -> Self {
        let provider = chameleon::ExchangeRateProvider::new(graphql_url, auth);
        Self { provider }
    }
}

impl ExchangeRateProvider for ExchangeRateProviderImpl {
    fn query_all_exchange_rates(&self) -> Result<Vec<ExchangeRate>, SimpleError> {
        Ok(self
            .provider
            .query_all_exchange_rates()
            .map_err(|e| SimpleError::Simple {
                msg: format!("Failed to query exchange rates: {e}"),
            })?
            .into_iter()
            .map(|r| ExchangeRate {
                currency_code: r.currency_code,
                rate: r.sats_per_unit,
                updated_at: r.updated_at,
            })
            .collect())
    }
}