소개

시작하기

Last updated August 27, 2026

이 가이드는 MPL-DistroUmi 프레임워크로 기존 토큰을 두 지갑에 보냅니다.

요약

MPL-Distro 런치에는 기존 SPL 토큰 mint, 보존된 오프체인 Merkle 할당, 배포 볼트에 충분한 토큰이 필요합니다.

  • prepareDistribution으로 루트와 증명을 만듭니다.
  • Permissionless 제출로 7일 Wallet 배포를 만듭니다.
  • 클레임이 시작되기 전에 모든 할당의 합을 입금합니다.
  • 트리에 커밋된 정확한 amount, nonce, 증명을 제출합니다.

만들게 될 것

두 수신자 배포를 만들고 350,000 토큰 기본 단위를 입금한 뒤, 첫 수신자의 100,000 단위 클레임을 제출합니다.

CLI에서 생성과 자금 투입

Metaplex CLI로 배포를 만들고 토큰을 입금하거나 출금할 수 있습니다. Merkle 증명 생성과 클레임 제출은 이 SDK 워크스루에서 합니다.

바로가기: 사전 요구사항 · 설치 · 생성 · 자금 투입 · 클레임 · 오류

빠른 시작

MPL-Distro 빠른 시작에는 네 개의 필수 단계가 있습니다.

  1. MPL-Distro 클라이언트를 설치하고 Umi에 mplDistro()를 등록합니다.
  2. 할당 루트, 증명, amount, nonce를 생성하고 보존합니다.
  3. 배포를 만들고 전체 토큰 할당을 입금합니다.
  4. distribute로 증명을 제출하고 클레임 영수증을 확인합니다.

사전 요구사항

MPL-Distro에는 자금이 있는 Solana 서명자와 원본 SPL Token 프로그램이 소유한 기존 mint가 필요합니다.

  • Node.js 20 이상
  • 임대료, 트랜잭션 수수료, 0.002 SOL 클레임 프로토콜 수수료용 SOL을 가진 Umi identity
  • 기존 SPL 토큰 mint와 그 권한자의 자금이 있는 associated token account
  • 토큰 기본 단위로 표현한 수신자 주소와 할당량(mint의 최소 단위. decimals가 6인 토큰은 1.0 토큰당 1_000_000 단위)

예제는 Token-2022 mint를 받지 않습니다. 원본 SPL Token 프로그램 mint를 사용하세요.

MPL-Distro SDK 설치

트랜잭션을 준비하고 제출하는 애플리케이션에 MPL-Distro 클라이언트와 Umi 피어 의존성을 설치합니다.

Terminal
npm install @metaplex-foundation/mpl-distro@^0.4 \
@metaplex-foundation/umi@^1.1 \
@metaplex-foundation/umi-bundle-defaults \
@metaplex-foundation/mpl-toolbox@^0.10

Core 에셋 서명자로 클레임할 때만 @metaplex-foundation/mpl-core를 설치하세요.

지갑 배포 생성

수신자 목록을 Merkle 루트로 커밋하고 반환된 증명을 오프체인에 저장해 배포를 만듭니다.

createDistribution.ts
1import {
2 AllowedDistributor,
3 createDistribution,
4 DistributionType,
5 findDistributionPda,
6 mplDistro,
7 prepareDistribution,
8} from '@metaplex-foundation/mpl-distro'
9import { generateSigner, publicKey } from '@metaplex-foundation/umi'
10import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
11
12const umi = createUmi(
13 process.env.RPC_URL ?? 'https://api.devnet.solana.com'
14).use(mplDistro())
15
16// Use umi.use(keypairIdentity(yourKeypair)) when the Umi identity
17// should be the distribution authority.
18
19const mint = publicKey(process.env.TOKEN_MINT!)
20const recipients = [
21 { address: publicKey(process.env.RECIPIENT_1!), amount: 100_000n },
22 { address: publicKey(process.env.RECIPIENT_2!), amount: 250_000n },
23]
24const { root, proofs, treeHeight } = prepareDistribution(recipients)
25const seed = generateSigner(umi)
26const now = BigInt(Math.floor(Date.now() / 1000))
27
28await createDistribution(umi, {
29 mint,
30 seed,
31 merkleRoot: root,
32 treeHeight,
33 startTime: now,
34 endTime: now + 7n * 24n * 60n * 60n,
35 totalClaimants: BigInt(recipients.length),
36 name: 'Community distribution',
37 distributionType: DistributionType.Wallet,
38 allowedDistributor: AllowedDistributor.Permissionless,
39 subsidizeReceipts: false,
40}).sendAndConfirm(umi)
41
42const [distribution] = findDistributionPda(umi, {
43 mint,
44 seed: seed.publicKey,
45})
46
47// Store each recipient's amount, nonce, and proof in your claim service.
48console.log('Distribution:', distribution)
49console.log('Proofs:', proofs)
50
51// Distribution: <distribution PDA>
52// Proofs: <one proof array per recipient>

seed 서명자는 mint에 대해 배포 주소를 고유하게 만들므로 같은 토큰에 둘 이상의 배포를 둘 수 있습니다. 결과 PDA["distribution", mint, seed]를 쓰므로, 주소를 다시 유도하려면 seed 공개 키를 보관해야 합니다.

클레임 중 할당 데이터는 불변

권한자는 startTime <= now <= endTime 동안 Merkle 루트, 트리 높이, 시작 시각, claimant 수를 바꿀 수 없습니다. 클레임을 열기 전에 전체 할당 파일을 검증하고 백업하세요.

지갑 배포에 자금 투입

모든 할당의 합 이상을 프로그램 소유 associated token account에 입금해 배포에 자금을 넣습니다. 현재 배포 권한자가 deposit에 서명해야 합니다.

fundDistribution.ts
1import {
2 deposit,
3 mplDistro,
4} from '@metaplex-foundation/mpl-distro'
5import { publicKey } from '@metaplex-foundation/umi'
6import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
7
8const umi = createUmi(
9 process.env.RPC_URL ?? 'https://api.devnet.solana.com'
10).use(mplDistro())
11
12// The Umi identity must be the current distribution authority.
13
14const distribution = publicKey(process.env.DISTRIBUTION_ADDRESS!)
15const mint = publicKey(process.env.TOKEN_MINT!)
16const totalAmount = 350_000n
17
18await deposit(umi, {
19 distribution,
20 mint,
21 amount: totalAmount,
22}).sendAndConfirm(umi)
23
24// The distribution ATA contains 350000 base units.

이 튜토리얼은 토큰만 입금합니다. 선택적 클레임 영수증 임대료 보조금은 자금 투입과 회수에서 다룹니다.

지갑 할당 클레임

커밋된 목록에서 생성한 동일한 수신자, amount, nonce, 증명을 제출해 할당을 클레임합니다.

claimDistribution.ts
1import {
2 distribute,
3 mplDistro,
4 prepareDistribution,
5} from '@metaplex-foundation/mpl-distro'
6import { publicKey } from '@metaplex-foundation/umi'
7import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
8
9const umi = createUmi(
10 process.env.RPC_URL ?? 'https://api.devnet.solana.com'
11).use(mplDistro())
12
13// The payer may be the recipient or a third-party distributor, depending on
14// the distribution's allowedDistributor setting.
15
16const distribution = publicKey(process.env.DISTRIBUTION_ADDRESS!)
17const mint = publicKey(process.env.TOKEN_MINT!)
18const recipients = [
19 { address: publicKey(process.env.RECIPIENT_1!), amount: 100_000n },
20 { address: publicKey(process.env.RECIPIENT_2!), amount: 250_000n },
21]
22const recipientIndex = 0
23const { proofs } = prepareDistribution(recipients)
24
25await distribute(umi, {
26 distribution,
27 mint,
28 recipient: recipients[recipientIndex].address,
29 amount: recipients[recipientIndex].amount,
30 proof: proofs[recipientIndex],
31 nonce: 0,
32}).sendAndConfirm(umi)
33
34// The recipient ATA receives 100000 base units and a claim receipt is created.

프로그램은 필요하면 수신자의 정규 associated token account를 만들고, 볼트에서 토큰을 전송하며, 클레임 영수증을 만듭니다. 같은 할당의 두 번째 트랜잭션은 AlreadyClaimed로 실패합니다.

MPL-Distro 계정 확인

확인 후 배포와 결정적 클레임 영수증을 가져와 클레임을 검증합니다.

verifyClaim.ts
1import {
2 fetchClaimReceipt,
3 fetchDistribution,
4 findClaimReceiptPda,
5 mplDistro,
6} from '@metaplex-foundation/mpl-distro'
7import { publicKey } from '@metaplex-foundation/umi'
8import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
9
10const umi = createUmi(
11 process.env.RPC_URL ?? 'https://api.devnet.solana.com'
12).use(mplDistro())
13
14const distribution = publicKey(process.env.DISTRIBUTION_ADDRESS!)
15const recipients = [
16 { address: publicKey(process.env.RECIPIENT_1!), amount: 100_000n },
17 { address: publicKey(process.env.RECIPIENT_2!), amount: 250_000n },
18]
19const recipientIndex = 0
20
21const [receipt] = findClaimReceiptPda(umi, {
22 distribution,
23 recipient: recipients[recipientIndex].address,
24 amount: recipients[recipientIndex].amount,
25 nonce: 0,
26})
27
28const [distributionAccount, receiptAccount] = await Promise.all([
29 fetchDistribution(umi, distribution),
30 fetchClaimReceipt(umi, receipt),
31])
32
33console.log(distributionAccount.claimCount)
34console.log(receiptAccount.amount)
35
36// claimCount includes this allocation and the receipt stores 100000

일반적인 MPL-Distro 오류

MPL-Distro 오류는 일치하지 않는 증명, 창, 권한, 볼트 잔액을 식별합니다.

오류원인해결
InvalidClaimProof주소, amount, nonce, 또는 증명이 커밋된 리프와 다름같은 보존된 할당 레코드에서 모든 값을 불러오세요
DistributionNotStarted클러스터 타임스탬프가 startTime보다 앞섬구성된 Unix 타임스탬프까지 기다리세요
DistributionEnded클러스터 타임스탬프가 endTime보다 뒤권한자가 새 배포를 만들어야 합니다
AlreadyClaimed클레임 영수증 PDA가 이미 존재함할당을 완료로 취급하세요
InsufficientFunds기록된 배포 잔액이 클레임 금액보다 적음활성 창 전·중·후에 더 입금하거나 이전 출금을 검토하세요
RecipientMustSignrecipient 게이트 클레임에서 수신자 서명자가 빠짐수신자를 서명자로 제출하세요
InvalidDistributorpermissioned distributor가 일치하지 않음구성된 distributor 서명자를 사용하세요

검증된 구성

시작하기 흐름은 현재 MPL-Distro 클라이언트 테스트와 생성된 명령 빌더를 따릅니다.

구성 요소버전
@metaplex-foundation/mpl-distro0.4.x
@metaplex-foundation/umi1.1.x 이상
@metaplex-foundation/mpl-toolbox0.10.x
Token program원본 SPL Token 프로그램

참고사항

시작하기 흐름은 작은 지갑 배포를 보여 줍니다. 프로덕션 전달이 증명 저장, 클레임 페이지, 미클레임 토큰 회수를 다룹니다.

  • Unix 타임스탬프는 초이며 JavaScript 밀리초가 아닙니다.
  • 토큰 기본 단위 수량과 타임스탬프에는 bigint를 사용하세요.
  • prepareDistribution은 1,000개 할당에서 메모리 최적화 구현으로 전환합니다.
  • 매우 큰 할당 구축은 제어된 Node.js 프로세스에서 실행하고, mainnet에 자금을 넣기 전에 증명 전달을 테스트하세요.
  • Permissionless 지불자는 다른 지갑의 클레임을 제출할 수 있지만, 토큰은 그 수신자에게만 갑니다.

FAQ

MPL-Distro가 토큰 mint를 만드나요?

아니요. 배포를 만들기 전에 SPL 토큰 mint를 만들고 자금을 넣으세요.

Merkle 증명은 어디에 저장해야 하나요?

프로그램은 루트만 저장하므로 각 주소, amount, nonce, 증명을 내구성 있는 데이터베이스 또는 클레임 파일에 저장하세요. 프로덕션 전달을 참조하세요.

한 지갑이 여러 할당을 받을 수 있나요?

예. 그 외에는 동일한 지갑과 amount 할당마다 다른 nonce를 지정하세요.

Previous
개요