# 发行代币

代币创建者使用 `createLaunchpad()` 来部署由绑定曲线支持的新代币。此单笔交易：

* 铸造代币
* 创建链上元数据
* 初始化绑定曲线
* 立即开放交易

无需额外设置。

***

## 代币发行工作原理

当代币被发行时，以下步骤会原子性发生：

1. **代币创建**\
   按指定供应量铸造新的 SPL 代币（或 Token-2022 代币）。
2. **元数据创建**\
   使用提供的名称、符号和 URI，通过 Metaplex 创建链上元数据。
3. **绑定曲线初始化**\
   使用配置的参数初始化绑定曲线池。
4. **开始交易**\
   用户可以立即在绑定曲线上买卖代币。
5. **迁移**\
   一旦达到筹资目标，流动性会自动迁移到 Raydium 池。

***

## 创建代币发行

```ts
import {
  TxVersion,
  LAUNCHPAD_PROGRAM,
  getPdaLaunchpadConfigId,
  CpmmCreatorFeeOn,
} from '@raydium-io/raydium-sdk-v2'
import { initSdk } from './config'
import { Keypair, PublicKey } from '@solana/web3.js'
import { NATIVE_MINT } from '@solana/spl-token'
import BN from 'bn.js'

const createToken = async () => {
  const raydium = await initSdk()

  // 生成新的 mint 密钥对
  const tokenKeypair = Keypair.generate()

  // 推导全局配置（以 SOL 计价，constant product）
  const configId = getPdaLaunchpadConfigId(
    LAUNCHPAD_PROGRAM,
    NATIVE_MINT,
    0,
    0
  ).publicKey

  const { execute, extInfo } = await raydium.launchpad.createLaunchpad({
    programId: LAUNCHPAD_PROGRAM,

    // 代币配置
    mintA: tokenKeypair.publicKey,
    decimals: 6,
    name: 'My token',
    symbol: 'MTK',
    uri: 'https://arweave.net/metadata.json',

    // 平台（可选）
    platformId: new PublicKey('your-platform-id'),

    // 全局配置
    configId,

    // 迁移目的地
    migrateType: 'cpmm',

    // 绑定曲线参数
    supply: new BN('1000000000000000'),
    totalSellA: new BN('793100000000000'),
    totalFundRaisingB: new BN('85000000000'),

    // 线性释放（可选）
    totalLockedAmount: new BN('0'),
    cliffPeriod: new BN('0'),
    unlockPeriod: new BN('0'),

    // 初始买入（可选）
    createOnly: true,
    buyAmount: new BN('0'),
    slippage: new BN(100),

    // 迁移后创始人费用
    creatorFeeOn: CpmmCreatorFeeOn.OnlyTokenB,

    // 交易设置
    txVersion: TxVersion.V0,
    extraSigners: [tokenKeypair],
  })

  const { txIds } = await execute({ sendAndConfirm: true, sequentially: true })
  console.log('Pool id:', extInfo.address.poolId.toBase58())
  console.log('Token mint:', tokenKeypair.publicKey.toBase58())
}
```

***

### 参数参考

### 代币配置

| 参数         | 类型          | 必需 | 说明                                         |
| ---------- | ----------- | -- | ------------------------------------------ |
| `mintA`    | `PublicKey` | 是  | 新代币 mint 的公钥。生成新的密钥对并将其包含在 `extraSigners`. |
| `decimals` | `number`    | 否  | 小数位数。默认： `6`.                              |
| `name`     | `string`    | 是  | 用于链上元数据的代币名称。                              |
| `symbol`   | `string`    | 是  | 代币简称。最多 10 个字符。                            |
| `uri`      | `string`    | 是  | 元数据 JSON 的 URL（Arweave、IPFS 或任何公共 URL）。    |

***

### 平台与全局配置

| 参数           | 类型          | 必需 | 说明                              |
| ------------ | ----------- | -- | ------------------------------- |
| `platformId` | `PublicKey` | 否  | 要在其上发行的平台注册配置。默认为 Raydium 官方平台。 |
| `configId`   | `PublicKey` | 是  | 定义计价代币和曲线类型的全局配置。               |
| `configInfo` | `object`    | 否  | 预取的配置数据。如果省略会自动获取。              |

***

### 绑定曲线参数

| 参数                  | 类型       | 必需 | 说明                               |
| ------------------- | -------- | -- | -------------------------------- |
| `supply`            | `BN`     | 否  | 总代币供应。最小值： `10,000,000` （未计小数位）。 |
| `totalSellA`        | `BN`     | 否  | 通过绑定曲线出售的代币数量。必须 ≥ 供应的 20%。      |
| `totalFundRaisingB` | `BN`     | 否  | 迁移前要筹集的计价代币金额。                   |
| `migrateType`       | `string` | 是  | 迁移目的地： `cpmm` 或 `amm`.           |

### 理解供应分配

```txt
supply = totalSellA + totalLockedAmount + migrateAmount
```

* `totalSellA`: 通过绑定曲线出售的代币
* `totalLockedAmount`: 为线性释放保留的代币
* `migrateAmount`: 迁移到 AMM 池的代币（必须 ≥ 供应的 20%）

### 线性释放参数（可选）

| 参数                  | 类型   | 必需 | 说明                     |
| ------------------- | ---- | -- | ---------------------- |
| `totalLockedAmount` | `BN` | 否  | 为线性释放保留的代币。最多为供应的 30%。 |
| `cliffPeriod`       | `BN` | 否  | 迁移后到线性释放开始的秒数。         |
| `unlockPeriod`      | `BN` | 否  | 线性释放的持续时间（秒）。          |

> 注意：线性释放开始时间会自动设置为迁移区块的时间戳。线性释放接收者需使用单独的 `createVesting()`.

***

### 初始买入参数（可选）

| 参数               | 类型        | 必需 | 说明                                        |
| ---------------- | --------- | -- | ----------------------------------------- |
| `createOnly`     | `boolean` | 否  | `true` 仅创建代币。 `false` 创建并执行初始买入。          |
| `buyAmount`      | `BN`      | 否  | 用于初始买入的计价代币金额。如果 `createOnly` is `false`. |
| `slippage`       | `BN`      | 否  | 最大滑点，单位为基点（`100 = 1%`).                   |
| `minMintAAmount` | `BN`      | 否  | 最少收到的代币数量。若省略则自动计算。                       |

***

### 迁移后设置

| 参数             | 类型                 | 必需 | 说明               |
| -------------- | ------------------ | -- | ---------------- |
| `creatorFeeOn` | `CpmmCreatorFeeOn` | 否  | 迁移后创始人费用以哪种代币收取。 |

### `CpmmCreatorFeeOn` 选项

| 值            | 说明                   |
| ------------ | -------------------- |
| `OnlyTokenB` | 创始人费用仅以计价代币收取（推荐）。   |
| `BothToken`  | 创始人费用同时以发行代币和计价代币收取。 |

***

### 推荐参数（可选）

| 参数                 | 类型          | 必需 | 说明                                                      |
| ------------------ | ----------- | -- | ------------------------------------------------------- |
| `shareFeeRate`     | `BN`        | 否  | 推荐人分成的交易手续费比例（bps × 100）。不得超过 `maxShareFeeRate` 来自全局配置。 |
| `shareFeeReceiver` | `PublicKey` | 否  | 接收推荐费的钱包。仅适用于初始买入。                                      |

***

### Token-2022 发行

LaunchLab 支持带有转账手续费扩展的 Token-2022 代币。转账手续费会在每次代币转移时自动收取。

```ts
const { execute, extInfo } = await raydium.launchpad.createLaunchpad({
  // 标准参数...

  // 启用带转账费的 Token-2022
  transferFeeExtensionParams: {
    transferFeeBasePoints: 100,     // 1% 转账费（100 bps）
    maxinumFee: new BN('1000000'),  // 每笔转账的最大费用（以代币单位计）
  },

  // Token-2022 发行必须迁移到 CPMM
  migrateType: 'cpmm',
})
```

### 关于 Token-2022 发行的重要说明

* migration is always `cpmm` (AMMv4 不支持 Token-2022)
* 迁移后，转账费权限会转移到平台的 `transferFeeExtensionAuth` wallet
* 平台可以修改费率或申领累积的被扣留费用

***

### 获取可用配置

全局配置决定了哪些计价代币和曲线类型可用。从 API 获取配置或直接推导。

### 从 API 获取

```ts
const configs = await raydium.api.fetchLaunchConfigs()

// 查找特定配置
const solConfig = configs.find(c => c.key.mintB === NATIVE_MINT.toBase58())
```

### 直接推导

```ts
import { getPdaLaunchpadConfigId, LAUNCHPAD_PROGRAM } from '@raydium-io/raydium-sdk-v2'
import { NATIVE_MINT } from '@solana/spl-token'

const configId = getPdaLaunchpadConfigId(
  LAUNCHPAD_PROGRAM,
  NATIVE_MINT, // 计价代币
  0,           // 曲线类型：0 = constant product，1 = fixed price，2 = linear
  0            // 配置索引
).publicKey
```

### 常见配置

| 计价代币                | 曲线类型                   | 说明            |
| ------------------- | ---------------------- | ------------- |
| SOL (`NATIVE_MINT`) | `0 (constant product)` | 以 SOL 计价的标准发行 |
| USD1 (mainnet)      | `0 (constant product)` | 以稳定币计价的发行     |
| sUSDC (devnet)      | `0 (constant product)` | 以稳定币计价的发行     |

***

### 池的生命周期

创建后，池会经过以下状态：

| 状态       | 值   | 说明                          |
| -------- | --- | --------------------------- |
| Trading  | `0` | 绑定曲线处于激活状态。用户可以买卖代币。        |
| Migrate  | `1` | 筹资目标已达到。正在迁移到 AMM。          |
| Migrated | `2` | 迁移完成。代币现在在 Raydium AMM 上交易。 |

从 **trading** 到 **migrate** 的转换会在达到以下条件时自动发生： `totalFundRaisingB` 已经筹集了价值

***

### 推导池 id

创建后，你可以推导池 id 以用于交易函数：

```ts
import { getPdaLaunchpadPoolId, LAUNCHPAD_PROGRAM } from '@raydium-io/raydium-sdk-v2'
import { NATIVE_MINT } from '@solana/spl-token'

const { publicKey: poolId } = getPdaLaunchpadPoolId(
  LAUNCHPAD_PROGRAM,
  mintA,
  NATIVE_MINT
)

console.log('Pool id:', poolId.toBase58())
```

***

## 下一步

一旦你的代币发行：

1. 分享池 — 用户可以使用 `buyToken()` 和 `sellToken()`
2. 监控进度 — 跟踪筹资进度以达到 `totalFundRaisingB`
3. 申领费用 — 使用 `claimCreatorFee()` 来收取绑定曲线的交易手续费
4. 迁移后 — 使用 `harvestLockLiquidity()`
