Solana

moonlite launches and trades tokens on Solana mainnet. A launch opens a Meteora Dynamic Bonding Curve pool quoted in its pair asset (SOL by default, or any listed asset, see Pairing); when the curve fills, the token migrates to a Meteora DAMM v2 pool and trades through the swap. moonlite never holds your funds: the API builds unsigned transactions and your wallet (Phantom, Solflare or Backpack) signs every one.

NetworkSolana mainnet-beta
Quote assetThe launch's pair: SOL (wrapped SOL So111…1112) by default, or a listed asset from GET /pairs
Supply1,000,000,000 per token, 6 decimals
Explorersolscan.io
Launch modesantirug or standard, fixed at launch
API basehttps://moonlite.so/sol, JSON, no key

The chain switch in the header moves between the Solana pages and their Arc counterparts. Solana is the default.

Launching on Solana

  1. 01
    PreparePOST /launch/prepare validates the input, pins the image and metadata to IPFS and returns the new mint, its pool and the unsigned transactions. Pinning can take 10 to 20 seconds.
  2. 02
    Sign in ordertxs is ordered: the config transaction, then the pool transaction (sometimes merged into one). Sign and send each one and wait for confirmation before the next.
  3. 03
    First buyIf the response has followUpBuySol > 0, request a buy with POST /trade/tx for that many lamports and sign it.
  4. 04
    TradeThe token trades on its bonding curve through /trade/tx until it migrates, then through /swap/*.

Name up to 32 bytes, symbol up to 10 characters, image as a PNG, JPEG, GIF or WebP data URL up to 4 MB. Invalid input returns 400 {"error": "…"} with the reason.

Fee and tokenomics

Each Solana launch has one trading fee, set by the creator between 1% and 10% (feeBps 100 to 1000). The same fee applies to buys and sells; there is no separate buy or sell fee. The fee is split in this order:

  • Meteora keeps 20% of every fee.
  • moonlite keeps 20% of the rest.
  • The remainder is split by the creator's allocation across four legs, in basis points that must sum to 10000.
CreatorPaid natively and claimed by the payout wallet (the creator wallet unless another Solana address is set at launch).
Holder rewardsPaid pro rata to wallets holding at least 100,000 tokens, in the launch's pair asset by default (reflections) or in SOL. On rewards paid in a non-SOL asset moonlite keeps a 30% handling fee; there is none on SOL rewards.
Buyback & burnBuys the token with the collected SOL and burns it.
Auto-LPAdded to the DAMM v2 pool after graduation and permanently locked.

Distribution runs every 6 hours. Presets: creator (1%, all to creator), holders (3%, all to dividends), deflation (3%, all to buyback), autolp (3%, all to liquidity). GET /tokenomics/preview returns the exact per-trade split for any setting:

curl "https://moonlite.so/sol/tokenomics/preview?feeBps=300&creator=2500&buyback=2500&dividend=5000&liquidity=0"
// "breakdown": {"feeBps":300,"creatorTradingFeePercentage":20,
//   "perTradeBps":{"meteora":60,"platform":48,"creator":48,"buyback":48,"dividend":96,"liquidity":0}}

perTradeBps is in basis points of the trade and sums to feeBps. Tokens launched before tokenomics return tokenomics: null.

Pairing

A launch can be paired with anything listed: its bonding curve is quoted in the pair asset instead of SOL. The default pair is SOL. The other listed assets are tokenized stocks (xStocks), crypto, currencies and commodities. Holder rewards (reflections) are paid in the pair by default. Market caps are reported in the pair (mcapQuote, priceQuote) and in SOL terms (mcapSol, price).

List pair assets

curl "https://moonlite.so/sol/pairs?category=stocks&q=SPY"
// {"pairs":[{"mint":"XsoCS1TfEyfFhfvj8EtZ528L3CaKBDBRqRapnBbDF2W","symbol":"SPYx","name":"SP500 xStock","decimals":8,
//   "logoURI":"/sol/icon/XsoCS1TfEyfFhfvj8EtZ528L3CaKBDBRqRapnBbDF2W","liquidity":…,"kind":"xstock","category":"stocks"}],
//  "categories":["solana","stocks","crypto","currencies","commodities"],"minLiquidityUsd":250000}

category is one of solana, stocks, crypto, currencies, commodities; q matches symbol, name or an exact mint. Only assets with enough liquidity (minLiquidityUsd) are listed. Every logoURI is /vendor/sol/solana.svg or /sol/icon/<mint>.

Icons

GET /icon/:mint returns a logo image for any mint, launch tokens and pair assets alike, served from the moonlite origin (cached for a day). It returns 404 only when no logo resolves on-chain or off-chain.

Launch with a pair

Add pair (a mint from GET /pairs) to POST /launch/prepare. Omit it for SOL. Unless tokenomics.rewardMint says otherwise, holder rewards are paid in the pair. The response echoes pair: {mint, symbol, decimals}; for a non-SOL pair the first buy (followUpBuySol) runs as a separate /trade/tx paid in SOL.

{ "mode": "antirug", "name": "My Token", "symbol": "MYT", "creator": "<your wallet>", "image": "data:image/png;base64,…",
  "pair": "XsoCS1TfEyfFhfvj8EtZ528L3CaKBDBRqRapnBbDF2W", "tokenomics": { "preset": "holders" } }

Trade a paired launch

Buys pay in SOL by default: payWith: "SOL" with amount in lamports adds a Jupiter swap from SOL into the pair before the curve buy. payWith: "pair" takes amount in raw pair units instead. Sells receive SOL by default: receiveIn: "SOL" adds a Jupiter swap from the pair back to SOL after the curve sell. SOL-paired launches stay a single transaction.

curl -X POST "https://moonlite.so/sol/trade/tx" -H "Content-Type: application/json" -d '{
  "mint": "<SPYx-paired launch>", "owner": "<your wallet>",
  "side": "buy", "amount": "100000000", "payWith": "SOL", "slippageBps": 300
}'
// {"txs":["<Jupiter SOL→SPYx>","<curve buy>"],"tx":"<= txs[0]>","pair":{"mint":"Xso…F2W","symbol":"SPYx","decimals":8},
//  "route":{"via":"jupiter","in":"SOL","out":"SPYx","solIn":"100000000","pairOut":"…","pairMin":"…","platformFee":{"amount":"…","feeBps":100}},
//  "expectedOut":"…","minOut":"…"}

txs is ordered. Sign and send each one and wait for confirmation before the next. The curve buy spends the Jupiter leg's guaranteed minimum (pairMin). On a sell with receiveIn: "SOL", route.solOut and route.solMin give the SOL you receive.

Fees

  • Trade fee 1% to 10%, set by the creator. Meteora keeps 20%; moonlite keeps 20% of the rest; the creator's split divides the remainder.
  • Holder-reward handling fee: moonlite keeps 30% of holder rewards paid in a non-SOL asset (holders get 70%). There is none on SOL rewards.
  • Jupiter routing fee: moonlite takes 1% on user-facing Jupiter routes (the swap page and the buy-with-SOL routing into a pair).

Worked example: 1 SOL of volume on a launch paired with SPYx, 3% fee, holders preset (all of the creator's split to holders). Amounts in SOL terms; the curve collects them in SPYx.

Trade fee3% of 1 SOL = 0.03
Meteora20% of 0.03 = 0.006
moonlite20% of the remaining 0.024 = 0.0048
Holder poolthe remaining 0.0192, in SPYx
Handling fee30% of 0.0192 = 0.00576 in SPYx, to moonlite
Holders70% of 0.0192 = 0.01344 in SPYx

If the 1 SOL was a buy routed from SOL through Jupiter, the 1% routing fee applies to that Jupiter leg as well.

Anti-Rug mode

Rules enforced onchain by the anti-rug program for tokens launched with mode: "antirug", as returned by GET /config in rules:

  • Floor. A sell that would leave the price below 80% of the all-time high is rejected (program error 6000). GET /maxsell/:mint?owner= returns the largest sell that stays above the floor.
  • 72h check. Every 72 hours from launch, volume over the last 72 hours must reach 10% of the market cap. If it does not, the token is immortalized.
  • IMMORTAL: trading is closed and the market cap is frozen at its final value. Holders withdraw their pro-rata share of the pool. The frozen market cap is a record, not the amount holders receive. On-chain, buys are rejected (error 6001) and a sell is a pro-rata withdrawal of the curve's reserve (dissolveWithdraw: true in the trade response, with the share in fairPayoutLamports).
  • Naming. The program and the API still call this state dissolve: an immortalized token has status: "dissolving" and antirug.state: "dissolving", and the 72h check is exposed as dissolve. The product name is Immortalize.

GET /token/:mint returns the live values in antirug: floorPrice, athPrice, state, and dissolve.nextCheckAt, volume72hSol, requiredSol, ratio, onTrack, progress (0 to 1 of the required volume) and verdict: safe (on track), will_halt (will be immortalized at the next check if volume stays below the requirement), halted (immortal) or graduated. GET /tokens carries the same object as dissolve on each token (null for Standard tokens), and GET /keeper returns the 72h check keeper's health, the upcoming checks and its recent decisions (decision: "dissolve" means immortalized). Standard tokens return antirug: null.

Solana HTTP API

Base URL https://moonlite.so/sol. Amounts in requests are integer strings in base units: lamports for SOL (1 SOL = 1,000,000,000), and raw units with 6 decimals for tokens. Prices in responses are SOL per token; solUsd is included for USD conversion. Errors are JSON {"error": "…"} with a 4xx status.

GET /configProgram ids, pool configs, anti-rug rules, supply, decimals, solUsd and the tokenomics limits and presets (including platformBpsOfRemainder, rewardHandlingBps, jupiterFeeBps).
GET /pairs?category=&q=. The assets a launch can be paired with, with categories and minLiquidityUsd. See Pairing.
GET /icon/:mintA logo for any mint (launch tokens and pair assets), served from the moonlite origin.
GET /tokens?sort=new|mcap|volume|progress&mode=antirug|standard&q=&limit=. Every launch with price, market cap, progress, status, 24h volume and its pair.
GET /token/:mintOne token: stats, holders, anti-rug state, tokenomics, fee breakdown and distributed fees.
GET /trades/:mint?limit=. The trade tape: side, SOL (SOL-equivalent), tokens, price, trader, signature, plus quote, quoteMint and priceQuote in the pair.
GET /candles/:mint?tf= seconds. OHLC in SOL per token, volume in SOL.
GET /statsTotals: tokens by status and mode, volume, anti-rug outcomes, launches by pair (pairs), fees distributed, top tokens by 24h volume.
GET /rwa_statsUSD totals routed by the distributor: rewards bought in paired assets, SOL dividends, buyback & burn, liquidity.
GET /streamServer-sent events trade and token. ?mint= filters to one token.
GET /maxsell/:mint?owner=The wallet's balance and the largest sell the anti-rug floor allows.
POST /trade/txUnsigned buy or sell on the bonding curve. Non-SOL pairs return an ordered txs list.
POST /launch/prepareUnsigned launch transactions for a new token.
POST /creator/claim/txUnsigned claim of the creator fee share. Only the payout wallet can claim (403 otherwise, 409 when nothing is claimable).
GET /dividends/:ownerDividends paid and owed to a wallet, per token, with payout signatures.
GET /portfolio/:ownerSOL balance, positions with cost and PnL, trade activity and launches.
GET /swap/tokens · /swap/quote · POST /swap/txJupiter routing for migrated tokens and any other SPL token.

Read launches

curl "https://moonlite.so/sol/tokens?sort=mcap&mode=antirug&limit=20"
// {"solUsd":…,"tokens":[{"mint":"…","pool":"…","mode":"antirug","symbol":"…","status":"live",
//   "price":…,"mcapSol":…,"progress":…,"thresholdSol":…,"athPrice":…,"volume24hSol":…,"trades24h":…}]}

curl "https://moonlite.so/sol/token/BHstHgS5S2moQMSf6s84R51FJ1Q4uiX12N8ykh542xHa"
curl "https://moonlite.so/sol/trades/BHstHgS5S2moQMSf6s84R51FJ1Q4uiX12N8ykh542xHa?limit=50"
curl "https://moonlite.so/sol/candles/BHstHgS5S2moQMSf6s84R51FJ1Q4uiX12N8ykh542xHa?tf=300"
curl -N "https://moonlite.so/sol/stream?mint=BHstHgS5S2moQMSf6s84R51FJ1Q4uiX12N8ykh542xHa"

Trade on the bonding curve

amount is lamports for a buy and raw token units (6 decimals) for a sell. The response is a base64 transaction for owner to sign and send. For a launch paired with a non-SOL asset the response has several transactions in txs; see Pairing.

curl -X POST "https://moonlite.so/sol/trade/tx" -H "Content-Type: application/json" -d '{
  "mint": "BHstHgS5S2moQMSf6s84R51FJ1Q4uiX12N8ykh542xHa",
  "owner": "<your wallet>",
  "side": "buy",
  "amount": "10000000",
  "slippageBps": 100
}'
// {"tx":"<base64>","txs":["<base64>"],"side":"buy","pair":{"mint":"So111…1112","symbol":"SOL","decimals":9},
//  "expectedOut":"…","minOut":"…","route":null,"dissolveWithdraw":false,"fairPayoutLamports":null}
  • 422 {"error", "maxSellRaw", "maxSellUi"}: the sell would break the anti-rug floor; retry with at most maxSellRaw.
  • 409: a buy on an immortalized token (API state dissolving), or the token has migrated (use the swap endpoints).

Launch a token

curl -X POST "https://moonlite.so/sol/launch/prepare" -H "Content-Type: application/json" -d '{
  "mode": "antirug",
  "name": "My Token",
  "symbol": "MYT",
  "description": "…",
  "website": "https://…", "twitter": "https://x.com/…", "telegram": "https://t.me/…",
  "image": "data:image/png;base64,…",
  "creator": "<your wallet>",
  "buySol": 0.1,
  "tokenomics": { "feeBps": 300, "creator": 2500, "buyback": 2500, "dividend": 5000, "liquidity": 0 }
}'
// {"mint":"…","pool":"…","config":"…","mode":"antirug","uri":"…","tokenomics":{…},"breakdown":{…},
//  "txs":["<base64 config tx>","<base64 pool tx>"],"followUpBuySol":0.1}

Instead of explicit legs, tokenomics can name a preset. payout sets another Solana address for the creator share.

Swap (Jupiter)

Migrated tokens and any other SPL token trade through Jupiter. moonlite takes a 1% fee on these routes when one side is SOL, USDC or USDT; the quote carries it as platformFee and GET /swap/tokens returns the current feeBps (100).

curl "https://moonlite.so/sol/swap/quote?inputMint=So11111111111111111111111111111111111111112&outputMint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v&amount=10000000&slippageBps=50"
// Jupiter quote: {"inAmount":"10000000","outAmount":"…","platformFee":{"amount":"…","feeBps":100},"routePlan":[…],…}

curl -X POST "https://moonlite.so/sol/swap/tx" -H "Content-Type: application/json" \
  -d '{"quoteResponse": <quote JSON>, "userPublicKey": "<your wallet>"}'
// {"swapTransaction":"<base64 versioned tx>",…}

Sign and send in the browser

// single-tx example; for txs.length > 1 sign and send each in order, waiting for confirmation before the next
const { tx } = await fetch("/sol/trade/tx", { method: "POST", headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ mint, owner, side: "buy", amount: "10000000", slippageBps: 100 }) }).then(r => r.json());
const bytes = Uint8Array.from(atob(tx), c => c.charCodeAt(0));
const signed = await window.phantom.solana.signTransaction(solanaWeb3.Transaction.from(bytes));
const sig = await connection.sendRawTransaction(signed.serialize());
// Jupiter swap transactions are versioned: use VersionedTransaction.deserialize(bytes)

Solana reference tokens

Live mainnet launches with known state, for validating an integration.

ARUGAnti-Rug mode · mint
BHstHgS5S2moQMSf6s84R51FJ1Q4uiX12N8ykh542xHa
TESTLITEStandard mode · mint
C3iHQz9BkC48X72NSvfE8WbgcYnPJZ6BripCF1UpSPqx

The Arc documentation follows.

Arc overview

moonlite is a place to launch and trade tokens on Arc. You can browse launches, open any token to see its details, and trade straight from your wallet. Every launched token is routable through the moonlite aggregator from its first block.

moonlite never holds your funds. Every launch and trade is a transaction your wallet asks you to approve.

Key facts
  • Names and symbols can be copied. Always check the token address.
  • Prices come from each token's live curve or pool.
  • USDC is the native asset of Arc. Every launch is priced and paired in USDC.
  • Launches can be volatile, illiquid, or lose all value.

How launches work

Creating a launch mints the token and opens its trading curve in a single transaction. The creator sets the name, symbol, image, description and links at creation, and with v2 also the tax rates and the fee allocation. Those settings are written onchain and never change afterward.

Every token trades against USDC. It opens on a bonding curve at a $3,000 market cap and, once enough USDC has been raised, graduates into its own liquidity pool where trading continues.

  1. 01
    CreateThe token is minted with a fixed supply and its curve goes live in the same transaction, opening at the $3,000 floor.
  2. 02
    TradeBuys and sells run against USDC on the curve and move the price. The aggregator routes any input token into it.
  3. 03
    GraduateOnce 24,000 USDC has been raised, liquidity is seeded into the token's own pool and trading continues there.

Each launch uses a fixed supply of one billion tokens, a flat $2.00 USDC launch fee, and a virtual-reserve curve: 2,400 USDC of virtual reserve against 800 million tokens on the curve, with 200 million tokens reserved for the graduation seed and burn.

Launch protection

The creator can buy at launch inside the same transaction that seeds the curve, at the $3,000 opening price. There is no block in which anyone can buy ahead of the creator, and the creator pays the same floor price as the public, so a dev-buy is never a discount. Selling and wallet-to-wallet transfers are never restricted.

v1 Curve launches charge a flat 1% fee on every buy and sell. 70% of the fee goes to the creator and 30% to the protocol.

v2 Tokenomics launches let the creator choose a buy tax and a sell tax, each between 1% and 10%, and an allocation of the proceeds. See Fees and taxes.

Trading and pricing

Before graduation every token trades on its own curve. The price you see is the live curve price, and it moves with each trade. The amount you actually receive can differ slightly from the quote. Slippage sets how much of that movement you accept.

PriceThe current curve or pool price for one token, in USDC.
Market capPrice multiplied by the total supply.
Curve progressUSDC raised on the curve over the graduation threshold.
Price impactThe curve movement caused by the size of your trade.
SlippageThe maximum execution movement your transaction accepts.
LiquidityUSDC held by the curve, or assets in the pool around the current price after graduation.

Trades on the site go through the moonlite router. The router quotes the best route across every venue it certifies on Arc, so you can pay with any token the aggregator knows and receive the launched token, or sell it back into anything.

Graduation

A launch graduates once the USDC raised on its curve reaches the threshold. The threshold is 24,000 USDC, which the interface shows as a $40,000 market cap, and the progress line tracks how close a launch is.

At graduation the curve seeds the token's own USDC pool with the reserved tokens and the raised USDC, and the pool is registered with the aggregator. Trading continues there. Under v4 the tax rates keep applying to trades in the pool.

Graduation only confirms the threshold was reached. It is not a quality signal and does not guarantee future liquidity, price, or an exit.

Fees and taxes

A v4 launch charges a buy tax and a sell tax, each set by the creator between 1% and 10%. The defaults are 1% each. Every fee is split the same way: the protocol always takes 20% off the top, and the remaining 80% is divided by the creator's allocation.

CreatorPaid to the creator wallet, or to a custom payout address set at launch.
HoldersAccrues as USDC dividends to wallets holding at least $20 of the token. Claimable at any time from the token page.
Buyback & burnBuys the token with the collected USDC and burns it. The pot fires automatically inside trades once it reaches $10.
LiquidityAdded to the token's liquidity at graduation and after it.

The rates and allocation are snapshotted for each token when it launches and never change afterward. They are emitted in the TokenomicsSet event and can be read from the factory at any time.

A v1 launch charges a flat 1% fee on every buy and sell on the curve. The split is fixed at 70% to the creator and 30% to the protocol. Creator fees accrue in the hook and are claimed from the token page.

Buybacks permanently reduce the supply in circulation. Burning does not guarantee a higher price.

Burn-adjusted market cap

price × (total supply − burned supply)

Protocol revenue

The protocol share is 20% of every fee generated by a v4 launch and 30% of every fee on a v1 curve. It goes to the protocol treasury and funds infrastructure, the aggregator, and the partner reward pool. The launch fee of $2.00 USDC is also protocol revenue.

Aggregator swaps outside the launchpad carry a 0.10% protocol fee, taken in the output token.

Safeguards and upgrades

The v4 launch stack runs behind upgradeable proxies, so addresses never change when the code does. The factory and registry are UUPS proxies; every hook and curve is a beacon proxy, so all launched tokens move to a new implementation in one step.

Every contract that can hold assets carries the same emergency kit, operated by a guardian:

  • Pause stops trading. It never blocks holders from claiming what they are owed.
  • Rescue sweep can only move surplus above the balances the contract owes to holders and creators.
  • Emergency withdraw can move any token, but only while paused and after a publicly announced delay: 30 seconds on Arc Testnet, at least 48 hours on any other chain.

On mainnet the guardian and the upgrade admin will be a multisig behind a timelock. Every action above emits an event, so it can be watched onchain.

Creator payout

The creator's share is paid to the launching wallet by default. Under Advanced at launch, the creator can set a custom payout address instead. The recipient is emitted in TokenomicsSet and read from the factory.

If a token's original creator steps away and an active community asks for the payout to be redirected, contact support. Any change is administrative, depends on what the token's contracts allow, and is not an endorsement or a statement about a token's safety or value. The token, its curve, and its liquidity are unaffected.

Never share a private key or seed phrase. moonlite will never ask you to send funds to process a request.

Risk disclosures

Tokens launched through moonlite are user-created and experimental. Review the token address, creator, liquidity, holder concentration, and transaction preview before signing.

  • Prices can move quickly and liquidity can be thin.
  • Similar names and images can represent unrelated tokens.
  • Smart contracts, wallets, RPCs, and indexers can fail.
  • Displayed values are estimates, not execution guarantees.

moonlite is an interface, not investment advice or a representation of token quality.

Network

moonlite runs on Arc mainnet. Tokens launch on a Uniswap v4 hook curve and graduate into their own USDC pool. Everything is quoted against USDC, the chain's native asset.

NetworkArc (mainnet)
Chain ID5042 (0x13b2)
Native assetUSDC, 6 decimals. ERC-20 view at 0x3600…0000
Public RPChttps://rpc.arc-scan.org
Explorerarc-scan.org
Launch fee2.00 USDC
Supply1,000,000,000 (1e9), 18 decimals
Opening market cap3,000 USDC
Graduation24,000 USDC raised
TestnetArc Testnet, Chain ID 5042002, at api.moonlite.so/testnet/

Contracts

Deployed addresses on Arc mainnet. The factory and registry are proxies and keep their addresses across upgrades.

Launch factoryUUPS proxy · start block 20882058
0x13D3d84ea33C80459793BEb88EA2F69e1615cFa6
Launch registryUUPS proxy · graduated pools
0x8AD3BF12885d985795Ca6Eeddd43D564614151E3
Hook beaconImplementation for every v2 hook
0x4f553ced6b572AbA316f1598aB3F24F239885C4d
Curve beaconImplementation for standalone curves
0x2D54240e9924597400cAA38cB5B9785c702976Ec
RouterswapExactIn(auth, sig, hops)
0x0B1E802Cd9a131170D035aaD19e13B8E6BbbF908
Curve adapterRoutes the aggregator into hook curves
0xAF1320Cfbec8FF494f36784d9752dB99a436f6CF
Graduated pair adapterRoutes into graduated pools
0xA3A45ec45fA24eAC3c520814e41Ddc1B0aDEAA02
Uniswap v4 PoolManagerCurves live here as ERC-6909 inventory
0x8366a39cc670b4001a1121b8f6a443a643e40951
USDC (quote token)Native asset, ERC-20 view
0x3600000000000000000000000000000000000000

Implementations behind the proxies and beacons are read onchain: the ERC-1967 implementation slot of a proxy, or implementation() on a beacon. The same stack runs on Arc Testnet (chain 5042002): factory 0xEBaE4D6e72db9Eee922D3A0bd4B7ED24bb229094, registry 0x987a109338E4c05125F8ac1756E13b51660d2611, served at https://api.moonlite.so/testnet/.

Onchain events

For a trust-minimized integration, index the factory's launch events, then index each token's hook for its trades, its tax splits and its graduation. Onchain events are the authoritative source of truth.

V4TokenLaunchedfactory · topic0
0x2fac50dab083f7c92c59cb68617bfd8904f40fe698286ea86dabd398dd42a247
TokenomicsSetfactory and hook · topic0
0x4043cfbfd926808e3852ce72461053c1542d28b192789229ce44aa7958e71328
DevBuyfactory · topic0
0x250a9fe9f4df510a19bc3854d8cb21ca8cf857f4a2867897850b2cd61c711a57
Buyhook · topic0
0x30df0cd28c6e48e6fe24bcab9f36b5052aef24c98ba64b6ef2ba66b659e9a29e
Sellhook · topic0
0x594898f0701a8fbcf3e869135bc2a2d8194e98a46765b1f6ef41138fe049ebb8
FeeSplithook · topic0
0xcf1e802f76459d095025dbce897ca4bae16bedd5d8502575a9b99bb7e6f5eecd
Graduatedhook · topic0 (v4)
0x1c858049e704460ab9455025be4078f9e746e3fd426a56040d06389edb8197db
PoolRegisteredregistry · topic0
0x7086256370df53a5ce3f71d018eda285020ad66d4d0889badd3fa9f5f9e4093c

Read launches with viem

import { createPublicClient, http, parseAbiItem } from "viem";

const client = createPublicClient({
  chain: {
    id: 5042,
    name: "Arc",
    nativeCurrency: { name: "USD Coin", symbol: "USDC", decimals: 18 },
    rpcUrls: { default: { http: ["https://rpc.arc-scan.org"] } },
  },
  transport: http(),
});

const launches = await client.getLogs({
  address: "0x13D3d84ea33C80459793BEb88EA2F69e1615cFa6",
  event: parseAbiItem(
    "event V4TokenLaunched(address indexed token, address indexed hook, address indexed creator, uint24 fee, int24 tickSpacing, uint256 launchFeeUsdc)",
  ),
  fromBlock: 20882058n,
  toBlock: "latest",
});

Each launch emits its hook address. Index that hook's Buy and Sell events for trades: they carry the USDC in or out, the fee, the new price, the new market cap and the curve progress, so there is nothing to derive.

// Buy(token, buyer,  usdcIn,   usdcFee, tokensOut, newPriceX96, newMcapUsdc, curveProgressBps)
// Sell(token, seller, tokensIn, usdcOut, usdcFee,   newPriceX96, newMcapUsdc, curveProgressBps)
side = log.eventName === "Buy" ? "buy" : "sell";

Graduation is an event on the hook, followed by LiquiditySeeded and the registry's PoolRegistered, which names the pool that trades from then on. The public RPC can time out on wide eth_getLogs ranges. Backfill in bounded block chunks from the factory's start block.

Reading token state

Every launch is self-describing onchain. The token is a plain ERC-20, and its hook exposes the curve, the taxes and the reward state directly, with no off-chain source required.

import { parseAbi } from "viem";

const hookAbi = parseAbi([
  "function tokenomics() view returns ((uint16 buyTaxBps, uint16 sellTaxBps, uint16 creatorBps, uint16 buybackBps, uint16 dividendBps, uint16 liquidityBps, address feeRecipient))",
  "function buyTaxBps() view returns (uint256)",
  "function sellTaxBps() view returns (uint256)",
  "function getReserves() view returns (uint256 usdcReserve, uint256 tokenReserve)",
  "function spotPriceX96() view returns (uint256)",
  "function currentMcapUsdc() view returns (uint256)",
  "function curveProgressBps() view returns (uint256)",
  "function getAmountOut(uint256 amountIn, bool buy) view returns (uint256)",
  "function pendingRewards(address holder) view returns (uint256)",
]);

const [cfg, mcap, progressBps] = await Promise.all([
  client.readContract({ address: hook, abi: hookAbi, functionName: "tokenomics" }),
  client.readContract({ address: hook, abi: hookAbi, functionName: "currentMcapUsdc" }),
  client.readContract({ address: hook, abi: hookAbi, functionName: "curveProgressBps" }),
]);

Launch-level parameters also live on the factory that deployed the token: tokenomicsOf(token) returns the same snapshot, and allLaunchesLength() counts launches. The registry's allPoolsLength() counts graduated pools.

Pricing and graduation

Price comes from the hook. spotPriceX96() is the USDC price of one token as a Q96 fixed-point number, and currentMcapUsdc() is the market cap in 6-decimal USDC. Quote a trade with getAmountOut(amountIn, buy): it already nets the tax.

const priceX96 = await client.readContract({ address: hook, abi: hookAbi, functionName: "spotPriceX96" });
const mcapUsdc = await client.readContract({ address: hook, abi: hookAbi, functionName: "currentMcapUsdc" });

const marketCapUsd = Number(mcapUsdc) / 1e6;          // 3,000 at launch, 40,000 at graduation
const priceUsd     = marketCapUsd / 1e9;               // fixed supply of one billion
const fdvUsd       = marketCapUsd;

Graduation is a single read. Progress is USDC raised over the 24,000 USDC threshold, and trading continues in the token's pool after it graduates.

const progress = Number(await client.readContract({ address: hook, abi: hookAbi, functionName: "curveProgressBps" })) / 10000;
const graduated = progress >= 1;

HTTP API

Everything above is also served over HTTP at https://api.moonlite.so, with no key required. The launch endpoints read the same onchain state; the quote and swap endpoints are the aggregator that powers the site.

GET /launch/listEvery launch with price, market cap, progress and graduation state.
GET /launch/token?address=One token: metadata, tokenomics, sinks, holders and reward state.
GET /launch/trades?address=The trade tape for a token.
GET /launch/streamServer-sent events: new launches, trades and graduations as they happen.
GET /quoteBest route for tokenIn, tokenOut and amount, with price impact.
POST /swapA signed swap plan: hops, calldata and the minimum you receive.
GET /tokensEvery token the aggregator can route.
POST /launch/createThe exact approve and launch calldata for a new token. Your wallet signs both.
curl "https://api.moonlite.so/quote?tokenIn=0x3600000000000000000000000000000000000000&tokenOut=<token>&amount=100000000"
// {"amountIn":"100000000","amountOut":"…","priceImpactBps":…,"feeBps":10,"block":…}

Amounts are integer strings in base units: 6 decimals for USDC, 18 for launched tokens. The swap page documents the full quote, sign and execute round trip.

Reference tokens

The first mainnet launch, with known onchain state, for validating an indexer or integration.

GENESISMoonlite Genesis · live on the curve · token
0x65f7e221a2169f39fbfc6e5f24083b4ac454a241
GENESIS hookCurve, taxes and rewards
0x740ee7632d56074430c6020f3fc9570d0f6a6088
Launch txblock 20882982
0xd45540776d3520c9378147f257b36ec8272bf7f416a1b828a34013cac86968cd

Launched through the mainnet factory with 1% buy and sell taxes, split equally between creator, holders, buyback and liquidity.

Support

We offer hands-on support for teams integrating moonlite. If you are indexing launches, deriving prices, wiring trades, or verifying onchain state, the team can help you get it right.

Reach us on X at @moonlite_so for integration questions and technical support, and through the partner program for embedding the swap or running a whitelabel bot.

Versioning

The factory and registry are upgradeable proxies and keep their addresses. New adapter versions ship as new addresses, listed under Contracts. v1 curves keep trading exactly as they launched.

Terms and attribution

Onchain data is public and free to read. You are responsible for how you use it. moonlite is provided as is, without warranties, and the team is not liable for losses arising from integrations, interfaces, RPCs, or indexers.

When you reference moonlite, write the name in lowercase and link back to the app. Do not imply a partnership, endorsement, or official status without a written agreement.

  • Do not present third-party services as operated by moonlite.
  • Do not use the moonlite name or marks in a way that misleads users.
  • Availability of interfaces and public infrastructure is not guaranteed.