Pełny przepływ transakcji Kora

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:
41hmwmkMfHR5mmhG9sNkjiakwHxpmr1H3Gi3bBL8v5PbsRrH7FhpUT8acHaf2mrPKNVD894dSYXfjp6LfAbVpcCE
View 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:

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:

  1. Tworzenie transakcji - Zbuduj zamierzoną transakcję użytkownika (transfery, wywołania programów itp.)
  2. Oszacowanie opłat - Utwórz transakcję szacunkową w celu obliczenia wymaganych opłat
  3. Instrukcja płatności - Uzyskaj od Kora instrukcję płatności określającą wysokość opłaty
  4. Podpisywanie przez użytkownika - Użytkownik podpisuje transakcję włącznie z instrukcją płatności
  5. Współpodpisywanie przez Kora - Kora waliduje płatność i współpodpisuje jako płatnik opłat
  6. 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.toml mogą być używane do płatności - upewnij się, że token zdefiniowany w Twoim .env jest 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 transfer
const transferSol = await client.transferTransaction({
amount: 10_000_000, // 0.01 SOL (9 decimals)
token: "11111111111111111111111111111111", // SOL mint address
source: testSenderKeypair.address,
destination: destinationKeypair.address
});
console.log(" ✓ SOL transfer instruction created");
// Add memo instruction
const 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:

  1. 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]).
  2. Tworzymy instrukcję transferu tokenów za pomocą metody transferTransaction Klienta Kora. Jest to metoda pomocnicza, która ułatwia tworzenie instrukcji transferu tokenów.
  3. Tworzymy instrukcję transferu SOL za pomocą metody transferTransaction Klienta Kora. Uwzględniamy ją tutaj, aby pokazać, jak budować transfery SOL przy użyciu Klienta Kora – zauważ, że używamy natywnego mintu SOL 11111111111111111111111111111111, aby wskazać, że chcemy przetransferować SOL zamiast wykonywać transfer tokena SPL.
  4. Dodajemy instrukcję memo, używając funkcji getAddMemoInstruction z biblioteki @solana/programs.
  5. Łą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 instruction
const 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 Kora
const 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:

  1. Najpierw tworzymy estimateTransaction, która zawiera nasze żądane instrukcje — ta transakcja zostanie zasymulowana na serwerze Kora w celu oszacowania opłat wymaganych dla transakcji.
  2. Następnie częściowo podpisujemy transakcję, aby uzyskać ciąg w formacie base64.
  3. Przekazujemy naszą zakodowaną w base64 transakcję do metody getPaymentInstruction wraz z tokenem płatności i źródłem płatności. Zwróci to obiekt Instruction, 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 instruction
const 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 keypair
const 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 signature
const { signed_transaction } = await client.signTransaction({
transaction: signedTransaction,
signer_key: signer_address
});
console.log(" ✓ Transaction co-signed by Kora");
// Submit to Solana network
const 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:

  1. Wywołujemy metodę signTransaction na 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ąc getConfig().
  2. Wysyłamy w pełni podpisaną transakcję do sieci Solana za pomocą klienta RPC Solana.
  3. 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 clients
const { client, rpc, confirmTransaction } = await initializeClients();
// Step 2: Setup keys
const { testSenderKeypair, destinationKeypair, signer_address } =
await setupKeys(client);
// Step 3: Create demo instructions
const { instructions, paymentToken } = await createInstructions(
client,
testSenderKeypair,
destinationKeypair
);
// Step 4: Get payment instruction from Kora
const { paymentInstruction } = await getPaymentInstruction(
client,
instructions,
testSenderKeypair,
paymentToken
);
// Step 5: Create and partially sign final transaction
const finalSignedTransaction = await getFinalTransaction(
client,
paymentInstruction,
testSenderKeypair,
instructions,
signer_address
);
// Step 6: Get Kora's signature and submit to Solana cluster
await 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:

  1. Uruchom lokalny walidator testowy:
solana-test-validator -r
  1. Uruchom serwer RPC Kora (z katalogu examples/getting-started/demo/server):
kora rpc start --signers-config signers.toml
  1. Zainicjuj swoje środowisko (z katalogu examples/getting-started/demo/client):
pnpm init-env

2. Uruchom demonstrację

# From the client directory
pnpm 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:

  1. Intencja użytkownika - Użytkownik złożył transakcję, która zawierała różnorodne instrukcje, które chciał wykonać.
  2. Szacowanie opłat - Kora obliczyła koszt transakcji w preferowanym tokenie użytkownika i utworzyła instrukcję płatności.
  3. 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.
  4. 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.
  5. 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?

Zarządzane przez

© 2026 Solana Foundation.
Wszelkie prawa zastrzeżone.
Bądź na bieżąco