Abstracción de tarifas

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:

  1. Cómo funciona el patrocinio de tarifas — el primitivo subyacente de Solana
  2. 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

Crea el cliente con el patrocinador configurado como pagador de comisiones mediante payer(sponsor), luego llama a client.sendTransaction. El patrocinador firma para pagar la comisión de red mientras que el remitente firma para autorizar la transferencia—sendTransaction recopila automáticamente cada firmante referenciado.

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

Crea el cliente con el patrocinador configurado como pagador de comisiones mediante payer(sponsor), luego llama a client.sendTransaction. El patrocinador firma para pagar la comisión de red mientras que el remitente firma para autorizar la transferencia—sendTransaction recopila automáticamente cada firmante referenciado.

Sponsor Transaction Fee
const sponsor = await generateKeyPairSigner();

Demo

Demo
// 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 tokens
const { client, mint } = await demoSetup(sender, recipient, sponsor);
console.log("\nMint Address:", mint.address);
// Derive the Associated Token Accounts addresses (ATAs) for sender and recipient
const [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 transfer
amount: 250_000n, // 0.25 tokens
decimals: 6
});
// Send transaction with sponsor as fee payer using @solana/kit
// The sponsor (client.payer) pays fees; the sender signs for the transfer
const { 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 RPC
const 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 details
const 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
// =============================================================================
Console
Click to execute the code.

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-cli
kora --config path/to/kora.toml rpc start --signers-config path/to/signers.toml

Luego apunta un cliente Kit a tu servidor Kora y envía transacciones con la misma API utilizada anteriormente:

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 SOL
const kora = await createKitKoraClient({
endpoint: "https://your-kora-instance",
rpcUrl: "https://api.mainnet-beta.solana.com",
feeToken: address("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"), // USDC
feePayerWallet: sender // Signs to authorize the token fee payment
});
// Same instruction, same call—Kora sponsors the network fee
const { context } = await kora.sendTransaction([transferInstruction]);
console.log("Signature:", context.signature);

Recursos de Kora

Is this page helpful?

Tabla de Contenidos

Editar Página