wp-solana-core 0.1.1

Cross-protocol shared core for waterpump-solana: token planning compatibility, error types, system constants.
Documentation
//! Token account utilities for waterpump-solana core.

use solana_account::Account as SolanaAccount;
use spl_token_2022_interface::{
    extension::{transfer_fee::TransferFeeConfig, BaseStateWithExtensions, StateWithExtensions},
    state::Mint,
};
use wp_solana_amm_math::liquidity_math::TransferFee;

pub mod account_planner;
pub mod account_state;
pub mod adapter;
#[cfg(feature = "legacy-wsol-shell")]
pub mod async_shell;

// Re-export so call sites can import from `token::*`.
pub use account_planner::{
    plan_token_account_instructions, TokenAccountInstructions, TokenAccountStrategy,
};
pub use account_state::{MintAndAta, TokenAccountState};

/// Strategy for wrapping native SOL (wSOL) when needed.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum NativeMintWrappingStrategy {
    /// Use Associated Token Account (ATA) for wSOL.
    #[default]
    Ata,
    /// Create a keypair-based token account for wSOL.
    Keypair,
    /// Create a seeded token account for wSOL.
    Seed,
    /// Do not wrap native SOL (treat as regular token).
    None,
}

/// Workspace-wide token-account planning configuration.
///
/// Replaces the previous process-global Mutexes
/// (`NATIVE_MINT_WRAPPING_STRATEGY` and `ENFORCE_TOKEN_BALANCE_CHECK`). Pass an
/// instance explicitly to every planning entry point so that:
///
/// - tests can use distinct configs per test without mutex contention or order
///   coupling
/// - a single process can drive different transactions with different wrapping
///   strategies
/// - call sites visibly declare the policies they're using
///
/// Construct via `WorkspacePlanConfig::default()` (Ata + enforce_balance) or
/// struct literal with `..Default::default()`.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct WorkspacePlanConfig {
    /// How to handle native SOL wrapping for this transaction.
    pub wsol_strategy: NativeMintWrappingStrategy,
    /// Whether non-SOL `WithBalance` strategies should validate balance at plan
    /// time. When `false`, `WithBalance(non_sol, n)` degrades to
    /// `EnsureAtaExists` (the v0.1 silent-drop behavior).
    pub enforce_balance: bool,
}

impl Default for WorkspacePlanConfig {
    /// Defaults: ATA wrapping + enforce non-SOL balance checks.
    fn default() -> Self {
        Self { wsol_strategy: NativeMintWrappingStrategy::Ata, enforce_balance: true }
    }
}

/// Get the current transfer fee for a Token-2022 mint at a specific epoch.
///
/// This function parses the `TransferFeeConfig` extension from a mint account
/// and returns the transfer fee configuration for the specified epoch.
pub fn get_current_transfer_fee(
    mint_info: Option<&SolanaAccount>,
    epoch: u64,
) -> Option<TransferFee> {
    let token_mint_data = &mint_info?.data;
    let token_mint_unpacked = StateWithExtensions::<Mint>::unpack(token_mint_data).ok()?;

    if let Ok(transfer_fee_config) = token_mint_unpacked.get_extension::<TransferFeeConfig>() {
        let fee = transfer_fee_config.get_epoch_fee(epoch);
        return Some(TransferFee {
            fee_bps: fee.transfer_fee_basis_points.into(),
            max_fee: fee.maximum_fee.into(),
        });
    }

    None
}