@gotake/gotake-sdk
Version:
SDK for interacting with GoTake blockchain contracts
175 lines (150 loc) • 6.55 kB
text/typescript
/**
* Video Upload and NFT Minting Script
*
* This script demonstrates the complete video upload flow including:
* 1. Checking and creating a TBA (Token Bound Account)
* 2. Uploading a video to the platform
* 3. Monitoring video processing status
* 4. Minting an IP NFT
*
* Usage:
* 1. Create a .env file and set the following environment variables:
* - PRIVATE_KEY: Private key of the NFT holder
* - API_KEY: GoodTake API key (optional)
*
* 2. Prepare a test video file and place it in scripts/assets/ directory
*
* 3. Run the script:
* npm run upload-video
* or
* yarn upload-video
*/
import { GoTakeSDK, NetworkId, VideoStatus } from "../src";
import * as dotenv from 'dotenv';
import { ethers } from 'ethers';
import * as fs from 'fs';
import * as path from 'path';
import { Blob } from 'fetch-blob';
import File from 'fetch-blob/file';
dotenv.config();
// Utility function: Convert file system file to browser File object
function createFileFromPath(filePath: string): File {
const fileName = path.basename(filePath);
const fileBuffer = fs.readFileSync(filePath);
const fileBlob = new Blob([fileBuffer]);
return new File([fileBlob], fileName, { type: getMimeType(fileName) });
}
// Utility function: Get MIME type based on file extension
function getMimeType(fileName: string): string {
const ext = fileName.split('.').pop()?.toLowerCase();
const mimeTypes: Record<string, string> = {
'mp4': 'video/mp4',
'mov': 'video/quicktime',
'avi': 'video/x-msvideo',
'webm': 'video/webm'
};
return mimeTypes[ext || ''] || 'application/octet-stream';
}
// Utility function: Wait for specified time
function sleep(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function main() {
// Check required environment variables
if (!process.env.PRIVATE_KEY) {
throw new Error("PRIVATE_KEY is not defined in environment variables. Please set it in your .env file");
}
const videoFilePath = path.join(__dirname, 'assets', 'sample-video.mp4');
if (!fs.existsSync(videoFilePath)) {
throw new Error(`Test video file not found: ${videoFilePath}`);
}
try {
console.log("=== GoodTake Video Upload Demo ===");
// Create Provider and Signer
const rpcUrl = "https://sepolia.base.org";
const ethersProvider = new ethers.providers.JsonRpcProvider(rpcUrl);
const ethersSigner = new ethers.Wallet(process.env.PRIVATE_KEY, ethersProvider);
const userAddress = await ethersSigner.getAddress();
console.log(`Using address: ${userAddress}`);
// Initialize SDK
const sdk = new GoTakeSDK({
network: NetworkId.BASE_SEPOLIA,
provider: ethersProvider,
signer: ethersSigner,
apiEndpoint: process.env.API_ENDPOINT || 'https://api.goodtake.io',
apiKey: process.env.API_KEY
});
console.log("SDK initialized successfully");
// Step 1: Check and create TBA if needed
console.log("\n=== Step 1: Check/Create TBA ===");
const { tbaAddress, isNew } = await sdk.checkAndCreateTBA();
if (isNew) {
console.log(`Created new TBA: ${tbaAddress}`);
} else {
console.log(`Using existing TBA: ${tbaAddress}`);
}
// Step 2: Prepare video file and upload
console.log("\n=== Step 2: Upload Video ===");
const videoFile = createFileFromPath(videoFilePath);
console.log(`Preparing to upload: ${videoFile.name} (${videoFile.size} bytes)`);
const videoMetadata = {
title: "GoodTake Test Video",
description: "This is a test video uploaded via SDK",
tags: ["test", "sdk", "demo"],
creator: userAddress
};
console.log("Uploading video...");
const videoId = await sdk.uploadVideo(videoFile, videoMetadata);
console.log(`Video uploaded successfully! Video ID: ${videoId}`);
// Step 3: Monitor video processing status
console.log("\n=== Step 3: Monitor Video Processing ===");
console.log("Setting up status monitoring...");
// Method A: Using polling
console.log("Using polling to monitor processing:");
let videoReady = false;
while (!videoReady) {
const status = await sdk.getVideoStatus(videoId);
console.log(`Current status: ${status.status}, Progress: ${status.progress || 'unknown'}%`);
if (status.status === VideoStatus.READY || status.status === VideoStatus.MINT_READY) {
videoReady = true;
console.log("Video processing completed, ready for minting");
} else if (status.status === VideoStatus.ERROR) {
throw new Error(`Video processing failed: ${status.error?.message || 'Unknown error'}`);
} else {
console.log("Waiting for processing to complete...");
await sleep(5000);
}
}
// Step 4: Mint IP NFT
console.log("\n=== Step 4: Mint IP NFT ===");
console.log("Starting NFT minting...");
const mintResult = await sdk.mintIPNFT(videoId);
console.log("NFT minted successfully!");
console.log(`Token ID: ${mintResult.tokenId}`);
console.log(`Transaction Hash: ${mintResult.transactionHash}`);
console.log(`Owner: ${mintResult.owner}`);
console.log(`Metadata: ${JSON.stringify(mintResult.metadata, null, 2)}`);
// Display final status
const finalStatus = await sdk.getVideoStatus(videoId);
console.log("\n=== Final Status ===");
console.log(`Video ID: ${videoId}`);
console.log(`Status: ${finalStatus.status}`);
if (finalStatus.assetInfo?.playbackUrl) {
console.log(`Playback URL: ${finalStatus.assetInfo.playbackUrl}`);
}
if (finalStatus.mintInfo) {
console.log(`NFT Token ID: ${finalStatus.mintInfo.tokenId}`);
console.log(`NFT Transaction: ${finalStatus.mintInfo.transactionHash}`);
}
console.log("\nProcess completed! Video uploaded and minted as NFT successfully.");
} catch (error) {
console.error("Error during video upload process:");
console.error(error);
process.exitCode = 1;
}
}
main().catch(error => {
console.error("Error executing script:");
console.error(error);
process.exitCode = 1;
});