zera-sdk 0.1.0

Rust SDK for ZERA transactions, validator APIs, and bridge workflows
Documentation
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::{CreateLiquidityPoolOptions, DexOptions};
use super::super::utils::{
    compute_lock_timestamp, create_dex_transaction_with_client, fee_id_or_default,
    resolve_amount_with_client, validate_signing_inputs,
};

pub async fn create_liquidity_pool(
    pool: CreateLiquidityPoolOptions,
    public_key_base58_identifier: &str,
    private_key_base58: &str,
    options: DexOptions,
) -> Result<SmartContractExecuteTxn> {
    let client = ValidatorApiClient::new(options.grpc_config.clone().unwrap_or_default())?;
    create_liquidity_pool_with_client(
        pool,
        public_key_base58_identifier,
        private_key_base58,
        options,
        &client,
    )
    .await
}

pub async fn create_liquidity_pool_with_client<T>(
    pool: CreateLiquidityPoolOptions,
    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 pool.token_a.is_empty() {
        return Err(ZeraError::Validation("tokenA is required".to_string()));
    }
    if pool.token_b.is_empty() {
        return Err(ZeraError::Validation("tokenB is required".to_string()));
    }
    if pool.amount_a.is_empty() {
        return Err(ZeraError::Validation("amountA is required".to_string()));
    }
    if pool.amount_b.is_empty() {
        return Err(ZeraError::Validation("amountB is required".to_string()));
    }

    let amount_a_parts = resolve_amount_with_client(&pool.amount_a, &pool.token_a, client).await?;
    let amount_b_parts = resolve_amount_with_client(&pool.amount_b, &pool.token_b, client).await?;

    let lock_timestamp = compute_lock_timestamp(pool.lock_duration);
    let parameter_value = format!(
        "{},{},{},{},{},{}",
        pool.token_a, pool.token_b, amount_a_parts, amount_b_parts, pool.fee_rate, lock_timestamp
    );
    let mut create_options = options;
    create_options.fee_id = Some(fee_id_or_default(&create_options));

    create_dex_transaction_with_client(
        "create_liquidity_pool",
        parameter_value,
        public_key_base58_identifier,
        private_key_base58,
        create_options,
        client,
    )
    .await
}

pub async fn create_liquidity_pool_and_send(
    pool: CreateLiquidityPoolOptions,
    public_key_base58_identifier: &str,
    private_key_base58: &str,
    options: DexOptions,
) -> Result<String> {
    let grpc_config = options.grpc_config.clone();
    let txn = create_liquidity_pool(
        pool,
        public_key_base58_identifier,
        private_key_base58,
        options,
    )
    .await?;
    send_smart_contract_execute_txn(&txn, grpc_config).await
}