모든 Solana 트랜잭션은 네트워크 수수료를 지불하기 위해 SOL이 필요합니다. 하지만 결제 애플리케이션을 사용하는 사용자는 두 번째 토큰 잔액을 관리하는 것이 아니라 스테이블코인으로 거래하기를 기대합니다. 수수료 추상화는 다른 사람이 수수료를 지불하도록 하여 이러한 마찰을 제거합니다.
이 가이드는 두 가지 수준을 다룹니다:
- 수수료 후원 작동 방식 — 기본 Solana 프리미티브
- Kora를 사용한 대규모 수수료 추상화 — 프로덕션 준비가 완료된 수수료 추상화 서비스
수수료 후원 작동 방식
Solana 트랜잭션에는 네트워크 수수료를 지불하는 계정인 지정된 수수료 지불자가 있습니다. 기본적으로 이것은 첫 번째 서명자입니다. 하지만 다른 계정을 수수료 지불자로 지정할 수 있어 제3자("후원자")가 발신자를 대신하여 수수료를 부담할 수 있습니다.
발신자와 후원자 모두 트랜잭션에 서명해야 합니다:
- 발신자는 토큰 전송을 승인하기 위해 서명합니다
- 후원자는 네트워크 수수료 지불을 승인하기 위해 서명합니다
핵심 결제 개념은 Solana에서 결제 작동 방식을 참조하세요.
아래 단계는 핵심 흐름을 보여줍니다. 완전히 실행 가능한 코드는 데모를 참조하세요.
후원자 계정 생성
트랜잭션 수수료를 지불할 후원자를 위한 별도의 키페어를 생성합니다. 후원자는 수수료를 위해 SOL이 필요하지만 전송되는 토큰을 보유할 필요는 없습니다.
전송 명령 생성
발신자를 권한으로 하여 토큰 전송 명령을 생성합니다. 발신자는 토큰을 소유하며 전송에 서명해야 합니다.
스폰서를 수수료 지불자로 하여 전송하기
payer(sponsor)를 통해 스폰서를 수수료 지불자로 설정하여 클라이언트를 생성한
후, client.sendTransaction를 호출하세요. 스폰서는 네트워크 수수료를 지불하기
위해 서명하고 발신자는 전송을 승인하기 위해 서명합니다—sendTransaction는
참조된 모든 서명자를 자동으로 수집합니다.
데모
// Generate keypairs for sender, recipient, and sponsor (fee payer)const sender = await generateKeyPairSigner();const recipient = await generateKeyPairSigner();const sponsor = await generateKeyPairSigner();console.log("Sender Address:", sender.address);console.log("Recipient Address:", recipient.address);console.log("Sponsor Address (Fee Payer):", sponsor.address);// Demo Setup: Create client, mint account, token accounts, and fund with initial tokensconst { client, mint } = await demoSetup(sender, recipient, sponsor);console.log("\nMint Address:", mint.address);// Derive the Associated Token Accounts addresses (ATAs) for sender and recipientconst [senderAta] = await findAssociatedTokenPda({mint: mint.address,owner: sender.address,tokenProgram: TOKEN_2022_PROGRAM_ADDRESS});const [recipientAta] = await findAssociatedTokenPda({mint: mint.address,owner: recipient.address,tokenProgram: TOKEN_2022_PROGRAM_ADDRESS});console.log("Sender Token Account:", senderAta.toString());console.log("Recipient Token Account:", recipientAta.toString());// =============================================================================// Sponsored Token Payment Demo// =============================================================================// Create instruction to transfer tokens from sender to recipient// Transferring 250,000 base units = 0.25 tokens (with 6 decimals)const transferInstruction = getTransferCheckedInstruction({source: senderAta,mint: mint.address,destination: recipientAta,authority: sender, // Sender signs to authorize the transferamount: 250_000n, // 0.25 tokensdecimals: 6});// Send transaction with sponsor as fee payer using @solana/kit// The sponsor (client.payer) pays fees; the sender signs for the transferconst { context } = await client.sendTransaction([transferInstruction]);const signature = context.signature;console.log("\n=== Sponsored Token Payment Complete ===");console.log("Transaction Signature:", signature.toString());// Fetch final token account balances from the RPCconst senderBalance = await client.rpc.getTokenAccountBalance(senderAta).send();const recipientBalance = await client.rpc.getTokenAccountBalance(recipientAta).send();console.log("\nSender Token Account Balance:", senderBalance.value.uiAmount);console.log("Recipient Token Account Balance:",recipientBalance.value.uiAmount);// Fetch transaction detailsconst transaction = await client.rpc.getTransaction(signature, {encoding: "jsonParsed",maxSupportedTransactionVersion: 0}).send();const feePayer = transaction?.transaction.message.accountKeys?.[0];console.log("\nNote: The first account in accountKeys is always the fee payer");console.log("Fee Payer Address:", feePayer);// =============================================================================// Demo Setup Helper Function// =============================================================================
최종 사용자를 위해 토큰 계정을 생성할 때, 사용자는 해당 계정을 닫고 rent에 사용된 SOL을 회수할 수 있습니다. 스테이블코인으로 계정 생성 비용을 사용자에게 청구하거나, 이 비용을 제품 경제 모델에 반영하는 것을 고려하세요.
Kora를 통한 대규모 수수료 추상화
수수료 지불자 프리미티브는 강력하지만, 프로덕션 가스리스 시스템을 구축하려면 더 많은 것이 필요합니다: 스폰서 지갑 관리, 토큰 변환 처리(사용자가 USDC로 수수료를 "지불"할 수 있도록), 속도 제한 및 보안 제어가 필요합니다.
Kora가 이러한 복잡성을 처리합니다. 수수료 추상화를 제공하는 JSON-RPC 서버로, 사용자는 SOL이 전혀 필요하지 않습니다. 수수료를 완전히 후원하거나 모든 토큰으로 수수료 결제를 받을 수 있습니다.
단일 명령으로 Kora를 배포하세요:
cargo install kora-clikora --config path/to/kora.toml rpc start --signers-config path/to/signers.toml
그런 다음 Kit 클라이언트가 Kora 서버를 가리키도록 설정하고 위에서 사용한 동일한 API로 트랜잭션을 전송하세요:
pnpm add @solana/kora
import { address } from "@solana/kit";import { createKitKoraClient } from "@solana/kora";// A Kora-backed Kit client: Kora is the fee payer, and users pay// fees in the SPL token of your choice instead of SOLconst kora = await createKitKoraClient({endpoint: "https://your-kora-instance",rpcUrl: "https://api.mainnet-beta.solana.com",feeToken: address("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"), // USDCfeePayerWallet: sender // Signs to authorize the token fee payment});// Same instruction, same call—Kora sponsors the network feeconst { context } = await kora.sendTransaction([transferInstruction]);console.log("Signature:", context.signature);
Kora 리소스
Is this page helpful?