Elke Solana-transactie vereist SOL om netwerkkosten te betalen. Maar gebruikers die naar jouw betalingsapplicatie komen, verwachten te transacteren in stablecoins—niet een tweede tokensaldo te beheren. Fee abstraction verwijdert deze wrijving doordat iemand anders de kosten betaalt.
Deze gids behandelt twee niveaus:
- Hoe fee sponsorship werkt — de onderliggende Solana-primitief
- Fee abstraction op schaal met Kora — een productierijpe fee abstraction-service
Hoe fee sponsorship werkt
Solana-transacties hebben een aangewezen fee payer—het account dat de netwerkkosten betaalt. Standaard is dit de eerste ondertekenaar. Maar je kunt een ander account als fee payer specificeren, waardoor een derde partij (de "sponsor") kosten kan dekken namens de verzender.
Zowel de verzender als de sponsor moeten de transactie ondertekenen:
- De verzender ondertekent om de overdracht van hun tokens te autoriseren
- De sponsor ondertekent om betaling van de netwerkkosten te autoriseren
Zie How Payments Work on Solana voor kernconcepten van betalingen.
De onderstaande stappen tonen de kernflow. Zie de Demo voor complete uitvoerbare code.
Maak een sponsor-account aan
Genereer een apart keypair voor de sponsor die transactiekosten zal betalen. De sponsor heeft SOL nodig voor kosten maar hoeft de tokens die worden overgedragen niet te bezitten.
Maak transfer-instructie aan
Maak de token transfer-instructie aan met de verzender als authority. De verzender bezit de tokens en moet de overdracht ondertekenen.
Verzenden met sponsor als betaler van kosten
Gebruik prepareAndSend met zowel authority (de verzender die de overdracht
ondertekent) als feePayer (de sponsor die de kosten betaalt). Beiden moeten de
transactie ondertekenen.
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// =============================================================================
Wanneer je een token account aanmaakt voor een eindgebruiker, kunnen ze deze sluiten en de SOL die gebruikt is voor rent terugvorderen. Overweeg om gebruikers te laten betalen voor het aanmaken van accounts in stablecoins, of verwerk deze kosten in je producteconomie.
Fee-abstractie op schaal met Kora
De fee payer primitive is krachtig, maar het bouwen van een productie-gasless systeem vereist meer: het beheren van sponsor wallets, het afhandelen van tokenconversies (zodat gebruikers kosten kunnen "betalen" in USDC), rate limiting en beveiligingscontroles.
Kora handelt deze complexiteit af. Het is een JSON-RPC server die fee-abstractie biedt zodat gebruikers nooit SOL nodig hebben. Je kunt kosten volledig sponsoren of betaling accepteren in elke token.
Deploy Kora met een enkel commando:
cargo install kora-clikora --config path/to/kora.toml rpc start --signers-config path/to/signers.toml
Gebruik vervolgens de Kora client om transacties te ondertekenen en te verzenden:
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-bronnen
Is this page helpful?