walletkitt-react
v0.1.2
Published
A provider-agnostic wallet integration package for React applications supporting WalletConnect, Privy, and Reown
Maintainers
Readme
WalletKitt React
A provider-agnostic wallet integration package for React applications. Configure multiple wallet providers (Privy, Reown) with a clean, modular API. Only install the dependencies you actually use!
Features
- Modular Dependencies: Only install adapters you need - no forced dependencies
- Multi-Provider Support: Configure multiple wallet providers with easy switching
- Clean API: Familiar
createWalletKitpattern for initialization - Provider-Agnostic: Unified interface for all wallet operations
- Type-Safe: Full TypeScript support with comprehensive type definitions
- React Hooks: Easy-to-use hooks for wallet interactions (
useWallet,useConnect,useAccount) - EVM Compatible: Support for Ethereum and EVM-compatible chains
- Auto-reconnection: Automatic wallet state restoration on page refresh
- Extensible: Add new wallet providers easily
Installation
Core Package (Required)
npm install walletkitt-react ethersAdapter-Specific Dependencies (Install Only What You Need)
For Privy:
npm install @privy-io/react-authFor Reown:
npm install @reown/appkit @reown/appkit-adapter-ethersSupported Providers
- Privy
- Reown (AppKit)
Basic Usage
1. Initialize WalletKit (Outside React)
import { createWalletKit, PrivyAdapter } from 'walletkitt-react';
// Initialize outside of React components
createWalletKit({
chains: [1, 137], // Ethereum, Polygon
metadata: {
name: 'My App',
description: 'My Web3 App',
url: 'https://myapp.com',
icons: ['https://myapp.com/icon.png'],
},
adapters: [
// Only include adapters you've installed dependencies for
new PrivyAdapter({
appId: 'your-privy-app-id',
config: {
appearance: {
theme: 'light',
accentColor: '#676FFF',
},
loginMethods: ['wallet', 'email'],
},
}),
],
});2. Use WalletProvider in React
import { WalletProvider } from 'walletkitt-react';
function App() {
return (
<WalletProvider>
<YourApp />
</WalletProvider>
);
}Note:
WalletProviderautomatically uses the singleton instance created bycreateWalletKit. For advanced use cases, you can pass a custom instance via theinstanceprop.
3. Use Wallet Hooks
import { useWallet, useConnect, useAccount } from 'walletkitt-react';
function ConnectButton() {
const { connect, isConnecting } = useConnect();
const { address, chainId, isConnected } = useAccount();
if (isConnected) {
return (
<div>
<p>Connected: {address}</p>
<p>Chain ID: {chainId}</p>
</div>
);
}
return (
<button onClick={connect} disabled={isConnecting}>
{isConnecting ? 'Connecting...' : 'Connect Wallet'}
</button>
);
}4. Access Wallet Information
import { useWallet } from 'walletkitt-react';
function WalletInfo() {
const { address, chainId, walletInfo, ready } = useWallet();
if (!ready) {
return <div>Loading...</div>;
}
return (
<div>
{address && (
<>
<p>Address: {address}</p>
<p>Chain ID: {chainId}</p>
<p>Wallet: {walletInfo?.name}</p>
</>
)}
</div>
);
}5. Sign Messages and Send Transactions
import { useWallet } from 'walletkitt-react';
function WalletActions() {
const { signMessage, sendTransaction, switchChain } = useWallet();
const handleSign = async () => {
const signature = await signMessage({ message: 'Hello Web3!' });
console.log('Signature:', signature);
};
const handleSend = async () => {
const txHash = await sendTransaction({
to: '0x...',
value: '1000000000000000000', // 1 ETH in wei
});
console.log('Transaction hash:', txHash);
};
const handleSwitchChain = async () => {
await switchChain({ chainId: 137 }); // Switch to Polygon
};
return (
<div>
<button onClick={handleSign}>Sign Message</button>
<button onClick={handleSend}>Send Transaction</button>
<button onClick={handleSwitchChain}>Switch to Polygon</button>
</div>
);
}Adapter Configurations
Privy Adapter
Installation:
npm install @privy-io/react-authUsage:
import { PrivyAdapter } from 'walletkitt-react';
const privyAdapter = new PrivyAdapter(
{
appId: 'your-privy-app-id',
clientId: 'your-client-id', // optional
config: {
appearance: {
theme: 'light',
accentColor: '#676FFF',
},
loginMethods: ['wallet', 'email'],
embeddedWallets: {
createOnLogin: 'users-without-wallets',
},
},
},
{
// Optional callbacks
onConnect: (address) => console.log('Connected:', address),
onDisconnect: () => console.log('Disconnected'),
}
);Note: With Privy, wallet state is automatically synchronized from Privy's authentication system. The adapter includes automatic reconnection prevention on explicit disconnect to avoid unwanted auto-reconnections after page refresh.
Reown Adapter
Installation:
npm install @reown/appkit @reown/appkit-adapter-ethersUsage:
import { ReownAdapter } from 'walletkitt-react';
const reownAdapter = new ReownAdapter({
projectId: 'your-reown-project-id',
chains: [1, 137], // Note: chains are also specified in createWalletKit
metadata: {
name: 'My App',
description: 'My Web3 App',
url: 'https://myapp.com',
icons: ['https://myapp.com/icon.png'],
},
enableAnalytics: true,
enableOnramp: true,
});Available Hooks
useWallet()
Main hook that provides access to all wallet functionality.
const {
// State
isConnected,
isConnecting,
ready, // Indicates if the wallet is initialized
address,
chainId,
provider, // Current wallet provider (privy/reown)
blockchainProvider, // ethers.provider instance
walletInfo, // Wallet name, icon, and type
error,
// Methods
connect,
disconnect,
signMessage,
sendTransaction,
switchChain,
switchProvider, // Switch between configured providers (if multiple)
} = useWallet();useConnect()
Hook for connecting to wallet.
const { connect, isConnecting } = useConnect();useDisconnect()
Hook for disconnecting wallet.
const { disconnect, isConnected } = useDisconnect();useAccount()
Hook for accessing account information.
const { address, chainId, isConnected, walletInfo } = useAccount();Key Concepts
Wallet Provider vs Blockchain Provider
This package makes a clear distinction between:
- Wallet Provider (WalletConnect, Privy, Reown): The connection layer for authenticating and managing user wallets
- Blockchain Provider (ethers.provider, viem): The RPC layer for interacting with blockchain networks
The blockchainProvider field in wallet state can hold your ethers provider or viem client for blockchain interactions.
Wallet State Management
The package maintains a reactive wallet state that includes:
- Connection Status:
isConnected,isConnecting,ready - Account Info:
address,chainId,walletInfo(name, icon, type) - Providers:
provider(wallet provider type),blockchainProvider(ethers instance) - Errors: Automatic error handling and state updates
State is automatically synchronized across all hooks and components.
Auto-reconnection Behavior
- Privy: Automatically restores wallet connection on page refresh unless user explicitly disconnected
- Reown: Follows Reown's built-in reconnection logic
- Explicit disconnection sets a localStorage flag to prevent unwanted auto-reconnection
Adding Custom Providers
Extend the BaseWalletProvider class to add new providers:
import { BaseWalletProvider } from 'walletkitt-react';
class CustomAdapter extends BaseWalletProvider {
async connect(): Promise<string> {
// Your implementation
const address = await yourCustomWallet.connect();
this.handleConnect(address, chainId);
return address;
}
async disconnect(): Promise<void> {
await yourCustomWallet.disconnect();
this.handleDisconnect();
}
async getAddress(): Promise<string | null> {
return this.currentAddress;
}
async getChainId(): Promise<number | null> {
return this.currentChainId;
}
async signMessage(params: { message: string }): Promise<string> {
return await yourCustomWallet.signMessage(params.message);
}
async sendTransaction(params: SendTransactionParams): Promise<string> {
return await yourCustomWallet.sendTransaction(params);
}
async switchChain(params: { chainId: number }): Promise<void> {
await yourCustomWallet.switchChain(params.chainId);
}
}TypeScript Support
The package is fully typed. Import types as needed:
import type {
WalletState,
ProviderType,
ProvidersConfig,
WalletConnectConfig,
PrivyConfig,
ReownConfig,
SignMessageParams,
SendTransactionParams,
SwitchChainParams,
WalletAdapter,
} from 'walletkitt-react';Advanced Usage
Adapter Lifecycle Events
import { PrivyAdapter } from 'walletkitt-react';
const privyAdapter = new PrivyAdapter(
{ appId: 'your-app-id' },
{
// Lifecycle callbacks
onConnect: (address: string) => console.log('Connected:', address),
onDisconnect: () => console.log('Disconnected'),
onAccountsChanged: (accounts: string[]) =>
console.log('Accounts:', accounts),
onChainChanged: (chainId: number) => console.log('Chain:', chainId),
onError: (error: Error) => console.error('Error:', error),
}
);Error Handling
const { connect, error } = useWallet();
const handleConnect = async () => {
try {
await connect();
} catch (err) {
console.error('Connection failed:', err);
}
};
if (error) {
return <div>Error: {error.message}</div>;
}API Reference
createWalletKit()
function createWalletKit(config: WalletKitConfig): WalletKit;
interface WalletKitConfig {
chains: ChainId[];
metadata: WalletKitMetadata;
adapters: WalletAdapter[];
}
interface WalletKitMetadata {
name: string;
description: string;
url: string;
icons: string[];
}WalletProvider
interface WalletProviderProps {
children: React.ReactNode;
instance?: WalletKit; // Optional custom instance
}Wallet Adapters
class PrivyAdapter extends BaseWalletProvider {
constructor(config: PrivyConfig, options?: BaseProviderOptions);
}
class ReownAdapter extends BaseWalletProvider {
constructor(config: ReownConfig, options?: BaseProviderOptions);
}WalletState
interface WalletState {
isConnected: boolean;
isConnecting: boolean;
address: string | null;
chainId: number | null;
provider: ProviderType | null;
blockchainProvider: any | null; // ethers.provider or viem client
error: Error | null;
}License
MIT
