SDK
API 클라이언트
Last updated October 12, 2026
Genesis API 클라이언트는 토큰 런칭을 생성하고 등록하기 위한 고수준 함수를 제공합니다. Umi 기반의 간단한 인터페이스를 통해 트랜잭션 빌드, 서명, 온체인 등록을 처리합니다.
Genesis 프로그램의 전체 기능을 metaplex.com에서 아직 지원하지 않으므로, 런칭을 프로그래밍 방식으로 생성하려면 SDK를 사용하는 것을 권장합니다. API를 통해 생성된 메인넷 런칭은 등록 후 metaplex.com에 표시됩니다.
설치
npm install @metaplex-foundation/genesis @metaplex-foundation/umi \
@metaplex-foundation/umi-bundle-defaults
설정
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import { genesis } from '@metaplex-foundation/genesis';
import { keypairIdentity } from '@metaplex-foundation/umi';
const umi = createUmi('https://api.mainnet-beta.solana.com')
.use(genesis());
// For server-side or scripts, load a keypair
umi.use(keypairIdentity(myKeypair));
함수 개요
| 함수 | 목적 |
|---|---|
createAndRegisterLaunch | 한 번의 호출로 토큰 런치 — 생성, 서명, 전송, 등록 |
createLaunch | 맞춤 서명 흐름을 위한 서명되지 않은 런치 트랜잭션 생성 |
registerLaunch | 생성 트랜잭션이 온체인에서 확인된 후 런치 등록 |
claimCreatorRewards | 지갑의 모든 버킷에서 누적된 창작자 보상 청구 |
세 가지 통합 모드
SDK는 완전 자동부터 완전 수동까지, 런칭 생성을 위한 세 가지 모드를 제공합니다.
간편 모드 — createAndRegisterLaunch
가장 간단한 방식입니다. 하나의 함수 호출로 온체인 계정 생성, Umi를 통한 트랜잭션 서명 및 전송, 런칭 등록까지 모든 것을 처리합니다.
1import {
2 createAndRegisterLaunch,
3 CreateLaunchInput,
4 genesis,
5} from '@metaplex-foundation/genesis'
6import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
7import { keypairIdentity } from '@metaplex-foundation/umi'
8
9const umi = createUmi('https://api.mainnet-beta.solana.com')
10 .use(genesis())
11
12// Use keypairIdentity to set a wallet when running server-side:
13// umi.use(keypairIdentity(myKeypair))
14
15const input: CreateLaunchInput = {
16 wallet: umi.identity.publicKey,
17 token: {
18 name: 'My Token',
19 symbol: 'MTK',
20 image: 'https://gateway.irys.xyz/...',
21 },
22 launchType: 'launchpool',
23 launch: {
24 launchpool: {
25 tokenAllocation: 500_000_000,
26 depositStartTime: new Date(Date.now() + 48 * 60 * 60 * 1000),
27 raiseGoal: 250,
28 raydiumLiquidityBps: 5000,
29 fundsRecipient: umi.identity.publicKey,
30 },
31 },
32}
33
34const result = await createAndRegisterLaunch(umi, {}, input)
35console.log(`Launch live at: ${result.launch.link}`)
CreateAndRegisterLaunchResult 반환값:
| 필드 | 타입 | 설명 |
|---|---|---|
signatures | Uint8Array[] | 트랜잭션 서명 |
mintAddress | string | 생성된 토큰 민트 주소 |
genesisAccount | string | Genesis 계정 PDA 주소 |
launch.id | string | 런칭 ID |
launch.link | string | 런칭 페이지 URL |
token.id | string | 토큰 ID |
token.mintAddress | string | 토큰 민트 주소 |
중간 모드 — 커스텀 트랜잭션 전송
멀티시그 지갑이나 커스텀 재시도 로직과 같은 시나리오를 위해 createAndRegisterLaunch에 커스텀 txSender 콜백을 사용합니다.
1import {
2 createAndRegisterLaunch,
3 SignAndSendOptions,
4} from '@metaplex-foundation/genesis'
5
6// Assumes umi and input from the Easy Mode example.
7
8const options: SignAndSendOptions = {
9 txSender: async (transactions) => {
10 // Replace myCustomSign / myCustomSend with your own
11 // signing and sending implementation.
12 const signatures: Uint8Array[] = []
13 for (const tx of transactions) {
14 const signed = await myCustomSign(tx) // your signer
15 const sig = await myCustomSend(signed) // your sender
16 signatures.push(sig)
17 }
18 return signatures
19 },
20}
21
22const result = await createAndRegisterLaunch(umi, {}, input, options)
23console.log(`Launch live at: ${result.launch.link}`)
txSender 콜백은 미서명 트랜잭션 배열을 받아 서명 배열을 반환해야 합니다. SDK는 콜백이 완료된 후 등록을 처리합니다.
완전 제어 — createLaunch + registerLaunch
트랜잭션 라이프사이클을 완전히 제어할 수 있습니다. createLaunch를 호출하여 미서명 트랜잭션을 받고, 서명과 전송을 직접 처리한 다음, registerLaunch를 호출합니다.
1import {
2 createLaunch,
3 registerLaunch,
4} from '@metaplex-foundation/genesis'
5
6// Assumes umi and input from the Easy Mode example.
7
8// Step 1: Get unsigned transactions from the API
9const createResult = await createLaunch(umi, {}, input)
10
11// Step 2: Sign and send each transaction
12for (const tx of createResult.transactions) {
13 const signedTx = await umi.identity.signTransaction(tx)
14 const signature = await umi.rpc.sendTransaction(signedTx, {
15 commitment: 'confirmed',
16 preflightCommitment: 'confirmed',
17 })
18 await umi.rpc.confirmTransaction(signature, {
19 commitment: 'confirmed',
20 strategy: {
21 type: 'blockhash',
22 ...createResult.blockhash,
23 },
24 })
25}
26
27// Step 3: Register the launch
28const registerResult = await registerLaunch(umi, {}, {
29 genesisAccount: createResult.genesisAccount,
30 createLaunchInput: input,
31})
32console.log(`Launch live at: ${registerResult.launch.link}`)
createLaunch 반환값 CreateLaunchResponse:
| 필드 | 타입 | 설명 |
|---|---|---|
transactions | Transaction[] | 서명하여 전송해야 할 미서명 Umi 트랜잭션 |
blockhash | BlockhashWithExpiryBlockHeight | 트랜잭션 확인을 위한 블록해시 |
mintAddress | string | 생성된 토큰 민트 주소 |
genesisAccount | string | Genesis 계정 PDA 주소 |
registerLaunch 반환값 RegisterLaunchResponse:
| 필드 | 타입 | 설명 |
|---|---|---|
existing | boolean? | 런칭이 이미 등록된 경우 true |
launch.id | string | 런칭 ID |
launch.link | string | 런칭 페이지 URL |
token.id | string | 토큰 ID |
token.mintAddress | string | 토큰 민트 주소 |
registerLaunch를 호출하기 전에 트랜잭션이 온체인에서 확인되어야 합니다. 등록 엔드포인트는 Genesis 계정이 존재하며 예상된 구성과 일치하는지 검증합니다.
창작자 보상 청구
claimCreatorRewards는 POST /v1/creator-rewards/claim을 호출하고, 청구 가능한 모든 본딩 커브 및 Raydium 버킷에 대한 Base64 인코딩된 청구 트랜잭션을 Umi Transaction으로 역직렬화하여 반환합니다. 각 트랜잭션에 Umi identity로 서명하고 전송하세요. 창작자 수수료 구성, 누적 확인, 버킷별 하위 수준 명령을 포함한 전체 청구 흐름은 Genesis 본딩 커브의 창작자 수수료를 참조하세요.
1import { claimCreatorRewards } from '@metaplex-foundation/genesis'
2import { base58 } from '@metaplex-foundation/umi/serializers'
3import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
4import { keypairIdentity } from '@metaplex-foundation/umi'
5
6const umi = createUmi('https://api.mainnet-beta.solana.com')
7const keypair = umi.eddsa.createKeypairFromSecretKey(mySecretKeyBytes)
8umi.use(keypairIdentity(keypair))
9
10const result = await claimCreatorRewards(umi, {}, {
11 wallet: umi.identity.publicKey,
12 network: 'solana-mainnet',
13 // payer is optional — defaults to `wallet` on the server.
14 // Set it to have a different wallet cover rent and transaction fees.
15 // payer: umi.identity.publicKey,
16})
17
18for (const tx of result.transactions) {
19 const signed = await umi.identity.signTransaction(tx)
20 const signature = await umi.rpc.sendTransaction(signed, {
21 preflightCommitment: 'confirmed',
22 })
23 await umi.rpc.confirmTransaction(signature, {
24 strategy: { type: 'blockhash', ...result.blockhash },
25 commitment: 'confirmed',
26 })
27 console.log('Claimed:', base58.deserialize(signature)[0])
28}
29
30// Claimed: 5uGGYEMmjP2HpyFCvLPNpVDSQEBtUE3LR6ZQFqhJxQSh5FbKacSyN8nQmAJowuFs6BTCdwzoFyyJz8Y2hQx8kPxo
31// Claimed: 3TAroVovEap1ZEAJYq3WiDZoMK3GU3soCdrhvZJNg6b9EANqvWrVcDGNffm7mD8wvtpR7ynWQBcbrmz8AK6nrhfy
ClaimCreatorRewardsInput
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
wallet | PublicKey | string | 예 | 청구 대상 창작자 수수료 지갑. |
network | SvmNetwork | 아니요 | 'solana-mainnet'(기본값) 또는 'solana-devnet'. API 기본 URL(https://api.metaplex.com)과 일치해야 합니다 |
payer | PublicKey | string | 아니요 | 반환된 트랜잭션의 수수료와 렌트를 부담하는 지갑. 기본값은 wallet. 창작자 수수료 지갑에 SOL이 없는 경우(예: 에이전트 PDA)에 사용하세요. payer는 반환된 트랜잭션에 서명해야 하며, 청구된 SOL은 계속 창작자 수수료 지갑이 받습니다. |
ClaimCreatorRewardsResponse
| 필드 | 타입 | 설명 |
|---|---|---|
transactions | Transaction[] | 역직렬화된 Umi 트랜잭션, 청구하는 버킷당 하나. payer identity로 각각 서명하고 전송하세요. |
blockhash | BlockhashWithExpiryBlockHeight | 트랜잭션이 빌드된 블록해시. 확인에는 이것을 사용하세요. 새로 가져온 블록해시로 대체하지 마세요. |
보상 없음은 빈 배열이 아니라 타입이 지정된 오류입니다
지갑에 청구할 것이 없으면 API는 HTTP 400과 {"error":{"message":"No rewards available to claim"}}을 반환하고 SDK는 GenesisApiError를 던집니다. 호출자는 오류를 잡아 err.message(또는 err.statusCode === 400)로 분기해야 하며, result.transactions.length === 0에 의존할 수 없습니다. 보상 없음 사례 처리를 참조하세요.
1import {
2 claimCreatorRewards,
3 isGenesisApiError,
4 isGenesisApiNetworkError,
5} from '@metaplex-foundation/genesis'
6
7// Assumes umi is configured with a keypair identity.
8
9try {
10 const result = await claimCreatorRewards(umi, {}, {
11 wallet: umi.identity.publicKey,
12 network: 'solana-mainnet',
13 })
14 console.log(`Claimable transactions: ${result.transactions.length}`)
15} catch (err) {
16 if (isGenesisApiError(err)) {
17 // The API returns HTTP 400 with
18 // { "error": { "message": "No rewards available to claim" } }
19 // when the wallet has no unclaimed creator rewards. Match on the message
20 // (or statusCode === 400) to handle this as a success case rather than a
21 // failure.
22 if (err.message === 'No rewards available to claim') {
23 console.log('Nothing to claim right now.')
24 } else {
25 console.error('API error:', err.statusCode, err.message)
26 }
27 } else if (isGenesisApiNetworkError(err)) {
28 console.error('Network error:', err.cause.message)
29 } else {
30 throw err
31 }
32}
33
34// Nothing to claim right now.
구성
CreateLaunchInput
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
wallet | PublicKey | string | 예 | 생성자의 지갑 (트랜잭션 서명) |
token | TokenMetadata | 예 | 토큰 메타데이터 |
network | SvmNetwork | 아니오 | 'solana-mainnet' (기본값) 또는 'solana-devnet' |
quoteMint | QuoteMintInput | 아니요 | 'SOL'(기본값) 또는 'USDC' |
launchType | CreateLaunchType | 예 | 'launchpool' — 기본 런칭 메커니즘 |
launch | LaunchpoolLaunchInput | 예 | 런칭 구성 |
TokenMetadata
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
name | string | 예 | 토큰 이름, 1–32자 |
symbol | string | 예 | 토큰 심볼, 1–10자 |
image | string | 예 | 이미지 URL (유효한 HTTPS URL) |
description | string | 아니오 | 최대 250자 |
externalLinks | ExternalLinks | 아니오 | 웹사이트, Twitter, Telegram 링크 |
ExternalLinks
| 필드 | 타입 | 설명 |
|---|---|---|
website | string? | 웹사이트 URL |
twitter | string? | Twitter/X 핸들 (@mytoken) 또는 전체 URL |
telegram | string? | Telegram 핸들 또는 전체 URL |
LaunchpoolConfig
| 필드 | 타입 | 설명 |
|---|---|---|
tokenAllocation | number | 판매할 토큰 수량 (총 공급량 10억 중 일부) |
depositStartTime | Date | string | 예치 기간 시작 시점 (48시간 지속) |
raiseGoal | number | 최소 모금 목표 견적 토큰, 정수 단위 (예: 250 SOL). 최소 250 SOL 또는 5,000 USDC |
raydiumLiquidityBps | number | Raydium LP에 사용할 모금 자금 비율, 베이시스 포인트 (2000–10000) |
fundsRecipient | PublicKey | string | 잠금 해제된 모금 자금을 수령하는 지갑 |
softCap | number? | 모금할 견적 토큰의 선택적 상한, 정수 단위. 이를 초과하는 예치금은 비례하여 환불됩니다. 0보다 커야 하며, 상한이 없으면 생략 |
ClaimScheduleAllocation (베스팅 잠금)
ClaimScheduleAllocation은 토큰 공급량 일부에 대한 Genesis 네이티브 베스팅 잠금을 정의하며 launch.claimScheduleAllocations로 전달합니다. 각 할당은 온체인 ClaimScheduleBucketV2가 됩니다. 토큰은 선택적 클리프가 있는 선형 곡선을 따라 누적되며, SDK는 아래의 사람이 읽기 쉬운 일정을 온체인 초 단위 및 베이시스 포인트 값으로 변환합니다.
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
name | string | 예 | 잠금 이름, 최대 64자 (예: "Team", "Advisors") |
recipient | PublicKey | string | 예 | 베스팅된 토큰을 청구할 수 있는 지갑 |
tokenAmount | number | 예 | 베스팅 일정의 총 토큰 수량 |
vestingStartTime | Date | string | 예 | 선형 베스팅 곡선이 누적되기 시작하는 시점 |
vestingDuration | { value: number, unit: TimeUnit } | 예 | 선형 베스팅 기간의 길이 |
unlockSchedule | TimeUnit | 예 | 토큰이 잠금 해제되는 빈도 |
cliff | { duration, unlockAmount? } | 아니요 | 선택적 클리프. duration은 vestingStartTime부터 측정하며, unlockAmount는 토큰 수량 또는 비례 몫을 뜻하는 'linear'(기본값) |
cancelable | boolean | 아니요 | 런치 생성자가 잠금을 취소할 수 있습니다. 기본값 false |
cancelableByRecipient | boolean | 아니요 | 수령인이 잠금을 취소할 수 있습니다. 기본값 false |
transferable | boolean | 아니요 | 런치 생성자가 잠금을 이전할 수 있습니다. 기본값 false |
transferableByRecipient | boolean | 아니요 | 수령인이 잠금을 이전할 수 있습니다. 기본값 false |
pausable | boolean | 아니요 | Genesis 권한자가 베스팅을 일시 중지하고 재개할 수 있습니다. 기본값 false |
런치 풀에서는 vestingStartTime이 더 이른 시점이고 토큰이 이미 누적되었더라도, 런치가 졸업(graduate)하기 전까지는 베스팅된 토큰을 청구할 수 없습니다. 확정된 클리프 몫은 0보다 커야 합니다.
lockedAllocations는 더 이상 사용되지 않습니다
launch.lockedAllocations(이전 Streamflow 잠금)는 더 이상 사용되지 않습니다(deprecated). SDK는 여전히 이를 허용하고 각 항목을 클레임 스케줄에 매핑하므로 기존 통합은 계속 컴파일됩니다. 새 통합에는 claimScheduleAllocations를 사용하세요. 마이그레이션할 때 cancelableBySender는 cancelable로, transferableBySender는 transferable로 이름을 바꾸세요.
TimeUnit 값: 'SECOND', 'MINUTE', 'HOUR', 'DAY', 'WEEK', 'TWO_WEEKS', 'MONTH', 'QUARTER', 'YEAR'
베스팅 잠금 예시:
1import {
2 createAndRegisterLaunch,
3 CreateLaunchInput,
4 genesis,
5} from '@metaplex-foundation/genesis'
6import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
7import { keypairIdentity } from '@metaplex-foundation/umi'
8
9const umi = createUmi('https://api.mainnet-beta.solana.com')
10 .use(genesis())
11
12// Use keypairIdentity to set a wallet when running server-side:
13// umi.use(keypairIdentity(myKeypair))
14
15const input: CreateLaunchInput = {
16 wallet: umi.identity.publicKey,
17 token: {
18 name: 'My Token',
19 symbol: 'MTK',
20 image: 'https://gateway.irys.xyz/...',
21 description: 'A project token with vesting locks.',
22 externalLinks: {
23 website: 'https://example.com',
24 twitter: '@mytoken',
25 },
26 },
27 launchType: 'launchpool',
28 launch: {
29 launchpool: {
30 tokenAllocation: 500_000_000,
31 depositStartTime: new Date('2026-04-01T00:00:00Z'),
32 raiseGoal: 250,
33 raydiumLiquidityBps: 5000,
34 fundsRecipient: 'FundsRecipientWallet...',
35 },
36 claimScheduleAllocations: [
37 {
38 name: 'Team',
39 recipient: 'TeamWallet...',
40 tokenAmount: 100_000_000,
41 vestingStartTime: new Date('2026-04-05T00:00:00Z'),
42 vestingDuration: { value: 1, unit: 'YEAR' },
43 unlockSchedule: 'MONTH',
44 cliff: {
45 duration: { value: 3, unit: 'MONTH' },
46 unlockAmount: 10_000_000,
47 },
48 cancelable: false,
49 pausable: false,
50 },
51 ],
52 },
53}
54
55const result = await createAndRegisterLaunch(umi, {}, input)
56console.log(`Launch live at: ${result.launch.link}`)
SignAndSendOptions
createAndRegisterLaunch를 위한 옵션 (RpcSendTransactionOptions 확장):
| 필드 | 타입 | 기본값 | 설명 |
|---|---|---|---|
txSender | (txs: Transaction[]) => Promise<Uint8Array[]> | — | 커스텀 트랜잭션 전송 콜백 |
commitment | string | 'confirmed' | 확인 커밋먼트 레벨 |
preflightCommitment | string | 'confirmed' | 프리플라이트 커밋먼트 레벨 |
skipPreflight | boolean | false | 프리플라이트 검사 건너뛰기 |
오류 처리
SDK는 타입 가드 함수와 함께 세 가지 오류 타입을 제공합니다.
GenesisApiError
API가 비성공 응답을 반환할 때 발생합니다.
import { isGenesisApiError } from '@metaplex-foundation/genesis';
try {
await createLaunch(umi, {}, input);
} catch (err) {
if (isGenesisApiError(err)) {
console.error('API error:', err.statusCode, err.responseBody);
}
}
| 속성 | 타입 | 설명 |
|---|---|---|
statusCode | number | HTTP 상태 코드 |
responseBody | unknown | API의 전체 응답 본문 |
GenesisApiNetworkError
fetch 호출이 실패할 때 (네트워크 문제, DNS 실패 등) 발생합니다.
import { isGenesisApiNetworkError } from '@metaplex-foundation/genesis';
if (isGenesisApiNetworkError(err)) {
console.error('Network error:', err.cause.message);
}
| 속성 | 타입 | 설명 |
|---|---|---|
cause | Error | 기본 fetch 오류 |
GenesisValidationError
API 호출 전에 입력 유효성 검사가 실패할 때 발생합니다.
import { isGenesisValidationError } from '@metaplex-foundation/genesis';
if (isGenesisValidationError(err)) {
console.error(`Validation failed on field "${err.field}":`, err.message);
}
| 속성 | 타입 | 설명 |
|---|---|---|
field | string | 유효성 검사에 실패한 입력 필드 |
종합 오류 처리
1import {
2 createAndRegisterLaunch,
3 isGenesisApiError,
4 isGenesisApiNetworkError,
5 isGenesisValidationError,
6} from '@metaplex-foundation/genesis'
7
8// Assumes umi and input from the Easy Mode example.
9
10try {
11 const result = await createAndRegisterLaunch(umi, {}, input)
12 console.log(`Launch live at: ${result.launch.link}`)
13} catch (err) {
14 if (isGenesisValidationError(err)) {
15 console.error(`Invalid input "${err.field}":`, err.message)
16 } else if (isGenesisApiError(err)) {
17 console.error('API error:', err.statusCode, err.responseBody)
18 } else if (isGenesisApiNetworkError(err)) {
19 console.error('Network error:', err.cause.message)
20 } else {
21 throw err
22 }
23}
유효성 검사 규칙
SDK는 API로 전송하기 전에 입력을 검증합니다:
| 규칙 | 제약 조건 |
|---|---|
| 토큰 이름 | 1–32자 |
| 토큰 심볼 | 1–10자 |
| 토큰 이미지 | 유효한 HTTPS URL |
| 토큰 설명 | 최대 250자 |
| 토큰 할당 | 0보다 큼 |
| 모금 목표 | 0보다 큼 |
| Raydium 유동성 BPS | 2000–10000 (20%–100%) |
| 총 공급량 | 10억 토큰으로 고정 |
| 잠금 할당 이름 | 최대 64자 |
총 공급량은 항상 10억 토큰입니다. SDK는 런치풀, Raydium LP, 잠금 할당을 뺀 나머지를 생성자 할당으로 자동 계산합니다.
헬퍼 함수
signAndSendLaunchTransactions
기본 서명 및 전송 동작을 독립 함수로 사용하려는 경우 (재시도나 부분 흐름에 유용):
import {
createLaunch,
signAndSendLaunchTransactions,
} from '@metaplex-foundation/genesis';
const createResult = await createLaunch(umi, {}, input);
const signatures = await signAndSendLaunchTransactions(umi, createResult, {
commitment: 'confirmed',
});
트랜잭션은 순차적으로 서명 및 전송됩니다 — 각 트랜잭션은 다음 트랜잭션이 전송되기 전에 확인됩니다.
buildCreateLaunchPayload
입력을 검증하고 원시 API 페이로드를 빌드합니다. 고급 사용 사례를 위해 내보내기됩니다:
import { buildCreateLaunchPayload } from '@metaplex-foundation/genesis';
const payload = buildCreateLaunchPayload(input);
// Use payload with your own HTTP client
