# Multi-Chain Savings Manager - Implementation Plan

**Created**: 2026-02-02
**Status**: 📋 Planning Phase
**Pattern**: Following EVM/SVM VM architecture

---

## 🎯 Architecture Pattern (Based on VM Structure)

### Current VM Pattern
```typescript
// Base abstract VM class
abstract class VM<AddressType, PrivateKeyType, ConnectionType> { }

// EVM implementation
class EVMVM extends VM<string, string, PublicClient> {
    derivationPath = "m/44'/60'/0'/0/";
}

// SVM implementation
class SVMVM extends VM<PublicKey, Keypair, Connection> {
    derivationPath = "m/44'/501'/";
}
```

### New Savings Pattern (Same Structure)
```typescript
// Base abstract savings manager
abstract class SavingsManager<AddressType, ClientType, WalletClientType> { }

// EVM savings implementation
class EVMSavingsManager extends SavingsManager<Hex, PublicClient, WalletClient> {
    coinType = 60;
}

// SVM savings implementation
class SVMSavingsManager extends SavingsManager<PublicKey, Connection, Keypair> {
    coinType = 501;
}

// Multi-chain orchestrator
class MultiChainSavingsManager {
    private evmManagers: Map<string, EVMSavingsManager>;
    private svmManagers: Map<string, SVMSavingsManager>;
}
```

---

## 📁 File Structure (Following EVM/SVM Pattern)

```
utils/savings/
├── index.ts                    // Export all savings modules
├── types.ts                    // Shared types (existing, extend)
├── validation.ts               // Validation utilities (existing, extend)
│
├── savings-manager.ts          // Base abstract SavingsManager class
├── evm-savings.ts              // EVMSavingsManager implementation
├── svm-savings.ts              // SVMSavingsManager implementation
├── multi-chain-savings.ts      // MultiChainSavingsManager orchestrator
│
└── utils/
    ├── chain-config.ts         // Chain configuration helpers
    └── balance-aggregator.ts   // Balance aggregation utilities
```

---

## 🏗️ Implementation Plan

### Phase 1: Base Abstract Class ⚡

**File**: `utils/savings/savings-manager.ts`

```typescript
import { Balance, TransactionResult } from "../types";

/**
 * Abstract base class for savings managers (similar to VM)
 *
 * @template AddressType - Address format (Hex for EVM, PublicKey for SVM)
 * @template ClientType - RPC client type (PublicClient for EVM, Connection for SVM)
 * @template WalletClientType - Wallet client type (WalletClient for EVM, Keypair for SVM)
 */
export abstract class SavingsManager<
    AddressType,
    ClientType,
    WalletClientType
> {
    protected mnemonic: string;
    protected walletIndex: number;
    protected disposed: boolean = false;

    // Abstract properties (implemented by subclasses)
    abstract coinType: number;
    abstract derivationPathBase: string;

    // Pocket cache: Map<pocketIndex, Pocket>
    protected pockets: Map<number, {
        privateKey: any;
        address: AddressType;
        derivationPath: string;
        index: number;
    }> = new Map();

    constructor(mnemonic: string, walletIndex: number = 0) {
        this.mnemonic = mnemonic;
        this.walletIndex = walletIndex;
    }

    // Abstract methods (must be implemented by subclasses)
    abstract derivePocket(accountIndex: number): {
        privateKey: any;
        address: AddressType;
        derivationPath: string;
        index: number;
    };

    abstract getMainWallet(): {
        privateKey: any;
        address: AddressType;
        derivationPath: string;
    };

    abstract createClient(rpcUrl: string): ClientType;

    // Shared methods (implemented in base class)
    getPocket(accountIndex: number) {
        if (!this.pockets.has(accountIndex)) {
            return this.derivePocket(accountIndex);
        }
        return this.pockets.get(accountIndex)!;
    }

    clearPocket(accountIndex: number): void {
        if (this.pockets.has(accountIndex)) {
            const pocket = this.pockets.get(accountIndex)!;
            (pocket as any).privateKey = '';
            this.pockets.delete(accountIndex);
        }
    }

    clearAllPockets(): void {
        for (const [_, pocket] of this.pockets.entries()) {
            (pocket as any).privateKey = '';
        }
        this.pockets.clear();
    }

    dispose(): void {
        if (this.disposed) return;
        this.clearAllPockets();
        (this as any).mnemonic = '';
        this.disposed = true;
    }

    isDisposed(): boolean {
        return this.disposed || !this.mnemonic;
    }

    protected checkNotDisposed(): void {
        if (this.isDisposed()) {
            throw new Error('SavingsManager has been disposed');
        }
    }
}
```

---

### Phase 2: EVM Implementation ⚡

**File**: `utils/savings/evm-savings.ts`

```typescript
import { SavingsManager } from "./savings-manager";
import { Hex, PublicClient, WalletClient, createPublicClient, createWalletClient, http } from "viem";
import { EVMDeriveChildPrivateKey, mnemonicToSeed } from "../walletBip32";
import { ChainWalletConfig, Balance, TransactionResult } from "../types";
import { ethers } from "ethers";
import {
    fromChainToViemChain,
    getNativeBalance,
    getTokenBalance,
    sendNativeToken,
    sendERC20Token
} from "../evm";
import { SavingsValidation } from "./validation";
import { privateKeyToAccount } from "viem/accounts";

/**
 * EVM Savings Manager
 *
 * Manages savings pockets across EVM-compatible chains (Ethereum, Polygon, BSC, etc.)
 * All EVM chains use the same addresses (coin type 60)
 */
export class EVMSavingsManager extends SavingsManager<Hex, PublicClient, WalletClient> {
    coinType = 60;
    derivationPathBase = "m/44'/60'/";

    private chain: ChainWalletConfig;
    private _client?: PublicClient;

    constructor(
        mnemonic: string,
        chain: ChainWalletConfig,
        walletIndex: number = 0
    ) {
        super(mnemonic, walletIndex);

        SavingsValidation.validateMnemonic(mnemonic);
        SavingsValidation.validateWalletIndex(walletIndex);
        SavingsValidation.validateChainId(chain.chainId);

        this.chain = chain;
    }

    // Lazy client creation (like VM pattern)
    get client(): PublicClient {
        if (!this._client) {
            this._client = this.createClient(this.chain.rpcUrl);
        }
        return this._client;
    }

    createClient(rpcUrl: string): PublicClient {
        return createPublicClient({
            chain: fromChainToViemChain(this.chain),
            transport: http(rpcUrl)
        });
    }

    clearClient(): void {
        this._client = undefined;
    }

    derivePocket(accountIndex: number) {
        this.checkNotDisposed();
        SavingsValidation.validateAccountIndex(accountIndex);

        const pocketIndex = accountIndex + 1; // Preserve index 0 for main wallet
        const derivationPath = `${this.derivationPathBase}${pocketIndex}'/0/${this.walletIndex}`;
        const seed = mnemonicToSeed(this.mnemonic);
        const { privateKey } = EVMDeriveChildPrivateKey(seed, this.walletIndex, derivationPath);
        const wallet = new ethers.Wallet(privateKey);

        const pocket = {
            privateKey,
            address: wallet.address as Hex,
            derivationPath,
            index: pocketIndex
        };

        this.pockets.set(accountIndex, pocket);
        return pocket;
    }

    getMainWallet() {
        this.checkNotDisposed();
        const derivationPath = `${this.derivationPathBase}0'/0/${this.walletIndex}`;
        const seed = mnemonicToSeed(this.mnemonic);
        const { privateKey } = EVMDeriveChildPrivateKey(seed, this.walletIndex, derivationPath);
        const wallet = new ethers.Wallet(privateKey);

        return {
            privateKey,
            address: wallet.address as Hex,
            derivationPath
        };
    }

    getMainWalletAddress(): Hex {
        return this.getMainWallet().address;
    }

    // Balance operations
    async getPocketBalance(pocketIndex: number, tokens: string[]): Promise<{
        address: Hex | 'native';
        balance: Balance;
    }[]> {
        SavingsValidation.validateAccountIndex(pocketIndex);

        const pocket = this.getPocket(pocketIndex);
        const balances: { address: Hex | 'native'; balance: Balance }[] = [];

        // Get native balance
        const nativeBalance = await getNativeBalance(pocket.address, this.client);
        balances.push({ address: 'native', balance: nativeBalance });

        // Get token balances
        await Promise.all(tokens.map(async (token) => {
            SavingsValidation.validateAddress(token, 'Token address');
            const tokenBalance = await getTokenBalance(token as Hex, pocket.address, this.client);
            balances.push({ address: token as Hex, balance: tokenBalance });
        }));

        return balances;
    }

    // Transfer operations
    async transferToPocket(
        mainWallet: WalletClient,
        pocketIndex: number,
        amount: string
    ): Promise<TransactionResult> {
        SavingsValidation.validateAccountIndex(pocketIndex);
        SavingsValidation.validateAmountString(amount, 'Transfer amount');

        const pocket = this.getPocket(pocketIndex);
        return await sendNativeToken(mainWallet, this.client, pocket.address, amount, 5);
    }

    async transferTokenToPocket(
        mainWallet: WalletClient,
        tokenAddress: string,
        pocketIndex: number,
        amount: bigint
    ): Promise<TransactionResult> {
        SavingsValidation.validateAddress(tokenAddress, 'Token address');
        SavingsValidation.validateAccountIndex(pocketIndex);
        SavingsValidation.validateAmount(amount, 'Transfer amount');

        const pocket = this.getPocket(pocketIndex);
        return await sendERC20Token(mainWallet, this.client, tokenAddress as Hex, pocket.address, amount, 5);
    }

    async sendToMainWallet(
        pocketIndex: number,
        amount: bigint,
        token: Hex | "native"
    ): Promise<TransactionResult> {
        SavingsValidation.validateAccountIndex(pocketIndex);

        const pocket = this.getPocket(pocketIndex);
        const account = privateKeyToAccount(`0x${pocket.privateKey}`);
        const mainWalletAddress = this.getMainWalletAddress();

        const walletClient = createWalletClient({
            account,
            transport: http(this.chain.rpcUrl),
            chain: fromChainToViemChain(this.chain)
        });

        if (token === "native") {
            return await sendNativeToken(walletClient, this.client, mainWalletAddress, amount);
        }

        return await sendERC20Token(walletClient, this.client, token, mainWalletAddress, amount);
    }

    dispose(): void {
        super.dispose();
        this.clearClient();
    }
}
```

---

### Phase 3: SVM (Solana) Implementation ⚡

**File**: `utils/savings/svm-savings.ts`

```typescript
import { SavingsManager } from "./savings-manager";
import { Connection, PublicKey, Keypair } from "@solana/web3.js";
import { SVMDeriveChildPrivateKey, mnemonicToSeed } from "../walletBip32";
import { Balance, TransactionResult } from "../types";
import {
    getSvmNativeBalance,
    getTokenBalance as getSvmTokenBalance,
    signAndSendTransaction,
    getTransferNativeTransaction,
    getTransferTokenTransaction
} from "../svm";
import { SavingsValidation } from "./validation";
import BN from "bn.js";

/**
 * Solana (SVM) Savings Manager
 *
 * Manages savings pockets on Solana
 * Uses coin type 501 (different addresses than EVM)
 */
export class SVMSavingsManager extends SavingsManager<PublicKey, Connection, Keypair> {
    coinType = 501;
    derivationPathBase = "m/44'/501'/";

    private rpcUrl: string;
    private _client?: Connection;

    constructor(
        mnemonic: string,
        rpcUrl: string,
        walletIndex: number = 0
    ) {
        super(mnemonic, walletIndex);

        SavingsValidation.validateMnemonic(mnemonic);
        SavingsValidation.validateWalletIndex(walletIndex);

        this.rpcUrl = rpcUrl;
    }

    // Lazy client creation
    get client(): Connection {
        if (!this._client) {
            this._client = this.createClient(this.rpcUrl);
        }
        return this._client;
    }

    createClient(rpcUrl: string): Connection {
        return new Connection(rpcUrl, 'confirmed');
    }

    clearClient(): void {
        this._client = undefined;
    }

    derivePocket(accountIndex: number) {
        this.checkNotDisposed();
        SavingsValidation.validateAccountIndex(accountIndex);

        const pocketIndex = accountIndex + 1;
        const derivationPath = `${this.derivationPathBase}${pocketIndex}'/0/${this.walletIndex}`;
        const seed = mnemonicToSeed(this.mnemonic);
        const keypair = SVMDeriveChildPrivateKey(seed, this.walletIndex, derivationPath);

        const pocket = {
            privateKey: keypair,
            address: keypair.publicKey,
            derivationPath,
            index: pocketIndex
        };

        this.pockets.set(accountIndex, pocket);
        return pocket;
    }

    getMainWallet() {
        this.checkNotDisposed();
        const derivationPath = `${this.derivationPathBase}0'/0/${this.walletIndex}`;
        const seed = mnemonicToSeed(this.mnemonic);
        const keypair = SVMDeriveChildPrivateKey(seed, this.walletIndex, derivationPath);

        return {
            privateKey: keypair,
            address: keypair.publicKey,
            derivationPath
        };
    }

    getMainWalletAddress(): PublicKey {
        return this.getMainWallet().address;
    }

    // Balance operations
    async getPocketBalance(pocketIndex: number, tokens: string[]): Promise<{
        address: PublicKey | 'native';
        balance: Balance;
    }[]> {
        SavingsValidation.validateAccountIndex(pocketIndex);

        const pocket = this.getPocket(pocketIndex);
        const balances: { address: PublicKey | 'native'; balance: Balance }[] = [];

        // Get native SOL balance
        const nativeBalance = await getSvmNativeBalance(pocket.address, this.client);
        balances.push({ address: 'native', balance: nativeBalance });

        // Get SPL token balances
        await Promise.all(tokens.map(async (token) => {
            const tokenPubkey = new PublicKey(token);
            const tokenBalanceData = await getSvmTokenBalance(pocket.address, tokenPubkey, this.client);
            const balance: Balance = {
                balance: new BN(tokenBalanceData.amount),
                formatted: tokenBalanceData.uiAmount || 0,
                decimal: tokenBalanceData.decimals
            };
            balances.push({ address: tokenPubkey, balance });
        }));

        return balances;
    }

    // Transfer operations
    async transferToPocket(
        mainWallet: Keypair,
        pocketIndex: number,
        amount: bigint
    ): Promise<TransactionResult> {
        SavingsValidation.validateAccountIndex(pocketIndex);

        const pocket = this.getPocket(pocketIndex);
        const tx = await getTransferNativeTransaction(
            mainWallet.publicKey,
            pocket.address,
            amount,
            this.client
        );

        return await signAndSendTransaction(tx, [mainWallet], this.client);
    }

    async transferTokenToPocket(
        mainWallet: Keypair,
        tokenMint: string,
        pocketIndex: number,
        amount: bigint
    ): Promise<TransactionResult> {
        SavingsValidation.validateAccountIndex(pocketIndex);

        const pocket = this.getPocket(pocketIndex);
        const tx = await getTransferTokenTransaction(
            mainWallet.publicKey,
            pocket.address,
            new PublicKey(tokenMint),
            amount,
            this.client
        );

        return await signAndSendTransaction(tx, [mainWallet], this.client);
    }

    async sendToMainWallet(
        pocketIndex: number,
        amount: bigint,
        token: PublicKey | "native"
    ): Promise<TransactionResult> {
        SavingsValidation.validateAccountIndex(pocketIndex);

        const pocket = this.getPocket(pocketIndex);
        const mainWalletAddress = this.getMainWalletAddress();

        if (token === "native") {
            const tx = await getTransferNativeTransaction(
                pocket.address,
                mainWalletAddress,
                amount,
                this.client
            );
            return await signAndSendTransaction(tx, [pocket.privateKey], this.client);
        }

        const tx = await getTransferTokenTransaction(
            pocket.address,
            mainWalletAddress,
            token,
            amount,
            this.client
        );

        return await signAndSendTransaction(tx, [pocket.privateKey], this.client);
    }

    dispose(): void {
        super.dispose();
        this.clearClient();
    }
}
```

---

### Phase 4: Multi-Chain Orchestrator 🚀

**File**: `utils/savings/multi-chain-savings.ts`

```typescript
import { EVMSavingsManager } from "./evm-savings";
import { SVMSavingsManager } from "./svm-savings";
import { ChainWalletConfig, Balance } from "../types";
import { Hex, PublicClient, WalletClient } from "viem";
import { Connection, PublicKey, Keypair } from "@solana/web3.js";

export type ChainType = 'EVM' | 'SVM';

export interface ChainConfig {
    id: string;  // e.g., "ethereum", "polygon", "solana"
    type: ChainType;
    config: ChainWalletConfig | { rpcUrl: string };
}

export interface PocketBalance {
    chainId: string;
    chainType: ChainType;
    pocketIndex: number;
    address: string;
    balances: {
        token: string; // address or 'native'
        balance: Balance;
    }[];
}

/**
 * Multi-Chain Savings Manager
 *
 * Orchestrates savings across multiple chains (EVM and Solana)
 * Similar to how you might have a multi-chain wallet manager
 */
export class MultiChainSavingsManager {
    private mnemonic: string;
    private walletIndex: number;

    // Separate managers by chain type
    private evmManagers: Map<string, EVMSavingsManager> = new Map();
    private svmManagers: Map<string, SVMSavingsManager> = new Map();

    // Track chain configs
    private chainConfigs: Map<string, ChainConfig> = new Map();

    constructor(
        mnemonic: string,
        chains: ChainConfig[],
        walletIndex: number = 0
    ) {
        this.mnemonic = mnemonic;
        this.walletIndex = walletIndex;

        // Initialize managers for each chain
        for (const chain of chains) {
            this.addChain(chain);
        }
    }

    /**
     * Add a new chain
     */
    addChain(chain: ChainConfig): void {
        this.chainConfigs.set(chain.id, chain);

        if (chain.type === 'EVM') {
            const manager = new EVMSavingsManager(
                this.mnemonic,
                chain.config as ChainWalletConfig,
                this.walletIndex
            );
            this.evmManagers.set(chain.id, manager);
        } else if (chain.type === 'SVM') {
            const config = chain.config as { rpcUrl: string };
            const manager = new SVMSavingsManager(
                this.mnemonic,
                config.rpcUrl,
                this.walletIndex
            );
            this.svmManagers.set(chain.id, manager);
        }
    }

    /**
     * Remove a chain
     */
    removeChain(chainId: string): void {
        if (this.evmManagers.has(chainId)) {
            this.evmManagers.get(chainId)?.dispose();
            this.evmManagers.delete(chainId);
        }
        if (this.svmManagers.has(chainId)) {
            this.svmManagers.get(chainId)?.dispose();
            this.svmManagers.delete(chainId);
        }
        this.chainConfigs.delete(chainId);
    }

    /**
     * Get list of all chain IDs
     */
    getChains(): string[] {
        return Array.from(this.chainConfigs.keys());
    }

    /**
     * Get pocket address for a specific chain
     */
    getPocketAddress(chainId: string, pocketIndex: number): string {
        const chain = this.chainConfigs.get(chainId);
        if (!chain) throw new Error(`Chain not found: ${chainId}`);

        if (chain.type === 'EVM') {
            const manager = this.evmManagers.get(chainId)!;
            return manager.getPocket(pocketIndex).address;
        } else {
            const manager = this.svmManagers.get(chainId)!;
            return manager.getPocket(pocketIndex).address.toBase58();
        }
    }

    /**
     * Get pocket balance for a specific chain
     */
    async getPocketBalance(
        chainId: string,
        pocketIndex: number,
        tokens: string[]
    ): Promise<PocketBalance> {
        const chain = this.chainConfigs.get(chainId);
        if (!chain) throw new Error(`Chain not found: ${chainId}`);

        if (chain.type === 'EVM') {
            const manager = this.evmManagers.get(chainId)!;
            const balances = await manager.getPocketBalance(pocketIndex, tokens);
            const pocket = manager.getPocket(pocketIndex);

            return {
                chainId,
                chainType: 'EVM',
                pocketIndex,
                address: pocket.address,
                balances: balances.map(b => ({
                    token: b.address,
                    balance: b.balance
                }))
            };
        } else {
            const manager = this.svmManagers.get(chainId)!;
            const balances = await manager.getPocketBalance(pocketIndex, tokens);
            const pocket = manager.getPocket(pocketIndex);

            return {
                chainId,
                chainType: 'SVM',
                pocketIndex,
                address: pocket.address.toBase58(),
                balances: balances.map(b => ({
                    token: b.address === 'native' ? 'native' : b.address.toBase58(),
                    balance: b.balance
                }))
            };
        }
    }

    /**
     * Get pocket balance across multiple chains
     */
    async getPocketBalanceAcrossChains(
        pocketIndex: number,
        tokensByChain: Map<string, string[]>
    ): Promise<PocketBalance[]> {
        const promises: Promise<PocketBalance>[] = [];

        for (const [chainId, tokens] of tokensByChain) {
            promises.push(this.getPocketBalance(chainId, pocketIndex, tokens));
        }

        return await Promise.all(promises);
    }

    /**
     * Get balances for multiple pockets across multiple chains
     */
    async getAllPocketsBalanceAcrossChains(
        pocketIndices: number[],
        tokensByChain: Map<string, string[]>
    ): Promise<Map<number, PocketBalance[]>> {
        const results = new Map<number, PocketBalance[]>();

        for (const pocketIndex of pocketIndices) {
            const balances = await this.getPocketBalanceAcrossChains(
                pocketIndex,
                tokensByChain
            );
            results.set(pocketIndex, balances);
        }

        return results;
    }

    /**
     * Get EVM manager for a chain (for advanced operations)
     */
    getEVMManager(chainId: string): EVMSavingsManager {
        const manager = this.evmManagers.get(chainId);
        if (!manager) throw new Error(`EVM chain not found: ${chainId}`);
        return manager;
    }

    /**
     * Get SVM manager for a chain (for advanced operations)
     */
    getSVMManager(chainId: string): SVMSavingsManager {
        const manager = this.svmManagers.get(chainId);
        if (!manager) throw new Error(`SVM chain not found: ${chainId}`);
        return manager;
    }

    /**
     * Clear all pockets across all chains
     */
    clearAllPockets(): void {
        for (const manager of this.evmManagers.values()) {
            manager.clearAllPockets();
        }
        for (const manager of this.svmManagers.values()) {
            manager.clearAllPockets();
        }
    }

    /**
     * Dispose all managers
     */
    dispose(): void {
        for (const manager of this.evmManagers.values()) {
            manager.dispose();
        }
        for (const manager of this.svmManagers.values()) {
            manager.dispose();
        }
        this.evmManagers.clear();
        this.svmManagers.clear();
        this.chainConfigs.clear();
        (this as any).mnemonic = '';
    }
}
```

---

### Phase 5: Update Exports 📦

**File**: `utils/savings/index.ts`

```typescript
// Base classes
export * from "./savings-manager";
export * from "./evm-savings";
export * from "./svm-savings";
export * from "./multi-chain-savings";

// Types and utilities
export * from "./types";
export * from "./validation";

// Backward compatibility (if needed)
export { EVMSavingsManager as SavingsManager } from "./evm-savings";
```

---

## 📊 Usage Examples

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

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

const manager = new EVMSavingsManager(
    mnemonic,
    { chainId: 1, name: 'ethereum', rpcUrl: 'https://...' },
    0  // wallet index
);

// Get pocket
const pocket = manager.getPocket(0);
console.log(pocket.address); // 0x...

// Get balances
const balances = await manager.getPocketBalance(0, [usdcAddress]);

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

---

### Example 2: Solana (Simple)

```typescript
import { SVMSavingsManager } from './savings/svm-savings';

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

// Get pocket
const pocket = manager.getPocket(0);
console.log(pocket.address.toBase58()); // Solana address

// Get balances
const balances = await manager.getPocketBalance(0, [usdcMint]);

// Transfer to pocket
await manager.transferToPocket(mainWalletKeypair, 0, 1000000n);
```

---

### Example 3: Multi-Chain (Advanced)

```typescript
import { MultiChainSavingsManager } from './savings/multi-chain-savings';

const manager = new MultiChainSavingsManager(
    mnemonic,
    [
        {
            id: 'ethereum',
            type: 'EVM',
            config: { chainId: 1, name: 'ethereum', rpcUrl: 'https://...' }
        },
        {
            id: 'polygon',
            type: 'EVM',
            config: { chainId: 137, name: 'polygon', rpcUrl: 'https://...' }
        },
        {
            id: 'solana',
            type: 'SVM',
            config: { rpcUrl: 'https://api.mainnet-beta.solana.com' }
        },
    ],
    0  // wallet index
);

// Get pocket address on Ethereum
const ethAddress = manager.getPocketAddress('ethereum', 0);

// Get pocket address on Polygon (same as Ethereum!)
const polyAddress = manager.getPocketAddress('polygon', 0);
console.log(ethAddress === polyAddress); // true! (same EVM address)

// Get pocket address on Solana (different!)
const solAddress = manager.getPocketAddress('solana', 0);
console.log(ethAddress !== solAddress); // true (different chain, different address)

// Get balances across all chains for pocket 0
const balances = await manager.getPocketBalanceAcrossChains(
    0,
    new Map([
        ['ethereum', [usdcEth]],
        ['polygon', [usdcPoly]],
        ['solana', [usdcSol]]
    ])
);

// Results grouped by chain
balances.forEach(balance => {
    console.log(`${balance.chainId}:`, balance.balances);
});

// Get specific manager for advanced operations
const ethManager = manager.getEVMManager('ethereum');
await ethManager.transferToPocket(walletClient, 0, '0.1');

const solManager = manager.getSVMManager('solana');
await solManager.transferToPocket(mainKeypair, 0, 1000000n);
```

---

## ✅ Implementation Checklist

### Phase 1: Base Infrastructure
- [ ] Create `savings-manager.ts` with abstract base class
- [ ] Add generic types for AddressType, ClientType, WalletClientType
- [ ] Implement shared methods (getPocket, clearPocket, dispose)
- [ ] Add validation checks

### Phase 2: EVM Implementation
- [ ] Create `evm-savings.ts` extending base class
- [ ] Implement EVM-specific derivation (coin type 60)
- [ ] Implement balance queries for EVM
- [ ] Implement transfer operations for EVM
- [ ] Add tests for EVM savings

### Phase 3: SVM Implementation
- [ ] Create `svm-savings.ts` extending base class
- [ ] Implement Solana-specific derivation (coin type 501)
- [ ] Implement balance queries for Solana
- [ ] Implement transfer operations for Solana
- [ ] Add tests for SVM savings

### Phase 4: Multi-Chain Orchestrator
- [ ] Create `multi-chain-savings.ts`
- [ ] Implement chain management (add/remove chains)
- [ ] Implement cross-chain balance queries
- [ ] Add chain type detection
- [ ] Add manager access methods

### Phase 5: Integration & Testing
- [ ] Update exports in `index.ts`
- [ ] Write unit tests for all classes
- [ ] Write integration tests for multi-chain
- [ ] Update documentation
- [ ] Create usage examples

---

## 🎓 Key Design Decisions

### 1. Same Pattern as VM Classes ✅
- Abstract base class with generics
- Concrete implementations for each chain type
- Shared logic in base, specific logic in subclasses

### 2. EVM Chains Share Addresses ✅
- All EVM chains use coin type 60
- Same mnemonic generates same addresses
- One `EVMSavingsManager` per EVM chain (for different RPC endpoints)

### 3. Solana Has Different Addresses ✅
- Uses coin type 501
- Different derivation path = different addresses
- Separate `SVMSavingsManager`

### 4. No Backward Compatibility Needed ✅
- Pockets not implemented yet
- Clean slate for proper design
- Can design optimal structure from start

---

## 📝 Next Steps

1. **Review & Approve** this plan
2. **Start with Phase 1** (Base class)
3. **Implement Phase 2** (EVM)
4. **Implement Phase 3** (Solana)
5. **Add Phase 4** (Multi-chain)
6. **Test & Document**

---

**Ready to implement?** Let me know which phase to start with!
