use zera_proto::zera_txn::SmartContractExecuteTxn;
use crate::error::{Result, ZeraError};
use crate::grpc::{UnaryTransport, ValidatorApiClient};
use crate::smart_contracts::send_smart_contract_execute_txn;
use super::super::types::{DexOptions, SwapOptions};
use super::super::utils::{
create_dex_transaction_with_client, fee_id_or_default, resolve_amount_with_client,
validate_signing_inputs,
};
pub async fn swap(
swap_options: SwapOptions,
public_key_base58_identifier: &str,
private_key_base58: &str,
options: DexOptions,
) -> Result<SmartContractExecuteTxn> {
let client = ValidatorApiClient::new(options.grpc_config.clone().unwrap_or_default())?;
swap_with_client(
swap_options,
public_key_base58_identifier,
private_key_base58,
options,
&client,
)
.await
}
pub async fn swap_with_client<T>(
swap_options: SwapOptions,
public_key_base58_identifier: &str,
private_key_base58: &str,
options: DexOptions,
client: &ValidatorApiClient<T>,
) -> Result<SmartContractExecuteTxn>
where
T: UnaryTransport,
{
validate_signing_inputs(public_key_base58_identifier, private_key_base58)?;
if swap_options.token_in.is_empty() {
return Err(ZeraError::Validation("tokenIn is required".to_string()));
}
if swap_options.token_out.is_empty() {
return Err(ZeraError::Validation("tokenOut is required".to_string()));
}
if swap_options.amount_in.is_empty() {
return Err(ZeraError::Validation("amountIn is required".to_string()));
}
let amount_in_parts =
resolve_amount_with_client(&swap_options.amount_in, &swap_options.token_in, client).await?;
let platform_fee_address = swap_options.platform_fee_address.unwrap_or_default();
let parameter_value = format!(
"{},{},{},{},{},{}",
swap_options.token_in,
swap_options.token_out,
amount_in_parts,
swap_options.fee_rate,
swap_options.platform_fee_bps,
platform_fee_address
);
let mut create_options = options;
create_options.fee_id = Some(fee_id_or_default(&create_options));
create_dex_transaction_with_client(
"swap",
parameter_value,
public_key_base58_identifier,
private_key_base58,
create_options,
client,
)
.await
}
pub async fn swap_and_send(
swap_options: SwapOptions,
public_key_base58_identifier: &str,
private_key_base58: &str,
options: DexOptions,
) -> Result<String> {
let grpc_config = options.grpc_config.clone();
let txn = swap(
swap_options,
public_key_base58_identifier,
private_key_base58,
options,
)
.await?;
send_smart_contract_execute_txn(&txn, grpc_config).await
}