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