# MetaMask Developer Guide for ChainID 138

Developer guide for integrating ChainID 138 with MetaMask in your dapp.

## Installation

### Using npm

```bash
npm install @defi-oracle/metamask-sdk
```

### Using the source

```bash
cd metamask-sdk
npm install
npm run build
```

## Basic Usage

### Import the SDK

```typescript
import {
  addOrSwitchNetwork,
  addToken,
  isOnChain138,
  getCurrentChainId,
} from '@defi-oracle/metamask-sdk';
```

### Connect to ChainID 138

```typescript
async function connect() {
  try {
    await addOrSwitchNetwork();
    const isOn138 = await isOnChain138();
    if (isOn138) {
      console.log('Connected to ChainID 138');
    }
  } catch (error) {
    console.error('Connection error:', error);
  }
}
```

### Add Token

```typescript
async function addWETHToken() {
  try {
    await addToken(
      '0xYourWETHAddress',
      'WETH',
      18,
      'https://explorer.d-bis.org/images/tokens/weth.png'
    );
  } catch (error) {
    console.error('Token add error:', error);
  }
}
```

## React Integration

### Custom Hook

```typescript
import { useState, useEffect } from 'react';
import { isOnChain138, addOrSwitchNetwork } from '@defi-oracle/metamask-sdk';

function useChain138() {
  const [isConnected, setIsConnected] = useState(false);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    checkConnection();
    
    // Listen for chain changes
    if (window.ethereum) {
      window.ethereum.on('chainChanged', checkConnection);
      return () => {
        window.ethereum.removeListener('chainChanged', checkConnection);
      };
    }
  }, []);

  async function checkConnection() {
    try {
      const on138 = await isOnChain138();
      setIsConnected(on138);
    } catch (error) {
      setIsConnected(false);
    } finally {
      setIsLoading(false);
    }
  }

  async function connect() {
    try {
      await addOrSwitchNetwork();
      await checkConnection();
    } catch (error) {
      console.error('Connection error:', error);
    }
  }

  return { isConnected, isLoading, connect };
}
```

### React Component

```typescript
import React from 'react';
import { useChain138 } from './useChain138';

function Chain138Button() {
  const { isConnected, isLoading, connect } = useChain138();

  if (isLoading) {
    return <button disabled>Loading...</button>;
  }

  if (isConnected) {
    return <button disabled>Connected to ChainID 138</button>;
  }

  return (
    <button onClick={connect}>
      Connect to ChainID 138
    </button>
  );
}
```

## Vue Integration

### Composable

```typescript
import { ref, onMounted, onUnmounted } from 'vue';
import { isOnChain138, addOrSwitchNetwork } from '@defi-oracle/metamask-sdk';

export function useChain138() {
  const isConnected = ref(false);
  const isLoading = ref(true);

  async function checkConnection() {
    try {
      const on138 = await isOnChain138();
      isConnected.value = on138;
    } catch (error) {
      isConnected.value = false;
    } finally {
      isLoading.value = false;
    }
  }

  async function connect() {
    try {
      await addOrSwitchNetwork();
      await checkConnection();
    } catch (error) {
      console.error('Connection error:', error);
    }
  }

  function handleChainChanged() {
    checkConnection();
  }

  onMounted(() => {
    checkConnection();
    if (window.ethereum) {
      window.ethereum.on('chainChanged', handleChainChanged);
    }
  });

  onUnmounted(() => {
    if (window.ethereum) {
      window.ethereum.removeListener('chainChanged', handleChainChanged);
    }
  });

  return { isConnected, isLoading, connect };
}
```

## Error Handling

### Common Errors

```typescript
import { addNetwork } from '@defi-oracle/metamask-sdk';

try {
  await addNetwork();
} catch (error) {
  if (error.message.includes('MetaMask is not installed')) {
    // Handle MetaMask not installed
    alert('Please install MetaMask');
  } else if (error.message.includes('User rejected')) {
    // Handle user rejection
    console.log('User rejected the request');
  } else if (error.code === 4902) {
    // Network already added, try switching
    await switchNetwork();
  } else {
    // Handle other errors
    console.error('Unexpected error:', error);
  }
}
```

## RPC Best Practices

### Rate Limiting

- Default: 1200 requests/minute per IP
- Use request batching when possible
- Implement client-side rate limiting
- Use WebSocket connections for real-time data

### Request Batching

```typescript
const batch = [
  { method: 'eth_blockNumber', params: [] },
  { method: 'eth_gasPrice', params: [] },
  { method: 'eth_getBalance', params: [address, 'latest'] },
];

const results = await Promise.all(
  batch.map(req => window.ethereum.request(req))
);
```

### WebSocket Connections

```typescript
const ws = new WebSocket('wss://rpc.d-bis.org');

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log('Received:', data);
};

ws.send(JSON.stringify({
  jsonrpc: '2.0',
  method: 'eth_subscribe',
  params: ['newHeads'],
  id: 1
}));
```

## Testing

### Mock MetaMask for Testing

```typescript
// mock-metamask.ts
export function createMockMetaMask() {
  return {
    isMetaMask: true,
    request: async (args: { method: string; params?: unknown[] }) => {
      if (args.method === 'eth_chainId') {
        return '0x8a';
      }
      if (args.method === 'wallet_addEthereumChain') {
        return null;
      }
      if (args.method === 'wallet_switchEthereumChain') {
        return null;
      }
      throw new Error('Method not implemented');
    },
    on: () => {},
    removeListener: () => {},
  };
}

// In your tests
global.window.ethereum = createMockMetaMask();
```

## Production Checklist

- [ ] Verify RPC URLs are correct and accessible
- [ ] Test network addition on all target browsers
- [ ] Test token addition for all tokens
- [ ] Verify error handling for all error cases
- [ ] Test network switching functionality
- [ ] Verify chain change event listeners
- [ ] Test on mobile MetaMask
- [ ] Verify token logos are accessible
- [ ] Test with different MetaMask versions
- [ ] Verify CORS headers on RPC endpoints

## References

- [MetaMask SDK Documentation](../../../metamask-sdk/README.md)
- [MetaMask Integration Guide](./METAMASK_INTEGRATION.md)
- [Quick Start Guide](../../../metamask/QUICK_START.md)
- [MetaMask Documentation](https://docs.metamask.io)
