1
0
Files
AstralRinth/packages/muralpay/src/transaction.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

139 lines
4.2 KiB
Rust

use std::str::FromStr;
use chrono::{DateTime, Utc};
use derive_more::{Deref, Display};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use crate::{AccountId, Blockchain, FiatAmount, PayoutId, PayoutRequestId, TokenAmount};
#[cfg(feature = "client")]
const _: () = {
use crate::{Account, MuralError, RequestExt, SearchParams, SearchResponse};
impl crate::Client {
pub async fn get_transaction(&self, id: TransactionId) -> Result<Transaction, MuralError> {
maybe_mock!(self, get_transaction(id));
self.http_get(|base| format!("{base}/api/transactions/{id}"))
.send_mural()
.await
}
pub async fn search_transactions(
&self,
account_id: AccountId,
params: Option<SearchParams<AccountId>>,
) -> Result<SearchResponse<AccountId, Account>, MuralError> {
maybe_mock!(self, search_transactions(account_id, params));
self.http_post(|base| format!("{base}/api/transactions/search/account/{account_id}"))
.query(&params.map(|p| p.to_query()).unwrap_or_default())
.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 TransactionId(pub Uuid);
impl FromStr for TransactionId {
type Err = <Uuid as FromStr>::Err;
fn from_str(s: &str) -> Result<Self, Self::Err> {
s.parse::<Uuid>().map(Self)
}
}
impl From<TransactionId> for Uuid {
fn from(value: TransactionId) -> Self {
value.0
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(rename_all = "camelCase")]
pub struct Transaction {
pub id: TransactionId,
pub hash: String,
pub transaction_execution_date: DateTime<Utc>,
pub memo: Option<String>,
pub blockchain: Blockchain,
pub amount: TokenAmount,
pub account_id: AccountId,
// pub counterparty_info,
pub transaction_details: TransactionDetails,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum TransactionDetails {
#[serde(rename_all = "camelCase")]
Payout {
payout_request_id: PayoutRequestId,
payout_id: PayoutId,
},
#[serde(rename_all = "camelCase")]
Deposit { details: DepositDetails },
#[serde(rename_all = "camelCase")]
ExternalPayout { recipient_wallet_address: String },
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum DepositDetails {
#[serde(rename_all = "camelCase")]
Fiat {
deposit_id: Uuid,
created_at: DateTime<Utc>,
sent_fiat_amount: FiatAmount,
sender_metadata: Option<SenderMetadata>,
deposit_status_info: DepositStatus,
},
#[serde(rename_all = "camelCase")]
Blockchain {
sender_address: String,
blockchain: Blockchain,
},
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum SenderMetadata {
#[serde(rename_all = "camelCase")]
Ach {
ach_routing_number: String,
sender_name: String,
description: Option<String>,
trace_number: String,
},
#[serde(rename_all = "camelCase")]
Wire {
wire_routing_number: String,
sender_name: Option<String>,
bank_name: String,
bank_beneficiary_name: String,
imad: String,
},
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum DepositStatus {
#[serde(rename_all = "camelCase")]
AwaitingFunds,
#[serde(rename_all = "camelCase")]
Completed {
initiated_at: DateTime<Utc>,
completed_at: DateTime<Utc>,
},
}