npm package: @stochain/provider-manager
Description: Blockchain provider manager with multi-RPC failover and network switching
Author: Stochain
Latest version: 1.0.0

# @stochain/provider-manager

Blockchain provider manager with multi-RPC failover and automatic network switching.

## Installation

```bash
npm install @stochain/provider-manager ethers
```

## Features

- 🌐 Multi-network support (BSC, Ethereum, Polygon)
- 🔄 Automatic RPC failover
- ⚡ Connection health monitoring
- 🔌 Simple provider interface
- 📊 Gas price and estimation
- 🔁 Automatic retry with backoff
- ⚙️ Configurable timeout and retries

## Usage

### Basic Setup

```typescript
import { ProviderManager } from '@stochain/provider-manager';

// Create manager
const manager = new ProviderManager({
  timeout: 10000,    // 10 seconds
  retries: 3,        // 3 retry attempts
  retryDelay: 1000   // 1 second delay between retries
});

// Switch to network
await manager.switchNetwork('BSC_MAINNET');

// Get provider
const provider = manager.getProvider();
```

### Network Switching

```typescript
// Switch to different networks
await manager.switchNetwork('BSC_MAINNET');
await manager.switchNetwork('BSC_TESTNET');
await manager.switchNetwork('ETHEREUM_MAINNET');
await manager.switchNetwork('POLYGON_MAINNET');

// Get current network info
const network = await manager.getNetwork();
console.log('Chain ID:', network.chainId);
console.log('Network name:', network.name);
```

### Provider Operations

```typescript
// Get gas price
const gasPrice = await manager.getGasPrice();

// Estimate gas
const gasEstimate = await manager.estimateGas({
  to: '0x...',
  data: '0x...'
});

// Get balance
const balance = await manager.getBalance('0x...');

// Get block number
const blockNumber = await manager.getBlockNumber();

// Get transaction
const tx = await manager.getTransaction('0x...');

// Wait for transaction
const receipt = await manager.waitForTransaction('0x...', 1);
```

### With Wallet

```typescript
import { ProviderManager } from '@stochain/provider-manager';
import { ethers } from 'ethers';

const manager = new ProviderManager();
await manager.switchNetwork('BSC_MAINNET');

// Connect wallet to provider
const wallet = new ethers.Wallet('private-key', manager.getProvider());

// Send transaction
const tx = await wallet.sendTransaction({
  to: '0x...',
  value: ethers.utils.parseEther('0.1')
});

await tx.wait();
```

### Network Utilities

```typescript
import {
  listNetworks,
  getNetworkConfig,
  getNetworkByChainId
} from '@stochain/provider-manager';

// List all networks
const networks = listNetworks();
// ['BSC_MAINNET', 'BSC_TESTNET', 'ETHEREUM_MAINNET', 'POLYGON_MAINNET']

// Get network config
const bscConfig = getNetworkConfig('BSC_MAINNET');
console.log(bscConfig.chainId);      // 56
console.log(bscConfig.rpcUrls);      // [...multiple RPCs]

// Get network by chain ID
const network = getNetworkByChainId(56);
console.log(network?.name);          // 'BSC Mainnet'
```

### Custom Network

```typescript
import { ProviderManager } from '@stochain/provider-manager';
import { NETWORKS } from '@stochain/provider-manager';

// Add custom network
NETWORKS['MY_NETWORK'] = {
  name: 'My Custom Network',
  chainId: 12345,
  rpcUrls: [
    'https://rpc1.mynetwork.com',
    'https://rpc2.mynetwork.com'
  ],
  nativeCurrency: {
    name: 'My Token',
    symbol: 'MTK',
    decimals: 18
  },
  blockExplorerUrls: ['https://explorer.mynetwork.com']
};

// Use custom network
const manager = new ProviderManager();
await manager.switchNetwork('MY_NETWORK');
```

### Error Handling

```typescript
try {
  await manager.switchNetwork('BSC_MAINNET');
} catch (error) {
  console.error('Failed to connect:', error);
  // All RPCs failed
}

// Check if ready
if (manager.isReady()) {
  const balance = await manager.getBalance('0x...');
}
```

### Advanced Usage

```typescript
// Automatic failover
// If first RPC fails, automatically tries next
await manager.switchNetwork('BSC_MAINNET');
// Tries:
// 1. https://bsc-dataseed1.binance.org/
// 2. https://bsc-dataseed2.binance.org/
// 3. https://bsc-dataseed3.binance.org/
// 4. https://bsc-dataseed4.binance.org/

// Custom options
const manager = new ProviderManager({
  timeout: 5000,     // 5 second timeout
  retries: 5,        // 5 retry attempts
  retryDelay: 2000   // 2 second delay
});

// Get current network
const currentNetwork = manager.getCurrentNetwork();
if (currentNetwork) {
  console.log('Connected to:', currentNetwork.name);
  console.log('Chain ID:', currentNetwork.chainId);
  console.log('Explorer:', currentNetwork.blockExplorerUrls[0]);
}
```

## Supported Networks

| Network | Chain ID | Name |
|---------|----------|------|
| BSC_MAINNET | 56 | BSC Mainnet |
| BSC_TESTNET | 97 | BSC Testnet |
| ETHEREUM_MAINNET | 1 | Ethereum Mainnet |
| POLYGON_MAINNET | 137 | Polygon Mainnet |

## API Reference

### ProviderManager

**Constructor:**
- `new ProviderManager(options?)`: Create new manager

**Methods:**
- `switchNetwork(networkName)`: Switch to network with failover
- `getProvider()`: Get current provider instance
- `getCurrentNetwork()`: Get current network config
- `getNetwork()`: Get ethers network info
- `getGasPrice()`: Get current gas price
- `estimateGas(tx)`: Estimate gas for transaction
- `getBlockNumber()`: Get latest block number
- `getBalance(address)`: Get address balance
- `getTransaction(txHash)`: Get transaction details
- `getTransactionReceipt(txHash)`: Get transaction receipt
- `waitForTransaction(txHash, confirmations?, timeout?)`: Wait for tx
- `call(tx)`: Call contract method (read-only)
- `sendTransaction(signedTx)`: Send signed transaction
- `isReady()`: Check if provider is initialized

### Network Utilities

- `listNetworks()`: List all available networks
- `getNetworkConfig(name)`: Get network configuration
- `getNetworkByChainId(chainId)`: Find network by chain ID

## Types

```typescript
interface NetworkConfig {
  name: string;
  chainId: number;
  rpcUrls: string[];
  nativeCurrency: {
    name: string;
    symbol: string;
    decimals: number;
  };
  blockExplorerUrls: string[];
}

interface ProviderOptions {
  timeout?: number;
  retries?: number;
  retryDelay?: number;
}
```

## License

MIT