@gotake/gotake-sdk
Version:
SDK for interacting with GoTake blockchain contracts
166 lines (142 loc) • 6.4 kB
text/typescript
/**
* Unified Video Upload and Mint Script
*
* This script demonstrates the one-step method to upload a video and mint an NFT
* when processing is complete.
*
* 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-and-mint
* or
* yarn upload-and-mint
*/
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';
}
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 One-Step Upload and Mint 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 (done automatically by the unified method)
console.log("\nChecking TBA account...");
// Step 2: Prepare video file
console.log("\nPreparing video file...");
const videoFile = createFileFromPath(videoFilePath);
console.log(`Video file: ${videoFile.name} (${videoFile.size} bytes)`);
const videoMetadata = {
title: "One-Step Upload Demo",
description: "This video was uploaded and minted in one step",
tags: ["demo", "sdk", "one-step"],
creator: userAddress
};
// Step 3: Use the unified method to upload and mint
console.log("\n=== Starting Unified Upload and Mint Process ===");
console.log("This will automatically upload, monitor, and mint when ready");
// Track process completion
let processCompleted = false;
// Use the unified method
const videoId = await sdk.uploadAndMintWhenReady(
videoFile,
videoMetadata,
{
statusCallback: (status) => {
console.log(`Status update: ${status.status}, Progress: ${status.progress || 'unknown'}%`);
if (status.status === VideoStatus.COMPLETED) {
console.log("\n=== Process Completed Successfully ===");
console.log(`Video ID: ${videoId}`);
if (status.mintInfo) {
console.log(`NFT Token ID: ${status.mintInfo.tokenId}`);
console.log(`NFT Transaction: ${status.mintInfo.transactionHash}`);
}
if (status.assetInfo?.playbackUrl) {
console.log(`Playback URL: ${status.assetInfo.playbackUrl}`);
}
processCompleted = true;
} else if (status.status === VideoStatus.ERROR) {
console.error(`Error: ${status.error?.message || 'Unknown error'}`);
processCompleted = true;
}
},
autoMint: true // Automatically mint when video is ready
}
);
console.log(`Process started! Video ID: ${videoId}`);
console.log("The process will continue in the background.");
console.log("Status updates will be displayed via the callback.");
// Wait for process to complete or timeout after 10 minutes
const timeout = 10 * 60 * 1000; // 10 minutes
const startTime = Date.now();
while (!processCompleted && (Date.now() - startTime < timeout)) {
await new Promise(resolve => setTimeout(resolve, 5000)); // Check every 5 seconds
// Check status directly if needed
if (!processCompleted && (Date.now() - startTime) % 30000 < 5000) { // Every 30 seconds
const status = await sdk.getVideoStatus(videoId);
console.log(`Current status: ${status.status}`);
}
}
if (!processCompleted) {
console.log("\nTimeout reached but process is still running in the background.");
console.log(`You can check the status later using the video ID: ${videoId}`);
}
} catch (error) {
console.error("Error during upload and mint process:");
console.error(error);
process.exitCode = 1;
}
}
main().catch(error => {
console.error("Error executing script:");
console.error(error);
process.exitCode = 1;
});