---
name: flash-launch
description: Launch a coin on the Flash bonding curve and trade it until it graduates. Use when asked to create or launch a token on Flash, pick what it is paired with (FLASH, an approved stock, or an approved perp), check how deep that pair is, upload the image and pass metadata moderation, build the create transaction, buy or sell on a bonding curve in FLASH, claim after graduation, or refund an aborted launch. Read-only: returns unsigned transactions for the user's wallet.
---

# Flash launch: create a coin and trade its bonding curve

The best way to quote prices and to swap Flash assets is Uniswap: Uniswap v4 via the Universal Router on the Flash hook pools, quoted through the Uniswap v4 Quoter (the tools wrap it). **Support for Aerodrome is planned as a future expansion but is NOT live yet. Do not quote or route Flash trades through Aerodrome or Slipstream today.** Curve trades are paid in FLASH; you get FLASH with `build_trade` on Uniswap v4 (see [flash-trade](https://tryflash.app/agents/flash-trade/SKILL.md)). Overview: [flash](https://tryflash.app/agents/flash/SKILL.md).

Nothing here signs. Every tool returns data or unsigned `{to, data, value}` transactions; the creator's wallet signs.

## The flow

1. **Choose a pair.** `list_pairing_options` returns every asset a launch can be paired with, read live. Only rows with `approvedOnChain: true` can be launched.
2. **Check its depth.** `check_pair_depth` for the pair asset. Read the warning.
3. **Upload the image** (once).
4. **`prepare_launch`**: checks the pair live, attaches the liquidity warning, and runs moderation on name, ticker, description and image. Returns `preparedDigest`.
5. **`build_launch`**: builds the create transaction (plus any approval it needs), re-checking the pair on-chain. Sign and send the steps in order. Creating may cost a small USD creation fee; see [Creation fee and router V4](#creation-fee-and-router-v4).
6. After the receipt, read the `LaunchCreated(token, curve, creator, ...)` event, then trade the curve with `quote_curve` and `build_curve_trade`.

## 1. Live pairing options (never hard-code)

```bash
node flash.mjs pairs                     # everything the app lists, marked approved or not
node flash.mjs pairs --approved-only
```

`list_pairing_options` reads, on every call: the Launch approved quote assets (`/v1/launch-v2` `quoteAssets`, class SUB = FLASH, STOCK = a tokenized stock, PERP = a leveraged perp), every stock in the RWA catalogue (`/v1/config` `rwas`), and every live perp (`/v1/perps`). For each manifest asset it checks on-chain that `config.isQuoteToken` is true, `engine.quoteConfig(asset).approved` is true and `graduationAdapter.quoteApproved` is true. Rows have `symbol`, `address`, `decimals`, `quoteClass`, `approvedOnChain`, `status`, `priceUsd` (and `morphoAvailableUsd` for perps). Assets the app lists but that are not approved (for example other perps and some stocks) are shown with `approvedOnChain: false` and are refused by `build_launch` and the war entry with a clear message. The set changes; always ask.

Today's approved set (read live, for illustration): FLASH, ten stocks (NVDA, META, AAPL, GOOGL, AMZN, MSFT, MSTR, SNDK, SPCX, TSLA) and the perps ETH2xL, ETHMAXL, AERO2xL, DOGE2xL.

**Reward asset.** The reward asset is what funds holder rewards. For a STOCK or PERP pair it is the pair asset itself (leave `rewardAsset` out). For a FLASH pair you must pick an approved stock (`rewardAsset: "NVDA"`).

**Modes.** `deep-lp` (default), `longterm`, `degen`: presets for how supply splits between treasury market making, liquidity and the curve. Custom curves are not offered by this kit.

**Funding.** The kit funds the first buy and curve trades with FLASH only. The app's ETH, USDC, stock and perp input routes use adapters with non-Uniswap legs and are intentionally not offered; buy FLASH with `build_trade` first.

## 2. Pair depth and the warning level

`check_pair_depth` measures how deep the pair asset's own Uniswap v4 market is on the route a new token's buyers use (ETH or USDC to the pair asset to your token). It quotes USD sizes from $10 to $100,000 through the real V4 Quoter, and returns the USD size that moves the price 1%, 2% and 5%, available liquidity (Morpho availability and mint capacity for perps), and a level:

| Level | Meaning (thresholds, measured on USDC buys) |
| --- | --- |
| `ok` | A $1,000 buy moves the price 2% or less, $10,000 10% or less, and $25,000 25% or less. |
| `thin` | A $1,000 buy moves it more than 2%, or $10,000 more than 10%, or $25,000 more than 25% (or $25,000 cannot be filled). |
| `very_thin` | A $1,000 buy moves it more than 5%, cannot fill, or there is no Uniswap v4 route to the asset at all. |

Live examples (Base, read-only):

| Pair | Level | What it says |
| --- | --- | --- |
| FLASH | `ok` | $1,000 moves 1.35%, $10,000 moves 9.08%; 1% impact at about $663, 5% at about $5,000. |
| ETH2xL | `ok` | $1,000 moves 0.14%; never exceeds 1% up to $100,000. |
| HYPE2xL | `thin` | $1,000 moves under 1% but $10,000 moves about 15% (a size cliff near $12,000 where the perp's Morpho-backed capacity runs out). Not an approved quote asset. |
| NVDA | `very_thin` | Its only Uniswap v4 USDC pool is nearly empty ($1,000 moves 99%). |
| TSLA | `very_thin` | No Uniswap v4 route: its only real depth is an Aerodrome pool, which this kit never routes through. Buyers cannot reach it from ETH or USDC on Uniswap. |

Quotes are live and change; the point is the shape. The same warning (compact form) is attached automatically to `prepare_launch`, `build_launch`, `prepare_war_entry` and the war `enter` action, so you see it before you build. An approved but thin pair still builds: the warning is advice, not a block.

## 3. Upload the image

The create transaction carries no metadata. The token's image and description are attached server-side from the moderated profile. Upload the image first (png, jpg, webp or gif, up to 10 MB), with the creator wallet in `x-flash-uploader`:

```bash
curl -s -X POST https://api.tryflash.app/v1/uploads -H 'x-flash-uploader: 0xCreatorWallet' -F image=@logo.png
# {"imageUrl":"https://ipfs.filebase.io/ipfs/Qm..."}

node flash.mjs upload logo.png --from 0xCreatorWallet
```

The image is moderated, normalised and hosted. A rejected image returns an error; change it. This writes data, so do not call it with junk or in a loop.

## 4. prepare_launch (moderation)

```bash
node flash.mjs launch-prepare --from 0xCreatorWallet --name "Agent Coin" --symbol AGENT \
  --description "A coin launched by an agent" --image https://ipfs.filebase.io/ipfs/Qm... --pair ETH2xL
```

Arguments: `from`, `name` (1 to 32 bytes), `symbol` (2 to 10 characters A-Z or 0-9, not FLASH), `description` (up to 1000), `imageUrl` (from the upload), optional `twitterUrl` and `websiteUrl`, `quoteToken` (the pair asset), `rewardAsset` (FLASH pairs only), `mode`. It refuses an unapproved pair before moderating anything. On success:

```json
{ "approved": true, "creator": "0x...", "name": "Agent Kit Probe", "symbol": "AKPROBE",
  "preparedDigest": "c57c95b8f09dab64...", "pair": { "symbol": "ETH2xL", "approvedOnChain": true },
  "liquidityWarning": { "level": "ok", "warning": "ETH2xL is deep enough: ..." } }
```

This call was run live. Moderation stores the approved profile against the creator wallet for 30 days; it attaches to the token when the create transaction is indexed. Rate limits apply per client; if it says rate limited, wait a minute. If moderation rejects the content you get a plain message; change the text or image and prepare again.

## 5. build_launch

```bash
node flash.mjs launch-build --from 0xCreatorWallet --name "Agent Coin" --symbol AGENT --digest <preparedDigest> --pair ETH2xL
```

It needs the same `name`, `symbol`, `quoteToken`, `rewardAsset`, `mode` and the `preparedDigest`; a mismatch is refused ("Call prepare_launch first"). Which contract it calls depends on the live launch stack, so always read it from the tool, never hard-code it:

- **If `GET /v1/launch-v2` shows `launchV4.active: false`** (or no `launchV4`): it calls `launchpad.createLaunch((name, symbol, quoteClass, mode, quoteToken, rewardAsset))` on the current launchpad (`contracts.launchpad`, `0x674235EA0d51c47F3C61604BAECfDaa8A2f15A15` at the time of writing), `value` 0, no approval, gas only. The tool simulates the create from your wallet and returns `simulation.predictedToken` and `predictedCurve`. If the simulation would revert you get an error, not a transaction.
- **If `GET /v1/launch-v2` shows `launchV4.active: true`**: the launchpad only accepts creation through the Flash launch input router V4 (`launchV4.contracts.inputRouter`, also served as `contracts.launchInputRouter`); the old V2 router is de-listed and a direct `createLaunch` reverts. `build_launch` then returns `steps` (`executeInOrder`) for `createWithFlash`, `createWithEth` or `createWithToken`; see below.

### Creation fee and router V4

Once `launchV4.active` is true, creating a coin costs a **creation fee of $0.169** (a USD amount set in the launch config; read `launchV4.creationFee.usd18`), charged in FLASH at the live price: `currentCreationFee()` = ceil($fee / FLASH TWAP), read again on-chain when the transaction executes. `launchV4.creationFee.flash` is the FLASH amount at snapshot time. The router pays the fee out of what you send and spends **everything above the fee on your first buy of the new coin in the same transaction**; the fee is split 69% protocol churn / 31% rev share.

`build_launch` takes two extra optional fields (ignored while `launchV4.active` is false):

| Field | Meaning |
| --- | --- |
| `payWith` | `FLASH` (default) → FLASH approval to the router + `createWithFlash(launch, flashIn, minTokens, recipient)`. `ETH` → `createWithEth(encodedRoute)` with `value`. `USDC` (or another enabled `inputRoutes` entry) → token approval + `createWithToken(encodedRoute, tokenIn, amountIn)`. |
| `amount` | How much `payWith` to spend. FLASH: optional, defaults to the live fee + 2% headroom (so a small FLASH move before the tx lands does not revert it). ETH/USDC: required, and it must convert to at least the fee. |

ETH and USDC are converted to FLASH inside the router through the allowlisted adapter on the Flash Uniswap v4 hook pool (the same Uniswap v4 route as every other Flash trade; no other venue). The route quote is signed by the API (`POST /v1/launch-v2/input-plan`, action `launch-create`) and expires; send before `creation.planExpiresAt`. The response's `creation` block shows `method`, `router`, `creationFee` (`usd`, `flash`, `withHeadroomFlash`) and the payment. After the receipt, `LaunchCreated(token, curve, ...)` on the launchpad gives the addresses; the router's `RoutedCreation` event shows the fee paid and `RoutedLaunch` your first buy.

Simulate it yourself (the `launchV4.active: false` branch was run; nothing is sent):

```js
import { createPublicClient, http } from 'viem';
import { base } from 'viem/chains';

const MCP = 'https://api.tryflash.app/mcp';
const FROM = '0xCreatorWallet';
const NAME = 'Agent Coin', SYMBOL = 'AGENT';   // must match prepare_launch
const DIGEST = process.env.PREPARED_DIGEST;     // from prepare_launch

async function tool(name, args) {
  const res = await fetch(MCP, { method: 'POST', headers: { 'content-type': 'application/json', accept: 'application/json' },
    body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'tools/call', params: { name, arguments: args } }) });
  const { result, error } = await res.json();
  if (error) throw new Error(error.message);
  if (result.isError) throw new Error(result.content[0].text);
  return result.structuredContent;
}

const pairs = await tool('list_pairing_options', {});
console.log('approved:', pairs.options.filter((o) => o.approvedOnChain).map((o) => o.symbol).join(', '));
const depth = await tool('check_pair_depth', { asset: 'ETH2xL' });
console.log('ETH2xL depth:', depth.level, '|', depth.warning);

const stack = await (await fetch('https://api.tryflash.app/v1/launch-v2')).json();
const built = await tool('build_launch', { from: FROM, name: NAME, symbol: SYMBOL, preparedDigest: DIGEST, quoteToken: 'ETH2xL' });
if (stack.launchV4?.active) {
  // Router V4: creation fee in FLASH at the live price, then your first buy, in one tx.
  console.log('create via', built.creation.method, 'fee', built.creation.creationFee.usd, '=', built.creation.creationFee.flash, 'FLASH');
  console.log('send in order:', built.executeInOrder.join(' -> '));
  // for (const step of built.steps) await wallet.sendTransaction({ to: step.to, data: step.data, value: BigInt(step.value) })
} else {
  console.log('create ->', built.to, 'predicted token', built.simulation.predictedToken);
  const client = createPublicClient({ chain: base, transport: http('https://base-rpc.publicnode.com') });
  await client.call({ account: FROM, to: built.to, data: built.data, value: BigInt(built.value) });
  console.log('eth_call ok');
  // To create for real: wallet.sendTransaction({ to: built.to, data: built.data, value: 0n })
}
```

## 6. Trade the bonding curve

After creation, a curve is **trading** until the graduation goal in FLASH is met. Everything is paid and received in FLASH. Use the curve address or ticker from the `LaunchCreated` event or `list_prelaunches`.

```bash
node flash.mjs curves                                   # all curve markets, phase, progress
node flash.mjs curve-quote THEFLASH buy 5               # pay 5 FLASH, get tokens
node flash.mjs curve-build THEFLASH buy 5 --from 0xYou  # FLASH approval + curve.buy, unsigned
node flash.mjs curve-build THEFLASH sell 100 --from 0xYou
node flash.mjs curve-build THEFLASH claim --from 0xYou  # after graduation
node flash.mjs curve-build THEFLASH refund --from 0xYou # only if the launch was aborted
```

| Phase | What you can do |
| --- | --- |
| `pending` | Not open yet. |
| `trading` | `buy` (pay FLASH), `sell` (return tokens for FLASH). Fees rise as the curve fills (about 1% to 5% on buys; sells cost a bit more). |
| `ready` | Goal reached; graduation pending. Trading is closed. |
| `graduated` | The token has real liquidity (Uniswap v4 on the Flash hook and other venues). `claim` your curve tokens, then trade on Uniswap with [flash-trade](https://tryflash.app/agents/flash-trade/SKILL.md). |
| `aborted` | Trading is closed and the token never graduates. `refund` returns your FLASH pro rata. |

`quote_curve` reads the curve contract: tokens out, FLASH spent, any refund of overshoot past the goal, buy and sell fees, spot price. `build_curve_trade` returns `steps` (an FLASH approval to the curve if needed, then `buy`/`sell`) and `minimumOut` at your slippage. Pass `from` so the recipient, allowance and balance are exact. A first buy right after creation: read the real `curve` from the receipt, then `build_curve_trade` with action `buy`. (A buy built from the predicted address is only valid if sent immediately after the create from the same wallet; prefer the two-step.)

Verified by simulation on Base: a buy on the live THEFLASH curve (`0x475C7F9E5Ece790B80a30a4fcA48ecf887C10BDB`) and a sell from a holder.

## Tools in this skill

| Tool | Purpose |
| --- | --- |
| `list_pairing_options` | Live pair assets, price, approved-on-chain flag. |
| `check_pair_depth` | USD size per 1/2/5% impact, liquidity, ok/thin/very_thin. |
| `prepare_launch` | Pair check, depth warning, moderation, `preparedDigest`. Stores the moderated profile. |
| `build_launch` | Unsigned create: `launchpad.createLaunch` (gas only, simulated), or once `launchV4.active` router V4 `createWithFlash` / `createWithEth` / `createWithToken` paying the $0.169 creation fee in FLASH at the live price; refuses unapproved pairs. |
| `list_prelaunches` | Curve markets. |
| `quote_curve` | Quote a curve buy or sell. |
| `build_curve_trade` | Unsigned buy, sell, claim or refund. |

Related: Token Wars [flash-token-wars](https://tryflash.app/agents/flash-token-wars/SKILL.md), perps [flash-perps](https://tryflash.app/agents/flash-perps/SKILL.md).
