Solana 에서의 PYUSD: 실전 연동 가이드 (BlockEden.xyz RPC 활용)
PayPal USD (PYUSD)가 Solana에 출시되며 디지털 결제의 중요한 이정표를 세웠습니다. 이 가이드는 엔지니어가 PYUSD를 Solana의 지갑, dApp 및 커머스 플랫폼에 통합하기 위한 직접적이고 실무적인 과정을 제공합니다.
모든 예제는 최신 Token-2022 호환 코드를 사용하며 BlockEden.xyz의 저지연 Solana RPC 엔드포인트와 원활하게 작동하도록 설계되었습니다.
핵심 요약
- 무엇인가: PayPal USD (PYUSD)는 이제 Solana의 네이티브 Token-2022 SPL 토큰으로, 세계적으로 인정받는 스테이블코인을 빠르고 저렴한 수수료로 결제할 수 있도록 지원합니다.
- 주요 파라미터: Mint
2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo, 소수점 자리수6, 토큰 프로그램Token-2022. - 기능 세트: Solana 토큰 확장(Token Extensions / Token-2022)을 활용합니다. Transfer Hook이 초기화되었으나 현재는 비활성 상태(null 프로그램)이며, 기밀 전송(confidential transfer) 기능 및 기타 확장 기능이 포함되어 있습니다.
- 크로스 체인: 공식 LayerZero 통합을 통해 기존 브릿지 대신 안전한 소각 및 발행(burn-and-mint) 메 커니즘을 사용하여 Ethereum과 Solana 간에 PYUSD를 이동할 수 있습니다.
- 실행: BlockEden.xyz의 신뢰할 수 있는 Solana RPC를 사용하여 애플리케이션에 PYUSD 지원을 추가하는 템플릿으로 이 가이드를 활용하세요.
Solana 기반 PYUSD가 중요한 이유
PayPal의 브랜드 파워와 Solana의 성능이 결합되어 디지털 달러를 위한 강력하고 새로운 레일이 생성되었습니다.
- 소비자 신뢰와 크립토 UX의 결합: PYUSD는 규제 대상 신탁 회사인 Paxos에서 발행하며 PayPal 및 Venmo에 긴밀하게 통합되어 있습니다. 이는 사용자에게 친숙한 자산을 제공합니다. 사용자는 하나의 PYUSD 잔액을 보유하고 Ethereum 또는 Solana의 외부 지갑으로 출금하도록 선택할 수 있어 체인의 복잡성을 추상화합니다.
- 결제 준비가 완료된 레일: Solana의 아키텍처는 1초 미만의 트랜잭션 확정성과 센트 단위 미만의 수수료를 제공합니다. PYUSD는 이러한 효율적인 결제 네트워크 위에 안정적이고 인식 가능한 계정 단위를 레이어링하여 결제, 상거래 및 송금에 이상적입니다.
- 기관급 제어 기능: Token-2022 토큰으로 출시됨으로써 PYUSD는 기밀 전송, 풍부한 메타데이터 및 영구 위임(permanent delegate)과 같은 기능에 내장된 확장 프로그램을 활용할 수 있습니다. 이를 통해 복잡하고 감사하기 어려운 별도의 스마트 컨트랙트 없이도 고급 규정 준수 및 기 능을 구현할 수 있습니다.
필수 정보 (이것만은 꼭 확인하세요)
코드를 작성하기 전에 다음 파라미터를 고정하세요. 사기성 토큰과의 상호작용을 피하기 위해 항상 신뢰할 수 있는 익스플로러에서 mint 주소를 확인하세요.
- Mint (메인넷):
2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo - 소수점 자리수:
6(즉, 1 PYUSD = 1,000,000 기본 단위) - 토큰 프로그램:
Token-2022(프로그램 ID:TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb) - 사용된 토큰 확장 프로그램 (발행 시):
- Metadata & Metadata Pointer (메타데이터 및 메타데이터 포인터)
- Permanent Delegate (영구 위임)
- Transfer Hook (null 프로그램으로 초기화됨)
- Confidential Transfer Configuration (기밀 전송 구성)
이 모든 정보는 Solana Explorer에서 확인할 수 있습니다. 익스플로러는 공식 mint 주소와 활성화된 확장 프로그램을 명확하게 보여줍니다.
프로젝트 설정
환경을 준비해 보겠습니다. 완전한 Token-2022 호환성을 보장하기 위해 최신 Solana web3 및 SPL 토큰 라이브러리가 필요합니다.
1. 라이브러리
npm에서 필요한 패키지를 설치합니다.
npm i @solana/web3.js @solana/spl-token
2. RPC 연결
애플리케이션이 BlockEden.xyz Solana 메인넷 RPC URL을 가리키도록 설정합니다. 프로덕션 환경에서는 환경 변수 사용이 필수적입니다.
// package.json
// npm i @solana/web3.js @solana/spl-token
import { Connection, Keypair, PublicKey } from "@solana/web3.js";
import {
TOKEN_2022_PROGRAM_ID,
getMint,
getOrCreateAssociatedTokenAccount,
getAssociatedTokenAddress,
createTransferCheckedInstruction,
} from "@solana/spl-token";
// 대시보드에서 받은 BlockEden.xyz Solana RPC URL을 사용하세요
const RPC_ENDPOINT =
process.env.SOLANA_RPC_URL ??
"[https://your-blockeden-solana-mainnet-endpoint.com](https://your-blockeden-solana-mainnet-endpoint.com)";
export const connection = new Connection(RPC_ENDPOINT, "confirmed");
// PYUSD (메인넷)
export const PYUSD_MINT = new PublicKey(
"2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo",
);
PYUSD Mint 데이터 읽기
먼저, 프로그래밍 방식으로 PYUSD mint의 속성을 확인해 보겠습니다. 이는 상수가 올바른지 확인하고 총 공급량과 같은 세부 정보를 가져오는 중요한 첫 단계입니다.
// Token-2022 API를 통해 PYUSD mint 정보 확인
const mintInfo = await getMint(
connection,
PYUSD_MINT,
"confirmed",
TOKEN_2022_PROGRAM_ID, // 프로그램 ID 지정
);
console.log({
supply: mintInfo.supply.toString(),
decimals: mintInfo.decimals, // 6 예상
isInitialized: mintInfo.isInitialized,
});
TOKEN_2022_PROGRAM_ID를 명시적으로 전달하는 것에 유의하세요. 이는 토큰 확장 프로그램을 사용할 때 발생하는 가장 흔한 오류의 원인입니다.
연관 토큰 계정(ATA) 생성 또는 가져오기
Token-2022 토큰을 위한 연관 토큰 계정은 반드시 Token-2022 프로그램 ID를 사용하여 파생되어야 합니다. 레거시 TOKEN_PROGRAM_ID를 사용하면 트랜잭션이 "incorrect program id" 오류와 함께 실패합니다.
// 새 ATA의 비용 지불자 및 소유자. 실제 지갑 로직으로 교체하세요.
const owner = Keypair.generate();
// 소유자의 PYUSD ATA 생성 또는 가져오기 (Token-2022 인식)
const ownerAta = await getOrCreateAssociatedTokenAccount(
connection,
owner, // 생성을 위한 비용 지불자
PYUSD_MINT, // Mint 주소
owner.publicKey, // ATA 소유자
false, // allowOwnerOffCurve
"confirmed",
undefined, // options
TOKEN_2022_PROGRAM_ID, // <-- 중요: Token-2022 프로그램 ID 사용
);
console.log("소유자 PYUSD ATA:", ownerAta.address.toBase58());
PYUSD 잔액 확인
사용자의 PYUSD 잔액을 확인하려면 ATA를 조회할 때 역시 올바른 프로그램 ID를 지정해야 함을 기억하세요.
@solana/spl-token 사용
import { getAccount } from "@solana/spl-token";
const accountInfo = await getAccount(
connection,
ownerAta.address,
"confirmed",
TOKEN_2022_PROGRAM_ID,
);
const balance = Number(accountInfo.amount) / 10 ** mintInfo.decimals; // decimals = 6
console.log("PYUSD 잔액:", balance);
직접 JSON-RPC 사용 (curl)
소유자의 모든 토큰 계정을 확인하고 Token-2022 프로그램 ID로 필터링할 수도 있습니다.
curl -X POST "$SOLANA_RPC_URL" -H 'content-type: application/json' -d '{
"jsonrpc":"2.0",
"id":1,
"method":"getTokenAccountsByOwner",
"params":[
"<OWNER_PUBLIC_KEY>",
{ "programId":"TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb" },
{ "encoding":"jsonParsed" }
]
}'
PYUSD 전송 (사용자 간 전송)
Token-2022 자산을 전송할 때의 철칙은 createTransferCheckedInstruction을 사용하는 것입니다. 이 명령에는 토큰의 소수점 자리수가 포함되어 있어 소수점 관련 보안 취약점을 방지할 수 있습니다.
다음은 PYUSD 전송을 위한 완전하고 재사용 가능한 함수입니다.
import { Transaction } from '@solana/web3.js';
async function transferPyusd({
fromWallet, // 발신자 Keypair
toPubkey, // 수신자 PublicKey
uiAmount, // PYUSD 금액, 예: 1.25
}: {
fromWallet: Keypair;
toPubkey: PublicKey;
uiAmount: number;
}) {
const decimals = 6; // mintInfo.decimals에서 가져옴
const rawAmount = BigInt(Math.round(uiAmount * (10 ** decimals)));
// 발신자의 ATA 주소 가져오기
const fromAta = await getAssociatedTokenAddress(
PYUSD_MINT,
fromWallet.publicKey,
false,
TOKEN_2022_PROGRAM_ID
);
// 수신자의 Token-2022용 ATA가 존재하는지 확인
const toAta = await getOrCreateAssociatedTokenAccount(
connection,
fromWallet, // 비용 지불자
PYUSD_MINT,
toPubkey,
false,
'confirmed',
undefined,
TOKEN_2022_PROGRAM_ID
);
const transferInstruction = createTransferCheckedInstruction(
fromAta, // 소스 ATA
PYUSD_MINT, // Mint 주소
toAta.address, // 목적지 ATA
fromWallet.publicKey, // 소스 ATA 소유자
rawAmount, // 기본 단위 금액
decimals, // 소수점 자리수
[], // 멀티시그 서명자
TOKEN_2022_PROGRAM_ID // <-- 중요
);
const transaction = new Transaction().add(transferInstruction);
// 최근 블록해시 및 수수료 지불자 설정
transaction.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;
transaction.feePayer = fromWallet.publicKey;
const signature = await connection.sendTransaction(transaction, [fromWallet]);
await connection.confirmTransaction(signature, 'confirmed');
console.log('트랜잭션 성공, 시그니처:', signature);
return signature;
}
Transfer Hook에 관한 참고 사항: PYUSD의 mint는 Transfer Hook 확장을 초기화하지만 프로그램을 null로 설정합니다. 이는 현재 표준 전송이 추가 계정이나 로직 없이 작동함을 의미합니다. PayPal/Paxos가 나중에 hook을 활성화하면 새 프로그램을 가리키도록 mint를 업데이트할 것입니다. 그러면 통합 과정에서 해당 프로그램의 인터페이스에 필요한 추가 계정을 전달해야 합니다.
Solana CLI 빠른 테스트
커맨드 라인에서 빠른 수동 테스트를 위해 올바른 프로그램 ID와 함께 spl-token을 사용할 수 있습니다.
# CLI가 메인넷을 가리키고 있고 키페어에 잔액이 있는지 확인하세요.
# 수신자에게 1.00 PYUSD를 전송합니다.
spl-token --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb \
transfer 2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo 1.00 <RECIPIENT_PUBKEY> \
--fund-recipient --allow-unfunded-recipient
크로스 체인 PYUSD (Ethereum ↔ Solana)
PayPal은 LayerZero를 사용하여 공식적인 크로스 체인 기능을 구현했습니다. 위험한 제3자 브릿지에 의존하는 대신, 이는 네이티브 소각 및 발행 프로세스입니다. PYUSD는 소스 체인(예: Ethereum)에서 소각되고 동일한 양이 목적지 체인(Solana)에서 발행됩니다. 이는 브릿지 특유의 위험과 슬리피지를 제거합니다.
전체 튜토리얼과 파라미터는 공식 PayPal Developer 문서에서 확인할 수 있습니다.
테스트용 파우셋(Faucets)
개발 및 테스트 시에는 메인넷 자산을 사용하지 마세요. 공식 파우셋을 사용하세요:
- Paxos PYUSD Faucet: 테스트넷 PYUSD 토큰을 받기 위해 사용합니다.
- Solana Faucet: 트랜잭션 수수료를 위한 데브넷/테스트넷 SOL을 받기 위해 사용합니다.
흔한 실수와 해결 방법
- 잘못된 프로그램 ID: 문제: 트랜잭션이
incorrect program id for instruction오류와 함께 실패합니다. 해결: 모든spl-token헬퍼 함수(getOrCreateAssociatedTokenAccount,getAccount,createTransferCheckedInstruction등)에TOKEN_2022_PROGRAM_ID를 명시적으로 전달하세요. - 잘못된 Mint 또는 가짜 자산: 문제: 애플리케이션이 가짜 PYUSD 토큰과 상호작용합니다. 해결: 공식 mint 주소인
2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo를 하드코딩하고 확인하세요. 정식 mint가 아닌 경우 경고를 표시하는 익스플로러를 사용하세요. - 소수점 자리수 불일치: 문제: 1 PYUSD를 보냈는데 실제로 0.000001 PYUSD만 전송됩니다. 해결: 항상 UI 금액에
10^6을 곱하여 원시 금액으로 변환하세요. 안전을 위해 mint의 소수점 자리수를 프로그래밍 방식으로 가져오세요. - Hook 관련 가정: 문제: 활성화되지 않은 transfer hook을 위해 복잡한 로직을 미리 빌드합니다. 해결: mint의 확장 데이터를 확인하세요. 현재 PYUSD의 hook은 null입니다. 향후 hook 프로그램이 활성화될 경우 적응할 수 있도록 시스템을 구축하세요.
PYUSD + BlockEden.xyz 프로덕션 체크리스트
프로덕션으로 전환할 때 인프라가 견고한지 확인하세요.
- RPC: 고가용성 BlockEden.xyz 엔드포인트를 사용하세요. 빠른 응답을 위해
confirmed확정도를 사용하고, 원장 무결성이 필요한 작업에는finalized로 쿼리하세요. - 재시도 및 멱등성: 지수 백오프(exponential backoff) 재시도 메커니즘으로 트랜잭션 제출을 감싸세요. 중복 전송을 방지하기 위해 각 비즈니스 작업과 함께 멱등성 키를 저장하세요.
- 관측성: 트랜잭션 시그니처, 슬롯 번호 및 트랜잭션 후 잔액을 기록하세요. BlockEden.xyz의 웹소켓 구독을 사용하여 애플리케이션 백엔드에서 실시간 결제 신호를 받으세 요.
- 규정 준수: Token-2022는 규정 준수를 위한 기본 요소를 제공합니다. 트래블 룰(travel rule)과 같은 기능을 구현해야 하는 경우, 확장 모델을 사용하면 비즈니스 로직을 토큰의 핵심 기능과 분리하여 깔끔하게 구현할 수 있습니다.
부록 A — 빠른 참조
- Mint (메인넷):
2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo - 소수점 자리수:
6 - 토큰 프로그램 ID:
TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb - 배경: PayPal은 2024년 5월 29일에 Solana 지원을 발표했습니다.
- 공식 문서: Solana Token Extensions, PayPal Developer Portal
부록 B — 직접 JSON-RPC 호출 (curl)
Mint 계정 정보 가져오기 및 소유자 확인
이 호출은 mint 계정 데이터를 가져오고 소유자가 Token-2022 프로그램인지 확인할 수 있게 해줍니다.
# BlockEden.xyz RPC URL로 교체하세요
curl -s -X POST "$SOLANA_RPC_URL" -H 'content-type: application/json' -d '{
"jsonrpc":"2.0","id":1,"method":"getAccountInfo",
"params":["2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo",
{"encoding":"base64","commitment":"confirmed"}]
}'
# JSON 응답에서 "owner" 필드는 "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb"와 같아야 합니다.
사용자의 모든 PYUSD 토큰 계정 나열
특정 사용자의 모든 PYUSD 보유량을 검색해야 하는 지갑 서비스에 유용합니다.
curl -s -X POST "$SOLANA_RPC_URL" -H 'content-type: application/json' -d '{
"jsonrpc":"2.0",
"id":1,
"method":"getTokenAccountsByOwner",
"params":[
"<OWNER_PUBLIC_KEY>",
{"mint":"2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo"},
{"encoding":"jsonParsed","commitment":"confirmed"}
]
}'
개발 준비가 되셨나요? 고성능 BlockEden.xyz RPC 엔드포인트를 확보하고 지금 바로 결제의 미래를 통합해 보세요.