fyuz-sdk 0.1.1

Async Rust client for the Fyuz public REST API — bonding-curve token market data on BNB Smart Chain.
Documentation
//! Where Fyuz is deployed, as compile-time constants.
//!
//! `GET /config` remains the authority: the launchpad sits behind an upgradeable
//! proxy, and a published crate that believed its own copy would keep calling a
//! dead address after a redeploy. What this module is for is the cases the API
//! cannot cover — pinning an address deliberately, forking a chain in a test,
//! reaching BSC testnet (which the public API does not serve at all), and
//! building a transaction when `/config` answers without a `contractAddress`.
//!
//! The data is transcribed from `shared/addresses/*.json` rather than read from
//! it. A published crate has no sibling `shared/` directory, so parsing the JSON
//! at runtime would work here and nowhere else; `include_str!` plus a parse would
//! ship but would turn a typo into a runtime panic instead of a compile error,
//! and would cost a parse per process to learn six addresses that never change
//! without a release. `tests/addresses.rs` asserts every constant below against
//! the JSON and against `shared/test-vectors/addresses.json`, so the
//! transcription cannot drift silently.
//!
//! ```
//! use fyuz::addresses;
//!
//! let bsc = addresses::deployment_for_chain_id(56).expect("mainnet is in the book");
//! assert_eq!(bsc.fyuz, "0x33a98bef6496684a8dac83734d9ceb0cefc7019c");
//! ```

/// One chain's deployment record.
///
/// Every address is the **proxy**, lower-cased. Implementations and proxy admins
/// are deliberately absent: they change under you on an upgrade, and nothing
/// should ever call them directly.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub struct Deployment {
    /// EIP-155 chain id.
    pub chain_id: i64,
    /// Slug used by this crate's trading layer, e.g. `"bsc"`.
    pub network: &'static str,
    /// Human-readable chain name.
    pub name: &'static str,
    /// The slug `GET /config` publishes for this chain, when it publishes one.
    ///
    /// `None` for testnet: the public API's chain list is mainnet-only, so a
    /// testnet build has to come from this book or from an explicit override.
    pub api_network: Option<&'static str>,
    /// The launchpad — the `to` of every swap, and the spender of every approval.
    pub fyuz: &'static str,
    /// Graduates a curve into a DEX pool. Called by [`Deployment::fyuz`], not by
    /// end users; here for completeness.
    pub liquidity_manager: Option<&'static str>,
    /// Fee and reward distribution. Not on any trading path.
    pub distributor: Option<&'static str>,
    /// Native gas currency symbol.
    pub currency: &'static str,
    /// Decimals of the native currency — what [`parse_units`](crate::parse_units)
    /// wants for a BNB amount.
    pub currency_decimals: u32,
    /// A public JSON-RPC endpoint. A default, not an entitlement: it is rate
    /// limited and shared, so configure your own for anything in production.
    pub rpc_url: &'static str,
    /// Block explorer root.
    pub explorer_url: &'static str,
}

/// BNB Smart Chain mainnet, chain id 56.
pub const BSC: Deployment = Deployment {
    chain_id: 56,
    network: "bsc",
    name: "BNB Smart Chain",
    api_network: Some("bsc"),
    fyuz: "0x33a98bef6496684a8dac83734d9ceb0cefc7019c",
    liquidity_manager: Some("0x5220da0b1a778c0d414f082a5ea3670b70d59b00"),
    distributor: Some("0x2c88255f6a80296a3aa8c328e5ff308d74615c7b"),
    currency: "BNB",
    currency_decimals: 18,
    rpc_url: "https://bsc-dataseed.bnbchain.org",
    explorer_url: "https://bscscan.com",
};

/// BNB Smart Chain testnet, chain id 97.
///
/// Its implementation is a different build from mainnet's, so treat testnet
/// behaviour as ahead of or behind production, never identical. No Distributor
/// is deployed there.
pub const BSC_TESTNET: Deployment = Deployment {
    chain_id: 97,
    network: "bsc-testnet",
    name: "BNB Smart Chain Testnet",
    api_network: None,
    fyuz: "0x24febdcc41c804873dbbfe703cd9d2d4b771c236",
    liquidity_manager: Some("0x7a5572709523af016d8b8ce22d6cec49b08a30da"),
    distributor: None,
    currency: "tBNB",
    currency_decimals: 18,
    rpc_url: "https://bsc-testnet-rpc.publicnode.com",
    explorer_url: "https://testnet.bscscan.com",
};

/// Every chain this crate knows an address for.
pub const DEPLOYMENTS: &[Deployment] = &[BSC, BSC_TESTNET];

/// Look a deployment up by EIP-155 chain id.
///
/// ```
/// assert_eq!(fyuz::deployment_for_chain_id(56).map(|d| d.network), Some("bsc"));
/// assert!(fyuz::deployment_for_chain_id(1).is_none(), "Fyuz is not on Ethereum");
/// ```
pub fn deployment_for_chain_id(chain_id: i64) -> Option<&'static Deployment> {
    DEPLOYMENTS.iter().find(|d| d.chain_id == chain_id)
}

/// Look a deployment up by slug (`"bsc"`, `"bsc-testnet"`) or by the decimal
/// chain id spelled as a string (`"56"`), which is what the trading layer
/// accepts as a network everywhere else.
pub fn deployment_for_network(network: &str) -> Option<&'static Deployment> {
    DEPLOYMENTS
        .iter()
        .find(|d| d.network == network || d.api_network == Some(network))
        .or_else(|| network.parse().ok().and_then(deployment_for_chain_id))
}