diff --git a/src/contracts/factories/NFTFactory.ts b/src/contracts/factories/NFTFactory.ts index 6f06412e..26543e0c 100644 --- a/src/contracts/factories/NFTFactory.ts +++ b/src/contracts/factories/NFTFactory.ts @@ -2,7 +2,12 @@ import Web3 from 'web3' import { TransactionReceipt } from 'web3-core' import { AbiItem } from 'web3-utils' import ERC721Factory from '@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json' -import { LoggerInstance, generateDtName, estimateGas, ZERO_ADDRESS } from '../../utils' +import { + LoggerInstance, + generateDtName, + calculateEstimatedGas, + ZERO_ADDRESS +} from '../../utils' import { FreCreationParams, DatatokenCreateParams, @@ -22,34 +27,17 @@ export class NftFactory extends SmartContractWithAddress { return ERC721Factory.abi as AbiItem[] } - /** - * 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 { - return estimateGas( - address, - this.contract.methods.deployERC721Contract, - nftData.name, - nftData.symbol, - nftData.templateIndex, - ZERO_ADDRESS, - ZERO_ADDRESS, - nftData.tokenURI, - nftData.transferable, - nftData.owner - ) - } - /** * Create new NFT * @param {String} address * @param {NFTCreateData} nftData * @return {Promise} NFT datatoken address */ - public async createNFT(address: string, nftData: NftCreateData): Promise { + public async createNFT( + address: string, + nftData: NftCreateData, + estimateGas?: G + ): Promise { if (!nftData.templateIndex) nftData.templateIndex = 1 if (!nftData.name || !nftData.symbol) { @@ -67,7 +55,7 @@ export class NftFactory extends SmartContractWithAddress { if ((await this.getNFTTemplate(nftData.templateIndex)).isActive === false) { throw new Error(`Template is not active`) } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.deployERC721Contract, nftData.name, @@ -79,6 +67,7 @@ export class NftFactory extends SmartContractWithAddress { nftData.transferable, nftData.owner ) + if (estimateGas) return estGas // Invoke createToken function of the contract const trxReceipt = await this.contract.methods @@ -190,33 +179,17 @@ export class NftFactory extends SmartContractWithAddress { return confirmAddress } - /** - * Estimate gas cost for add721TokenTemplate method - * @param {String} address - * @param {String} templateAddress template address to add - * @return {Promise} - */ - public async estGasAddNFTTemplate( - address: string, - templateAddress: string - ): Promise { - return estimateGas( - address, - this.contract.methods.add721TokenTemplate, - templateAddress - ) - } - /** * Add a new NFT token template - only factory Owner * @param {String} address * @param {String} templateAddress template address to add * @return {Promise} */ - public async addNFTTemplate( + public async addNFTTemplate( address: string, - templateAddress: string - ): Promise { + templateAddress: string, + estimateGas?: G + ): Promise { if ((await this.getOwner()) !== address) { throw new Error(`Caller is not Factory Owner`) } @@ -224,11 +197,12 @@ export class NftFactory extends SmartContractWithAddress { throw new Error(`Template cannot be ZERO address`) } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.add721TokenTemplate, templateAddress ) + if (estimateGas) return estGas // Invoke add721TokenTemplate function of the contract const trxReceipt = await this.contract.methods @@ -242,33 +216,17 @@ export class NftFactory extends SmartContractWithAddress { return trxReceipt } - /** - * Estimate gas cost for disable721TokenTemplate method - * @param {String} address - * @param {Number} templateIndex index of the template we want to disable - * @return {Promise} current token template count - */ - public async estGasDisableNFTTemplate( - address: string, - templateIndex: number - ): Promise { - return estimateGas( - address, - this.contract.methods.disable721TokenTemplate, - templateIndex - ) - } - /** * Disable token template - only factory Owner * @param {String} address * @param {Number} templateIndex index of the template we want to disable * @return {Promise} current token template count */ - public async disableNFTTemplate( + public async disableNFTTemplate( address: string, - templateIndex: number - ): Promise { + templateIndex: number, + estimateGas?: G + ): Promise { if ((await this.getOwner()) !== address) { throw new Error(`Caller is not Factory Owner`) } @@ -279,11 +237,12 @@ export class NftFactory extends SmartContractWithAddress { if (templateIndex === 0) { throw new Error(`Template index cannot be ZERO`) } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.disable721TokenTemplate, templateIndex ) + if (estimateGas) return estGas // Invoke createToken function of the contract const trxReceipt = await this.contract.methods @@ -303,27 +262,11 @@ export class NftFactory extends SmartContractWithAddress { * @param {Number} templateIndex index of the template we want to reactivate * @return {Promise} current token template count */ - public async estGasReactivateNFTTemplate( + public async reactivateNFTTemplate( address: string, - templateIndex: number - ): Promise { - return estimateGas( - address, - this.contract.methods.reactivate721TokenTemplate, - templateIndex - ) - } - - /** - * Reactivate a previously disabled token template - only factory Owner - * @param {String} address - * @param {Number} templateIndex index of the template we want to reactivate - * @return {Promise} current token template count - */ - public async reactivateNFTTemplate( - address: string, - templateIndex: number - ): Promise { + templateIndex: number, + estimateGas?: G + ): Promise { if ((await this.getOwner()) !== address) { throw new Error(`Caller is not Factory Owner`) } @@ -335,11 +278,12 @@ export class NftFactory extends SmartContractWithAddress { throw new Error(`Template index cannot be ZERO`) } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.reactivate721TokenTemplate, templateIndex ) + if (estimateGas) return estGas // Invoke createToken function of the contract const trxReceipt = await this.contract.methods @@ -353,29 +297,17 @@ export class NftFactory extends SmartContractWithAddress { return trxReceipt } - /** - * Estimate gas cost for addTokenTemplate method - * @param {String} address - * @param {String} templateAddress template address to add - * @return {Promise} - */ - public async estGasAddTokenTemplate( - address: string, - templateAddress: string - ): Promise { - return estimateGas(address, this.contract.methods.addTokenTemplate, templateAddress) - } - /** * Add a new NFT token template - only factory Owner * @param {String} address * @param {String} templateAddress template address to add * @return {Promise} */ - public async addTokenTemplate( + public async addTokenTemplate( address: string, - templateAddress: string - ): Promise { + templateAddress: string, + estimateGas?: G + ): Promise { if ((await this.getOwner()) !== address) { throw new Error(`Caller is not Factory Owner`) } @@ -383,11 +315,12 @@ export class NftFactory extends SmartContractWithAddress { throw new Error(`Template cannot be address ZERO`) } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.addTokenTemplate, templateAddress ) + if (estimateGas) return estGas // Invoke createToken function of the contract const trxReceipt = await this.contract.methods @@ -401,29 +334,17 @@ export class NftFactory extends SmartContractWithAddress { return trxReceipt } - /** - * Estimate gas cost for disableTokenTemplate method - * @param {String} address - * @param {Number} templateIndex index of the template we want to disable - * @return {Promise} current token template count - */ - public async estGasDisableTokenTemplate( - address: string, - templateIndex: number - ): Promise { - return estimateGas(address, this.contract.methods.disableTokenTemplate, templateIndex) - } - /** * Disable token template - only factory Owner * @param {String} address * @param {Number} templateIndex index of the template we want to disable * @return {Promise} current token template count */ - public async disableTokenTemplate( + public async disableTokenTemplate( address: string, - templateIndex: number - ): Promise { + templateIndex: number, + estimateGas?: G + ): Promise { if ((await this.getOwner()) !== address) { throw new Error(`Caller is not Factory Owner`) } @@ -437,11 +358,12 @@ export class NftFactory extends SmartContractWithAddress { if ((await this.getTokenTemplate(templateIndex)).isActive === false) { throw new Error(`Template is already disabled`) } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.disableTokenTemplate, templateIndex ) + if (estimateGas) return estGas // Invoke createToken function of the contract const trxReceipt = await this.contract.methods @@ -455,33 +377,17 @@ export class NftFactory extends SmartContractWithAddress { return trxReceipt } - /** - * Estimate gas cost for reactivateTokenTemplate method - * @param {String} address - * @param {Number} templateIndex index of the template we want to reactivate - * @return {Promise} current token template count - */ - public async estGasReactivateTokenTemplate( - address: string, - templateIndex: number - ): Promise { - return estimateGas( - address, - this.contract.methods.reactivateTokenTemplate, - templateIndex - ) - } - /** * Reactivate a previously disabled token template - only factory Owner * @param {String} address * @param {Number} templateIndex index of the template we want to reactivate * @return {Promise} current token template count */ - public async reactivateTokenTemplate( + public async reactivateTokenTemplate( address: string, - templateIndex: number - ): Promise { + templateIndex: number, + estimateGas?: G + ): Promise { if ((await this.getOwner()) !== address) { throw new Error(`Caller is not Factory Owner`) } @@ -496,11 +402,12 @@ export class NftFactory extends SmartContractWithAddress { throw new Error(`Template is already active`) } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.reactivateTokenTemplate, templateIndex ) + if (estimateGas) return estGas // Invoke createToken function of the contract const trxReceipt = await this.contract.methods @@ -514,18 +421,6 @@ export class NftFactory extends SmartContractWithAddress { return trxReceipt } - /** Estimate gas cost for startMultipleTokenOrder method - * @param address Caller address - * @param orders an array of struct tokenOrder - * @return {Promise} transaction receipt - */ - public async estGasStartMultipleTokenOrder( - address: string, - orders: TokenOrder[] - ): Promise { - return estimateGas(address, this.contract.methods.startMultipleTokenOrder, orders) - } - /** * @dev startMultipleTokenOrder * Used as a proxy to order multiple services @@ -538,19 +433,21 @@ export class NftFactory extends SmartContractWithAddress { * @param orders an array of struct tokenOrder * @return {Promise} transaction receipt */ - public async startMultipleTokenOrder( + public async startMultipleTokenOrder( address: string, - orders: TokenOrder[] - ): Promise { + orders: TokenOrder[], + estimateGas?: G + ): Promise { if (orders.length > 50) { throw new Error(`Too many orders`) } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.startMultipleTokenOrder, orders ) + if (estimateGas) return estGas // Invoke createToken function of the contract const trxReceipt = await this.contract.methods.startMultipleTokenOrder(orders).send({ @@ -562,28 +459,6 @@ export class NftFactory extends SmartContractWithAddress { return trxReceipt } - /** - * Estimate gas cost for createNftWithDatatoken method - * @param address Caller address - * @param _NftCreateData input data for NFT creation - * @param _ErcCreateData input data for Datatoken creation - * @return {Promise} transaction receipt - */ - - public async estGasCreateNftWithDatatoken( - address: string, - nftCreateData: NftCreateData, - dtParams: DatatokenCreateParams - ): Promise { - const ercCreateData = this.getErcCreationParams(dtParams) - return estimateGas( - address, - this.contract.methods.createNftWithErc20, - nftCreateData, - ercCreateData - ) - } - /** * @dev createNftWithDatatoken * Creates a new NFT, then a Datatoken,all in one call @@ -593,19 +468,21 @@ export class NftFactory extends SmartContractWithAddress { * @return {Promise} transaction receipt */ - public async createNftWithDatatoken( + public async createNftWithDatatoken( address: string, nftCreateData: NftCreateData, - dtParams: DatatokenCreateParams - ): Promise { + dtParams: DatatokenCreateParams, + estimateGas?: G + ): Promise { const ercCreateData = this.getErcCreationParams(dtParams) - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.createNftWithErc20, nftCreateData, ercCreateData ) + if (estimateGas) return estGas // Invoke createToken function of the contract const trxReceipt = await this.contract.methods @@ -619,31 +496,6 @@ export class NftFactory extends SmartContractWithAddress { return trxReceipt } - /** - * Estimate gas cost for createNftWithDatatokenWithPool method - * @param address Caller address - * @param nftCreateData input data for NFT Creation - * @param dtParams input data for Datatoken Creation - * @param poolParams input data for Pool Creation - * @return {Promise} transaction receipt - */ - public async estGasCreateNftWithDatatokenWithPool( - address: string, - nftCreateData: NftCreateData, - dtParams: DatatokenCreateParams, - poolParams: PoolCreationParams - ): Promise { - const ercCreateData = this.getErcCreationParams(dtParams) - const poolData = await this.getPoolCreationParams(poolParams) - return estimateGas( - address, - this.contract.methods.createNftWithErc20WithPool, - nftCreateData, - ercCreateData, - poolData - ) - } - /** * @dev createNftWithDatatokenWithPool * Creates a new NFT, then a Datatoken, then a Pool, all in one call @@ -654,22 +506,24 @@ export class NftFactory extends SmartContractWithAddress { * @param poolParams input data for Pool Creation * @return {Promise} transaction receipt */ - public async createNftWithDatatokenWithPool( + public async createNftWithDatatokenWithPool( address: string, nftCreateData: NftCreateData, dtParams: DatatokenCreateParams, - poolParams: PoolCreationParams - ): Promise { + poolParams: PoolCreationParams, + estimateGas?: G + ): Promise { const ercCreateData = this.getErcCreationParams(dtParams) const poolData = await this.getPoolCreationParams(poolParams) - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.createNftWithErc20WithPool, nftCreateData, ercCreateData, poolData ) + if (estimateGas) return estGas // Invoke createToken function of the contract const trxReceipt = await this.contract.methods @@ -683,30 +537,6 @@ export class NftFactory extends SmartContractWithAddress { return trxReceipt } - /** Estimate gas cost for createNftWithDatatokenWithFixedRate method - * @param address Caller address - * @param nftCreateData input data for NFT Creation - * @param dtParams input data for Datatoken Creation - * @param freParams input data for FixedRate Creation - * @return {Promise} transaction receipt - */ - public async estGasCreateNftWithDatatokenWithFixedRate( - address: string, - nftCreateData: NftCreateData, - dtParams: DatatokenCreateParams, - freParams: FreCreationParams - ): Promise { - const ercCreateData = this.getErcCreationParams(dtParams) - const fixedData = await this.getFreCreationParams(freParams) - return estimateGas( - address, - this.contract.methods.createNftWithErc20WithFixedRate, - nftCreateData, - ercCreateData, - fixedData - ) - } - /** * @dev createNftWithDatatokenWithFixedRate * Creates a new NFT, then a Datatoken, then a FixedRateExchange, all in one call @@ -717,22 +547,24 @@ export class NftFactory extends SmartContractWithAddress { * @param freParams input data for FixedRate Creation * @return {Promise} transaction receipt */ - public async createNftWithDatatokenWithFixedRate( + public async createNftWithDatatokenWithFixedRate( address: string, nftCreateData: NftCreateData, dtParams: DatatokenCreateParams, - freParams: FreCreationParams - ): Promise { + freParams: FreCreationParams, + estimateGas?: G + ): Promise { const ercCreateData = this.getErcCreationParams(dtParams) const fixedData = this.getFreCreationParams(freParams) - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.createNftWithErc20WithFixedRate, nftCreateData, ercCreateData, fixedData ) + if (estimateGas) return estGas // Invoke createToken function of the contract const trxReceipt = await this.contract.methods @@ -746,29 +578,6 @@ export class NftFactory extends SmartContractWithAddress { return trxReceipt } - /** Estimate gas cost for estGasCreateNftWithDatatokenWithDispenser method - * @param address Caller address - * @param nftCreateData input data for NFT Creation - * @param dtParams input data for Datatoken Creation - * @param dispenserParams input data for Dispenser Creation - * @return {Promise} transaction receipt - */ - public async estGasCreateNftWithDatatokenWithDispenser( - address: string, - nftCreateData: NftCreateData, - dtParams: DatatokenCreateParams, - dispenserParams: DispenserCreationParams - ): Promise { - const ercCreateData = this.getErcCreationParams(dtParams) - return estimateGas( - address, - this.contract.methods.createNftWithErc20WithDispenser, - nftCreateData, - ercCreateData, - dispenserParams - ) - } - /** * @dev createNftWithDatatokenWithDispenser * Creates a new NFT, then a Datatoken, then a Dispenser, all in one call @@ -779,24 +588,26 @@ export class NftFactory extends SmartContractWithAddress { * @param dispenserParams input data for Dispenser Creation * @return {Promise} transaction receipt */ - public async createNftWithDatatokenWithDispenser( + public async createNftWithDatatokenWithDispenser( address: string, nftCreateData: NftCreateData, dtParams: DatatokenCreateParams, - dispenserParams: DispenserCreationParams - ): Promise { + dispenserParams: DispenserCreationParams, + estimateGas?: G + ): Promise { const ercCreateData = this.getErcCreationParams(dtParams) dispenserParams.maxBalance = Web3.utils.toWei(dispenserParams.maxBalance) dispenserParams.maxTokens = Web3.utils.toWei(dispenserParams.maxTokens) - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.createNftWithErc20WithDispenser, nftCreateData, ercCreateData, dispenserParams ) + if (estimateGas) return estGas // Invoke createToken function of the contract const trxReceipt = await this.contract.methods diff --git a/src/contracts/pools/Dispenser.ts b/src/contracts/pools/Dispenser.ts index c78d4b63..41ab6cd7 100644 --- a/src/contracts/pools/Dispenser.ts +++ b/src/contracts/pools/Dispenser.ts @@ -2,7 +2,7 @@ import { AbiItem } from 'web3-utils' import { TransactionReceipt } from 'web3-eth' import Decimal from 'decimal.js' import DispenserAbi from '@oceanprotocol/contracts/artifacts/contracts/pools/dispenser/Dispenser.sol/Dispenser.json' -import { LoggerInstance, estimateGas } from '../../utils/' +import { LoggerInstance, calculateEstimatedGas } from '../../utils/' import { Datatoken, SmartContractWithAddress } from '..' import { DispenserToken } from '../../@types' @@ -29,33 +29,6 @@ export class Dispenser extends SmartContractWithAddress { return null } - /** - * Estimate gas cost for create method - * @param {String} dtAddress Datatoken address - * @param {String} address Owner address - * @param {String} maxTokens max tokens to dispense - * @param {String} maxBalance max balance of requester - * @param {String} allowedSwapper if !=0, only this address can request DTs - * @return {Promise} - */ - public async estGasCreate( - dtAddress: string, - address: string, - maxTokens: string, - maxBalance: string, - allowedSwapper: string - ): Promise { - return estimateGas( - address, - this.contract.methods.create, - dtAddress, - this.web3.utils.toWei(maxTokens), - this.web3.utils.toWei(maxBalance), - address, - allowedSwapper - ) - } - /** * Creates a new Dispenser * @param {String} dtAddress Datatoken address @@ -65,14 +38,15 @@ export class Dispenser extends SmartContractWithAddress { * @param {String} allowedSwapper only account that can ask tokens. set address(0) if not required * @return {Promise} transactionId */ - public async create( + public async create( dtAddress: string, address: string, maxTokens: string, maxBalance: string, - allowedSwapper: string - ): Promise { - const estGas = await estimateGas( + allowedSwapper: string, + estimateGas?: G + ): Promise { + const estGas = await calculateEstimatedGas( address, this.contract.methods.create, dtAddress, @@ -81,6 +55,7 @@ export class Dispenser extends SmartContractWithAddress { address, allowedSwapper ) + if (estimateGas) return estGas // Call createFixedRate contract method const trxReceipt = await this.contract.methods @@ -99,29 +74,6 @@ export class Dispenser extends SmartContractWithAddress { return trxReceipt } - /** - * Estimate gas for activate method - * @param {String} dtAddress - * @param {Number} maxTokens max amount of tokens to dispense - * @param {Number} maxBalance max balance of user. If user balance is >, then dispense will be rejected - * @param {String} address User address (must be owner of the datatoken) - * @return {Promise} - */ - public async estGasActivate( - dtAddress: string, - maxTokens: string, - maxBalance: string, - address: string - ): Promise { - return estimateGas( - address, - this.contract.methods.activate, - dtAddress, - this.web3.utils.toWei(maxTokens), - this.web3.utils.toWei(maxBalance) - ) - } - /** * Activates a new dispener. * @param {String} dtAddress refers to datatoken address. @@ -130,20 +82,22 @@ export class Dispenser extends SmartContractWithAddress { * @param {String} address User address (must be owner of the datatoken) * @return {Promise} TransactionReceipt */ - public async activate( + public async activate( dtAddress: string, maxTokens: string, maxBalance: string, - address: string - ): Promise { + address: string, + estimateGas?: G + ): Promise { try { - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.activate, dtAddress, this.web3.utils.toWei(maxTokens), this.web3.utils.toWei(maxBalance) ) + if (estimateGas) return estGas const trxReceipt = await this.contract.methods .activate( @@ -163,32 +117,24 @@ export class Dispenser extends SmartContractWithAddress { return null } - /** - * Estimate gas for deactivate method - * @param {String} dtAddress - * @param {String} address User address (must be owner of the datatoken) - * @return {Promise} - */ - public async estGasDeactivate(dtAddress: string, address: string): Promise { - return estimateGas(address, this.contract.methods.deactivate, dtAddress) - } - /** * Deactivate an existing dispenser. * @param {String} dtAddress refers to datatoken address. * @param {String} address User address (must be owner of the datatoken) * @return {Promise} TransactionReceipt */ - public async deactivate( + public async deactivate( dtAddress: string, - address: string - ): Promise { + address: string, + estimateGas?: G + ): Promise { try { - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.deactivate, dtAddress ) + if (estimateGas) return estGas const trxReceipt = await this.contract.methods.deactivate(dtAddress).send({ from: address, @@ -202,26 +148,6 @@ export class Dispenser extends SmartContractWithAddress { return null } - /** - * Estimate gas for setAllowedSwapper method - * @param {String} dtAddress refers to datatoken address. - * @param {String} address User address (must be owner of the datatoken) - * @param {String} newAllowedSwapper refers to the new allowedSwapper - * @return {Promise} - */ - public async estGasSetAllowedSwapper( - dtAddress: string, - address: string, - newAllowedSwapper: string - ): Promise { - return estimateGas( - address, - this.contract.methods.setAllowedSwapper, - dtAddress, - newAllowedSwapper - ) - } - /** * Sets a new allowedSwapper. * @param {String} dtAddress refers to datatoken address. @@ -229,18 +155,20 @@ export class Dispenser extends SmartContractWithAddress { * @param {String} newAllowedSwapper refers to the new allowedSwapper * @return {Promise} TransactionReceipt */ - public async setAllowedSwapper( + public async setAllowedSwapper( dtAddress: string, address: string, - newAllowedSwapper: string - ): Promise { + newAllowedSwapper: string, + estimateGas?: G + ): Promise { try { - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.setAllowedSwapper, dtAddress, newAllowedSwapper ) + if (estimateGas) return estGas const trxReceipt = await this.contract.methods .setAllowedSwapper(dtAddress, newAllowedSwapper) @@ -256,28 +184,6 @@ export class Dispenser extends SmartContractWithAddress { return null } - /** - * Estimate gas for dispense method - * @param {String} dtAddress refers to datatoken address. - * @param {String} address User address (must be owner of the datatoken) - * @param {String} newAllowedSwapper refers to the new allowedSwapper - * @return {Promise} - */ - public async estGasDispense( - dtAddress: string, - address: string, - amount: string = '1', - destination: string - ): Promise { - return estimateGas( - address, - this.contract.methods.dispense, - dtAddress, - this.web3.utils.toWei(amount), - destination - ) - } - /** * Dispense datatokens to caller. * The dispenser must be active, hold enough DT (or be able to mint more) @@ -288,19 +194,21 @@ export class Dispenser extends SmartContractWithAddress { * @param {String} destination who will receive the tokens * @return {Promise} TransactionReceipt */ - public async dispense( + public async dispense( dtAddress: string, address: string, amount: string = '1', - destination: string - ): Promise { - const estGas = await estimateGas( + destination: string, + estimateGas?: G + ): Promise { + const estGas = await calculateEstimatedGas( address, this.contract.methods.dispense, dtAddress, this.web3.utils.toWei(amount), destination ) + if (estimateGas) return estGas try { const trxReceipt = await this.contract.methods @@ -317,32 +225,23 @@ export class Dispenser extends SmartContractWithAddress { return null } - /** - * Estimate gas for ownerWithdraw method - * @param {String} dtAddress refers to datatoken address. - * @param {String} address User address (must be owner of the datatoken) - * @param {String} newAllowedSwapper refers to the new allowedSwapper - * @return {Promise} - */ - public async estGasOwnerWithdraw(dtAddress: string, address: string): Promise { - return estimateGas(address, this.contract.methods.ownerWithdraw, dtAddress) - } - /** * Withdraw all tokens from the dispenser * @param {String} dtAddress refers to datatoken address. * @param {String} address User address (must be owner of the dispenser) * @return {Promise} TransactionReceipt */ - public async ownerWithdraw( + public async ownerWithdraw( dtAddress: string, - address: string - ): Promise { - const estGas = await estimateGas( + address: string, + estimateGas?: G + ): Promise { + const estGas = await calculateEstimatedGas( address, this.contract.methods.ownerWithdraw, dtAddress ) + if (estimateGas) return estGas try { const trxReceipt = await this.contract.methods.ownerWithdraw(dtAddress).send({ diff --git a/src/contracts/pools/FixedRateExchange.ts b/src/contracts/pools/FixedRateExchange.ts index 4ab96c7f..d5fa05b8 100644 --- a/src/contracts/pools/FixedRateExchange.ts +++ b/src/contracts/pools/FixedRateExchange.ts @@ -1,8 +1,7 @@ import FixedRateExchangeAbi from '@oceanprotocol/contracts/artifacts/contracts/pools/fixedRate/FixedRateExchange.sol/FixedRateExchange.json' import { TransactionReceipt } from 'web3-core' -import { Contract } from 'web3-eth-contract' import { AbiItem } from 'web3-utils/types' -import { LoggerInstance, estimateGas, ZERO_ADDRESS } from '../../utils' +import { LoggerInstance, calculateEstimatedGas, ZERO_ADDRESS } from '../../utils' import { PriceAndFees, FeesInfo, FixedPriceExchange } from '../../@types' import { SmartContractWithAddress } from '..' @@ -24,38 +23,6 @@ export class FixedRateExchange extends SmartContractWithAddress { return exchangeId } - /** - * Estimate gas cost for buyDT - * @param {String} account - * @param {String} dtAmount datatoken amount we want to buy - * @param {String} datatokenAddress datatokenAddress - * @param {String} consumeMarketAddress consumeMarketAddress - * @param {String} consumeMarketFee fee recieved by the consume market when a dt is bought from a fixed rate exchange, percent - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasBuyDT( - account: string, - datatokenAddress: string, - dtAmount: string, - maxBaseTokenAmount: string, - consumeMarketAddress: string, - consumeMarketFee: string, - contractInstance?: Contract - ): Promise { - const fixedRate = contractInstance || this.contract - - return estimateGas( - account, - fixedRate.methods.buyDT, - datatokenAddress, - dtAmount, - maxBaseTokenAmount, - consumeMarketAddress, - consumeMarketFee - ) - } - /** * Atomic swap * @param {String} exchangeId ExchangeId @@ -66,14 +33,15 @@ export class FixedRateExchange extends SmartContractWithAddress { * @param {String} consumeMarketFee consumeMarketFee in fraction * @return {Promise} transaction receipt */ - public async buyDT( + public async buyDT( address: string, exchangeId: string, datatokenAmount: string, maxBaseTokenAmount: string, consumeMarketAddress: string = ZERO_ADDRESS, - consumeMarketFee: string = '0' - ): Promise { + consumeMarketFee: string = '0', + estimateGas?: G + ): Promise { const exchange = await this.getExchange(exchangeId) const consumeMarketFeeFormatted = this.web3.utils.toWei(consumeMarketFee) const dtAmountFormatted = await this.amountToUnits( @@ -87,7 +55,7 @@ export class FixedRateExchange extends SmartContractWithAddress { +exchange.btDecimals ) - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.buyDT, exchangeId, @@ -96,6 +64,8 @@ export class FixedRateExchange extends SmartContractWithAddress { consumeMarketAddress, consumeMarketFeeFormatted ) + if (estimateGas) return estGas + try { const trxReceipt = await this.contract.methods .buyDT( @@ -117,38 +87,6 @@ export class FixedRateExchange extends SmartContractWithAddress { } } - /** - * Estimate gas cost for sellDT - * @param {String} account - * @param {String} dtAmount datatoken amount we want to sell - * @param {String} datatokenAddress datatokenAddress - * @param {String} consumeMarketAddress consumeMarketAddress - * @param {String} consumeMarketFee consumeMarketFee - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasSellDT( - account: string, - datatokenAddress: string, - dtAmount: string, - maxBaseTokenAmount: string, - consumeMarketAddress: string, - consumeMarketFee: string, - contractInstance?: Contract - ): Promise { - const fixedRate = contractInstance || this.contract - - return estimateGas( - account, - fixedRate.methods.sellDT, - datatokenAddress, - dtAmount, - maxBaseTokenAmount, - consumeMarketAddress, - consumeMarketFee - ) - } - /** * Atomic swap * @param {String} exchangeId ExchangeId @@ -159,14 +97,15 @@ export class FixedRateExchange extends SmartContractWithAddress { * @param {String} consumeMarketFee consumeMarketFee in fraction * @return {Promise} transaction receipt */ - public async sellDT( + public async sellDT( address: string, exchangeId: string, datatokenAmount: string, minBaseTokenAmount: string, consumeMarketAddress: string = ZERO_ADDRESS, - consumeMarketFee: string = '0' - ): Promise { + consumeMarketFee: string = '0', + estimateGas?: G + ): Promise { const exchange = await this.getExchange(exchangeId) const consumeMarketFeeFormatted = this.web3.utils.toWei(consumeMarketFee) const dtAmountFormatted = await this.amountToUnits( @@ -179,7 +118,7 @@ export class FixedRateExchange extends SmartContractWithAddress { minBaseTokenAmount, +exchange.btDecimals ) - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.sellDT, exchangeId, @@ -188,6 +127,8 @@ export class FixedRateExchange extends SmartContractWithAddress { consumeMarketAddress, consumeMarketFeeFormatted ) + if (estimateGas) return estGas + try { const trxReceipt = await this.contract.methods .sellDT( @@ -220,30 +161,6 @@ export class FixedRateExchange extends SmartContractWithAddress { return numExchanges } - /** - * Estimate gas cost for setRate - * @param {String} account - * @param {String} exchangeId ExchangeId - * @param {String} newRate New rate - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasSetRate( - account: string, - exchangeId: string, - newRate: string, - contractInstance?: Contract - ): Promise { - const fixedRate = contractInstance || this.contract - - return estimateGas( - account, - fixedRate.methods.setRate, - exchangeId, - await this.web3.utils.toWei(newRate) - ) - } - /** * Set new rate * @param {String} exchangeId ExchangeId @@ -251,17 +168,20 @@ export class FixedRateExchange extends SmartContractWithAddress { * @param {String} address User account * @return {Promise} transaction receipt */ - public async setRate( + public async setRate( address: string, exchangeId: string, - newRate: string - ): Promise { - const estGas = await estimateGas( + newRate: string, + estimateGas?: G + ): Promise { + const estGas = await calculateEstimatedGas( address, this.contract.methods.setRate, exchangeId, this.web3.utils.toWei(newRate) ) + if (estimateGas) return estGas + const trxReceipt = await this.contract.methods .setRate(exchangeId, this.web3.utils.toWei(newRate)) .send({ @@ -272,30 +192,6 @@ export class FixedRateExchange extends SmartContractWithAddress { return trxReceipt } - /** - * Estimate gas cost for setRate - * @param {String} account - * @param {String} exchangeId ExchangeId - * @param {String} newAllowedSwapper new allowed swapper address - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasSetAllowedSwapper( - account: string, - exchangeId: string, - newAllowedSwapper: string, - contractInstance?: Contract - ): Promise { - const fixedRate = contractInstance || this.contract - - return estimateGas( - account, - fixedRate.methods.setAllowedSwapper, - exchangeId, - newAllowedSwapper - ) - } - /** * Set new rate * @param {String} exchangeId ExchangeId @@ -303,17 +199,20 @@ export class FixedRateExchange extends SmartContractWithAddress { * @param {String} address User account * @return {Promise} transaction receipt */ - public async setAllowedSwapper( + public async setAllowedSwapper( address: string, exchangeId: string, - newAllowedSwapper: string - ): Promise { - const estGas = await estimateGas( + newAllowedSwapper: string, + estimateGas?: G + ): Promise { + const estGas = await calculateEstimatedGas( address, this.contract.methods.setAllowedSwapper, exchangeId, newAllowedSwapper ) + if (estimateGas) return estGas + const trxReceipt = await this.contract.methods .setAllowedSwapper(exchangeId, newAllowedSwapper) .send({ @@ -324,41 +223,27 @@ export class FixedRateExchange extends SmartContractWithAddress { return trxReceipt } - /** - * Estimate gas cost for activate - * @param {String} account - * @param {String} exchangeId ExchangeId - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasActivate( - account: string, - exchangeId: string, - contractInstance?: Contract - ): Promise { - const fixedRate = contractInstance || this.contract - - return estimateGas(account, fixedRate.methods.toggleExchangeState, exchangeId) - } - /** * Activate an exchange * @param {String} exchangeId ExchangeId * @param {String} address User address * @return {Promise} transaction receipt */ - public async activate( + public async activate( address: string, - exchangeId: string - ): Promise { + exchangeId: string, + estimateGas?: G + ): Promise { const exchange = await this.getExchange(exchangeId) if (!exchange) return null if (exchange.active === true) return null - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.toggleExchangeState, exchangeId ) + if (estimateGas) return estGas + const trxReceipt = await this.contract.methods.toggleExchangeState(exchangeId).send({ from: address, gas: estGas + 1, @@ -367,42 +252,27 @@ export class FixedRateExchange extends SmartContractWithAddress { return trxReceipt } - /** - * Estimate gas cost for deactivate - * @param {String} account - * @param {String} exchangeId ExchangeId - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasDeactivate( - account: string, - exchangeId: string, - contractInstance?: Contract - ): Promise { - const fixedRate = contractInstance || this.contract - - return estimateGas(account, fixedRate.methods.toggleExchangeState, exchangeId) - } - /** * Deactivate an exchange * @param {String} exchangeId ExchangeId * @param {String} address User address * @return {Promise} transaction receipt */ - public async deactivate( + public async deactivate( address: string, - exchangeId: string - ): Promise { + exchangeId: string, + estimateGas?: G + ): Promise { const exchange = await this.getExchange(exchangeId) if (!exchange) return null if (exchange.active === false) return null - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.toggleExchangeState, exchangeId ) + if (estimateGas) return estGas const trxReceipt = await this.contract.methods.toggleExchangeState(exchangeId).send({ from: address, @@ -614,43 +484,29 @@ export class FixedRateExchange extends SmartContractWithAddress { return result } - /** - * Estimate gas cost for activate - * @param {String} account - * @param {String} exchangeId ExchangeId - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasActivateMint( - account: string, - exchangeId: string, - contractInstance?: Contract - ): Promise { - const fixedRate = contractInstance || this.contract - - return estimateGas(account, fixedRate.methods.toggleMintState, exchangeId, true) - } - /** * Activate minting option for fixed rate contract * @param {String} exchangeId ExchangeId * @param {String} address User address * @return {Promise} transaction receipt */ - public async activateMint( + public async activateMint( address: string, - exchangeId: string - ): Promise { + exchangeId: string, + estimateGas?: G + ): Promise { const exchange = await this.getExchange(exchangeId) if (!exchange) return null if (exchange.withMint === true) return null - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.toggleMintState, exchangeId, true ) + if (estimateGas) return estGas + const trxReceipt = await this.contract.methods .toggleMintState(exchangeId, true) .send({ @@ -661,48 +517,28 @@ export class FixedRateExchange extends SmartContractWithAddress { return trxReceipt } - /** - * Estimate gas cost for deactivate - * @param {String} account - * @param {String} exchangeId ExchangeId - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasDeactivateMint( - account: string, - exchangeId: string, - contractInstance?: Contract - ): Promise { - const fixedRate = contractInstance || this.contract - - return estimateGas( - account, - fixedRate.methods.toggleMintState(exchangeId, false), - exchangeId, - false - ) - } - /** * Deactivate minting for fixed rate * @param {String} exchangeId ExchangeId * @param {String} address User address * @return {Promise} transaction receipt */ - public async deactivateMint( + public async deactivateMint( address: string, - exchangeId: string - ): Promise { + exchangeId: string, + estimateGas?: G + ): Promise { const exchange = await this.getExchange(exchangeId) if (!exchange) return null if (exchange.withMint === false) return null - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.toggleMintState, exchangeId, false ) + if (estimateGas) return estGas const trxReceipt = await this.contract.methods .toggleMintState(exchangeId, false) @@ -715,32 +551,6 @@ export class FixedRateExchange extends SmartContractWithAddress { return trxReceipt } - /** - * Estimate gas cost for collectBT - * @param {String} account - * @param {String} exchangeId ExchangeId - * @param {String} amount amount to be collected - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasCollectBT( - account: string, - exchangeId: string, - amount: string, - contractInstance?: Contract - ): Promise { - const fixedRate = contractInstance || this.contract - const fixedrate: FixedPriceExchange = await this.contract.methods - .getExchange(exchangeId) - .call() - const amountWei = await this.amountToUnits( - fixedrate.baseToken, - amount, - +fixedrate.btDecimals - ) - return estimateGas(account, fixedRate.methods.collectBT, exchangeId, amountWei) - } - /** * Collect BaseTokens in the contract (anyone can call this, funds are sent to Datatoken.paymentCollector) * @param {String} address User address @@ -748,11 +558,12 @@ export class FixedRateExchange extends SmartContractWithAddress { * @param {String} amount amount to be collected * @return {Promise} transaction receipt */ - public async collectBT( + public async collectBT( address: string, exchangeId: string, - amount: string - ): Promise { + amount: string, + estimateGas?: G + ): Promise { const exchange = await this.getExchange(exchangeId) if (!exchange) return null @@ -765,12 +576,13 @@ export class FixedRateExchange extends SmartContractWithAddress { +fixedrate.btDecimals ) - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.collectBT, exchangeId, amountWei ) + if (estimateGas) return estGas const trxReceipt = await this.contract.methods.collectBT(exchangeId, amountWei).send({ from: address, @@ -780,33 +592,6 @@ export class FixedRateExchange extends SmartContractWithAddress { return trxReceipt } - /** - * Estimate gas cost for collecDT - * @param {String} account - * @param {String} exchangeId ExchangeId - * @param {String} amount amount to be collected - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasCollectDT( - account: string, - exchangeId: string, - amount: string, - contractInstance?: Contract - ): Promise { - const fixedRate = contractInstance || this.contract - const fixedrate: FixedPriceExchange = await this.contract.methods - .getExchange(exchangeId) - .call() - - const amountWei = await this.amountToUnits( - fixedrate.datatoken, - amount, - +fixedrate.dtDecimals - ) - return estimateGas(account, fixedRate.methods.collectDT, exchangeId, amountWei) - } - /** * Collect datatokens in the contract (anyone can call this, funds are sent to Datatoken.paymentCollector) * @param {String} address User address @@ -814,11 +599,12 @@ export class FixedRateExchange extends SmartContractWithAddress { * @param {String} amount amount to be collected * @return {Promise} transaction receipt */ - public async collectDT( + public async collectDT( address: string, exchangeId: string, - amount: string - ): Promise { + amount: string, + estimateGas?: G + ): Promise { const exchange = await this.getExchange(exchangeId) if (!exchange) return null @@ -831,12 +617,13 @@ export class FixedRateExchange extends SmartContractWithAddress { +fixedrate.dtDecimals ) - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.collectDT, exchangeId, amountWei ) + if (estimateGas) return estGas const trxReceipt = await this.contract.methods.collectDT(exchangeId, amountWei).send({ from: address, @@ -846,41 +633,27 @@ export class FixedRateExchange extends SmartContractWithAddress { return trxReceipt } - /** - * Estimate gas cost for collecMarketFee - * @param {String} account - * @param {String} exchangeId ExchangeId - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasCollectMarketFee( - account: string, - exchangeId: string, - contractInstance?: Contract - ): Promise { - const fixedRate = contractInstance || this.contract - - return estimateGas(account, fixedRate.methods.collectMarketFee, exchangeId) - } - /** * Collect market fee and send it to marketFeeCollector (anyone can call it) * @param {String} exchangeId ExchangeId * @param {String} address User address * @return {Promise} transaction receipt */ - public async collectMarketFee( + public async collectMarketFee( address: string, - exchangeId: string - ): Promise { + exchangeId: string, + estimateGas?: G + ): Promise { const exchange = await this.getExchange(exchangeId) if (!exchange) return null - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.collectMarketFee, exchangeId ) + if (estimateGas) return estGas + const trxReceipt = await this.contract.methods.collectMarketFee(exchangeId).send({ from: address, gas: estGas + 1, @@ -889,41 +662,27 @@ export class FixedRateExchange extends SmartContractWithAddress { return trxReceipt } - /** - * Estimate gas cost for collectOceanFee - * @param {String} account - * @param {String} exchangeId ExchangeId - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasCollectOceanFee( - account: string, - exchangeId: string, - contractInstance?: Contract - ): Promise { - const fixedRate = contractInstance || this.contract - - return estimateGas(account, fixedRate.methods.collectMarketFee, exchangeId) - } - /** * Collect ocean fee and send it to OPF collector (anyone can call it) * @param {String} exchangeId ExchangeId * @param {String} address User address * @return {Promise} transaction receipt */ - public async collectOceanFee( + public async collectOceanFee( address: string, - exchangeId: string - ): Promise { + exchangeId: string, + estimateGas?: G + ): Promise { const exchange = await this.getExchange(exchangeId) if (!exchange) return null - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.collectOceanFee, exchangeId ) + if (estimateGas) return estGas + const trxReceipt = await this.contract.methods.collectOceanFee(exchangeId).send({ from: address, gas: estGas + 1, @@ -975,30 +734,6 @@ export class FixedRateExchange extends SmartContractWithAddress { return result } - /** - * Estimate gas cost for updateMarketFee - * @param {String} account - * @param {String} exchangeId ExchangeId - * @param {String} newMarketFee New market fee - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasUpdateMarketFee( - account: string, - exchangeId: string, - newMarketFee: string, - contractInstance?: Contract - ): Promise { - const fixedRate = contractInstance || this.contract - - return estimateGas( - account, - fixedRate.methods.updateMarketFee, - exchangeId, - newMarketFee - ) - } - /** * Set new market fee, only market fee collector can update it * @param {String} address user address @@ -1006,17 +741,20 @@ export class FixedRateExchange extends SmartContractWithAddress { * @param {String} newMarketFee New market fee * @return {Promise} transaction receipt */ - public async updateMarketFee( + public async updateMarketFee( address: string, exchangeId: string, - newMarketFee: string - ): Promise { - const estGas = await estimateGas( + newMarketFee: string, + estimateGas?: G + ): Promise { + const estGas = await calculateEstimatedGas( address, this.contract.methods.updateMarketFee, exchangeId, this.web3.utils.toWei(newMarketFee) ) + if (estimateGas) return estGas + const trxReceipt = await this.contract.methods .updateMarketFee(exchangeId, this.web3.utils.toWei(newMarketFee)) .send({ @@ -1027,30 +765,6 @@ export class FixedRateExchange extends SmartContractWithAddress { return trxReceipt } - /** - * Estimate gas cost for updateMarketFeeCollector - * @param {String} account - * @param {String} exchangeId ExchangeId - * @param {String} newMarketFee New market fee collector - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasUpdateMarketFeeCollector( - account: string, - exchangeId: string, - newMarketFeeCollector: string, - contractInstance?: Contract - ): Promise { - const fixedRate = contractInstance || this.contract - - return estimateGas( - account, - fixedRate.methods.updateMarketFeeCollector, - exchangeId, - newMarketFeeCollector - ) - } - /** * Set new market fee collector, only market fee collector can update it * @param {String} address user address @@ -1058,17 +772,20 @@ export class FixedRateExchange extends SmartContractWithAddress { * @param {String} newMarketFeeCollector New market fee collector * @return {Promise} transaction receipt */ - public async updateMarketFeeCollector( + public async updateMarketFeeCollector( address: string, exchangeId: string, - newMarketFeeCollector: string - ): Promise { - const estGas = await estimateGas( + newMarketFeeCollector: string, + estimateGas?: G + ): Promise { + const estGas = await calculateEstimatedGas( address, this.contract.methods.updateMarketFeeCollector, exchangeId, newMarketFeeCollector ) + if (estimateGas) return estGas + const trxReceipt = await this.contract.methods .updateMarketFeeCollector(exchangeId, newMarketFeeCollector) .send({ diff --git a/src/contracts/pools/Pool.ts b/src/contracts/pools/Pool.ts index 4685dac4..4d8d4e89 100644 --- a/src/contracts/pools/Pool.ts +++ b/src/contracts/pools/Pool.ts @@ -1,12 +1,11 @@ import { AbiItem } from 'web3-utils/types' import { TransactionReceipt } from 'web3-core' -import { Contract } from 'web3-eth-contract' import Decimal from 'decimal.js' import BigNumber from 'bignumber.js' import Bpool from '@oceanprotocol/contracts/artifacts/contracts/pools/balancer/BPool.sol/BPool.json' import { LoggerInstance, - estimateGas, + calculateEstimatedGas, MAX_UINT_256, decimals, calcMaxExactOut, @@ -47,41 +46,22 @@ export class Pool extends SmartContract { return result } - /** - * Estimate gas cost for setSwapFee - * @param {String} account - * @param {String} tokenAddress - * @param {String} spender - * @param {String} amount - * @param {String} force - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasSetSwapFee( - account: string, - poolAddress: string, - fee: string, - contractInstance?: Contract - ): Promise { - const poolContract = contractInstance || this.getContract(poolAddress) - - return estimateGas(account, poolContract.methods.setSwapFee, fee) - } - /** * Allows controller to change the swapFee * @param {String} account * @param {String} poolAddress * @param {String} fee swap fee (1e17 = 10 % , 1e16 = 1% , 1e15 = 0.1%, 1e14 = 0.01%) */ - async setSwapFee( + async setSwapFee( account: string, poolAddress: string, - fee: string - ): Promise { + fee: string, + estimateGas?: G + ): Promise { const pool = this.getContract(poolAddress, account) let result = null - const estGas = await estimateGas(account, pool.methods.setSwapFee, fee) + const estGas = await calculateEstimatedGas(account, pool.methods.setSwapFee, fee) + if (estimateGas) return estGas try { result = await pool.methods.setSwapFee(this.web3.utils.toWei(fee)).send({ @@ -472,33 +452,21 @@ export class Pool extends SmartContract { return weight } - /** - * Estimate gas cost for collectOPF - * @param {String} address - * @param {String} poolAddress - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasCollectOPC( - address: string, - poolAddress: string, - contractInstance?: Contract - ): Promise { - const poolContract = contractInstance || this.getContract(poolAddress) - - return estimateGas(address, poolContract.methods.collectOPC) - } - /** * collectOPF - collect opf fee - can be called by anyone * @param {String} address * @param {String} poolAddress * @return {TransactionReceipt} */ - async collectOPC(address: string, poolAddress: string): Promise { + async collectOPC( + address: string, + poolAddress: string, + estimateGas?: G + ): Promise { const pool = this.getContract(poolAddress) let result = null - const estGas = await estimateGas(address, pool.methods.collectOPC) + const estGas = await calculateEstimatedGas(address, pool.methods.collectOPC) + if (estimateGas) return estGas try { result = await pool.methods.collectOPC().send({ @@ -512,24 +480,6 @@ export class Pool extends SmartContract { return result } - /** - * Estimate gas cost for collectMarketFee - * @param {String} address - * @param {String} poolAddress - * @param {String} to address that will receive fees - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasCollectMarketFee( - address: string, - poolAddress: string, - contractInstance?: Contract - ): Promise { - const poolContract = contractInstance || this.getContract(poolAddress) - - return estimateGas(address, poolContract.methods.collectMarketFee) - } - /** * collectOPF - collect market fees - can be called by the publishMarketCollector * @param {String} address @@ -537,16 +487,18 @@ export class Pool extends SmartContract { * @param {String} to address that will receive fees * @return {TransactionReceipt} */ - async collectMarketFee( + async collectMarketFee( address: string, - poolAddress: string - ): Promise { + poolAddress: string, + estimateGas?: G + ): Promise { if ((await this.getMarketFeeCollector(poolAddress)) !== address) { throw new Error(`Caller is not MarketFeeCollector`) } const pool = this.getContract(poolAddress) let result = null - const estGas = await estimateGas(address, pool.methods.collectMarketFee) + const estGas = await calculateEstimatedGas(address, pool.methods.collectMarketFee) + if (estimateGas) return estGas try { result = await pool.methods.collectMarketFee().send({ @@ -560,32 +512,6 @@ export class Pool extends SmartContract { return result } - /** - * Estimate gas cost for updatePublishMarketFee - * @param {String} address - * @param {String} poolAddress - * @param {String} newPublishMarketAddress new market address - * @param {String} newPublishMarketSwapFee new market swap fee - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasUpdatePublishMarketFee( - address: string, - poolAddress: string, - newPublishMarketAddress: string, - newPublishMarketSwapFee: string, - contractInstance?: Contract - ): Promise { - const poolContract = contractInstance || this.getContract(poolAddress) - - return estimateGas( - address, - poolContract.methods.updatePublishMarketFee, - newPublishMarketAddress, - this.web3.utils.toWei(newPublishMarketSwapFee) - ) - } - /** * updatePublishMarketFee - sets a new newPublishMarketAddress and new newPublishMarketSwapFee- can be called only by the marketFeeCollector * @param {String} address @@ -594,24 +520,27 @@ export class Pool extends SmartContract { * @param {String} newPublishMarketSwapFee fee recieved by the publisher market when a dt is swaped from a pool, percent * @return {TransactionReceipt} */ - async updatePublishMarketFee( + async updatePublishMarketFee( address: string, poolAddress: string, newPublishMarketAddress: string, - newPublishMarketSwapFee: string - ): Promise { + newPublishMarketSwapFee: string, + estimateGas?: G + ): Promise { if ((await this.getMarketFeeCollector(poolAddress)) !== address) { throw new Error(`Caller is not MarketFeeCollector`) } const pool = this.getContract(poolAddress) let result = null - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, pool.methods.updatePublishMarketFee, newPublishMarketAddress, this.web3.utils.toWei(newPublishMarketSwapFee) ) + if (estimateGas) return estGas + try { result = await pool.methods .updatePublishMarketFee( @@ -629,60 +558,6 @@ export class Pool extends SmartContract { return result } - /** - * Estimate gas cost for swapExactAmountIn - * @param {String} address - * @param {String} poolAddress - * @param {TokenInOutMarket} tokenInOutMarket object contianing addresses like tokenIn, tokenOut, consumeMarketFeeAddress - * @param {AmountsInMaxFee} amountsInOutMaxFee object contianing tokenAmountIn, minAmountOut, maxPrice, consumeMarketSwapFee - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasSwapExactAmountIn( - address: string, - poolAddress: string, - tokenInOutMarket: TokenInOutMarket, - amountsInOutMaxFee: AmountsInMaxFee, - contractInstance?: Contract - ): Promise { - const poolContract = contractInstance || this.getContract(poolAddress) - - const tokenAmountIn = await this.amountToUnits( - tokenInOutMarket.tokenIn, - amountsInOutMaxFee.tokenAmountIn, - tokenInOutMarket.tokenInDecimals - ) - - const minAmountOut = await this.amountToUnits( - tokenInOutMarket.tokenOut, - amountsInOutMaxFee.minAmountOut, - tokenInOutMarket.tokenOutDecimals - ) - - const maxPrice = amountsInOutMaxFee.maxPrice - ? this.amountToUnits( - await this.getBaseToken(poolAddress), - amountsInOutMaxFee.maxPrice - ) - : MAX_UINT_256 - - return estimateGas( - address, - poolContract.methods.swapExactAmountIn, - [ - tokenInOutMarket.tokenIn, - tokenInOutMarket.tokenOut, - tokenInOutMarket.marketFeeAddress - ], - [ - tokenAmountIn, - minAmountOut, - maxPrice, - this.web3.utils.toWei(amountsInOutMaxFee.swapMarketFee) - ] - ) - } - /** * Swaps an exact amount of tokensIn to get a mimum amount of tokenOut * Trades an exact tokenAmountIn of tokenIn taken from the caller by the pool, @@ -696,12 +571,13 @@ export class Pool extends SmartContract { * @param {AmountsInMaxFee} amountsInOutMaxFee object contianing tokenAmountIn, minAmountOut, maxPrice, consumeMarketSwapFee * @return {TransactionReceipt} */ - async swapExactAmountIn( + async swapExactAmountIn( address: string, poolAddress: string, tokenInOutMarket: TokenInOutMarket, - amountsInOutMaxFee: AmountsInMaxFee - ): Promise { + amountsInOutMaxFee: AmountsInMaxFee, + estimateGas?: G + ): Promise { const pool = this.getContract(poolAddress) const maxSwap = await this.getMaxSwapExactIn(poolAddress, tokenInOutMarket.tokenIn) @@ -728,7 +604,7 @@ export class Pool extends SmartContract { ) : MAX_UINT_256 - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, pool.methods.swapExactAmountIn, [ @@ -743,6 +619,7 @@ export class Pool extends SmartContract { this.web3.utils.toWei(amountsInOutMaxFee.swapMarketFee) ] ) + if (estimateGas) return estGas let result = null try { @@ -772,60 +649,6 @@ export class Pool extends SmartContract { return result } - /** - * Estimate gas cost for swapExactAmountOut - * @param {String} address - * @param {String} poolAddress - * @param {TokenInOutMarket} tokenInOutMarket - * @param {AmountsOutMaxFee} amountsInOutMaxFee - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasSwapExactAmountOut( - address: string, - poolAddress: string, - tokenInOutMarket: TokenInOutMarket, - amountsInOutMaxFee: AmountsOutMaxFee, - contractInstance?: Contract - ): Promise { - const poolContract = contractInstance || this.getContract(poolAddress) - - const maxAmountIn = await this.amountToUnits( - tokenInOutMarket.tokenIn, - amountsInOutMaxFee.maxAmountIn, - tokenInOutMarket.tokenInDecimals - ) - - const tokenAmountOut = await this.amountToUnits( - tokenInOutMarket.tokenOut, - amountsInOutMaxFee.tokenAmountOut, - tokenInOutMarket.tokenOutDecimals - ) - - const maxPrice = amountsInOutMaxFee.maxPrice - ? await this.amountToUnits( - await this.getBaseToken(poolAddress), - amountsInOutMaxFee.maxPrice - ) - : MAX_UINT_256 - - return estimateGas( - address, - poolContract.methods.swapExactAmountOut, - [ - tokenInOutMarket.tokenIn, - tokenInOutMarket.tokenOut, - tokenInOutMarket.marketFeeAddress - ], - [ - maxAmountIn, - tokenAmountOut, - maxPrice, - this.web3.utils.toWei(amountsInOutMaxFee.swapMarketFee) - ] - ) - } - /** * Swaps a maximum maxAmountIn of tokensIn to get an exact amount of tokenOut * @param {String} account @@ -834,12 +657,13 @@ export class Pool extends SmartContract { * @param {AmountsOutMaxFee} amountsInOutMaxFee Object containging maxAmountIn,tokenAmountOut,maxPrice, consumeMarketSwapFee] * @return {TransactionReceipt} */ - async swapExactAmountOut( + async swapExactAmountOut( account: string, poolAddress: string, tokenInOutMarket: TokenInOutMarket, - amountsInOutMaxFee: AmountsOutMaxFee - ): Promise { + amountsInOutMaxFee: AmountsOutMaxFee, + estimateGas?: G + ): Promise { const pool = this.getContract(poolAddress) let result = null @@ -867,7 +691,7 @@ export class Pool extends SmartContract { ) : MAX_UINT_256 - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( account, pool.methods.swapExactAmountOut, [ @@ -882,6 +706,7 @@ export class Pool extends SmartContract { this.web3.utils.toWei(amountsInOutMaxFee.swapMarketFee) ] ) + if (estimateGas) return estGas try { result = await pool.methods @@ -909,33 +734,6 @@ export class Pool extends SmartContract { return result } - /** - * Estimate gas cost for joinswapExternAmountIn - * @param {String} address - * @param {String} poolAddress - * @param {String} tokenIn - * @param {String} tokenAmountIn exact number of base tokens to spend - * @param {String} minPoolAmountOut minimum of pool shares expectex - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasJoinswapExternAmountIn( - address: string, - poolAddress: string, - tokenAmountIn: string, - minPoolAmountOut: string, - contractInstance?: Contract - ): Promise { - const poolContract = contractInstance || this.getContract(poolAddress) - - return estimateGas( - address, - poolContract.methods.joinswapExternAmountIn, - tokenAmountIn, - minPoolAmountOut - ) - } - /** * Single side add liquidity to the pool, * expecting a minPoolAmountOut of shares for spending tokenAmountIn basetokens. @@ -947,13 +745,14 @@ export class Pool extends SmartContract { * @param {number} tokenInDecimals optional number of decimals of the token * @return {TransactionReceipt} */ - async joinswapExternAmountIn( + async joinswapExternAmountIn( account: string, poolAddress: string, tokenAmountIn: string, minPoolAmountOut: string, - tokenInDecimals?: number - ): Promise { + tokenInDecimals?: number, + estimateGas?: G + ): Promise { const pool = this.getContract(poolAddress) let result = null const tokenIn = await this.getBaseToken(poolAddress) @@ -967,12 +766,13 @@ export class Pool extends SmartContract { tokenAmountIn, tokenInDecimals ) - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( account, pool.methods.joinswapExternAmountIn, amountInFormatted, this.web3.utils.toWei(minPoolAmountOut) ) + if (estimateGas) return estGas try { result = await pool.methods @@ -992,32 +792,6 @@ export class Pool extends SmartContract { return result } - /** - * Estimate gas cost for exitswapPoolAmountIn - * @param {String} address - * @param {String} poolAddress - * @param {String} poolAmountIn exact number of pool shares to spend - * @param {String} minTokenAmountOut minimum amount of basetokens expected - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasExitswapPoolAmountIn( - address: string, - poolAddress: string, - poolAmountIn: string, - minTokenAmountOut: string, - contractInstance?: Contract - ): Promise { - const poolContract = contractInstance || this.getContract(poolAddress) - - return estimateGas( - address, - poolContract.methods.exitswapPoolAmountIn, - poolAmountIn, - minTokenAmountOut - ) - } - /** * Single side remove liquidity from the pool, * expecting a minAmountOut of basetokens for spending poolAmountIn pool shares @@ -1029,13 +803,14 @@ export class Pool extends SmartContract { * @param {number} poolDecimals optional number of decimals of the poool * @return {TransactionReceipt} */ - async exitswapPoolAmountIn( + async exitswapPoolAmountIn( account: string, poolAddress: string, poolAmountIn: string, minTokenAmountOut: string, - poolDecimals?: number - ): Promise { + poolDecimals?: number, + estimateGas?: G + ): Promise { const pool = this.getContract(poolAddress) let result = null const tokenOut = await this.getBaseToken(poolAddress) @@ -1056,12 +831,13 @@ export class Pool extends SmartContract { minTokenAmountOut, poolDecimals ) - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( account, pool.methods.exitswapPoolAmountIn, this.web3.utils.toWei(poolAmountIn), minTokenOutFormatted ) + if (estimateGas) return estGas try { result = await pool.methods diff --git a/src/contracts/pools/Router.ts b/src/contracts/pools/Router.ts index 71f65313..24d1243d 100644 --- a/src/contracts/pools/Router.ts +++ b/src/contracts/pools/Router.ts @@ -1,8 +1,7 @@ -import { Contract } from 'web3-eth-contract' import { TransactionReceipt } from 'web3-core' import { AbiItem } from 'web3-utils' import FactoryRouter from '@oceanprotocol/contracts/artifacts/contracts/pools/FactoryRouter.sol/FactoryRouter.json' -import { estimateGas } from '../../utils' +import { calculateEstimatedGas } from '../../utils' import { Operation } from '../../@types' import { SmartContractWithAddress } from '..' @@ -14,31 +13,23 @@ export class Router extends SmartContractWithAddress { return FactoryRouter.abi as AbiItem[] } - /** - * Estimate gas cost for buyDTBatch method - * @param {String} address - * @param {Operation} operations Operations objects array - * @return {Promise} Transaction receipt - */ - public async estGasBuyDTBatch(address: string, operations: Operation[]): Promise { - return estimateGas(address, this.contract.methods.buyDTBatch, operations) - } - /** * BuyDTBatch * @param {String} address * @param {Operation} operations Operations objects array * @return {Promise} Transaction receipt */ - public async buyDTBatch( + public async buyDTBatch( address: string, - operations: Operation[] - ): Promise { - const estGas = await estimateGas( + operations: Operation[], + estimateGas?: G + ): Promise { + const estGas = await calculateEstimatedGas( address, this.contract.methods.buyDTBatch, operations ) + if (estimateGas) return estGas // Invoke createToken function of the contract const trxReceipt = await this.contract.methods.buyDTBatch(operations).send({ @@ -92,40 +83,27 @@ export class Router extends SmartContractWithAddress { return await this.contract.methods.isPoolTemplate(address).call() } - /** - * Estimate gas cost for addApprovedToken - * @param {String} address - * @param {String} tokenAddress token address we want to add - * @param {Contract} routerContract optional contract instance - * @return {Promise} - */ - public async estGasAddApprovedToken( - address: string, - tokenAddress: string, - contractInstance?: Contract - ): Promise { - return estimateGas(address, this.contract.methods.addApprovedToken, tokenAddress) - } - /** * Add a new token to oceanTokens list, pools with baseToken in this list have NO opf Fee * @param {String} address caller address * @param {String} tokenAddress token address to add * @return {Promise} */ - public async addApprovedToken( + public async addApprovedToken( address: string, - tokenAddress: string - ): Promise { + tokenAddress: string, + estimateGas?: G + ): Promise { if ((await this.getOwner()) !== address) { throw new Error(`Caller is not Router Owner`) } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.addApprovedToken, tokenAddress ) + if (estimateGas) return estGas // Invoke createToken function of the contract const trxReceipt = await this.contract.methods.addApprovedToken(tokenAddress).send({ @@ -137,40 +115,27 @@ export class Router extends SmartContractWithAddress { return trxReceipt } - /** - * Estimate gas cost for removeApprovedToken - * @param {String} address caller address - * @param {String} tokenAddress token address we want to add - * @param {Contract} routerContract optional contract instance - * @return {Promise} - */ - public async estGasRemoveApprovedToken( - address: string, - tokenAddress: string, - contractInstance?: Contract - ): Promise { - return estimateGas(address, this.contract.methods.removeApprovedToken, tokenAddress) - } - /** * Remove a token from oceanTokens list, pools without baseToken in this list have a opf Fee * @param {String} address * @param {String} tokenAddress address to remove * @return {Promise} */ - public async removeApprovedToken( + public async removeApprovedToken( address: string, - tokenAddress: string - ): Promise { + tokenAddress: string, + estimateGas?: G + ): Promise { if ((await this.getOwner()) !== address) { throw new Error(`Caller is not Router Owner`) } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.removeApprovedToken, tokenAddress ) + if (estimateGas) return estGas // Invoke createToken function of the contract const trxReceipt = await this.contract.methods @@ -184,35 +149,27 @@ export class Router extends SmartContractWithAddress { return trxReceipt } - /** - * Estimate gas cost for addSSContract method - * @param {String} address - * @param {String} tokenAddress contract address to add - * @return {Promise} - */ - public async estGasAddSSContract(address: string, tokenAddress: string): Promise { - return estimateGas(address, this.contract.methods.addSSContract, tokenAddress) - } - /** * Add a new contract to ssContract list, after is added, can be used when deploying a new pool * @param {String} address * @param {String} tokenAddress contract address to add * @return {Promise} */ - public async addSSContract( + public async addSSContract( address: string, - tokenAddress: string - ): Promise { + tokenAddress: string, + estimateGas?: G + ): Promise { if ((await this.getOwner()) !== address) { throw new Error(`Caller is not Router Owner`) } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.addSSContract, tokenAddress ) + if (estimateGas) return estGas // Invoke createToken function of the contract const trxReceipt = await this.contract.methods.addSSContract(tokenAddress).send({ @@ -224,38 +181,27 @@ export class Router extends SmartContractWithAddress { return trxReceipt } - /** - * Estimate gas cost for removeSSContract method - * @param {String} address caller address - * @param {String} tokenAddress contract address to add - * @return {Promise} - */ - public async estGasRemoveSSContract( - address: string, - tokenAddress: string - ): Promise { - return estimateGas(address, this.contract.methods.removeSSContract, tokenAddress) - } - /** * Removes a new contract from ssContract list * @param {String} address caller address * @param {String} tokenAddress contract address to removed * @return {Promise} */ - public async removeSSContract( + public async removeSSContract( address: string, - tokenAddress: string - ): Promise { + tokenAddress: string, + estimateGas?: G + ): Promise { if ((await this.getOwner()) !== address) { throw new Error(`Caller is not Router Owner`) } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.removeSSContract, tokenAddress ) + if (estimateGas) return estGas // Invoke createToken function of the contract const trxReceipt = await this.contract.methods.removeSSContract(tokenAddress).send({ @@ -267,38 +213,27 @@ export class Router extends SmartContractWithAddress { return trxReceipt } - /** - * Estimate gas cost for addFixedRateContract method - * @param {String} address - * @param {String} tokenAddress contract address to add - * @return {Promise} - */ - public async estGasAddFixedRateContract( - address: string, - tokenAddress: string - ): Promise { - return estimateGas(address, this.contract.methods.addFixedRateContract, tokenAddress) - } - /** * Add a new contract to fixedRate list, after is added, can be used when deploying a new pool * @param {String} address * @param {String} tokenAddress contract address to add * @return {Promise} */ - public async addFixedRateContract( + public async addFixedRateContract( address: string, - tokenAddress: string - ): Promise { + tokenAddress: string, + estimateGas?: G + ): Promise { if ((await this.getOwner()) !== address) { throw new Error(`Caller is not Router Owner`) } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.addFixedRateContract, tokenAddress ) + if (estimateGas) return estGas // Invoke createToken function of the contract const trxReceipt = await this.contract.methods @@ -312,42 +247,27 @@ export class Router extends SmartContractWithAddress { return trxReceipt } - /** - * Estimate gas cost for addFixedRateContract method - * @param {String} address - * @param {String} tokenAddress contract address to add - * @return {Promise} - */ - public async estGasRemoveFixedRateContract( - address: string, - tokenAddress: string - ): Promise { - return estimateGas( - address, - this.contract.methods.removeFixedRateContract, - tokenAddress - ) - } - /** * Removes a contract from fixedRate list * @param {String} address * @param {String} tokenAddress contract address to add * @return {Promise} */ - public async removeFixedRateContract( + public async removeFixedRateContract( address: string, - tokenAddress: string - ): Promise { + tokenAddress: string, + estimateGas?: G + ): Promise { if ((await this.getOwner()) !== address) { throw new Error(`Caller is not Router Owner`) } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.removeFixedRateContract, tokenAddress ) + if (estimateGas) return estGas // Invoke removeFixedRateContract function of the contract const trxReceipt = await this.contract.methods @@ -361,38 +281,27 @@ export class Router extends SmartContractWithAddress { return trxReceipt } - /** - * Estimate gas cost for addDispenserContract method - * @param {String} address - * @param {String} tokenAddress contract address to add - * @return {Promise} - */ - public async estGasAddDispenserContract( - address: string, - tokenAddress: string - ): Promise { - return estimateGas(address, this.contract.methods.addDispenserContract, tokenAddress) - } - /** * Add a new contract to dispenser list, after is added, can be used when deploying a new pool * @param {String} address * @param {String} tokenAddress contract address to add * @return {Promise} */ - public async addDispenserContract( + public async addDispenserContract( address: string, - tokenAddress: string - ): Promise { + tokenAddress: string, + estimateGas?: G + ): Promise { if ((await this.getOwner()) !== address) { throw new Error(`Caller is not Router Owner`) } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.addDispenserContract, tokenAddress ) + if (estimateGas) return estGas // Invoke createToken function of the contract const trxReceipt = await this.contract.methods @@ -406,42 +315,27 @@ export class Router extends SmartContractWithAddress { return trxReceipt } - /** - * Estimate gas cost for addDispenserContract method - * @param {String} address - * @param {String} tokenAddress contract address to add - * @return {Promise} - */ - public async estGasRemoveDispenserContract( - address: string, - tokenAddress: string - ): Promise { - return estimateGas( - address, - this.contract.methods.removeDispenserContract, - tokenAddress - ) - } - /** * Add a new contract to dispenser list, after is added, can be used when deploying a new pool * @param {String} address * @param {String} tokenAddress contract address to add * @return {Promise} */ - public async removeDispenserContract( + public async removeDispenserContract( address: string, - tokenAddress: string - ): Promise { + tokenAddress: string, + estimateGas?: G + ): Promise { if ((await this.getOwner()) !== address) { throw new Error(`Caller is not Router Owner`) } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.removeDispenserContract, tokenAddress ) + if (estimateGas) return estGas // Invoke createToken function of the contract const trxReceipt = await this.contract.methods @@ -469,29 +363,6 @@ export class Router extends SmartContractWithAddress { return await this.contract.methods.swapOceanFee().call() } - /** - * Estimate gas cost for updateOPFFee method - * @param {String} address - * @param {String} newFee new OPF Fee - * @return {Promise} - */ - public async estGasUpdateOPCFee( - address: string, - newSwapOceanFee: number, - newSwapNonOceanFee: number, - newConsumeFee: number, - newProviderFee: number - ): Promise { - return estimateGas( - address, - this.contract.methods.updateOPCFee, - newSwapOceanFee, - newSwapNonOceanFee, - newConsumeFee, - newProviderFee - ) - } - /** * Add a new contract to fixedRate list, after is added, can be used when deploying a new pool * @param {String} address @@ -501,18 +372,19 @@ export class Router extends SmartContractWithAddress { * @param {number} newProviderFee Amount charged for providerFees * @return {Promise} */ - public async updateOPCFee( + public async updateOPCFee( address: string, newSwapOceanFee: number, newSwapNonOceanFee: number, newConsumeFee: number, - newProviderFee: number - ): Promise { + newProviderFee: number, + estimateGas?: G + ): Promise { if ((await this.getOwner()) !== address) { throw new Error(`Caller is not Router Owner`) } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.updateOPCFee, newSwapOceanFee, @@ -520,6 +392,7 @@ export class Router extends SmartContractWithAddress { newConsumeFee, newProviderFee ) + if (estimateGas) return estGas // Invoke createToken function of the contract const trxReceipt = await this.contract.methods @@ -533,38 +406,27 @@ export class Router extends SmartContractWithAddress { return trxReceipt } - /** - * Estimate gas cost for addPoolTemplate method - * @param {String} address - * @param {String} templateAddress template address to add - * @return {Promise} - */ - public async estGasAddPoolTemplate( - address: string, - templateAddress: string - ): Promise { - return estimateGas(address, this.contract.methods.addPoolTemplate, templateAddress) - } - /** * Add a new template to poolTemplates mapping, after template is added,it can be used * @param {String} address * @param {String} templateAddress template address to add * @return {Promise} */ - public async addPoolTemplate( + public async addPoolTemplate( address: string, - templateAddress: string - ): Promise { + templateAddress: string, + estimateGas?: G + ): Promise { if ((await this.getOwner()) !== address) { throw new Error(`Caller is not Router Owner`) } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.addPoolTemplate, templateAddress ) + if (estimateGas) return estGas // Invoke createToken function of the contract const trxReceipt = await this.contract.methods.addPoolTemplate(templateAddress).send({ @@ -576,38 +438,27 @@ export class Router extends SmartContractWithAddress { return trxReceipt } - /** - * Estimate gas cost for removePoolTemplate method - * @param {String} address - * @param {String} templateAddress template address to remove - * @return {Promise} - */ - public async estGasRemovePoolTemplate( - address: string, - templateAddress: string - ): Promise { - return estimateGas(address, this.contract.methods.removePoolTemplate, templateAddress) - } - /** * Remove template from poolTemplates mapping, after template is removed,it can be used anymore * @param {String} address * @param {String} templateAddress template address to remove * @return {Promise} */ - public async removePoolTemplate( + public async removePoolTemplate( address: string, - templateAddress: string - ): Promise { + templateAddress: string, + estimateGas?: G + ): Promise { if ((await this.getOwner()) !== address) { throw new Error(`Caller is not Router Owner`) } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, this.contract.methods.removePoolTemplate, templateAddress ) + if (estimateGas) return estGas // Invoke createToken function of the contract const trxReceipt = await this.contract.methods diff --git a/src/contracts/pools/SideStaking.ts b/src/contracts/pools/SideStaking.ts index ad0c245a..dd62ae4e 100644 --- a/src/contracts/pools/SideStaking.ts +++ b/src/contracts/pools/SideStaking.ts @@ -1,8 +1,7 @@ import { AbiItem } from 'web3-utils/types' import { TransactionReceipt } from 'web3-core' -import { Contract } from 'web3-eth-contract' import SideStakingAbi from '@oceanprotocol/contracts/artifacts/contracts/pools/ssContracts/SideStaking.sol/SideStaking.json' -import { LoggerInstance, estimateGas } from '../../utils' +import { LoggerInstance, calculateEstimatedGas } from '../../utils' import { SmartContract } from '..' export class SideStaking extends SmartContract { @@ -235,25 +234,6 @@ export class SideStaking extends SmartContract { return result } - /** - * Estimate gas cost for getVesting - * @param {String} account - * @param {String} ssAddress side staking contract address - * @param {String} datatokenAddress datatokenAddress - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasGetVesting( - account: string, - ssAddress: string, - datatokenAddress: string, - contractInstance?: Contract - ): Promise { - const sideStaking = contractInstance || this.getContract(ssAddress) - - return estimateGas(account, sideStaking.methods.getVesting, datatokenAddress) - } - /** Send vested tokens available to the publisher address, can be called by anyone * * @param {String} account @@ -261,19 +241,21 @@ export class SideStaking extends SmartContract { * @param {String} datatokenAddress datatokenAddress * @return {TransactionReceipt} */ - async getVesting( + async getVesting( account: string, ssAddress: string, - datatokenAddress: string - ): Promise { + datatokenAddress: string, + estimateGas?: G + ): Promise { const sideStaking = this.getContract(ssAddress) let result = null - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( account, sideStaking.methods.getVesting, datatokenAddress ) + if (estimateGas) return estGas try { result = await sideStaking.methods.getVesting(datatokenAddress).send({ @@ -287,33 +269,6 @@ export class SideStaking extends SmartContract { return result } - /** - * Estimate gas cost for getVesting - * @param {String} account - * @param {String} ssAddress side staking contract address - * @param {String} datatokenAddress datatokenAddress - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasSetPoolSwapFee( - account: string, - ssAddress: string, - datatokenAddress: string, - poolAddress: string, - swapFee: number, - contractInstance?: Contract - ): Promise { - const sideStaking = contractInstance || this.getContract(ssAddress) - - return estimateGas( - account, - sideStaking.methods.setPoolSwapFee, - datatokenAddress, - poolAddress, - swapFee - ) - } - /** Send vested tokens available to the publisher address, can be called by anyone * * @param {String} account @@ -321,23 +276,25 @@ export class SideStaking extends SmartContract { * @param {String} datatokenAddress datatokenAddress * @return {TransactionReceipt} */ - private async setPoolSwapFee( + private async setPoolSwapFee( account: string, ssAddress: string, datatokenAddress: string, poolAddress: string, - swapFee: number - ): Promise { + swapFee: number, + estimateGas?: G + ): Promise { const sideStaking = this.getContract(ssAddress) let result = null - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( account, sideStaking.methods.setPoolSwapFee, datatokenAddress, poolAddress, swapFee ) + if (estimateGas) return estGas try { result = await sideStaking.methods diff --git a/src/contracts/tokens/Datatoken.ts b/src/contracts/tokens/Datatoken.ts index a80ea569..2e464933 100644 --- a/src/contracts/tokens/Datatoken.ts +++ b/src/contracts/tokens/Datatoken.ts @@ -1,11 +1,10 @@ import Web3 from 'web3' import { AbiItem } from 'web3-utils' import { TransactionReceipt } from 'web3-eth' -import { Contract } from 'web3-eth-contract' import Decimal from 'decimal.js' import ERC20Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json' import ERC20TemplateEnterprise from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20TemplateEnterprise.sol/ERC20TemplateEnterprise.json' -import { LoggerInstance, estimateGas, ZERO_ADDRESS } from '../../utils' +import { LoggerInstance, calculateEstimatedGas, ZERO_ADDRESS } from '../../utils' import { ConsumeMarketFee, FreOrderParams, @@ -45,32 +44,6 @@ export class Datatoken extends SmartContract { this.nft = new Nft(this.web3) } - /** - * Estimate gas cost for mint method - * @param {String} dtAddress Datatoken address - * @param {String} spender Spender address - * @param {string} amount Number of datatokens, as number. Will be converted to wei - * @param {String} address User adress - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasApprove( - dtAddress: string, - spender: string, - amount: string, - address: string, - contractInstance?: Contract - ): Promise { - const dtContract = contractInstance || this.getContract(dtAddress) - - return estimateGas( - address, - dtContract.methods.approve, - spender, - this.web3.utils.toWei(amount) - ) - } - /** * Approve * @param {String} dtAddress Datatoken address @@ -79,20 +52,22 @@ export class Datatoken extends SmartContract { * @param {String} address User adress * @return {Promise} trxReceipt */ - public async approve( + public async approve( dtAddress: string, spender: string, amount: string, - address: string - ): Promise { + address: string, + estimateGas?: G + ): Promise { const dtContract = this.getContract(dtAddress) - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, dtContract.methods.approve, spender, this.web3.utils.toWei(amount) ) + if (estimateGas) return estGas // Call mint contract method const trxReceipt = await dtContract.methods @@ -105,72 +80,6 @@ export class Datatoken extends SmartContract { return trxReceipt } - /** - * Estimate gas cost for mint method - * @param {String} dtAddress Datatoken address - * @param {String} address Minter address - * @param {String} amount Number of datatokens, as number. Will be converted to wei - * @param {String} toAddress only if toAddress is different from the minter - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasMint( - dtAddress: string, - address: string, - amount: string, - toAddress?: string, - contractInstance?: Contract - ): Promise { - const dtContract = contractInstance || this.getContract(dtAddress) - - return estimateGas( - address, - dtContract.methods.mint, - toAddress || address, - this.web3.utils.toWei(amount) - ) - } - - /** - * Estimate gas cost for createFixedRate method - * @param {String} dtAddress Datatoken address - * @param {String} address Caller address - * @param {String} fixedPriceAddress - * @param {FixedRateParams} fixedRateParams - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasCreateFixedRate( - dtAddress: string, - address: string, - fixedRateParams: FreCreationParams, - contractInstance?: Contract - ): Promise { - const dtContract = contractInstance || this.getContract(dtAddress) - - if (!fixedRateParams.allowedConsumer) fixedRateParams.allowedConsumer = ZERO_ADDRESS - const withMint = fixedRateParams.withMint ? 1 : 0 - - return estimateGas( - address, - dtContract.methods.createFixedRate, - fixedRateParams.fixedRateAddress, - [ - fixedRateParams.baseTokenAddress, - address, - fixedRateParams.marketFeeCollector, - fixedRateParams.allowedConsumer - ], - [ - fixedRateParams.baseTokenDecimals, - fixedRateParams.datatokenDecimals, - fixedRateParams.fixedRate, - fixedRateParams.marketFee, - withMint - ] - ) - } - /** * Creates a new FixedRateExchange setup. * @param {String} dtAddress Datatoken address @@ -179,11 +88,12 @@ export class Datatoken extends SmartContract { * @param {FixedRateParams} fixedRateParams * @return {Promise} transactionId */ - public async createFixedRate( + public async createFixedRate( dtAddress: string, address: string, - fixedRateParams: FreCreationParams - ): Promise { + fixedRateParams: FreCreationParams, + estimateGas?: G + ): Promise { const dtContract = this.getContract(dtAddress) if (!(await this.isDatatokenDeployer(dtAddress, address))) { throw new Error(`User is not Datatoken Deployer`) @@ -194,7 +104,7 @@ export class Datatoken extends SmartContract { // should check DatatokenDeployer role using NFT level .. - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, dtContract.methods.createFixedRate, fixedRateParams.fixedRateAddress, @@ -212,6 +122,7 @@ export class Datatoken extends SmartContract { withMint ] ) + if (estimateGas) return estGas // Call createFixedRate contract method const trxReceipt = await dtContract.methods @@ -239,39 +150,6 @@ export class Datatoken extends SmartContract { return trxReceipt } - /** - * Estimate gas cost for createDispenser method - * @param {String} dtAddress Datatoken address - * @param {String} address Caller address - * @param {String} dispenserAddress ispenser contract address - * @param {String} dispenserParams - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasCreateDispenser( - dtAddress: string, - address: string, - dispenserAddress: string, - dispenserParams: DispenserParams, - contractInstance?: Contract - ): Promise { - const dtContract = contractInstance || this.getContract(dtAddress) - - if (!dispenserParams.allowedSwapper) dispenserParams.allowedSwapper = ZERO_ADDRESS - - if (!dispenserParams.withMint) dispenserParams.withMint = false - - return estimateGas( - address, - dtContract.methods.createDispenser, - dispenserAddress, - dispenserParams.maxTokens, - dispenserParams.maxBalance, - dispenserParams.withMint, - dispenserParams.allowedSwapper - ) - } - /** * Creates a new Dispenser * @param {String} dtAddress Datatoken address @@ -280,12 +158,13 @@ export class Datatoken extends SmartContract { * @param {String} dispenserParams * @return {Promise} transactionId */ - public async createDispenser( + public async createDispenser( dtAddress: string, address: string, dispenserAddress: string, - dispenserParams: DispenserParams - ): Promise { + dispenserParams: DispenserParams, + estimateGas?: G + ): Promise { if (!(await this.isDatatokenDeployer(dtAddress, address))) { throw new Error(`User is not Datatoken Deployer`) } @@ -298,7 +177,7 @@ export class Datatoken extends SmartContract { // should check DatatokenDeployer role using NFT level .. - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, dtContract.methods.createDispenser, dispenserAddress, @@ -307,6 +186,7 @@ export class Datatoken extends SmartContract { dispenserParams.withMint, dispenserParams.allowedSwapper ) + if (estimateGas) return estGas // Call createFixedRate contract method const trxReceipt = await dtContract.methods @@ -333,12 +213,13 @@ export class Datatoken extends SmartContract { * @param {String} toAddress only if toAddress is different from the minter * @return {Promise} transactionId */ - public async mint( + public async mint( dtAddress: string, address: string, amount: string, - toAddress?: string - ): Promise { + toAddress?: string, + estimateGas?: G + ): Promise { const dtContract = this.getContract(dtAddress) if ((await this.getDTPermissions(dtAddress, address)).minter !== true) { @@ -347,12 +228,13 @@ export class Datatoken extends SmartContract { const capAvailble = await this.getCap(dtAddress) if (new Decimal(capAvailble).gte(amount)) { - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, dtContract.methods.mint, toAddress || address, this.web3.utils.toWei(amount) ) + if (estimateGas) return estGas // Call mint contract method const trxReceipt = await dtContract.methods @@ -368,25 +250,6 @@ export class Datatoken extends SmartContract { } } - /** - * Estimate gas cost for addMinter method - * @param {String} dtAddress Datatoken address - * @param {String} address User address - * @param {String} minter User which is going to be a Minter - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasAddMinter( - dtAddress: string, - address: string, - minter: string, - contractInstance?: Contract - ): Promise { - const dtContract = contractInstance || this.getContract(dtAddress) - - return estimateGas(address, dtContract.methods.addMinter, minter) - } - /** * Add Minter for an ERC20 Datatoken * only DatatokenDeployer can succeed @@ -395,18 +258,24 @@ export class Datatoken extends SmartContract { * @param {String} minter User which is going to be a Minter * @return {Promise} transactionId */ - public async addMinter( + public async addMinter( dtAddress: string, address: string, - minter: string - ): Promise { + minter: string, + estimateGas?: G + ): Promise { const dtContract = this.getContract(dtAddress) if ((await this.isDatatokenDeployer(dtAddress, address)) !== true) { throw new Error(`Caller is not DatatokenDeployer`) } // Estimate gas cost for addMinter method - const estGas = await estimateGas(address, dtContract.methods.addMinter, minter) + const estGas = await calculateEstimatedGas( + address, + dtContract.methods.addMinter, + minter + ) + if (estimateGas) return estGas // Call addMinter function of the contract const trxReceipt = await dtContract.methods.addMinter(minter).send({ @@ -418,27 +287,6 @@ export class Datatoken extends SmartContract { return trxReceipt } - /** - * Estimate gas for removeMinter method - * @param {String} dtAddress Datatoken address - * @param {String} address User address - * @param {String} minter User which will be removed from Minter permission - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasRemoveMinter( - dtAddress: string, - address: string, - minter: string, - contractInstance?: Contract - ): Promise { - const dtContract = contractInstance || this.getContract(dtAddress) - - // should check DatatokenDeployer role using NFT level .. - - return estimateGas(address, dtContract.methods.removeMinter, minter) - } - /** * Revoke Minter permission for an ERC20 Datatoken * only DatatokenDeployer can succeed @@ -448,18 +296,24 @@ export class Datatoken extends SmartContract { * @param {Contract} contractInstance optional contract instance * @return {Promise} */ - public async removeMinter( + public async removeMinter( dtAddress: string, address: string, - minter: string - ): Promise { + minter: string, + estimateGas?: G + ): Promise { const dtContract = this.getContract(dtAddress) if ((await this.isDatatokenDeployer(dtAddress, address)) !== true) { throw new Error(`Caller is not DatatokenDeployer`) } - const estGas = await estimateGas(address, dtContract.methods.removeMinter, minter) + const estGas = await calculateEstimatedGas( + address, + dtContract.methods.removeMinter, + minter + ) + if (estimateGas) return estGas // Call dtContract function of the contract const trxReceipt = await dtContract.methods.removeMinter(minter).send({ @@ -471,25 +325,6 @@ export class Datatoken extends SmartContract { return trxReceipt } - /** - * Estimate gas for addPaymentManager method - * @param {String} dtAddress Datatoken address - * @param {String} address User address - * @param {String} paymentManager User which is going to be a Minter - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasAddPaymentManager( - dtAddress: string, - address: string, - paymentManager: string, - contractInstance?: Contract - ): Promise { - const dtContract = contractInstance || this.getContract(dtAddress) - - return estimateGas(address, dtContract.methods.addPaymentManager, paymentManager) - } - /** * Add addPaymentManager (can set who's going to collect fee when consuming orders) * only DatatokenDeployer can succeed @@ -498,22 +333,24 @@ export class Datatoken extends SmartContract { * @param {String} paymentManager User which is going to be a Minter * @return {Promise} transactionId */ - public async addPaymentManager( + public async addPaymentManager( dtAddress: string, address: string, - paymentManager: string - ): Promise { + paymentManager: string, + estimateGas?: G + ): Promise { const dtContract = this.getContract(dtAddress) if ((await this.isDatatokenDeployer(dtAddress, address)) !== true) { throw new Error(`Caller is not DatatokenDeployer`) } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, dtContract.methods.addPaymentManager, paymentManager ) + if (estimateGas) return estGas // Call addPaymentManager function of the contract const trxReceipt = await dtContract.methods.addPaymentManager(paymentManager).send({ @@ -525,25 +362,6 @@ export class Datatoken extends SmartContract { return trxReceipt } - /** - * Estimate gas for removePaymentManager method - * @param {String} dtAddress Datatoken address - * @param {String} address User address - * @param {String} paymentManager User which will be removed from paymentManager permission - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasRemovePaymentManager( - dtAddress: string, - address: string, - paymentManager: string, - contractInstance?: Contract - ): Promise { - const dtContract = contractInstance || this.getContract(dtAddress) - - return estimateGas(address, dtContract.methods.removePaymentManager, paymentManager) - } - /** * Revoke paymentManager permission for an ERC20 Datatoken * only DatatokenDeployer can succeed @@ -552,22 +370,24 @@ export class Datatoken extends SmartContract { * @param {String} paymentManager User which will be removed from paymentManager permission * @return {Promise} trxReceipt */ - public async removePaymentManager( + public async removePaymentManager( dtAddress: string, address: string, - paymentManager: string - ): Promise { + paymentManager: string, + estimateGas?: G + ): Promise { const dtContract = this.getContract(dtAddress) if ((await this.isDatatokenDeployer(dtAddress, address)) !== true) { throw new Error(`Caller is not DatatokenDeployer`) } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, dtContract.methods.removePaymentManager, paymentManager ) + if (estimateGas) return estGas // Call removeFeeManager function of the contract const trxReceipt = await dtContract.methods @@ -581,25 +401,6 @@ export class Datatoken extends SmartContract { return trxReceipt } - /** - * Estimate gas for setPaymentCollector method - * @param dtAddress datatoken address - * @param address Caller address - * @param paymentCollector User to be set as new payment collector - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasSetPaymentCollector( - dtAddress: string, - address: string, - paymentCollector: string, - contractInstance?: Contract - ): Promise { - const dtContract = contractInstance || this.getContract(dtAddress) - - return estimateGas(address, dtContract.methods.setPaymentCollector, paymentCollector) - } - /** * This function allows to set a new PaymentCollector (receives DT when consuming) * If not set the paymentCollector is the NFT Owner @@ -609,11 +410,12 @@ export class Datatoken extends SmartContract { * @param paymentCollector User to be set as new payment collector * @return {Promise} trxReceipt */ - public async setPaymentCollector( + public async setPaymentCollector( dtAddress: string, address: string, - paymentCollector: string - ): Promise { + paymentCollector: string, + estimateGas?: G + ): Promise { const dtContract = this.getContract(dtAddress) const isPaymentManager = (await this.getDTPermissions(dtAddress, address)) .paymentManager @@ -626,11 +428,12 @@ export class Datatoken extends SmartContract { throw new Error(`Caller is not Fee Manager, owner or Datatoken Deployer`) } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, dtContract.methods.setPaymentCollector, paymentCollector ) + if (estimateGas) return estGas // Call setFeeCollector method of the contract const trxReceipt = await dtContract.methods @@ -672,27 +475,6 @@ export class Datatoken extends SmartContract { return this.transferWei(dtAddress, toAddress, weiAmount, address) } - /** - * Estimate gas for transfer method - * @param {String} dtAddress Datatoken address - * @param {String} toAddress Receiver address - * @param {String} amount Number of datatokens, as number. Expressed as wei - * @param {String} address User adress - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasTransfer( - dtAddress: string, - toAddress: string, - amount: string, - address: string, - contractInstance?: Contract - ): Promise { - const dtContract = contractInstance || this.getContract(dtAddress) - - return estimateGas(address, dtContract.methods.transfer, toAddress, amount) - } - /** * Transfer in wei from address to toAddress * @param {String} dtAddress Datatoken address @@ -701,20 +483,23 @@ export class Datatoken extends SmartContract { * @param {String} address User adress * @return {Promise} transactionId */ - public async transferWei( + public async transferWei( dtAddress: string, toAddress: string, amount: string, - address: string - ): Promise { + address: string, + estimateGas?: G + ): Promise { const dtContract = this.getContract(dtAddress) try { - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, dtContract.methods.transfer, toAddress, amount ) + if (estimateGas) return estGas + // Call transfer function of the contract const trxReceipt = await dtContract.methods.transfer(toAddress, amount).send({ from: address, @@ -728,37 +513,6 @@ export class Datatoken extends SmartContract { } } - /** Estimate gas cost for startOrder method - * @param {String} dtAddress Datatoken address - * @param {String} address User address which calls - * @param {String} consumer Consumer Address - * @param {Number} serviceIndex Service index in the metadata - * @param {providerFees} providerFees provider fees - * @param {consumeMarketFee} ConsumeMarketFee consume market fees - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasStartOrder( - dtAddress: string, - address: string, - consumer: string, - serviceIndex: number, - providerFees: ProviderFees, - consumeMarketFee?: ConsumeMarketFee, - contractInstance?: Contract - ): Promise { - const dtContract = contractInstance || this.getContract(dtAddress) - - return estimateGas( - address, - dtContract.methods.startOrder, - consumer, - serviceIndex, - providerFees, - consumeMarketFee - ) - } - /** Start Order: called by payer or consumer prior ordering a service consume on a marketplace. * @param {String} dtAddress Datatoken address * @param {String} address User address which calls @@ -768,14 +522,15 @@ export class Datatoken extends SmartContract { * @param {consumeMarketFee} ConsumeMarketFee consume market fees * @return {Promise} string */ - public async startOrder( + public async startOrder( dtAddress: string, address: string, consumer: string, serviceIndex: number, providerFees: ProviderFees, - consumeMarketFee?: ConsumeMarketFee - ): Promise { + consumeMarketFee?: ConsumeMarketFee, + estimateGas?: G + ): Promise { const dtContract = this.getContract(dtAddress) if (!consumeMarketFee) { consumeMarketFee = { @@ -785,7 +540,7 @@ export class Datatoken extends SmartContract { } } try { - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, dtContract.methods.startOrder, consumer, @@ -793,6 +548,7 @@ export class Datatoken extends SmartContract { providerFees, consumeMarketFee ) + if (estimateGas) return estGas const trxReceipt = await dtContract.methods .startOrder(consumer, serviceIndex, providerFees, consumeMarketFee) @@ -808,26 +564,6 @@ export class Datatoken extends SmartContract { } } - /** Estimate gas cost for reuseOrder method - * @param {String} dtAddress Datatoken address - * @param {String} address User address which calls - * @param {String} orderTxId previous valid order - * @param {providerFees} providerFees provider fees - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasReuseOrder( - dtAddress: string, - address: string, - orderTxId: string, - providerFees: ProviderFees, - contractInstance?: Contract - ): Promise { - const dtContract = contractInstance || this.getContract(dtAddress) - - return estimateGas(address, dtContract.methods.reuseOrder, orderTxId, providerFees) - } - /** Reuse Order: called by payer or consumer having a valid order, but with expired provider access. * Pays the provider fee again, but it will not require a new datatoken payment * Requires previous approval of provider fee. @@ -837,20 +573,22 @@ export class Datatoken extends SmartContract { * @param {providerFees} providerFees provider fees * @return {Promise} string */ - public async reuseOrder( + public async reuseOrder( dtAddress: string, address: string, orderTxId: string, - providerFees: ProviderFees - ): Promise { + providerFees: ProviderFees, + estimateGas?: G + ): Promise { const dtContract = this.getContract(dtAddress) try { - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, dtContract.methods.reuseOrder, orderTxId, providerFees ) + if (estimateGas) return estGas const trxReceipt = await dtContract.methods .reuseOrder(orderTxId, providerFees) @@ -866,32 +604,6 @@ export class Datatoken extends SmartContract { } } - /** Estimate gas cost for buyFromFreAndOrder method - * @param {String} dtAddress Datatoken address - * @param {String} address User address which calls - * @param {OrderParams} orderParams Consumer Address - * @param {FreParams} freParams Amount of tokens that is going to be transfered - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasBuyFromFreAndOrder( - dtAddress: string, - address: string, - orderParams: OrderParams, - freParams: FreOrderParams, - contractInstance?: Contract - ): Promise { - const dtContract = - contractInstance || this.getContract(dtAddress, null, this.abiEnterprise) - - return estimateGas( - address, - dtContract.methods.buyFromFreAndOrder, - orderParams, - freParams - ) - } - /** Buys 1 DT from the FRE and then startsOrder, while burning that DT * @param {String} dtAddress Datatoken address * @param {String} address User address which calls @@ -899,22 +611,24 @@ export class Datatoken extends SmartContract { * @param {FreParams} freParams Amount of tokens that is going to be transfered * @return {Promise} */ - public async buyFromFreAndOrder( + public async buyFromFreAndOrder( dtAddress: string, address: string, orderParams: OrderParams, - freParams: FreOrderParams - ): Promise { + freParams: FreOrderParams, + estimateGas?: G + ): Promise { const dtContract = this.getContract(dtAddress, null, this.abiEnterprise) try { const freContractParams = this.getFreOrderParams(freParams) - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, dtContract.methods.buyFromFreAndOrder, orderParams, freContractParams ) + if (estimateGas) return estGas const trxReceipt = await dtContract.methods .buyFromFreAndOrder(orderParams, freContractParams) @@ -930,32 +644,6 @@ export class Datatoken extends SmartContract { } } - /** Estimate gas cost for buyFromFreAndOrder method - * @param {String} dtAddress Datatoken address - * @param {String} address User address which calls - * @param {OrderParams} orderParams - * @param {String} dispenserContract - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasBuyFromDispenserAndOrder( - dtAddress: string, - address: string, - orderParams: OrderParams, - dispenserContract: string, - contractInstance?: Contract - ): Promise { - const dtContract = - contractInstance || this.getContract(dtAddress, null, this.abiEnterprise) - - return estimateGas( - address, - dtContract.methods.buyFromDispenserAndOrder, - orderParams, - dispenserContract - ) - } - /** Gets DT from dispenser and then startsOrder, while burning that DT * @param {String} dtAddress Datatoken address * @param {String} address User address which calls @@ -963,20 +651,22 @@ export class Datatoken extends SmartContract { * @param {String} dispenserContract * @return {Promise} */ - public async buyFromDispenserAndOrder( + public async buyFromDispenserAndOrder( dtAddress: string, address: string, orderParams: OrderParams, - dispenserContract: string - ): Promise { + dispenserContract: string, + estimateGas?: G + ): Promise { const dtContract = this.getContract(dtAddress, null, this.abiEnterprise) try { - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, dtContract.methods.buyFromDispenserAndOrder, orderParams, dispenserContract ) + if (estimateGas) return estGas const trxReceipt = await dtContract.methods .buyFromDispenserAndOrder(orderParams, dispenserContract) @@ -992,24 +682,6 @@ export class Datatoken extends SmartContract { } } - /** Estimate gas for setData method - * @param {String} dtAddress Datatoken address - * @param {String} address User address - * @param {String} value Data to be stored into 725Y standard - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasSetData( - dtAddress: string, - address: string, - value: string, - contractInstance?: Contract - ): Promise { - const dtContract = contractInstance || this.getContract(dtAddress) - - return estimateGas(address, dtContract.methods.setData, value) - } - /** setData * This function allows to store data with a preset key (keccak256(dtAddress)) into NFT 725 Store * only DatatokenDeployer can succeed @@ -1018,18 +690,20 @@ export class Datatoken extends SmartContract { * @param {String} value Data to be stored into 725Y standard * @return {Promise} transactionId */ - public async setData( + public async setData( dtAddress: string, address: string, - value: string - ): Promise { + value: string, + estimateGas?: G + ): Promise { if (!(await this.isDatatokenDeployer(dtAddress, address))) { throw new Error(`User is not Datatoken Deployer`) } const dtContract = this.getContract(dtAddress) - const estGas = await estimateGas(address, dtContract.methods.setData, value) + const estGas = await calculateEstimatedGas(address, dtContract.methods.setData, value) + if (estimateGas) return estGas // Call setData function of the contract const trxReceipt = await dtContract.methods.setData(value).send({ @@ -1041,22 +715,6 @@ export class Datatoken extends SmartContract { return trxReceipt } - /** Estimate gas for cleanPermissions method - * @param dtAddress Datatoken address where we want to clean permissions - * @param address User adress - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ - public async estGasCleanPermissions( - dtAddress: string, - address: string, - contractInstance?: Contract - ): Promise { - const dtContract = contractInstance || this.getContract(dtAddress) - - return estimateGas(address, dtContract.methods.cleanPermissions) - } - /** * Clean Datatoken level Permissions (minters, paymentManager and reset the paymentCollector) for an ERC20 Datatoken * Only NFT Owner (at 721 level) can call it. @@ -1064,16 +722,21 @@ export class Datatoken extends SmartContract { * @param address User adress * @return {Promise} transactionId */ - public async cleanPermissions( + public async cleanPermissions( dtAddress: string, - address: string - ): Promise { + address: string, + estimateGas?: G + ): Promise { if ((await this.nft.getNftOwner(await this.getNFTAddress(dtAddress))) !== address) { throw new Error('Caller is NOT Nft Owner') } const dtContract = this.getContract(dtAddress) - const estGas = await estimateGas(address, dtContract.methods.cleanPermissions) + const estGas = await calculateEstimatedGas( + address, + dtContract.methods.cleanPermissions + ) + if (estimateGas) return estGas // Call cleanPermissions function of the contract const trxReceipt = await dtContract.methods.cleanPermissions().send({ @@ -1152,33 +815,6 @@ export class Datatoken extends SmartContract { return this.web3.utils.fromWei(balance) } - /** - * @dev estGasSetPublishingMarketFee - * Estimating gas for publishMarketFeeAddress method - * @param {string} datatokenAddress Datatoken adress - * @param {string} publishMarketFeeAddress new publish Market Fee Address - * @param {string} publishMarketFeeToken new publish Market Fee Token - * @param {string} publishMarketFeeAmount new fee amount - * @param {String} address user adress - */ - public async estGasSetPublishingMarketFee( - datatokenAddress: string, - publishMarketFeeAddress: string, - publishMarketFeeToken: string, - publishMarketFeeAmount: string, - address: string - ): Promise { - // Estimate gas cost for publishMarketFeeAddress method - const dtContract = this.getContract(datatokenAddress, address) - return estimateGas( - address, - dtContract.methods.setPublishingMarketFee, - publishMarketFeeAddress, - publishMarketFeeToken, - publishMarketFeeAmount - ) - } - /** * @dev setPublishingMarketFee * Only publishMarketFeeAddress can call it @@ -1189,26 +825,29 @@ export class Datatoken extends SmartContract { * @param {string} publishMarketFeeAmount new fee amount * @param {String} address user adress */ - public async setPublishingMarketFee( + public async setPublishingMarketFee( datatokenAddress: string, publishMarketFeeAddress: string, publishMarketFeeToken: string, publishMarketFeeAmount: string, - address: string - ) { + address: string, + estimateGas?: G + ): Promise { const dtContract = this.getContract(datatokenAddress, address) const mktFeeAddress = (await dtContract.methods.getPublishingMarketFee().call())[0] if (mktFeeAddress !== address) { throw new Error(`Caller is not the Publishing Market Fee Address`) } - const estGas = await this.estGasSetPublishingMarketFee( - datatokenAddress, + const estGas = await calculateEstimatedGas( + address, + dtContract.methods.setPublishingMarketFee, publishMarketFeeAddress, publishMarketFeeToken, - publishMarketFeeAmount, - address + publishMarketFeeAmount ) - await dtContract.methods + if (estimateGas) return estGas + + const trxReceipt = await dtContract.methods .setPublishingMarketFee( publishMarketFeeAddress, publishMarketFeeToken, @@ -1219,6 +858,8 @@ export class Datatoken extends SmartContract { gas: estGas + 1, gasPrice: await this.getFairGasPrice() }) + + return trxReceipt } /** diff --git a/src/contracts/tokens/NFT.ts b/src/contracts/tokens/NFT.ts index b0fa44ee..18a5a836 100644 --- a/src/contracts/tokens/NFT.ts +++ b/src/contracts/tokens/NFT.ts @@ -1,8 +1,7 @@ import { AbiItem } from 'web3-utils' import { TransactionReceipt } from 'web3-eth' import ERC721Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC721Template.sol/ERC721Template.json' -import { LoggerInstance, generateDtName, estimateGas } from '../../utils' -import { Contract } from 'web3-eth-contract' +import { LoggerInstance, generateDtName, calculateEstimatedGas } from '../../utils' import { MetadataProof, MetadataAndTokenURI, NftRoles } from '../../@types' import { SmartContract } from '..' @@ -11,48 +10,6 @@ export class Nft extends SmartContract { return ERC721Template.abi as AbiItem[] } - /** - * Estimate gas cost for createDatatoken token creation - * @param {String} nftAddress NFT address - * @param {String} address User address - * @param {String} minter User set as initial minter for the Datatoken - * @param {String} paymentCollector initial paymentCollector for this DT - * @param {String} mpFeeAddress Consume marketplace fee address - * @param {String} feeToken address of the token marketplace wants to add fee on top - * @param {String} feeAmount amount of feeToken to be transferred to mpFeeAddress on top, will be converted to WEI - * @param {String} cap Maximum cap (Number) - will be converted to wei - * @param {String} name Token name - * @param {String} symbol Token symbol - * @param {Number} templateIndex NFT template index - * @param {Contract} nftContract optional contract instance - * @return {Promise} - */ - public async estGasGasCreateDatatoken( - nftAddress: string, - address: string, - minter: string, - paymentCollector: string, - mpFeeAddress: string, - feeToken: string, - feeAmount: string, - cap: string, - name?: string, - symbol?: string, - templateIndex?: number, - contractInstance?: Contract - ): Promise { - const nftContract = contractInstance || this.getContract(nftAddress) - return estimateGas( - address, - nftContract.methods.createERC20, - templateIndex, - [name, symbol], - [minter, paymentCollector, mpFeeAddress, feeToken], - [this.web3.utils.toWei(cap), this.web3.utils.toWei(feeAmount)], - [] - ) - } - /** * Create new ERC20 Datatoken - only user with DatatokenDeployer permission can succeed * @param {String} nftAddress NFT address @@ -68,7 +25,7 @@ export class Nft extends SmartContract { * @param {Number} templateIndex NFT template index * @return {Promise} ERC20 Datatoken address */ - public async createDatatoken( + public async createDatatoken( nftAddress: string, address: string, minter: string, @@ -79,8 +36,9 @@ export class Nft extends SmartContract { cap: string, name?: string, symbol?: string, - templateIndex?: number - ): Promise { + templateIndex?: number, + estimateGas?: G + ): Promise { if ((await this.getNftPermissions(nftAddress, address)).deployERC20 !== true) { throw new Error(`Caller is not DatatokenDeployer`) } @@ -94,7 +52,7 @@ export class Nft extends SmartContract { // Create 721contract object const nftContract = this.getContract(nftAddress) - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, nftContract.methods.createERC20, templateIndex, @@ -103,6 +61,7 @@ export class Nft extends SmartContract { [this.web3.utils.toWei(cap), this.web3.utils.toWei(feeAmount)], [] ) + if (estimateGas) return estGas // Call createERC20 token function of the contract const trxReceipt = await nftContract.methods @@ -128,25 +87,6 @@ export class Nft extends SmartContract { return tokenAddress } - /** - * Estimate gas cost for add manager call - * @param {String} nftAddress NFT contract address - * @param {String} address NFT Owner adress - * @param {String} manager User adress which is going to be assing manager - * @param {Contract} nftContract optional contract instance - * @return {Promise} - */ - public async estGasGasAddManager( - nftAddress: string, - address: string, - manager: string, - contractInstance?: Contract - ) { - const nftContract = contractInstance || this.getContract(nftAddress) - - return estimateGas(address, nftContract.methods.addManager, manager) - } - /** * Add Manager for NFT Contract (only NFT Owner can succeed) * @param {String} nftAddress NFT contract address @@ -154,14 +94,24 @@ export class Nft extends SmartContract { * @param {String} manager User adress which is going to be assing manager * @return {Promise} trxReceipt */ - public async addManager(nftAddress: string, address: string, manager: string) { + public async addManager( + nftAddress: string, + address: string, + manager: string, + estimateGas?: G + ): Promise { const nftContract = this.getContract(nftAddress) if ((await this.getNftOwner(nftAddress)) !== address) { throw new Error(`Caller is not NFT Owner`) } - const estGas = await estimateGas(address, nftContract.methods.addManager, manager) + const estGas = await calculateEstimatedGas( + address, + nftContract.methods.addManager, + manager + ) + if (estimateGas) return estGas // Invoke addManager function of the contract const trxReceipt = await nftContract.methods.addManager(manager).send({ @@ -173,24 +123,6 @@ export class Nft extends SmartContract { return trxReceipt } - /** - * Estimate gas cost for removeManager method - * @param {String} nftAddress NFT contract address - * @param {String} address NFT Owner adress - * @param {String} manager User adress which is going to be removed as manager - * @param {Contract} nftContract optional contract instance - * @return {Promise} - */ - public async estGasGasRemoveManager( - nftAddress: string, - address: string, - manager: string, - contractInstance?: Contract - ) { - const nftContract = contractInstance || this.getContract(nftAddress) - return estimateGas(address, nftContract.methods.removeManager, manager) - } - /** * Removes a specific manager for NFT Contract (only NFT Owner can succeed) * @param {String} nftAddress NFT contract address @@ -198,14 +130,24 @@ export class Nft extends SmartContract { * @param {String} manager User adress which is going to be removed as manager * @return {Promise} trxReceipt */ - public async removeManager(nftAddress: string, address: string, manager: string) { + public async removeManager( + nftAddress: string, + address: string, + manager: string, + estimateGas?: G + ): Promise { const nftContract = this.getContract(nftAddress) if ((await this.getNftOwner(nftAddress)) !== address) { throw new Error(`Caller is not NFT Owner`) } - const estGas = await estimateGas(address, nftContract.methods.removeManager, manager) + const estGas = await calculateEstimatedGas( + address, + nftContract.methods.removeManager, + manager + ) + if (estimateGas) return estGas // Invoke removeManager function of the contract const trxReceipt = await nftContract.methods.removeManager(manager).send({ @@ -217,28 +159,6 @@ export class Nft extends SmartContract { return trxReceipt } - /** - * Estimate gas cost for addToCreateERC20List method - * @param {String} nftAddress NFT contract address - * @param {String} address NFT Manager adress - * @param {String} datatokenDeployer User adress which is going to have DatatokenDeployer permission - * @param {Contract} nftContract optional contract instance - * @return {Promise} - */ - public async estGasGasAddDatatokenDeployer( - nftAddress: string, - address: string, - datatokenDeployer: string, - contractInstance?: Contract - ): Promise { - const nftContract = contractInstance || this.getContract(nftAddress) - return estimateGas( - address, - nftContract.methods.addToCreateERC20List, - datatokenDeployer - ) - } - /** * Add DatatokenDeployer permission - only Manager can succeed * @param {String} nftAddress NFT contract address @@ -246,11 +166,12 @@ export class Nft extends SmartContract { * @param {String} datatokenDeployer User adress which is going to have DatatokenDeployer permission * @return {Promise} trxReceipt */ - public async addDatatokenDeployer( + public async addDatatokenDeployer( nftAddress: string, address: string, - datatokenDeployer: string - ): Promise { + datatokenDeployer: string, + estimateGas?: G + ): Promise { const nftContract = this.getContract(nftAddress) if ((await this.getNftPermissions(nftAddress, address)).manager !== true) { @@ -258,11 +179,12 @@ export class Nft extends SmartContract { } // Estimate gas for addToCreateERC20List method - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, nftContract.methods.addToCreateERC20List, datatokenDeployer ) + if (estimateGas) return estGas // Invoke addToCreateERC20List function of the contract const trxReceipt = await nftContract.methods @@ -276,29 +198,6 @@ export class Nft extends SmartContract { return trxReceipt } - /** - * Estimate gas cost for removeFromCreateERC20List method - * @param {String} nftAddress NFT contract address - * @param {String} address NFT Manager adress - * @param {String} datatokenDeployer Address of the user to be revoked DatatokenDeployer Permission - * @param {Contract} nftContract optional contract instance - * @return {Promise} - */ - public async estGasGasRemoveDatatokenDeployer( - nftAddress: string, - address: string, - datatokenDeployer: string, - contractInstance?: Contract - ): Promise { - const nftContract = contractInstance || this.getContract(nftAddress) - - return estimateGas( - address, - nftContract.methods.removeFromCreateERC20List, - datatokenDeployer - ) - } - /** * Remove DatatokenDeployer permission - only Manager can succeed * @param {String} nftAddress NFT contract address @@ -306,11 +205,12 @@ export class Nft extends SmartContract { * @param {String} datatokenDeployer Address of the user to be revoked DatatokenDeployer Permission * @return {Promise} trxReceipt */ - public async removeDatatokenDeployer( + public async removeDatatokenDeployer( nftAddress: string, address: string, - datatokenDeployer: string - ): Promise { + datatokenDeployer: string, + estimateGas?: G + ): Promise { const nftContract = this.getContract(nftAddress) if ( @@ -320,11 +220,12 @@ export class Nft extends SmartContract { ) { throw new Error(`Caller is not Manager nor DatatokenDeployer`) } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, nftContract.methods.removeFromCreateERC20List, datatokenDeployer ) + if (estimateGas) return estGas // Call removeFromCreateERC20List function of the contract const trxReceipt = await nftContract.methods @@ -338,25 +239,6 @@ export class Nft extends SmartContract { return trxReceipt } - /** - * Estimate gas cost for addToMetadataList method - * @param {String} nftAddress NFT contract address - * @param {String} address NFT Manager adress - * @param {String} metadataUpdater User adress which is going to have Metadata Updater permission - * @param {Contract} nftContract optional contract instance - * @return {Promise} - */ - public async estGasGasAddMetadataUpdater( - nftAddress: string, - address: string, - metadataUpdater: string, - contractInstance?: Contract - ): Promise { - const nftContract = contractInstance || this.getContract(nftAddress) - - return estimateGas(address, nftContract.methods.addToMetadataList, metadataUpdater) - } - /** * Add Metadata Updater permission - only Manager can succeed * @param {String} nftAddress NFT contract address @@ -364,22 +246,24 @@ export class Nft extends SmartContract { * @param {String} metadataUpdater User adress which is going to have Metadata Updater permission * @return {Promise} trxReceipt */ - public async addMetadataUpdater( + public async addMetadataUpdater( nftAddress: string, address: string, - metadataUpdater: string - ): Promise { + metadataUpdater: string, + estimateGas?: G + ): Promise { const nftContract = this.getContract(nftAddress) if ((await this.getNftPermissions(nftAddress, address)).manager !== true) { throw new Error(`Caller is not Manager`) } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, nftContract.methods.addToMetadataList, metadataUpdater ) + if (estimateGas) return estGas // Call addToMetadataList function of the contract const trxReceipt = await nftContract.methods.addToMetadataList(metadataUpdater).send({ @@ -391,29 +275,6 @@ export class Nft extends SmartContract { return trxReceipt } - /** - * Estimate gas cost for removeFromMetadataList method - * @param {String} nftAddress NFT contract address - * @param {String} address NFT Manager adress - * @param {String} metadataUpdater Address of the user to be revoked Metadata updater Permission - * @param {Contract} nftContract optional contract instance - * @return {Promise} - */ - public async esGasRemoveMetadataUpdater( - nftAddress: string, - address: string, - metadataUpdater: string, - contractInstance?: Contract - ): Promise { - const nftContract = contractInstance || this.getContract(nftAddress) - - return estimateGas( - address, - nftContract.methods.removeFromMetadataList, - metadataUpdater - ) - } - /** * Remove Metadata Updater permission - only Manager can succeed * @param {String} nftAddress NFT contract address @@ -421,11 +282,12 @@ export class Nft extends SmartContract { * @param {String} metadataUpdater Address of the user to be revoked Metadata updater Permission * @return {Promise} trxReceipt */ - public async removeMetadataUpdater( + public async removeMetadataUpdater( nftAddress: string, address: string, - metadataUpdater: string - ): Promise { + metadataUpdater: string, + estimateGas?: G + ): Promise { const nftContract = this.getContract(nftAddress) if ( @@ -436,12 +298,12 @@ export class Nft extends SmartContract { throw new Error(`Caller is not Manager nor Metadata Updater`) } - const estGas = await this.esGasRemoveMetadataUpdater( - nftAddress, + const estGas = await calculateEstimatedGas( address, - metadataUpdater, - nftContract + nftContract.methods.removeFromMetadataList, + metadataUpdater ) + if (estimateGas) return estGas // Call removeFromMetadataList function of the contract const trxReceipt = await nftContract.methods @@ -455,25 +317,6 @@ export class Nft extends SmartContract { return trxReceipt } - /** - * Estimate gas cost for addTo725StoreList method - * @param {String} nftAddress NFT contract address - * @param {String} address NFT Manager adress - * @param {String} storeUpdater User adress which is going to have Store Updater permission - * @param {Contract} nftContract optional contract instance - * @return {Promise} - */ - public async estGasGasAddStoreUpdater( - nftAddress: string, - address: string, - storeUpdater: string, - contractInstance?: Contract - ): Promise { - const nftContract = contractInstance || this.getContract(nftAddress) - - return estimateGas(address, nftContract.methods.addTo725StoreList, storeUpdater) - } - /** * Add Store Updater permission - only Manager can succeed * @param {String} nftAddress NFT contract address @@ -481,22 +324,24 @@ export class Nft extends SmartContract { * @param {String} storeUpdater User adress which is going to have Store Updater permission * @return {Promise} trxReceipt */ - public async addStoreUpdater( + public async addStoreUpdater( nftAddress: string, address: string, - storeUpdater: string - ): Promise { + storeUpdater: string, + estimateGas?: G + ): Promise { const nftContract = this.getContract(nftAddress) if ((await this.getNftPermissions(nftAddress, address)).manager !== true) { throw new Error(`Caller is not Manager`) } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, nftContract.methods.addTo725StoreList, storeUpdater ) + if (estimateGas) return estGas // Call addTo725StoreList function of the contract const trxReceipt = await nftContract.methods.addTo725StoreList(storeUpdater).send({ @@ -508,25 +353,6 @@ export class Nft extends SmartContract { return trxReceipt } - /** - * Estimate gas cost for removeFrom725StoreList method - * @param {String} nftAddress NFT contract address - * @param {String} address NFT Manager adress - * @param {String} storeUpdater Address of the user to be revoked Store Updater Permission - * @param {Contract} nftContract optional contract instance - * @return {Promise} - */ - public async estGasGasRemoveStoreUpdater( - nftAddress: string, - address: string, - storeUpdater: string, - contractInstance?: Contract - ): Promise { - const nftContract = contractInstance || this.getContract(nftAddress) - - return estimateGas(address, nftContract.methods.removeFrom725StoreList, storeUpdater) - } - /** * Remove Store Updater permission - only Manager can succeed * @param {String} nftAddress NFT contract address @@ -534,11 +360,12 @@ export class Nft extends SmartContract { * @param {String} storeUpdater Address of the user to be revoked Store Updater Permission * @return {Promise} trxReceipt */ - public async removeStoreUpdater( + public async removeStoreUpdater( nftAddress: string, address: string, - storeUpdater: string - ): Promise { + storeUpdater: string, + estimateGas?: G + ): Promise { const nftContract = this.getContract(nftAddress) if ( @@ -549,11 +376,12 @@ export class Nft extends SmartContract { throw new Error(`Caller is not Manager nor storeUpdater`) } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, nftContract.methods.removeFrom725StoreList, storeUpdater ) + if (estimateGas) return estGas // Call removeFrom725StoreList function of the contract const trxReceipt = await nftContract.methods @@ -567,23 +395,6 @@ export class Nft extends SmartContract { return trxReceipt } - /** - * Estimate gas cost for cleanPermissions method - * @param {String} nftAddress NFT contract address - * @param {String} address NFT Owner adress - * @param {Contract} nftContract optional contract instance - * @return {Promise} - */ - public async estGasGasCleanPermissions( - nftAddress: string, - address: string, - contractInstance?: Contract - ): Promise { - const nftContract = contractInstance || this.getContract(nftAddress) - - return estimateGas(address, nftContract.methods.cleanPermissions) - } - /** * This function allows to remove all ROLES at NFT level: Managers, DatatokenDeployer, MetadataUpdater, StoreUpdater * Even NFT Owner has to readd himself as Manager @@ -594,17 +405,22 @@ export class Nft extends SmartContract { * @return {Promise} trxReceipt */ - public async cleanPermissions( + public async cleanPermissions( nftAddress: string, - address: string - ): Promise { + address: string, + estimateGas?: G + ): Promise { const nftContract = this.getContract(nftAddress) if ((await this.getNftOwner(nftAddress)) !== address) { throw new Error(`Caller is not NFT Owner`) } - const estGas = await estimateGas(address, nftContract.methods.cleanPermissions) + const estGas = await calculateEstimatedGas( + address, + nftContract.methods.cleanPermissions + ) + if (estimateGas) return estGas // Call cleanPermissions function of the contract const trxReceipt = await nftContract.methods.cleanPermissions().send({ @@ -616,33 +432,6 @@ export class Nft extends SmartContract { return trxReceipt } - /** - * Estimate gas cost for transfer NFT method - * @param {String} nftAddress NFT contract address - * @param {String} nftOwner Current NFT Owner adress - * @param {String} nftReceiver User which will receive the NFT, will also be set as Manager - * @param {Number} tokenId The id of the token to be transfered - * @param {Contract} nftContract optional contract instance - * @return {Promise} - */ - public async estGasGasTransferNft( - nftAddress: string, - nftOwner: string, - nftReceiver: string, - tokenId: number, - contractInstance?: Contract - ): Promise { - const nftContract = contractInstance || this.getContract(nftAddress) - - return estimateGas( - nftOwner, - nftContract.methods.transferFrom, - nftOwner, - nftReceiver, - tokenId - ) - } - /** * Transfers the NFT * will clean all permissions both on NFT and Datatoken level. @@ -652,12 +441,13 @@ export class Nft extends SmartContract { * @param {Number} tokenId The id of the token to be transfered * @return {Promise} trxReceipt */ - public async transferNft( + public async transferNft( nftAddress: string, nftOwner: string, nftReceiver: string, - tokenId?: number - ): Promise { + tokenId?: number, + estimateGas?: G + ): Promise { const nftContract = this.getContract(nftAddress) if ((await this.getNftOwner(nftAddress)) !== nftOwner) { @@ -666,13 +456,14 @@ export class Nft extends SmartContract { const tokenIdentifier = tokenId || 1 - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( nftOwner, nftContract.methods.transferFrom, nftOwner, nftReceiver, tokenIdentifier ) + if (estimateGas) return estGas // Call transferFrom function of the contract const trxReceipt = await nftContract.methods @@ -686,33 +477,6 @@ export class Nft extends SmartContract { return trxReceipt } - /** - * Estimate gas cost for safeTransfer NFT method - * @param {String} nftAddress NFT contract address - * @param {String} nftOwner Current NFT Owner adress - * @param {String} nftReceiver User which will receive the NFT, will also be set as Manager - * @param {Number} tokenId The id of the token to be transfered - * @param {Contract} nftContract optional contract instance - * @return {Promise} - */ - public async estGasGasSafeTransferNft( - nftAddress: string, - nftOwner: string, - nftReceiver: string, - tokenId: number, - contractInstance?: Contract - ): Promise { - const nftContract = contractInstance || this.getContract(nftAddress) - - return estimateGas( - nftOwner, - nftContract.methods.safeTransferFrom, - nftOwner, - nftReceiver, - tokenId - ) - } - /** * safeTransferNFT Used for transferring the NFT, can be used by an approved relayer * will clean all permissions both on NFT and Datatoken level. @@ -722,12 +486,13 @@ export class Nft extends SmartContract { * @param {Number} tokenId The id of the token to be transfered * @return {Promise} trxReceipt */ - public async safeTransferNft( + public async safeTransferNft( nftAddress: string, nftOwner: string, nftReceiver: string, - tokenId?: number - ): Promise { + tokenId?: number, + estimateGas?: G + ): Promise { const nftContract = this.getContract(nftAddress) if ((await this.getNftOwner(nftAddress)) !== nftOwner) { @@ -736,13 +501,14 @@ export class Nft extends SmartContract { const tokenIdentifier = tokenId || 1 - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( nftOwner, nftContract.methods.safeTransferFrom, nftOwner, nftReceiver, tokenIdentifier ) + if (estimateGas) return estGas // Call transferFrom function of the contract const trxReceipt = await nftContract.methods @@ -756,44 +522,6 @@ export class Nft extends SmartContract { return trxReceipt } - // TODO: Finish this description - /** - * Estimate gas cost for setMetadata method - * @param {String} nftAddress NFT contract address - * @param {String} metadataUpdater metadataUpdater address - * @param {Number} metadataState User which will receive the NFT, will also be set as Manager - * @param {String} metadataDecryptorUrl - * @param {Number} tokenId The id of the token to be transfered - * @param {Contract} nftContract optional contract instance - * @return {Promise} - */ - public async estGasGasSetMetadata( - nftAddress: string, - metadataUpdater: string, - metadataState: number, - metadataDecryptorUrl: string, - metadataDecryptorAddress: string, - flags: string, - data: string, - metadataHash: string, - metadataProofs?: MetadataProof[], - contractInstance?: Contract - ): Promise { - const nftContract = contractInstance || this.getContract(nftAddress) - if (!metadataProofs) metadataProofs = [] - return estimateGas( - metadataUpdater, - nftContract.methods.setMetaData, - metadataState, - metadataDecryptorUrl, - metadataDecryptorAddress, - flags, - data, - metadataHash, - metadataProofs - ) - } - /** * safeTransferNFT Used for transferring the NFT, can be used by an approved relayer * will clean all permissions both on NFT and Datatoken level. @@ -801,7 +529,7 @@ export class Nft extends SmartContract { * @param {String} address Caller address NFT Owner adress * @return {Promise} trxReceipt */ - public async setMetadata( + public async setMetadata( nftAddress: string, address: string, metadataState: number, @@ -810,14 +538,15 @@ export class Nft extends SmartContract { flags: string, data: string, metadataHash: string, - metadataProofs?: MetadataProof[] - ): Promise { + metadataProofs?: MetadataProof[], + estimateGas?: G + ): Promise { const nftContract = this.getContract(nftAddress) if (!metadataProofs) metadataProofs = [] if (!(await this.getNftPermissions(nftAddress, address)).updateMetadata) { throw new Error(`Caller is not Metadata updater`) } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, nftContract.methods.setMetaData, metadataState, @@ -828,6 +557,8 @@ export class Nft extends SmartContract { metadataHash, metadataProofs ) + if (estimateGas) return estGas + const trxReceipt = await nftContract.methods .setMetaData( metadataState, @@ -847,32 +578,6 @@ export class Nft extends SmartContract { return trxReceipt } - /** - * Estimate gas cost for setMetadata method - * @param {String} nftAddress NFT contract address - * @param {String} metadataUpdater metadataUpdater address - * @param {MetaDataAndTokenURI} metadataAndTokenURI metaDataAndTokenURI object - * @param {Contract} nftContract optional contract instance - * @return {Promise} - */ - public async estGasGasSetMetadataAndTokenURI( - nftAddress: string, - metadataUpdater: string, - metadataAndTokenURI: MetadataAndTokenURI, - contractInstance?: Contract - ): Promise { - const nftContract = contractInstance || this.getContract(nftAddress) - const sanitizedMetadataAndTokenURI = { - ...metadataAndTokenURI, - metadataProofs: metadataAndTokenURI.metadataProofs || [] - } - return estimateGas( - metadataUpdater, - nftContract.methods.setMetaDataAndTokenURI, - sanitizedMetadataAndTokenURI - ) - } - /** * Helper function to improve UX sets both MetaData & TokenURI in one tx * @param {String} nftAddress NFT contract address @@ -880,11 +585,12 @@ export class Nft extends SmartContract { * @param {MetadataAndTokenURI} metadataAndTokenURI metaDataAndTokenURI object * @return {Promise} trxReceipt */ - public async setMetadataAndTokenURI( + public async setMetadataAndTokenURI( nftAddress: string, metadataUpdater: string, - metadataAndTokenURI: MetadataAndTokenURI - ): Promise { + metadataAndTokenURI: MetadataAndTokenURI, + estimateGas?: G + ): Promise { const nftContract = this.getContract(nftAddress) if (!(await this.getNftPermissions(nftAddress, metadataUpdater)).updateMetadata) { throw new Error(`Caller is not Metadata updater`) @@ -893,11 +599,13 @@ export class Nft extends SmartContract { ...metadataAndTokenURI, metadataProofs: metadataAndTokenURI.metadataProofs || [] } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( metadataUpdater, nftContract.methods.setMetaDataAndTokenURI, sanitizedMetadataAndTokenURI ) + if (estimateGas) return estGas + const trxReceipt = await nftContract.methods .setMetaDataAndTokenURI(sanitizedMetadataAndTokenURI) .send({ @@ -909,29 +617,6 @@ export class Nft extends SmartContract { return trxReceipt } - /** - * Estimate gas cost for setMetadataState method - * @param {String} nftAddress NFT contract address - * @param {String} nftOwner Current NFT Owner adress - * @param {Number} metadataState new metadata state - * @param {Contract} nftContract optional contract instance - * @return {Promise} - */ - public async estGasGasSetMetadataState( - nftAddress: string, - metadataUpdater: string, - metadataState: number, - contractInstance?: Contract - ): Promise { - const nftContract = contractInstance || this.getContract(nftAddress) - - return estimateGas( - metadataUpdater, - nftContract.methods.setMetaDataState, - metadataState - ) - } - /** * setMetadataState Used for updating the metadata State * @param {String} nftAddress NFT contract address @@ -939,22 +624,24 @@ export class Nft extends SmartContract { * @param {Number} metadataState new metadata state * @return {Promise} trxReceipt */ - public async setMetadataState( + public async setMetadataState( nftAddress: string, address: string, - metadataState: number - ): Promise { + metadataState: number, + estimateGas?: G + ): Promise { const nftContract = this.getContract(nftAddress) if (!(await this.getNftPermissions(nftAddress, address)).updateMetadata) { throw new Error(`Caller is not Metadata updater`) } - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( address, nftContract.methods.setMetaDataState, metadataState ) + if (estimateGas) return estGas // Call transferFrom function of the contract const trxReceipt = await nftContract.methods.setMetaDataState(metadataState).send({ @@ -966,36 +653,28 @@ export class Nft extends SmartContract { return trxReceipt } - /** Estimate gas cost for setTokenURI method - * @param nftAddress NFT contract address - * @param address user adress - * @param data input data for TokenURI - * @return {Promise} transaction receipt - */ - public async estGasSetTokenURI( - nftAddress: string, - address: string, - data: string - ): Promise { - const nftContract = this.getContract(nftAddress) - - return estimateGas(address, nftContract.methods.setTokenURI, '1', data) - } - /** set TokenURI on an nft * @param nftAddress NFT contract address * @param address user adress * @param data input data for TokenURI * @return {Promise} transaction receipt */ - public async setTokenURI( + public async setTokenURI( nftAddress: string, address: string, - data: string - ): Promise { + data: string, + estimateGas?: G + ): Promise { const nftContract = this.getContract(nftAddress) - const estGas = await estimateGas(address, nftContract.methods.setTokenURI, '1', data) + const estGas = await calculateEstimatedGas( + address, + nftContract.methods.setTokenURI, + '1', + data + ) + if (estimateGas) return estGas + const trxReceipt = await nftContract.methods.setTokenURI('1', data).send({ from: address, gas: estGas + 1, diff --git a/src/utils/ContractUtils.ts b/src/utils/ContractUtils.ts index 77fd387b..42b0521e 100644 --- a/src/utils/ContractUtils.ts +++ b/src/utils/ContractUtils.ts @@ -81,7 +81,7 @@ export async function amountToUnits( * @param {...any[]} args arguments of the function * @return {Promise} gas cost of the function */ -export async function estimateGas( +export async function calculateEstimatedGas( from: string, functionToEstimateGas: Function, ...args: any[] diff --git a/src/utils/TokenUtils.ts b/src/utils/TokenUtils.ts index 344d11f3..c034e714 100644 --- a/src/utils/TokenUtils.ts +++ b/src/utils/TokenUtils.ts @@ -1,39 +1,15 @@ import Decimal from 'decimal.js' -import { Contract } from 'web3-eth-contract' import { TransactionReceipt } from 'web3-core' import Web3 from 'web3' import { amountToUnits, - estimateGas, + calculateEstimatedGas, getFairGasPrice, unitsToAmount, minAbi, LoggerInstance } from '.' -/** - * Estimate gas cost for approval function - * @param {String} account - * @param {String} tokenAddress - * @param {String} spender - * @param {String} amount - * @param {String} force - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ -export async function estApprove( - web3: Web3, - account: string, - tokenAddress: string, - spender: string, - amount: string, - contractInstance?: Contract -): Promise { - const tokenContract = contractInstance || new web3.eth.Contract(minAbi, tokenAddress) - - return estimateGas(account, tokenContract.methods.approve, spender, amount) -} - /** * Approve spender to spent amount tokens * @param {String} account @@ -43,30 +19,32 @@ export async function estApprove( * @param {boolean} force if true, will overwrite any previous allowence. Else, will check if allowence is enough and will not send a transaction if it's not needed * @param {number} tokenDecimals optional number of decimals of the token */ -export async function approve( +export async function approve( web3: Web3, account: string, tokenAddress: string, spender: string, amount: string, force = false, - tokenDecimals?: number -): Promise { + tokenDecimals?: number, + estimateGas?: G +): Promise { const tokenContract = new web3.eth.Contract(minAbi, tokenAddress) if (!force) { const currentAllowence = await allowance(web3, tokenAddress, account, spender) if (new Decimal(currentAllowence).greaterThanOrEqualTo(new Decimal(amount))) { - return currentAllowence + return null } } let result = null const amountFormatted = await amountToUnits(web3, tokenAddress, amount, tokenDecimals) - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( account, tokenContract.methods.approve, spender, amountFormatted ) + if (estimateGas) return estGas try { result = await tokenContract.methods.approve(spender, amountFormatted).send({ @@ -82,29 +60,6 @@ export async function approve( return result } -/** - * Estimate gas cost for transfer function - * @param {String} account - * @param {String} tokenAddress - * @param {String} recipient - * @param {String} amount - * @param {String} force - * @param {Contract} contractInstance optional contract instance - * @return {Promise} - */ -export async function estTransfer( - web3: Web3, - account: string, - tokenAddress: string, - recipient: string, - amount: string, - contractInstance?: Contract -): Promise { - const tokenContract = contractInstance || new web3.eth.Contract(minAbi, tokenAddress) - - return estimateGas(account, tokenContract.methods.transfer, recipient, amount) -} - /** * Moves amount tokens from the caller’s account to recipient. * @param {String} account @@ -113,23 +68,25 @@ export async function estTransfer( * @param {String} amount amount of ERC20 Datatokens (not as wei) * @param {String} force if true, will overwrite any previous allowence. Else, will check if allowence is enough and will not send a transaction if it's not needed */ -export async function transfer( +export async function transfer( web3: Web3, account: string, tokenAddress: string, recipient: string, - amount: string -): Promise { + amount: string, + estimateGas?: G +): Promise { const tokenContract = new web3.eth.Contract(minAbi, tokenAddress) let result = null const amountFormatted = await amountToUnits(web3, tokenAddress, amount) - const estGas = await estimateGas( + const estGas = await calculateEstimatedGas( account, tokenContract.methods.transfer, recipient, amountFormatted ) + if (estimateGas) return estGas try { result = await tokenContract.methods.transfer(recipient, amountFormatted).send({