import { BigNumber, ethers } from 'ethers' import ERC721Factory from '@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json' import { generateDtName, ZERO_ADDRESS, sendTx, getEventFromTx, getTokenDecimals, LoggerInstance } from '../utils' import { AbiItem, FreCreationParams, DatatokenCreateParams, DispenserCreationParams, NftCreateData, Template, TokenOrder, ReceiptOrEstimate } from '../@types' import { SmartContractWithAddress } from './SmartContractWithAddress' /** * Provides an interface for NFT Factory contract */ export class NftFactory extends SmartContractWithAddress { getDefaultAbi() { return ERC721Factory.abi as AbiItem[] } /** * Create new data NFT * @param {NFTCreateData} nftData The data needed to create an NFT. * @param {Boolean} [estimateGas] if True, return gas estimate * @return {Promise} The transaction hash or the gas estimate. */ public async createNFT( nftData: NftCreateData, estimateGas?: G ): Promise { if (!nftData.templateIndex) nftData.templateIndex = 1 if (!nftData.name || !nftData.symbol) { const { name, symbol } = generateDtName() nftData.name = name nftData.symbol = symbol } if (nftData.templateIndex > (await this.getCurrentNFTTemplateCount())) { throw new Error(`Template index doesnt exist`) } if (nftData.templateIndex === 0) { throw new Error(`Template index cannot be ZERO`) } if ((await this.getNFTTemplate(nftData.templateIndex)).isActive === false) { throw new Error(`Template is not active`) } const estGas = await this.contract.estimateGas.deployERC721Contract( nftData.name, nftData.symbol, nftData.templateIndex, ZERO_ADDRESS, ZERO_ADDRESS, nftData.tokenURI, nftData.transferable, nftData.owner ) if (estimateGas) return estGas // Invoke createToken function of the contract try { const tx = await sendTx( estGas, this.getSignerAccordingSdk(), this.config?.gasFeeMultiplier, this.contract.deployERC721Contract, nftData.name, nftData.symbol, nftData.templateIndex, ZERO_ADDRESS, ZERO_ADDRESS, nftData.tokenURI, nftData.transferable, nftData.owner ) if (!tx) { const e = 'Tx for deploying new NFT contract does not exist or status is not successful.' console.error(e) throw e } const trxReceipt = await tx.wait() const events = getEventFromTx(trxReceipt, 'NFTCreated') return events.args[0] } catch (e) { console.error(`Creation of NFT failed: ${e}`) } } /** * Get Current NFT Count (NFT created) * @return {Promise} Number of NFT created from this factory */ public async getCurrentNFTCount(): Promise { const nftCount = await this.contract.getCurrentNFTCount() return nftCount } /** * Get Current Datatoken Count * @return {Promise} Number of DTs created from this factory */ public async getCurrentTokenCount(): Promise { const tokenCount = await this.contract.getCurrentTokenCount() return tokenCount } /** * Get Factory Owner * @return {Promise} Factory Owner address */ public async getOwner(): Promise { const owner = await this.contract.owner() return owner } /** * Get Current NFT Template Count * @return {Promise} Number of NFT Template added to this factory */ public async getCurrentNFTTemplateCount(): Promise { const count = await this.contract.getCurrentNFTTemplateCount() return count } /** * Get Current Template Datatoken (ERC20) Count * @return {Promise} Number of Datatoken Template added to this factory */ public async getCurrentTokenTemplateCount(): Promise { const count = await this.contract.getCurrentTemplateCount() return count } /** * Get NFT Template * @param {number} index Template index * @return {Promise