unich-web3-sdk
Version:
Web3 SDK for DEX applications with multi-chain support
554 lines (422 loc) • 13.8 kB
Markdown
# Web3 SDK
A comprehensive Web3 SDK for DEX applications with multi-chain support. This package provides a unified interface for interacting with various blockchain networks and wallet providers.
## Features
### Chains Management
- Support for multiple blockchain networks (EVM, SVM, BitLayer, etc.)
- Easy to add new chains and networks
- Support for testnet chains and networks
- Unified API for cross-chain interactions
### Wallet Connector
- Configurable wallet adapters
- Easy to add new supported wallets
- Custom UI connect wallet modal
- Seamless chain switching
- Persistent connection state using Zustand
## Installation
```bash
npm install unich-web3-sdk
# or
yarn add unich-web3-sdk
# or
pnpm add unich-web3-sdk
```
## Next.js Integration
This SDK is fully compatible with Next.js 13+ applications. Here's how to use it:
1. Install the package:
```bash
npm install unich-web3-sdk
```
2. Create a client component (required for Web3 functionality):
```tsx
'use client';
import { useWallet } from 'unich-web3-sdk';
export default function Web3Component() {
const { connect, disconnect, isConnected, address } = useWallet();
return (
<div>
{!isConnected ? (
<button onClick={() => connect()}>Connect Wallet</button>
) : (
<button onClick={() => disconnect()}>Disconnect</button>
)}
</div>
);
}
```
3. For server components, you can import non-interactive utilities:
```tsx
import { formatAddress } from 'unich-web3-sdk';
export default function ServerComponent() {
return <div>Static Web3 Content</div>;
}
```
### Important Notes for Next.js
- All components that use Web3 functionality must be marked with `'use client'` directive
- The SDK automatically handles hydration and SSR compatibility
- Use the hooks provided by the SDK for client-side Web3 interactions
- For server components, only use non-interactive utilities and types
## Quick Start
```tsx
import { Web3Provider, useWeb3 } from "unich-web3-sdk";
// Wrap your app with the provider
function App() {
return (
<Web3Provider>
<YourApp />
</Web3Provider>
);
}
// Use the hook in your components
function YourApp() {
const { connect, disconnect, account, chain, switchChain } = useWeb3();
return (
<div>
{account ? (
<>
<p>Connected to {account}</p>
<p>Current chain: {chain.name}</p>
<button onClick={disconnect}>Disconnect</button>
<button onClick={() => switchChain("ethereum")}>Switch to Ethereum</button>
</>
) : (
<button onClick={connect}>Connect Wallet</button>
)}
</div>
);
}
```
### Using with Next.js
This package is fully compatible with Next.js, including the App Router. All components are properly marked with the "use client" directive.
#### Next.js App Router
When using the App Router in Next.js 13+, you can use the SDK in your client components:
```tsx
// app/providers.tsx
"use client";
import { Web3Provider } from "unich-web3-sdk";
export function Providers({ children }: { children: React.ReactNode }) {
return <Web3Provider>{children}</Web3Provider>;
}
```
```tsx
// app/layout.tsx
import { Providers } from "./providers";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<Providers>{children}</Providers>
</body>
</html>
);
}
```
```tsx
// app/wallet/page.tsx
"use client";
import { useWeb3 } from "unich-web3-sdk";
export default function WalletPage() {
const { connect, disconnect, account, chain } = useWeb3();
return (
<div>
{account ? (
<>
<p>Connected to {account}</p>
<p>Current chain: {chain?.name || "Unknown"}</p>
<button onClick={disconnect}>Disconnect</button>
</>
) : (
<button onClick={connect}>Connect Wallet</button>
)}
</div>
);
}
```
#### Next.js Pages Router
For the Pages Router, you can wrap your app in `_app.tsx`:
```tsx
// pages/_app.tsx
import type { AppProps } from "next/app";
import { Web3Provider } from "unich-web3-sdk";
export default function App({ Component, pageProps }: AppProps) {
return (
<Web3Provider>
<Component {...pageProps} />
</Web3Provider>
);
}
```
## Developer Guide
### Architecture Overview
The Web3 SDK is built with a modular architecture that consists of the following components:
1. **Chain Adapters**: Implementations for different blockchain types (EVM, SVM, BitLayer)
2. **Wallet Connectors**: Implementations for different wallet providers (MetaMask, Phantom)
3. **State Management**: Zustand store for managing connection state
4. **React Components**: Provider and hooks for easy integration with React applications
### Core Concepts
#### Chain Types
The SDK supports multiple blockchain types:
```typescript
export enum ChainType {
EVM = "evm", // Ethereum Virtual Machine
SVM = "svm", // Solana Virtual Machine
BITLAYER = "bitlayer",
}
```
#### Network Types
Different network environments are supported:
```typescript
export enum NetworkType {
MAINNET = "mainnet",
TESTNET = "testnet",
DEVNET = "devnet",
}
```
#### Chain Configuration
Each blockchain network is defined with a configuration:
```typescript
export interface ChainConfig {
id: string | number; // Chain ID (number for EVM, string for others)
name: string; // Display name
type: ChainType; // Chain type (EVM, SVM, etc.)
networkType: NetworkType; // Network type (mainnet, testnet, etc.)
rpcUrls: string[]; // RPC endpoints
nativeCurrency: {
name: string;
symbol: string;
decimals: number;
};
blockExplorerUrls?: string[]; // Block explorer URLs
iconUrl?: string; // Chain icon URL
testnet?: boolean; // Is testnet
}
```
### Using the SDK
#### Setting Up the Provider
Wrap your application with the `Web3Provider` component:
```tsx
import { Web3Provider } from "web3-sdk";
function App() {
return (
<Web3Provider config={{
autoConnect: true, // Automatically connect if previously connected
defaultChain: 1, // Default chain ID to connect to
}}>
<YourApp />
</Web3Provider>
);
}
```
#### Using the Web3 Hook
Access web3 functionality in your components:
```tsx
import { useWeb3Context } from "web3-sdk";
function WalletInfo() {
const {
// Connection state
account, // Connected account address
chainId, // Current chain ID
chain, // Current chain configuration
status, // Connection status
error, // Error if any
// Connection status helpers
isConnected, // Is wallet connected
isConnecting, // Is connecting in progress
isDisconnected, // Is wallet disconnected
isError, // Is there an error
// Actions
connect, // Connect to wallet
disconnect, // Disconnect from wallet
switchChain, // Switch to a different chain
// Utilities
getAvailableConnectors, // Get available wallet connectors
} = useWeb3Context();
// Your component logic
}
```
#### Using the Connect Wallet Button
The SDK provides a ready-to-use button component:
```tsx
import { ConnectWalletButton } from "web3-sdk";
function ConnectButton() {
return (
<ConnectWalletButton
onConnect={(account) => console.log(`Connected to ${account}`)}
onError={(error) => console.error("Connection error:", error)}
chainId={1} // Optional: Connect to a specific chain
className="your-custom-class"
>
Connect Wallet
</ConnectWalletButton>
);
}
```
### Advanced Usage
#### Adding Custom Chains
You can add custom chains to the SDK:
```typescript
import { ChainConfig, ChainType, NetworkType } from "web3-sdk";
const myCustomChain: ChainConfig = {
id: 12345,
name: "My Custom Chain",
type: ChainType.EVM,
networkType: NetworkType.MAINNET,
rpcUrls: ["https://my-custom-chain-rpc.com"],
nativeCurrency: {
name: "Custom Token",
symbol: "CTK",
decimals: 18,
},
blockExplorerUrls: ["https://explorer.my-custom-chain.com"],
iconUrl: "https://my-custom-chain.com/logo.png",
};
// Then you can use it with switchChain
const { switchChain } = useWeb3Context();
switchChain(myCustomChain.id);
```
#### Viem Integration for EVM Chains
This SDK uses [Viem](https://viem.sh/) for EVM chain interactions, providing a robust and reliable way to interact with EVM-compatible blockchains:
```typescript
import { useWeb3Context } from "web3-sdk";
import { EVMChainAdapter } from "web3-sdk/chains";
import { parseEther } from "viem";
function EVMInteractions() {
const { account, chain } = useWeb3Context();
const sendTransaction = async () => {
if (chain?.type === ChainType.EVM) {
const evmAdapter = getChainAdapter(ChainType.EVM) as EVMChainAdapter;
// Get the wallet client for signing transactions
const walletClient = evmAdapter.getWalletClient(chain);
if (walletClient) {
// Send a transaction
const hash = await walletClient.sendTransaction({
to: '0x...',
value: parseEther('0.01')
});
console.log(`Transaction sent: ${hash}`);
}
}
};
return (
<div>
{account && chain?.type === ChainType.EVM && (
<button onClick={sendTransaction}>Send Transaction</button>
)}
</div>
);
}
```
The SDK directly integrates Viem for EVM chains, providing:
- High-performance blockchain interactions
- Type-safe API for EVM operations
- Better handling of wallet events (account changes, chain changes)
- Consistent error handling
- Support for multiple EVM chains through MetaMask
### Troubleshooting
#### Common Issues
1. **Wallet Not Connecting**
- Check if the wallet extension is installed
- Ensure the wallet supports the chain you're trying to connect to
- Check browser console for errors
2. **Chain Switching Fails**
- Some wallets don't support programmatic chain switching
- The chain might need to be added to the wallet first
3. **"Request Already Pending" Error**
- This occurs when multiple wallet requests are made simultaneously
- The SDK handles this by debouncing requests and providing clear error messages
- If you encounter this error, check your wallet extension for pending requests
- Error code: `-32002` with message like "Request of type 'wallet_requestPermissions' already pending"
- Solution: Wait for the pending request to be resolved in the wallet extension
4. **React Hooks Error**
- Ensure you're using the hooks within the Web3Provider context
- Check that you're not violating React hooks rules
#### Error Handling
The SDK provides error information through the `error` property:
```tsx
const { error, isError } = useWeb3Context();
if (isError && error) {
console.error("Web3 error:", error.message);
// Handle the error appropriately
}
```
## API Reference
### Components
#### `Web3Provider`
Props:
- `children`: React nodes
- `config`: (Optional) Configuration object
- `autoConnect`: Boolean to enable auto-connection
- `defaultChain`: Default chain ID to connect to
- `connectors`: Array of custom connectors
- `chains`: Array of custom chains
#### `ConnectWalletButton`
Props:
- `onConnect`: Callback when connection is successful
- `onError`: Callback when connection fails
- `chainId`: Optional chain ID to connect to
- `className`: CSS class name
- `children`: Button content
### Hooks
#### `useWeb3Context`
Returns the web3 context with all state and actions.
#### `useWeb3`
Lower-level hook that provides direct access to the web3 store.
### Types
The SDK exports all types for TypeScript integration:
- `ChainType`: Enum of supported chain types
- `NetworkType`: Enum of supported network types
- `ChainConfig`: Interface for chain configuration
- `ConnectorStatus`: Enum of connection statuses
- `Connector`: Interface for wallet connectors
## Project Structure
```
src/
├── chains/ # Chain adapters and configurations
│ ├── evm.ts # EVM chain adapter
│ ├── svm.ts # Solana chain adapter
│ ├── bitlayer.ts # BitLayer chain adapter
│ ├── mainnet.ts # Mainnet chain configurations
│ ├── testnet.ts # Testnet chain configurations
│ └── index.ts # Chain exports and utilities
├── connectors/ # Wallet connectors
│ ├── base.ts # Base connector class
│ ├── metamask.ts # MetaMask connector
│ ├── phantom.ts # Phantom connector
│ └── index.ts # Connector exports and utilities
├── components/ # React components
│ └── Web3Provider.tsx # Web3 provider component
├── hooks/ # React hooks
│ └── useWeb3.ts # Web3 hook
├── store/ # State management
│ └── web3Store.ts # Zustand store for web3 state
├── types/ # TypeScript types
│ ├── chain.ts # Chain-related types
│ ├── connector.ts # Connector-related types
│ └── index.ts # Type exports
└── index.ts # Main entry point
```
## Development
### Building the Package
```bash
# Install dependencies
npm install
# Build the package
npm run build
# Run in development mode with watch
npm run dev
```
### Testing
```bash
# Run tests
npm test
```
### Linting
```bash
# Run linter
npm run lint
```
## License
MIT