# Multi-Chain Savings Manager - Usage Guide

**Status**: ✅ **Implementation Complete**
**Date**: 2026-02-02

---

## 🎉 What's Been Implemented

Following the same pattern as EVM/SVM VM classes, we've implemented a complete multi-chain savings manager system:

### Files Created

```
utils/savings/
├── savings-manager.ts       # Abstract base class
├── evm-savings.ts           # EVM implementation (Ethereum, Polygon, BSC, etc.)
├── svm-savings.ts           # Solana implementation
├── multi-chain-savings.ts   # Multi-chain orchestrator
└── index.ts                 # Updated exports
```

### Architecture

```typescript
// Abstract base (like VM class)
abstract class SavingsManager<AddressType, ClientType, WalletClientType>

↓

// EVM implementation
EVMSavingsManager extends SavingsManager<Hex, PublicClient, WalletClient>

// Solana implementation
SVMSavingsManager extends SavingsManager<PublicKey, Connection, Keypair>

↓

// Multi-chain orchestrator
MultiChainSavingsManager (manages both EVM and SVM)
```

---

## 📖 Usage Examples

### Example 1: Single EVM Chain (Ethereum)

```typescript
import { EVMSavingsManager } from './utils/savings';

const manager = new EVMSavingsManager(
    mnemonic,
    {
        chainId: 1,
        name: 'ethereum',
        rpcUrl: 'https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY'
    },
    0  // wallet index
);

// Get pocket 0
const pocket = manager.getPocket(0);
console.log('Pocket address:', pocket.address);
console.log('Derivation path:', pocket.derivationPath);

// Get balances for pocket 0
const balances = await manager.getPocketBalance(0, [
    '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'  // USDC
]);

console.log('Native ETH:', balances[0].balance.formatted);
console.log('USDC:', balances[1].balance.formatted);

// Transfer 0.1 ETH to pocket 0
await manager.transferToPocket(walletClient, 0, '0.1');

// Transfer from pocket back to main wallet
await manager.sendToMainWallet(0, 100000000n, 'native');

// Cleanup
manager.dispose();
```

---

### Example 2: Solana (SVM)

```typescript
import { SVMSavingsManager } from './utils/savings';
import { Keypair } from '@solana/web3.js';

const manager = new SVMSavingsManager(
    mnemonic,
    'https://api.mainnet-beta.solana.com',
    0  // wallet index
);

// Get pocket 0
const pocket = manager.getPocket(0);
console.log('Pocket address:', pocket.address.toBase58());
console.log('Derivation path:', pocket.derivationPath);

// Get balances for pocket 0
const balances = await manager.getPocketBalance(0, [
    'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'  // USDC on Solana
]);

console.log('Native SOL:', balances[0].balance.formatted);
console.log('USDC:', balances[1].balance.formatted);

// Transfer 1 SOL to pocket 0
const mainWalletKeypair = manager.getMainWallet().privateKey;
await manager.transferToPocket(mainWalletKeypair, 0, 1000000000n);  // 1 SOL

// Transfer SPL token
await manager.transferTokenToPocket(
    mainWalletKeypair,
    { address: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', decimals: 6 },
    0,
    1000000n  // 1 USDC
);

// Cleanup
manager.dispose();
```

---

### Example 3: Multi-Chain (The Full Power!)

```typescript
import { MultiChainSavingsManager } from './utils/savings';

// Create manager with multiple chains
const manager = new MultiChainSavingsManager(
    mnemonic,
    [
        // EVM chains
        {
            id: 'ethereum',
            type: 'EVM',
            config: {
                chainId: 1,
                name: 'ethereum',
                rpcUrl: 'https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY'
            }
        },
        {
            id: 'polygon',
            type: 'EVM',
            config: {
                chainId: 137,
                name: 'polygon',
                rpcUrl: 'https://polygon-mainnet.g.alchemy.com/v2/YOUR_KEY'
            }
        },
        {
            id: 'bsc',
            type: 'EVM',
            config: {
                chainId: 56,
                name: 'bsc',
                rpcUrl: 'https://bsc-dataseed1.binance.org'
            }
        },
        // Solana
        {
            id: 'solana',
            type: 'SVM',
            config: {
                rpcUrl: 'https://api.mainnet-beta.solana.com'
            }
        }
    ],
    0  // wallet index
);

// Get pocket addresses (notice EVM chains share addresses!)
const ethAddress = manager.getPocketAddress('ethereum', 0);
const polyAddress = manager.getPocketAddress('polygon', 0);
const bscAddress = manager.getPocketAddress('bsc', 0);
const solAddress = manager.getPocketAddress('solana', 0);

console.log('Ethereum pocket 0:', ethAddress);
console.log('Polygon pocket 0:', polyAddress);
console.log('BSC pocket 0:', bscAddress);
console.log('Solana pocket 0:', solAddress);

console.log('ETH === Polygon?', ethAddress === polyAddress);  // true!
console.log('ETH === BSC?', ethAddress === bscAddress);      // true!
console.log('ETH === Solana?', ethAddress === solAddress);    // false (different chain)

// Get balances across all chains for pocket 0
const balances = await manager.getPocketBalanceAcrossChains(
    0,  // pocket index
    new Map([
        ['ethereum', ['0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48']],  // USDC on Ethereum
        ['polygon', ['0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174']],   // USDC on Polygon
        ['bsc', ['0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d']],       // USDC on BSC
        ['solana', ['EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v']]    // USDC on Solana
    ])
);

// Display balances by chain
balances.forEach(chainBalance => {
    console.log(`\n${chainBalance.chainId.toUpperCase()}:`);
    console.log(`  Address: ${chainBalance.address}`);
    chainBalance.balances.forEach(bal => {
        const tokenName = bal.token === 'native' ? 'Native' : 'USDC';
        console.log(`  ${tokenName}: ${bal.balance.formatted}`);
    });
});

// Get all pockets (0, 1, 2) balances across all chains
const allBalances = await manager.getAllPocketsBalanceAcrossChains(
    [0, 1, 2],  // pocket indices
    new Map([
        ['ethereum', ['0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48']],
        ['polygon', ['0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174']],
        ['solana', ['EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v']]
    ])
);

// Display total across all pockets and chains
for (const [pocketIndex, chainBalances] of allBalances) {
    console.log(`\nPocket ${pocketIndex}:`);
    chainBalances.forEach(cb => {
        console.log(`  ${cb.chainId}: ${cb.balances.length} tokens`);
    });
}

// Advanced: Get specific chain manager for direct operations
const ethManager = manager.getEVMManager('ethereum');
await ethManager.transferToPocket(ethWalletClient, 0, '0.1');

const solManager = manager.getSVMManager('solana');
await solManager.transferToPocket(solKeypair, 0, 1000000000n);

// Cleanup all chains
manager.dispose();
```

---

## 🔑 Key Features

### 1. EVM Address Sharing ✅
All EVM-compatible chains (Ethereum, Polygon, BSC, Arbitrum, Optimism, etc.) share the same addresses because they all use BIP-44 coin type 60.

```typescript
// Same pocket, same address across all EVM chains
const ethPocket = manager.getPocketAddress('ethereum', 0);
const polyPocket = manager.getPocketAddress('polygon', 0);
// ethPocket === polyPocket ✅
```

### 2. Solana Has Different Addresses ✅
Solana uses BIP-44 coin type 501, so it generates different addresses.

```typescript
const ethPocket = manager.getPocketAddress('ethereum', 0);   // 0x...
const solPocket = manager.getPocketAddress('solana', 0);     // Different!
```

### 3. Memory Management ✅
Following the VM pattern, all managers support proper cleanup:

```typescript
// Clear specific pocket
manager.clearPocket(0);

// Clear all pockets
manager.clearAllPockets();

// Clear all RPC clients
manager.clearAllClients();

// Dispose everything (clear mnemonic + all data)
manager.dispose();
```

### 4. Lazy RPC Client Creation ✅
RPC clients are created on-demand and can be garbage collected:

```typescript
// Client created when first accessed
const balance = await manager.getPocketBalance(...);

// Clear client to free memory
manager.clearClient();  // Single chain
manager.clearAllClients();  // Multi-chain
```

---

## 🏗️ Architecture Highlights

### Follows VM Pattern Exactly

```typescript
// VM Pattern
abstract class VM<AddressType, PrivateKeyType, ConnectionType> { }
class EVMVM extends VM<string, string, PublicClient> { }
class SVMVM extends VM<PublicKey, Keypair, Connection> { }

// Savings Pattern (Same Structure!)
abstract class SavingsManager<AddressType, ClientType, WalletClientType> { }
class EVMSavingsManager extends SavingsManager<Hex, PublicClient, WalletClient> { }
class SVMSavingsManager extends SavingsManager<PublicKey, Connection, Keypair> { }
```

### Type Safety

All managers are fully typed with generics:
- **AddressType**: `Hex` for EVM, `PublicKey` for Solana
- **ClientType**: `PublicClient` for EVM, `Connection` for Solana
- **WalletClientType**: `WalletClient` for EVM, `Keypair` for Solana

---

## 📊 Comparison: Single-Chain vs Multi-Chain

### Before (Old Pattern)
```typescript
// Old: Single chain only
const manager = new BaseSavingsManager(mnemonic, 0, ethConfig);
const pocket = manager.getPocket(0);
const balances = await manager.getPocketTokenBalance([usdc], 0);
```

### After (New Pattern)
```typescript
// New: Single chain (still works the same)
const manager = new EVMSavingsManager(mnemonic, ethConfig, 0);
const pocket = manager.getPocket(0);
const balances = await manager.getPocketBalance(0, [usdc]);

// OR Multi-chain (new capability!)
const multiManager = new MultiChainSavingsManager(mnemonic, [
    { id: 'ethereum', type: 'EVM', config: ethConfig },
    { id: 'polygon', type: 'EVM', config: polyConfig },
    { id: 'solana', type: 'SVM', config: { rpcUrl: '...' } }
], 0);

// Query all chains at once
const allBalances = await multiManager.getPocketBalanceAcrossChains(0, tokensByChain);
```

---

## 🎯 Migration Guide

### Old Code (Legacy Manager)
```typescript
import { SavingsManager } from './utils/savings';

const manager = new SavingsManager(mnemonic, ethConfig, 0);
```

**Status**: ✅ Still works! Legacy exports maintained for backward compatibility.

### New Code (Multi-Chain)
```typescript
import { EVMSavingsManager, SVMSavingsManager, MultiChainSavingsManager } from './utils/savings';

// Single EVM chain
const evmManager = new EVMSavingsManager(mnemonic, ethConfig, 0);

// Single Solana chain
const svmManager = new SVMSavingsManager(mnemonic, rpcUrl, 0);

// Multi-chain
const multiManager = new MultiChainSavingsManager(mnemonic, chains, 0);
```

---

## 🧪 Testing Checklist

- [x] Abstract base class created
- [x] EVM implementation complete
- [x] Solana implementation complete
- [x] Multi-chain orchestrator complete
- [x] Exports updated
- [x] Build successful (no TypeScript errors in savings module)
- [ ] Unit tests (TODO)
- [ ] Integration tests (TODO)
- [ ] End-to-end tests (TODO)

---

## 📝 Next Steps (Optional)

1. **Add Unit Tests**
   - Test pocket derivation
   - Test balance queries
   - Test transfers

2. **Add Integration Tests**
   - Test with real RPC endpoints (testnet)
   - Test cross-chain operations

3. **Performance Optimizations**
   - Implement balance caching
   - Batch RPC requests
   - Add rate limiting helpers

4. **Additional Features**
   - Pocket discovery (scan for pockets with balances)
   - Transaction history per pocket
   - USD value aggregation (with price feeds)

---

## 🎉 Summary

✅ **Complete multi-chain savings manager implemented**
- Follows EVM/SVM VM pattern exactly
- Supports all EVM chains + Solana
- EVM chains share addresses (coin type 60)
- Solana has different addresses (coin type 501)
- Full type safety with generics
- Memory management and disposal patterns
- Lazy RPC client creation
- Backward compatible with legacy code

**Ready to use!** 🚀
