Skip to main content

Crate fyuz

Crate fyuz 

Source
Expand description

Async Rust client for the Fyuz public REST API.

Fyuz is a bonding-curve token launchpad on BNB Smart Chain. A new token trades on an internal bonding curve until it reaches a $30,000 market cap, at which point it graduates into a PancakeSwap V2 pair.

Before graduation there is no DEX pool anywhere. pair_address is None, no on-chain pair exists to quote, and this API is the only source of price, liquidity and volume data for that token. Anything you build that reads pre-graduation prices from a DEX aggregator will simply find nothing.

Every endpoint in this crate is unauthenticated and safe to poll.

§Quickstart

use fyuz::{DiscoverParams, DiscoverTab, FyuzClient};

#[tokio::main]
async fn main() -> Result<(), fyuz::Error> {
    let client = FyuzClient::new()?;

    let trending = client
        .discover(&DiscoverParams::new().tab(DiscoverTab::Trending).limit(10))
        .await?;

    for token in &trending {
        println!(
            "{:<10} ${:>12.0} mcap   {:>6.2}% to graduation",
            token.symbol, token.marketcap, token.graduation_pct
        );
    }

    Ok(())
}

§Decimal strings, and why they are not floats

Token balances, prices, market caps and every *_wei field come back as decimal strings and stay String in this crate’s models. An 18-decimal token amount, or a uint256 wei total, does not survive a round trip through f64:

let wire = "123456789012345678901234567890";
// What a "just parse it as a number" client would do:
let lossy = wire.parse::<f64>().unwrap();
assert_ne!(format!("{lossy:.0}"), wire); // silently wrong

If you need arithmetic, parse into a big-integer or decimal type of your choosing (rust_decimal, bigdecimal, primitive_types::U256, …) at the edge of your own code. The SDK deliberately does not pick one for you, and deliberately never parses these into f64 on your behalf.

Aggregates that the server already computed in floating point — volume_usd, points, reward_eth, pot_bnb, PnL figures — arrive as JSON numbers and are modelled as f64.

Timestamps get the same treatment for the same reason, one step further: the RFC-3339 created_at/updated_at strings and the unix-second date and round_end fields stay as they arrived. There is no date type in core, and picking chrono or time for you would put a dependency — and a major version of it — into every downstream build to save one parse call. This is the one helper the TypeScript, Go and Python SDKs have that this one deliberately does not.

§Where Fyuz is deployed

addresses carries the deployed proxy addresses as compile-time constants, looked up by chain id or slug:

let bsc = fyuz::deployment_for_chain_id(56).expect("mainnet is in the book");
assert_eq!(bsc.fyuz, "0x33a98bef6496684a8dac83734d9ceb0cefc7019c");

GET /config still wins wherever it answers — the launchpad is behind an upgradeable proxy, and a published crate that trusted its own copy would keep calling a dead address after a redeploy. The book is what covers the cases the API cannot: BSC testnet, which the public API does not serve at all, and a /config response that arrives without a contractAddress.

§None is not 0

Pot::pot_bnb, Claimable::claimable_wei, TokenDetail::curve_holding and the nullable *_wei fields on RoundReceipt are None when the value is unknown — the RPC was unreachable, or the settlement is not indexed yet. Rendering 0 in that case tells a user something false.

§Rate limits and retries

The API allows 120 requests per minute per IP and answers 429 with {"error": "Too many requests"} past that. The client retries 429s, 5xxs and transport failures automatically with exponential backoff and full jitter, honouring Retry-After when the server sends one. Other 4xx statuses are never retried. Three retries is the default:

use std::time::Duration;

let client = fyuz::FyuzClient::builder()
    .timeout(Duration::from_secs(10))
    .max_retries(5)
    .user_agent("acme-indexer/2.1 (ops@acme.example)")
    .build()?;

Once the retries are spent the call fails with Error::RateLimited, which is a distinct variant precisely so a backpressure handler can match on it.

§What is not here

Only the public, unauthenticated surface is implemented. The API-key-gated routes (recording a distribution round, posting chats, watchlists, paper trading, airdrops, …) are deliberately absent — including POST /distributor/rounds, which shares a path with Distributor::list_rounds but is not a public endpoint.

Re-exports§

pub use addresses::deployment_for_chain_id;
pub use addresses::deployment_for_network;
pub use addresses::Deployment;
pub use addresses::BSC;
pub use addresses::BSC_TESTNET;
pub use addresses::DEPLOYMENTS;
pub use models::*;

Modules§

addresses
Where Fyuz is deployed, as compile-time constants.
models
Response types for every endpoint of the Fyuz public API.

Structs§

BuiltBuy
A built buy with the quote it was priced from.
BuiltSell
A built sell with the quote it was priced from.
BuyExactTokensParams
Buy an exact number of tokens, capping the spend.
BuyParams
Spend an exact amount of native currency on a token.
BuyQuote
What a buy will cost and return, priced against current curve state.
ChartDataParams
Arguments for FyuzClient::get_chart_data.
DiscoverParams
Filters for FyuzClient::discover.
Distributor
The Distributor endpoints, reached with FyuzClient::distributor.
FyuzClient
Async client for the Fyuz public REST API.
FyuzClientBuilder
Builder for FyuzClient. Created with FyuzClient::builder.
ListTokensParams
Filters, sorting and paging for FyuzClient::list_tokens.
RecentTradesParams
Incremental polling cursor for FyuzClient::get_recent_trades.
RoundsParams
Paging for Distributor::list_rounds.
RpcClient
Minimal JSON-RPC transport.
SellParams
Sell tokens for native currency.
SellQuote
What a sell will return, priced against current curve state.
SharesParams
Window and size for Distributor::get_shares.
TokenDetailParams
Paging of the trade list embedded in FyuzClient::get_token.
TokenPager
Walks every page of GET /tokens, one request at a time.
TokenTradesParams
Paging for FyuzClient::get_token_trades.
TopHoldersParams
Window and chain filter for FyuzClient::get_top_holders.
TradeApi
Builds unsigned bonding-curve transactions. Reach it through FyuzClient::trade.
U256
A 256-bit unsigned integer, stored big-endian.
UnsignedTransaction
A transaction ready to be signed and sent.

Enums§

CallOutcome
The outcome of an eth_call: return data, or revert data.
DiscoverTab
Preset ordering for the discovery feed.
Error
Anything that can go wrong talking to the Fyuz API.
RevertKind
How a contract revert was classified.
SortDirection
Sort direction for ListTokensParams::order_flag.
TokenStatus
Bonding-curve lifecycle filter.

Constants§

DEFAULT_BASE_URL
Production base URL, used unless FyuzClientBuilder::base_url overrides it.
DEFAULT_BLOCK_TAG
Default block tag every eth_call is evaluated against.
DEFAULT_DEADLINE_SECONDS
How long a built transaction stays valid when the caller does not say.
DEFAULT_NETWORK
Chain slug used when a call does not name one.
DEFAULT_RPC_TIMEOUT
Default per-call timeout for RPC requests.
MAX_DEADLINE_SECONDS
Longest relative deadline this crate will accept, in seconds.
MAX_RESPONSE_BYTES
Ceiling on any single response body this crate buffers, in bytes.
SELECTOR_ALLOWANCE
allowance(address,address)
SELECTOR_ALREADY_LAUNCHED
AlreadyLaunched() — the graduated-token revert.
SELECTOR_APPROVE
approve(address,uint256)
SELECTOR_BALANCE_OF
balanceOf(address)
SELECTOR_GET_FIRST_BUY_FEE
getFirstBuyFee(address)
SELECTOR_GET_MAX_SELLABLE_ETH
getMaxSellableETH(address)
SELECTOR_GET_SWAP_OUTPUT
getSwapOutput(address,uint256,bool)
SELECTOR_PAUSED
paused()
SELECTOR_PLATFORM_BUY_FEE_BPS
PLATFORM_BUY_FEE_BPS() — public storage with an owner setter (setPlatformBuyFeeBps), so it is read rather than assumed.
SELECTOR_SWAP_ETH_FOR_EXACT_TOKENS
swapETHForExactTokens(address,uint256,uint256,uint256)
SELECTOR_SWAP_EXACT_ETH_FOR_TOKENS
swapExactETHForTokens(address,uint256,uint256,uint256)
SELECTOR_SWAP_EXACT_TOKENS_FOR_ETH
swapExactTokensForETH(address,uint256,uint256,uint256)
SELECTOR_TOKEN_OWNER_FEE_BPS
TOKEN_OWNER_FEE_BPS() — likewise owner-settable.
SELECTOR_TOKEN_POOLS
tokenPools(address)
VERSION
Version of this crate, as reported in the User-Agent.

Functions§

address_word
An address as one 64-character word: 12 zero bytes then the 20 address bytes.
bool_word
A bool as one 64-character word.
decode_address_at
Read the index-th word as an address, lower-cased.
decode_bool_at
Read the index-th word as a bool. Any non-zero word is true.
decode_uint256_at
Read the index-th 32-byte word of a return payload as a uint256.
encode_call
Selector plus words, as 0x-prefixed calldata.
format_units
The smallest unit back to whole units, exactly. Inverse of parse_units.
normalize_address
Validate an EVM address and return it lower-cased.
parse_units
Whole units to the smallest unit — "0.5" BNB to 500000000000000000 wei.
revert_error
Classify revert data into a typed Error::ContractRevert.
revert_selector
The first four bytes of some revert data, lower-cased, or None.
uint256_word
A uint256 as one 64-character word.

Type Aliases§

Result
Convenience alias: every fallible call in this crate returns this.