UNPKG

@gotake/gotake-sdk

Version:

SDK for interacting with GoTake blockchain contracts

465 lines (379 loc) โ€ข 17.8 kB
import { ethers } from 'ethers'; import { GoTakeSDK } from '../src'; import * as dotenv from 'dotenv'; dotenv.config(); // Removed unused interfaces to fix linting warnings interface ContentManagerOptions { batchSize?: number; confirmActions?: boolean; dryRun?: boolean; } // Removed unused ContentBatchConfig interface interface ContentSummary { contentId: number; status: string; error?: string; } class ContentManager { private sdk: GoTakeSDK; private options: ContentManagerOptions; constructor( private provider: ethers.providers.Provider, signer: ethers.Signer, options: ContentManagerOptions = {} ) { this.sdk = new GoTakeSDK({ provider: provider, signer: signer }); this.options = { batchSize: 10, confirmActions: true, dryRun: false, ...options }; } async checkAdminRights(): Promise<void> { console.log('\n๐Ÿ” Checking Admin Rights'); console.log('========================'); try { await this.sdk.videoPayment.init(); console.log('\nโœ… Admin rights verified - you can manage content'); } catch (error) { console.error('\nโŒ Admin rights check failed:', error.message); throw error; } } async createContent( contentId: number, priceETH: string, viewCount: number, durationHours: number, isActive: boolean = true ): Promise<void> { console.log(`\n๐Ÿ“ Creating Content ID: ${contentId}`); console.log('='.repeat(40)); try { const priceWei = ethers.utils.parseEther(priceETH); const durationSeconds = durationHours * 3600; console.log('\nContent Configuration:'); console.log(` Content ID: ${contentId}`); console.log(` Price: ${priceETH} ETH (${priceWei.toString()} wei)`); console.log(` View Count: ${viewCount}`); console.log(` Duration: ${durationHours} hours (${durationSeconds} seconds)`); console.log(` Active: ${isActive ? 'Yes' : 'No'}`); if (this.options.dryRun) { console.log('\n๐Ÿงช DRY RUN MODE - No actual transaction will be sent'); return; } console.log('\n๐Ÿ’พ Creating content...'); const txHash = await this.sdk.videoPayment.setContentConfig({ contentId, nativePrice: priceETH, defaultViewCount: viewCount, viewDuration: durationSeconds, isActive }); console.log(`โœ… Content created successfully!`); console.log(` Transaction Hash: ${txHash}`); console.log(` Content ID: ${contentId}`); // Wait for transaction confirmation console.log('\nโณ Waiting for transaction confirmation...'); const receipt = await this.provider.waitForTransaction(txHash); console.log(`โœ… Transaction confirmed in block ${receipt.blockNumber}`); } catch (error) { console.error(`โŒ Failed to create content ${contentId}:`, error.message); throw error; } } async batchCreateContent(configurations: Array<{ contentId: number; priceETH: string; viewCount: number; durationHours: number; isActive?: boolean; }>): Promise<void> { console.log(`\n๐Ÿ“ฆ Batch Creating ${configurations.length} Content Items`); console.log('='.repeat(60)); if (configurations.length === 0) { console.log('โŒ No configurations provided'); return; } // Prepare batch data const contentIds = configurations.map(c => c.contentId); const nativePrices = configurations.map(c => c.priceETH); const defaultViewCounts = configurations.map(c => c.viewCount); const viewDurations = configurations.map(c => c.durationHours * 3600); const isActiveArray = configurations.map(c => c.isActive ?? true); console.log('Batch Configuration Summary:'); configurations.forEach((config, index) => { console.log(` ${index + 1}. Content ${config.contentId}: ${config.priceETH} ETH, ${config.viewCount} views, ${config.durationHours}h, ${config.isActive ? 'Active' : 'Inactive'}`); }); if (this.options.dryRun) { console.log('\n๐Ÿงช DRY RUN MODE - No actual transaction will be sent'); return; } try { console.log('\n๐Ÿ’พ Executing batch content creation...'); const txHash = await this.sdk.videoPayment.batchSetContentConfig({ contentIds, nativePrices, defaultViewCounts, viewDurations, isActiveArray }); console.log(`โœ… Batch content creation successful!`); console.log(` Transaction Hash: ${txHash}`); console.log(` Created ${configurations.length} content items`); // Wait for transaction confirmation console.log('\nโณ Waiting for transaction confirmation...'); const receipt = await this.provider.waitForTransaction(txHash); console.log(`โœ… Transaction confirmed in block ${receipt.blockNumber}`); } catch (error) { console.error('โŒ Batch content creation failed:', error.message); throw error; } } async updateContentPrice(contentId: number, newPriceETH: string): Promise<void> { console.log(`\n๐Ÿ’ฐ Updating Price for Content ID: ${contentId}`); console.log('='.repeat(50)); try { console.log(`New Price: ${newPriceETH} ETH`); if (this.options.dryRun) { console.log('\n๐Ÿงช DRY RUN MODE - No actual transaction will be sent'); return; } console.log('\n๐Ÿ’พ Updating price...'); const txHash = await this.sdk.videoPayment.updateContentPrice( contentId, ethers.utils.parseEther(newPriceETH) ); console.log(`โœ… Price updated successfully!`); console.log(` Transaction Hash: ${txHash}`); console.log(` Content ID: ${contentId}`); console.log(` New Price: ${newPriceETH} ETH`); } catch (error) { console.error(`โŒ Failed to update price for content ${contentId}:`, error.message); throw error; } } async bulkUpdatePrices(updates: Array<{ contentId: number; newPriceETH: string }>): Promise<void> { console.log(`\n๐Ÿ’ฐ Bulk Price Update (${updates.length} items)`); console.log('='.repeat(50)); console.log('Price Update Summary:'); updates.forEach((update, index) => { console.log(` ${index + 1}. Content ${update.contentId}: ${update.newPriceETH} ETH`); }); if (this.options.dryRun) { console.log('\n๐Ÿงช DRY RUN MODE - No actual transactions will be sent'); return; } let successful = 0; let failed = 0; for (const update of updates) { try { console.log(`\n๐Ÿ’พ Updating Content ${update.contentId}...`); await this.updateContentPrice(update.contentId, update.newPriceETH); successful++; console.log(`โœ… Success`); } catch (error) { console.error(`โŒ Failed: ${error.message}`); failed++; } } console.log(`\n๐Ÿ“Š Bulk Update Results:`); console.log(` Successful: ${successful}`); console.log(` Failed: ${failed}`); console.log(` Success Rate: ${((successful / updates.length) * 100).toFixed(1)}%`); } async listContentStatus(contentIds: number[]): Promise<ContentSummary[]> { console.log(`\n๐Ÿ“‹ Content Status Check (${contentIds.length} items)`); console.log('='.repeat(60)); const summaries: ContentSummary[] = []; for (const contentId of contentIds) { try { // Simple status check - just verify if we can access the content console.log(`Checking Content ${contentId}...`); await this.sdk.videoPayment.init(); summaries.push({ contentId, status: 'Accessible' }); } catch (error) { console.error(`โŒ Failed to check content ${contentId}:`, error.message); summaries.push({ contentId, status: 'Error', error: error.message }); } } // Display content table this.displayContentTable(summaries); return summaries; } private displayContentTable(summaries: ContentSummary[]): void { console.log('\n๐Ÿ“Š Content Status Table:'); console.log('โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”'); console.log('โ”‚ Content ID โ”‚ Status โ”‚'); console.log('โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค'); summaries.forEach(summary => { const contentId = summary.contentId.toString().padStart(10); const status = summary.status.padStart(12); console.log(`โ”‚ ${contentId} โ”‚ ${status} โ”‚`); }); console.log('โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜'); // Summary statistics const accessibleCount = summaries.filter(s => s.status === 'Accessible').length; const errorCount = summaries.length - accessibleCount; console.log(`\n๐Ÿ“ˆ Summary Statistics:`); console.log(` Total Content: ${summaries.length}`); console.log(` Accessible: ${accessibleCount} (${((accessibleCount / summaries.length) * 100).toFixed(1)}%)`); console.log(` Errors: ${errorCount} (${((errorCount / summaries.length) * 100).toFixed(1)}%)`); } async generateContentReport(contentIds: number[]): Promise<void> { console.log('\n๐Ÿ“Š Generating Content Report'); console.log('='.repeat(50)); const summaries = await this.listContentStatus(contentIds); console.log('\n๐Ÿ“ˆ Report Analysis:'); const accessibleContent = summaries.filter(s => s.status === 'Accessible'); const errorContent = summaries.filter(s => s.status === 'Error'); if (accessibleContent.length > 0) { console.log(`\nโœ… Accessible Content: ${accessibleContent.length} items`); accessibleContent.forEach(s => { console.log(` โ€ข Content ${s.contentId}: Ready for use`); }); } if (errorContent.length > 0) { console.log(`\nโŒ Content with Errors: ${errorContent.length} items`); errorContent.forEach(s => { console.log(` โ€ข Content ${s.contentId}: ${s.error}`); }); } console.log('\n๐Ÿ’ก Recommendations:'); if (errorContent.length > 0) { console.log(` โ€ข Review and fix ${errorContent.length} content items with errors`); } if (accessibleContent.length > 0) { console.log(` โ€ข ${accessibleContent.length} content items are ready for use`); } console.log('\nโœ… Report generation complete'); } } async function main() { console.log('๐ŸŽ›๏ธ GoTake Content Manager'); console.log('==========================\n'); // Environment configuration const PROVIDER_URL = process.env.PROVIDER_URL || 'https://sepolia.base.org'; const PRIVATE_KEY = process.env.PRIVATE_KEY; if (!PRIVATE_KEY) { console.error('โŒ Please set PRIVATE_KEY environment variable'); process.exit(1); } try { // Initialize provider and signer const provider = new ethers.providers.JsonRpcProvider(PROVIDER_URL); const signer = new ethers.Wallet(PRIVATE_KEY, provider); // Parse command line options const isDryRun = process.argv.includes('--dry-run'); const skipConfirm = process.argv.includes('--no-confirm'); const manager = new ContentManager(provider, signer, { dryRun: isDryRun, confirmActions: !skipConfirm }); // Check admin rights first await manager.checkAdminRights(); // Parse command const command = process.argv[2]; switch (command) { case 'create': // Create single content const contentId = parseInt(process.argv[3]); const price = process.argv[4]; const views = parseInt(process.argv[5]); const hours = parseInt(process.argv[6]); const active = process.argv[7] !== 'false'; if (!contentId || !price || !views || !hours) { console.error('Usage: npm run manage-content create <contentId> <priceETH> <viewCount> <durationHours> [active]'); process.exit(1); } await manager.createContent(contentId, price, views, hours, active); break; case 'batch-create': // Batch create content from configuration const batchConfig = [ { contentId: 10, priceETH: '0.001', viewCount: 5, durationHours: 24 }, { contentId: 11, priceETH: '0.002', viewCount: 10, durationHours: 48 }, { contentId: 12, priceETH: '0.005', viewCount: 20, durationHours: 72 } ]; await manager.batchCreateContent(batchConfig); break; case 'update-price': // Update single content price const updateContentId = parseInt(process.argv[3]); const newPrice = process.argv[4]; if (!updateContentId || !newPrice) { console.error('Usage: npm run manage-content update-price <contentId> <newPriceETH>'); process.exit(1); } await manager.updateContentPrice(updateContentId, newPrice); break; case 'list': // List all content const defaultContentIds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; await manager.listContentStatus(defaultContentIds); break; case 'list-range': // List content in range const startId = parseInt(process.argv[3]); const endId = parseInt(process.argv[4]); if (!startId || !endId) { console.error('Usage: npm run manage-content list-range <startId> <endId>'); process.exit(1); } const rangeIds = Array.from({ length: endId - startId + 1 }, (_, i) => startId + i); await manager.listContentStatus(rangeIds); break; case 'bulk-price-update': // Bulk update prices const priceUpdates = [ { contentId: 1, newPriceETH: '0.001' }, { contentId: 2, newPriceETH: '0.002' }, { contentId: 3, newPriceETH: '0.003' } ]; await manager.bulkUpdatePrices(priceUpdates); break; case 'report': // Generate comprehensive report const reportContentIds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; await manager.generateContentReport(reportContentIds); break; default: console.log('Available commands:'); console.log(' create <id> <price> <views> <hours> [active] - Create single content'); console.log(' batch-create - Create multiple content (predefined)'); console.log(' update-price <id> <newPrice> - Update content price'); console.log(' list - List all content (default IDs)'); console.log(' list-range <start> <end> - List content in ID range'); console.log(' bulk-price-update - Bulk update prices (predefined)'); console.log(' report - Generate comprehensive report'); console.log('\nOptions:'); console.log(' --dry-run - Simulate operations without executing'); console.log(' --no-confirm - Skip confirmation prompts'); console.log('\nExamples:'); console.log(' npm run manage-content create 1 0.01 10 24 true'); console.log(' npm run manage-content update-price 1 0.02'); console.log(' npm run manage-content list-range 1 20'); console.log(' npm run manage-content report --dry-run'); break; } } catch (error) { console.error('โŒ Content management operation failed:', error); console.error('Details:', error.message); process.exit(1); } } // Run the script if (require.main === module) { main().catch(console.error); }