terra_rust_api/client/
market.rs1use crate::client::core_types::Coin;
2
3use crate::{LCDResult, Message, Terra};
4use rust_decimal::Decimal;
5
6use crate::messages::market::MsgSwap;
7use futures::future::join_all;
8
9pub struct Market<'a> {
11 terra: &'a Terra,
12}
13impl Market<'_> {
14 pub fn create(terra: &'_ Terra) -> Market<'_> {
15 Market { terra }
16 }
17 pub async fn swap(&self, offer: &Coin, ask_denom: &str) -> anyhow::Result<LCDResult<Coin>> {
19 let response = self
20 .terra
21 .send_cmd::<LCDResult<Coin>>(
22 "/market/swap",
23 Some(&format!("?offer_coin={}&ask_denom={}", offer, ask_denom)),
24 )
25 .await?;
26 Ok(response)
27 }
28 pub async fn generate_sweep_messages(
30 &self,
31 from: String,
32 to_coin: String,
33 threshold: Decimal,
34 ) -> anyhow::Result<Vec<Message>> {
35 let account_balances = self.terra.bank().balances(&from).await?;
36 let potential_coins = account_balances
37 .result
38 .into_iter()
39 .filter(|c| c.denom != to_coin);
40 let into_currency_futures = potential_coins
42 .into_iter()
43 .map(|c| async {
44 let resp = self
45 .terra
46 .market()
47 .swap(&c.clone(), &to_coin)
48 .await
49 .map(|f| (c, f.result));
50 resp
51 })
52 .collect::<Vec<_>>();
53
54 let into_currency = join_all(into_currency_futures).await;
55
56 let mut err = None;
57 let to_convert = &into_currency
58 .into_iter()
59 .flat_map(|f| match f {
60 Ok(coins) => {
61 if coins.1.amount > threshold {
62 Some(coins)
63 } else {
64 None
65 }
66 }
67 Err(e) => {
68 eprintln!("Error {}", e);
69 err = Some(e);
70 None
71 }
72 })
73 .collect::<Vec<_>>();
74 match err {
75 Some(e) => Err(e),
76 None => {
77 let mut messages = Vec::new();
78 for swap_coins in to_convert {
79 let message =
80 MsgSwap::create(swap_coins.0.clone(), to_coin.clone(), from.clone())?;
81 messages.push(message);
82 }
83 Ok(messages)
84 }
85 }
86 }
87}