Integration kit
Index Longevity in an afternoon
For trading terminals and screeners: how a Longevity coin is created on Solana, how to recognise one, and the engine's JSON for every coin; then what a coin has on the other chains, the event topics, the maths behind every price and progress bar, the metadata format, the JSON API and a real-time stream. Everything here is derived from the same configuration the site runs on. Machine-readable: /api/integrate/kit.json (version 2.0.0).
Solana first.A Longevity coin is a Meteora DBC pool created by Longevity's deployer under a Longevity config; the engine's JSON names the launcher and the creator's trading fees.
Solana: the engine
Launches on Meteora by the engine, with its JSON per coin.
A coin is launched by the engine: the launcher pays 0.25 SOL to Longevity's deployer, and within seconds the worker creates the coin from a mint derived from a secret, on Meteora's Dynamic Bonding Curve under a Longevity config (every buy in the first three slots pays the 99% opening fee; a bot or a bundle can still buy there and pays it), paired with SOL or with another coin launched here. The pool's creator is Longevity's deployer, so the creator trading fees reach the engine, which pays them to the launcher as the coin grows (nothing for 3 days, then a quarter of what has built up from a $50K peak, and everything at graduation; they are forfeited if the launcher's wallets sell more than half of what they bought in the first 3 days, or if the coin goes 7 days without a trade before graduation). The launcher's own coins earn holder rewards like any holder's. Shortly after launch the worker reads which wallet first funded each early buyer, to tell the creator's wallets apart for those rules; it publishes no verdict. A curve graduates into a DAMM v2 pool when it reaches its migration threshold.
Recognise a coin
A DBC pool is a Longevity coin when its config account names Longevity's partner wallet as feeClaimer and its creator is Longevity's deployer. Both wallets are on the indexing guide. A coin paired with another coin, or one that picked other chains, gets its own config with the same partner wallet, so match on the config's feeClaimer rather than on a list.
Launcher, not creator
The on-chain creator is the deployer for every coin. The launcher (the wallet that paid) is in GET /api/engine/coin/<mint> as coin.launcher; show that as the creator, and use the same reply for the creator's trading fees, the rebates and the bounty state.
Pairs
A coin paired with another Longevity coin is quoted in its parent: pair.parent and pair.depth in the engine reply, at most two deep, the chain ending in SOL. A trade on it goes through the parent in one transaction (POST /api/engine/route), so price it against its parent and convert.
Other chains
A coin can keep 5% of its supply per picked chain; at graduation the slice opens that chain's pool at the Solana price. xchain in the engine reply lists the chains and each slice's state. Section 02 has the rest.
# the engine's view of one coin: the launch, the bundle check, the creator's trading fees, the rebates, the bounty, the pair
curl -s "https://longevity.trading/api/engine/coin/<mint>" | jq '{launch, bundle: .coin.bundle, pair, xchain}'
# this week's Summit Bounty, with the rule it runs under
curl -s "https://longevity.trading/api/bounty" | jq '.rule'
# the OTC desk's filled deals and totals
curl -s "https://longevity.trading/api/otc/feed"The engine refuses mainnet until it is configured; this deployment is configured. The OTC desk (/api/otc/*) settles wallet to wallet in one transaction and never touches a pool, so a filled deal prints no swap on the chart.
Other chains
No coin is launched on an EVM chain. A picked chain gets the coin's token and, at graduation, one pool.
Every coin starts on Solana. On the launch form the launcher can pick Base, Robinhood Chain, BNB Chain and Hyperliquid. The coin keeps 5% of its supply for each picked chain, out of the curve. When the coin graduates on Solana, each slice opens the coin's pool on its chain at the Solana price. There is no bonding curve on these chains and no contract a wallet calls to launch a coin there, so the only things to index are a token, one pool and its swaps.
The token
The TwinOFTFactory creates the coin's token on a picked chain, at the same address on every chain, with 18 decimals. Its TwinDeployed event carries the Solana mint, so you can join the token to the Solana coin. The declaration and topic0 are on the indexing guide.
The pool
The AlignedListingFactory opens one Uniswap v4 pool per coin per chain and emits Listed. The quote is currency0 and the coin is currency1. The quote is the chain's native coin, or the parent coin's token for a paired coin. Tick spacing is 200. Read the key with poolKeyOf(token).
The fee
Every Longevity pool carries the chain's FeeStyleHook and the v4 dynamic-fee flag, so the hook sets each swap's fee. quoteFee(key, params) on the hook returns what a swap pays now. This page does not publish how the trading fee is divided.
One supply
A coin has one supply across every chain. Use the Solana supply for market cap, not the token's totalSupply on one chain.
The pool's liquidity position is kept by the factory's own locker (locker() on the factory; Listed.tokenId is the position). The plain-language version is on How it works.
Contracts per chain
The contracts Longevity deploys, from the site's configuration. Nothing here is a placeholder.
| Contract | What it does |
|---|---|
| TwinOFTFactory | creates a picked coin's token on this chain, at the same address on every chain; emits TwinDeployed with the Solana mint |
| AlignedPoolSeeder | receives the coin's slice at graduation and opens its pool here at the Solana price |
| AlignedListingFactory | opens the coin's Uniswap v4 pool and keeps the liquidity position in its own locker; emits Listed |
| FeeStyleHook | the hook on every Longevity pool: it sets each swap's fee; quoteFee(key, params) gives the fee a swap pays now. Its address differs per chain |
| AlignmentVault | registers each coin and trades in the open to keep this chain's price in line with Solana's |
| HeldFees | this chain's books for creator trading fees and holder rewards |
| StakeVault | where a holder stakes a coin on this chain |
| FeeRouter | receives Longevity's side of the trading fees |
| OtcDesk | settles an OTC deal wallet to wallet in one transaction; it never touches a pool |
No Longevity contract address is published for this chain.
Uniswap v4 (canonical deployments, swap layout v1)
- poolManager
0x498581fF718922c3f8e6A244956aF099B2652b2b- positionManager
0x7C5f5A4bBd8fD63184577525326123B519429bDc- universalRouter
0x6fF5693b99212Da76ad316178A184AB56D299b43
No Longevity contract address is published for this chain.
Uniswap v4 (canonical deployments, swap layout v2)
- poolManager
0x8366a39CC670B4001A1121B8F6A443A643e40951- positionManager
0x58daec3116aae6D93017bAAea7749052E8a04fA7- universalRouter
0x8876789976decbfcbbbe364623c63652db8c0904
No Longevity contract address is published for this chain.
Uniswap v4 (canonical deployments, swap layout v1)
- poolManager
0x28e2Ea090877bF75740558f6BFB36A5ffeE9e9dF- positionManager
0x7A4a5c919aE2541AeD11041A1AEeE68f1287f95b- universalRouter
0x1906c1d672b88cD1B9aC7593301cA990F94Eae07
No Longevity contract address is published for this chain.
Uniswap v4 (canonical deployments, swap layout v2)
- poolManager
0x12D4Fd9C5DeDd00ab8a0bCe2CF0167bbf94b6B1F- positionManager
0x0d7Ab5B3db668128Aff6F70C4eBC71D7d4DA9bf9- universalRouter
0x9aFe3C497e19501DB228F28CdBdD29bC98F65DBa
An address appears here only for a chain whose status is live. The same list is under chains in /api/integrate/kit.json, where an address that is not published is null.
Events to index
Signatures and topic0 computed from the same ABI the indexer decodes with, so they cannot drift.
Watch the AlignedListingFactory for Listed, then filter PoolManager.Swap by the pool ids it announces (topic1 = poolId). The last column says where each event lands in the read model (db/schema.sql); the JSON API exposes those tables.
| Event | Emitter | topic0 | Lands in |
|---|---|---|---|
| Listedevent Listed(address indexed token, uint256 indexed tokenId, address indexed lister, address quote, bytes32 poolId, int24 startTick, uint24 lpFee, uint256 amount, string metadataURI) | AlignedListingFactory | 0xad5a4aaa469875ff13658232c22a8ba97398205fa40bdf452cdbd83b1ee2d117 | bb_listings + bb_launches (kind listing) + bb_launch_pools (one row per pool)a coin's pool opened on this chain: token, tokenId (the position in the factory's locker), quote, poolId, startTick, lpFee, amount. Its metadataURI is a fixed marker, not a URL: read the coin's metadata from the Solana mint |
| Swapevent Swap(bytes32 indexed id, address indexed sender, int128 amount0, int128 amount1, uint160 sqrtPriceX96, uint128 liquidity, int24 tick, uint24 fee) | PoolManager (Uniswap v4) | 0x40e9cecb9f5f1f1c5b9c97dec2917b7ee92e57ba5563708daca94dd84ad7112f | bb_launch_swaps (filtered by the pool ids Listed announced: topic1 = poolId) + rolling price / volume / buys / sells on bb_launches and bb_launch_poolsevery trade on a coin's pool; the quote is currency0 on every Longevity pool |
Amounts in events are raw integers in the quote's decimals; the coin's token always has 18 decimals. TwinDeployed, which joins a token to its Solana mint, is on the indexing guide.
Prices and progress bars
The formulas the site uses, written for another codebase.
On Solana the price and the progress bar come from the DBC pool account, and after graduation from the DAMM v2 pool. On an EVM chain the price comes from sqrtPriceX96 (the Swap event or StateView.getSlot0(poolId)), quote first. The API already gives every swap and price quote first.
- Solana progress
- progress = quoteReserve / migrationThreshold, both read from the DBC pool accountA coin is completed once its pool has migrated.
- EVM pool, tokens per quote
- tokensPerQuote = (sqrtPriceX96 / 2^96)^2 * 10^(quoteDecimals - 18)Uniswap's raw price is token-wei per smallest quote unit; the power of ten converts to whole quote units.
- EVM pool, quote per token
- priceQuote = 1 / tokensPerQuote
- From a tick
- tokensPerQuote = 1.0001^tick * 10^(quoteDecimals - 18)The opening price is the start tick:
startTickinListed. - Market cap
- fdvQuote = priceQuote * supply; usd = fdvQuote * quoteUsd. supply is the coin's one supply across every chain (the Solana supply), not this chain's totalSupply
Metadata and logos
Off-chain, on this domain, referenced from the Solana mint.
The mint's Metaplex uri is https://longevity.trading/api/meta/<mint>. It answers the JSON below and exists the moment the coin does. A coin's token on another chain has no metadata of its own: the metadataURI in Listed is a fixed marker, not a URL, so read the coin's name, logo and links from its Solana mint (TwinDeployed.solanaMint). Every list and feed row already carries image_url, so the list endpoints are enough to render logos. Cache metadata for an hour, as the header says.
{
"name": "My Coin",
"symbol": "MYC",
"description": "…",
"image": "https://longevity.trading/api/launch/solana/blind/img/<hash>",
"external_url": "https://longevity.trading/t/solana/<mint>",
"extensions": { "website": "https://…", "twitter": "https://x.com/…" }
}REST reference
Every public read endpoint of the EVM index. The engine's endpoints are in section 01 and on the agents guide. The same list, as OpenAPI 3.1: /api/openapi.json.
/api/launch/listBrowse launches. The list every tab of the home page reads. Raw amounts are decimal integer strings in the quote's decimals (`quote_decimals`); `price_quote` / `fdv_quote` are numbers in the quote asset; `*_usd` fields are null when the quote has no price.
chain=base|robinhood|bnb|hyperevm sort=live|new|mcap|volume|gainers|holders window=1h|24h|all filter=fee0|burn|usdg|gitlawb|today|stock|holders|platform|parasite|posters limit offset quote format=json|csvcache: public, s-maxage=2, stale-while-revalidate=10 example: /api/launch/list?chain=base&sort=new&limit=50/api/launch/liveOne call for a live page. The activity feed, the site totals, the trending strip and (with `sort`) one list page, in one response. The site polls it every ~5 s.
chain=base|robinhood|bnb|hyperevm sort=live|new|mcap|volume|gainers|holders window=1h|24h|all filter=fee0|burn|usdg|gitlawb|today|stock|holders|platform|parasite|posters limit offset quotecache: public, s-maxage=2, stale-while-revalidate=10 example: /api/launch/live?chain=base&sort=live&limit=40/api/launch/feedLatest launches and trades. The newest 24 launch and swap events across every chain, newest first.
format=json|csvcache: public, s-maxage=2, stale-while-revalidate=10 example: /api/launch/feed/api/launch/searchSearch by name, symbol or address. Substring match on name / symbol, exact match on a token address; at most 20 rows.
q* chain=base|robinhood|bnb|hyperevmcache: public, s-maxage=5, stale-while-revalidate=30 example: /api/launch/search?q=pepe&chain=base/api/launch/candlesOHLCV candles. Sparse whole buckets in quote per token (multiply by `quote.usd` for dollars), at most 2000 including the current bucket; fill gaps from `baseline.price`. `launch.price` is the opening price from the start tick.
chain*=base|robinhood|bnb|hyperevm token* interval=1m|5m|15m|1h|4h|1d from walletcache: public, s-maxage=5, stale-while-revalidate=30 example: /api/launch/candles?chain=base&token=0x...&interval=5m/api/launch/holdersHolder distribution. Top holders, concentration, the creator's position and sniper-window buyers. `synced` is false while the token's transfer history is still being backfilled.
chain*=base|robinhood|bnb|hyperevm token*cache: no-store (5 s server memo) example: /api/launch/holders?chain=base&token=0x.../api/launch/rewardsReward-coin payouts. The holder-reward payouts the index has recorded for one coin on one chain.
chain*=base|robinhood|bnb|hyperevm token* walletcache: no-store (5 s server memo) example: /api/launch/rewards?chain=base&token=0x.../api/launch/sistersSister-coin candidates. Coins on one chain quoted in the same asset, for a sister-coin picker.
chain*=base|robinhood|bnb|hyperevm quote* qcache: no-store example: /api/launch/sisters?chain=base"e=0x.../api/public/v1/feesPublic fee data: totals and per coin. Fees every coin has generated and where they went, from indexed events only, in the buckets the response names. Totals per chain and quote asset across all coins (quote legs only: coin legs are different tokens); one page of coins with both legs. Every bucket: { amount | quote + coin, events, txs (its newest tx hashes) }. Solana: fee claims by source, in lamports. Raw integer strings, no USD. CORS open; unknown parameters are refused at the edge; a busy database answers 503 + retry-after.
chain=base|robinhood|bnb|hyperevm limit offsetcache: public, s-maxage=60, stale-while-revalidate=300 example: /api/public/v1/fees?chain=base&limit=50/api/public/v1/fees/{chain}/{token}Public fee data: one coin, event by event. One coin's fee breakdown (generated, the buckets it went to, a summary, reconciled per leg) and its fee events newest first, each with tx_hash and log_index. chain = solana takes a mint and returns that coin's fee claims by source.
{chain}*=base|robinhood|bnb|hyperevm|solana {token}* limit offsetcache: public, s-maxage=60, stale-while-revalidate=300 example: /api/public/v1/fees/base/0x.../api/launch/meta/{token}Token metadata by address. Name, symbol, description, logo and links the creator registered. The logo is a 512x512 WebP on this domain when it was uploaded here, else the https URL the creator gave.
{token}* chain=base|robinhood|bnb|hyperevmcache: public, max-age=300 example: /api/launch/meta/0x...?chain=base/api/launch/meta/{launcher}/{key}Token metadata by its on-chain URI. The same metadata addressed by a launcher address and a 32-byte key. Same JSON as the by-address form. A Longevity pool's Listed event does not carry this form: use the by-address form, or the Solana mint's own uri.
{launcher}* {key}*cache: public, max-age=300 example: /api/launch/meta/0x<launcher>/0x<key>/api/voteAdvisory holder votes. For a launch with a fee module: the proposals to switch its mode, their tallies (weight = min(balance when voting, balance at close), from the holder index) and, with `wallet`, that wallet's own vote. Advisory only: the creator decides; a vote changes nothing on-chain.
chain*=base|robinhood|bnb|hyperevm token* walletcache: no-store example: /api/vote?chain=base&token=0x.../api/quotesQuote assets on a chain. The fixed quotes (ETH; USDG on Robinhood Chain) and the chain's tokenized-stock registry with live USD prices. Only registry addresses are ever labelled stocks.
chain*=base|robinhood|bnb|hyperevm qcache: no-store (30 s server memo) example: /api/quotes?chain=base&q=AAPL/api/quotes/inspectCan this ERC-20 be a quote?. On-chain reads, a market-depth check and (Base) a token-safety scan for an arbitrary quote coin. Per-IP limit: 30 per minute.
chain*=base|robinhood|bnb|hyperevm address*cache: no-store (10 min server cache) example: /api/quotes/inspect?chain=base&address=0x.../api/healthIndex freshness. Database reachability and the indexer cursor per chain (block lag, last run, last error).
cache: no-store example: /api/health/api/integrate/kit.jsonThis kit, machine-readable. The Solana launch facts, the EVM contracts with their addresses on a live chain, Uniswap v4 addresses, event signatures and topics, the REST reference and the stream description; versioned.
cache: public, s-maxage=60, stale-while-revalidate=300 example: /api/integrate/kit.json/api/openapi.jsonOpenAPI 3.1. The public read API, this kit and the stream as an OpenAPI 3.1 document.
cache: public, s-maxage=300, stale-while-revalidate=3600 example: /api/openapi.json/api/streamReal-time events (SSE). Server-sent events: new coins, swaps, holder-reward payouts and fee events as the indexer writes them. Resume with `Last-Event-ID` or `since=`.
chain=base|robinhood|bnb|hyperevm sincecache: no-store example: /api/stream?chain=baseCSV. /api/launch/list and /api/launch/feed also answer ?format=csv: the same rows as text/csv, RFC 4180 with CRLF line endings, one header line then one line per row. Amounts stay decimal integer strings in the same units as the JSON. Coin names and symbols are written by whoever launched the coin, so a field that starts with =, +, - or @ is prefixed with a single quote: a spreadsheet must not treat a coin name as a formula.
Raw token and quote amounts are decimal integer strings; use quote_decimals, never a blanket 18. price_quote and fdv_quote are numbers in the quote asset; price_usd, fdv_usd and volume_usd are dollars and null when the quote has no price.
Caching: s-maxage is the CDN window per endpoint (2 s on the hot lists, 5 s on candles and search, 300 s on metadata); responses with no-store are memoised a few seconds server-side. When the database is busy a cached read answers 503 with retry-after: 2: keep your last data and retry. Unknown query parameters are refused with 400 at the edge on the cached endpoints. /api/quotes/inspect allows 30 calls per IP per minute. Poll modestly; for anything real-time use the stream below.
curl -s "https://longevity.trading/api/integrate/kit.json" | jq '.chains.base.events[] | {name, contract, topic0}'
curl -s "https://longevity.trading/api/openapi.json" | jq '.paths | keys'# every coin indexed on Base, newest first, as CSV
curl -s "https://longevity.trading/api/launch/list?chain=base&sort=new&limit=200&format=csv" > coins.csv
# the latest coins and trades
curl -s "https://longevity.trading/api/launch/feed?format=csv" > trades.csvReal-time stream
Server-sent events over plain HTTP. No socket library, no key.
GET /api/stream emits new rows of the EVM index as the indexer writes them, polling the index every 2 s and sending a : ping comment every 15 s. A connection closes cleanly after about 290 s; every event's id is a cursor, so reconnecting with Last-Event-ID (which EventSource does on its own) resumes exactly after the last event you saw. Optional chain= narrows to one chain; optional since= takes a cursor or a moment (unix seconds, unix ms or an ISO date, at most 24 h back) to replay before following; absent, the stream starts at the head.
# follow every chain from now on
curl -N "https://longevity.trading/api/stream"
# one chain, resuming from the last id you processed (what EventSource sends on its own)
curl -N -H "Last-Event-ID: v1.120.5531.7.40.12.9" "https://longevity.trading/api/stream?chain=base"
# or from a moment (unix seconds, unix ms or an ISO date; at most 24 h back)
curl -N "https://longevity.trading/api/stream?since=2026-09-14T00:00:00Z"event: ready
id: v1.120.5531.7.40.12.9
retry: 3000
data: {"cursor":"v1.120.5531.7.40.12.9","chain":"base","poll_ms":2000,"publish_lag_s":3,"lifetime_s":290,"page_limit":200}
event: swap
id: v1.120.5532.7.40.12.9
data: {"chain":"base","chain_id":8453,"token":"0x…","pool_id":"0x…","trader":"0x…","is_buy":true,"amount0":"-50000000000000000","amount1":"1234567000000000000000000","sqrt_price_x96":"…","tick":183800,"block_number":37000000,"block_time":"2026-09-14T12:00:02.000Z","tx_hash":"0x…","log_index":12}
: ping| event | data |
|---|---|
| ready | { cursor, chain, poll_ms, publish_lag_s, lifetime_s, page_limit } once per connection; its id is the resolved start cursor |
| launch | a new bb_launches row: { chain, chain_id, token, token_id, launcher, creator, quote, pool_id, kind, curve, hooks, start_tick, lp_fee, supply, name, symbol, metadata_uri, reward_pool, fee_vault, block_number, block_time, tx_hash, log_index } |
| swap | a new bb_launch_swaps row (quote = currency0 convention): { chain, chain_id, token, pool_id, trader, is_buy, amount0, amount1, sqrt_price_x96, tick, block_number, block_time, tx_hash, log_index } |
| curve | a bb_curve_launches row was inserted or changed (graduation, sweep, refund, redemption): { chain, chain_id, token, curve, pool_id, phase, graduated, refunding, refund_venue, refund_quote, refund_supply, redeemed, abandoned_at, updated_at } |
| reward | a bb_rewards row: { chain, chain_id, token, pool, round, holder, amount, block_number, block_time, tx_hash, log_index } |
| burn | a bb_burns row: { chain, chain_id, kind, round, currency, amount_in, burned, to, block_number, block_time, tx_hash, log_index } |
| split | a bb_fee_splits row: { chain, chain_id, currency, treasury_amount, payee_amount, block_number, block_time, tx_hash, log_index } |
| unavailable | { reason } then the server closes (no database, or the database is busy): reconnect after `retry` |
Cursor design: the id is v1 followed by one insertion-sequence position per table of the index. A row is published only once its insert is 3 s old, so an insert whose transaction commits late is never skipped past; a block number or a block time would not work as a cursor because the chains' indexers lag differently and the reorg re-scan writes old blocks late. Each poll reads at most 200 rows per table and polls again at once when a page was full, so a reconnect catches up quickly. Delivery is at-least-once within a connection and exactly-once across reconnects when you resume from the last id you processed.
Latency is the indexer's: the cron polls the chains about once a minute, and POST /api/launch/sync?chain=&tx= indexes one transaction at once. Without a database the stream sends one event: unavailable and closes; the retry hint makes clients reconnect.
const es = new EventSource("https://longevity.trading/api/stream?chain=base");
es.addEventListener("launch", (e) => index(JSON.parse(e.data)));
es.addEventListener("swap", (e) => trade(JSON.parse(e.data)));
// the browser reconnects with Last-Event-ID = the last id it saw; nothing is missedBrand assets and contact
The mark, one render at every size listings ask for.
Platform name: longevity.trading. The mark on ink #0B0F0E; accent mint #34D3A6.Contact: @Longevitylaunch on X