# Chain Configuration Examples

This guide shows how to customize chain configurations (e.g., RPC URLs) without recreating entire `ChainWalletConfig` objects.

## Table of Contents
- [Problem](#problem)
- [Solution](#solution)
- [Single Chain Override](#single-chain-override)
- [Multiple Chain Overrides](#multiple-chain-overrides)
- [Quick RPC URL Override](#quick-rpc-url-override)
- [Get Chain by Name](#get-chain-by-name)
- [Advanced Use Cases](#advanced-use-cases)

---

## Problem

Previously, if you wanted to use your own RPC URL (e.g., your Alchemy API key), you had to recreate the entire chain configuration:

```typescript
// ❌ BAD: Lots of duplication
const ethConfig: ChainWalletConfig = {
    chainId: 1,
    name: "Ethereum",
    rpcUrl: "https://eth-mainnet.g.alchemy.com/v2/MY_KEY", // Only want to change this!
    explorerUrl: "https://etherscan.io",
    nativeToken: { name: "Ether", symbol: "ETH", decimals: 18 },
    testnet: false,
    logoUrl: "https://etherscan.io/images/svg/brands/ethereum-original-light.svg",
    vmType: "EVM",
    savings: {
        supported: true,
        tokens: [/* ... need to know all this! */]
    }
    // Missing other fields might cause issues!
};
```

---

## Solution

New helper functions let you override only what you need:

```typescript
import { getChainConfig, ChainId } from "@deserialize/multi-vm-wallet";

// ✅ GOOD: Override only RPC URL, keep everything else
const ethConfig = getChainConfig(ChainId.ETHEREUM, {
    rpcUrl: "https://eth-mainnet.g.alchemy.com/v2/MY_KEY"
});
```

---

## Single Chain Override

### Basic Usage

```typescript
import { getChainConfig, ChainId, EVMChainWallet } from "@deserialize/multi-vm-wallet";

// Override RPC URL
const ethConfig = getChainConfig(ChainId.ETHEREUM, {
    rpcUrl: "https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY"
});

// Use with wallet
const wallet = new EVMChainWallet(ethConfig, privateKey, 0);

// Get balance
const balance = await wallet.getNativeBalance();
console.log(`Balance: ${balance.formatted} ETH`);
```

### Override Multiple Properties

```typescript
import { getChainConfig, ChainId } from "@deserialize/multi-vm-wallet";

// Override RPC + Account Abstraction config
const baseConfig = getChainConfig(ChainId.BASE, {
    rpcUrl: "https://base-mainnet.g.alchemy.com/v2/YOUR_KEY",
    aaSupport: {
        enabled: true,
        bundlerUrl: "https://api.pimlico.io/v2/8453/rpc?apikey=YOUR_KEY",
        paymasterUrl: "https://your-paymaster.com",
        entryPoints: [
            {
                address: "0x0000000071727De22E5E9d8BAf0edAc6f37da032",
                version: "0.7"
            }
        ],
        kernelImplementations: [
            {
                address: "0xYourKernelAddress",
                version: 3
            }
        ]
    }
});
```

---

## Multiple Chain Overrides

### Using `getMultipleChainConfigs`

```typescript
import {
    getMultipleChainConfigs,
    ChainId,
    EVMVM,
    MultiChainSavingsManager
} from "@deserialize/multi-vm-wallet";

// Configure multiple chains at once
const chains = getMultipleChainConfigs([
    {
        chainId: ChainId.ETHEREUM,
        overrides: {
            rpcUrl: "https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY"
        }
    },
    {
        chainId: ChainId.BSC,
        overrides: {
            rpcUrl: "https://bsc-dataseed.bnbchain.org"
        }
    },
    {
        chainId: ChainId.BASE,
        overrides: {
            rpcUrl: "https://base-mainnet.g.alchemy.com/v2/YOUR_KEY"
        }
    },
    {
        chainId: ChainId.SOLANA,
        overrides: {
            rpcUrl: "https://solana-mainnet.g.alchemy.com/v2/YOUR_KEY"
        }
    }
]);

// Use with multi-chain savings
const vm = EVMVM.fromMnemonic("your mnemonic here");
const savingsManager = new MultiChainSavingsManager(vm, chains);
```

### Using `getCustomizedChains` (Selective Overrides)

```typescript
import {
    getCustomizedChains,
    ChainId
} from "@deserialize/multi-vm-wallet";

// Override only specific chains, keep others as default
const chains = getCustomizedChains({
    [ChainId.ETHEREUM]: {
        rpcUrl: "https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY"
    },
    [ChainId.BASE]: {
        rpcUrl: "https://base-mainnet.g.alchemy.com/v2/YOUR_KEY"
    },
    // BSC, Arbitrum, Optimism, Solana will use default RPC URLs
});

// Returns ALL default chains with your overrides applied
console.log(chains.length); // 6 (all default chains)
```

---

## Quick RPC URL Override

### Single Chain

```typescript
import { withCustomRpc, ChainId, EVMChainWallet } from "@deserialize/multi-vm-wallet";

// Shortest way to override just RPC URL
const ethConfig = withCustomRpc(
    ChainId.ETHEREUM,
    "https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY"
);

const wallet = new EVMChainWallet(ethConfig, privateKey, 0);
```

### Multiple Chains

```typescript
import { withCustomRpcs, ChainId } from "@deserialize/multi-vm-wallet";

// Override RPC URLs for multiple chains
const chains = withCustomRpcs({
    [ChainId.ETHEREUM]: "https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY",
    [ChainId.BSC]: "https://bsc-dataseed.bnbchain.org",
    [ChainId.BASE]: "https://base-mainnet.g.alchemy.com/v2/YOUR_KEY",
    [ChainId.SOLANA]: "https://solana-mainnet.g.alchemy.com/v2/YOUR_KEY"
});

// Use the configured chains
const [ethConfig, bscConfig, baseConfig, solConfig] = chains;
```

---

## Get Chain by Name

```typescript
import { getChainByName } from "@deserialize/multi-vm-wallet";

// Get chain by name (case-insensitive)
const ethConfig = getChainByName("Ethereum", {
    rpcUrl: "https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY"
});

const baseConfig = getChainByName("base", {
    rpcUrl: "https://base-mainnet.g.alchemy.com/v2/YOUR_KEY"
});

const solConfig = getChainByName("Solana", {
    rpcUrl: "https://solana-mainnet.g.alchemy.com/v2/YOUR_KEY"
});
```

---

## Advanced Use Cases

### Multi-Chain Wallet Application

```typescript
import {
    EVMVM,
    SVMVM,
    EVMChainWallet,
    SVMChainWallet,
    getMultipleChainConfigs,
    ChainId
} from "@deserialize/multi-vm-wallet";

const mnemonic = "your twelve word seed phrase here...";

// Configure all chains with your RPC URLs
const chains = getMultipleChainConfigs([
    {
        chainId: ChainId.ETHEREUM,
        overrides: { rpcUrl: process.env.ETH_RPC_URL! }
    },
    {
        chainId: ChainId.BASE,
        overrides: { rpcUrl: process.env.BASE_RPC_URL! }
    },
    {
        chainId: ChainId.SOLANA,
        overrides: { rpcUrl: process.env.SOLANA_RPC_URL! }
    }
]);

// Create VMs
const evmVm = EVMVM.fromMnemonic(mnemonic);
const svmVm = SVMVM.fromMnemonic(mnemonic);

// Create wallets for each chain
const wallets = chains.map((chainConfig, index) => {
    if (chainConfig.vmType === "EVM") {
        const { privateKey } = evmVm.generatePrivateKey(0);
        return new EVMChainWallet(chainConfig, privateKey, 0);
    } else {
        const { privateKey } = svmVm.generatePrivateKey(0);
        return new SVMChainWallet(chainConfig, privateKey, 0);
    }
});

// Get balances across all chains
const balances = await Promise.all(
    wallets.map(async (wallet) => ({
        chain: wallet.config.name,
        balance: await wallet.getNativeBalance()
    }))
);

console.log(balances);
```

### Environment-Based Configuration

```typescript
import { getCustomizedChains, ChainId } from "@deserialize/multi-vm-wallet";

// Read RPC URLs from environment variables
const chains = getCustomizedChains({
    [ChainId.ETHEREUM]: {
        rpcUrl: process.env.ETH_RPC_URL || "https://eth.llamarpc.com"
    },
    [ChainId.BASE]: {
        rpcUrl: process.env.BASE_RPC_URL || "https://mainnet.base.org"
    },
    [ChainId.BSC]: {
        rpcUrl: process.env.BSC_RPC_URL || "https://bsc-dataseed.binance.org/"
    },
    [ChainId.SOLANA]: {
        rpcUrl: process.env.SOLANA_RPC_URL || "https://api.mainnet-beta.solana.com"
    }
});

// Chains not specified will use defaults
export default chains;
```

### Smart Wallet with Custom Bundler

```typescript
import {
    getChainConfig,
    ChainId,
    EVMChainWallet,
    EVMVM
} from "@deserialize/multi-vm-wallet";

const baseConfig = getChainConfig(ChainId.BASE, {
    rpcUrl: process.env.BASE_RPC_URL!,
    aaSupport: {
        enabled: true,
        bundlerUrl: process.env.BUNDLER_URL!,
        paymasterUrl: process.env.PAYMASTER_URL!,
        entryPoints: [
            {
                address: "0x0000000071727De22E5E9d8BAf0edAc6f37da032",
                version: "0.7"
            }
        ],
        kernelImplementations: [
            {
                address: "0xd3082872F8B06073A021b4602e022d5A070d7cfC",
                version: 3
            }
        ]
    }
});

const vm = EVMVM.fromMnemonic(process.env.MNEMONIC!);
const { privateKey } = vm.generatePrivateKey(0);
const wallet = new EVMChainWallet(baseConfig, privateKey, 0);

// Create smart wallet with custom bundler
const smartWallet = await wallet.createSmartWallet({
    sponsored: true // Use paymaster for gas
});

// Send batch transaction
const result = await smartWallet.sendBatchTransaction([
    {
        to: "0x...",
        value: BigInt(0),
        data: "0x..."
    },
    {
        to: "0x...",
        value: BigInt(0),
        data: "0x..."
    }
]);
```

### Testing with Local RPC

```typescript
import { getChainConfig, ChainId } from "@deserialize/multi-vm-wallet";

// Use local Hardhat/Anvil node for testing
const localEthConfig = getChainConfig(ChainId.ETHEREUM, {
    rpcUrl: "http://localhost:8545"
});

// Use testnet
const sepoliaConfig = getChainConfig(11155111, {
    rpcUrl: "https://sepolia.infura.io/v3/YOUR_KEY"
});
```

---

## Chain ID Reference

Use the `ChainId` constant instead of hardcoding numbers:

```typescript
import { ChainId } from "@deserialize/multi-vm-wallet";

console.log(ChainId.ETHEREUM);  // 1
console.log(ChainId.BSC);       // 56
console.log(ChainId.BASE);      // 8453
console.log(ChainId.ARBITRUM);  // 42161
console.log(ChainId.OPTIMISM);  // 10
console.log(ChainId.SOLANA);    // 123456789
```

---

## Best Practices

1. **Use Environment Variables for Sensitive Data**
   ```typescript
   const config = getChainConfig(ChainId.ETHEREUM, {
       rpcUrl: process.env.ETH_RPC_URL! // Don't hardcode API keys
   });
   ```

2. **Use ChainId Constants**
   ```typescript
   // ✅ Good
   getChainConfig(ChainId.ETHEREUM, {...})

   // ❌ Bad
   getChainConfig(1, {...})
   ```

3. **Validate Chain IDs**
   ```typescript
   try {
       const config = getChainConfig(999999, {...});
   } catch (error) {
       console.error("Chain not found:", error.message);
       // Error includes available chains
   }
   ```

4. **Reuse Configurations**
   ```typescript
   // Configure once
   const chains = withCustomRpcs({
       [ChainId.ETHEREUM]: process.env.ETH_RPC_URL!,
       [ChainId.BASE]: process.env.BASE_RPC_URL!,
   });

   // Export and reuse across your app
   export { chains };
   ```

---

## Migration Guide

If you're currently using hardcoded configs:

### Before
```typescript
const config: ChainWalletConfig = {
    chainId: 1,
    name: "Ethereum",
    rpcUrl: "https://eth-mainnet.g.alchemy.com/v2/MY_KEY",
    explorerUrl: "https://etherscan.io",
    nativeToken: { name: "Ether", symbol: "ETH", decimals: 18 },
    testnet: false,
    logoUrl: "...",
    vmType: "EVM",
    savings: { /* ... */ }
};
```

### After
```typescript
import { getChainConfig, ChainId } from "@deserialize/multi-vm-wallet";

const config = getChainConfig(ChainId.ETHEREUM, {
    rpcUrl: "https://eth-mainnet.g.alchemy.com/v2/MY_KEY"
});
```

**Benefits:**
- Less code
- No risk of missing fields
- Automatic updates when defaults change
- Type-safe
