Her Solana işlemi, ağ ücretlerini ödemek için SOL gerektirir. Ancak ödeme uygulamanıza gelen kullanıcılar stablecoin'lerle işlem yapmayı bekler—ikinci bir token bakiyesi yönetmeyi değil. Ücret soyutlama, ücretleri başka birinin ödemesini sağlayarak bu sürtünmeyi ortadan kaldırır.
Bu kılavuz iki seviyeyi kapsar:
- Ücret sponsorluğu nasıl çalışır — altta yatan Solana ilkeli
- Kora ile ölçekte ücret soyutlama — üretime hazır bir ücret soyutlama hizmeti
Ücret sponsorluğu nasıl çalışır
Solana işlemlerinin belirlenmiş bir ücret ödeyicisi vardır—ağ ücretini ödeyen hesap. Varsayılan olarak bu, ilk imzalayandır. Ancak ücret ödeyici olarak farklı bir hesap belirleyebilirsiniz, bu da üçüncü bir tarafın ("sponsor") gönderen adına ücretleri karşılamasına olanak tanır.
Hem gönderen hem de sponsor işlemi imzalamalıdır:
- Gönderen, token'larının transferini yetkilendirmek için imzalar
- Sponsor, ağ ücretinin ödenmesini yetkilendirmek için imzalar
Temel ödeme kavramları için Solana'da ödemeler nasıl çalışır bölümüne bakın.
Aşağıdaki adımlar temel akışı gösterir. Tam çalıştırılabilir kod için Demo bölümüne bakın.
Sponsor hesabı oluştur
İşlem ücretlerini ödeyecek sponsor için ayrı bir keypair oluşturun. Sponsor'un ücretler için SOL'a ihtiyacı vardır ancak transfer edilen token'ları tutmasına gerek yoktur.
Transfer talimatı oluştur
Gönderen yetkili olarak token transfer talimatını oluşturun. Gönderen token'lara sahiptir ve transferi imzalamalıdır.
Sponsor'u ücret ödeyici olarak kullanarak gönder
prepareAndSend metodunu hem authority (transferi imzalayan gönderici) hem de
feePayer (ücretleri ödeyen sponsor) ile kullanın. Her ikisi de işlemi
imzalamalıdır.
Demo
// Generate keypairs for sender, recipient, and sponsor (fee payer)const sender = (await generateKeypair()).signer;const recipient = (await generateKeypair()).signer;const sponsor = (await generateKeypair()).signer;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 = getTransferInstruction({source: senderAta,destination: recipientAta,authority: sender, // Pass signer, not just addressamount: 250_000n // 0.25 tokens});// Prepare and send transaction with sponsor as fee payer using @solana/client// The sponsor pays transaction fees, sender signs for the transferconst signature = await client.transaction.prepareAndSend({authority: sender, // Sender signs the transfer instructionfeePayer: sponsor, // Sponsor pays the transaction fees (different account)instructions: [transferInstruction],version: 0});console.log("\n=== Sponsored Token Payment Complete ===");console.log("Transaction Signature:", signature.toString());// Fetch final token account balances using @solana/client SPL token helperconst splToken = client.splToken({mint: mint.address,tokenProgram: "auto"});const senderBalance = await splToken.fetchBalance(sender.address);const recipientBalance = await splToken.fetchBalance(recipient.address);console.log("\nSender Token Account Balance:", senderBalance);console.log("Recipient Token Account Balance:", recipientBalance);// Fetch transaction detailsconst transaction = await client.runtime.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// =============================================================================
Son kullanıcı için bir token account oluşturduğunuzda, kullanıcı bunu kapatabilir ve rent için kullanılan SOL'u geri alabilir. Hesap oluşturma için kullanıcılardan stablecoin cinsinden ücret almayı düşünün veya bu maliyeti ürün ekonominize dahil edin.
Kora ile ölçekte ücret soyutlama
Ücret ödeyici primitive güçlüdür, ancak production seviyesinde gassız bir sistem oluşturmak daha fazlasını gerektirir: sponsor cüzdanlarını yönetmek, token dönüşümlerini işlemek (kullanıcıların USDC ile ücret "ödemesi" için), hız sınırlama ve güvenlik kontrolleri.
Kora bu karmaşıklığı yönetir. Kullanıcıların asla SOL'a ihtiyaç duymayacağı şekilde ücret soyutlama sağlayan bir JSON-RPC sunucusudur. Ücretleri tamamen sponsor edebilir veya herhangi bir token ile ücret ödemesini kabul edebilirsiniz.
Kora'yı tek bir komutla deploy edin:
cargo install kora-clikora --config path/to/kora.toml rpc start --signers-config path/to/signers.toml
Ardından işlemleri imzalamak ve göndermek için Kora client'ını kullanın:
pnpm add @solana/kora
import { KoraClient } from "@solana/kora";const kora = new KoraClient({ rpcUrl: "https://your-kora-instance" });const { signature } = await kora.signAndSendTransaction({transaction: base64EncodedTransaction});
Kora kaynakları
Is this page helpful?