balius_runtime/ledgers/
u5c.rs

1use serde::{Deserialize, Serialize};
2use utxorpc::CardanoQueryClient;
3
4use crate::wit::balius::app::ledger as wit;
5
6impl From<utxorpc::Error> for crate::Error {
7    fn from(error: utxorpc::Error) -> Self {
8        crate::Error::Ledger(error.to_string())
9    }
10}
11
12impl From<utxorpc::Error> for wit::LedgerError {
13    fn from(error: utxorpc::Error) -> Self {
14        wit::LedgerError::Upstream(error.to_string())
15    }
16}
17
18impl From<wit::TxoRef> for utxorpc::spec::query::TxoRef {
19    fn from(value: wit::TxoRef) -> Self {
20        utxorpc::spec::query::TxoRef {
21            hash: value.tx_hash.into(),
22            index: value.tx_index,
23        }
24    }
25}
26
27impl From<utxorpc::spec::query::TxoRef> for wit::TxoRef {
28    fn from(value: utxorpc::spec::query::TxoRef) -> Self {
29        wit::TxoRef {
30            tx_hash: value.hash.into(),
31            tx_index: value.index,
32        }
33    }
34}
35
36impl From<utxorpc::ChainUtxo<utxorpc::spec::cardano::TxOutput>> for wit::Utxo {
37    fn from(value: utxorpc::ChainUtxo<utxorpc::spec::cardano::TxOutput>) -> Self {
38        wit::Utxo {
39            body: value.native.into(),
40            ref_: value.txo_ref.unwrap_or_default().into(),
41        }
42    }
43}
44
45impl From<wit::AddressPattern> for utxorpc::spec::cardano::AddressPattern {
46    fn from(value: wit::AddressPattern) -> Self {
47        utxorpc::spec::cardano::AddressPattern {
48            exact_address: value.exact_address.into(),
49            ..Default::default()
50        }
51    }
52}
53
54impl From<wit::AssetPattern> for utxorpc::spec::cardano::AssetPattern {
55    fn from(value: wit::AssetPattern) -> Self {
56        utxorpc::spec::cardano::AssetPattern {
57            policy_id: value.policy.into(),
58            asset_name: value.name.map(|n| n.into()).unwrap_or_default(),
59        }
60    }
61}
62
63impl From<wit::UtxoPattern> for utxorpc::spec::cardano::TxOutputPattern {
64    fn from(value: wit::UtxoPattern) -> Self {
65        utxorpc::spec::cardano::TxOutputPattern {
66            address: value.address.map(|a| a.into()),
67            asset: value.asset.map(|a| a.into()),
68        }
69    }
70}
71
72impl From<utxorpc::UtxoPage<utxorpc::Cardano>> for wit::UtxoPage {
73    fn from(value: utxorpc::UtxoPage<utxorpc::Cardano>) -> Self {
74        wit::UtxoPage {
75            utxos: value.items.into_iter().map(|u| u.into()).collect(),
76            next_token: value.next,
77        }
78    }
79}
80
81#[derive(Clone, Serialize, Deserialize, Debug)]
82pub struct Config {
83    pub endpoint_url: String,
84    pub api_key: String,
85}
86
87#[derive(Clone)]
88pub struct Ledger {
89    queries: utxorpc::CardanoQueryClient,
90}
91
92impl Ledger {
93    pub async fn new(config: Config) -> Result<Self, crate::Error> {
94        let queries = utxorpc::ClientBuilder::new()
95            .uri(&config.endpoint_url)?
96            .metadata("dmtr-api-key", config.api_key)?
97            .build::<CardanoQueryClient>()
98            .await;
99
100        Ok(Self { queries })
101    }
102
103    pub async fn read_utxos(
104        &mut self,
105        refs: Vec<wit::TxoRef>,
106    ) -> Result<Vec<wit::Utxo>, wit::LedgerError> {
107        let refs = refs.into_iter().map(|r| r.into()).collect();
108        let utxos = self.queries.read_utxos(refs).await?;
109        Ok(utxos.into_iter().map(|u| u.into()).collect())
110    }
111
112    pub async fn search_utxos(
113        &mut self,
114        pattern: wit::UtxoPattern,
115        start: Option<String>,
116        max_items: u32,
117    ) -> Result<wit::UtxoPage, wit::LedgerError> {
118        let pattern = pattern.into();
119        let utxos = self.queries.match_utxos(pattern, start, max_items).await?;
120        Ok(utxos.into())
121    }
122
123    pub async fn read_params(&mut self) -> Result<wit::Json, wit::LedgerError> {
124        let req = utxorpc::spec::query::ReadParamsRequest::default();
125        let res = self
126            .queries
127            .read_params(req)
128            .await
129            .map_err(|err| wit::LedgerError::Upstream(format!("{:?}", err)))?
130            .into_inner();
131
132        let params = res
133            .values
134            .and_then(|v| v.params)
135            .ok_or(wit::LedgerError::Upstream(
136                "unexpected response from read_params".to_string(),
137            ))?;
138
139        match params {
140            utxorpc::spec::query::any_chain_params::Params::Cardano(params) => {
141                Ok(serde_json::to_vec(&params).unwrap())
142            }
143            _ => Err(wit::LedgerError::Upstream(
144                "unexpected response from read_params".to_string(),
145            )),
146        }
147    }
148}