Cada transação na Solana requer SOL para pagar as taxas de rede. Mas os utilizadores que chegam à sua aplicação de pagamento esperam transacionar em stablecoins—não gerir um segundo saldo de token. A abstração de taxas remove este atrito ao ter outra pessoa a pagar as taxas.
Este guia abrange dois níveis:
- Como funciona o patrocínio de taxas — a primitiva subjacente da Solana
- Abstração de taxas em escala com Kora — um serviço de abstração de taxas pronto para produção
Como funciona o patrocínio de taxas
As transações na Solana têm um pagador de taxas designado—a conta que paga a taxa de rede. Por predefinição, este é o primeiro signatário. Mas pode especificar uma conta diferente como pagador de taxas, permitindo que um terceiro (o "patrocinador") cubra as taxas em nome do remetente.
Tanto o remetente como o patrocinador devem assinar a transação:
- O remetente assina para autorizar a transferência dos seus tokens
- O patrocinador assina para autorizar o pagamento da taxa de rede
Consulte Como funcionam os pagamentos na Solana para conceitos fundamentais de pagamento.
Os passos abaixo mostram o fluxo principal. Consulte a Demonstração para código completo executável.
Criar uma conta de patrocinador
Gere um keypair separado para o patrocinador que pagará as taxas de transação. O patrocinador precisa de SOL para as taxas, mas não precisa de deter os tokens que estão a ser transferidos.
Criar instrução de transferência
Crie a instrução de transferência de token com o remetente como autoridade. O remetente detém os tokens e deve assinar a transferência.
Enviar com patrocinador como pagador de taxa
Use prepareAndSend com ambos authority (o remetente que assina a
transferência) e feePayer (o patrocinador que paga as taxas). Ambos devem
assinar a transação.
Demonstração
// 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// =============================================================================
Quando você cria uma token account para um utilizador final, ele pode fechá-la e recuperar o SOL usado para rent. Considere cobrar os utilizadores pela criação de conta em stablecoins, ou incorpore este custo na economia do seu produto.
Abstração de taxas em escala com Kora
A primitiva de pagador de taxa é poderosa, mas construir um sistema sem taxas em produção requer mais: gerir carteiras de patrocinadores, lidar com conversões de tokens (para que os utilizadores possam "pagar" taxas em USDC), limitação de taxa e controlos de segurança.
Kora lida com esta complexidade. É um servidor JSON-RPC que fornece abstração de taxas para que os utilizadores nunca precisem de SOL. Você pode patrocinar totalmente as taxas ou aceitar pagamento de taxas em qualquer token.
Implemente o Kora com um único comando:
cargo install kora-clikora --config path/to/kora.toml rpc start --signers-config path/to/signers.toml
Depois use o cliente Kora para assinar e enviar transações:
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});
Recursos do Kora
Início rápido do Kora
Coloque o Kora a funcionar localmente em minutos.
Demonstração de transação completa
Guia completo de implementação de transação com abstração de taxas.
Referência da API
Métodos JSON-RPC e documentação do SDK.
Guia do operador de nó
Implemente e configure a sua própria instância do Kora.
Is this page helpful?