stellar_baselib/
operation.rs1use crate::liquidity_pool_asset::LiquidityPoolAssetBehavior;
3use crate::utils::decode_encode_muxed_account::decode_address_to_muxed_account_fix_for_g_address;
4use crate::xdr;
5use crate::xdr::WriteXdr;
6use num_traits::identities::One;
7use num_traits::ToPrimitive;
8use num_traits::{FromPrimitive, Num, Signed, Zero};
9use std::collections::HashMap;
10use std::hash::Hash;
11use std::str::FromStr;
12use stellar_strkey::ed25519::{MuxedAccount, PublicKey};
13
14use crate::asset::Asset;
15use crate::asset::AssetBehavior;
16use crate::claimant::Claimant;
17use crate::claimant::ClaimantBehavior;
18use crate::liquidity_pool_asset::LiquidityPoolAsset;
19use crate::utils::decode_encode_muxed_account::{
20 decode_address_to_muxed_account, encode_muxed_account_to_address,
21};
22
23pub use super::op_list::set_options::AccountFlags;
24pub use super::op_list::set_trustline_flags::TrustlineFlags;
25
26pub const ONE: i64 = 10_000_000;
27const MAX_INT64: &str = "9223372036854775807";
28pub enum SignerKeyAttrs {
29 Ed25519PublicKey(String),
30 PreAuthTx(String),
31 Sha256Hash(String),
32}
33
34pub struct Operation {
35 pub source: Option<xdr::MuxedAccount>,
36}
37
38#[derive(Debug, PartialEq, Eq)]
39pub enum Error {
40 InvalidField(String),
41 InvalidAmount(i64),
42 InvalidPrice(i32, i32),
43}
44
45impl Operation {
46 pub fn new() -> Self {
47 Self { source: None }
48 }
49
50 pub fn with_source(source: &str) -> Result<Self, Error> {
51 Ok(Self {
52 source: Some(
53 xdr::MuxedAccount::from_str(source)
54 .map_err(|_| Error::InvalidField("source".into()))?,
55 ),
56 })
57 }
58}
59
60impl Default for Operation {
61 fn default() -> Self {
62 Self::new()
63 }
64}
65
66pub fn is_valid_amount(value: &str, allow_zero: bool) -> bool {
68 if !value.is_empty() {
69 if let Ok(amount) = value.parse::<i64>() {
70 if !allow_zero && amount.is_zero() {
71 return false;
72 }
73
74 let max_int64 = i64::MAX;
75 let one = 1i64;
76
77 if amount.is_negative()
78 || amount > max_int64
79 || amount.to_string().chars().filter(|&c| c == '.').count() > 1
80 || amount
81 .to_string()
82 .chars()
83 .skip_while(|&c| c != '.')
84 .skip(1)
85 .count()
86 > 7
87 {
89 return false;
90 }
91
92 return true;
93 }
94 }
95
96 false
97}
98
99pub fn to_xdr_amount(value: &str) -> Result<xdr::Int64, Box<dyn std::error::Error>> {
101 let amount = value.parse::<i64>()?;
102 let one = 1i64;
103 let xdr_amount = amount * one;
104 let xdr_string = xdr_amount.to_string();
105 let xdr_int64 = xdr::Int64::from_str(&xdr_string)?;
106 Ok(xdr_int64)
107}
108
109pub fn from_xdr_amount(value: u64) -> f64 {
110 round_to((value.to_f64().unwrap() / ONE as f64), 7)
112}
113
114pub fn round_to(value: f64, decimal_places: u32) -> f64 {
116 let multiplier = 10f64.powi(decimal_places as i32);
117 (value * multiplier).round() / multiplier
118}
119
120fn account_id_to_address(account_id: &xdr::AccountId) -> String {
121 let xdr::PublicKey::PublicKeyTypeEd25519(val) = account_id.0.clone();
122 let key: Result<PublicKey, stellar_strkey::DecodeError> =
123 PublicKey::from_string(val.to_string().as_str());
124
125 if key.is_ok() {
126 val.to_string()
127 } else {
128 panic!("Invalid account");
129 }
130}
131
132fn convert_xdr_signer_key_to_object(
133 signer_key: &xdr::SignerKeyType,
134) -> Result<SignerKeyAttrs, String> {
135 match signer_key {
136 xdr::SignerKeyType::Ed25519 => {
137 let ed25519_public_key = PublicKey::from_string(signer_key.to_string().as_str())
138 .unwrap()
139 .to_string();
140 Ok(SignerKeyAttrs::Ed25519PublicKey(ed25519_public_key))
141 }
142 xdr::SignerKeyType::PreAuthTx => Ok(SignerKeyAttrs::PreAuthTx(
143 signer_key.to_xdr_base64(xdr::Limits::none()).unwrap(),
144 )),
145 xdr::SignerKeyType::HashX => Ok(SignerKeyAttrs::Sha256Hash(
146 signer_key.to_xdr_base64(xdr::Limits::none()).unwrap(),
147 )),
148 _ => panic!("Invalid Type"),
149 }
150}