본문으로 건너뛰기

"integration" 태그로 연결된 1 개 게시물 개의 게시물이 있습니다.

플랫폼 통합

모든 태그 보기

Solana 에서의 PYUSD: 실전 연동 가이드 (BlockEden.xyz RPC 활용)

· 약 9 분
Dora Noda
Software Engineer

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의 성능이 결합되어 디지털 달러를 위한 강력하고 새로운 레일이 생성되었습니다.

  1. 소비자 신뢰와 크립토 UX의 결합: PYUSD는 규제 대상 신탁 회사인 Paxos에서 발행하며 PayPal 및 Venmo에 긴밀하게 통합되어 있습니다. 이는 사용자에게 친숙한 자산을 제공합니다. 사용자는 하나의 PYUSD 잔액을 보유하고 Ethereum 또는 Solana의 외부 지갑으로 출금하도록 선택할 수 있어 체인의 복잡성을 추상화합니다.
  2. 결제 준비가 완료된 레일: Solana의 아키텍처는 1초 미만의 트랜잭션 확정성과 센트 단위 미만의 수수료를 제공합니다. PYUSD는 이러한 효율적인 결제 네트워크 위에 안정적이고 인식 가능한 계정 단위를 레이어링하여 결제, 상거래 및 송금에 이상적입니다.
  3. 기관급 제어 기능: 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을 받기 위해 사용합니다.

흔한 실수와 해결 방법​

  1. 잘못된 프로그램 ID: 문제: 트랜잭션이 incorrect program id for instruction 오류와 함께 실패합니다. 해결: 모든 spl-token 헬퍼 함수(getOrCreateAssociatedTokenAccount, getAccount, createTransferCheckedInstruction 등)에 TOKEN_2022_PROGRAM_ID를 명시적으로 전달하세요.
  2. 잘못된 Mint 또는 가짜 자산: 문제: 애플리케이션이 가짜 PYUSD 토큰과 상호작용합니다. 해결: 공식 mint 주소인 2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo를 하드코딩하고 확인하세요. 정식 mint가 아닌 경우 경고를 표시하는 익스플로러를 사용하세요.
  3. 소수점 자리수 불일치: 문제: 1 PYUSD를 보냈는데 실제로 0.000001 PYUSD만 전송됩니다. 해결: 항상 UI 금액에 10^6을 곱하여 원시 금액으로 변환하세요. 안전을 위해 mint의 소수점 자리수를 프로그래밍 방식으로 가져오세요.
  4. 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 엔드포인트를 확보하고 지금 바로 결제의 미래를 통합해 보세요.