import { ethers } from 'ethers'; import { GoTakeSDK, NetworkId, getNetworkById, getNetworkByName } from '../src'; import * as dotenv from 'dotenv'; // Load environment variables dotenv.config(); interface ContentDebugInfo { contentId: number; nativePrice: ethers.BigNumber; viewCount: number; isActive: boolean; tokenPrices: Record; executionTime: number; blockNumber?: number; gasPrice?: ethers.BigNumber; } /** * Content Info Debugger for testing getContentInfo method */ class ContentInfoDebugger { private sdk: GoTakeSDK; private provider: ethers.providers.JsonRpcProvider; private signer: ethers.Signer; constructor(network: NetworkId, signer: ethers.Signer, provider: ethers.providers.JsonRpcProvider) { this.provider = provider; this.signer = signer; this.sdk = new GoTakeSDK({ network: network, signer: signer }); } /** * Debug content info for a specific content ID */ async debugContentInfo(contentId: number): Promise { console.log(`\nšŸ” Debugging Content Info for ID: ${contentId}`); console.log('='.repeat(60)); const startTime = Date.now(); try { // Get network status await this.displayNetworkStatus(); // Call getContentInfo console.log(`šŸ“ž Calling getContentInfo(${contentId})...`); const contentInfo = await this.sdk.videoPayment.getContentInfo(contentId); const executionTime = Date.now() - startTime; const blockNumber = await this.provider.getBlockNumber(); const gasPrice = await this.provider.getGasPrice(); const debugInfo: ContentDebugInfo = { contentId: contentInfo.contentId, nativePrice: contentInfo.nativePrice, viewCount: contentInfo.viewCount, isActive: contentInfo.isActive, tokenPrices: contentInfo.tokenPrices, executionTime, blockNumber, gasPrice }; await this.displayDetailedInfo(debugInfo); this.displayPerformanceStats(debugInfo); return debugInfo; } catch (error) { const executionTime = Date.now() - startTime; console.error(`āŒ Error debugging content ${contentId}:`, error); // Display error details await this.displayErrorDetails(error, contentId, executionTime); throw error; } } /** * Display network connection status */ private async displayNetworkStatus(): Promise { console.log('🌐 Network Status:'); try { const networkInfo = await this.provider.getNetwork(); const blockNumber = await this.provider.getBlockNumber(); const gasPrice = await this.provider.getGasPrice(); const userAddress = await this.signer.getAddress(); console.log(` Network Name: ${networkInfo.name}`); console.log(` Chain ID: ${networkInfo.chainId}`); console.log(` Current Block: ${blockNumber}`); console.log(` Gas Price: ${ethers.utils.formatUnits(gasPrice, 'gwei')} Gwei`); console.log(` User Address: ${userAddress}`); console.log(` Connection: āœ… Connected`); } catch (error) { console.log(` Connection: āŒ Failed - ${error.message}`); throw error; } } /** * Display detailed content information */ private async displayDetailedInfo(debugInfo: ContentDebugInfo): Promise { console.log('\nšŸ“Š Content Information:'); console.log('ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”'); console.log('│ Field │ Value │'); console.log('ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤'); console.log(`│ Content ID │ ${debugInfo.contentId.toString().padEnd(38)} │`); console.log(`│ Active Status │ ${(debugInfo.isActive ? 'āœ… Active' : 'āŒ Inactive').padEnd(38)} │`); console.log(`│ View Count │ ${debugInfo.viewCount.toString().padEnd(38)} │`); console.log(`│ Native Price (ETH) │ ${ethers.utils.formatEther(debugInfo.nativePrice).padEnd(38)} │`); console.log(`│ Native Price (Wei) │ ${debugInfo.nativePrice.toString().padEnd(38)} │`); console.log('ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜'); // Display token prices console.log('\nšŸ’° Token Prices:'); const tokenEntries = Object.entries(debugInfo.tokenPrices); if (tokenEntries.length === 0) { console.log(' No token prices available'); } else { console.log('ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”'); console.log('│ Token Address │ Price │'); console.log('ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤'); tokenEntries.forEach(([tokenAddress, price]) => { const displayAddress = tokenAddress === ethers.constants.AddressZero ? 'ETH (Native)'.padEnd(44) : `${tokenAddress.slice(0, 42)}`.padEnd(44); const displayPrice = tokenAddress === ethers.constants.AddressZero ? `${ethers.utils.formatEther(price)} ETH` : `${ethers.utils.formatUnits(price, 18)} Tokens`; console.log(`│ ${displayAddress} │ ${displayPrice.padEnd(18)} │`); }); console.log('ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜'); } } /** * Display performance statistics */ private displayPerformanceStats(debugInfo: ContentDebugInfo): void { console.log('\n⚔ Performance Statistics:'); console.log(` Execution Time: ${debugInfo.executionTime}ms`); console.log(` Block Number: ${debugInfo.blockNumber}`); console.log(` Gas Price: ${debugInfo.gasPrice ? ethers.utils.formatUnits(debugInfo.gasPrice, 'gwei') + ' Gwei' : 'N/A'}`); // Performance indicators if (debugInfo.executionTime < 1000) { console.log(` Performance: āœ… Excellent (< 1s)`); } else if (debugInfo.executionTime < 3000) { console.log(` Performance: āš ļø Good (1-3s)`); } else { console.log(` Performance: āŒ Slow (> 3s)`); } } /** * Display error details for debugging */ private async displayErrorDetails(error: any, contentId: number, executionTime: number): Promise { console.log('\nāŒ Error Details:'); console.log(` Content ID: ${contentId}`); console.log(` Execution Time: ${executionTime}ms`); console.log(` Error Type: ${error.constructor.name}`); console.log(` Error Message: ${error.message}`); if (error.code) { console.log(` Error Code: ${error.code}`); } if (error.data) { console.log(` Error Data: ${JSON.stringify(error.data, null, 2)}`); } // Try to get current network status for debugging try { const blockNumber = await this.provider.getBlockNumber(); console.log(` Current Block: ${blockNumber}`); } catch (networkError) { console.log(` Network Status: āŒ Unable to connect`); } // Suggest troubleshooting steps console.log('\nšŸ’” Troubleshooting Suggestions:'); console.log(' 1. Check if content ID exists on the network'); console.log(' 2. Verify contract deployment on the target network'); console.log(' 3. Check network connection and RPC endpoint'); console.log(' 4. Verify wallet has sufficient funds for gas'); console.log(' 5. Check if content is properly configured'); } /** * Batch debug multiple content IDs */ async batchDebugContentInfo(contentIds: number[]): Promise { console.log(`\nšŸ”„ Batch Debugging ${contentIds.length} Content IDs`); console.log('='.repeat(60)); const results: ContentDebugInfo[] = []; const errors: { contentId: number; error: any }[] = []; for (const contentId of contentIds) { try { const result = await this.debugContentInfo(contentId); results.push(result); console.log(`āœ… Content ${contentId}: Success`); } catch (error) { console.log(`āŒ Content ${contentId}: Failed`); errors.push({ contentId, error }); } } // Display batch summary console.log('\nšŸ“Š Batch Summary:'); console.log(` Total: ${contentIds.length}`); console.log(` Success: ${results.length}`); console.log(` Errors: ${errors.length}`); if (errors.length > 0) { console.log('\nāŒ Failed Content IDs:'); errors.forEach(({ contentId, error }) => { console.log(` • Content ${contentId}: ${error.message}`); }); } return results; } } async function main() { console.log('šŸ”¬ GoTake Content Info Debugger'); console.log('================================\n'); // Environment configuration const NETWORK = process.env.NETWORK || 'Base Sepolia'; const PRIVATE_KEY = process.env.PRIVATE_KEY; if (!PRIVATE_KEY) { console.error('āŒ Please set PRIVATE_KEY environment variable'); console.log('Example: export PRIVATE_KEY="your-private-key-here"'); process.exit(1); } try { // Resolve network configuration let networkConfig; if (typeof NETWORK === 'string' && !isNaN(Number(NETWORK))) { const networkId = Number(NETWORK) as NetworkId; networkConfig = getNetworkById(networkId); } else { networkConfig = getNetworkByName(NETWORK); } if (!networkConfig) { console.error(`āŒ Unsupported network: ${NETWORK}`); console.log('Supported networks: Base Mainnet, Base Sepolia'); process.exit(1); } console.log(`🌐 Network: ${networkConfig.name} (ID: ${networkConfig.id})`); console.log(`šŸ”— RPC: ${networkConfig.rpcUrl}\n`); // Create provider and signer const provider = new ethers.providers.JsonRpcProvider(networkConfig.rpcUrl); const signer = new ethers.Wallet(PRIVATE_KEY, provider); const contentDebugger = new ContentInfoDebugger(networkConfig.id, signer, provider); // Get command line arguments const command = process.argv[2]; const contentIdArg = process.argv[3]; switch (command) { case 'debug': const contentId = contentIdArg ? parseInt(contentIdArg) : 8888; if (isNaN(contentId)) { console.error('āŒ Invalid content ID provided'); process.exit(1); } await contentDebugger.debugContentInfo(contentId); break; case 'batch': const contentIds = process.argv.slice(3).map(id => parseInt(id)).filter(id => !isNaN(id)); if (contentIds.length === 0) { console.error('āŒ Please provide at least one content ID'); console.log('Usage: npm run debug-content-info batch 8888 1234 5678'); process.exit(1); } await contentDebugger.batchDebugContentInfo(contentIds); break; case 'help': default: console.log('šŸ“– Available commands:'); console.log(' debug [contentId] - Debug single content (default: 8888)'); console.log(' batch [id2] [id3]... - Debug multiple content IDs'); console.log(' help - Show this help message'); console.log('\n🌟 Examples:'); console.log(' npm run debug-content-info debug 8888'); console.log(' npm run debug-content-info debug'); console.log(' npm run debug-content-info batch 8888 1234 5678'); console.log('\nšŸ”§ Environment Variables:'); console.log(' PRIVATE_KEY - Your wallet private key (required)'); console.log(' NETWORK - Target network (default: Base Sepolia)'); console.log('\nšŸ“‹ Supported Networks:'); console.log(' - Base Mainnet'); console.log(' - Base Sepolia'); break; } } catch (error) { console.error('āŒ Debug failed:', error); process.exit(1); } } // Run the script if (require.main === module) { main().catch(console.error); }