equanetwork-cli 0.0.4

The Equa Network command line interface
//! Shared helpers for building Equa Network instruction transactions.

use anyhow::{anyhow, Result};
use equanetwork::{get_network_address, get_vault_address};
use solana_address::Address;
use solana_client::rpc_client::RpcClient;
use solana_instruction::Instruction;
use solana_pubkey::Pubkey;
use solana_signer::Signer;
use spl_associated_token_account_interface::{
    address::get_associated_token_address, instruction::create_associated_token_account_idempotent,
};

pub fn pk(address: Address) -> Pubkey {
    Pubkey::new_from_array(address.to_bytes())
}

pub fn addr(pubkey: Pubkey) -> Address {
    Address::new_from_array(pubkey.to_bytes())
}

pub fn account_exists(rpc: &RpcClient, account: &Pubkey) -> bool {
    rpc.get_account(account).is_ok()
}

pub fn ensure_ata(
    rpc: &RpcClient,
    ixs: &mut Vec<Instruction>,
    payer: &impl Signer,
    owner: &Pubkey,
    mint: &Pubkey,
) -> Pubkey {
    let ata = get_associated_token_address(owner, mint);
    if !account_exists(rpc, &ata) {
        ixs.push(create_associated_token_account_idempotent(
            &payer.pubkey(),
            owner,
            mint,
            &spl_token_interface::ID,
        ));
    }
    ata
}

pub fn require_signer(config: &crate::config::Config) -> Result<solana_keypair::Keypair> {
    config
        .keypair()
        .ok_or_else(|| anyhow!("signer required (set --signer or Solana CLI config keypair)"))
}

/// Parse a `u32` network id from decimal or hex (`0x…` / bare hex).
pub fn parse_network_id(raw: &str) -> Result<u32> {
    let trimmed = raw.trim();
    if let Some(hex) = trimmed
        .strip_prefix("0x")
        .or_else(|| trimmed.strip_prefix("0X"))
    {
        return u32::from_str_radix(hex, 16).map_err(|e| anyhow!("invalid network-id hex: {e}"));
    }
    if trimmed.chars().all(|c| c.is_ascii_hexdigit())
        && trimmed.chars().any(|c| matches!(c, 'a'..='f' | 'A'..='F'))
        && !trimmed.chars().all(|c| c.is_ascii_digit())
    {
        return u32::from_str_radix(trimmed, 16)
            .map_err(|e| anyhow!("invalid network-id hex: {e}"));
    }
    trimmed
        .parse::<u32>()
        .map_err(|e| anyhow!("network-id must be a u32 decimal or hex: {e}"))
}

pub fn network_pda(network_id: u32) -> Address {
    get_network_address(network_id).0
}

pub fn vault_pda(network: &Pubkey, mint: &Pubkey) -> Address {
    get_vault_address(&addr(*network), &addr(*mint)).0
}