diff --git a/src/factories/NftFactory.ts b/src/factories/NftFactory.ts new file mode 100644 index 00000000..aa87a7c4 --- /dev/null +++ b/src/factories/NftFactory.ts @@ -0,0 +1,758 @@ +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 { + LoggerInstance, + getFairGasPrice, + generateDtName, + getFreCreationParams, + getErcCreationParams, + getPoolCreationParams +} from '../utils' +import { FreCreationParams, Erc20CreateParams, PoolCreationParams } from '../interfaces' + +interface Template { + templateAddress: string + isActive: boolean +} + +export interface TokenOrder { + tokenAddress: string + consumer: string + amount: string | number + serviceIndex: number + providerFeeAddress: string + providerFeeToken: string + providerFeeAmount: string +} + +export interface NftCreateData { + name: string + symbol: string + templateIndex: number + tokenURI: string +} + +/** + * Provides an interface for NFT Factory contract + */ +export class NftFactory { + public GASLIMIT_DEFAULT = 1000000 + public factory721Address: string + public factory721Abi: AbiItem | AbiItem[] + public web3: Web3 + public startBlock: number + public factory721: Contract + + /** + * Instantiate DataTokens. + * @param {String} factory721Address + * @param {AbiItem | AbiItem[]} factory721ABI + * @param {Web3} web3 + */ + constructor( + factory721Address: string, + web3: Web3, + factory721Abi?: AbiItem | AbiItem[], + startBlock?: number + ) { + this.factory721Address = factory721Address + this.factory721Abi = factory721Abi || (defaultFactory721Abi.abi as AbiItem[]) + this.web3 = web3 + this.startBlock = startBlock || 0 + this.factory721 = new this.web3.eth.Contract( + this.factory721Abi, + this.factory721Address + ) + } + + /** + * Get estimated gas cost for deployERC721Contract value + * @param {String} address + * @param {String} nftData + * @return {Promise} NFT datatoken address + */ + public async estGasCreateNFT(address: string, nftData: NftCreateData): Promise { + const gasLimitDefault = this.GASLIMIT_DEFAULT + let estGas + try { + estGas = await this.factory721.methods + .deployERC721Contract( + nftData.name, + nftData.symbol, + nftData.templateIndex, + '0x0000000000000000000000000000000000000000', + nftData.tokenURI + ) + .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas)) + } catch (e) { + estGas = gasLimitDefault + } + return estGas + } + + /** + * Create new NFT + * @param {String} address + * @param {NFTCreateData} nftData + * @return {Promise} NFT datatoken address + */ + public async createNFT(address: string, nftData: NftCreateData): Promise { + if (!nftData.templateIndex) nftData.templateIndex = 1 + + if (!nftData.name || !nftData.symbol) { + const { name, symbol } = generateDtName() + nftData.name = name + nftData.symbol = symbol + } + + const estGas = await this.estGasCreateNFT(address, nftData) + + // Invoke createToken function of the contract + const trxReceipt = await this.factory721.methods + .deployERC721Contract( + nftData.name, + nftData.symbol, + nftData.templateIndex, + '0x0000000000000000000000000000000000000000', + nftData.tokenURI + ) + .send({ + from: address, + gas: estGas + 1, + gasPrice: await getFairGasPrice(this.web3) + }) + + let tokenAddress = null + try { + tokenAddress = trxReceipt.events.NFTCreated.returnValues[0] + } catch (e) { + LoggerInstance.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