Astrazione delle commissioni

Ogni transazione Solana richiede SOL per pagare le commissioni di rete. Ma gli utenti che arrivano alla tua applicazione di pagamento si aspettano di effettuare transazioni in stablecoin, non di gestire un secondo saldo di token. L'astrazione delle commissioni elimina questo attrito facendo pagare le commissioni a qualcun altro.

Questa guida copre due livelli:

  1. Come funziona la sponsorizzazione delle commissioni — la primitiva sottostante di Solana
  2. Astrazione delle commissioni su larga scala con Kora — un servizio di astrazione delle commissioni pronto per la produzione

Come funziona la sponsorizzazione delle commissioni

Le transazioni Solana hanno un pagatore di commissioni designato, l'account che paga la commissione di rete. Per impostazione predefinita, questo è il primo firmatario. Ma puoi specificare un account diverso come pagatore delle commissioni, consentendo a una terza parte (lo "sponsor") di coprire le commissioni per conto del mittente.

Sia il mittente che lo sponsor devono firmare la transazione:

  • Il mittente firma per autorizzare il trasferimento dei propri token
  • Lo sponsor firma per autorizzare il pagamento della commissione di rete

Vedi Come funzionano i pagamenti su Solana per i concetti fondamentali sui pagamenti.

I passaggi seguenti mostrano il flusso principale. Vedi la Demo per il codice completo eseguibile.

Crea un account sponsor

Genera una keypair separata per lo sponsor che pagherà le commissioni di transazione. Lo sponsor ha bisogno di SOL per le commissioni ma non deve detenere i token che vengono trasferiti.

Sponsor Transaction Fee
const sponsor = await generateKeyPairSigner();

Crea l'istruzione di trasferimento

Crea l'istruzione di trasferimento dei token con il mittente come autorità. Il mittente possiede i token e deve firmare il trasferimento.

Invia con lo sponsor come pagatore delle commissioni

Crea il client con lo sponsor impostato come pagatore delle commissioni tramite payer(sponsor), poi chiama client.sendTransaction. Lo sponsor firma per pagare la commissione di rete mentre il mittente firma per autorizzare il trasferimento—sendTransaction raccoglie automaticamente ogni firmatario referenziato.

Crea un account sponsor

Genera una keypair separata per lo sponsor che pagherà le commissioni di transazione. Lo sponsor ha bisogno di SOL per le commissioni ma non deve detenere i token che vengono trasferiti.

Crea l'istruzione di trasferimento

Crea l'istruzione di trasferimento dei token con il mittente come autorità. Il mittente possiede i token e deve firmare il trasferimento.

Invia con lo sponsor come pagatore delle commissioni

Crea il client con lo sponsor impostato come pagatore delle commissioni tramite payer(sponsor), poi chiama client.sendTransaction. Lo sponsor firma per pagare la commissione di rete mentre il mittente firma per autorizzare il trasferimento—sendTransaction raccoglie automaticamente ogni firmatario referenziato.

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.

Quando crei un token account per un utente finale, questi può chiuderlo e recuperare i SOL utilizzati per il rent. Considera di addebitare agli utenti la creazione dell'account in stablecoin, oppure includi questo costo nell'economia del tuo prodotto.

Astrazione delle commissioni su larga scala con Kora

La primitiva del pagatore delle commissioni è potente, ma costruire un sistema gasless in produzione richiede di più: gestire i wallet degli sponsor, gestire le conversioni di token (in modo che gli utenti possano "pagare" le commissioni in USDC), limitazione della frequenza e controlli di sicurezza.

Kora gestisce questa complessità. È un server JSON-RPC che fornisce l'astrazione delle commissioni in modo che gli utenti non abbiano mai bisogno di SOL. Puoi sponsorizzare completamente le commissioni o accettare il pagamento delle commissioni in qualsiasi token.

Distribuisci Kora con un singolo comando:

cargo install kora-cli
kora --config path/to/kora.toml rpc start --signers-config path/to/signers.toml

Quindi punta un client Kit al tuo server Kora e invia transazioni con la stessa API utilizzata sopra:

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);

Risorse Kora

Is this page helpful?

Indice dei contenuti

Modifica pagina
© 2026 Solana Foundation. Tutti i diritti riservati.