@gotake/gotake-sdk
Version:
SDK for interacting with GoTake blockchain contracts
268 lines (267 loc) • 10.2 kB
JavaScript
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);
}
}
}