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를 통한 트랜잭션 서명 및 전송, 런칭 등록까지 모든 것을 처리합니다.

createAndRegisterLaunch.ts
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 반환값:

필드타입설명
signaturesUint8Array[]트랜잭션 서명
mintAddressstring생성된 토큰 민트 주소
genesisAccountstringGenesis 계정 PDA 주소
launch.idstring런칭 ID
launch.linkstring런칭 페이지 URL
token.idstring토큰 ID
token.mintAddressstring토큰 민트 주소

중간 모드 — 커스텀 트랜잭션 전송

멀티시그 지갑이나 커스텀 재시도 로직과 같은 시나리오를 위해 createAndRegisterLaunch에 커스텀 txSender 콜백을 사용합니다.

customTxSender.ts
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를 호출합니다.

fullControl.ts
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:

필드타입설명
transactionsTransaction[]서명하여 전송해야 할 미서명 Umi 트랜잭션
blockhashBlockhashWithExpiryBlockHeight트랜잭션 확인을 위한 블록해시
mintAddressstring생성된 토큰 민트 주소
genesisAccountstringGenesis 계정 PDA 주소

registerLaunch 반환값 RegisterLaunchResponse:

필드타입설명
existingboolean?런칭이 이미 등록된 경우 true
launch.idstring런칭 ID
launch.linkstring런칭 페이지 URL
token.idstring토큰 ID
token.mintAddressstring토큰 민트 주소

registerLaunch를 호출하기 전에 트랜잭션이 온체인에서 확인되어야 합니다. 등록 엔드포인트는 Genesis 계정이 존재하며 예상된 구성과 일치하는지 검증합니다.


창작자 보상 청구

claimCreatorRewards는 POST /v1/creator-rewards/claim을 호출하고, 청구 가능한 모든 본딩 커브 및 Raydium 버킷에 대한 Base64 인코딩된 청구 트랜잭션을 Umi Transaction으로 역직렬화하여 반환합니다. 각 트랜잭션에 Umi identity로 서명하고 전송하세요. 창작자 수수료 구성, 누적 확인, 버킷별 하위 수준 명령을 포함한 전체 청구 흐름은 Genesis 본딩 커브의 창작자 수수료를 참조하세요.

claimCreatorRewards.ts
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

필드타입필수설명
walletPublicKey | string예청구 대상 창작자 수수료 지갑.
networkSvmNetwork아니요'solana-mainnet'(기본값) 또는 'solana-devnet'. API 기본 URL(https://api.metaplex.com)과 일치해야 합니다
payerPublicKey | string아니요반환된 트랜잭션의 수수료와 렌트를 부담하는 지갑. 기본값은 wallet. 창작자 수수료 지갑에 SOL이 없는 경우(예: 에이전트 PDA)에 사용하세요. payer는 반환된 트랜잭션에 서명해야 하며, 청구된 SOL은 계속 창작자 수수료 지갑이 받습니다.

ClaimCreatorRewardsResponse

필드타입설명
transactionsTransaction[]역직렬화된 Umi 트랜잭션, 청구하는 버킷당 하나. payer identity로 각각 서명하고 전송하세요.
blockhashBlockhashWithExpiryBlockHeight트랜잭션이 빌드된 블록해시. 확인에는 이것을 사용하세요. 새로 가져온 블록해시로 대체하지 마세요.

보상 없음은 빈 배열이 아니라 타입이 지정된 오류입니다

지갑에 청구할 것이 없으면 API는 HTTP 400과 {"error":{"message":"No rewards available to claim"}}을 반환하고 SDK는 GenesisApiError를 던집니다. 호출자는 오류를 잡아 err.message(또는 err.statusCode === 400)로 분기해야 하며, result.transactions.length === 0에 의존할 수 없습니다. 보상 없음 사례 처리를 참조하세요.

errorHandling.ts
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

필드타입필수설명
walletPublicKey | string예생성자의 지갑 (트랜잭션 서명)
tokenTokenMetadata예토큰 메타데이터
networkSvmNetwork아니오'solana-mainnet' (기본값) 또는 'solana-devnet'
quoteMintQuoteMintInput아니요'SOL'(기본값) 또는 'USDC'
launchTypeCreateLaunchType예'launchpool' — 기본 런칭 메커니즘
launchLaunchpoolLaunchInput예런칭 구성

TokenMetadata

필드타입필수설명
namestring예토큰 이름, 1–32자
symbolstring예토큰 심볼, 1–10자
imagestring예이미지 URL (유효한 HTTPS URL)
descriptionstring아니오최대 250자
externalLinksExternalLinks아니오웹사이트, Twitter, Telegram 링크
필드타입설명
websitestring?웹사이트 URL
twitterstring?Twitter/X 핸들 (@mytoken) 또는 전체 URL
telegramstring?Telegram 핸들 또는 전체 URL

LaunchpoolConfig

필드타입설명
tokenAllocationnumber판매할 토큰 수량 (총 공급량 10억 중 일부)
depositStartTimeDate | string예치 기간 시작 시점 (48시간 지속)
raiseGoalnumber최소 모금 목표 견적 토큰, 정수 단위 (예: 250 SOL). 최소 250 SOL 또는 5,000 USDC
raydiumLiquidityBpsnumberRaydium LP에 사용할 모금 자금 비율, 베이시스 포인트 (2000–10000)
fundsRecipientPublicKey | string잠금 해제된 모금 자금을 수령하는 지갑
softCapnumber?모금할 견적 토큰의 선택적 상한, 정수 단위. 이를 초과하는 예치금은 비례하여 환불됩니다. 0보다 커야 하며, 상한이 없으면 생략

ClaimScheduleAllocation (베스팅 잠금)

ClaimScheduleAllocation은 토큰 공급량 일부에 대한 Genesis 네이티브 베스팅 잠금을 정의하며 launch.claimScheduleAllocations로 전달합니다. 각 할당은 온체인 ClaimScheduleBucketV2가 됩니다. 토큰은 선택적 클리프가 있는 선형 곡선을 따라 누적되며, SDK는 아래의 사람이 읽기 쉬운 일정을 온체인 초 단위 및 베이시스 포인트 값으로 변환합니다.

필드타입필수설명
namestring예잠금 이름, 최대 64자 (예: "Team", "Advisors")
recipientPublicKey | string예베스팅된 토큰을 청구할 수 있는 지갑
tokenAmountnumber예베스팅 일정의 총 토큰 수량
vestingStartTimeDate | string예선형 베스팅 곡선이 누적되기 시작하는 시점
vestingDuration{ value: number, unit: TimeUnit }예선형 베스팅 기간의 길이
unlockScheduleTimeUnit예토큰이 잠금 해제되는 빈도
cliff{ duration, unlockAmount? }아니요선택적 클리프. duration은 vestingStartTime부터 측정하며, unlockAmount는 토큰 수량 또는 비례 몫을 뜻하는 'linear'(기본값)
cancelableboolean아니요런치 생성자가 잠금을 취소할 수 있습니다. 기본값 false
cancelableByRecipientboolean아니요수령인이 잠금을 취소할 수 있습니다. 기본값 false
transferableboolean아니요런치 생성자가 잠금을 이전할 수 있습니다. 기본값 false
transferableByRecipientboolean아니요수령인이 잠금을 이전할 수 있습니다. 기본값 false
pausableboolean아니요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'

베스팅 잠금 예시:

claimScheduleAllocations.ts
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[]>—커스텀 트랜잭션 전송 콜백
commitmentstring'confirmed'확인 커밋먼트 레벨
preflightCommitmentstring'confirmed'프리플라이트 커밋먼트 레벨
skipPreflightbooleanfalse프리플라이트 검사 건너뛰기

오류 처리

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);
}
}
속성타입설명
statusCodenumberHTTP 상태 코드
responseBodyunknownAPI의 전체 응답 본문

GenesisApiNetworkError

fetch 호출이 실패할 때 (네트워크 문제, DNS 실패 등) 발생합니다.

import { isGenesisApiNetworkError } from '@metaplex-foundation/genesis';
if (isGenesisApiNetworkError(err)) {
console.error('Network error:', err.cause.message);
}
속성타입설명
causeError기본 fetch 오류

GenesisValidationError

API 호출 전에 입력 유효성 검사가 실패할 때 발생합니다.

import { isGenesisValidationError } from '@metaplex-foundation/genesis';
if (isGenesisValidationError(err)) {
console.error(`Validation failed on field "${err.field}":`, err.message);
}
속성타입설명
fieldstring유효성 검사에 실패한 입력 필드

종합 오류 처리

errorHandling.ts
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 유동성 BPS2000–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