@gotake/gotake-sdk
Version:
SDK for interacting with GoTake blockchain contracts
465 lines (379 loc) โข 17.8 kB
text/typescript
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);
}