> For the complete documentation index, see [llms.txt](https://docs.surged.fun/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.surged.fun/integration/sdk/launching.md).

# Launching a token

One transaction creates the token, its curve and, optionally, the creator's first buy.

## Read the terms first

The factory enforces the economics it publishes, and it rejects a launch built against stale ones. Always start from `GET /config`:

```ts
const config = await fetch(`${API}/config`).then((r) => r.json())
const launchConfig = config.launchConfigs.find((c) => c.enabled)
```

That gives you the launch fee, the supply, the trade fee, the phantom reserve, the graduation threshold and the `economicsDigest` you must echo back. A mismatch reverts with `EconomicsMismatch`, which is the contract refusing to launch a token on terms you did not actually see.

## Launch with a first buy

```ts
import { encodeLaunchAndBuy, NATIVE_QUOTE } from '@surged/sdk'

const { data, value } = encodeLaunchAndBuy({
  params: {
    name: 'My Token',
    symbol: 'MYT',
    logoUri: 'ipfs://…',
    description: '…',
    socials: { website: '', twitter: '', telegram: '', discord: '' },
    creatorFeeRecipient: account.address,
    creatorTaxBps: 0,
    expectedEconomics: launchConfig.economicsDigest,
    salt: '0x…',
  },
  launchConfigId: 0n,
  pairToken: NATIVE_QUOTE,
  snipeTaxExemptions: [account.address],
  launchFee: BigInt(config.launchFee),
  quoteIn,
  minTokensOut,
  recipient: account.address,
})

await wallet.sendTransaction({ to: config.addresses.launchForwarder, data, value })
```

`encodeLaunchToken` is the same without the buy.

Three things to get right:

**`salt` decides the token's address.** It derives from the creator and the salt, so the same wallet cannot reuse a salt: the second launch reverts. Use a random 32-byte value.

**`snipeTaxExemptions`** are extra addresses that skip the anti-snipe tax. The `recipient` of the buy inside the launch is exempt automatically, and so is every buyer of a bundle, so you do not need to list them. Add an address only if it will buy in the first blocks from a separate transaction.

**`creatorTaxBps` is permanent.** It is fixed at launch and cannot be changed afterwards. `maxCreatorTaxBps` from `/config` is the ceiling.

## Finding the token afterwards

The launch emits the token and curve addresses, and the indexer picks them up within a block or two. Read the token address out of the receipt's logs, then either poll `GET /launches/{token}`, which answers 404 until the indexer catches up, or subscribe to `feed` on the websocket, which pushes a `launch` message the moment it lands. See [Realtime feed](/integration/api/realtime.md).

## Bundles

Several wallets can buy in the launch transaction itself, which is how a team opens a position without racing the snipe window. Each wallet signs a v2 EIP-712 consent binding the complete launch hash, its current nonce, the amount and a deadline, and the forwarder verifies every signature before it launches.

```ts
import { bundleAuthorizationCalls, bundleBuyTypedData } from '@surged/sdk'
import { isHex } from 'viem'

// Read against the exact launch being signed; this includes current factory policy.
const [version, launchHash, nonce] = await client.multicall({
  contracts: bundleAuthorizationCalls(forwarder, launch, [buyer]),
  allowFailure: false,
  batchSize: 0,
})
if (version !== 2n || !isHex(launchHash, { strict: true }) || launchHash.length !== 66 || typeof nonce !== 'bigint') {
  throw new Error('Secure bundle consent is unavailable for this forwarder')
}

const signature = await buyerWallet.signTypedData(
  bundleBuyTypedData(chainId, forwarder, {
    buyer,
    quoteIn,
    minTokensOut,
    initiator,
    launchHash,
    nonce,
    deadline,
  }),
)
```

`quoteIn` must be a whole number of USDC micro-units, a multiple of `1e12` in native units, because the forwarder moves it through the ERC-20 view of USDC, which has 6 decimals. Anything else reverts with `NotAMultipleOfErc20Unit`.

Then pass each signed consent, including its nonce, to `encodeLaunchAndBuyManyFrom`. Each buyer funds their own buy; the initiator pays only the launch fee and the gas.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.surged.fun/integration/sdk/launching.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
