UNPKG

@gotake/gotake-sdk

Version:

SDK for interacting with GoTake blockchain contracts

213 lines (212 loc) 8.32 kB
import { ethers } from 'ethers'; import { IPNFT__factory } from 'gotake-contracts/dist/typechain/factories/contracts/IPNFT__factory.js'; import { BaseTransactionWrapper } from './base-transaction-wrapper.js'; /** * Wrapper for IPNFT contract, used for minting and managing IP NFTs */ export class IPNFTWrapper extends BaseTransactionWrapper { /** * Create IPNFT wrapper instance * @param provider Provider instance * @param signer Signer instance */ constructor(provider, signer) { super(provider, signer); this._ipnft = null; } /** * Get IPNFT contract instance * @returns IPNFT contract instance */ async getIPNFT() { // Ensure networkId is initialized await this.init(); if (!this._ipnft) { const address = this.getContractAddress('ipnft'); this._ipnft = IPNFT__factory.connect(address, this._signer); } return this._ipnft; } /** * Mint a new IPNFT (New Contract Interface) * @param to Recipient address * @param uri Metadata URI * @param options Transaction options * @returns Transaction object and minted NFT ID */ async mint(to, uri, options) { var _a; const ipnft = await this.getIPNFT(); const overrides = this.createOverrides(options === null || options === void 0 ? void 0 : options.gasConfig); const tx = await ipnft.mint(to, uri, overrides); const receipt = await tx.wait(); const transferEvent = (_a = receipt.events) === null || _a === void 0 ? void 0 : _a.find(event => { return event.event === 'MediaNFTMinted' || event.event === 'Transfer'; }); if (!transferEvent || !transferEvent.args) { throw new Error('Unable to get TokenId from transaction'); } const tokenId = transferEvent.args.tokenId; return { tx, tokenId }; } /** * Set media information for a token * @param tokenId Token ID * @param mediaData Media information data * @param options Transaction options * @returns Transaction object */ async setMediaInfo(tokenId, mediaData, options) { const ipnft = await this.getIPNFT(); const tokenIdBN = ethers.BigNumber.from(tokenId); // Create transaction overrides from gas configuration const overrides = this.createOverrides(options === null || options === void 0 ? void 0 : options.gasConfig); // Handle overrides correctly for setMediaInfo if (Object.keys(overrides).length > 0) { // Use populateTransaction + sendTransaction for custom gas settings const populatedTx = await ipnft.populateTransaction.setMediaInfo(tokenIdBN, mediaData.seriesTitle, mediaData.description, mediaData.totalSeasons, mediaData.totalEpisodes, mediaData.genres, mediaData.creators, mediaData.posterUri); const txWithOverrides = { ...populatedTx, ...overrides }; return this._signer.sendTransaction(txWithOverrides); } else { // Standard call without overrides return ipnft.setMediaInfo(tokenIdBN, mediaData.seriesTitle, mediaData.description, mediaData.totalSeasons, mediaData.totalEpisodes, mediaData.genres, mediaData.creators, mediaData.posterUri); } } /** * Get media information (New Contract Interface) * @param tokenId NFT ID * @returns Media information */ async getMediaInfo(tokenId) { const ipnft = await this.getIPNFT(); const tokenIdBN = ethers.BigNumber.from(tokenId); const mediaInfo = await ipnft.getMediaInfo(tokenIdBN); return { seriesTitle: mediaInfo.seriesTitle, description: mediaInfo.description, totalSeasons: mediaInfo.totalSeasons, totalEpisodes: mediaInfo.totalEpisodes, genres: mediaInfo.genres, creators: mediaInfo.creators, createdAt: mediaInfo.createdAt, posterUri: mediaInfo.posterUri }; } /** * Mint with metadata (Convenience method that combines mint and setMediaInfo) * @param to Recipient address * @param uri Metadata URI * @param metadata Media metadata * @param options Transaction options * @returns Transaction object and minted NFT ID */ async mintWithMetadata(to, uri, metadata, options) { // First mint the NFT const mintResult = await this.mint(to, uri, options); let setInfoTx; // If metadata is provided, set the media info if (metadata.title) { const mediaData = { seriesTitle: metadata.title, description: metadata.description || '', totalSeasons: metadata.totalSeasons || 1, totalEpisodes: metadata.totalEpisodes || 1, genres: metadata.genres || [], creators: metadata.creators || (metadata.creator ? [metadata.creator] : []), posterUri: metadata.posterUri || metadata.thumbnailUrl || '' }; setInfoTx = await this.setMediaInfo(mintResult.tokenId, mediaData, options); await setInfoTx.wait(); // Wait for setMediaInfo to complete } return { ...mintResult, setInfoTx }; } /** * Legacy mint method (for backward compatibility) * @deprecated Use mintWithMetadata instead */ async legacyMint(to, uri, title, description, ipType = 0, options) { const metadata = { title, description, totalSeasons: 1, totalEpisodes: 1, genres: [`type_${ipType}`], creators: [], posterUri: uri }; const result = await this.mintWithMetadata(to, uri, metadata, options); return { tx: result.tx, tokenId: result.tokenId }; } /** * Get URI for a specific NFT * @param tokenId NFT ID * @returns NFT's metadata URI */ async tokenURI(tokenId) { const ipnft = await this.getIPNFT(); const tokenIdBN = ethers.BigNumber.from(tokenId); return ipnft.tokenURI(tokenIdBN); } /** * Check if a specific address is the owner of a specific NFT * @param address Address to check * @param tokenId NFT ID * @returns true if the address is the owner; otherwise false */ async isOwnerOf(address, tokenId) { const ipnft = await this.getIPNFT(); const tokenIdBN = ethers.BigNumber.from(tokenId); const owner = await ipnft.ownerOf(tokenIdBN); return owner.toLowerCase() === address.toLowerCase(); } /** * Get the owner of a specific NFT * @param tokenId NFT ID * @returns Owner address */ async ownerOf(tokenId) { const ipnft = await this.getIPNFT(); const tokenIdBN = ethers.BigNumber.from(tokenId); return ipnft.ownerOf(tokenIdBN); } /** * Legacy getIPInfo method (for backward compatibility) * @deprecated Use getMediaInfo instead * @param tokenId NFT ID * @returns IP information */ async getIPInfo(tokenId) { const mediaInfo = await this.getMediaInfo(tokenId); // Convert MediaInfo to legacy IPInfo format return { title: mediaInfo.seriesTitle, description: mediaInfo.description, ipType: 0, // Default type since new contract doesn't have ipType createdAt: mediaInfo.createdAt }; } /** * Convert contract NFT details to MintResult (Updated for new contract) * @param details NFT details from contract * @param tx Transaction object * @returns Formatted mint result */ formatMintResult(details, tx) { return { tokenId: details.tokenId.toString(), transactionHash: tx.hash, owner: details.owner, metadata: details.mediaInfo }; } /** * Update connection information (when network changes) * @param provider New Provider * @param signer New Signer */ updateConnection(provider, signer) { super.updateConnection(provider, signer); this._ipnft = null; // Clear cached contract instance, will be recreated on next use } }