Solana integration
Overview
This sample demonstrates how to integrate Openfort's embedded wallet infrastructure with the Solana blockchain. It showcases user creation and transaction execution on Solana.
Project structure
solana-sample/
├── src/
│ ├── App.tsx # Main application component
│ ├── main.tsx # React entry point
│ ├── Login.tsx # Authentication flow
│ ├── content.tsx # UI content and components
│ ├── solana.tsx # Solana blockchain interactions
│ ├── openfort.ts # Openfort SDK configuration
│ ├── index.css # Global styles
│ ├── vite-env.d.ts # Vite type definitions
│ ├── contexts/
│ │ └── OpenfortContext.tsx # Openfort wallet context provider
│ ├── utils/
│ │ ├── kora.ts # Gasless transaction logic (Kora relayer)
│ │ ├── transaction.ts # Standard SOL transfer implementation
│ │ └── systemProgram.ts # Custom SOL transfer instruction builder
│ └── assets/ # Static assets (logos, icons)
│ ├── openfort.svg
│ └── solanaLogo.svg
├── public/
│ └── favicon.ico # Favicon
├── .env.local.example # Environment template
├── package.json # Dependencies and scripts
├── vite.config.ts # Vite configuration
├── tsconfig.json # TypeScript configuration
└── README.md # Project documentation
Key features
-
Openfort embedded wallet creation
-
Solana transaction execution
-
Gasless Solana transactions via Kora relayer
-
Simple authentication flow
| Component | Technology |
|---|---|
| Frontend | React + Vite + TypeScript |
| Key Libraries | @openfort/openfort-js, @solana/kit, @solana/kora |
| Blockchain | Solana |
| Styling | CSS |
Quick start
Clone the repository and navigate to the solana sample:
git clone https://github.com/openfort-xyz/openfort-js.git
cd openfort-js
pnpm install
pnpm build
cd examples/apps/solana-samplePrerequisites
- Node.js 18+
- pnpm
- Openfort account with configured API keys
- Modern web browser
Configuration
-
Copy the environment template:
cp .env.local.example .env.local -
Add your Openfort credentials to
.env.local:VITE_PROJECT_PUBLISHABLE_KEY=your_publishable_key VITE_SHIELD_PUBLISHABLE_KEY=your_shield_key VITE_SOLANA_TEST_RECEIVE_ADDRESS=your_solana_receive_address
Install and run
From the openfort-js project root:
pnpm dev:solanaOr from the solana-sample directory:
pnpm install
pnpm devHow it works
The application demonstrates three core functionalities:
- User Creation: Creates a new Openfort user with embedded wallet support
- Solana Transactions: Executes transactions on the Solana blockchain using Openfort's signer
- Gasless Solana Transactions: Sends SOL without the user needing to pay network fees
This sample is ideal for developers looking to add Solana support to their applications using Openfort's embedded wallet infrastructure.
Gasless transactions
The sample includes support for gasless Solana transactions using the Kora relayer (built by the Solana Foundation). In a gasless transaction, the user does not need to hold SOL to cover network fees. Instead, a fee payer (Kora, accessed through Openfort's RPC endpoint) covers the transaction fees on the user's behalf.
How gasless transactions work
The gasless flow uses a co-signing pattern:
- Initialize the Kora client pointing to Openfort's hosted relayer endpoint
- Build the transaction with Kora set as the fee payer
- Sign with the user's embedded wallet via Openfort's
signMessage(withhashMessage: falsefor Solana Ed25519 compatibility) - Submit to Kora which co-signs as the fee payer and broadcasts the transaction to the Solana network
Configuration
Set up the Kora client using your Openfort Shield publishable key:
import { KoraClient } from '@solana/kora';
const koraConfig = {
rpcUrl: 'https://api.openfort.io/rpc/solana/devnet',
apiKey: `Bearer ${import.meta.env.VITE_SHIELD_PUBLISHABLE_KEY}`,
};
const client = new KoraClient(koraConfig);Sending a gasless transaction
The sendGaslessSolTransaction utility in src/utils/kora.ts handles the complete flow:
import { sendGaslessSolTransaction } from './utils/kora';
const result = await sendGaslessSolTransaction({
from: userPublicKey,
to: recipientAddress,
amountInSol: 0.01,
signMessage: handleSignMessage,
koraConfig,
});Under the hood, the function:
- Calls
client.getPayerSigner()to get the Kora fee payer address - Builds a transfer instruction via
client.transferTransaction() - Constructs a versioned (v0) transaction message with compute budget instructions
- Signs the transaction with the user's Openfort embedded wallet
- Sends the user-signed transaction to Kora via
client.signAndSendTransaction(), which co-signs and broadcasts it
The user's wallet only needs to sign the transaction payload -- no SOL is deducted from their account for fees.