Files
AstralRinth/packages/muralpay/src/account.rs
aecsocket 9aa06fbc26 Fix Mural payout status syncing (#4853)
* Fix Mural payout status syncing

* Make Mural payout code more resilient

* prepare sqlx

* fix test
2025-12-08 20:34:41 +00:00

237 lines
6.9 KiB
Rust

use {
crate::{Blockchain, FiatAmount, TokenAmount, WalletDetails},
chrono::{DateTime, Utc},
derive_more::{Deref, Display},
rust_decimal::Decimal,
serde::{Deserialize, Serialize},
std::str::FromStr,
uuid::Uuid,
};
#[cfg(feature = "client")]
const _: () = {
use crate::{MuralError, RequestExt};
impl crate::Client {
pub async fn get_all_accounts(&self) -> Result<Vec<Account>, MuralError> {
maybe_mock!(self, get_all_accounts());
self.http_get(|base| format!("{base}/api/accounts"))
.send_mural()
.await
}
pub async fn get_account(&self, id: AccountId) -> Result<Account, MuralError> {
maybe_mock!(self, get_account(id));
self.http_get(|base| format!("{base}/api/accounts/{id}"))
.send_mural()
.await
}
pub async fn create_account(
&self,
name: impl AsRef<str>,
description: Option<impl AsRef<str>>,
) -> Result<Account, MuralError> {
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
struct Body<'a> {
name: &'a str,
description: Option<&'a str>,
}
maybe_mock!(
self,
create_account(name.as_ref(), description.as_ref().map(AsRef::as_ref))
);
let body = Body {
name: name.as_ref(),
description: description.as_ref().map(AsRef::as_ref),
};
self.http_post(|base| format!("{base}/api/accounts"))
.json(&body)
.send_mural()
.await
}
}
};
#[derive(Debug, Display, Clone, Copy, PartialEq, Eq, Hash, Deref, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[display("{}", _0.hyphenated())]
pub struct AccountId(pub Uuid);
impl FromStr for AccountId {
type Err = <Uuid as FromStr>::Err;
fn from_str(s: &str) -> Result<Self, Self::Err> {
s.parse::<Uuid>().map(Self)
}
}
impl From<AccountId> for Uuid {
fn from(value: AccountId) -> Self {
value.0
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(rename_all = "camelCase")]
pub struct Account {
pub id: AccountId,
pub name: String,
pub description: Option<String>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub is_api_enabled: bool,
pub status: AccountStatus,
pub account_details: Option<AccountDetails>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum AccountStatus {
Initializing,
Active,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(rename_all = "camelCase")]
pub struct AccountDetails {
pub wallet_details: WalletDetails,
pub balances: Vec<TokenAmount>,
pub payin_methods: Vec<PayinMethod>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(rename_all = "camelCase")]
pub struct PayinMethod {
pub status: PayinMethodStatus,
pub supported_destination_tokens: Vec<DestinationToken>,
pub payin_rail_details: PayinRailDetails,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum PayinMethodStatus {
Activated,
Deactivated,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(rename_all = "camelCase")]
pub struct DestinationToken {
pub fees: Fees,
pub token: Token,
pub transaction_minimum: Option<FiatAmount>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(rename_all = "camelCase")]
pub struct Fees {
#[serde(with = "rust_decimal::serde::float")]
pub variable_fee_percentage: Decimal,
pub fixed_transaction_fee: Option<FiatAmount>,
#[serde(with = "rust_decimal::serde::float_option", default)]
pub developer_fee_percentage: Option<Decimal>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(rename_all = "camelCase")]
pub struct Token {
pub symbol: String,
pub blockchain: Blockchain,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum PayinRailDetails {
#[serde(rename_all = "camelCase")]
Usd {
currency: UsdCurrency,
payin_rails: Vec<String>,
bank_beneficiary_name: String,
bank_beneficiary_address: String,
bank_name: String,
bank_address: String,
bank_routing_number: String,
bank_account_number: String,
},
#[serde(rename_all = "camelCase")]
Eur {
currency: EurCurrency,
payin_rail: EurPayinRail,
bank_name: String,
bank_address: String,
account_holder_name: String,
iban: String,
bic: String,
},
#[serde(rename_all = "camelCase")]
Cop {
currency: CopCurrency,
payin_rail: CopPayinRail,
},
#[serde(rename_all = "camelCase")]
BlockchainDeposit {
deposit_token: DepositToken,
sender_address: Option<String>,
destination_address: String,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(rename_all = "SCREAMING-KEBAB-CASE")]
pub enum UsdCurrency {
Usd,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(rename_all = "SCREAMING-KEBAB-CASE")]
pub enum EurCurrency {
Eur,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(rename_all = "SCREAMING-KEBAB-CASE")]
pub enum EurPayinRail {
Sepa,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(rename_all = "SCREAMING-KEBAB-CASE")]
pub enum CopCurrency {
Cop,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(rename_all = "SCREAMING-KEBAB-CASE")]
pub enum CopPayinRail {
Pse,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum DepositToken {
#[serde(rename_all = "camelCase")]
UsdtTron { contract_address: String },
}