CHAIN
launch

docs

Coins quoted in other coins.

CHAIN launches pump.fun coins whose bonding curve is priced in another pump.fun coin. This page covers how that works, what you can and can't do, and the API behind the site.

Overview

On pump.fun a coin's curve is normally priced in SOL. Pump also lets a curve be priced in another pump.fun coin. We build on that.

When you launch on CHAIN you pick a parent. Your coin's curve is quoted in that parent, so every buy of your coin is also a buy of the parent, and of the parent's parent, all the way up to a SOL root. Coins linked this way form a family tree, and the home page ranks those trees.

PieceWho runs it
Bonding curvespump.fun. Every coin here is a normal pump.fun coin, listed on pump.fun itself.
Quote currencySet once at creation and stored on the curve. It never changes.
RoutingCHAIN builds one transaction that hops through each curve in the chain.
CustodyNone. You sign every transaction in your own wallet.
TermMeaning
RootA coin quoted in SOL (or a base pump.fun allows, like USDC). Generation 0.
ParentThe coin your coin is quoted in. Your curve holds parent tokens, not SOL.
ChildA coin quoted in yours. Anyone can launch one.
GenerationHow many links sit between a coin and its root. G0 is the root, G1 its child, and so on.
Family treeA root and every coin launched under it here.
RouteThe path a trade takes, e.g. SOL → ROOT → CHILD → YOURS.

Launching a coin

One signature. The mint key is generated and signed on the server, so you only approve once.

  1. 1

    Pick a parent, or none

    Paste any pump.fun mint, on its curve or graduated. We check its generation against the live limit before you fill anything in. Leave it empty to start a SOL root.
  2. 2

    Name, ticker, image

    Name up to 32 characters, ticker up to 10 letters or numbers, image PNG, JPEG, GIF or WebP under 3.5 MB.
  3. 3

    Optional dev buy

    Bought in the same transaction as the create. For a child it's an amount of the parent coin, so you need to hold some. For a root it's SOL, capped at 50.
  4. 4

    Sign and land

    The server checks the signed bytes match what it built, then sends it. The coin appears on the board within seconds.

Trading a chain

You trade with SOL. We do the hops.

A buy of a G2 coin swaps SOL into the root, the root into the G1 coin, and the G1 coin into yours, in one atomic transaction. If any hop fails, nothing happens. Sells run the same path backwards and pay out in SOL.

SettingDetail
SlippageDefault 5%, from 0.1% to 50%. It protects the final output of the whole route.
FeesEach hop is a normal pump.fun trade, so each hop pays pump.fun’s usual fee.
Creator feesEvery coin launched here is a pump.fun holder-rewards coin: its creator is the holder-rewards account, so creator fees are paid out to holders, not to the launcher. This is set at creation and is permanent.
Graduated coinsRoutes through the PumpSwap pool instead of the curve, automatically.
Roots not in SOLIf a root is quoted in USDC or another base, the route starts from that base.

pump.fun's program allows chains up to 5 generations deep, but the limit it actually enforces is a setting it can change. We read it live from pump's global account.

Enforced right now

G2

Deepest generation you can launch today.

Program cap

G5

Unlocks only if pump.fun raises the setting.

The board, search, feed and coin pages only show coins launched through CHAIN. You can still launch a child of any pump.fun coin; that outside parent appears in your coin's lineage as plain text, without a page.

API basics

The site runs on the same public JSON API you can call. No key needed.

Base URLhttps://www.chainpad.tech
FormatJSON in and out, except launch prepare, which is multipart.
TransactionsBase64-encoded v0 transactions. You sign; we never hold keys.
AmountsHuman units as strings, e.g. "0.5" SOL. Decimals are handled for you.

GET/api/parent/:mint

Check whether a coin can be a parent, and what generation your coin would be.

request
curl https://www.chainpad.tech/api/parent/2yPZk2wkw16r1BvDRSqKfqyKQumeCvs9EdUNRetNpump
response
{
  "mint": "2yPZk2wkw16r1BvDRSqKfqyKQumeCvs9EdUNRetNpump",
  "source": "pumpCoin",
  "depth": 1,
  "decimals": 6,
  "maxDepth": 2,
  "symbol": "EXAMPLE",
  "name": "Example coin",
  "icon": "https://…",
  "mcap": 182400,
  "allowed": true
}

Your coin would be generation depth + 1. allowed is false once the parent already sits at the live limit.

POST/api/launch/prepare

Multipart form with an image file and a data field holding JSON.

FieldDescription
launcherYour wallet address. It pays and signs.
name1 to 32 characters.
symbol1 to 10 letters or numbers. A leading $ is dropped.
descriptionOptional, up to 600 characters.
parentOptional parent mint. Omit for a SOL root.
devBuyOptional. Parent-coin amount for a child, SOL for a root (max 50).

Returns { mint, depth, tx }.

POST/api/launch/confirm

Send { mint, tx } with the signed transaction. Anything other than the exact prepared transaction is rejected with 422. Calling it again after success returns the same signature.

launch.ts
import { VersionedTransaction } from '@solana/web3.js'

const b64 = (bytes: Uint8Array) => btoa(String.fromCharCode(...bytes))
const fromB64 = (s: string) => Uint8Array.from(atob(s), (c) => c.charCodeAt(0))

export async function launchChild(wallet: Wallet, image: File) {
  // 1. Prepare: the server pins metadata and builds the create transaction.
  const form = new FormData()
  form.append('image', image)
  form.append(
    'data',
    JSON.stringify({
      launcher: wallet.publicKey.toBase58(),
      name: 'Grandchild',
      symbol: 'GRAND',
      description: 'Quoted in its parent, not SOL.',
      parent: '2yPZk2wkw16r1BvDRSqKfqyKQumeCvs9EdUNRetNpump', // omit for a SOL root
      devBuy: '1000', // optional, in the parent coin
    }),
  )
  const prepared = await fetch('https://www.chainpad.tech/api/launch/prepare', { method: 'POST', body: form })
    .then((r) => r.json())
  if (prepared.error) throw new Error(prepared.error)

  // 2. Sign: one signature from the launcher. The mint key is already on it.
  const tx = VersionedTransaction.deserialize(fromB64(prepared.tx))
  const signed = await wallet.signTransaction(tx)

  // 3. Confirm: the server checks it is the exact transaction it built, then sends it.
  const done = await fetch('https://www.chainpad.tech/api/launch/confirm', {
    method: 'POST',
    headers: { 'content-type': 'application/json' },
    body: JSON.stringify({ mint: prepared.mint, tx: b64(signed.serialize()) }),
  }).then((r) => r.json())
  if (done.error) throw new Error(done.error)

  return { mint: done.mint, signature: done.signature, generation: prepared.depth }
}

POST/api/trade

One endpoint, four actions. route and quote need no wallet.

actionBodyReturns
routemint, sidepath, hops, currency
quote+ amount+ amountOut
prepare+ user, slippageBps+ minOut, tx
sendmint, user, tx (signed)signature
quote
curl -X POST https://www.chainpad.tech/api/trade \
  -H 'content-type: application/json' \
  -d '{"action":"quote","mint":"<coin>","side":"buy","amount":"0.5"}'
response
{
  "path": ["So111…1112", "<root>", "<child>", "<coin>"],
  "hops": ["SOL → ROOT", "ROOT → CHILD", "CHILD → COIN"],
  "currency": "SOL",
  "amountOut": 1843210.55
}
trade.ts
// Buy 0.5 SOL worth of any coin launched here, however deep it sits.
const prepared = await post({
  action: 'prepare',
  mint: coin,
  side: 'buy',
  amount: '0.5',
  user: wallet.publicKey.toBase58(),
  slippageBps: 500, // 5%, applies to the final output
})

const signed = await wallet.signTransaction(
  VersionedTransaction.deserialize(fromB64(prepared.tx)),
)

const { signature } = await post({
  action: 'send',
  mint: coin,
  side: 'buy',
  user: wallet.publicKey.toBase58(),
  tx: b64(signed.serialize()),
})

function post(body: object) {
  return fetch('https://www.chainpad.tech/api/trade', {
    method: 'POST',
    headers: { 'content-type': 'application/json' },
    body: JSON.stringify(body),
  }).then(async (r) => {
    const json = await r.json()
    if (!r.ok) throw new Error(json.error)
    return json
  })
}
EndpointReturns
GET /api/feedRecent trades on coins launched here. Cached 15 s.
GET /api/search?q=Coins launched here matching a name, ticker or mint.
GET /api/coin/:mint/treeChildren and grandchildren launched here.
GET /api/coin/:mint/candles?tf=OHLCV candles. tf is 1m, 5m, 15m, 1h, 4h or 1d.
GET /api/coin/:mint/tradesThe last 50 trades.
GET /api/balances?owner=&mints=Token balances for up to 8 comma-separated mints.
examples
# Live trades on coins launched here
curl https://www.chainpad.tech/api/feed

# Children and grandchildren of a coin
curl https://www.chainpad.tech/api/coin/<mint>/tree

# Candles: 1m 5m 15m 1h 4h 1d
curl "https://www.chainpad.tech/api/coin/<mint>/candles?tf=15m"

# Search coins launched here by name, ticker or mint
curl "https://www.chainpad.tech/api/search?q=grand"

Failures return a non-2xx status and a readable message you can show to users as-is.

error
{ "error": "That chain is already as deep as pump.fun allows." }
StatusWhen
400Bad input: invalid address, name too long, depth limit reached.
401Trade prepare without a wallet.
404Unknown launch, or a coin not launched here.
422Signed transaction does not match what was prepared.
5xxSolana RPC or upstream trouble. Safe to retry.
Can I launch under a coin I didn’t create?

Yes. Any pump.fun coin can be a parent, as long as its chain is below the live depth limit.

Does buying my coin really buy the parent?

Yes. Your curve can only accept the parent coin, so every SOL buy first acquires parent tokens on the open market.

What happens when my coin graduates?

It moves to a PumpSwap pool paired with its parent, just like a SOL coin pairs with SOL. Routing switches over automatically.

Can the quote currency change later?

No. It is fixed in the curve at creation.

Do you hold my funds?

No. Every launch and trade is a transaction you sign in your own wallet.