Ostatnia aktualizacja: 2025-10-31
Co zbudujesz
W Przewodniku Szybkiego Startu nauczyłeś się, jak skonfigurować Kora RPC i wykonywać podstawowe wywołania. Teraz zbudujemy kompletny system transakcji bez opłat za gaz, który demonstruje pełne możliwości Kora. Pod koniec tego przewodnika wdrożysz przepływ transakcji, który:
-
Tworzy wiele instrukcji transferu (tokeny SPL i SOL)
-
Uzyskuje instrukcje płatności od Kora w celu pokrycia opłat
-
Podpisuje transakcje kluczami użytkownika, podczas gdy Kora obsługuje opłaty za gaz
-
Przesyła w pełni podpisane transakcje do sieci Solana
-
Tworzy wiele instrukcji transferu (tokeny SPL i SOL)
-
Uzyskuje instrukcje płatności od Kora w celu pokrycia opłat
-
Podpisuje transakcje kluczami użytkownika, podczas gdy Kora obsługuje opłaty za gaz
-
Przesyła w pełni podpisane transakcje do sieci Solana
Końcowy rezultat będzie działającym systemem transakcji bez opłat za gaz:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━KORA GASLESS TRANSACTION DEMO━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[1/6] Initializing clients→ Kora RPC: http://localhost:8080/→ Solana RPC: http://127.0.0.1:8899[2/6] Setting up keypairs→ Sender: BYJVBqQ2xV9GECc84FeoPQy2DpgoonZQFQu97MMWTbBc→ Destination: C8MC9E6nf9Am1rVqdDedDavm53uCJMiSwarEko1aXmny→ Kora signer address: 3Z1Ef7YaxK8oUMoi6exf7wYZjZKWJJsrzJXSt1c3qrDE[3/6] Creating demonstration instructions→ Payment token: 9BgeTKqmFsPVnfYscfM6NvsgmZxei7XfdciShQ6D3bxJ✓ Token transfer instruction created✓ SOL transfer instruction created✓ Memo instruction created→ Total: 3 instructions[4/6] Estimating Kora fee and assembling payment instruction→ Fee payer: 3Z1Ef7Ya...→ Blockhash: 7HZUaMqV...✓ Estimate transaction built✓ Payment instruction received from Kora[5/6] Creating and signing final transaction (with payment)✓ Final transaction built with payment✓ Transaction signed by user[6/6] Signing transaction with Kora and sending to Solana cluster✓ Transaction co-signed by Kora✓ Transaction submitted to network⏳ Awaiting confirmation...━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━SUCCESS: Transaction confirmed on Solana━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━Transaction signature:41hmwmkMfHR5mmhG9sNkjiakwHxpmr1H3Gi3bBL8v5PbsRrH7FhpUT8acHaf2mrPKNVD894dSYXfjp6LfAbVpcCEView on explorer:https://explorer.solana.com/tx/41hmwmkMfHR5mmhG9sNkjiakwHxpmr1H3Gi3bBL8v5PbsRrH7FhpUT8acHaf2mrPKNVD894dSYXfjp6LfAbVpcCE?cluster=custom&customUrl=http%3A%2F%2Flocalhost%3A8899
Zbudujmy to krok po kroku!
Wymagania wstępne
Przed rozpoczęciem tego samouczka upewnij się, że posiadasz:
- Ukończony Przewodnik Szybkiego Startu Kora - użyjemy tego samego środowiska testowego co w przewodniku szybkiego startu.
- Node.js (LTS lub nowszy)
- Solana CLI w wersji 2.2.x lub wyższej
- Znajomość transakcji Solana oraz tokenów SPL
- Działający serwer Kora RPC ze skonfigurowanymi signerami (instrukcje znajdziesz w Przewodniku Szybkiego Startu)
Przepływ transakcji Kora
Kora umożliwia transakcje bez opłat za gaz, działając jako płatnik opłat dla transakcji użytkowników. Przepływ transakcji bez opłat za gaz składa się z następujących głównych kroków:
- Tworzenie transakcji - Zbuduj zamierzoną transakcję użytkownika (transfery, wywołania programów itp.)
- Oszacowanie opłat - Utwórz transakcję szacunkową w celu obliczenia wymaganych opłat
- Instrukcja płatności - Uzyskaj od Kora instrukcję płatności określającą wysokość opłaty
- Podpisywanie przez użytkownika - Użytkownik podpisuje transakcję włącznie z instrukcją płatności
- Współpodpisywanie przez Kora - Kora waliduje płatność i współpodpisuje jako płatnik opłat
- Przesłanie - Prześlij w pełni podpisaną transakcję do Solana
*Uwaga: Kora można skonfigurować tak, aby nie wymagała płatności, ale użyjemy jej do zademonstrowania pełnego przepływu.
Konfiguracja projektu
Kwestie dotyczące serwera Kora
- Lista dozwolonych tokenów - Tylko tokeny skonfigurowane w
kora.tomlmogą być używane do płatności - upewnij się, że token zdefiniowany w Twoim.envjest uwzględniony w kora.toml na liście dozwolonych. - Ograniczenia programów - Transakcje mogą wchodzić w interakcję tylko z programami z białej listy. Wstępnie skonfigurowaliśmy kora.toml aby umożliwić interakcję z System Program, Token Program, Compute Unit Program i programem Memo.
Konfiguracja klienta
Ten przewodnik zakłada, że ukończyłeś Szybki start i masz skonfigurowany projekt demonstracyjny. Jeśli nie, najpierw to zrób.
Przejdź do katalogu klienta demonstracyjnego:
cd kora/examples/getting-started/demo/client
Uwaga: Pliki demonstracyjne znajdują się w repozytorium GitHub ponieważ wymagają pełnego środowiska deweloperskiego.
Implementacja
Zanim zaczniemy uruchamiać demo, przejdźmy przez pełne demo implementację krok po kroku:
Importy i konfiguracja
Nasze demo rozpoczyna się od niezbędnych importów i konfiguracji:
import { KoraClient } from "@solana/kora";import {createKeyPairSignerFromBytes,getBase58Encoder,createNoopSigner,address,getBase64EncodedWireTransaction,partiallySignTransactionMessageWithSigners,Blockhash,Base64EncodedWireTransaction,partiallySignTransaction,TransactionVersion,Instruction,KeyPairSigner,Rpc,SolanaRpcApi,createSolanaRpc,createSolanaRpcSubscriptions,pipe,createTransactionMessage,setTransactionMessageFeePayerSigner,setTransactionMessageLifetimeUsingBlockhash,MicroLamports,appendTransactionMessageInstructions} from "@solana/kit";import { getAddMemoInstruction } from "@solana-program/memo";import { createRecentSignatureConfirmationPromiseFactory } from "@solana/transaction-confirmation";import {updateOrAppendSetComputeUnitLimitInstruction,updateOrAppendSetComputeUnitPriceInstruction} from "@solana-program/compute-budget";import dotenv from "dotenv";import path from "path";dotenv.config({ path: path.join(process.cwd(), "..", ".env") });const CONFIG = {computeUnitLimit: 200_000,computeUnitPrice: 1_000_000n as MicroLamports,solanaRpcUrl: "http://127.0.0.1:8899",solanaWsUrl: "ws://127.0.0.1:8900",koraRpcUrl: "http://localhost:8080/"};
Importujemy klienta Kora z Kora SDK oraz kilka typów/pomocników z biblioteki Solana Kit do budowania transakcji.
Tworzymy również globalny obiekt konfiguracyjny, który definiuje:
- Budżet obliczeniowy - Jednostki i cena dla priorytetyzacji transakcji
- Wersja transakcji - Używamy V0 dla obsługi tabel wyszukiwania adresów
- Punkty końcowe RPC - Lokalne serwery Solana i Kora RPC
Zostaw te domyślne ustawienia na razie - po demonstracji możesz eksperymentować z różnymi wartościami, aby zobaczyć, jak wpływają na przepływ transakcji.
Funkcje Narzędziowe
Demo zawiera funkcję pomocniczą do wczytywania par kluczy ze zmiennych środowiskowych:
async function getEnvKeyPair(envKey: string) {if (!process.env[envKey]) {throw new Error(`Environment variable ${envKey} is not set`);}const base58Encoder = getBase58Encoder();const b58SecretEncoded = base58Encoder.encode(process.env[envKey]);return await createKeyPairSignerFromBytes(b58SecretEncoded);}
Ta funkcja:
- Odczytuje klucze prywatne zakodowane w base58 ze zmiennych środowiskowych
- Koduje ciąg klucza prywatnego do tablicy bajtów U8
- Konwertuje je na obiekty podpisujące keypair
Krok 1: Inicjalizacja Klientów
Najpierw konfigurujemy połączenie zarówno z Kora, jak i Solana:
async function initializeClients() {console.log("\n[1/6] Initializing clients");console.log(" → Kora RPC:", CONFIG.koraRpcUrl);console.log(" → Solana RPC:", CONFIG.solanaRpcUrl);const client = new KoraClient({rpcUrl: CONFIG.koraRpcUrl// apiKey: process.env.KORA_API_KEY, // Uncomment if authentication is enabled// hmacSecret: process.env.KORA_HMAC_SECRET, // Uncomment if HMAC is enabled});const rpc = createSolanaRpc(CONFIG.solanaRpcUrl);const rpcSubscriptions = createSolanaRpcSubscriptions(CONFIG.solanaWsUrl);const confirmTransaction = createRecentSignatureConfirmationPromiseFactory({rpc,rpcSubscriptions});return { client, rpc, confirmTransaction };}
Ta funkcja:
- Tworzy instancję klienta Kora poprzez przekazanie naszego adresu URL Kora RPC.
- Nawiązuje połączenie Solana RPC z obsługą subskrypcji (użyjemy tego do wysyłania i potwierdzania transakcji do klastra Solana)
- Konfiguruje narzędzia do potwierdzania transakcji
Uwaga: Nasz plik kora.toml nie zawiera żadnego uwierzytelniania, więc nie musimy przekazywać klucza API ani sekretu HMAC, ale pozostawiliśmy zakomentowany kod dla odniesienia.
Krok 2: Konfiguracja Kluczy
Wczytaj wymagane pary kluczy ze zmiennych środowiskowych i pobierz adres podpisującego Kora:
async function setupKeys(client: KoraClient) {console.log("\n[2/6] Setting up keypairs");const testSenderKeypair = await getEnvKeyPair("TEST_SENDER_KEYPAIR");const destinationKeypair = await getEnvKeyPair("DESTINATION_KEYPAIR");const { signer_address } = await client.getPayerSigner();console.log(" → Sender:", testSenderKeypair.address);console.log(" → Destination:", destinationKeypair.address);console.log(" → Kora signer address:", signer_address);return { testSenderKeypair, destinationKeypair, signer_address };}
Tutaj używamy naszej funkcji getEnvKeyPair do wczytywania par kluczy ze
zmiennych środowiskowych. Pary kluczy reprezentują:
- Nadawca - Użytkownik inicjujący transakcję i odpowiedzialny za opłacenie węzła Kora w tokenie płatności.
- Odbiorca - Odbiorca przelewów.
Używamy również metody getPayerSigner do pobrania adresu podpisującego Kora.
To jest adres, który zostanie użyty do podpisania transakcji podpisem Kora.
Ważne jest, abyśmy pobrali prawidłowego podpisującego z węzła Kora i używali go
konsekwentnie w całym przepływie transakcji.
Krok 3: Tworzenie Instrukcji Demo
Następnie budujemy zestaw instrukcji, które nasz testSender chce wysłać do
sieci. Użyjemy Klienta Kora do zbudowania niektórych z tych instrukcji oraz
biblioteki @solana/programs do zbudowania innych, aby pokazać, jak używać obu
rozwiązań.
async function createInstructions(client: KoraClient,testSenderKeypair: KeyPairSigner,destinationKeypair: KeyPairSigner) {console.log("\n[3/6] Creating demonstration instructions");const paymentToken = await client.getConfig().then((config) => config.validation_config.allowed_spl_paid_tokens[0]);console.log(" → Payment token:", paymentToken);// Create token transfer (will initialize ATA if needed)const transferTokens = await client.transferTransaction({amount: 10_000_000, // 10 USDC (6 decimals)token: paymentToken,source: testSenderKeypair.address,destination: destinationKeypair.address});console.log(" ✓ Token transfer instruction created");// Create SOL transferconst transferSol = await client.transferTransaction({amount: 10_000_000, // 0.01 SOL (9 decimals)token: "11111111111111111111111111111111", // SOL mint addresssource: testSenderKeypair.address,destination: destinationKeypair.address});console.log(" ✓ SOL transfer instruction created");// Add memo instructionconst memoInstruction = getAddMemoInstruction({memo: "Hello, Kora!"});console.log(" ✓ Memo instruction created");const instructions = [...transferTokens.instructions,...transferSol.instructions,memoInstruction];console.log(` → Total: ${instructions.length} instructions`);return { instructions, paymentToken };}
Dzieje się tu całkiem sporo, więc przejdźmy przez to krok po kroku:
- Używamy
getConfig, aby uzyskać token płatności z konfiguracji Kora. Ponieważ skonfigurowaliśmy nasz serwer, wiemy, że na liście dozwolonych jest tylko jeden token, więc możemy uzyskać do niego bezpośredni dostęp na pierwszej pozycji (config.validation_config.allowed_spl_paid_tokens[0]). - Tworzymy instrukcję transferu tokenów za pomocą metody
transferTransactionKlienta Kora. Jest to metoda pomocnicza, która ułatwia tworzenie instrukcji transferu tokenów. - Tworzymy instrukcję transferu SOL za pomocą metody
transferTransactionKlienta Kora. Uwzględniamy ją tutaj, aby pokazać, jak budować transfery SOL przy użyciu Klienta Kora – zauważ, że używamy natywnego mintu SOL11111111111111111111111111111111, aby wskazać, że chcemy przetransferować SOL zamiast wykonywać transfer tokena SPL. - Dodajemy instrukcję memo, używając funkcji
getAddMemoInstructionz biblioteki @solana/programs. - Łączymy wszystkie instrukcje w jedną tablicę. Użyjemy tej tablicy do zbudowania naszej transakcji szacunkowej w następnym kroku.
Krok 4: Uzyskaj instrukcję płatności z Kora
Utwórz transakcję, która wygeneruje instrukcję płatności do Kora w zamian za opłaty wymagane do wykonania transakcji.
async function getPaymentInstruction(client: KoraClient,instructions: Instruction[],testSenderKeypair: KeyPairSigner,paymentToken: string): Promise<{ paymentInstruction: Instruction }> {console.log("\n[4/6] Estimating Kora fee and assembling payment instruction");const { signer_address } = await client.getPayerSigner();const noopSigner = createNoopSigner(address(signer_address));const latestBlockhash = await client.getBlockhash();console.log(" → Fee payer:", signer_address.slice(0, 8) + "...");console.log(" → Blockhash:", latestBlockhash.blockhash.slice(0, 8) + "...");// Create estimate transaction to get payment instructionconst estimateTransaction = pipe(createTransactionMessage({ version: 0 }),(tx) => setTransactionMessageFeePayerSigner(noopSigner, tx),(tx) =>setTransactionMessageLifetimeUsingBlockhash({blockhash: latestBlockhash.blockhash as Blockhash,lastValidBlockHeight: 0n},tx),(tx) => appendTransactionMessageInstructions(instructions, tx),(tx) =>updateOrAppendSetComputeUnitPriceInstruction(CONFIG.computeUnitPrice, tx),(tx) =>updateOrAppendSetComputeUnitLimitInstruction(CONFIG.computeUnitLimit, tx));const signedEstimateTransaction =await partiallySignTransactionMessageWithSigners(estimateTransaction);const base64EncodedWireTransaction = getBase64EncodedWireTransaction(signedEstimateTransaction);console.log(" ✓ Estimate transaction built");// Get payment instruction from Koraconst paymentInstruction = await client.getPaymentInstruction({transaction: base64EncodedWireTransaction,fee_token: paymentToken,source_wallet: testSenderKeypair.address});console.log(" ✓ Payment instruction received from Kora");return { paymentInstruction: paymentInstruction.payment_instruction };}
SDK Kora posiada metodę pomocniczą getPaymentInstruction, która obliczy
dokładne opłaty wymagane dla transakcji i utworzy instrukcję transferu
płatności. Oto jak z niej korzystamy:
- Najpierw tworzymy
estimateTransaction, która zawiera nasze żądane instrukcje — ta transakcja zostanie zasymulowana na serwerze Kora w celu oszacowania opłat wymaganych dla transakcji. - Następnie częściowo podpisujemy transakcję, aby uzyskać ciąg w formacie base64.
- Przekazujemy naszą zakodowaną w base64 transakcję do metody
getPaymentInstructionwraz z tokenem płatności i źródłem płatności. Zwróci to obiektInstruction, który możemy dodać do naszej transakcji.
Kluczowe koncepcje:
- Ważny Blockhash - Używamy metody
getBlockhash, aby uzyskać ważny blockhash dla naszej transakcji. Jest to wymagane do oszacowania transakcji, ponieważ zasymuluje ona transakcję na serwerze. - Noop Signer - Zastępczy podpisujący używany podczas budowania transakcji przed podpisaniem przez Kora. Pozwala to określić płatnika opłat w naszej transakcji zanim otrzymamy podpis Kora. Więcej informacji o Noop Signers znajdziesz w Dokumentacji Solana Kit.
- Częściowe Podpisywanie - Aby uzyskać naszą transakcję jako ciąg zakodowany w base64 (potrzebujemy tego do wysłania transakcji przez Kora RPC), musimy częściowo podpisać transakcję. Więcej informacji o Partial Signers znajdziesz w Dokumentacji Solana Kit.
Krok 5: Utwórz i Podpisz Końcową Transakcję
Teraz, gdy mamy naszą instrukcję płatności, możemy utworzyć końcową transakcję, która zawiera nasze oryginalne instrukcje oraz instrukcję płatności.
async function getFinalTransaction(client: KoraClient,paymentInstruction: Instruction,testSenderKeypair: KeyPairSigner,instructions: Instruction[],signer_address: string): Promise<Base64EncodedWireTransaction> {console.log("\n[5/6] Creating and signing final transaction (with payment)");const noopSigner = createNoopSigner(address(signer_address));// Build final transaction with payment instructionconst newBlockhash = await client.getBlockhash();const fullTransaction = pipe(createTransactionMessage({ version: 0 }),(tx) => setTransactionMessageFeePayerSigner(noopSigner, tx),(tx) =>setTransactionMessageLifetimeUsingBlockhash({blockhash: newBlockhash.blockhash as Blockhash,lastValidBlockHeight: 0n},tx),(tx) =>appendTransactionMessageInstructions([...instructions, paymentInstruction],tx),(tx) =>updateOrAppendSetComputeUnitPriceInstruction(CONFIG.computeUnitPrice, tx),(tx) =>updateOrAppendSetComputeUnitLimitInstruction(CONFIG.computeUnitLimit, tx));console.log(" ✓ Final transaction built with payment");// Sign with user keypairconst signedFullTransaction =await partiallySignTransactionMessageWithSigners(fullTransaction);const userSignedTransaction = await partiallySignTransaction([testSenderKeypair.keyPair],signedFullTransaction);const base64EncodedWireFullTransaction = getBase64EncodedWireTransaction(userSignedTransaction);console.log(" ✓ Transaction signed by user");return base64EncodedWireFullTransaction;}
Używamy tej samej funkcji pipe do złożenia naszej transakcji. Nasza końcowa
transakcja zawiera:
- Nasze oryginalne instrukcje
- Instrukcję płatności
- Świeży blockhash
- Tego samego podpisującego noop, który był wcześniej użyty do zbudowania transakcji szacunkowej
Następnie wywołujemy tę samą funkcję
partiallySignTransactionMessageWithSigners, aby uzyskać zakodowany w base64
ciąg wire transakcji. Tym razem jednak uruchamiamy również
partiallySignTransaction, aby podpisać transakcję naszym testSenderKeypair.
Chociaż nasz węzeł Kora płaci opłaty sieciowe, nasz testSender nadal musi
podpisać, aby autoryzować płatność tokenem oraz inne instrukcje transferu, które
utworzyliśmy. W przypadku węzłów Kora, które nie wymagają płatności, pewne
instrukcje mogą nie wymagać tego kroku podpisywania. Na koniec zwracamy
zakodowany w base64 ciąg wire transakcji.
Krok 6: Przesłanie transakcji
Na koniec musimy sprawić, aby węzeł Kora podpisał transakcję, dzięki czemu
będziemy mogli wysłać w pełni podpisaną transakcję do sieci. Robimy to,
wywołując metodę signTransaction na kliencie Kora.
async function submitTransaction(client: KoraClient,rpc: Rpc<SolanaRpcApi>,confirmTransaction: ReturnType<typeof createRecentSignatureConfirmationPromiseFactory>,signedTransaction: Base64EncodedWireTransaction,signer_address: string) {console.log("\n[6/6] Signing transaction with Kora and sending to Solana cluster");// Get Kora's signatureconst { signed_transaction } = await client.signTransaction({transaction: signedTransaction,signer_key: signer_address});console.log(" ✓ Transaction co-signed by Kora");// Submit to Solana networkconst signature = await rpc.sendTransaction(signed_transaction as Base64EncodedWireTransaction, {encoding: "base64"}).send();console.log(" ✓ Transaction submitted to network");console.log(" ⏳ Awaiting confirmation...");await confirmTransaction({commitment: "confirmed",signature,abortSignal: new AbortController().signal});console.log("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");console.log("SUCCESS: Transaction confirmed on Solana");console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");console.log("\nTransaction signature:");console.log(signature);return signature;}
Tutaj wykonujemy trzy czynności:
- Wywołujemy metodę
signTransactionna kliencie Kora, aby węzeł Kora podpisał transakcję. Węzeł sprawdzi transakcję, aby upewnić się, że płatność jest wystarczająca, a następnie podpisze transakcję. Uwaga: niektóre węzły Kora mogą mieć włączoną opcjęsignTransaction, która nie wymaga płatności. Możesz sprawdzić konfigurację swojego węzła, aby zobaczyć, czy jest to włączone, uruchamiającgetConfig(). - Wysyłamy w pełni podpisaną transakcję do sieci Solana za pomocą klienta RPC Solana.
- Czekamy na potwierdzenie transakcji w sieci.
Główna funkcja orkiestrująca
Funkcja główna łączy wszystko razem i wywołuje każdą z naszych funkcji w sekwencji:
async function main() {console.log("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");console.log("KORA GASLESS TRANSACTION DEMO");console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");try {// Step 1: Initialize clientsconst { client, rpc, confirmTransaction } = await initializeClients();// Step 2: Setup keysconst { testSenderKeypair, destinationKeypair, signer_address } =await setupKeys(client);// Step 3: Create demo instructionsconst { instructions, paymentToken } = await createInstructions(client,testSenderKeypair,destinationKeypair);// Step 4: Get payment instruction from Koraconst { paymentInstruction } = await getPaymentInstruction(client,instructions,testSenderKeypair,paymentToken);// Step 5: Create and partially sign final transactionconst finalSignedTransaction = await getFinalTransaction(client,paymentInstruction,testSenderKeypair,instructions,signer_address);// Step 6: Get Kora's signature and submit to Solana clusterawait submitTransaction(client,rpc,confirmTransaction,finalSignedTransaction,signer_address);} catch (error) {console.error("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");console.error("ERROR: Demo failed");console.error("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");console.error("\nDetails:", error);process.exit(1);}}
Uruchomienie pełnego demo
Aby uruchomić kompletne demo transakcji bez opłat za gaz:
1. Upewnij się, że spełniasz wymagania wstępne
Skonfiguruj trzy okna terminala:
- Uruchom lokalny walidator testowy:
solana-test-validator -r
- Uruchom serwer RPC Kora (z katalogu examples/getting-started/demo/server):
kora rpc start --signers-config signers.toml
- Zainicjuj swoje środowisko (z katalogu examples/getting-started/demo/client):
pnpm init-env
2. Uruchom demonstrację
# From the client directorypnpm full-demo
3. Oczekiwany wynik
Powinieneś zobaczyć krok po kroku wykonanie z pomyślną transakcją na końcu. Transakcja będzie:
- Przesyłać tokeny od nadawcy do odbiorcy
- Przesyłać SOL od nadawcy do odbiorcy
- Zawierać wiadomość memo "Hello, Kora!"
- Płacić opłaty operatorowi węzła Kora w skonfigurowanym tokenie SPL
- Mieć opłaty za gaz transakcji opłacane przez operatora węzła Kora
Podsumowanie: Zrozumienie przepływu
Przejrzyjmy, co dzieje się w tej demonstracji:
- Intencja użytkownika - Użytkownik złożył transakcję, która zawierała różnorodne instrukcje, które chciał wykonać.
- Szacowanie opłat - Kora obliczyła koszt transakcji w preferowanym tokenie użytkownika i utworzyła instrukcję płatności.
- Składanie transakcji - Użytkownik złożył finalną transakcję, która zawierała zamierzone przez użytkownika instrukcje oraz instrukcję płatności Kora.
- Podpisywanie transakcji - Użytkownik częściowo podpisał transakcję swoją parą kluczy i wysłał do węzła Kora w celu podpisania po zweryfikowaniu, że płatność była wystarczająca.
- Atomowe wykonanie - Użytkownik wysyła transakcję do Solana i wszystko
dzieje się w jednej transakcji:
- Zamierzone przez użytkownika przelewy są wykonywane
- Płatność za opłaty jest przekazywana do Kora
- Kora płaci opłaty sieciowe Solana i podpisuje transakcję
I w ten sposób użytkownicy nie muszą posiadać SOL, aby płacić za opłaty za gaz — mogą płacić za wszystko tokenami, które już posiadają!
Rozwiązywanie problemów
Typowe problemy
Walidacja transakcji kończy się niepowodzeniem
- Sprawdź, czy wszystkie programy znajdują się na białej liście w
kora.toml - Upewnij się, że minty tokenów są w
allowed_spl_paid_tokens - Sprawdź, czy transakcja nie przekracza
max_allowed_lamports
Generowanie instrukcji płatności kończy się niepowodzeniem
- Upewnij się, że transakcja szacunkowa ma świeży blockhash do symulacji
- Zweryfikuj, czy adres płatności Kora ma zainicjalizowane ATA
- Sprawdź, czy token płatności jest poprawnie skonfigurowany
Weryfikacja podpisu kończy się niepowodzeniem
- Upewnij się, że uwzględniono wszystkich wymaganych sygnatariuszy (Kora oraz wszelkich sygnatariuszy wymaganych do płatności tokenami lub innych instrukcji zawartych w transakcji)
- Sprawdź, czy transakcja nie została zmodyfikowana po podpisaniu
- Upewnij się, że keypair są poprawnie wczytane
Podsumowanie
Gratulacje! Pomyślnie zaimplementowałeś kompletny przepływ transakcji bezgazowych z Kora.
Kora umożliwia zapewnienie użytkownikom płynnego doświadczenia Web3, w którym nie muszą martwić się o opłaty za gaz ani przechowywanie SOL. Niezależnie od tego, czy budujesz NeoBank, platformę gamingową czy platformę liquid staking, transakcje bezgazowe Kora usuwają główną barierę w adopcji użytkowników.
Wskazówka: Aby uprościć integrację, sprawdź Przewodnik Kit Client. API
createKitKoraClient()automatycznie obsługuje zarządzanie blockhash, szacowanie opłat, wstrzykiwanie instrukcji płatności i wysyłanie transakcji — redukując manualne kroki przedstawione w tym przewodniku do kilku linijek kodu.
Dodatkowe zasoby
Is this page helpful?