Абстракція комісій

Кожна транзакція в Solana потребує SOL для оплати мережевих комісій. Але користувачі, які приходять до вашого платіжного застосунку, очікують здійснювати транзакції у стейблкоїнах — а не керувати балансом другого токена. Абстракція комісій усуває це тертя, дозволяючи комусь іншому оплачувати комісії.

Цей посібник охоплює два рівні:

  1. Як працює спонсорство комісій — базовий примітив Solana
  2. Абстракція комісій у масштабі з Kora — готовий до продакшену сервіс абстракції комісій

Як працює спонсорство комісій

Транзакції Solana мають визначеного платника комісій — обліковий запис, який оплачує мережеву комісію. За замовчуванням це перший підписант. Але ви можете вказати інший обліковий запис як платника комісій, дозволяючи третій стороні ("спонсору") покривати комісії від імені відправника.

І відправник, і спонсор повинні підписати транзакцію:

  • Відправник підписує для авторизації переказу своїх токенів
  • Спонсор підписує для авторизації оплати мережевої комісії

Дивіться Як працюють платежі в Solana для основних концепцій платежів.

Кроки нижче показують основний потік. Дивіться Демо для повного робочого коду.

Створіть обліковий запис спонсора

Згенеруйте окрему пару ключів для спонсора, який оплачуватиме комісії транзакцій. Спонсору потрібен SOL для комісій, але йому не потрібно тримати токени, які переказуються.

Створіть інструкцію переказу

Створіть інструкцію переказу токенів з відправником як авторитетом. Відправник володіє токенами і повинен підписати переказ.

Надсилання зі спонсором як платником комісії

Створіть клієнта зі спонсором як платником комісії за допомогою payer(sponsor), потім викличте client.sendTransaction. Спонсор підписує транзакцію для оплати мережевої комісії, а відправник підписує для авторизації переказу — sendTransaction автоматично збирає кожного зазначеного підписанта.

Створіть обліковий запис спонсора

Згенеруйте окрему пару ключів для спонсора, який оплачуватиме комісії транзакцій. Спонсору потрібен SOL для комісій, але йому не потрібно тримати токени, які переказуються.

Створіть інструкцію переказу

Створіть інструкцію переказу токенів з відправником як авторитетом. Відправник володіє токенами і повинен підписати переказ.

Надсилання зі спонсором як платником комісії

Створіть клієнта зі спонсором як платником комісії за допомогою payer(sponsor), потім викличте client.sendTransaction. Спонсор підписує транзакцію для оплати мережевої комісії, а відправник підписує для авторизації переказу — sendTransaction автоматично збирає кожного зазначеного підписанта.

Sponsor Transaction Fee
const sponsor = await generateKeyPairSigner();

Демонстрація

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.

Коли ви створюєте токен-акаунт для кінцевого користувача, він може закрити його та повернути SOL, використаний для rent. Розгляньте можливість стягнення плати з користувачів за створення акаунта у стейблкоїнах або врахуйте цю вартість в економіці вашого продукту.

Абстракція комісій у масштабі з Kora

Примітив платника комісії є потужним, але побудова продакшн-системи без газу вимагає більшого: управління гаманцями спонсорів, обробка конвертації токенів (щоб користувачі могли "оплачувати" комісії в USDC), обмеження швидкості та контроль безпеки.

Kora керує цією складністю. Це JSON-RPC сервер, який надає абстракцію комісій, тому користувачам ніколи не потрібен SOL. Ви можете повністю спонсорувати комісії або приймати оплату комісій у будь-якому токені.

Розгорніть Kora однією командою:

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

Потім налаштуйте клієнт Kit на ваш сервер Kora і надсилайте транзакції за допомогою того самого API, що використовувався вище:

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

Ресурси Kora

Is this page helpful?

Зміст

Редагувати сторінку