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