UNPKG

@gotake/gotake-sdk

Version:

SDK for interacting with GoTake blockchain contracts

268 lines (267 loc) 10.2 kB
import { ethers } from 'ethers'; import { BaseApi } from './base-api.js'; import { VideoPaymentWrapper } from '../wrappers/index.js'; /** * High-level API for VideoPayment contract interactions * Provides user-friendly interfaces for purchasing and managing video content */ export class VideoPaymentApi extends BaseApi { /** * Create VideoPaymentApi instance * @param provider Provider instance * @param signer Signer instance */ constructor(provider, signer) { super(provider, signer); this._videoPaymentWrapper = null; } /** * Initialize VideoPayment wrapper */ async getVideoPaymentWrapper() { if (!this._videoPaymentWrapper) { this._videoPaymentWrapper = new VideoPaymentWrapper(this._provider, this._signer); await this._videoPaymentWrapper.init(); } return this._videoPaymentWrapper; } /** * Initialize the API */ async init() { await this.getVideoPaymentWrapper(); } // Purchase Functions /** * Purchase content with specified payment method * @param contentId Content ID to purchase * @param paymentMethod Payment method: 'ETH' or 'ERC20' * @param tokenAddress ERC20 token address (required for ERC20 payment) * @param options Transaction options * @returns Purchase result */ async purchaseContent(contentId, paymentMethod, tokenAddress, options) { const wrapper = await this.getVideoPaymentWrapper(); if (paymentMethod === 'ETH') { const tx = await wrapper.purchaseWithNative(contentId, options); const receipt = await tx.wait(); return { transactionHash: tx.hash, contentId, gasUsed: receipt.gasUsed }; } else { if (!tokenAddress) { throw new Error('Token address is required for ERC20 payment'); } // For ERC20, we need to get the token amount first // This is a simplified implementation - in practice you might want to expose this throw new Error('ERC20 payment requires token amount - use wrapper directly for ERC20 payments'); } } /** * Batch purchase multiple content items * @param contentIds Array of content IDs to purchase * @param paymentMethod Payment method: 'ETH' or 'ERC20' * @param tokenAddress ERC20 token address (required for ERC20 payment) * @param options Transaction options * @returns Purchase result */ async batchPurchaseContent(contentIds, paymentMethod, tokenAddress, options) { const wrapper = await this.getVideoPaymentWrapper(); if (paymentMethod === 'ETH') { const tx = await wrapper.batchPurchaseWithNative(contentIds, options); const receipt = await tx.wait(); return { transactionHash: tx.hash, contentId: contentIds[0], // First content ID as reference gasUsed: receipt.gasUsed }; } else { if (!tokenAddress) { throw new Error('Token address is required for ERC20 payment'); } throw new Error('ERC20 batch payment requires total amount - use wrapper directly for ERC20 payments'); } } // Permission Functions /** * Check if current user has view permission for content * @param contentId Content ID * @returns True if user has valid view permission */ async hasViewPermission(contentId) { const wrapper = await this.getVideoPaymentWrapper(); const userAddress = await this._signer.getAddress(); return wrapper.hasViewPermission(userAddress, contentId); } /** * Get current user's permission details for content * @param contentId Content ID * @returns View permission details */ async getMyPermissions(contentId) { const wrapper = await this.getVideoPaymentWrapper(); const userAddress = await this._signer.getAddress(); const details = await wrapper.getPermissionDetails(userAddress, contentId); return { purchaseTime: details.purchaseTime, remainingViews: details.remainingViews, isValid: details.isValid }; } /** * Get content configuration information * @param contentId Content ID * @returns Content configuration */ async getContentInfo(contentId) { // Suppress unused parameter warning for incomplete implementation void contentId; // Note: This method doesn't exist in the contract interface we saw // We need to implement it or use individual calls throw new Error('getContentInfo method needs to be implemented based on available contract methods'); } /** * Batch get content information for multiple items * @param contentIds Array of content IDs * @returns Array of content configurations */ async batchGetContentInfo(contentIds) { // Since there's no batch method in the contract, we do individual calls const results = []; for (const contentId of contentIds) { try { const info = await this.getContentInfo(contentId); results.push(info); } catch (error) { throw error; // Fail fast as per user requirements } } return results; } /** * Batch check user permissions for multiple content items * @param userAddress User address * @param contentIds Array of content IDs * @returns Array of permission results */ async batchCheckUserPermissions(userAddress, contentIds) { const wrapper = await this.getVideoPaymentWrapper(); try { // Use the contract's batch method const permissions = await wrapper.getUserPermissions(userAddress, contentIds); return permissions.map((permission) => ({ hasPermission: permission.isValid, permissionDetails: permission })); } catch (error) { throw error; // Fail fast as per user requirements } } // Admin Functions /** * Get current user's admin role information * @returns Admin role information */ async getMyAdminRole() { // This would need to be implemented based on available contract methods // For now, returning a placeholder return { isOwner: false, isAdmin: false, canManageContent: false, canManageTokens: false, canManageAdmins: false }; } /** * Set content configuration (Admin only) * @param config Content configuration * @param options Transaction options * @returns Transaction hash */ async setContentConfig(config, options) { const wrapper = await this.getVideoPaymentWrapper(); const tx = await wrapper.setContentConfig(config.contentId, ethers.utils.parseEther(config.nativePrice), config.defaultViewCount, config.viewDuration, config.isActive, options); return tx.hash; } /** * Batch set content configurations (Admin only) * @param configs Array of content configurations * @param options Transaction options * @returns Transaction hash */ async batchSetContentConfig(configs, options) { const wrapper = await this.getVideoPaymentWrapper(); const nativePricesWei = configs.nativePrices.map(price => ethers.utils.parseEther(price)); const tx = await wrapper.batchSetContentConfig(configs.contentIds, nativePricesWei, configs.defaultViewCounts, configs.viewDurations, configs.isActiveArray, options); return tx.hash; } /** * Update content price (Admin only) * @param contentId Content ID * @param newPrice New price in ETH * @param options Transaction options * @returns Transaction hash */ async updateContentPrice(contentId, newPrice, options) { const wrapper = await this.getVideoPaymentWrapper(); const tx = await wrapper.updateNativePrice(contentId, newPrice, options); return tx.hash; } /** * Set content active status (Admin only) * @param contentId Content ID * @param isActive Active status * @param options Transaction options * @returns Transaction hash */ async setContentActive(contentId, isActive, options) { // Suppress unused parameter warnings for incomplete implementation void contentId; void isActive; void options; // This method doesn't exist in the contract interface we saw // We might need to use setContentConfig with current values throw new Error('setContentActive method needs to be implemented'); } /** * Check if user has view permission (wrapper for external address) * @param userAddress User address * @param contentId Content ID * @returns True if user has valid view permission */ async userHasViewPermission(userAddress, contentId) { const wrapper = await this.getVideoPaymentWrapper(); return wrapper.hasViewPermission(userAddress, contentId); } /** * Get user permissions (wrapper for external address) * @param userAddress User address * @param contentId Content ID * @returns View permission details */ async getUserPermissions(userAddress, contentId) { const wrapper = await this.getVideoPaymentWrapper(); const details = await wrapper.getPermissionDetails(userAddress, contentId); return { purchaseTime: details.purchaseTime, remainingViews: details.remainingViews, isValid: details.isValid }; } /** * Process connection update */ async onConnectionUpdated() { await super.onConnectionUpdated(); if (this._videoPaymentWrapper) { this._videoPaymentWrapper.updateConnection(this._provider, this._signer); } } }