#[cfg(feature = "sign")]
use crate::account::keys::ApiKey;
use crate::client::Network;
#[cfg(feature = "sign")]
use crate::client::{Client, Http, SendError, Sent};
use crate::transfer::send::{MAX_AMOUNT, halves};
use crate::utils::json::Json;
use crate::utils::sign::goldilocks::Fp;
use crate::utils::sign::tx::{BadTx, Tx, TxType, element, number};
use crate::utils::units::{BadUnits, exact_units};
use crate::utils::{AssetId, Dec, Route};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Withdraw {
pub asset: AssetId,
pub route: Route,
pub amount: u64,
}
impl Withdraw {
pub fn new(asset: AssetId, decimals: u32, route: Route, amount: Dec) -> Result<Withdraw, BadUnits> {
Ok(Withdraw { asset, route, amount: exact_units(amount, decimals, MAX_AMOUNT)? })
}
pub fn collateral(network: Network, amount: Dec) -> Result<Withdraw, BadUnits> {
let collateral = network.collateral();
Withdraw::new(collateral.asset, collateral.decimals, Route::Perps, amount)
}
}
impl Tx for Withdraw {
fn tx_type(&self) -> TxType {
TxType::Withdraw
}
fn hash_fields(&self) -> Vec<Fp> {
let mut fields = vec![element(self.asset.get()), element(self.route.code())];
fields.extend(halves(self.amount));
fields
}
fn info_fields(&self) -> Vec<(&'static str, Json)> {
vec![
("AssetIndex", number(self.asset.get())),
("RouteType", number(self.route.code())),
("Amount", number(self.amount)),
]
}
fn account_key(&self) -> &'static str {
"FromAccountIndex"
}
fn check(&self) -> Result<(), BadTx> {
if self.amount == 0 {
return Err(BadTx::new("Amount", "a withdrawal moves at least 1 unit (WithdrawalAmountTooLow)"));
}
if self.amount > MAX_AMOUNT {
return Err(BadTx::new("Amount", "a withdrawal moves at most 2^60 - 1 units"));
}
Ok(())
}
}
#[cfg(feature = "sign")]
pub async fn withdraw<H: Http>(client: &Client<H, ApiKey>, amount: Dec) -> Result<Sent, SendError> {
let withdraw = Withdraw::collateral(client.network(), amount)
.map_err(|error| crate::transfer::send::refused_units("Amount", &error))?;
client.send(&withdraw).await
}
#[cfg(test)]
#[path = "tests/withdraw.rs"]
mod tests;