Κάθε συναλλαγή στο Solana απαιτεί SOL για την πληρωμή των προμηθειών δικτύου. Αλλά οι χρήστες που έρχονται στην εφαρμογή πληρωμών σας αναμένουν να συναλλάσσονται σε stablecoins—όχι να διαχειρίζονται ένα δεύτερο υπόλοιπο token. Η αφαίρεση προμηθειών εξαλείφει αυτή την τριβή επιτρέποντας σε κάποιον άλλον να πληρώσει τις προμήθειες.
Αυτός ο οδηγός καλύπτει δύο επίπεδα:
- Πώς λειτουργεί η χορηγία προμηθειών — το υποκείμενο πρωτόκολλο του Solana
- Αφαίρεση προμηθειών σε κλίμακα με το Kora — μια υπηρεσία αφαίρεσης προμηθειών έτοιμη για παραγωγή
Πώς λειτουργεί η χορηγία προμηθειών
Οι συναλλαγές στο Solana έχουν έναν καθορισμένο πληρωτή προμηθειών—τον λογαριασμό που πληρώνει την προμήθεια δικτύου. Από προεπιλογή, αυτός είναι ο πρώτος υπογράφων. Αλλά μπορείτε να ορίσετε έναν διαφορετικό λογαριασμό ως πληρωτή προμηθειών, επιτρέποντας σε ένα τρίτο μέρος (τον "χορηγό") να καλύψει τις προμήθειες εκ μέρους του αποστολέα.
Τόσο ο αποστολέας όσο και ο χορηγός πρέπει να υπογράψουν τη συναλλαγή:
- Ο αποστολέας υπογράφει για να εξουσιοδοτήσει τη μεταφορά των tokens του
- Ο χορηγός υπογράφει για να εξουσιοδοτήσει την πληρωμή της προμήθειας δικτύου
Δείτε το Πώς λειτουργούν οι πληρωμές στο Solana για βασικές έννοιες πληρωμών.
Τα παρακάτω βήματα δείχνουν τη βασική ροή. Δείτε το Demo για πλήρη εκτελέσιμο κώδικα.
Δημιουργία λογαριασμού χορηγού
Δημιουργήστε ένα ξεχωριστό ζεύγος κλειδιών για τον χορηγό που θα πληρώνει τις προμήθειες συναλλαγών. Ο χορηγός χρειάζεται SOL για τις προμήθειες αλλά δεν χρειάζεται να κατέχει τα tokens που μεταφέρονται.
Δημιουργία εντολής μεταφοράς
Δημιουργήστε την εντολή μεταφοράς token με τον αποστολέα ως εξουσιοδοτημένο. Ο αποστολέας κατέχει τα tokens και πρέπει να υπογράψει τη μεταφορά.
Αποστολή με χορηγό ως πληρωτή χρέωσης
Δημιουργήστε τον client με τον sponsor ορισμένο ως fee payer μέσω
payer(sponsor), στη συνέχεια καλέστε client.sendTransaction. Ο sponsor
υπογράφει για να πληρώσει το network fee ενώ ο αποστολέας υπογράφει για να
εξουσιοδοτήσει τη μεταφορά—sendTransaction συλλέγει αυτόματα κάθε αναφερόμενο
signer.
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 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 = getTransferCheckedInstruction({source: senderAta,mint: mint.address,destination: recipientAta,authority: sender, // Sender signs to authorize the transferamount: 250_000n, // 0.25 tokensdecimals: 6});// Send transaction with sponsor as fee payer using @solana/kit// The sponsor (client.payer) pays fees; the sender signs for the transferconst { 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 RPCconst 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 detailsconst 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// =============================================================================
Όταν δημιουργείτε ένα token account για έναν τελικό χρήστη, μπορεί να το κλείσει και να ανακτήσει το SOL που χρησιμοποιήθηκε για rent. Σκεφτείτε να χρεώνετε τους χρήστες για τη δημιουργία λογαριασμού σε stablecoins, ή να συνυπολογίζετε αυτό το κόστος στα οικονομικά του προϊόντος σας.
Αφαίρεση χρεώσεων σε κλίμακα με το Kora
Το primitive του πληρωτή χρέωσης είναι ισχυρό, αλλά η κατασκευή ενός production συστήματος χωρίς χρεώσεις απαιτεί περισσότερα: διαχείριση πορτοφολιών χορηγών, χειρισμό μετατροπών tokens (ώστε οι χρήστες να μπορούν να "πληρώνουν" χρεώσεις σε USDC), περιορισμό ρυθμού και ελέγχους ασφαλείας.
Η Kora διαχειρίζεται αυτήν την πολυπλοκότητα. Είναι ένας διακομιστής JSON-RPC που παρέχει αφαίρεση τελών ώστε οι χρήστες να μην χρειάζονται ποτέ SOL. Μπορείτε να χρηματοδοτήσετε πλήρως τα τέλη ή να δέχεστε πληρωμή τελών σε οποιοδήποτε token.
Αναπτύξτε το Kora με μία μόνο εντολή:
cargo install kora-clikora --config path/to/kora.toml rpc start --signers-config path/to/signers.toml
Στη συνέχεια, συνδέστε έναν Kit client στον Kora server σας και στείλτε συναλλαγές με το ίδιο 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 SOLconst kora = await createKitKoraClient({endpoint: "https://your-kora-instance",rpcUrl: "https://api.mainnet-beta.solana.com",feeToken: address("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"), // USDCfeePayerWallet: sender // Signs to authorize the token fee payment});// Same instruction, same call—Kora sponsors the network feeconst { context } = await kora.sendTransaction([transferInstruction]);console.log("Signature:", context.signature);
Πόροι Kora
Is this page helpful?