### Verify Kora TypeScript SDK Installation Source: https://launch.solana.com/docs/kora/getting-started/installation A TypeScript example demonstrating how to connect to a Kora server using the `KoraClient` and fetch its configuration. This verifies the SDK's connectivity and basic functionality. ```typescript import { KoraClient } from '@solana/kora'; async function testConnection() { const client = new KoraClient('http://localhost:8080'); // Replace with your Kora server URL try { const config = await client.getConfig(); console.log('✅ Successfully connected to Kora server'); } catch (error) { console.error('❌ Connection failed:', error.message); } } testConnection(); ``` -------------------------------- ### Install Kora CLI using Docker Source: https://launch.solana.com/docs/kora/getting-started/installation Pulls the official Kora Docker image and runs it, mounting configuration files and exposing the RPC port. This is ideal for containerized deployments and simplifies environment setup. ```bash docker pull ghcr.io/solana-foundation/kora:latest docker run -v $(pwd)/kora.toml:/app/kora.toml \ -v $(pwd)/signers.toml:/app/signers.toml \ -p 8080:8080 \ ghcr.io/solana-foundation/kora:latest \ rpc start --signers-config /app/signers.toml ``` -------------------------------- ### Install Node.js Type Definitions for TypeScript Source: https://launch.solana.com/docs/kora/getting-started/installation Installs the type definitions for Node.js using pnpm, which can help resolve TypeScript errors related to Node.js APIs when using the Kora SDK. ```bash pnpm add -D @types/node ``` -------------------------------- ### Install Kora TypeScript SDK Peer Dependencies Source: https://launch.solana.com/docs/kora/getting-started/installation Installs the necessary Solana peer dependencies required by the Kora TypeScript SDK. These include `@solana/kit` and `@solana-program/token`. ```bash pnpm add @solana/kit @solana-program/token ``` -------------------------------- ### Initializing Client Environment (Shell) Source: https://launch.solana.com/docs/kora/guides/full-demo This command initializes the client-side environment for the Kora gasless transaction demo. It likely installs dependencies, sets up configuration files, or performs other setup tasks required for the client application to interact with the Kora RPC server and the Solana cluster. ```shell pnpm init-env ``` -------------------------------- ### Verify Kora CLI Installation Source: https://launch.solana.com/docs/kora/getting-started/installation Checks if the Kora CLI has been installed correctly by running the version command. This helps confirm that the binary is accessible in the system's PATH. ```bash kora --version ``` -------------------------------- ### Install Kora TypeScript SDK Source: https://launch.solana.com/docs/kora/getting-started/installation Installs the Kora TypeScript SDK using the pnpm package manager. This SDK is used for building client applications that interact with a Kora node. ```bash pnpm add @solana/kora ``` -------------------------------- ### HMAC Client-Side Implementation Source: https://launch.solana.com/docs/kora/operators/authentication Steps and examples for implementing HMAC authentication on the client-side using the Kora SDK or JavaScript's crypto library. ```APIDOC ## HMAC Client-Side Implementation To use HMAC client-side, you can use the Kora SDK or the `crypto` library in JavaScript: 1. **Create a timestamp**: Get the current Unix timestamp. 2. **Create the request body**: Prepare the JSON payload for your request. 3. **Create a message**: Concatenate the timestamp and the request body (e.g., `message = timestamp + body`). 4. **Create a signature**: Sign the message using your HMAC secret with SHA256 (e.g., using `crypto.createHmac('sha256', secret).update(message).digest('hex')`). 5. **Send the request**: Include the `x-timestamp` and `x-hmac-signature` headers in your HTTP request. ### JavaScript Example using Kora SDK The Kora SDK simplifies HMAC authentication. ```javascript const { KoraClient } = require('@solana/kora'); const kora = new KoraClient({ rpcUrl: 'http://localhost:8080', hmacSecret: process.env.KORA_HMAC_SECRET }); const config = await kora.getConfig(); console.log(config); ``` ### JavaScript Example using `crypto` library This example demonstrates manual HMAC signature generation. ```javascript async function callKoraHMAC(method, params = []) { const timestamp = Math.floor(Date.now() / 1000).toString(); const body = JSON.stringify({ jsonrpc: '2.0', method, params, id: 1 }); // Create HMAC signature const message = timestamp + body; const signature = crypto .createHmac('sha256', process.env.KORA_HMAC_SECRET) // kora_hmac_your-strong-hmac-secret-key .update(message) .digest('hex'); const response = await fetch('http://localhost:8080', { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-timestamp': timestamp, 'x-hmac-signature': signature }, body: body }); return response.json(); } const config = await callKoraHMAC('getConfig'); console.log(config); ``` ``` -------------------------------- ### Prometheus Queries for Multi-Signer Setups Source: https://launch.solana.com/docs/kora/operators/monitoring Examples of Prometheus queries to monitor signer balances, detect low balances, and track balance distribution. ```APIDOC ## Prometheus Queries ### Description Provides examples of Prometheus queries for analyzing signer balances and system health. ### Method N/A (These are Prometheus query examples, not direct API calls) ### Endpoint N/A ### Parameters N/A ### Request Example ```promql # Alert if any signer has low balance (< 0.05 SOL) min(signer_balance_lamports) < 50000000 # Monitor balance distribution across signers signer_balance_lamports / on() group_left() sum(signer_balance_lamports) # Track signer with lowest balance min_over_time(signer_balance_lamports[1h]) # Count number of healthy signers (> 0.01 SOL) count(signer_balance_lamports > 10000000) # Average balance across all signers avg(signer_balance_lamports) / 1000000000 ``` ### Response N/A ``` -------------------------------- ### JavaScript HMAC Authentication using Kora SDK Source: https://launch.solana.com/docs/kora/operators/authentication This example demonstrates how to use the Kora SDK for client-side HMAC authentication. The SDK abstracts the HMAC process, simplifying API calls. It requires initializing the KoraClient with RPC URL and HMAC secret. ```javascript const { KoraClient } = require('@solana/kora'); const kora = new KoraClient({ rpcUrl: 'http://localhost:8080', hmacSecret: process.env.KORA_HMAC_SECRET }); const config = await kora.getConfig(); console.log(config); ``` -------------------------------- ### Start Kora RPC Server Source: https://launch.solana.com/docs/kora/operators/cli Starts the Kora RPC server with various configuration options. It can be started with default settings, custom ports, logging formats, or without loading signers for testing. ```bash # Basic start with default settings kora --config path/to/kora.toml rpc start --signers-config path/to/signers.toml # Start with custom port and config kora --config path/to/kora.toml rpc start \ --signers-config path/to/signers.toml \ --port 8080 \ --logging-format json # Start for testing without signers kora --config path/to/kora.toml rpc start --no-load-signer ``` -------------------------------- ### Launch Kora RPC Server Source: https://launch.solana.com/docs/kora/operators Starts the Kora RPC server with specified configuration files. It allows for custom kora.toml and signers.toml files to be provided. ```bash kora --config path/to/kora.toml rpc start --signers-config path/to/signers.toml ``` -------------------------------- ### Starting Local Solana Test Validator (Shell) Source: https://launch.solana.com/docs/kora/guides/full-demo This command starts a local Solana test validator with the `-r` flag, which typically enables read-only mode or specific configurations for testing purposes. It's a prerequisite for running the Kora gasless transaction demo locally. ```shell solana-test-validator -r ``` -------------------------------- ### Running the Full Gasless Demo (Shell) Source: https://launch.solana.com/docs/kora/guides/full-demo This command executes the complete gasless transaction demo from the client directory. It assumes that the local Solana validator and Kora RPC server have already been started, and the client environment has been initialized. ```shell # From the client directory pnpm full-demo ``` -------------------------------- ### Update Rust Toolchain Source: https://launch.solana.com/docs/kora/getting-started/installation Updates the Rust toolchain to the latest stable version using `rustup`. This is recommended for resolving build failures or compatibility issues with the Kora CLI. ```bash rustup update stable ``` -------------------------------- ### Start Kora Server Source: https://launch.solana.com/docs/kora/operators/configuration This command starts the Kora server using a specified configuration file. The `--no-load-signer` flag can be used for testing to initialize the server without loading signers. ```bash kora --config path/to/kora.toml rpc start --no-load-signer # --other-rpc-flags-here ``` -------------------------------- ### Clone Kora Repository and Install Dependencies (Shell) Source: https://launch.solana.com/docs/kora/index Clones the Kora project from GitHub and installs its dependencies using the 'just' build tool. This is part of the local development setup process. ```shell git clone https://github.com/solana-foundation/kora.git cd kora just install ``` -------------------------------- ### JavaScript Kora SDK with API Key Source: https://launch.solana.com/docs/kora/operators/authentication Example of using the Kora SDK in JavaScript to connect to a Kora RPC endpoint with API Key authentication. The API key is typically loaded from environment variables. ```javascript const { KoraClient } = require('@solana/kora'); const kora = new KoraClient({ rpcUrl: 'http://localhost:8080', apiKey: process.env.KORA_API_KEY }); const config = await kora.getConfig(); console.log(config); ``` -------------------------------- ### JavaScript fetch Request with API Key Source: https://launch.solana.com/docs/kora/operators/authentication Example of making a fetch request to a Kora RPC endpoint in JavaScript, manually including the 'x-api-key' header for authentication. ```javascript async function callKora(method, params = []) { const response = await fetch('http://localhost:8080', { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-api-key': process.env.KORA_API_KEY //'kora_live_sk_1234567890abcdef' }, body: JSON.stringify({ jsonrpc: '2.0', method, params, id: 1 }) }); return response.json(); } const config = await callKora('getConfig'); console.log(config); ``` -------------------------------- ### Install Kora CLI using Cargo Source: https://launch.solana.com/docs/kora/operators/cli Installs the Kora command-line interface using the Rust package manager, Cargo. Ensure you have Rust and Cargo installed on your system. ```bash cargo install kora-cli ``` -------------------------------- ### Signers Configuration Example (TOML) Source: https://launch.solana.com/docs/kora/operators/signers An example `signers.toml` file demonstrating a round-robin signer pool with three signers: two memory signers and one Turnkey signer. This configuration specifies the selection strategy and details for each signer, including their types and required environment variables. ```toml [signer_pool] # Selection strategy: round_robin, random, weighted strategy = "round_robin" # Primary memory signer [[signers]] name = "signer_1" type = "memory" private_key_env = "SIGNER_1_PRIVATE_KEY" # weight = 1 # Not required if strategy is not weighted # Backup memory signer [[signers]] name = "signer_2" type = "memory" private_key_env = "SIGNER_2_PRIVATE_KEY" # weight = 1 # Not required if strategy is not weighted # Turnkey signer for high-value operations [[signers]] name = "signer_3_turnkey" type = "turnkey" api_public_key_env = "TURNKEY_API_PUBLIC_KEY" api_private_key_env = "TURNKEY_API_PRIVATE_KEY" organization_id_env = "TURNKEY_ORG_ID" private_key_id_env = "TURNKEY_PRIVATE_KEY_ID" public_key_env = "TURNKEY_PUBLIC_KEY" # weight = 2 # Higher weight = selected more often ``` -------------------------------- ### Run Kora Server (Shell) Source: https://launch.solana.com/docs/kora/index Starts the Kora server with basic options. The '[OPTIONS]' placeholder indicates that various command-line arguments can be provided to configure the server's behavior. ```shell kora rpc [OPTIONS] ``` -------------------------------- ### Prometheus Query Examples for Kora Metrics Source: https://launch.solana.com/docs/kora/operators/monitoring Example Prometheus queries to analyze Kora RPC server metrics, including requests per second, response time percentiles, error rates, and signer balances. ```promql # Requests per second by method rate(kora_http_requests_total[1m]) # 95th percentile response time histogram_quantile(0.95, kora_http_request_duration_seconds_bucket) # Error rate rate(kora_http_requests_total{status!="200"}[5m]) # Balance of specific signer by name signer_balance_lamports{signer_name="primary_signer"} / 1000000000 # Balance of specific signer by public key signer_balance_lamports{signer_pubkey="4gBe...xyz"} / 1000000000 # Total balance across all signers sum(signer_balance_lamports) / 1000000000 # Minimum balance across all signers (useful for alerts) min(signer_balance_lamports) / 1000000000 ``` -------------------------------- ### JavaScript HMAC Authentication using crypto library Source: https://launch.solana.com/docs/kora/operators/authentication This example shows how to manually implement HMAC authentication using Node.js's built-in 'crypto' library. It involves creating a timestamp, constructing the message, signing it with HMAC-SHA256, and sending it with custom headers. Dependencies include 'crypto' and 'node-fetch'. ```javascript async function callKoraHMAC(method, params = []) { const timestamp = Math.floor(Date.now() / 1000).toString(); const body = JSON.stringify({ jsonrpc: '2.0', method, params, id: 1 }); // Create HMAC signature const message = timestamp + body; const signature = crypto .createHmac('sha256', process.env.KORA_HMAC_SECRET) // kora_hmac_your-strong-hmac-secret-key .update(message) .digest('hex'); const response = await fetch('http://localhost:8080', { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-timestamp': timestamp, 'x-hmac-signature': signature }, body: body }); return response.json(); } const config = await callKoraHMAC('getConfig'); console.log(config); ``` -------------------------------- ### Basic Kora CLI Usage Source: https://launch.solana.com/docs/kora/operators/cli Demonstrates the basic structure for invoking Kora CLI commands. This serves as a starting point for all Kora CLI operations. ```bash kora [OPTIONS] ``` -------------------------------- ### TypeScript SDK Example for getSupportedTokens Source: https://launch.solana.com/docs/kora/json-rpc-api/methods/get-supported-tokens An example using the TypeScript SDK to call the getSupportedTokens method. It demonstrates how to initialize the client, make the call, and log the resulting array of supported token addresses. ```typescript const { tokens } = await client.getSupportedTokens(); console.log('Supported tokens:', tokens); // Output: ['EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', ...] ``` -------------------------------- ### Example Kora Metrics Output Source: https://launch.solana.com/docs/kora/operators/monitoring Example output from the Kora RPC server's `/metrics` endpoint, showing various Prometheus metrics like HTTP requests, duration, and signer balances. ```text # Total requests by method and status kora_http_requests_total{method="signTransaction",status="200"} 42 kora_http_requests_total{method="signTransaction",status="400"} 3 # Request duration (in seconds) by method kora_http_request_duration_seconds{method="signTransaction"} 0.045 # Signer balances (for multi-signer setups) signer_balance_lamports{signer_name="primary_signer",signer_pubkey="4gBe...xyz"} 500000000 signer_balance_lamports{signer_name="backup_signer",signer_pubkey="7XyZ...abc"} 300000000 ``` -------------------------------- ### TypeScript SDK Example for signTransaction Source: https://launch.solana.com/docs/kora/json-rpc-api/methods/sign-transaction An example of using the Kora Solana SDK in TypeScript to sign a transaction. It shows how to call the client method and access the results. ```typescript const result = await client.signTransaction({ transaction: 'base64EncodedTransaction' }); console.log('Signature:', result.signature); console.log('Signed tx:', result.signed_transaction); ``` -------------------------------- ### cURL Example for signTransaction Source: https://launch.solana.com/docs/kora/json-rpc-api/methods/sign-transaction An example of how to call the signTransaction method using cURL. This demonstrates sending a JSON-RPC request with the transaction payload. ```bash curl -X POST http://localhost:8080 \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"signTransaction","params":{"transaction":"base64EncodedTransaction"}}' ``` -------------------------------- ### Configure Kora API Key Authentication Source: https://launch.solana.com/docs/kora/operators/authentication Demonstrates how to configure API Key authentication for Kora by setting the KORA_API_KEY environment variable or the api_key in the kora.toml file. ```toml [kora.auth] api_key = "kora_live_sk_1234567890abcdef" # Use a strong, unique key ``` -------------------------------- ### Start Kora with Signers Configuration (CLI) Source: https://launch.solana.com/docs/kora/operators/signers Command to start the Kora RPC service with a specified signers configuration file. This command integrates the defined signers into the Kora node's operation for transaction signing. ```bash kora --config path/to/kora.toml rpc start --signers-config path/to/signers.toml ``` -------------------------------- ### Private Key Signer - Base58 Format Source: https://launch.solana.com/docs/kora/operators/signers Example of configuring a private key signer using the default Base58 format. This format is a standard Solana encoding for private keys and is directly provided as an environment variable. ```bash KORA_PRIVATE_KEY="5KKsLVU6TcbVDK4BS6K1DGDxnh4Q9xjYJ8XaDCG5t8ht..." ``` -------------------------------- ### cURL Example for getPayerSigner Source: https://launch.solana.com/docs/kora/json-rpc-api/methods/get-payer-signer This cURL command demonstrates how to make a POST request to the Kora server to invoke the getPayerSigner method. It sets the Content-Type header and provides the JSON-RPC payload. ```bash curl -X POST http://localhost:8080 \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"getPayerSigner","params":[]}' ``` -------------------------------- ### Accessing Signer Balances Source: https://launch.solana.com/docs/kora/operators/monitoring These examples show how to retrieve specific signer balances or all signer balances from the /metrics endpoint using curl and grep. ```APIDOC ## GET /metrics ### Description Retrieves Prometheus-formatted metrics, including signer balances. ### Method GET ### Endpoint `/metrics` ### Query Parameters None ### Request Example ```bash # Check balance of specific signer curl http://localhost:8080/metrics | grep 'signer_balance_lamports{signer_name="primary_signer"}' # View all signer balances curl http://localhost:8080/metrics | grep signer_balance_lamports ``` ### Response #### Success Response (200) - **Metrics Data** (string) - Prometheus-formatted text output. #### Response Example ```text # HELP signer_balance_lamports Lamports balance for a given signer # TYPE signer_balance_lamports gauge signer_balance_lamports{signer_name="primary_signer"} 1000000000 signer_balance_lamports{signer_name="secondary_signer"} 500000000 ``` ``` -------------------------------- ### Get Kora Payment Instruction (TypeScript) Source: https://launch.solana.com/docs/kora/guides/full-demo This function estimates transaction fees and generates a payment instruction from Kora. It requires a KoraClient, an array of instructions, a sender keypair, and a payment token. It returns a payment instruction object. ```typescript 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 }; } ``` -------------------------------- ### Troubleshooting Authentication Errors Source: https://launch.solana.com/docs/kora/operators/authentication Common authentication issues and their resolutions for both API Key and HMAC methods. ```APIDOC ## Troubleshooting ### 401 Unauthorized with API Key * Verify the API key is correct and matches the server configuration. * Check that the `x-api-key` header is being sent correctly. * Ensure there is no leading or trailing whitespace in the API key. ### 401 Unauthorized with HMAC * Verify the timestamp is current (typically within a 5-minute window). * Check that the message construction exactly matches the expected format: `{timestamp}{body}`. * Ensure the HMAC secret used on the client matches the server configuration precisely. * Verify the generated signature is in lowercase hexadecimal format. ``` -------------------------------- ### Deploy Application to Railway Source: https://launch.solana.com/docs/kora/operators/deployment/railway Deploys the application to Railway by uploading files, building the Docker image, and starting the container. This command assumes the project has been initialized. ```bash railway up ``` -------------------------------- ### Keypair JSON Content Source: https://launch.solana.com/docs/kora/operators/signers Example structure of a `keypair.json` file. It contains a JSON array of integers, which represents the private key bytes. ```json [174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56, 222, 53, 138, 189, 224, 216, 117, 173, 10, 149, 53, 45, 73, 251, 237, 246, 15, 185, 186, 82, 177, 240, 148, 69, 241, 227, 167, 80, 141, 89, 240, 121, 121, 35, 172, 247, 68, 251, 226, 218, 48, 63, 176, 109, 168, 89, 238, 135] ``` -------------------------------- ### Environment Variables for Signers Source: https://launch.solana.com/docs/kora/operators/signers Example environment variables required for configuring memory and Turnkey signers in Kora. These variables provide the necessary credentials and keys for each signer type to operate securely. ```bash # Memory signers SIGNER_1_PRIVATE_KEY="your_base58_private_key_1" SIGNER_2_PRIVATE_KEY="your_base58_private_key_2" # Turnkey signer TURNKEY_API_PUBLIC_KEY="your_turnkey_api_public_key" TURNKEY_API_PRIVATE_KEY="your_turnkey_api_private_key" TURNKEY_ORG_ID="your_turnkey_organization_id" TURNKEY_PRIVATE_KEY_ID="your_turnkey_private_key_id" TURNKEY_PUBLIC_KEY="your_turnkey_public_key" ``` -------------------------------- ### Configuration for Combined Authentication Source: https://launch.solana.com/docs/kora/operators/authentication This configuration snippet shows how to enable both API key and HMAC secret authentication simultaneously. When both are active, clients must include `x-api-key`, `x-timestamp`, and `x-hmac-signature` headers in their requests. ```ini [kora.auth] api_key = "kora_live_sk_1234567890abcdef" hmac_secret = "kora_hmac_your-strong-hmac-secret-key" ``` -------------------------------- ### View All Signer Balances (curl) Source: https://launch.solana.com/docs/kora/operators/monitoring Fetches and displays the balances of all signers by querying the /metrics endpoint. This command uses curl to get all metrics and grep to filter for lines containing signer balances. ```shell curl http://localhost:8080/metrics | grep signer_balance_lamports ``` -------------------------------- ### Starting Kora RPC Server (Shell) Source: https://launch.solana.com/docs/kora/guides/full-demo This command initiates the Kora RPC server, which is essential for handling gasless transactions. The `--signers-config signers.toml` argument specifies the configuration file for managing signers, likely containing necessary keys and permissions for the Kora node. ```shell kora rpc start --signers-config signers.toml ``` -------------------------------- ### Kora RPC Server Help Source: https://launch.solana.com/docs/kora/operators Displays the help information for the Kora RPC command, listing available flags and options. ```bash kora rpc --help ``` -------------------------------- ### Initialize Kora and Solana Clients Source: https://launch.solana.com/docs/kora/guides/full-demo Initializes the Kora client and establishes connections to the Solana RPC and WebSocket endpoints. It also sets up transaction confirmation utilities using the provided RPC and WebSocket URLs. ```typescript 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 }; } ``` -------------------------------- ### Import and Configure Solana Kora SDK Source: https://launch.solana.com/docs/kora/guides/full-demo Imports necessary modules from '@solana/kora', '@solana/kit', '@solana-program/memo', '@solana/transaction-confirmation', '@solana-program/compute-budget', 'dotenv', and 'path'. It also configures environment variables and sets up a global configuration object for Kora and Solana RPC endpoints, compute budget, and transaction versions. ```typescript 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/", }; ``` -------------------------------- ### cURL Request with API Key Authentication Source: https://launch.solana.com/docs/kora/operators/authentication Example of making a POST request to a Kora RPC endpoint using cURL, including the 'x-api-key' header for authentication. ```bash curl -X POST http://localhost:8080 \ -H "Content-Type: application/json" \ -H "x-api-key: kora_live_sk_1234567890abcdef" \ -d '{"jsonrpc": "2.0", "method": "getConfig", "id": 1}' ``` -------------------------------- ### Add Kora CLI to PATH Environment Variable Source: https://launch.solana.com/docs/kora/getting-started/installation Appends the Cargo bin directory to the user's bashrc file to ensure the `kora` command is recognized system-wide. This is a common troubleshooting step for 'command not found' errors. ```bash echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> ~/.bashrc source ~/.bashrc ``` -------------------------------- ### Get Solana Blockhash using cURL Source: https://launch.solana.com/docs/kora/json-rpc-api/methods/get-blockhash This example demonstrates how to call the getBlockhash method using cURL. It sends a POST request with the JSON-RPC payload to the specified RPC endpoint. This is useful for testing or direct interaction without an SDK. ```bash curl -X POST http://localhost:8080 \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"getBlockhash","params":[]}' ``` -------------------------------- ### Initialize Railway Project Source: https://launch.solana.com/docs/kora/operators/deployment/railway Initializes a new Railway project in the current directory. This command prompts the user to select or create a project and set a project name. ```bash railway init ``` -------------------------------- ### Create Solana Transaction Instructions with Kora Client Source: https://launch.solana.com/docs/kora/guides/full-demo Builds a series of transaction instructions, including SPL token transfers, native SOL transfers, and memo instructions. It utilizes the Kora Client's `transferTransaction` method for token and SOL transfers and `@solana/programs`' `getAddMemoInstruction` for adding memos. This function aggregates these instructions for subsequent transaction building. ```typescript 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 }; } ``` -------------------------------- ### Setup Solana Keypairs and Kora Signer Address Source: https://launch.solana.com/docs/kora/guides/full-demo Loads keypairs for transaction sender and destination from environment variables using `getEnvKeyPair`. It also fetches the Kora signer address required for transaction signing using `client.getPayerSigner`. This function is crucial for initializing the necessary cryptographic credentials for interacting with the Solana network via Kora. ```typescript 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 }; } ``` -------------------------------- ### Initialize KoraClient (TypeScript) Source: https://launch.solana.com/docs/kora/json-rpc-api Demonstrates how to initialize a standalone KoraClient for interacting with a Kora server. Requires '@solana/kora' and '@solana/kit' v5.0+. ```typescript import { KoraClient } from '@solana/kora'; const kora = new KoraClient('https://your-kora-server.com'); const config = await kora.getConfig(); ``` -------------------------------- ### Test Kora RPC Server with getConfig Source: https://launch.solana.com/docs/kora/operators/monitoring How to send a POST request to the Kora RPC server to call the `getConfig` method and generate some initial metrics. ```bash curl -X POST http://localhost:8080 \ -H "Content-Type: application/json" \ -d '{"jsonrpc": "2.0", "method": "getConfig", "id": 1}' ``` -------------------------------- ### Exempt Endpoints Source: https://launch.solana.com/docs/kora/operators/authentication Details on endpoints that are exempt from authentication, such as health checks. ```APIDOC ## Exempt Endpoints The `/liveness` endpoint is always exempt from authentication, allowing for health checks even when authentication is enabled. ```bash # This works even with authentication enabled curl http://localhost:8080/liveness ``` ``` -------------------------------- ### Combined Authentication Source: https://launch.solana.com/docs/kora/operators/authentication Enabling both API Key and HMAC authentication for enhanced security. ```APIDOC ## Combined Authentication You can enable both API Key and HMAC authentication simultaneously for maximum security. Configure both in your settings: ```ini [kora.auth] api_key = "kora_live_sk_1234567890abcdef" hmac_secret = "kora_hmac_your-strong-hmac-secret-key" ``` When both are configured, clients must send the `x-api-key`, `x-timestamp`, and `x-hmac-signature` headers with their requests. ``` -------------------------------- ### JSON-RPC 2.0 Error Response Format Source: https://launch.solana.com/docs/kora/json-rpc-api Example of an error response in JSON-RPC 2.0 format, detailing the error code and message. ```json { "jsonrpc": "2.0", "id": 1, "error": { "code": -32600, "message": "Invalid request" } } ``` -------------------------------- ### Main Orchestration Function for Kora Gasless Transactions (JavaScript) Source: https://launch.solana.com/docs/kora/guides/full-demo The main asynchronous function orchestrates the entire gasless transaction process. It initializes necessary clients, sets up keypairs, creates transaction instructions, fetches payment instructions from Kora, assembles and partially signs the final transaction, and finally submits it for execution on the Solana cluster. Error handling is included to catch and report any failures during the process. ```javascript 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); } } ``` -------------------------------- ### JSON-RPC Response for getPayerSigner Source: https://launch.solana.com/docs/kora/json-rpc-api/methods/get-payer-signer This is an example JSON-RPC response for the getPayerSigner method. It includes the payment address and the signer address returned by the Kora server. ```json { "jsonrpc": "2.0", "id": 1, "result": { "payment_address": "3Z1Ef7YaxK8oUMoi6exf7wYZjZKWJJsrzJXSt1c3qrDE", "signer_address": "3Z1Ef7YaxK8oUMoi6exf7wYZjZKWJJsrzJXSt1c3qrDE" } } ``` -------------------------------- ### Get Supported Tokens Source: https://launch.solana.com/docs/kora/json-rpc-api/methods/get-supported-tokens Retrieves a list of tokens supported for fee payments. This endpoint is useful for understanding which cryptocurrencies can be utilized for transactions. ```APIDOC ## GET /getSupportedTokens ### Description Retrieves the list of tokens supported for fee payment. ### Method POST ### Endpoint /getSupportedTokens ### Parameters #### Query Parameters None #### Request Body ```json { "jsonrpc": "2.0", "id": 1, "method": "getSupportedTokens", "params": [] } ``` ### Request Example ```bash curl -X POST http://localhost:8080 \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"getSupportedTokens","params":[]}' ``` ### Response #### Success Response (200) - **tokens** (array) - A list of token addresses supported for fee payments. #### Response Example ```json { "jsonrpc": "2.0", "id": 1, "result": { "tokens": [ "3Z1Ef7YaxK8oUMoi6exf7wYZjZKWJJsrzJXSt1c3qrDE" ] } } ``` ### SDK Example (TypeScript) ```typescript const { tokens } = await client.getSupportedTokens(); console.log('Supported tokens:', tokens); // Output: ['EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', ...] ``` ``` -------------------------------- ### Generate and Manage Keypairs with Solana CLI (Shell) Source: https://launch.solana.com/docs/kora/operators/signers Commands to generate a new keypair file, retrieve its public key, and fund the associated wallet with SOL for transaction fees using the Solana CLI. ```shell # Generate new keypair file solana-keygen new --outfile ~/.config/solana/kora-keypair.json # Get the public key solana-keygen pubkey ~/.config/solana/kora-keypair.json # Fund with SOL for transaction fees solana transfer --from 0.1 ``` -------------------------------- ### Build Kora Project (Shell) Source: https://launch.solana.com/docs/kora/index Builds the Kora project using the 'just' build tool. This command compiles the Rust backend and prepares the application for execution. ```shell just build ``` -------------------------------- ### JSON-RPC 2.0 Successful Response Format Source: https://launch.solana.com/docs/kora/json-rpc-api Example of a successful JSON-RPC 2.0 response from the Kora API, containing the result of the requested method. ```json { "jsonrpc": "2.0", "id": 1, "result": {} } ``` -------------------------------- ### Initialize Kora Client and Sign Transaction (TypeScript) Source: https://launch.solana.com/docs/kora/index Demonstrates how to initialize the Kora client using the TypeScript SDK and sign a transaction. This is useful for applications that need to interact with Kora's signing capabilities. ```typescript // Initialize Kora client import { KoraClient } from '@solana/kora'; const kora = new KoraClient({ rpcUrl: 'http://localhost:8080' }); // Sign transaction as paymaster const signed = await kora.signTransaction({ transaction }); ```