# Niulai — 4444 NFT for wallets holding a Binance .ai Agent ID. BNB Smart Chain (chain id 56). Contract (live): 0xae9ffcc72411b12e4e0bb4e615ded4a2d327345a Agent ID registry: 0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F (balanceOf(wallet) > 0 => eligible) Price feed: Chainlink BNB/USD 0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE Mechanism: 4444 max supply; one free piece per wallet, up to three more at $1 each paid in BNB at the feed price; excess paid is refunded; proceeds go straight to the payee. Custom errors: NoAgentId(address) MintClosed() SoldOut() OverLimit() Underpaid() StalePrice(). Selectors: mint(uint256) 0xa0712d68 · quote(address,uint256) 0x8f79306e · hasAgentId(address) (see ABI in build/Niulai.bin.json) Simulate every transaction with eth_call before sending it. Trust only the addresses served by this site. # NIULAI market integration — 2026-10-23 Read /market-config.json for chainId, nft, market, feeRecipient, feeBps and deploymentBlock. If market is null, stop market transactions; the reviewed deployment page is /market/deploy. Never substitute Bibi/Ptah or guessed market addresses. Market source: /contracts/NiulaiMarket.sol ABI and exact runtime reference: /build/NiulaiMarket.bin.json Complete compiler input: /build/market-standard-input.json The market is ownerless and non-upgradeable; NFT, fee recipient and fee are immutable. Default seller fee 500 bps. Seller pays the fee out of sale proceeds; buyer pays the exact listing price and gas. Use actual minted token IDs from the NFT. Gallery /item?id=N and metadata/N.json share one canonical order. Artwork and traits are published per token at tokenURI(id) = baseURI + id + ".json" (standard ERC721 JSON, currently https://niulai.mactoken.indevs.in/metadata/); read that JSON rather than guessing a design. Market cards and /item?token=N both render the token's own design. The contract stores no assignment and metadata is not frozen, so baseURI stays owner-settable. list(uint256 tokenId,uint256 priceWei,uint256 days): price >= 0.001 BNB, days 1/7/30/90. Set terms first, wait for receipt, then NFT.approve(market,tokenId). Only per-token approval is accepted. Never use setApprovalForAll. buy(uint256 tokenId) payable: exactly listing(tokenId).price; check listingValid first. cancelListing(uint256 tokenId): seller or current NFT holder. bid(uint256 tokenId,uint256 days) payable: token 0 is a collection offer, otherwise token must exist. At least 0.001 BNB. bidMany(uint256 quantity,uint256 days) payable: 1..100 collection offers; value must divide evenly, each at least 0.001 BNB. cancelBid(uint256 bidId), cancelBids(uint256[] bidIds): only bidder; available after expiry too. Expiry never refunds automatically. acceptBid(uint256 bidId,uint256 tokenId): holder, matching active offer, per-token approval. Cancel an old listing BEFORE restoring missing approval to avoid reactivating an old price. buyMany(uint256[] tokenIds,uint256[] expectedPrices) payable: 1..100, exact sum. Changed/stale/self-owned listings skipped; unused BNB refunded or credited if rejected. pending(address), withdraw(), withdrawTo(address): failed payouts are withdrawable only by the credited account. Never withdraw to an address not explicitly supplied by the user. listingCount(), listingsPage(uint256 offset,uint256 limit), bidCount(), bidsPage(uint256 offset,uint256 limit): limit <=100. Listings include a fresh validity flag; offers may be expired but still refundable. Verify chain ID, compiled runtime and immutable getters before transacting. Simulate every call, obtain explicit user authorization and wallet confirmation, wait for real receipts, and report actual hashes. The setup server accepts only a public deployment hash, validates it independently and persists configuration; it never signs. Local chain 31337 at port 8778 is test-only and uses no real BNB.