# 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
