# 6. FAQ

### Error Codes and Debugging Tools

#### Common Error Codes

```javascript
// JuCoin Wallet Error Code Reference Table
const ERROR_CODES = {
    // Standard Error Codes
    4001: {
        message: "User rejected the request",
        description: "User rejected the request",
        solution: "Guide the user to reinitiate the request and confirm"
    },
    4100: {
        message: "The requested account and/or method has not been authorized",
        description: "Account or method not authorized",
        solution: "Call eth_requestAccounts first to get authorization"
    },
    4200: {
        message: "The requested method is not supported",
        description: "Unsupported method",
        solution: "Check if method name is correct, refer to API documentation"
    },
    4900: {
        message: "The provider is disconnected",
        description: "Provider is disconnected",
        solution: "Check network connection, reconnect wallet"
    },
    4901: {
        message: "The provider is disconnected from the specified chain",
        description: "Disconnected from specified chain",
        solution: "Switch to the correct network"
    },
    
    // JSON-RPC Error Codes
    "-32700": {
        message: "Parse error",
        description: "JSON parsing error",
        solution: "Check request parameter format"
    },
    "-32600": {
        message: "Invalid request",
        description: "Invalid request",
        solution: "Check if request structure complies with JSON-RPC specification"
    },
    "-32601": {
        message: "Method not found",
        description: "Method does not exist",
        solution: "Check method name spelling"
    },
    "-32602": {
        message: "Invalid params",
        description: "Invalid parameters",
        solution: "Check parameter types and formats"
    },
    "-32603": {
        message: "Internal error",
        description: "Internal error",
        solution: "Retry request, contact support if persistent"
    },
    "-32000": {
        message: "Invalid input",
        description: "Invalid input",
        solution: "Check transaction data format"
    },
    "-32001": {
        message: "Resource not found",
        description: "Resource not found",
        solution: "Confirm if address or transaction hash is correct"
    },
    "-32002": {
        message: "Resource unavailable",
        description: "Resource unavailable",
        solution: "Request may be processing, check wallet popup"
    },
    "-32003": {
        message: "Transaction rejected",
        description: "Transaction rejected",
        solution: "Check transaction parameters like gas price, balance, etc."
    },
    "-32005": {
        message: "Method not supported",
        description: "Method not supported",
        solution: "This method is not available in current version"
    }
};
```

#### Debugging Tools

```javascript
// JuCoin Debug Helper
class JuCoinDebugger {
    constructor() {
        this.logs = [];
        this.enabled = localStorage.getItem('jucoin_debug') === 'true';
    }
    
    // Enable/disable debug mode
    toggle() {
        this.enabled = !this.enabled;
        localStorage.setItem('jucoin_debug', this.enabled);
        console.log(`JuCoin debug mode: ${this.enabled ? 'ON' : 'OFF'}`);
    }
    
    // Intercept and log all requests
    interceptRequests() {
        const originalRequest = window.jcEthereum.request;
        
        window.jcEthereum.request = async (args) => {
            const startTime = Date.now();
            const requestId = Math.random().toString(36).substring(7);
            
            if (this.enabled) {
                console.group(`🔵 JuCoin Request [${requestId}]`);
                console.log('Method:', args.method);
                console.log('Params:', args.params);
                console.groupEnd();
            }
            
            try {
                const result = await originalRequest.call(window.jucoin, args);
                
                if (this.enabled) {
                    console.group(`✅ JuCoin Response [${requestId}]`);
                    console.log('Duration:', Date.now() - startTime + 'ms');
                    console.log('Result:', result);
                    console.groupEnd();
                }
                
                this.logs.push({
                    id: requestId,
                    timestamp: startTime,
                    duration: Date.now() - startTime,
                    request: args,
                    response: result,
                    status: 'success'
                });
                
                return result;
            } catch (error) {
                if (this.enabled) {
                    console.group(`❌ JuCoin Error [${requestId}]`);
                    console.log('Duration:', Date.now() - startTime + 'ms');
                    console.log('Error:', error);
                    console.log('Error Code:', error.code);
                    console.log('Solution:', ERROR_CODES[error.code]?.solution);
                    console.groupEnd();
                }
                
                this.logs.push({
                    id: requestId,
                    timestamp: startTime,
                    duration: Date.now() - startTime,
                    request: args,
                    error: error,
                    status: 'error'
                });
                
                throw error;
            }
        };
    }
    
    // Export debug logs
    exportLogs() {
        const data = JSON.stringify(this.logs, null, 2);
        const blob = new Blob([data], { type: 'application/json' });
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = `jucoin-debug-${Date.now()}.json`;
        a.click();
    }
    
    // Clear logs
    clearLogs() {
        this.logs = [];
        console.log('Debug logs cleared');
    }
}

// Usage example
const debugger = new JuCoinDebugger();
debugger.toggle(); // Enable debugging
debugger.interceptRequests(); // Start intercepting requests
```

#### Quick Diagnostic Tools

```javascript
// Environment diagnostics
async function diagnoseEnvironment() {
    const diagnosis = {
        wallet: {
            installed: !!window.jcEthereum,
            version: window.jcEthereum?.version,
            isConnected: window.jcEthereum?.isConnected()
        },
        network: null,
        account: null,
        permissions: null
    };
    
    if (window.jucoin) {
        try {
            diagnosis.network = await window.jcEthereum.request({
                method: 'eth_chainId'
            });
            
            diagnosis.account = await window.jcEthereum.request({
                method: 'eth_accounts'
            });
            
            diagnosis.permissions = await window.jcEthereum.request({
                method: 'wallet_getPermissions'
            });
        } catch (error) {
            console.error('Error during diagnosis:', error);
        }
    }
    
    console.table(diagnosis);
    return diagnosis;
}
```

### Compatibility Notes

#### Browser Compatibility

```javascript
// Supported browsers and versions
const BROWSER_SUPPORT = {
    Chrome: '90+',
    Firefox: '89+',
    Edge: '90+',
    Safari: '14+',
    Brave: '1.25+',
    Opera: '76+'
};

// Browser detection
function checkBrowserCompatibility() {
    const ua = navigator.userAgent;
    const browser = {
        chrome: /Chrome\/(\d+)/.test(ua),
        firefox: /Firefox\/(\d+)/.test(ua),
        safari: /Safari\/(\d+)/.test(ua) && !/Chrome/.test(ua),
        edge: /Edg\/(\d+)/.test(ua)
    };
    
    // Check required Web APIs support
    const requiredAPIs = {
        'Web Crypto API': typeof crypto !== 'undefined',
        'IndexedDB': 'indexedDB' in window,
        'Web Storage': 'localStorage' in window,
        'Promises': typeof Promise !== 'undefined',
        'Async/Await': (async () => {})().constructor.name === 'AsyncFunction'
    };
    
    return {
        browser,
        apis: requiredAPIs,
        compatible: Object.values(requiredAPIs).every(v => v)
    };
}
```

#### MetaMask Compatibility Mode

```javascript
// JuCoin provides MetaMask compatibility mode
class MetaMaskCompatibility {
    static enable() {
        // Bind jucoin object to ethereum as well
        if (window.jucoin && !window.ethereum) {
            window.ethereum = window.jcEthereum;
            window.ethereum.isMetaMask = true; // Compatibility flag
            console.log('MetaMask compatibility mode enabled');
        }
    }
    
    static detectWallet() {
        // Prioritize JuCoin
        if (window.jcEthereum) {
            return {
                type: 'JuCoin',
                provider: window.jcEthereum
            };
        }
        
        // Check other wallets
        if (window.ethereum) {
            if (window.ethereum.isMetaMask) {
                return {
                    type: 'MetaMask',
                    provider: window.ethereum
                };
            }
            
            return {
                type: 'Unknown',
                provider: window.ethereum
            };
        }
        
        return null;
    }
}
```

### Migration Guide

#### Migrating from MetaMask

```javascript
// MetaMask to JuCoin migration helper
class MigrationHelper {
    // 1. Detect and switch Provider
    static async migrateProvider() {
        // Original MetaMask code
        // const provider = window.ethereum;
        
        // Migrated code
        const provider = window.jcEthereum || window.ethereum;
        
        return provider;
    }
    
    // 2. API call migration
    static async migrateAPICalls() {
        // MetaMask-specific API mapping
        const apiMapping = {
            // MetaMask's ethereum.request is already compatible
            'eth_requestAccounts': 'eth_requestAccounts',
            
            // JuCoin extended features
            'metamask_getProviderState': 'jucoin_getProviderState',
            'metamask_watchAsset': 'jucoin_watchAsset',
            
            // Network switching
            'wallet_switchEthereumChain': 'wallet_switchEthereumChain',
            'wallet_addEthereumChain': 'wallet_addEthereumChain'
        };
        
        return apiMapping;
    }
    
    // 3. Event listener migration
    static migrateEventListeners(oldProvider, newProvider) {
        // Get all event listeners
        const events = ['accountsChanged', 'chainChanged', 'disconnect'];
        
        events.forEach(event => {
            const listeners = oldProvider.listeners(event);
            listeners.forEach(listener => {
                newProvider.on(event, listener);
            });
        });
    }
    
    // 4. Complete migration example
    static async performMigration() {
        console.log('Starting migration from MetaMask to JuCoin...');
        
        // Check if JuCoin is installed
        if (!window.jucoin) {
            console.error('Please install JuCoin Wallet first');
            return false;
        }
        
        // Save MetaMask data (if needed)
        const backup = {
            accounts: await window.ethereum?.request({
                method: 'eth_accounts'
            }),
            chainId: await window.ethereum?.request({
                method: 'eth_chainId'
            })
        };
        
        // Switch to JuCoin
        window.ethereum = window.jcEthereum;
        
        // Restore connection
        if (backup.accounts?.length > 0) {
            await window.jcEthereum.request({
                method: 'eth_requestAccounts'
            });
        }
        
        console.log('Migration complete!');
        return true;
    }
}
```

#### Web3.js Project Migration

```javascript
// Web3.js compatibility layer
class Web3Migration {
    static async migrateWeb3() {
        // Original Web3.js code
        // const web3 = new Web3(window.ethereum);
        
        // JuCoin compatible code
        const provider = window.jcEthereum || window.ethereum;
        const web3 = new Web3(provider);
        
        // Ensure provider methods are compatible
        if (!provider.send) {
            provider.send = provider.request;
        }
        
        return web3;
    }
    
    // Migrate common Web3 methods
    static getCompatibleMethods() {
        return {
            // Account related
            getAccounts: async (web3) => {
                return await web3.eth.getAccounts();
            },
            
            // Transaction related
            sendTransaction: async (web3, tx) => {
                return await web3.eth.sendTransaction(tx);
            },
            
            // Contract related
            contractCall: async (web3, contract, method, params) => {
                return await contract.methods[method](...params).call();
            },
            
            // Signature related
            signMessage: async (web3, message, account) => {
                return await web3.eth.personal.sign(message, account);
            }
        };
    }
}
```

#### Ethers.js Project Migration

```javascript
// Ethers.js migration is simpler as it uses standard Provider interface
class EthersMigration {
    static async migrateEthers() {
        // Original Ethers.js code
        // const provider = new ethers.providers.Web3Provider(window.ethereum);
        
        // JuCoin compatible code
        const provider = new ethers.providers.Web3Provider(
            window.jcEthereum || window.ethereum
        );
        
        return provider;
    }
    
    // Usage example
    static async example() {
        const provider = await this.migrateEthers();
        const signer = provider.getSigner();
        
        // All Ethers.js functionality works normally
        const address = await signer.getAddress();
        const balance = await provider.getBalance(address);
        
        return { address, balance };
    }
}
```

#### Quick Migration Checklist

```javascript
// Migration checklist
const MIGRATION_CHECKLIST = {
    '1. Installation Check': {
        check: () => !!window.jcEthereum,
        fix: 'Please install JuCoin Wallet extension'
    },
    '2. Provider Switch': {
        check: () => window.ethereum === window.jcEthereum,
        fix: 'window.ethereum = window.jcEthereum'
    },
    '3. API Compatibility': {
        check: () => typeof window.jucoin.request === 'function',
        fix: 'Ensure using request method for API calls'
    },
    '4. Event Listeners': {
        check: () => typeof window.jucoin.on === 'function',
        fix: 'Use on/off methods instead of addListener/removeListener'
    },
    '5. Network Support': {
        check: async () => {
            const chainId = await window.jcEthereum.request({ method: 'eth_chainId' });
            return ['0x1', '0x38', '0x8956'].includes(chainId);
        },
        fix: 'Add required network configurations'
    }
};

// Automatic check tool
async function runMigrationCheck() {
    console.log('=== JuCoin Migration Check ===');
    
    for (const [name, item] of Object.entries(MIGRATION_CHECKLIST)) {
        try {
            const result = await item.check();
            console.log(`${result ? '✅' : '❌'} ${name}`);
            if (!result) {
                console.log(`   Fix: ${item.fix}`);
            }
        } catch (error) {
            console.log(`❌ ${name}`);
            console.log(`   Error: ${error.message}`);
        }
    }
}
```

#### Version Compatibility Table

```javascript
// Version compatibility
const VERSION_COMPATIBILITY = {
    'JuCoin Wallet': {
        '1.0.0': {
            features: ['Basic wallet functions', 'ETH/BSC support'],
            breaking: []
        },
        '1.1.0': {
            features: ['JuChain support', 'Batch transactions'],
            breaking: []
        },
        '1.2.0': {
            features: ['Hardware wallet support', 'Advanced security features'],
            breaking: ['jucoin_batchSendTransactions parameter format change']
        }
    },
    'Web3.js': {
        '1.x': 'Fully compatible',
        '4.x': 'Fully compatible'
    },
    'Ethers.js': {
        '5.x': 'Fully compatible',
        '6.x': 'Fully compatible'
    }
};
```

#### Common Migration Issues and Solutions

```javascript
// Collection of problem solutions
const MIGRATION_SOLUTIONS = {
    // Issue 1: window.ethereum is undefined
    ethereumUndefined: {
        problem: 'window.ethereum is undefined',
        solution: `
            // Add during app initialization
            if (window.jucoin && !window.ethereum) {
                window.ethereum = window.jcEthereum;
            }
        `
    },
    
    // Issue 2: Event listeners not working
    eventListenerNotWorking: {
        problem: 'Event listeners not triggering after migration',
        solution: `
            // Ensure removing old listeners and re-adding
            provider.removeAllListeners();
            provider.on('accountsChanged', handleAccountsChanged);
            provider.on('chainChanged', handleChainChanged);
        `
    },
    
    // Issue 3: Transaction signing failed
    transactionSigningFailed: {
        problem: 'Transaction signing failed or rejected',
        solution: `
            // Check gas parameter format
            const tx = {
                from: account,
                to: recipient,
                value: '0x' + value.toString(16), // Ensure hex format
                gas: '0x' + gasLimit.toString(16),
                gasPrice: '0x' + gasPrice.toString(16)
            };
        `
    },
    
    // Issue 4: Network switch failed
    networkSwitchFailed: {
        problem: 'Error when switching networks',
        solution: `
            // Try switching first, add network if failed
            try {
                await provider.request({
                    method: 'wallet_switchEthereumChain',
                    params: [{ chainId: '0x8956' }]
                });
            } catch (error) {
                if (error.code === 4902) {
                    await provider.request({
                        method: 'wallet_addEthereumChain',
                        params: [networkConfig]
                    });
                }
            }
        `
    }
};
```

#### One-Click Migration Script

```javascript
// One-click migration script
async function migrateToJuCoin() {
    console.log('🚀 Starting migration to JuCoin Wallet...');
    
    try {
        // Step 1: Check environment
        if (!window.jcEthereum) {
            throw new Error('Please install JuCoin Wallet first');
        }
        
        // Step 2: Backup existing configuration
        const backup = {
            provider: window.ethereum,
            listeners: {}
        };
        
        // Step 3: Set compatibility
        window.ethereum = window.jcEthereum;
        window.ethereum.isMetaMask = true; // Compatible with MetaMask-dependent libraries
        
        // Step 4: Migrate event listeners
        ['accountsChanged', 'chainChanged', 'disconnect'].forEach(event => {
            const listeners = backup.provider?.listeners?.(event) || [];
            listeners.forEach(listener => {
                window.jucoin.on(event, listener);
            });
        });
        
        // Step 5: Test connection
        const accounts = await window.jcEthereum.request({
            method: 'eth_requestAccounts'
        });
        
        // Step 6: Verify functionality
        const chainId = await window.jcEthereum.request({
            method: 'eth_chainId'
        });
        
        console.log('✅ Migration successful!');
        console.log('- Connected account:', accounts[0]);
        console.log('- Current network:', chainId);
        console.log('- Provider:', window.ethereum);
        
        return {
            success: true,
            account: accounts[0],
            chainId: chainId
        };
        
    } catch (error) {
        console.error('❌ Migration failed:', error);
        return {
            success: false,
            error: error.message
        };
    }
}

// Usage
// await migrateToJuCoin();
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://jucoin-wallet.gitbook.io/jucoin-wallet-docs/developer-documentation-for-jucoin-wallet/developer-guide/6.-faq.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
