For AI agents: a documentation index is available at /llms.txt. A markdown version of this page is available at the same URL with .md appended (or via Accept: text/markdown).
Skip to main content

Integrate Embedded Wallets with the Solana Blockchain in React Native

The React Native SDK v9 exposes a TransactionSigner from @solana/signers through useWeb3Auth().web3Auth.signer. Use it with @solana/web3.js for balances, signing, and sending transactions. This replaces the v8 SolanaWallet class from @web3auth/solana-provider.

Migration from v8

If your app still uses SolanaWallet, SolanaPrivateKeyProvider, or @web3auth/solana-provider, follow React Native migration guide.

Prerequisites

Complete the React Native SDK get started guide first:

  • Install @web3auth/react-native-sdk@^9 and configure Metro, Babel, and the entry-point setup import.
  • Export a Web3AuthContextConfig from web3authConfig.ts and wrap your app in Web3AuthProvider.
  • Sign users in with useWeb3AuthConnect().connectTo() before you read the signer.

Chain details for Solana

  • Chain Namespace: SOLANA
  • Chain ID: 0x1
  • Public RPC URL: https://api.mainnet-beta.solana.com (avoid public RPC in production; prefer managed services)
  • Display Name: Solana Mainnet
  • Block Explorer Link: https://explorer.solana.com
  • Ticker: SOL
  • Ticker Name: Solana
  • Logo: https://images.toruswallet.io/solana.svg

Installation

v9 does not require @web3auth/solana-provider. Install @solana/web3.js for RPC calls such as balance lookups and transaction broadcast:

npm install @solana/web3.js

The SDK bundles @solana/signers types for web3Auth.signer.

SDK configuration

Add a Solana chain to the chains array in web3authConfig.ts. Do not pass SolanaPrivateKeyProvider or privateKeyProvider in v9.

web3authConfig.ts
import {
CHAIN_NAMESPACES,
WEB3AUTH_NETWORK,
type Web3AuthContextConfig,
} from '@web3auth/react-native-sdk'

const web3AuthConfig: Web3AuthContextConfig = {
web3AuthOptions: {
clientId: 'YOUR_CLIENT_ID',
redirectUrl: 'yourapp://auth',
network: WEB3AUTH_NETWORK.SAPPHIRE_MAINNET,
chains: [
{
chainNamespace: CHAIN_NAMESPACES.SOLANA,
chainId: '0x1', // Mainnet (use 0x2 for Testnet, 0x3 for Devnet)
rpcTarget: 'https://api.mainnet-beta.solana.com',
displayName: 'Solana Mainnet',
blockExplorerUrl: 'https://explorer.solana.com',
ticker: 'SOL',
tickerName: 'Solana',
logo: 'https://images.toruswallet.io/solana.svg',
},
],
defaultChainId: '0x1',
},
}

export default web3AuthConfig

Get the signer

After the user connects, read isConnected and access the signer through useWeb3Auth():

import { useWeb3Auth } from '@web3auth/react-native-sdk'
import type { TransactionSigner } from '@solana/signers'

function useSolanaSigner() {
const { isConnected, web3Auth } = useWeb3Auth()
if (!isConnected) return null
return web3Auth?.signer as TransactionSigner | null
}

Get accounts

import { Text } from 'react-native'
import { useWeb3Auth } from '@web3auth/react-native-sdk'
import type { TransactionSigner } from '@solana/signers'

function SolanaAddress() {
const { web3Auth } = useWeb3Auth()
const signer = web3Auth?.signer as TransactionSigner | null
const address = signer ? String(signer.address) : null

return <Text>{address ?? 'Not connected'}</Text>
}

Get balance

import { useWeb3Auth } from '@web3auth/react-native-sdk'
import type { TransactionSigner } from '@solana/signers'
import { Connection, PublicKey, LAMPORTS_PER_SOL } from '@solana/web3.js'

function useSolanaBalance(rpcUrl = 'https://api.mainnet-beta.solana.com') {
const { web3Auth } = useWeb3Auth()
const signer = web3Auth?.signer as TransactionSigner | null

const getBalance = async () => {
if (!signer) return null
const connection = new Connection(rpcUrl, 'confirmed')
const lamports = await connection.getBalance(new PublicKey(String(signer.address)))
return lamports / LAMPORTS_PER_SOL
}

return { getBalance }
}

Sign a transaction

import type { TransactionSigner } from '@solana/signers'
import {
Connection,
PublicKey,
Transaction,
SystemProgram,
LAMPORTS_PER_SOL,
} from '@solana/web3.js'

async function signSolanaTransaction(signer: TransactionSigner, to: string) {
const connection = new Connection('https://api.mainnet-beta.solana.com', 'confirmed')
const address = new PublicKey(String(signer.address))
const { blockhash } = await connection.getRecentBlockhash('finalized')

const transaction = new Transaction({
recentBlockhash: blockhash,
feePayer: address,
}).add(
SystemProgram.transfer({
fromPubkey: address,
toPubkey: new PublicKey(to),
lamports: 0.01 * LAMPORTS_PER_SOL,
})
)

const signedTransaction = await signer.signTransaction(transaction)
return signedTransaction
}

Send a transaction

import type { TransactionSigner } from '@solana/signers'
import {
Connection,
PublicKey,
Transaction,
SystemProgram,
LAMPORTS_PER_SOL,
} from '@solana/web3.js'

async function sendSolanaTransaction(signer: TransactionSigner, to: string) {
const connection = new Connection('https://api.mainnet-beta.solana.com', 'confirmed')
const address = new PublicKey(String(signer.address))
const block = await connection.getLatestBlockhash('finalized')

const transaction = new Transaction({
blockhash: block.blockhash,
lastValidBlockHeight: block.lastValidBlockHeight,
feePayer: address,
}).add(
SystemProgram.transfer({
fromPubkey: address,
toPubkey: new PublicKey(to),
lamports: 0.01 * LAMPORTS_PER_SOL,
})
)

const signedTransaction = await signer.signTransaction(transaction)
const signature = await connection.sendRawTransaction(signedTransaction.serialize())
return signature
}

Sign a message

import type { TransactionSigner } from '@solana/signers'
import { signBytes } from '@solana/signers'

async function signSolanaMessage(signer: TransactionSigner, message: string) {
const encoded = new TextEncoder().encode(message)
const signature = await signBytes(signer, encoded)
return Buffer.from(signature).toString('base64')
}

Next steps