zera-sdk 0.1.0

Rust SDK for ZERA transactions, validator APIs, and bridge workflows
Documentation
use zera_proto::zera_txn::{CoinDenomination, ContractType};
use zera_sdk::{
    build_contract_txn, build_contract_update_txn, build_smart_contract_execute_txn,
    build_vote_txn, BuildContractOptions, BuildSmartContractExecuteOptions, BuildVoteTxnOptions,
    UpdateContractOptions,
};

fn dummy_coin_denomination() -> CoinDenomination {
    CoinDenomination {
        denomination_name: "ZRA".to_string(),
        amount: "1000000000".to_string(),
    }
}

#[tokio::test]
async fn build_vote_txn_validation_matches_js_contract() {
    assert!(build_vote_txn(
        "",
        "aabb",
        "pk",
        BuildVoteTxnOptions {
            support: Some(true),
            ..Default::default()
        }
    )
    .await
    .unwrap_err()
    .to_string()
    .contains("contractId is required"));

    assert!(build_vote_txn(
        "$ZRA+0000",
        "",
        "pk",
        BuildVoteTxnOptions {
            support: Some(true),
            ..Default::default()
        }
    )
    .await
    .unwrap_err()
    .to_string()
    .contains("proposalId (hex) is required"));

    assert!(build_vote_txn(
        "$ZRA+0000",
        "aabb",
        "",
        BuildVoteTxnOptions {
            support: Some(true),
            ..Default::default()
        }
    )
    .await
    .unwrap_err()
    .to_string()
    .contains("publicKey identifier is required"));

    assert!(build_vote_txn(
        "$ZRA+0000",
        "aabb",
        "pk",
        BuildVoteTxnOptions {
            support: Some(true),
            support_option: Some(2),
            ..Default::default()
        }
    )
    .await
    .unwrap_err()
    .to_string()
    .contains("Specify exactly one of"));

    assert!(
        build_vote_txn("$ZRA+0000", "aabb", "pk", BuildVoteTxnOptions::default())
            .await
            .unwrap_err()
            .to_string()
            .contains("Specify exactly one of")
    );

    assert!(build_vote_txn(
        "$ZRA+0000",
        "xyz",
        "pk",
        BuildVoteTxnOptions {
            support: Some(true),
            ..Default::default()
        }
    )
    .await
    .unwrap_err()
    .to_string()
    .contains("Invalid proposalId"));
}

#[tokio::test]
async fn build_contract_txn_validation_matches_js_contract() {
    assert!(build_contract_txn(BuildContractOptions {
        contract_version: 0,
        symbol: "T".to_string(),
        name: "Test".to_string(),
        contract_type: ContractType::Token,
        contract_id: "bad".to_string(),
        public_key_base58_identifier: "pk".to_string(),
        private_key_base58: String::new(),
        governance: None,
        restricted_keys: vec![],
        max_supply: None,
        contract_fees: None,
        premint_wallets: vec![],
        coin_denomination: dummy_coin_denomination(),
        custom_parameters: vec![],
        expense_ratio: vec![],
        update_contract_fees: None,
        update_expense_ratio: None,
        quash_threshold: None,
        token_compliance: vec![],
        kyc_status: None,
        immutable_kyc_status: None,
        max_supply_release: vec![],
        fee_id: None,
        fee_amount_parts: None,
        memo: None,
        grpc_config: None,
        nonce: None,
    })
    .await
    .unwrap_err()
    .to_string()
    .contains("ContractId must be provided"));

    assert!(build_contract_txn(BuildContractOptions {
        contract_version: 0,
        symbol: String::new(),
        name: "Test".to_string(),
        contract_type: ContractType::Token,
        contract_id: "$TST+0000".to_string(),
        public_key_base58_identifier: "pk".to_string(),
        private_key_base58: String::new(),
        governance: None,
        restricted_keys: vec![],
        max_supply: None,
        contract_fees: None,
        premint_wallets: vec![],
        coin_denomination: dummy_coin_denomination(),
        custom_parameters: vec![],
        expense_ratio: vec![],
        update_contract_fees: None,
        update_expense_ratio: None,
        quash_threshold: None,
        token_compliance: vec![],
        kyc_status: None,
        immutable_kyc_status: None,
        max_supply_release: vec![],
        fee_id: None,
        fee_amount_parts: None,
        memo: None,
        grpc_config: None,
        nonce: None,
    })
    .await
    .unwrap_err()
    .to_string()
    .contains("Symbol must be provided"));

    assert!(build_contract_txn(BuildContractOptions {
        contract_version: 0,
        symbol: "TST".to_string(),
        name: "Test".to_string(),
        contract_type: ContractType::Token,
        contract_id: "$TST+0000".to_string(),
        public_key_base58_identifier: String::new(),
        private_key_base58: String::new(),
        governance: None,
        restricted_keys: vec![],
        max_supply: None,
        contract_fees: None,
        premint_wallets: vec![],
        coin_denomination: dummy_coin_denomination(),
        custom_parameters: vec![],
        expense_ratio: vec![],
        update_contract_fees: None,
        update_expense_ratio: None,
        quash_threshold: None,
        token_compliance: vec![],
        kyc_status: None,
        immutable_kyc_status: None,
        max_supply_release: vec![],
        fee_id: None,
        fee_amount_parts: None,
        memo: None,
        grpc_config: None,
        nonce: None,
    })
    .await
    .unwrap_err()
    .to_string()
    .contains("Public key identifier is required"));
}

#[tokio::test]
async fn build_contract_update_txn_validation_matches_js_contract() {
    assert!(build_contract_update_txn(UpdateContractOptions {
        contract_id: "bad".to_string(),
        contract_version: 1,
        public_key_base58_identifier: "pk".to_string(),
        private_key_base58: String::new(),
        name: None,
        governance: None,
        restricted_keys: vec![],
        contract_fees: None,
        custom_parameters: vec![],
        expense_ratio: vec![],
        token_compliance: vec![],
        kyc_status: None,
        immutable_kyc_status: None,
        quash_threshold: None,
        fee_id: None,
        fee_amount_parts: None,
        memo: None,
        grpc_config: None,
        nonce: None,
    })
    .await
    .unwrap_err()
    .to_string()
    .contains("ContractId must be provided"));

    assert!(build_contract_update_txn(UpdateContractOptions {
        contract_id: "$TST+0000".to_string(),
        contract_version: 0,
        public_key_base58_identifier: "pk".to_string(),
        private_key_base58: String::new(),
        name: None,
        governance: None,
        restricted_keys: vec![],
        contract_fees: None,
        custom_parameters: vec![],
        expense_ratio: vec![],
        token_compliance: vec![],
        kyc_status: None,
        immutable_kyc_status: None,
        quash_threshold: None,
        fee_id: None,
        fee_amount_parts: None,
        memo: None,
        grpc_config: None,
        nonce: None,
    })
    .await
    .unwrap_err()
    .to_string()
    .contains("at least 1"));

    assert!(build_contract_update_txn(UpdateContractOptions {
        contract_id: "$TST+0000".to_string(),
        contract_version: 1,
        public_key_base58_identifier: String::new(),
        private_key_base58: String::new(),
        name: None,
        governance: None,
        restricted_keys: vec![],
        contract_fees: None,
        custom_parameters: vec![],
        expense_ratio: vec![],
        token_compliance: vec![],
        kyc_status: None,
        immutable_kyc_status: None,
        quash_threshold: None,
        fee_id: None,
        fee_amount_parts: None,
        memo: None,
        grpc_config: None,
        nonce: None,
    })
    .await
    .unwrap_err()
    .to_string()
    .contains("Public key identifier is required"));
}

#[tokio::test]
async fn build_smart_contract_execute_validation_matches_js_contract() {
    assert!(build_smart_contract_execute_txn(
        "",
        0,
        "fn",
        &[],
        "pk",
        BuildSmartContractExecuteOptions::default(),
    )
    .await
    .unwrap_err()
    .to_string()
    .contains("smartContractName is required"));

    assert!(build_smart_contract_execute_txn(
        "sc",
        0,
        "",
        &[],
        "pk",
        BuildSmartContractExecuteOptions::default(),
    )
    .await
    .unwrap_err()
    .to_string()
    .contains("functionName is required"));

    assert!(build_smart_contract_execute_txn(
        "sc",
        0,
        "fn",
        &[],
        "",
        BuildSmartContractExecuteOptions::default(),
    )
    .await
    .unwrap_err()
    .to_string()
    .contains("publicKeyBase58Identifier is required"));
}