Cada transacción de Solana requiere SOL para pagar las tarifas de red. Pero los usuarios que llegan a tu aplicación de pagos esperan realizar transacciones en stablecoins, no gestionar un segundo saldo de tokens. La abstracción de tarifas elimina esta fricción al hacer que otra persona pague las tarifas.
Esta guía cubre dos niveles:
- Cómo funciona el patrocinio de tarifas — el primitivo subyacente de Solana
- Abstracción de tarifas a escala con Kora — un servicio de abstracción de tarifas listo para producción
Cómo funciona el patrocinio de tarifas
Las transacciones de Solana tienen un pagador de tarifas designado: la cuenta que paga la tarifa de red. Por defecto, este es el primer firmante. Pero puedes especificar una cuenta diferente como pagador de tarifas, permitiendo que un tercero (el "patrocinador") cubra las tarifas en nombre del remitente.
Tanto el remitente como el patrocinador deben firmar la transacción:
- El remitente firma para autorizar la transferencia de sus tokens
- El patrocinador firma para autorizar el pago de la tarifa de red
Consulta Cómo funcionan los pagos en Solana para conocer los conceptos básicos de pagos.
Los pasos a continuación muestran el flujo principal. Consulta la Demo para ver el código completo ejecutable.
Crear una cuenta de patrocinador
Genera un keypair separado para el patrocinador que pagará las tarifas de transacción. El patrocinador necesita SOL para las tarifas pero no necesita mantener los tokens que se están transfiriendo.
Crear instrucción de transferencia
Crea la instrucción de transferencia de tokens con el remitente como autoridad. El remitente posee los tokens y debe firmar la transferencia.
Enviar con patrocinador como pagador de tarifas
Usa prepareAndSend con ambos authority (el remitente que firma la
transferencia) y feePayer (el patrocinador que paga las tarifas). Ambos deben
firmar la transacción.
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// =============================================================================
Cuando creas una token account para un usuario final, este puede cerrarla y recuperar el SOL utilizado para rent. Considera cobrar a los usuarios por la creación de cuentas en stablecoins, o incluye este costo en la economía de tu producto.
Abstracción de tarifas a escala con Kora
La primitiva de pagador de tarifas es poderosa, pero construir un sistema sin gas en producción requiere más: gestionar billeteras de patrocinadores, manejar conversiones de tokens (para que los usuarios puedan "pagar" tarifas en USDC), limitación de tasa y controles de seguridad.
Kora maneja esta complejidad. Es un servidor JSON-RPC que proporciona abstracción de tarifas para que los usuarios nunca necesiten SOL. Puedes patrocinar completamente las tarifas o aceptar el pago de tarifas en cualquier token.
Despliega Kora con un solo comando:
cargo install kora-clikora --config path/to/kora.toml rpc start --signers-config path/to/signers.toml
Luego usa el cliente de Kora para firmar y enviar transacciones:
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 de Kora
Inicio rápido de Kora
Pon Kora en funcionamiento localmente en minutos.
Demo de transacción completa
Guía completa de implementación de transacciones con abstracción de tarifas.
Referencia de API
Métodos JSON-RPC y documentación del SDK.
Guía del operador de nodo
Despliega y configura tu propia instancia de Kora.
Is this page helpful?