whisky_provider/maestro/
evaluator.rs1use async_trait::async_trait;
2use whisky_csl::{calculate_tx_hash, TxParser};
3
4use uplc::tx::SlotConfig;
5use whisky_common::models::{Network, UTxO};
6
7use whisky_common::*;
8
9use super::*;
10
11#[derive(Serialize)]
12pub struct AdditionalUtxo {
13 pub tx_hash: String,
14 pub index: u32,
15 pub txout_cbor: String,
16}
17
18#[derive(Serialize)]
19pub struct EvaluateTx {
20 cbor: String,
21 additional_utxos: Vec<AdditionalUtxo>,
22}
23
24#[async_trait]
25impl Evaluator for MaestroProvider {
26 async fn evaluate_tx(
27 &self,
28 tx: &str,
29 _inputs: &[UTxO], additional_txs: &[String],
31 _network: &Network,
32 _slot_config: &SlotConfig,
33 ) -> Result<Vec<Action>, WError> {
34 let tx_out_cbors: Vec<AdditionalUtxo> = additional_txs
35 .iter()
36 .flat_map(|tx| {
37 let parsed_tx = TxParser::new(tx);
38 parsed_tx
39 .unwrap() .get_tx_outs_cbor()
41 .iter()
42 .enumerate() .map(|(index, txout_cbor)| AdditionalUtxo {
44 tx_hash: calculate_tx_hash(tx).unwrap(), index: index as u32, txout_cbor: txout_cbor.to_string(),
47 })
48 .collect::<Vec<AdditionalUtxo>>()
49 })
50 .collect();
51
52 let url = "/transactions/evaluate";
53 let body = EvaluateTx {
54 cbor: tx.to_string(),
55 additional_utxos: tx_out_cbors,
56 };
57
58 let resp = self
59 .maestro_client
60 .post(url, &body)
61 .await
62 .map_err(WError::from_err("Maestro - evaluate_tx"))?;
63
64 let result: Vec<Action> = serde_json::from_str::<Vec<RedeemerEvaluation>>(&resp)
65 .map_err(WError::from_err("Maestro - evaluate_tx"))?
66 .iter()
67 .map(|r: &RedeemerEvaluation| Action {
68 index: r.redeemer_index as u32,
69 budget: Budget {
70 mem: r.ex_units.mem as u64,
71 steps: r.ex_units.steps as u64,
72 },
73 tag: match r.redeemer_tag.as_str() {
74 "spend" => RedeemerTag::Spend,
75 "mint" => RedeemerTag::Mint,
76 "cert" => RedeemerTag::Cert,
77 "wdrl" => RedeemerTag::Reward,
78 _ => panic!("Unknown redeemer tag from maestro service"),
79 },
80 })
81 .collect();
82 Ok(result)
83 }
84}