import { Contract } from 'web3-eth-contract' import Web3 from 'web3' import { TransactionReceipt } from 'web3-core' import { AbiItem } from 'web3-utils' import defaultFactory721ABI from '@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json' import { Logger, getFairGasPrice, generateDtName } from '../utils' interface Template { templateAddress: string isActive: boolean } interface TokenOrder { tokenAddress: string consumer: string amount: number serviceId: number consumeFeeAddress: string consumeFeeToken: string // address of the token marketplace wants to add fee on top consumeFeeAmount: number } interface NFTCreateData { name: string symbol: string templateIndex: number baseURI: string } interface ErcCreateData { templateIndex: number strings: string[] addresses: string[] uints:(string | number)[] bytess: string[] } interface PoolData { addresses: string[] ssParams: number[] swapFees: number[] } interface FixedData { fixedPriceAddress: string addresses: string[] uints: number[] } /** * Provides an interface for NFT DataTokens */ export class NFTFactory { public GASLIMIT_DEFAULT = 1000000 public factory721Address: string public factory721ABI: AbiItem | AbiItem[] public web3: Web3 private logger: Logger public startBlock: number public factory721: Contract /** * Instantiate DataTokens. * @param {String} factory721Address * @param {AbiItem | AbiItem[]} factory721ABI * @param {Web3} web3 */ constructor( factory721Address: string, web3: Web3, logger: Logger, factory721ABI?: AbiItem | AbiItem[], startBlock?: number ) { this.factory721Address = factory721Address this.factory721ABI = factory721ABI || (defaultFactory721ABI.abi as AbiItem[]) this.web3 = web3 this.logger = logger this.startBlock = startBlock || 0 this.factory721 = new this.web3.eth.Contract( this.factory721ABI, this.factory721Address ) } /** * Create new NFT * @param {String} address * @param {String} name Token name * @param {String} symbol Token symbol * @param {Number} templateIndex NFT template index * @return {Promise} NFT datatoken address */ public async createNFT( address: string, name?: string, symbol?: string, templateIndex?: number ): Promise { if (!templateIndex) templateIndex = 1 // Generate name & symbol if not present if (!name || !symbol) { ;({ name, symbol } = generateDtName()) } // Get estimated gas value const gasLimitDefault = this.GASLIMIT_DEFAULT let estGas try { estGas = await this.factory721.methods .deployERC721Contract(name, symbol, templateIndex, null) .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas)) } catch (e) { estGas = gasLimitDefault } // Invoke createToken function of the contract const trxReceipt = await this.factory721.methods .deployERC721Contract(name, symbol, templateIndex, null) .send({ from: address, gas: estGas + 1, gasPrice: await getFairGasPrice(this.web3) }) let tokenAddress = null try { tokenAddress = trxReceipt.events.TokenCreated.returnValues[0] } catch (e) { this.logger.error(`ERROR: Failed to create datatoken : ${e.message}`) } return tokenAddress } /** Get Current NFT Count (NFT created) * @return {Promise} Number of NFT created from this factory */ public async getCurrentNFTCount(): Promise { const trxReceipt = await this.factory721.methods.getCurrentNFTCount().call() return trxReceipt } /** Get Current Datatoken Count * @return {Promise} Number of DTs created from this factory */ public async getCurrentTokenCount(): Promise { const trxReceipt = await this.factory721.methods.getCurrentTokenCount().call() return trxReceipt } /** Get Factory Owner * @return {Promise} Factory Owner address */ public async getOwner(): Promise { const trxReceipt = await this.factory721.methods.owner().call() return trxReceipt } /** Get Current NFT Template Count * @return {Promise} Number of NFT Template added to this factory */ public async getCurrentNFTTemplateCount(): Promise { const count = await this.factory721.methods.getCurrentNFTTemplateCount().call() return count } /** Get Current Template Datatoken (ERC20) Count * @return {Promise} Number of ERC20 Template added to this factory */ public async getCurrentTokenTemplateCount(): Promise { const count = await this.factory721.methods.getCurrentTemplateCount().call() return count } /** Get NFT Template * @param {Number} index Template index * @return {Promise