useWallet()
Primary hook for accessing wallet state and methods. Supports both legacy web3.js and modern @solana/kit architectures.
import { useWallet } from '@hermis/solana-headless-react';
const {
// Wallet state
wallet,
publicKey,
connected,
connecting,
disconnecting,
wallets,
autoConnect,
// Kit properties (NEW in v2!)
address,
addressString,
chain,
messageSigner,
transactionSigner,
// Methods
select,
connect,
disconnect,
sendTransaction,
signTransaction,
signAllTransactions,
signAndSendTransaction,
signMessage,
signIn,
getChainId,
hasFeature,
} = useWallet();
Wallet State Properties
Currently selected wallet adapter
Public key of connected wallet (web3.js format)
Whether wallet is connected
Disconnection in progress
Array of all available wallet adapters (both installed and detected)
Whether auto-connect is enabled
Kit Architecture Properties
These properties enable seamless integration with @solana/kit’s modern architecture.
Kit Address type - Use this with @solana/kit instead of publicKey. Null if wallet not connected.const { address } = useWallet();
// Use with Kit instructions
const instruction = getTransferSolInstruction({
source: address,
destination: recipientAddress,
amount: lamports(1000000n)
});
Plain address string - Base58-encoded address. Null if wallet not connected.const { addressString } = useWallet();
console.log('Wallet address:', addressString);
chain
`solana:${string}` | null
Current Solana chain identifier following Wallet Standard format (CAIP-2). Null if not configured.Examples:
- Mainnet:
'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp'
- Devnet:
'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1'
- Testnet:
'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z'
messageSigner
MessageModifyingSigner<string> | null
Kit message signer - Use for signing messages with @solana/kit architecture. Null if wallet doesn’t support message signing or not connected.const { messageSigner } = useWallet();
if (messageSigner) {
const signedMessages = await messageSigner.modifyAndSignMessages([{
content: new TextEncoder().encode('Hello, Solana!'),
signatures: {}
}]);
}
transactionSigner
TransactionSendingSigner<string> | null
Kit transaction signer - Use for signing and sending transactions with @solana/kit. Null if wallet doesn’t support transactions or not connected.import { pipe, createTransactionMessage, setTransactionMessageFeePayerSigner } from '@solana/kit';
const { transactionSigner } = useWallet();
if (transactionSigner) {
const message = pipe(
createTransactionMessage({ version: 0 }),
m => setTransactionMessageFeePayerSigner(transactionSigner, m),
// ... add instructions
);
}
Wallet Methods
select
(walletName: string | null) => Promise<void>
Select a wallet by name. Pass null to deselect.
connect
() => Promise<WalletAdapter>
Connect to selected wallettry {
await connect();
} catch (error) {
console.error('Connection failed:', error);
}
Transaction Methods
All transaction methods support both web3.js and @solana/kit architectures through DualConnection and DualTransaction types.
signTransaction
<T extends DualTransaction>(transaction: T, options?: DualArchitectureOptions) => Promise<T>
Sign a transaction without sending it. Supports both web3.js Transaction/VersionedTransaction and Kit TransactionMessage.// Web3.js usage (legacy)
import { Transaction } from '@solana/web3.js';
const tx = new Transaction();
const signed = await signTransaction(tx);
// Kit usage (NEW!)
import { createTransactionMessage } from '@solana/kit';
const kitTx = createTransactionMessage({ version: 0 });
const signed = await signTransaction(kitTx);
sendTransaction
<T extends DualTransaction>(transaction: T, connection: DualConnection, options?: DualArchitectureOptions) => Promise<string>
Sign and send a transaction. Accepts both legacy Connection and Kit Rpc.// With web3.js Connection
import { Connection } from '@solana/web3.js';
const connection = new Connection('https://api.devnet.solana.com');
const signature = await sendTransaction(transaction, connection);
// With Kit Rpc (NEW!)
import { createSolanaRpc, devnet } from '@solana/kit';
const rpc = createSolanaRpc(devnet('https://api.devnet.solana.com'));
const signature = await sendTransaction(transaction, rpc);
signAllTransactions
<T extends DualTransaction>(transactions: T[], options?: DualArchitectureOptions) => Promise<T[]>
Sign multiple transactions. All transactions must use the same architecture (all web3.js OR all Kit).const signed = await signAllTransactions([tx1, tx2, tx3]);
signAndSendTransaction
<T extends DualTransaction>(transaction: T, connection: DualConnection, options?: DualArchitectureOptions) => Promise<string>
Sign and send a transaction in one call. More efficient than separate sign + send.const signature = await signAndSendTransaction(transaction, connection);
signMessage
(message: Uint8Array) => Promise<Uint8Array>
Sign a message for authentication. Returns the signature bytes.const message = new TextEncoder().encode('Sign in to MyApp');
const signature = await signMessage(message);
signIn
() => Promise<SolanaSignInOutput>
Sign in with Solana (SIWS) - standardized authentication method.const { account, signedMessage, signature } = await signIn();
Utility Methods
getChainId
(network: 'mainnet' | 'devnet' | 'testnet') => `solana:${string}`
Get the Wallet Standard chain identifier for a given network.const devnetChain = getChainId('devnet');
// 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1'
hasFeature
(feature: 'signMessage' | 'signTransaction' | 'signAllTransactions' | 'signIn') => boolean
Check if the connected wallet supports a specific feature.if (hasFeature('signMessage')) {
const signature = await signMessage(message);
}
Complete Example with Kit
import { useWallet, useConnection } from '@hermis/solana-headless-react';
import { createSolanaRpc, devnet, pipe, createTransactionMessage,
setTransactionMessageFeePayerSigner, setTransactionMessageLifetimeUsingBlockhash,
appendTransactionMessageInstruction } from '@solana/kit';
import { getTransferSolInstruction } from '@solana-program/system';
import { lamports } from '@solana/kit';
function SendTransaction({ recipientAddress }: { recipientAddress: Address<string> }) {
const {
address,
transactionSigner,
connected,
signAndSendTransaction
} = useWallet();
const { connection } = useConnection();
const handleSend = async () => {
if (!address || !transactionSigner) {
throw new Error('Wallet not connected');
}
// Get latest blockhash
const { value: latestBlockhash } = await connection.getLatestBlockhash().send();
// Build transaction using Kit
const message = pipe(
createTransactionMessage({ version: 0 }),
m => setTransactionMessageFeePayerSigner(transactionSigner, m),
m => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, m),
m => appendTransactionMessageInstruction(
getTransferSolInstruction({
source: address,
destination: recipientAddress,
amount: lamports(1000000n)
}),
m
)
);
// Sign and send
const signature = await signAndSendTransaction(message, connection);
console.log('Transaction signature:', signature);
};
return (
<button onClick={handleSend} disabled={!connected}>
Send 0.001 SOL
</button>
);
}
Migration from v1
If you’re upgrading from v1, here are the key changes:
New Kit Properties:
// v1 (legacy only)
const { publicKey } = useWallet();
// v2 (dual architecture)
const {
publicKey, // Still available for web3.js
address, // NEW: Kit Address type
transactionSigner, // NEW: Kit signer
messageSigner // NEW: Kit message signer
} = useWallet();
Enhanced Transaction Methods:
// v1 - Only web3.js Connection
await sendTransaction(tx, connection);
// v2 - Both Connection AND Kit Rpc
await sendTransaction(tx, connection); // web3.js Connection
await sendTransaction(tx, rpc); // Kit Rpc (NEW!)
All legacy APIs remain fully supported - v2 is backward compatible!