发行类型

通过 Metaplex API 发行联合曲线

Last updated April 9, 2026

使用 Genesis SDK 和 Metaplex API 在 Solana 上创建、签署、发送并注册联合曲线代币发行。

本指南涵盖内容

本指南涵盖:

  • 通过 createAndRegisterLaunch 单次调用发行联合曲线代币
  • 添加创作者费——指定到特定钱包或自动路由到 Agent PDA
  • 配置发行时的免费首次购买
  • createLaunch + registerLaunch 手动签名并注册发行
  • 在 devnet 上测试以及使用自定义 API 基础 URL 或交易发送器
  • 处理带类型的 SDK 错误

摘要

createAndRegisterLaunch(或其底层等价函数)调用 POST /v1/launches/create,返回未签名的 Solana 交易,签名并发送后注册发行,使代币出现在 metaplex.com 上。

  • 一键路径createAndRegisterLaunch 在单次等待调用中处理完整流程
  • 手动路径createLaunch + signAndSendLaunchTransactions + registerLaunch,用于自定义签名、bundles 或重试逻辑
  • 创作者费 — 联合曲线和毕业后 Raydium 池上每次兑换的可选费用;可按钱包配置或为 Agent 发行自动推导
  • 首次购买 — 曲线创建时为发行钱包或 Agent PDA 保留的可选免费初始购买

快速开始

跳转至: 安装 · 配置 · 一键发行 · 创作者费 · 首次购买 · 手动签名 · 代币元数据 · Devnet · 高级 · 错误 · API 参考

  1. 安装 Genesis SDK 并使用密钥对身份配置 Umi 实例
  2. token 元数据和 launch: {} 对象调用 createAndRegisterLaunch
  3. 从响应中读取 result.mintAddressresult.launch.link

如需自定义签名或重试逻辑,请改用手动签名流程

前置条件

  • Node.js 18+ — 原生 BigInt 支持所必需
  • 已充值 SOL 的 Solana 钱包密钥对,用于支付交易费用和可选的首次购买金额
  • Solana RPC 端点(mainnet-beta 或 devnet)
  • 预先上传到 Irys 的图片——代币元数据 image 字段必须是 Irys 网关 URL

安装

安装三个必需的依赖包。

Terminal
npm install @metaplex-foundation/genesis \
@metaplex-foundation/umi \
@metaplex-foundation/umi-bundle-defaults

Umi 配置

调用任何 Genesis API 函数前,使用密钥对身份配置 Umi 实例。

setup.ts
1import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
2import { keypairIdentity } from '@metaplex-foundation/umi';
3
4const umi = createUmi('https://api.mainnet-beta.solana.com');
5
6// Load your keypair — use your preferred key management solution in production.
7const keypair = umi.eddsa.createKeypairFromSecretKey(mySecretKeyBytes);
8umi.use(keypairIdentity(keypair));

Genesis API 函数不需要 genesis() 插件——它们通过 HTTP 与托管的 Metaplex API 通信,而非直接提交指令。Umi 实例仅用于其签名者身份和交易发送能力。

发行联合曲线(一键流程)

createAndRegisterLaunch 是最简单的路径——在单次等待调用中创建发行、签名发送所有交易并在 metaplex.com 上注册代币。

1import { createAndRegisterLaunch } from '@metaplex-foundation/genesis/api';
2import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
3import { keypairIdentity } from '@metaplex-foundation/umi';
4
5const umi = createUmi('https://api.mainnet-beta.solana.com');
6const keypair = umi.eddsa.createKeypairFromSecretKey(mySecretKeyBytes);
7umi.use(keypairIdentity(keypair));
8
9const result = await createAndRegisterLaunch(umi, {}, {
10 wallet: umi.identity.publicKey,
11 launchType: 'bondingCurve',
12 token: {
13 name: 'My Token',
14 symbol: 'MTK',
15 image: 'https://gateway.irys.xyz/your-image-id',
16 },
17 launch: {},
18});
19
20console.log('Token launched!');
21console.log('Mint address:', result.mintAddress);
22console.log('View at:', result.launch.link);
23
24// Token launched!
25// Mint address: <base58 mint address>
26// View at: https://www.metaplex.com/...

launch: {} 为空时,所有协议参数——供应分配、虚拟储备、资金流向和锁定计划——均设为协议默认值。以下各节展示如何添加创作者费和首次购买。

创作者费

每次兑换的可选费用累积到配置的钱包。在 launch 对象中设置 creatorFeeWallet 可将费用重定向到特定地址;默认使用发行钱包。

launch-with-creator-fee.ts
launch: {
creatorFeeWallet: 'FeeRecipientWalletAddress...',
},

完整配置选项、如何检查累积余额以及认领指令(claimBondingCurveCreatorFeeV2 / claimRaydiumCreatorFeeV2),请参阅创作者费

首次购买

首次购买为发行钱包保留曲线上的初始兑换,指定 SOL 金额,所有手续费豁免。

firstBuyAmount 设置为免费初始购买的 SOL 金额。

1import { createAndRegisterLaunch } from '@metaplex-foundation/genesis/api';
2import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
3import { keypairIdentity } from '@metaplex-foundation/umi';
4
5const umi = createUmi('https://api.mainnet-beta.solana.com');
6const keypair = umi.eddsa.createKeypairFromSecretKey(mySecretKeyBytes);
7umi.use(keypairIdentity(keypair));
8
9const result = await createAndRegisterLaunch(umi, {}, {
10 wallet: umi.identity.publicKey,
11 launchType: 'bondingCurve',
12 token: {
13 name: 'My Token',
14 symbol: 'MTK',
15 image: 'https://gateway.irys.xyz/your-image-id',
16 },
17 launch: {
18 firstBuyAmount: 0.1, // 0.1 SOL, fee-free initial purchase
19 },
20});

API 在发行交易流程中执行首次购买——交易确认后曲线已应用初始购买。买家默认为发行 wallet,或提供 agent 时为 Agent PDA。用 firstBuyWallet(一个 Signer)覆盖以指定不同买家。

省略 firstBuyAmount 或设为 0 时,不应用首次购买限制,任何钱包均可进行第一次兑换。

可以将首次购买与创作者费钱包组合:

launch-combined.ts
launch: {
creatorFeeWallet: 'FeeRecipientWalletAddress...',
firstBuyAmount: 0.5,
},

手动签名流程

当需要控制交易签名和提交方式时,分别使用 createLaunchregisterLaunch——例如使用 Jito bundles、优先费或自定义重试逻辑时。

manual-launch.ts
1import {
2 createLaunch,
3 registerLaunch,
4 signAndSendLaunchTransactions,
5} from '@metaplex-foundation/genesis/api';
6
7// Step 1: Call the API to get unsigned transactions.
8const createResult = await createLaunch(umi, {}, {
9 wallet: umi.identity.publicKey,
10 launchType: 'bondingCurve',
11 token: {
12 name: 'My Token',
13 symbol: 'MTK',
14 image: 'https://gateway.irys.xyz/your-image-id',
15 },
16 launch: {
17 creatorFeeWallet: 'FeeRecipientWalletAddress...',
18 },
19});
20
21console.log('Mint address:', createResult.mintAddress);
22console.log('Transactions to sign:', createResult.transactions.length);
23
24// Step 2: Sign and send the transactions.
25const signatures = await signAndSendLaunchTransactions(umi, createResult);
26
27// Step 3: Register the launch after all transactions are confirmed onchain.
28const registered = await registerLaunch(umi, {}, {
29 genesisAccount: createResult.genesisAccount,
30 createLaunchInput: {
31 wallet: umi.identity.publicKey,
32 launchType: 'bondingCurve',
33 token: {
34 name: 'My Token',
35 symbol: 'MTK',
36 image: 'https://gateway.irys.xyz/your-image-id',
37 },
38 launch: {
39 creatorFeeWallet: 'FeeRecipientWalletAddress...',
40 },
41 },
42});
43
44console.log('Launch live at:', registered.launch.link);

仅在创建交易链上确认后调用 registerLaunch。API 在注册前验证 genesis 账户存在——过早调用将返回 API 错误。

代币元数据

每次发行都需要包含以下字段的 token 对象。

字段是否必填约束
name1–32 个字符
symbol1–10 个字符
image必须是 Irys URL(https://gateway.irys.xyz/...
description最多 250 个字符
externalLinks可选的 websitetwittertelegram
token-metadata.ts
token: {
name: 'My Token',
symbol: 'MTK',
image: 'https://gateway.irys.xyz/your-image-id',
description: 'A token launched on the bonding curve',
externalLinks: {
website: 'https://mytoken.com',
twitter: '@mytoken',
telegram: '@mytoken',
},
},

Devnet 测试

传入 network: 'solana-devnet' 并将 Umi 实例指向 devnet RPC 端点,将发行路由通过 devnet 基础设施。使用 CLI 时,网络由配置的 RPC 端点决定。

1import { createAndRegisterLaunch } from '@metaplex-foundation/genesis/api';
2import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
3import { keypairIdentity } from '@metaplex-foundation/umi';
4
5const umi = createUmi('https://api.devnet.solana.com');
6const keypair = umi.eddsa.createKeypairFromSecretKey(mySecretKeyBytes);
7umi.use(keypairIdentity(keypair));
8
9const result = await createAndRegisterLaunch(umi, {}, {
10 wallet: umi.identity.publicKey,
11 launchType: 'bondingCurve',
12 network: 'solana-devnet',
13 token: {
14 name: 'Test Token',
15 symbol: 'TEST',
16 image: 'https://gateway.irys.xyz/test-image',
17 },
18 launch: {},
19});

高级

自定义 API 基础 URL

SDK 默认使用 https://api.metaplex.com。在配置对象(第二个参数)中传入 baseUrl 以指向不同环境,如暂存 API。

custom-base-url.ts
1const API_CONFIG = { baseUrl: 'https://your-api-base-url.example.com' };
2
3const result = await createAndRegisterLaunch(umi, API_CONFIG, {
4 wallet: umi.identity.publicKey,
5 launchType: 'bondingCurve',
6 token: {
7 name: 'My Token',
8 symbol: 'MTK',
9 image: 'https://gateway.irys.xyz/your-image-id',
10 },
11 launch: {},
12});

手动签名流程中的 createLaunchregisterLaunch 也接受同一 API_CONFIG 对象。

自定义交易发送器

在选项(第四个参数)中传入 txSender 回调以使用自己的签名和提交基础设施。

custom-sender.ts
1const result = await createAndRegisterLaunch(
2 umi,
3 {},
4 {
5 wallet: umi.identity.publicKey,
6 launchType: 'bondingCurve',
7 token: {
8 name: 'My Token',
9 symbol: 'MTK',
10 image: 'https://gateway.irys.xyz/your-image-id',
11 },
12 launch: {},
13 },
14 {
15 txSender: async (txs) => {
16 const signatures = [];
17 for (const tx of txs) {
18 const signed = await umi.identity.signTransaction(tx);
19 signatures.push(await myCustomSend(signed));
20 }
21 return signatures;
22 },
23 }
24);

常见错误

错误类型检查原因解决方法
Validation error on "token.image"isGenesisValidationError图片 URL 不是 Irys 网关 URL将图片上传到 Irys 并使用 https://gateway.irys.xyz/... URL
Validation error on "token.name"isGenesisValidationError名称超过 32 个字符或为空将代币名称缩短到 1–32 个字符
Network errorisGenesisApiNetworkError无法访问 https://api.metaplex.com检查连接性或提供指向可访问端点的 baseUrl
API error (4xx)isGenesisApiErrorAPI 拒绝了无效输入读取 err.responseBody 查看字段级错误详情
API error (5xx)isGenesisApiErrorMetaplex API 不可用使用指数退避重试;不要重新发送已确认的交易
registerLaunch API 错误isGenesisApiError在创建交易确认前调用注册在调用 registerLaunch 前等待所有签名在链上确认

使用带类型的错误守卫区分这些情况:

error-handling.ts
1import {
2 createLaunch,
3 isGenesisApiError,
4 isGenesisApiNetworkError,
5 isGenesisValidationError,
6} from '@metaplex-foundation/genesis/api';
7
8try {
9 const result = await createLaunch(umi, {}, input);
10} catch (err) {
11 if (isGenesisValidationError(err)) {
12 console.error(`Validation error on "${err.field}": ${err.message}`);
13 } else if (isGenesisApiNetworkError(err)) {
14 console.error('Network error:', err.message);
15 } else if (isGenesisApiError(err)) {
16 console.error(`API error (${err.statusCode}): ${err.message}`);
17 console.error('Details:', err.responseBody);
18 } else {
19 throw err;
20 }
21}

注意事项

  • createAndRegisterLaunch 从调用方角度是原子的,但内部进行两次 API 调用——创建交易确认后但 registerLaunch 之前失败意味着代币在链上存在但在 metaplex.com 上尚不可见;手动调用 registerLaunch 完成注册
  • Metaplex API 端点(https://api.metaplex.com)是托管基础设施——它构建并返回未签名的交易;调用方始终持有并控制签名
  • launch: {} 为空时,虚拟储备、供应分配和锁定计划由协议默认值设定;不支持按发行覆盖这些参数
  • agent.setToken 标志不可撤销——一旦代币被设为 Agent 的主要代币,就无法更改或重新分配;详见创建 Agent 代币了解完整 Agent 发行流程
  • 曲线上线后,使用联合曲线兑换集成指南集成兑换功能
  • 首次购买在发行创建时配置,曲线上线后无法添加;firstBuyAmount: 0 或省略该字段将完全禁用它
  • 创作者费累积在 bucket 中,而非按次转账;通过无需许可的 claimBondingCurveCreatorFeeV2(联合曲线)和 claimRaydiumCreatorFeeV2(毕业后 Raydium)指令认领

API 参考

createAndRegisterLaunch(umi, config, input, options?)

编排完整发行流程的便捷函数:创建、签名、发送并注册。

参数类型描述
umiUmi配置了身份和 RPC 的 Umi 实例
configGenesisApiConfig | null可选 API 配置(baseUrl、自定义 fetch
inputCreateBondingCurveLaunchInput发行配置
optionsSignAndSendOptions可选的 txSender 覆盖
registerOptionsRegisterOptions转发给 registerLaunch 的可选字段(如 creatorWallettwitterVerificationToken

返回 Promise<CreateAndRegisterLaunchResult>

字段描述
signatures交易签名
mintAddress创建的代币 mint 地址
genesisAccountGenesis 账户 PDA
launch.link在 metaplex.com 上查看代币的 URL

createLaunch(umi, config, input)

调用 POST /v1/launches/create 并返回反序列化的交易。

返回 Promise<CreateLaunchResponse>

字段描述
transactions待签名和发送的 Umi Transaction 对象数组
blockhash交易有效性的区块哈希
mintAddress创建的代币 mint 地址
genesisAccountGenesis 账户 PDA

registerLaunch(umi, config, input)

在 metaplex.com 上注册已确认的 genesis 账户。在所有创建交易链上确认后调用。

返回 Promise<RegisterLaunchResponse>

字段描述
launch.id发行标识符
launch.link查看代币的 URL
token.mintAddress已确认的 mint 地址

类型

types.ts
interface CreateBondingCurveLaunchInput {
wallet: PublicKey | string;
launchType: 'bondingCurve';
token: TokenMetadata;
network?: 'solana-mainnet' | 'solana-devnet';
quoteMint?: 'SOL';
agent?: {
mint: PublicKey | string; // Core asset (NFT) address
setToken: boolean; // set launched token as the agent's primary token
};
launch: BondingCurveLaunchInput;
}
interface BondingCurveLaunchInput {
creatorFeeWallet?: PublicKey | string;
firstBuyAmount?: number; // SOL amount (e.g. 0.1 = 0.1 SOL)
firstBuyWallet?: Signer;
}
interface TokenMetadata {
name: string; // max 32 characters
symbol: string; // max 10 characters
image: string; // must be an Irys URL: https://gateway.irys.xyz/...
description?: string; // max 250 characters
externalLinks?: {
website?: string;
twitter?: string;
telegram?: string;
};
}
interface GenesisApiConfig {
baseUrl?: string;
fetch?: typeof fetch;
}

FAQ

createAndRegisterLaunch 和分别调用 createLaunchregisterLaunch 有什么区别?

createAndRegisterLaunch 是在单次调用中处理完整流程的便捷封装。当需要自定义签名逻辑(如 Jito bundles、优先费)或在提交前检查或修改未签名交易时,分别使用底层函数。详见手动签名流程

上线前可以在 devnet 上测试联合曲线发行吗?

可以。在输入中传入 network: 'solana-devnet' 并将 Umi 实例指向 https://api.devnet.solana.com。API 将请求路由到 devnet 基础设施。发送交易前确保钱包有 devnet SOL。详见 Devnet 测试

如果我错误地将 agent.setToken: true 会怎样?

setToken: true 会永久将已发行代币与 Agent 关联为其主要代币——此操作不可撤销且无法取消或重新分配。如果不确定,省略 agent 字段或将 setToken 设为 false,然后单独处理代币关联。

可以同时配置创作者费钱包和首次购买吗?

可以。在 launch 对象中同时设置 creatorFeeWalletfirstBuyAmount。首次购买本身免费——不收取协议费或创作者费。之后所有兑换正常收取创作者费。详见首次购买

代币元数据需要什么图片格式和托管方式?

image 字段必须是 Irys URL——https://gateway.irys.xyz/<id>。先将图片上传到 Irys 并使用返回的网关 URL。其他托管方将无法通过 API 验证。SDK 将此报告为 token.image 字段上的 isGenesisValidationError

为什么必须在交易链上确认后才能调用 registerLaunch

registerLaunch 将发行记录写入 Metaplex 数据库,并在注册前验证 genesis 账户在链上存在。在创建交易确认前调用将返回 API 错误,因为账户尚不可见。在 createAndRegisterLaunch 中,这种顺序是自动处理的。