@oceanprotocol/lib 1.0.0-next.7 → 1.0.0-next.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/lib.js +1 -1
- package/dist/lib.js.map +1 -1
- package/dist/lib.modern.js +1 -1
- package/dist/lib.modern.js.map +1 -1
- package/dist/lib.module.js +1 -1
- package/dist/lib.module.js.map +1 -1
- package/dist/lib.umd.js +1 -1
- package/dist/lib.umd.js.map +1 -1
- package/dist/src/@types/DownloadResponse.d.ts +4 -0
- package/dist/src/aquarius/Aquarius.d.ts +3 -3
- package/dist/src/interfaces/Erc721Interface.d.ts +12 -0
- package/dist/src/pools/balancer/Pool.d.ts +0 -5
- package/dist/src/provider/Provider.d.ts +15 -11
- package/dist/src/tokens/NFT.d.ts +5 -2
- package/dist/src/utils/ConfigHelper.d.ts +1 -1
- package/dist/src/utils/Constants.d.ts +1 -0
- package/dist/src/utils/ContractUtils.d.ts +2 -0
- package/dist/src/utils/FetchHelper.d.ts +3 -2
- package/dist/src/utils/TokenUtils.d.ts +7 -0
- package/dist/src/utils/index.d.ts +1 -0
- package/dist/src/utils/minAbi.d.ts +2 -0
- package/package.json +3 -4
package/dist/lib.module.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lib.module.js","sources":["../src/utils/Logger.ts","../src/utils/DatatokenName.ts","../src/utils/ContractUtils.ts","../src/utils/FetchHelper.ts","../src/utils/ConfigHelper.ts","../src/utils/DdoHelpers.ts","../src/utils/Constants.ts","../src/utils/SignatureUtils.ts","../src/pools/balancer/Pool.ts","../src/pools/dispenser/Dispenser.ts","../src/pools/fixedRate/FixedRateExchange.ts","../src/tokens/NFT.ts","../src/tokens/Datatoken.ts","../src/factories/NFTFactory.ts","../src/models/Config.ts","../src/utils/ConversionTypeHelper.ts","../src/provider/Provider.ts"],"sourcesContent":["export enum LogLevel {\n None = -1,\n Error = 0,\n Warn = 1,\n Log = 2,\n Verbose = 3\n}\n\nexport class Logger {\n constructor(private logLevel: LogLevel = LogLevel.Error) {}\n\n public setLevel(logLevel: LogLevel): void {\n this.logLevel = logLevel\n }\n\n public bypass(...args: any[]): void {\n this.dispatch('log', -Infinity as any, ...args)\n }\n\n public debug(...args: any[]): void {\n this.dispatch('debug', LogLevel.Verbose, ...args)\n }\n\n public log(...args: any[]): void {\n this.dispatch('log', LogLevel.Log, ...args)\n }\n\n public warn(...args: any[]): void {\n this.dispatch('warn', LogLevel.Warn, ...args)\n }\n\n public error(...args: any[]): void {\n this.dispatch('error', LogLevel.Error, ...args)\n }\n\n private dispatch(verb: string, level: LogLevel, ...args: any[]) {\n if (this.logLevel >= level) {\n console[verb](...args)\n }\n }\n}\n\nexport const LoggerInstance = new Logger()\nexport default LoggerInstance\n","import wordListDefault from '../data/words.json'\n\n/**\n * Generate new datatoken name & symbol from a word list\n * @return {<{ name: String; symbol: String }>} datatoken name & symbol. Produces e.g. \"Endemic Jellyfish Token\" & \"ENDJEL-45\"\n */\nexport function generateDtName(wordList?: { nouns: string[]; adjectives: string[] }): {\n name: string\n symbol: string\n} {\n const list = wordList || wordListDefault\n const random1 = Math.floor(Math.random() * list.adjectives.length)\n const random2 = Math.floor(Math.random() * list.nouns.length)\n const indexNumber = Math.floor(Math.random() * 100)\n\n // Capitalized adjective & noun\n const adjective = list.adjectives[random1].replace(/^\\w/, (c) => c.toUpperCase())\n const noun = list.nouns[random2].replace(/^\\w/, (c) => c.toUpperCase())\n\n const name = `${adjective} ${noun} Token`\n // use first 3 letters of name, uppercase it, and add random number\n const symbol = `${(\n adjective.substring(0, 3) + noun.substring(0, 3)\n ).toUpperCase()}-${indexNumber}`\n\n return { name, symbol }\n}\n","import Web3 from 'web3'\nimport BigNumber from 'bignumber.js'\nimport { Contract } from 'web3-eth-contract'\nimport { generateDtName } from './DatatokenName'\nimport { Erc20CreateParams, FreCreationParams, PoolCreationParams } from '../interfaces'\nimport { Config } from '../models'\n\nexport function setContractDefaults(contract: Contract, config: Config): Contract {\n if (config) {\n if (config.transactionBlockTimeout)\n contract.transactionBlockTimeout = config.transactionBlockTimeout\n if (config.transactionConfirmationBlocks)\n contract.transactionConfirmationBlocks = config.transactionConfirmationBlocks\n if (config.transactionPollingTimeout)\n contract.transactionPollingTimeout = config.transactionPollingTimeout\n }\n return contract\n}\n\nexport async function getFairGasPrice(web3: Web3, config: Config): Promise<string> {\n const x = new BigNumber(await web3.eth.getGasPrice())\n if (config && config.gasFeeMultiplier)\n return x\n .multipliedBy(config.gasFeeMultiplier)\n .integerValue(BigNumber.ROUND_DOWN)\n .toString(10)\n else return x.toString(10)\n}\n\nexport function getErcCreationParams(ercParams: Erc20CreateParams): any {\n let name: string, symbol: string\n // Generate name & symbol if not present\n if (!ercParams.name || !ercParams.symbol) {\n ;({ name, symbol } = generateDtName())\n }\n return {\n templateIndex: ercParams.templateIndex,\n strings: [ercParams.name || name, ercParams.symbol || symbol],\n addresses: [\n ercParams.minter,\n ercParams.feeManager,\n ercParams.mpFeeAddress,\n ercParams.feeToken\n ],\n uints: [Web3.utils.toWei(ercParams.cap), Web3.utils.toWei(ercParams.feeAmount)],\n bytess: []\n }\n}\n\nexport function getFreCreationParams(freParams: FreCreationParams): any {\n if (!freParams.allowedConsumer)\n freParams.allowedConsumer = '0x0000000000000000000000000000000000000000'\n const withMint = freParams.withMint ? 1 : 0\n\n return {\n fixedPriceAddress: freParams.fixedRateAddress,\n addresses: [\n freParams.baseTokenAddress,\n freParams.owner,\n freParams.marketFeeCollector,\n freParams.allowedConsumer\n ],\n uints: [\n freParams.baseTokenDecimals,\n freParams.datatokenDecimals,\n freParams.fixedRate,\n freParams.marketFee,\n withMint\n ]\n }\n}\n\nexport function getPoolCreationParams(poolParams: PoolCreationParams): any {\n return {\n addresses: [\n poolParams.ssContract,\n poolParams.baseTokenAddress,\n poolParams.baseTokenSender,\n poolParams.publisherAddress,\n poolParams.marketFeeCollector,\n poolParams.poolTemplateAddress\n ],\n ssParams: [\n Web3.utils.toWei(poolParams.rate),\n poolParams.baseTokenDecimals,\n Web3.utils.toWei(poolParams.vestingAmount),\n poolParams.vestedBlocks,\n Web3.utils.toWei(poolParams.initialBaseTokenLiquidity)\n ],\n swapFees: [poolParams.swapFeeLiquidityProvider, poolParams.swapFeeMarketRunner]\n }\n}\n","import fetch from 'cross-fetch'\nimport LoggerInstance from './Logger'\nimport fs from 'fs'\nimport save from 'save-file'\n\nexport async function fetchData(url: string, opts: RequestInit): Promise<Response> {\n const result = await fetch(url, opts)\n if (!result.ok) {\n LoggerInstance.error(`Error requesting [${opts.method}] ${url}`)\n LoggerInstance.error(`Response message: \\n${await result.text()}`)\n throw result\n }\n return result\n}\n\nexport async function downloadFile(\n url: string,\n destination?: string,\n index?: number\n): Promise<string> {\n const response = await fetch(url)\n if (!response.ok) {\n throw new Error('Response error.')\n }\n let filename: string\n try {\n filename = response.headers\n .get('content-disposition')\n .match(/attachment;filename=(.+)/)[1]\n } catch {\n try {\n filename = url.split('/').pop()\n } catch {\n filename = `file${index}`\n }\n }\n if (destination) {\n // eslint-disable-next-line no-async-promise-executor\n fs.mkdirSync(destination, { recursive: true })\n fs.writeFileSync(`${destination}/${filename}`, await response.text())\n return destination\n } else {\n save(await response.arrayBuffer(), filename)\n }\n}\n\nexport async function getData(url: string): Promise<Response> {\n return fetch(url, {\n method: 'GET',\n headers: {\n 'Content-type': 'application/json'\n }\n })\n}\n\nasync function postWithHeaders(\n url: string,\n payload: BodyInit,\n headers: any\n): Promise<Response> {\n if (payload != null) {\n return fetch(url, {\n method: 'POST',\n body: payload,\n headers\n })\n } else {\n return fetch(url, {\n method: 'POST'\n })\n }\n}\n\nexport async function postData(url: string, payload: BodyInit): Promise<Response> {\n const headers = {\n 'Content-type': 'application/json'\n }\n return postWithHeaders(url, payload, headers)\n}\n\n// simple fetch function used in tests\nexport async function crossFetchGeneric(\n method: string,\n url: string,\n body: string,\n headers: any\n) {\n return fetch(url, {\n method: method,\n body: body,\n headers: headers\n })\n}\n","import Config from '../models/Config'\nimport fs from 'fs'\n// eslint-disable-next-line import/no-named-default\nimport { default as DefaultContractsAddresses } from '@oceanprotocol/contracts/addresses/address.json'\nimport LoggerInstance from './Logger'\n\nconst configHelperNetworksBase: Config = {\n chainId: null,\n network: 'unknown',\n metadataCacheUri: 'https://aquarius.oceanprotocol.com',\n nodeUri: 'http://localhost:8545',\n providerUri: 'http://127.0.0.1:8030',\n subgraphUri: null,\n explorerUri: null,\n oceanTokenAddress: null,\n oceanTokenSymbol: 'OCEAN',\n poolTemplateAddress: null,\n fixedRateExchangeAddress: null,\n dispenserAddress: null,\n startBlock: 0,\n transactionBlockTimeout: 50,\n transactionConfirmationBlocks: 1,\n transactionPollingTimeout: 750,\n gasFeeMultiplier: 1\n}\n\nexport const configHelperNetworks: Config[] = [\n {\n ...configHelperNetworksBase\n },\n {\n // barge\n ...configHelperNetworksBase,\n chainId: 8996,\n network: 'development',\n metadataCacheUri: 'http://127.0.0.1:5000'\n },\n {\n ...configHelperNetworksBase,\n chainId: 3,\n network: 'ropsten',\n nodeUri: 'https://ropsten.infura.io/v3',\n providerUri: 'https://provider.ropsten.oceanprotocol.com',\n subgraphUri: 'https://subgraph.ropsten.oceanprotocol.com',\n explorerUri: 'https://ropsten.etherscan.io',\n startBlock: 9227563\n },\n {\n ...configHelperNetworksBase,\n chainId: 4,\n network: 'rinkeby',\n nodeUri: 'https://rinkeby.infura.io/v3',\n providerUri: 'https://providerv4.rinkeby.oceanprotocol.com',\n subgraphUri: 'https://subgraphv4.rinkeby.oceanprotocol.com',\n explorerUri: 'https://rinkeby.etherscan.io',\n startBlock: 7294090\n },\n {\n ...configHelperNetworksBase,\n chainId: 1,\n network: 'mainnet',\n nodeUri: 'https://mainnet.infura.io/v3',\n providerUri: 'https://provider.mainnet.oceanprotocol.com',\n subgraphUri: 'https://subgraph.mainnet.oceanprotocol.com',\n explorerUri: 'https://etherscan.io',\n startBlock: 11105459,\n transactionBlockTimeout: 150,\n transactionConfirmationBlocks: 5,\n transactionPollingTimeout: 1750,\n gasFeeMultiplier: 1.05\n },\n {\n ...configHelperNetworksBase,\n chainId: 137,\n network: 'polygon',\n nodeUri: 'https://polygon-mainnet.infura.io/v3',\n providerUri: 'https://provider.polygon.oceanprotocol.com',\n subgraphUri: 'https://subgraph.polygon.oceanprotocol.com',\n explorerUri: 'https://polygonscan.com',\n oceanTokenSymbol: 'mOCEAN',\n startBlock: 11005222\n },\n {\n ...configHelperNetworksBase,\n chainId: 1287,\n network: 'moonbeamalpha',\n nodeUri: 'https://rpc.testnet.moonbeam.network',\n providerUri: 'https://provider.moonbeamalpha.oceanprotocol.com',\n subgraphUri: 'https://subgraph.moonbeamalpha.oceanprotocol.com',\n explorerUri: 'https://moonbase-blockscout.testnet.moonbeam.network/',\n startBlock: 90707\n },\n {\n ...configHelperNetworksBase,\n chainId: 2021000,\n network: 'gaiaxtestnet',\n nodeUri: 'https://rpc.gaiaxtestnet.oceanprotocol.com',\n providerUri: 'https://provider.gaiaxtestnet.oceanprotocol.com',\n subgraphUri: 'https://subgraph.gaiaxtestnet.oceanprotocol.com',\n explorerUri: 'https://blockscout.gaiaxtestnet.oceanprotocol.com'\n },\n {\n ...configHelperNetworksBase,\n chainId: 2021001,\n network: 'catenaxtestnet',\n nodeUri: 'https://rpc.catenaxtestnet.oceanprotocol.com',\n providerUri: 'https://provider.catenaxtestnet.oceanprotocol.com',\n subgraphUri: 'https://subgraph.catenaxtestnet.oceanprotocol.com',\n explorerUri: 'https://blockscout.catenaxtestnet.oceanprotocol.com',\n metadataCacheUri: 'https://aquarius.catenaxtestnet.oceanprotocol.com'\n },\n {\n ...configHelperNetworksBase,\n chainId: 80001,\n network: 'mumbai',\n nodeUri: 'https://polygon-mumbai.infura.io/v3',\n providerUri: 'https://provider.mumbai.oceanprotocol.com',\n subgraphUri: 'https://subgraph.mumbai.oceanprotocol.com',\n explorerUri: 'https://mumbai.polygonscan.com'\n },\n {\n ...configHelperNetworksBase,\n chainId: 56,\n network: 'bsc',\n nodeUri: 'https://bsc-dataseed.binance.org',\n providerUri: 'https://provider.bsc.oceanprotocol.com',\n subgraphUri: 'https://subgraph.bsc.oceanprotocol.com',\n explorerUri: 'https://bscscan.com/',\n gasFeeMultiplier: 1.05\n },\n {\n ...configHelperNetworksBase,\n chainId: 44787,\n network: 'celoalfajores',\n nodeUri: 'https://alfajores-forno.celo-testnet.org',\n providerUri: 'https://provider.celoalfajores.oceanprotocol.com',\n subgraphUri: 'https://subgraph.celoalfajores.oceanprotocol.com',\n explorerUri: 'https://alfajores-blockscout.celo-testnet.org'\n },\n {\n ...configHelperNetworksBase,\n chainId: 246,\n network: 'energyweb',\n nodeUri: 'https://rpc.energyweb.org',\n providerUri: 'https://provider.energyweb.oceanprotocol.com',\n subgraphUri: 'https://subgraph.energyweb.oceanprotocol.com',\n explorerUri: 'https://explorer.energyweb.org',\n gasFeeMultiplier: 1.05\n },\n {\n ...configHelperNetworksBase,\n chainId: 1285,\n network: 'moonriver',\n nodeUri: 'https://moonriver.api.onfinality.io/public',\n providerUri: 'https://provider.moonriver.oceanprotocol.com',\n subgraphUri: 'https://subgraph.moonriver.oceanprotocol.com',\n explorerUri: 'https://blockscout.moonriver.moonbeam.network',\n gasFeeMultiplier: 1.05\n }\n]\n\nexport class ConfigHelper {\n /* Load contract addresses from env ADDRESS_FILE (generated by ocean-contracts) */\n public getAddressesFromEnv(network: string): Partial<Config> {\n // use the defaults first\n let configAddresses: Partial<Config>\n if (DefaultContractsAddresses[network]) {\n const {\n FixedPrice,\n Dispenser,\n Staking,\n poolTemplate,\n OPFCommunityFeeCollector,\n ERC721Factory,\n Ocean,\n chainId,\n startBlock\n } = DefaultContractsAddresses[network]\n configAddresses = {\n erc721FactoryAddress: ERC721Factory,\n sideStakingAddress: Staking,\n opfCommunityFeeCollector: OPFCommunityFeeCollector,\n poolTemplateAddress: poolTemplate,\n fixedRateExchangeAddress: FixedPrice,\n dispenserAddress: Dispenser,\n oceanTokenAddress: Ocean,\n chainId: chainId,\n startBlock: startBlock,\n ...(process.env.AQUARIUS_URI && { metadataCacheUri: process.env.AQUARIUS_URI })\n }\n }\n // try ADDRESS_FILE env\n if (fs && process.env.ADDRESS_FILE) {\n try {\n const data = JSON.parse(fs.readFileSync(process.env.ADDRESS_FILE, 'utf8'))\n const {\n FixedPrice,\n Dispenser,\n Staking,\n poolTemplate,\n ERC721Factory,\n OPFCommunityFeeCollector,\n Ocean,\n chainId,\n startBlock\n } = data[network]\n configAddresses = {\n erc721FactoryAddress: ERC721Factory,\n sideStakingAddress: Staking,\n opfCommunityFeeCollector: OPFCommunityFeeCollector,\n poolTemplateAddress: poolTemplate,\n fixedRateExchangeAddress: FixedPrice,\n dispenserAddress: Dispenser,\n oceanTokenAddress: Ocean,\n chainId: chainId,\n startBlock: startBlock,\n ...(process.env.AQUARIUS_URI && { metadataCacheUri: process.env.AQUARIUS_URI })\n }\n } catch (e) {\n // console.error(`ERROR: Could not load local contract address file: ${e.message}`)\n // return null\n }\n }\n return configAddresses\n }\n\n public getConfig(network: string | number, infuraProjectId?: string): Config {\n const filterBy = typeof network === 'string' ? 'network' : 'chainId'\n let config = configHelperNetworks.find((c) => c[filterBy] === network)\n\n if (!config) {\n LoggerInstance.error(`No config found for given network '${network}'`)\n return null\n }\n\n const contractAddressesConfig = this.getAddressesFromEnv(config.network)\n config = { ...config, ...contractAddressesConfig }\n\n const nodeUri = infuraProjectId\n ? `${config.nodeUri}/${infuraProjectId}`\n : config.nodeUri\n\n return { ...config, nodeUri }\n }\n}\n","import sha256 from 'crypto-js/sha256'\nimport Web3 from 'web3'\n\nexport function generateDid(erc721Address: string, chainId: number): string {\n erc721Address = Web3.utils.toChecksumAddress(erc721Address)\n const checksum = sha256(erc721Address + chainId.toString(10))\n return `did:op:${checksum.toString()}`\n}\n\nexport function getHash(data: any): string {\n return sha256(data).toString()\n}\n","export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'\n","import Web3 from 'web3'\nimport { LoggerInstance } from './Logger'\n\nexport async function signText(\n web3: Web3,\n text: string,\n publicKey: string,\n password?: string\n): Promise<string> {\n const isMetaMask =\n web3 && web3.currentProvider && (web3.currentProvider as any).isMetaMask\n try {\n return await web3.eth.personal.sign(text, publicKey, password)\n } catch (e) {\n if (isMetaMask) {\n throw e\n }\n LoggerInstance.warn('Error on personal sign.')\n LoggerInstance.warn(e)\n try {\n return await web3.eth.sign(text, publicKey)\n } catch (e2) {\n LoggerInstance.error('Error on sign.')\n LoggerInstance.error(e2)\n throw new Error('Error executing personal sign')\n }\n }\n}\n\nexport async function signHash(web3: Web3, message: string, address: string) {\n let signedMessage = await web3.eth.sign(message, address)\n signedMessage = signedMessage.substr(2) // remove 0x\n const r = '0x' + signedMessage.slice(0, 64)\n const s = '0x' + signedMessage.slice(64, 128)\n let v = '0x' + signedMessage.slice(128, 130)\n // make sure we obey 27 and 28 standards\n if (v === '0x00') v = '0x1b'\n if (v === '0x01') v = '0x1c'\n return { v, r, s }\n}\n\nexport async function signWithHash(\n web3: Web3,\n text: string,\n publicKey: string,\n password?: string\n): Promise<string> {\n const hash = web3.utils.utf8ToHex(text)\n const isMetaMask =\n web3 && web3.currentProvider && (web3.currentProvider as any).isMetaMask\n try {\n return await web3.eth.personal.sign(hash, publicKey, password)\n } catch (e) {\n if (isMetaMask) {\n throw e\n }\n LoggerInstance.warn('Error on personal sign.')\n LoggerInstance.warn(e)\n try {\n return await web3.eth.sign(hash, publicKey)\n } catch (e2) {\n LoggerInstance.error('Error on sign.')\n LoggerInstance.error(e2)\n throw new Error('Error executing personal sign')\n }\n }\n}\n","import Web3 from 'web3'\nimport { AbiItem } from 'web3-utils/types'\nimport { TransactionReceipt } from 'web3-core'\nimport { Contract } from 'web3-eth-contract'\nimport {\n Logger,\n getFairGasPrice,\n LoggerInstance,\n configHelperNetworks,\n setContractDefaults\n} from '../../utils'\nimport BigNumber from 'bignumber.js'\nimport PoolTemplate from '@oceanprotocol/contracts/artifacts/contracts/pools/balancer/BPool.sol/BPool.json'\nimport defaultErc20Abi from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json'\nimport Decimal from 'decimal.js'\nimport {\n CurrentFees,\n TokenInOutMarket,\n AmountsInMaxFee,\n AmountsOutMaxFee\n} from '../../interfaces'\nimport { Config } from '../../models'\nconst MaxUint256 =\n '115792089237316195423570985008687907853269984665640564039457584007913129639934'\n\n/**\n * Provides an interface to Ocean friendly fork from Balancer BPool\n */\nexport class Pool {\n public poolAbi: AbiItem | AbiItem[]\n public web3: Web3\n public GASLIMIT_DEFAULT = 1000000\n private logger: Logger\n private config: Config\n\n constructor(\n web3: Web3,\n logger: Logger,\n poolAbi: AbiItem | AbiItem[] = null,\n config?: Config\n ) {\n if (poolAbi) this.poolAbi = poolAbi\n else this.poolAbi = PoolTemplate.abi as AbiItem[]\n this.web3 = web3\n this.logger = logger\n this.config = config || configHelperNetworks[0]\n }\n\n /**\n * Estimate gas cost for approval function\n * @param {String} account\n * @param {String} tokenAddress\n * @param {String} spender\n * @param {String} amount\n * @param {String} force\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estApprove(\n account: string,\n tokenAddress: string,\n spender: string,\n amount: string,\n contractInstance?: Contract\n ): Promise<number> {\n const tokenContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(defaultErc20Abi.abi as AbiItem[], tokenAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await tokenContract.methods\n .approve(spender, amount)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n LoggerInstance.error('estimate gas failed for approve!', e)\n }\n return estGas\n }\n\n /**\n * Get Alloance for both Datatoken and Ocean\n * @param {String } tokenAdress\n * @param {String} owner\n * @param {String} spender\n */\n public async allowance(\n tokenAddress: string,\n owner: string,\n spender: string\n ): Promise<string> {\n const tokenAbi = defaultErc20Abi.abi as AbiItem[]\n const datatoken = setContractDefaults(\n new this.web3.eth.Contract(tokenAbi, tokenAddress),\n this.config\n )\n const trxReceipt = await datatoken.methods.allowance(owner, spender).call()\n\n return await this.unitsToAmount(tokenAddress, trxReceipt)\n }\n\n /**\n * Approve spender to spent amount tokens\n * @param {String} account\n * @param {String} tokenAddress\n * @param {String} spender\n * @param {String} amount (always expressed as wei)\n * @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\n */\n async approve(\n account: string,\n tokenAddress: string,\n spender: string,\n amount: string,\n force = false\n ): Promise<TransactionReceipt | string> {\n const minABI = [\n {\n constant: false,\n inputs: [\n {\n name: '_spender',\n type: 'address'\n },\n {\n name: '_value',\n type: 'uint256'\n }\n ],\n name: 'approve',\n outputs: [\n {\n name: '',\n type: 'bool'\n }\n ],\n payable: false,\n stateMutability: 'nonpayable',\n type: 'function'\n }\n ] as AbiItem[]\n const token = setContractDefaults(\n new this.web3.eth.Contract(minABI, tokenAddress),\n this.config\n )\n if (!force) {\n const currentAllowence = await this.allowance(tokenAddress, account, spender)\n if (new Decimal(currentAllowence).greaterThanOrEqualTo(new Decimal(amount))) {\n return currentAllowence\n }\n }\n let result = null\n const amountFormatted = await this.amountToUnits(tokenAddress, amount)\n const estGas = await this.estApprove(account, tokenAddress, spender, amountFormatted)\n\n try {\n result = await token.methods.approve(spender, amountFormatted).send({\n from: account,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n this.logger.error(`ERRPR: Failed to approve spender to spend tokens : ${e.message}`)\n }\n return result\n }\n\n /**\n * Get user shares of pool tokens\n * @param {String} account\n * @param {String} poolAddress\n * @return {String}\n */\n async sharesBalance(account: string, poolAddress: string): Promise<string> {\n let result = null\n try {\n const token = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n const balance = await token.methods.balanceOf(account).call()\n result = this.web3.utils.fromWei(balance)\n } catch (e) {\n this.logger.error(`ERROR: Failed to get shares of pool : ${e.message}`)\n }\n return result\n }\n\n /**\n * Estimate gas cost for setSwapFee\n * @param {String} account\n * @param {String} tokenAddress\n * @param {String} spender\n * @param {String} amount\n * @param {String} force\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estSetSwapFee(\n account: string,\n poolAddress: string,\n fee: string,\n contractInstance?: Contract\n ): Promise<number> {\n const poolContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(defaultErc20Abi.abi as AbiItem[], poolAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await poolContract.methods\n .setSwapFee(fee)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Set pool fee\n * @param {String} account\n * @param {String} poolAddress\n * @param {String} fee 0.1=10% fee(max allowed)\n */\n async setSwapFee(\n account: string,\n poolAddress: string,\n fee: string\n ): Promise<TransactionReceipt> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress, {\n from: account\n }),\n this.config\n )\n let result = null\n const estGas = await this.estSetSwapFee(account, poolAddress, fee)\n\n try {\n result = await pool.methods.setSwapFee(this.web3.utils.toWei(fee)).send({\n from: account,\n gas: estGas,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n this.logger.error(`ERROR: Failed to set pool swap fee: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get number of tokens composing this pool\n * @param {String} poolAddress\n * @return {String}\n */\n async getNumTokens(poolAddress: string): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n try {\n result = await pool.methods.getNumTokens().call()\n } catch (e) {\n this.logger.error(`ERROR: Failed to get number of tokens: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get total supply of pool shares\n * @param {String} poolAddress\n * @return {String}\n */\n async getPoolSharesTotalSupply(poolAddress: string): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let amount = null\n try {\n const result = await pool.methods.totalSupply().call()\n amount = this.web3.utils.fromWei(result)\n } catch (e) {\n this.logger.error(`ERROR: Failed to get total supply of pool shares: ${e.message}`)\n }\n return amount\n }\n\n /**\n * Get tokens composing this pool\n * @param {String} poolAddress\n * @return {String[]}\n */\n async getCurrentTokens(poolAddress: string): Promise<string[]> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n try {\n result = await pool.methods.getCurrentTokens().call()\n } catch (e) {\n this.logger.error(`ERROR: Failed to get tokens composing this pool: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get the final tokens composing this pool\n * @param {String} poolAddress\n * @return {String[]}\n */\n async getFinalTokens(poolAddress: string): Promise<string[]> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n try {\n result = await pool.methods.getFinalTokens().call()\n } catch (e) {\n this.logger.error(`ERROR: Failed to get the final tokens composing this pool`)\n }\n return result\n }\n\n /**\n * Get controller address of this pool\n * @param {String} poolAddress\n * @return {String}\n */\n async getController(poolAddress: string): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n try {\n result = await pool.methods.getController().call()\n } catch (e) {\n this.logger.error(`ERROR: Failed to get pool controller address: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get baseToken address of this pool\n * @param {String} poolAddress\n * @return {String}\n */\n async getBaseToken(poolAddress: string): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n try {\n result = await pool.methods.getBaseTokenAddress().call()\n } catch (e) {\n this.logger.error(`ERROR: Failed to get baseToken address: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get datatoken address of this pool\n * @param {String} poolAddress\n * @return {String}\n */\n async getDatatoken(poolAddress: string): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n try {\n result = await pool.methods.getDatatokenAddress().call()\n } catch (e) {\n this.logger.error(`ERROR: Failed to get datatoken address: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get marketFeeCollector of this pool\n * @param {String} poolAddress\n * @return {String}\n */\n async getMarketFeeCollector(poolAddress: string): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n try {\n result = await pool.methods._publishMarketCollector().call()\n } catch (e) {\n this.logger.error(`ERROR: Failed to get marketFeeCollector address: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get OPF Collector of this pool\n * @param {String} poolAddress\n * @return {String}\n */\n async getOPFCollector(poolAddress: string): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n try {\n result = await pool.methods._opfCollector().call()\n } catch (e) {\n this.logger.error(`ERROR: Failed to get OPF Collector address: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get if a token is bounded to a pool\n * @param {String} poolAddress\n * @param {String} token Address of the token\n * @return {Boolean}\n */\n async isBound(poolAddress: string, token: string): Promise<boolean> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n try {\n result = await pool.methods.isBound(token).call()\n } catch (e) {\n this.logger.error(`ERROR: Failed to check whether a token \\\n bounded to a pool. ${e.message}`)\n }\n return result\n }\n\n /**\n * Get how many tokens are in the pool\n * @param {String} poolAddress\n * @param {String} token Address of the token\n * @return {String}\n */\n async getReserve(poolAddress: string, token: string): Promise<string> {\n let amount = null\n try {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n const result = await pool.methods.getBalance(token).call()\n amount = await this.unitsToAmount(token, result)\n } catch (e) {\n this.logger.error(`ERROR: Failed to get how many tokens \\\n are in the pool: ${e.message}`)\n }\n return amount.toString()\n }\n\n /**\n * Get if a pool is finalized\n * @param {String} poolAddress\n * @return {Boolean}\n */\n async isFinalized(poolAddress: string): Promise<boolean> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n try {\n result = await pool.methods.isFinalized().call()\n } catch (e) {\n this.logger.error(`ERROR: Failed to check whether pool is finalized: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get pool fee\n * @param {String} poolAddress\n * @return {String} Swap fee. To get the percentage value, substract by 100. E.g. `0.1` represents a 10% swap fee.\n */\n async getSwapFee(poolAddress: string): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let fee = null\n try {\n const result = await pool.methods.getSwapFee().call()\n fee = this.web3.utils.fromWei(result)\n } catch (e) {\n this.logger.error(`ERROR: Failed to get pool fee: ${e.message}`)\n }\n return fee\n }\n\n /**\n * The normalized weight of a token. The combined normalized weights of all tokens will sum up to 1. (Note: the actual sum may be 1 plus or minus a few wei due to division precision loss)\n * @param {String} poolAddress\n * @param {String} token\n * @return {String}\n */\n async getNormalizedWeight(poolAddress: string, token: string): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let weight = null\n try {\n const result = await pool.methods.getNormalizedWeight(token).call()\n weight = this.web3.utils.fromWei(result)\n } catch (e) {\n this.logger.error(`ERROR: Failed to get normalized weight of a token: ${e.message}`)\n }\n return weight\n }\n\n /**\n * getDenormalizedWeight of a token in pool\n * @param {String} poolAddress\n * @param {String} token\n * @return {String}\n */\n async getDenormalizedWeight(poolAddress: string, token: string): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let weight = null\n try {\n const result = await pool.methods.getDenormalizedWeight(token).call()\n weight = this.web3.utils.fromWei(result)\n } catch (e) {\n this.logger.error('ERROR: Failed to get denormalized weight of a token in pool')\n }\n return weight\n }\n\n /**\n * getTotalDenormalizedWeight in pool\n * @param {String} poolAddress\n * @return {String}\n */\n async getTotalDenormalizedWeight(poolAddress: string): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let weight = null\n try {\n const result = await pool.methods.getTotalDenormalizedWeight().call()\n weight = this.web3.utils.fromWei(result)\n } catch (e) {\n this.logger.error('ERROR: Failed to get total denormalized weight in pool')\n }\n return weight\n }\n\n /**\n * Get Market Fees available to be collected for a specific token\n * @param {String} poolAddress\n * @param {String} token token we want to check fees\n * @return {String}\n */\n async getMarketFees(poolAddress: string, token: string): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let weight = null\n try {\n const result = await pool.methods.publishMarketFees(token).call()\n weight = await this.unitsToAmount(token, result)\n } catch (e) {\n this.logger.error(`ERROR: Failed to get market fees for a token: ${e.message}`)\n }\n return weight\n }\n\n /**\n * Get Community Get the current amount of fees which can be withdrawned by the Market\n * @return {CurrentFees}\n */\n async getCurrentMarketFees(poolAddress: string): Promise<CurrentFees> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n try {\n const currentMarketFees = await pool.methods.getCurrentOPFFees().call()\n return currentMarketFees\n } catch (e) {\n this.logger.error(`ERROR: Failed to get community fees for a token: ${e.message}`)\n }\n }\n\n /**\n * Get getCurrentOPFFees Get the current amount of fees which can be withdrawned by OPF\n * @return {CurrentFees}\n */\n async getCurrentOPFFees(poolAddress: string): Promise<CurrentFees> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n try {\n const currentMarketFees = await pool.methods.getCurrentOPFFees().call()\n return currentMarketFees\n } catch (e) {\n this.logger.error(`ERROR: Failed to get community fees for a token: ${e.message}`)\n }\n }\n\n /**\n * Get Community Fees available to be collected for a specific token\n * @param {String} poolAddress\n * @param {String} token token we want to check fees\n * @return {String}\n */\n async getCommunityFees(poolAddress: string, token: string): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let weight = null\n try {\n const result = await pool.methods.communityFees(token).call()\n weight = await this.unitsToAmount(token, result)\n } catch (e) {\n this.logger.error(`ERROR: Failed to get community fees for a token: ${e.message}`)\n }\n return weight\n }\n\n /**\n * Estimate gas cost for collectOPF\n * @param {String} address\n * @param {String} poolAddress\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estCollectOPF(\n address: string,\n poolAddress: string,\n contractInstance?: Contract\n ): Promise<number> {\n const poolContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi as AbiItem[], poolAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await poolContract.methods\n .collectOPF()\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * collectOPF - collect opf fee - can be called by anyone\n * @param {String} address\n * @param {String} poolAddress\n * @return {TransactionReceipt}\n */\n async collectOPF(address: string, poolAddress: string): Promise<TransactionReceipt> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n const estGas = await this.estCollectOPF(address, poolAddress)\n\n try {\n result = await pool.methods.collectOPF().send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n this.logger.error(`ERROR: Failed to swap exact amount in : ${e.message}`)\n }\n return result\n }\n\n /**\n * Estimate gas cost for collectMarketFee\n * @param {String} address\n * @param {String} poolAddress\n * @param {String} to address that will receive fees\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estCollectMarketFee(\n address: string,\n poolAddress: string,\n contractInstance?: Contract\n ): Promise<number> {\n const poolContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi as AbiItem[], poolAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await poolContract.methods\n .collectMarketFee()\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * collectOPF - collect market fees - can be called by the publishMarketCollector\n * @param {String} address\n * @param {String} poolAddress\n * @param {String} to address that will receive fees\n * @return {TransactionReceipt}\n */\n async collectMarketFee(\n address: string,\n poolAddress: string\n ): Promise<TransactionReceipt> {\n if ((await this.getMarketFeeCollector(poolAddress)) !== address) {\n throw new Error(`Caller is not MarketFeeCollector`)\n }\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n const estGas = await this.estCollectMarketFee(address, poolAddress)\n\n try {\n result = await pool.methods.collectMarketFee().send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n this.logger.error(`ERROR: Failed to swap exact amount in : ${e.message}`)\n }\n return result\n }\n\n /**\n * Estimate gas cost for updateMarketFeeCollector\n * @param {String} address\n * @param {String} poolAddress\n * @param {String} newCollector new market fee collector address\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estUpdateMarketFeeCollector(\n address: string,\n poolAddress: string,\n newCollector: string,\n contractInstance?: Contract\n ): Promise<number> {\n const poolContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi as AbiItem[], poolAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await poolContract.methods\n .updateMarketFeeCollector(newCollector)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * updateMarketFeeCollector - updates marketFeeCollector - can be called only by the marketFeeCollector\n * @param {String} address\n * @param {String} poolAddress\n * @param {String} newCollector new market fee collector address\n * @return {TransactionReceipt}\n */\n async updateMarketFeeCollector(\n address: string,\n poolAddress: string,\n newCollector: string\n ): Promise<TransactionReceipt> {\n if ((await this.getMarketFeeCollector(poolAddress)) !== address) {\n throw new Error(`Caller is not MarketFeeCollector`)\n }\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n const estGas = await this.estUpdateMarketFeeCollector(\n address,\n poolAddress,\n newCollector\n )\n\n try {\n result = await pool.methods.updateMarketFeeCollector(newCollector).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n this.logger.error(`ERROR: Failed to swap exact amount in : ${e.message}`)\n }\n return result\n }\n\n async amountToUnits(token: string, amount: string): Promise<string> {\n try {\n const tokenContract = setContractDefaults(\n new this.web3.eth.Contract(defaultErc20Abi.abi as AbiItem[], token),\n this.config\n )\n let decimals = await tokenContract.methods.decimals().call()\n if (decimals === '0') {\n decimals = 18\n }\n const amountFormatted = new BigNumber(parseInt(amount) * 10 ** decimals)\n BigNumber.config({ EXPONENTIAL_AT: 50 })\n return amountFormatted.toString()\n } catch (e) {\n this.logger.error('ERROR: FAILED TO CALL DECIMALS(), USING 18')\n }\n }\n\n async unitsToAmount(token: string, amount: string): Promise<string> {\n try {\n const tokenContract = setContractDefaults(\n new this.web3.eth.Contract(defaultErc20Abi.abi as AbiItem[], token),\n this.config\n )\n let decimals = await tokenContract.methods.decimals().call()\n if (decimals === '0') {\n decimals = 18\n }\n const amountFormatted = new BigNumber(parseInt(amount) / 10 ** decimals)\n\n return amountFormatted.toString()\n } catch (e) {\n this.logger.error('ERROR: FAILED TO CALL DECIMALS(), USING 18')\n }\n }\n\n /**\n * Estimate gas cost for swapExactAmountIn\n * @param {String} address\n * @param {String} poolAddress\n * @param {TokenInOutMarket} tokenInOutMarket\n * @param {AmountsInMaxFee} amountsInOutMaxFee\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estSwapExactAmountIn(\n address: string,\n poolAddress: string,\n tokenInOutMarket: TokenInOutMarket,\n amountsInOutMaxFee: AmountsInMaxFee,\n contractInstance?: Contract\n ): Promise<number> {\n const poolContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi as AbiItem[], poolAddress),\n this.config\n )\n\n const maxPrice = amountsInOutMaxFee.maxPrice\n ? this.web3.utils.toWei(amountsInOutMaxFee.maxPrice)\n : MaxUint256\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await poolContract.methods\n .swapExactAmountIn(\n [\n tokenInOutMarket.tokenIn,\n tokenInOutMarket.tokenOut,\n tokenInOutMarket.marketFeeAddress\n ],\n [\n amountsInOutMaxFee.tokenAmountIn,\n amountsInOutMaxFee.minAmountOut,\n maxPrice,\n this.web3.utils.toWei(amountsInOutMaxFee.swapMarketFee)\n ]\n )\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * swapExactAmountIn - Trades an exact tokenAmountIn of tokenIn taken from the caller by the pool,\n * in exchange for at least minAmountOut of tokenOut given to the caller from the pool, with a maximum marginal price of maxPrice.\n * Returns (tokenAmountOut, spotPriceAfter), where tokenAmountOut is the amount of token that came out of the pool,\n * and spotPriceAfter is the new marginal spot price, ie, the result of getSpotPrice after the call.\n * (These values are what are limited by the arguments; you are guaranteed tokenAmountOut >= minAmountOut and spotPriceAfter <= maxPrice).\n * @param {String} address\n * @param {String} poolAddress\n * @param {TokenInOutMarket} tokenInOutMarket\n * @param {AmountsInMaxFee} amountsInOutMaxFee\n * @return {TransactionReceipt}\n */\n async swapExactAmountIn(\n address: string,\n poolAddress: string,\n tokenInOutMarket: TokenInOutMarket,\n amountsInOutMaxFee: AmountsInMaxFee\n ): Promise<TransactionReceipt> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n\n amountsInOutMaxFee.tokenAmountIn = await this.amountToUnits(\n tokenInOutMarket.tokenIn,\n amountsInOutMaxFee.tokenAmountIn\n )\n\n amountsInOutMaxFee.minAmountOut = await this.amountToUnits(\n tokenInOutMarket.tokenOut,\n amountsInOutMaxFee.minAmountOut\n )\n\n let result = null\n\n const estGas = await this.estSwapExactAmountIn(\n address,\n poolAddress,\n tokenInOutMarket,\n amountsInOutMaxFee\n )\n\n const maxPrice = amountsInOutMaxFee.maxPrice\n ? this.web3.utils.toWei(amountsInOutMaxFee.maxPrice)\n : MaxUint256\n\n try {\n result = await pool.methods\n .swapExactAmountIn(\n [\n tokenInOutMarket.tokenIn,\n tokenInOutMarket.tokenOut,\n tokenInOutMarket.marketFeeAddress\n ],\n [\n amountsInOutMaxFee.tokenAmountIn,\n amountsInOutMaxFee.minAmountOut,\n maxPrice,\n this.web3.utils.toWei(amountsInOutMaxFee.swapMarketFee)\n ]\n )\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n this.logger.error(`ERROR: Failed to swap exact amount in : ${e.message}`)\n }\n\n return result\n }\n\n /**\n * Estimate gas cost for swapExactAmountOut\n * @param {String} address\n * @param {String} poolAddress\n * @param {TokenInOutMarket} tokenInOutMarket\n * @param {AmountsOutMaxFee} amountsInOutMaxFee\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estSwapExactAmountOut(\n address: string,\n poolAddress: string,\n tokenInOutMarket: TokenInOutMarket,\n amountsInOutMaxFee: AmountsOutMaxFee,\n contractInstance?: Contract\n ): Promise<number> {\n const poolContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi as AbiItem[], poolAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n\n const maxPrice = amountsInOutMaxFee.maxPrice\n ? this.web3.utils.toWei(amountsInOutMaxFee.maxPrice)\n : MaxUint256\n\n let estGas\n try {\n estGas = await poolContract.methods\n .swapExactAmountOut(\n [\n tokenInOutMarket.tokenIn,\n tokenInOutMarket.tokenOut,\n tokenInOutMarket.marketFeeAddress\n ],\n [\n amountsInOutMaxFee.maxAmountIn,\n amountsInOutMaxFee.tokenAmountOut,\n maxPrice,\n this.web3.utils.toWei(amountsInOutMaxFee.swapMarketFee)\n ]\n )\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * swapExactAmountOut\n * @param {String} account\n * @param {String} poolAddress\n * @param {TokenInOutMarket} tokenInOutMarket\n * @param {AmountsOutMaxFee} amountsInOutMaxFee\n * @return {TransactionReceipt}\n */\n async swapExactAmountOut(\n account: string,\n poolAddress: string,\n tokenInOutMarket: TokenInOutMarket,\n amountsInOutMaxFee: AmountsOutMaxFee\n ): Promise<TransactionReceipt> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n\n amountsInOutMaxFee.maxAmountIn = await this.amountToUnits(\n tokenInOutMarket.tokenIn,\n amountsInOutMaxFee.maxAmountIn\n )\n\n amountsInOutMaxFee.tokenAmountOut = await this.amountToUnits(\n tokenInOutMarket.tokenOut,\n amountsInOutMaxFee.tokenAmountOut\n )\n\n const estGas = await this.estSwapExactAmountOut(\n account,\n poolAddress,\n tokenInOutMarket,\n amountsInOutMaxFee\n )\n\n const maxPrice = amountsInOutMaxFee.maxPrice\n ? this.web3.utils.toWei(amountsInOutMaxFee.maxPrice)\n : MaxUint256\n\n try {\n result = await pool.methods\n .swapExactAmountOut(\n [\n tokenInOutMarket.tokenIn,\n tokenInOutMarket.tokenOut,\n tokenInOutMarket.marketFeeAddress\n ],\n [\n amountsInOutMaxFee.maxAmountIn,\n amountsInOutMaxFee.tokenAmountOut,\n maxPrice,\n this.web3.utils.toWei(amountsInOutMaxFee.swapMarketFee)\n ]\n )\n .send({\n from: account,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n this.logger.error(`ERROR: Failed to swap exact amount out: ${e.message}`)\n }\n return result\n }\n\n /**\n * Estimate gas cost for swapExactAmountOut\n * @param {String} address\n * @param {String} poolAddress\n * @param {String} poolAmountOut will be converted to wei\n * @param {String[]} maxAmountsIn array holding maxAmount per each token, will be converted to wei\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estJoinPool(\n address: string,\n poolAddress: string,\n poolAmountOut: string,\n maxAmountsIn: string[],\n contractInstance?: Contract\n ): Promise<number> {\n const poolContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi as AbiItem[], poolAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await poolContract.methods\n .joinPool(poolAmountOut, maxAmountsIn)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Join the pool, getting poolAmountOut pool tokens. This will pull some of each of the currently trading tokens in the pool, meaning you must have called approve for each token for this pool. These values are limited by the array of maxAmountsIn in the order of the pool tokens.\n * @param {String} address\n * @param {String} poolAddress\n * @param {String} poolAmountOut will be converted to wei\n * @param {String[]} maxAmountsIn array holding maxAmount per each token, will be converted to wei\n * @return {TransactionReceipt}\n */\n async joinPool(\n address: string,\n poolAddress: string,\n poolAmountOut: string,\n maxAmountsIn: string[]\n ): Promise<TransactionReceipt> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n const weiMaxAmountsIn = []\n const tokens = await this.getFinalTokens(poolAddress)\n\n for (let i = 0; i < 2; i++) {\n const amount = await this.amountToUnits(tokens[i], maxAmountsIn[i])\n weiMaxAmountsIn.push(amount)\n }\n\n let result = null\n\n const estGas = await this.estJoinPool(\n address,\n poolAddress,\n this.web3.utils.toWei(poolAmountOut),\n weiMaxAmountsIn\n )\n\n try {\n result = await pool.methods\n .joinPool(this.web3.utils.toWei(poolAmountOut), weiMaxAmountsIn)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n this.logger.error(`ERROR: Failed to join pool: ${e.message}`)\n }\n return result\n }\n\n /**\n * Estimate gas cost for exitPool\n* @param {String} address\n * @param {String} poolAddress\n ``* @param {String} poolAmountIn will be converted to wei\n * @param {String[]} minAmountsOut array holding minAmount per each token, will be converted to wei\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estExitPool(\n address: string,\n poolAddress: string,\n poolAmountIn: string,\n minAmountsOut: string[],\n contractInstance?: Contract\n ): Promise<number> {\n const poolContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi as AbiItem[], poolAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await poolContract.methods\n .exitPool(poolAmountIn, minAmountsOut)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Exit the pool, paying poolAmountIn pool tokens and getting some of each of the currently trading tokens in return. These values are limited by the array of minAmountsOut in the order of the pool tokens.\n * @param {String} account\n * @param {String} poolAddress\n * @param {String} poolAmountIn will be converted to wei\n * @param {String[]} minAmountsOut array holding minAmount per each token, will be converted to wei\n * @return {TransactionReceipt}\n */\n async exitPool(\n account: string,\n poolAddress: string,\n poolAmountIn: string,\n minAmountsOut: string[]\n ): Promise<TransactionReceipt> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n const weiMinAmountsOut = []\n const tokens = await this.getFinalTokens(poolAddress)\n\n for (let i = 0; i < 2; i++) {\n const amount = await this.amountToUnits(tokens[i], minAmountsOut[i])\n weiMinAmountsOut.push(amount)\n }\n let result = null\n const estGas = await this.estExitPool(\n account,\n poolAddress,\n this.web3.utils.toWei(poolAmountIn),\n weiMinAmountsOut\n )\n\n try {\n result = await pool.methods\n .exitPool(this.web3.utils.toWei(poolAmountIn), weiMinAmountsOut)\n .send({\n from: account,\n gas: estGas,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n this.logger.error(`ERROR: Failed to exit pool: ${e.message}`)\n }\n return result\n }\n\n /**\n * Estimate gas cost for joinswapExternAmountIn\n * @param {String} address\n * @param {String} poolAddress\n * @param {String} tokenIn\n * @param {String} tokenAmountIn will be converted to wei\n * @param {String} minPoolAmountOut will be converted to wei\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estJoinswapExternAmountIn(\n address: string,\n poolAddress: string,\n tokenIn: string,\n tokenAmountIn: string,\n minPoolAmountOut: string,\n contractInstance?: Contract\n ): Promise<number> {\n const poolContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi as AbiItem[], poolAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await poolContract.methods\n .joinswapExternAmountIn(tokenIn, tokenAmountIn, minPoolAmountOut)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Pay tokenAmountIn of token tokenIn to join the pool, getting poolAmountOut of the pool shares.\n * @param {String} account\n * @param {String} poolAddress\n * @param {String} tokenIn\n * @param {String} tokenAmountIn will be converted to wei\n * @param {String} minPoolAmountOut will be converted to wei\n * @return {TransactionReceipt}\n */\n async joinswapExternAmountIn(\n account: string,\n poolAddress: string,\n tokenIn: string,\n tokenAmountIn: string,\n minPoolAmountOut: string\n ): Promise<TransactionReceipt> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n\n const amountInFormatted = await this.amountToUnits(tokenIn, tokenAmountIn)\n const estGas = await this.estJoinswapExternAmountIn(\n account,\n poolAddress,\n tokenIn,\n amountInFormatted,\n this.web3.utils.toWei(minPoolAmountOut)\n )\n\n try {\n result = await pool.methods\n .joinswapExternAmountIn(\n tokenIn,\n amountInFormatted,\n this.web3.utils.toWei(minPoolAmountOut)\n )\n .send({\n from: account,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n this.logger.error(`ERROR: Failed to pay tokens in order to \\\n join the pool: ${e.message}`)\n }\n return result\n }\n\n /**\n * Estimate gas cost for joinswapPoolAmountOut\n * @param {String} address\n * @param {String} poolAddress\n * @param {String} tokenIn\n * @param {String} poolAmountOut will be converted to wei\n * @param {String} maxAmountIn will be converted to wei\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estJoinswapPoolAmountOut(\n address: string,\n poolAddress: string,\n tokenIn: string,\n poolAmountOut: string,\n maxAmountIn: string,\n contractInstance?: Contract\n ): Promise<number> {\n const poolContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi as AbiItem[], poolAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await poolContract.methods\n .joinswapPoolAmountOut(tokenIn, poolAmountOut, maxAmountIn)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Specify poolAmountOut pool shares that you want to get, and a token tokenIn to pay with. This costs tokenAmountIn tokens (these went into the pool).\n * @param {String} account\n * @param {String} poolAddress\n * @param {String} tokenIn\n * @param {String} poolAmountOut will be converted to wei\n * @param {String} maxAmountIn will be converted to wei\n * @return {TransactionReceipt}\n */\n async joinswapPoolAmountOut(\n account: string,\n poolAddress: string,\n tokenIn: string,\n poolAmountOut: string,\n maxAmountIn: string\n ): Promise<TransactionReceipt> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n\n const maxAmountInFormatted = await this.amountToUnits(tokenIn, maxAmountIn)\n const estGas = await this.estJoinswapPoolAmountOut(\n account,\n poolAddress,\n tokenIn,\n this.web3.utils.toWei(poolAmountOut),\n maxAmountInFormatted\n )\n\n try {\n result = await pool.methods\n .joinswapPoolAmountOut(\n tokenIn,\n this.web3.utils.toWei(poolAmountOut),\n maxAmountInFormatted\n )\n .send({\n from: account,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n this.logger.error('ERROR: Failed to join swap pool amount out')\n }\n return result\n }\n\n /**\n * Estimate gas cost for joinswapExternAmountIn\n * @param {String} address\n @param {String} poolAddress\n * @param {String} tokenOut\n * @param {String} poolAmountIn will be converted to wei\n * @param {String} minTokenAmountOut will be converted to wei\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estExitswapPoolAmountIn(\n address: string,\n poolAddress: string,\n tokenOut: string,\n poolAmountIn: string,\n minTokenAmountOut: string,\n contractInstance?: Contract\n ): Promise<number> {\n const poolContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi as AbiItem[], poolAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await poolContract.methods\n .exitswapPoolAmountIn(tokenOut, poolAmountIn, minTokenAmountOut)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Pay poolAmountIn pool shares into the pool, getting minTokenAmountOut of the given token tokenOut out of the pool.\n * @param {String} account\n * @param {String} poolAddress\n * @param {String} tokenOut\n * @param {String} poolAmountIn will be converted to wei\n * @param {String} minTokenAmountOut will be converted to wei\n * @return {TransactionReceipt}\n */\n async exitswapPoolAmountIn(\n account: string,\n poolAddress: string,\n tokenOut: string,\n poolAmountIn: string,\n minTokenAmountOut: string\n ): Promise<TransactionReceipt> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n\n const minTokenOutFormatted = await this.amountToUnits(tokenOut, minTokenAmountOut)\n const estGas = await this.estExitswapPoolAmountIn(\n account,\n poolAddress,\n tokenOut,\n this.web3.utils.toWei(poolAmountIn),\n minTokenOutFormatted\n )\n\n try {\n result = await pool.methods\n .exitswapPoolAmountIn(\n tokenOut,\n this.web3.utils.toWei(poolAmountIn),\n minTokenOutFormatted\n )\n .send({\n from: account,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n this.logger.error(`ERROR: Failed to pay pool shares into the pool: ${e.message}`)\n }\n return result\n }\n\n /**\n * Estimate gas cost for joinswapExternAmountIn\n * @param {String} address\n * @param {String} poolAddress\n * @param {String} tokenOut\n * @param {String} tokenAmountOut will be converted to wei\n * @param {String} maxPoolAmountIn will be converted to wei\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estExitswapExternAmountOut(\n address: string,\n poolAddress: string,\n tokenOut: string,\n tokenAmountOut: string,\n maxPoolAmountIn: string,\n contractInstance?: Contract\n ): Promise<number> {\n const poolContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi as AbiItem[], poolAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await poolContract.methods\n .exitswapExternAmountOut(tokenOut, tokenAmountOut, maxPoolAmountIn)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Specify tokenAmountOut of token tokenOut that you want to get out of the pool. This costs poolAmountIn pool shares (these went into the pool).\n * @param {String} account\n * @param {String} poolAddress\n * @param {String} tokenOut\n * @param {String} tokenAmountOut will be converted to wei\n * @param {String} maxPoolAmountIn will be converted to wei\n * @return {TransactionReceipt}\n */\n async exitswapExternAmountOut(\n account: string,\n poolAddress: string,\n tokenOut: string,\n tokenAmountOut: string,\n maxPoolAmountIn: string\n ): Promise<TransactionReceipt> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n\n const estGas = await this.estExitswapExternAmountOut(\n account,\n poolAddress,\n tokenOut,\n this.web3.utils.toWei(tokenAmountOut),\n this.web3.utils.toWei(maxPoolAmountIn)\n )\n\n try {\n result = await pool.methods\n .exitswapExternAmountOut(\n tokenOut,\n this.web3.utils.toWei(tokenAmountOut),\n this.web3.utils.toWei(maxPoolAmountIn)\n )\n .send({\n from: account,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n this.logger.error('ERROR: Failed to exitswapExternAmountOut')\n }\n return result\n }\n\n /**\n * Get Spot Price of swaping tokenIn to tokenOut\n * @param {String} poolAddress\n * @param {String} tokenIn\n * @param {String} tokenOut\n * @param {String} swapMarketFe\n * @return {String}\n */\n async getSpotPrice(\n poolAddress: string,\n tokenIn: string,\n tokenOut: string,\n swapMarketFee: string\n ): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let decimalsTokenIn = 18\n let decimalsTokenOut = 18\n\n const tokenInContract = setContractDefaults(\n new this.web3.eth.Contract(defaultErc20Abi.abi as AbiItem[], tokenIn),\n this.config\n )\n const tokenOutContract = setContractDefaults(\n new this.web3.eth.Contract(defaultErc20Abi.abi as AbiItem[], tokenOut),\n this.config\n )\n try {\n decimalsTokenIn = await tokenInContract.methods.decimals().call()\n } catch (e) {\n this.logger.error('ERROR: FAILED TO CALL DECIMALS(), USING 18')\n }\n try {\n decimalsTokenOut = await tokenOutContract.methods.decimals().call()\n } catch (e) {\n this.logger.error('ERROR: FAILED TO CALL DECIMALS(), USING 18')\n }\n\n let price = null\n try {\n price = await pool.methods\n .getSpotPrice(tokenIn, tokenOut, this.web3.utils.toWei(swapMarketFee))\n .call()\n price = new BigNumber(price.toString())\n } catch (e) {\n this.logger.error('ERROR: Failed to get spot price of swapping tokenIn to tokenOut')\n }\n\n let decimalsDiff\n if (decimalsTokenIn > decimalsTokenOut) {\n decimalsDiff = decimalsTokenIn - decimalsTokenOut\n price = new BigNumber(price / 10 ** decimalsDiff)\n price = price / 10 ** decimalsTokenOut\n } else {\n decimalsDiff = decimalsTokenOut - decimalsTokenIn\n price = new BigNumber(price * 10 ** (2 * decimalsDiff))\n price = price / 10 ** decimalsTokenOut\n }\n\n return price.toString()\n }\n\n public async getAmountInExactOut(\n poolAddress: string,\n tokenIn: string,\n tokenOut: string,\n tokenAmountOut: string,\n swapMarketFee: string\n ): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n\n const amountOutFormatted = await this.amountToUnits(tokenOut, tokenAmountOut)\n\n let amount = null\n\n try {\n const result = await pool.methods\n .getAmountInExactOut(\n tokenIn,\n tokenOut,\n amountOutFormatted,\n this.web3.utils.toWei(swapMarketFee)\n )\n .call()\n amount = await this.unitsToAmount(tokenIn, result)\n } catch (e) {\n this.logger.error('ERROR: Failed to calcInGivenOut')\n }\n return amount\n }\n\n public async getAmountOutExactIn(\n poolAddress: string,\n tokenIn: string,\n tokenOut: string,\n tokenAmountIn: string,\n swapMarketFee: string\n ): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n\n const amountInFormatted = await this.amountToUnits(tokenIn, tokenAmountIn)\n\n let amount = null\n\n try {\n const result = await pool.methods\n .getAmountOutExactIn(\n tokenIn,\n tokenOut,\n amountInFormatted,\n this.web3.utils.toWei(swapMarketFee)\n )\n .call()\n\n amount = await this.unitsToAmount(tokenOut, result)\n } catch (e) {\n this.logger.error('ERROR: Failed to calcOutGivenIn')\n }\n return amount\n }\n\n public async calcPoolOutGivenSingleIn(\n poolAddress: string,\n tokenIn: string,\n tokenAmountIn: string\n ): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let amount = null\n\n try {\n const result = await pool.methods\n .calcPoolOutSingleIn(tokenIn, await this.amountToUnits(tokenIn, tokenAmountIn))\n .call()\n\n amount = await this.unitsToAmount(poolAddress, result)\n } catch (e) {\n this.logger.error(`ERROR: Failed to calculate PoolOutGivenSingleIn : ${e.message}`)\n }\n return amount\n }\n\n public async calcSingleInGivenPoolOut(\n poolAddress: string,\n tokenIn: string,\n poolAmountOut: string\n ): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let amount = null\n const amountFormatted = await this.amountToUnits(poolAddress, poolAmountOut)\n try {\n const result = await pool.methods\n .calcSingleInPoolOut(tokenIn, amountFormatted)\n\n .call()\n\n amount = await this.unitsToAmount(tokenIn, result)\n } catch (e) {\n this.logger.error(`ERROR: Failed to calculate SingleInGivenPoolOut : ${e.message}`)\n }\n return amount\n }\n\n public async calcSingleOutGivenPoolIn(\n poolAddress: string,\n tokenOut: string,\n poolAmountIn: string\n ): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let amount = null\n\n try {\n const result = await pool.methods\n .calcSingleOutPoolIn(\n tokenOut,\n await this.amountToUnits(poolAddress, poolAmountIn)\n )\n .call()\n amount = await this.unitsToAmount(tokenOut, result)\n } catch (e) {\n this.logger.error(`ERROR: Failed to calculate SingleOutGivenPoolIn : ${e}`)\n }\n return amount\n }\n\n public async calcPoolInGivenSingleOut(\n poolAddress: string,\n tokenOut: string,\n tokenAmountOut: string\n ): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let amount = null\n\n try {\n const result = await pool.methods\n .calcPoolInSingleOut(tokenOut, await this.amountToUnits(tokenOut, tokenAmountOut))\n .call()\n\n amount = await this.unitsToAmount(poolAddress, result)\n } catch (e) {\n this.logger.error(`ERROR: Failed to calculate PoolInGivenSingleOut : ${e.message}`)\n }\n return amount\n }\n\n /**\n * Get LOG_SWAP encoded topic\n * @return {String}\n */\n public getSwapEventSignature(): string {\n const abi = this.poolAbi as AbiItem[]\n const eventdata = abi.find(function (o) {\n if (o.name === 'LOG_SWAP' && o.type === 'event') return o\n })\n const topic = this.web3.eth.abi.encodeEventSignature(eventdata as any)\n return topic\n }\n\n /**\n * Get LOG_JOIN encoded topic\n * @return {String}\n */\n public getJoinEventSignature(): string {\n const abi = this.poolAbi as AbiItem[]\n const eventdata = abi.find(function (o) {\n if (o.name === 'LOG_JOIN' && o.type === 'event') return o\n })\n const topic = this.web3.eth.abi.encodeEventSignature(eventdata as any)\n return topic\n }\n\n /**\n * Get LOG_EXIT encoded topic\n * @return {String}\n */\n public getExitEventSignature(): string {\n const abi = this.poolAbi as AbiItem[]\n const eventdata = abi.find(function (o) {\n if (o.name === 'LOG_EXIT' && o.type === 'event') return o\n })\n const topic = this.web3.eth.abi.encodeEventSignature(eventdata as any)\n return topic\n }\n}\n","import Web3 from 'web3'\nimport { AbiItem } from 'web3-utils'\nimport { Contract } from 'web3-eth-contract'\nimport { TransactionReceipt } from 'web3-eth'\nimport Decimal from 'decimal.js'\nimport defaultDispenserAbi from '@oceanprotocol/contracts/artifacts/contracts/pools/dispenser/Dispenser.sol/Dispenser.json'\nimport {\n LoggerInstance as logger,\n getFairGasPrice,\n configHelperNetworks,\n setContractDefaults\n} from '../../utils/'\nimport { Datatoken } from '../../tokens'\nimport { Config } from '../../models/index.js'\n\nexport interface DispenserToken {\n active: boolean\n owner: string\n maxTokens: string\n maxBalance: string\n balance: string\n isMinter: boolean\n allowedSwapper: string\n}\n\nexport class Dispenser {\n public GASLIMIT_DEFAULT = 1000000\n public web3: Web3 = null\n public dispenserAddress: string\n public config: Config\n public dispenserAbi: AbiItem | AbiItem[]\n public dispenserContract: Contract\n\n /**\n * Instantiate Dispenser\n * @param {any} web3\n * @param {String} dispenserAddress\n * @param {any} dispenserABI\n */\n constructor(\n web3: Web3,\n dispenserAddress: string = null,\n dispenserAbi: AbiItem | AbiItem[] = null,\n config?: Config\n ) {\n this.web3 = web3\n this.dispenserAddress = dispenserAddress\n this.dispenserAbi = dispenserAbi || (defaultDispenserAbi.abi as AbiItem[])\n this.config = config || configHelperNetworks[0]\n if (web3)\n this.dispenserContract = setContractDefaults(\n new this.web3.eth.Contract(this.dispenserAbi, this.dispenserAddress),\n this.config\n )\n }\n\n /**\n * Get information about a datatoken dispenser\n * @param {String} dtAddress\n * @return {Promise<FixedPricedExchange>} Exchange details\n */\n public async status(dtAdress: string): Promise<DispenserToken> {\n try {\n const result: DispenserToken = await this.dispenserContract.methods\n .status(dtAdress)\n .call()\n result.maxTokens = this.web3.utils.fromWei(result.maxTokens)\n result.maxBalance = this.web3.utils.fromWei(result.maxBalance)\n result.balance = this.web3.utils.fromWei(result.balance)\n return result\n } catch (e) {\n logger.warn(`No dispenser available for datatoken: ${dtAdress}`)\n }\n return null\n }\n\n /**\n * Estimate gas cost for create method\n * @param {String} dtAddress Datatoken address\n * @param {String} address Owner address\n * @param {String} maxTokens max tokens to dispense\n * @param {String} maxBalance max balance of requester\n * @param {String} allowedSwapper if !=0, only this address can request DTs\n * @return {Promise<any>}\n */\n public async estGasCreate(\n dtAddress: string,\n address: string,\n maxTokens: string,\n maxBalance: string,\n allowedSwapper: string\n ): Promise<any> {\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await this.dispenserContract.methods\n .create(\n dtAddress,\n this.web3.utils.toWei(maxTokens),\n this.web3.utils.toWei(maxBalance),\n address,\n allowedSwapper\n )\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * Creates a new Dispenser\n * @param {String} dtAddress Datatoken address\n * @param {String} address Owner address\n * @param {String} maxTokens max tokens to dispense\n * @param {String} maxBalance max balance of requester\n * @param {String} allowedSwapper only account that can ask tokens. set address(0) if not required\n * @return {Promise<TransactionReceipt>} transactionId\n */\n public async create(\n dtAddress: string,\n address: string,\n maxTokens: string,\n maxBalance: string,\n allowedSwapper: string\n ): Promise<TransactionReceipt> {\n const estGas = await this.estGasCreate(\n dtAddress,\n address,\n maxTokens,\n maxBalance,\n allowedSwapper\n )\n\n // Call createFixedRate contract method\n const trxReceipt = await this.dispenserContract.methods\n .create(\n dtAddress,\n this.web3.utils.toWei(maxTokens),\n this.web3.utils.toWei(maxBalance),\n address,\n allowedSwapper\n )\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n\n /**\n * Estimate gas for activate method\n * @param {String} dtAddress\n * @param {Number} maxTokens max amount of tokens to dispense\n * @param {Number} maxBalance max balance of user. If user balance is >, then dispense will be rejected\n * @param {String} address User address (must be owner of the datatoken)\n * @return {Promise<any>}\n */\n public async estGasActivate(\n dtAddress: string,\n maxTokens: string,\n maxBalance: string,\n address: string\n ): Promise<any> {\n let estGas\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n try {\n estGas = await this.dispenserContract.methods\n .activate(\n dtAddress,\n this.web3.utils.toWei(maxTokens),\n this.web3.utils.toWei(maxBalance)\n )\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Activates a new dispener.\n * @param {String} dtAddress refers to datatoken address.\n * @param {Number} maxTokens max amount of tokens to dispense\n * @param {Number} maxBalance max balance of user. If user balance is >, then dispense will be rejected\n * @param {String} address User address (must be owner of the datatoken)\n * @return {Promise<TransactionReceipt>} TransactionReceipt\n */\n public async activate(\n dtAddress: string,\n maxTokens: string,\n maxBalance: string,\n address: string\n ): Promise<TransactionReceipt> {\n try {\n const estGas = await this.estGasActivate(dtAddress, maxTokens, maxBalance, address)\n const trxReceipt = await this.dispenserContract.methods\n .activate(\n dtAddress,\n this.web3.utils.toWei(maxTokens),\n this.web3.utils.toWei(maxBalance)\n )\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n } catch (e) {\n logger.error(`ERROR: Failed to activate dispenser: ${e.message}`)\n }\n return null\n }\n\n /**\n * Estimate gas for deactivate method\n * @param {String} dtAddress\n * @param {String} address User address (must be owner of the datatoken)\n * @return {Promise<any>}\n */\n public async estGasDeactivate(dtAddress: string, address: string): Promise<any> {\n let estGas\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n try {\n estGas = await this.dispenserContract.methods\n .deactivate(dtAddress)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Deactivate an existing dispenser.\n * @param {String} dtAddress refers to datatoken address.\n * @param {String} address User address (must be owner of the datatoken)\n * @return {Promise<TransactionReceipt>} TransactionReceipt\n */\n public async deactivate(\n dtAddress: string,\n address: string\n ): Promise<TransactionReceipt> {\n try {\n const estGas = await this.estGasDeactivate(dtAddress, address)\n const trxReceipt = await this.dispenserContract.methods.deactivate(dtAddress).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n } catch (e) {\n logger.error(`ERROR: Failed to activate dispenser: ${e.message}`)\n }\n return null\n }\n\n /**\n * Estimate gas for setAllowedSwapper method\n * @param {String} dtAddress refers to datatoken address.\n * @param {String} address User address (must be owner of the datatoken)\n * @param {String} newAllowedSwapper refers to the new allowedSwapper\n * @return {Promise<any>}\n */\n public async estGasSetAllowedSwapper(\n dtAddress: string,\n address: string,\n newAllowedSwapper: string\n ): Promise<any> {\n let estGas\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n try {\n estGas = await this.dispenserContract.methods\n .setAllowedSwapper(dtAddress, newAllowedSwapper)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Sets a new allowedSwapper.\n * @param {String} dtAddress refers to datatoken address.\n * @param {String} address User address (must be owner of the datatoken)\n * @param {String} newAllowedSwapper refers to the new allowedSwapper\n * @return {Promise<TransactionReceipt>} TransactionReceipt\n */\n public async setAllowedSwapper(\n dtAddress: string,\n address: string,\n newAllowedSwapper: string\n ): Promise<TransactionReceipt> {\n try {\n const estGas = await this.estGasSetAllowedSwapper(\n dtAddress,\n address,\n newAllowedSwapper\n )\n const trxReceipt = await this.dispenserContract.methods\n .setAllowedSwapper(dtAddress, newAllowedSwapper)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n } catch (e) {\n logger.error(`ERROR: Failed to activate dispenser: ${e.message}`)\n }\n return null\n }\n\n /**\n * Estimate gas for dispense method\n * @param {String} dtAddress refers to datatoken address.\n * @param {String} address User address (must be owner of the datatoken)\n * @param {String} newAllowedSwapper refers to the new allowedSwapper\n * @return {Promise<any>}\n */\n public async estGasDispense(\n dtAddress: string,\n address: string,\n amount: string = '1',\n destination: string\n ): Promise<any> {\n let estGas\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n try {\n estGas = await this.dispenserContract.methods\n .dispense(dtAddress, this.web3.utils.toWei(amount), destination)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Dispense datatokens to caller.\n * The dispenser must be active, hold enough DT (or be able to mint more)\n * and respect maxTokens/maxBalance requirements\n * @param {String} dtAddress refers to datatoken address.\n * @param {String} address User address\n * @param {String} amount amount of datatokens required.\n * @param {String} destination who will receive the tokens\n * @return {Promise<TransactionReceipt>} TransactionReceipt\n */\n public async dispense(\n dtAddress: string,\n address: string,\n amount: string = '1',\n destination: string\n ): Promise<TransactionReceipt> {\n const estGas = await this.estGasDispense(dtAddress, address, amount, destination)\n try {\n const trxReceipt = await this.dispenserContract.methods\n .dispense(dtAddress, this.web3.utils.toWei(amount), destination)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n } catch (e) {\n logger.error(`ERROR: Failed to dispense tokens: ${e.message}`)\n }\n return null\n }\n\n /**\n * Estimate gas for ownerWithdraw method\n * @param {String} dtAddress refers to datatoken address.\n * @param {String} address User address (must be owner of the datatoken)\n * @param {String} newAllowedSwapper refers to the new allowedSwapper\n * @return {Promise<any>}\n */\n public async estGasOwnerWithdraw(dtAddress: string, address: string): Promise<any> {\n let estGas\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n try {\n estGas = await this.dispenserContract.methods\n .ownerWithdraw(dtAddress)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Withdraw all tokens from the dispenser\n * @param {String} dtAddress refers to datatoken address.\n * @param {String} address User address (must be owner of the dispenser)\n * @return {Promise<TransactionReceipt>} TransactionReceipt\n */\n public async ownerWithdraw(\n dtAddress: string,\n address: string\n ): Promise<TransactionReceipt> {\n const estGas = await this.estGasOwnerWithdraw(dtAddress, address)\n try {\n const trxReceipt = await this.dispenserContract.methods\n .ownerWithdraw(dtAddress)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n } catch (e) {\n logger.error(`ERROR: Failed to withdraw tokens: ${e.message}`)\n }\n return null\n }\n\n /**\n * Check if tokens can be dispensed\n * @param {String} dtAddress\n * @param {String} address User address that will receive datatokens\n * @param {String} amount amount of datatokens required.\n * @return {Promise<Boolean>}\n */\n public async isDispensable(\n dtAddress: string,\n datatoken: Datatoken,\n address: string,\n amount: string = '1'\n ): Promise<Boolean> {\n const status = await this.status(dtAddress)\n if (!status) return false\n // check active\n if (status.active === false) return false\n // check maxBalance\n const userBalance = new Decimal(await datatoken.balance(dtAddress, address))\n if (userBalance.greaterThanOrEqualTo(status.maxBalance)) return false\n // check maxAmount\n if (new Decimal(String(amount)).greaterThan(status.maxTokens)) return false\n // check dispenser balance\n const contractBalance = new Decimal(status.balance)\n if (contractBalance.greaterThanOrEqualTo(amount) || status.isMinter === true)\n return true\n return false\n }\n}\n","import defaultFixedRateExchangeAbi from '@oceanprotocol/contracts/artifacts/contracts/pools/fixedRate/FixedRateExchange.sol/FixedRateExchange.json'\nimport defaultErc20Abi from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json'\nimport BigNumber from 'bignumber.js'\nimport { TransactionReceipt } from 'web3-core'\nimport { Contract } from 'web3-eth-contract'\nimport { AbiItem } from 'web3-utils/types'\nimport Web3 from 'web3'\nimport {\n LoggerInstance,\n getFairGasPrice,\n configHelperNetworks,\n setContractDefaults\n} from '../../utils'\nimport { Config } from '../../models/index.js'\n\nexport interface FixedPriceExchange {\n active: boolean\n exchangeOwner: string\n datatoken: string\n baseToken: string\n fixedRate: string\n dtDecimals: string\n btDecimals: string\n dtBalance: string\n btBalance: string\n dtSupply: string\n btSupply: string\n withMint: boolean\n allowedSwapper: string\n exchangeId?: string\n}\n\nexport interface FeesInfo {\n opfFee: string\n marketFee: string\n marketFeeCollector: string\n marketFeeAvailable: string\n oceanFeeAvailable: string\n exchangeId: string\n}\nexport interface FixedPriceSwap {\n exchangeId: string\n caller: string\n baseTokenAmount: string\n datatokenAmount: string\n}\n\nexport enum FixedRateCreateProgressStep {\n CreatingExchange,\n ApprovingDatatoken\n}\n\nexport class FixedRateExchange {\n public GASLIMIT_DEFAULT = 1000000\n /** Ocean related functions */\n public oceanAddress: string = null\n public fixedRateAddress: string\n public fixedRateExchangeAbi: AbiItem | AbiItem[]\n public fixedRateContract: Contract\n public web3: Web3\n public contract: Contract = null\n\n public config: Config\n public ssAbi: AbiItem | AbiItem[]\n\n /**\n * Instantiate FixedRateExchange\n * @param {any} web3\n * @param {any} fixedRateExchangeAbi\n */\n constructor(\n web3: Web3,\n fixedRateAddress: string,\n fixedRateExchangeAbi: AbiItem | AbiItem[] = null,\n oceanAddress: string = null,\n config?: Config\n ) {\n this.web3 = web3\n this.config = config || configHelperNetworks[0]\n this.fixedRateExchangeAbi =\n fixedRateExchangeAbi || (defaultFixedRateExchangeAbi.abi as AbiItem[])\n this.oceanAddress = oceanAddress\n this.fixedRateAddress = fixedRateAddress\n this.contract = setContractDefaults(\n new this.web3.eth.Contract(this.fixedRateExchangeAbi, this.fixedRateAddress),\n this.config\n )\n }\n\n async amountToUnits(token: string, amount: string): Promise<string> {\n let decimals = 18\n const tokenContract = setContractDefaults(\n new this.web3.eth.Contract(defaultErc20Abi.abi as AbiItem[], token),\n this.config\n )\n\n try {\n decimals = await tokenContract.methods.decimals().call()\n } catch (e) {\n LoggerInstance.error('ERROR: FAILED TO CALL DECIMALS(), USING 18')\n }\n\n const amountFormatted = new BigNumber(parseInt(amount) * 10 ** decimals)\n\n return amountFormatted.toString()\n }\n\n async unitsToAmount(token: string, amount: string): Promise<string> {\n let decimals = 18\n const tokenContract = setContractDefaults(\n new this.web3.eth.Contract(defaultErc20Abi.abi as AbiItem[], token),\n this.config\n )\n try {\n decimals = await tokenContract.methods.decimals().call()\n } catch (e) {\n LoggerInstance.error('ERROR: FAILED TO CALL DECIMALS(), USING 18')\n }\n\n const amountFormatted = new BigNumber(parseInt(amount) / 10 ** decimals)\n\n return amountFormatted.toString()\n }\n\n /**\n * Creates unique exchange identifier.\n * @param {String} datatoken Datatoken contract address\n * @param {String} owner Owner of the exchange\n * @return {Promise<string>} exchangeId\n */\n public async generateExchangeId(\n baseToken: string,\n datatoken: string,\n owner: string\n ): Promise<string> {\n const exchangeId = await this.contract.methods\n .generateExchangeId(baseToken, datatoken, owner)\n .call()\n return exchangeId\n }\n\n /**\n * Estimate gas cost for buyDT\n * @param {String} account\n * @param {String} dtAmount datatoken amount we want to buy\n * @param {String} datatokenAddress datatokenAddress\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estBuyDT(\n account: string,\n datatokenAddress: string,\n dtAmount: string,\n maxBaseTokenAmount: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await fixedRate.methods\n .buyDT(datatokenAddress, dtAmount.toString(), maxBaseTokenAmount.toString())\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Atomic swap\n * @param {String} exchangeId ExchangeId\n * @param {String} datatokenAmount Amount of datatokens\n * @param {String} maxBaseTokenAmount max amount of baseToken we want to pay for datatokenAmount\n * @param {String} address User address\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async buyDT(\n address: string,\n exchangeId: string,\n datatokenAmount: string,\n maxBaseTokenAmount: string\n ): Promise<TransactionReceipt> {\n const dtAmountFormatted = await this.amountToUnits(\n (\n await this.getExchange(exchangeId)\n ).datatoken,\n datatokenAmount\n )\n const maxBtFormatted = await this.amountToUnits(\n (\n await this.getExchange(exchangeId)\n ).baseToken,\n maxBaseTokenAmount\n )\n\n const estGas = await this.estBuyDT(\n address,\n exchangeId,\n dtAmountFormatted,\n maxBtFormatted\n )\n try {\n const trxReceipt = await this.contract.methods\n .buyDT(exchangeId, dtAmountFormatted, maxBtFormatted)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to buy datatokens: ${e.message}`)\n return null\n }\n }\n\n /**\n * Estimate gas cost for sellDT\n * @param {String} account\n * @param {String} dtAmount datatoken amount we want to sell\n * @param {String} datatokenAddress datatokenAddress\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estSellDT(\n account: string,\n datatokenAddress: string,\n dtAmount: string,\n maxBaseTokenAmount: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await fixedRate.methods\n .sellDT(datatokenAddress, dtAmount, maxBaseTokenAmount)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Atomic swap\n * @param {String} exchangeId ExchangeId\n * @param {String} datatokenAmount Amount of datatokens\n * @param {String} minBaseTokenAmount min amount of baseToken we want to receive back\n * @param {String} address User address\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async sellDT(\n address: string,\n exchangeId: string,\n datatokenAmount: string,\n minBaseTokenAmount: string\n ): Promise<TransactionReceipt> {\n const dtAmountFormatted = await this.amountToUnits(\n (\n await this.getExchange(exchangeId)\n ).datatoken,\n datatokenAmount\n )\n const minBtFormatted = await this.amountToUnits(\n (\n await this.getExchange(exchangeId)\n ).baseToken,\n minBaseTokenAmount\n )\n const estGas = await this.estBuyDT(\n address,\n exchangeId,\n dtAmountFormatted,\n minBtFormatted\n )\n try {\n const trxReceipt = await this.contract.methods\n .sellDT(exchangeId, dtAmountFormatted, minBtFormatted)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to sell datatokens: ${e.message}`)\n return null\n }\n }\n\n /**\n * Gets total number of exchanges\n * @param {String} exchangeId ExchangeId\n * @param {Number} datatokenAmount Amount of datatokens\n * @return {Promise<Number>} no of available exchanges\n */\n public async getNumberOfExchanges(): Promise<number> {\n const numExchanges = await this.contract.methods.getNumberOfExchanges().call()\n return numExchanges\n }\n\n /**\n * Estimate gas cost for setRate\n * @param {String} account\n * @param {String} exchangeId ExchangeId\n * @param {Number} newRate New rate\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estSetRate(\n account: string,\n exchangeId: string,\n newRate: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await fixedRate.methods\n .setRate(exchangeId, newRate)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Set new rate\n * @param {String} exchangeId ExchangeId\n * @param {Number} newRate New rate\n * @param {String} address User account\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async setRate(\n address: string,\n exchangeId: string,\n newRate: string\n ): Promise<TransactionReceipt> {\n const estGas = await this.estSetRate(\n address,\n exchangeId,\n this.web3.utils.toWei(String(newRate))\n )\n const trxReceipt = await this.contract.methods\n .setRate(exchangeId, this.web3.utils.toWei(newRate))\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for setRate\n * @param {String} account\n * @param {String} exchangeId ExchangeId\n * @param {String} newAllowedSwapper new allowed swapper address\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estSetAllowedSwapper(\n account: string,\n exchangeId: string,\n newAllowedSwapper: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await fixedRate.methods\n .setRate(exchangeId, newAllowedSwapper)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Set new rate\n * @param {String} exchangeId ExchangeId\n * @param {String} newAllowedSwapper newAllowedSwapper (set address zero if we want to remove allowed swapper)\n * @param {String} address User account\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async setAllowedSwapper(\n address: string,\n exchangeId: string,\n newAllowedSwapper: string\n ): Promise<TransactionReceipt> {\n const estGas = await this.estSetAllowedSwapper(address, exchangeId, newAllowedSwapper)\n const trxReceipt = await this.contract.methods\n .setAllowedSwapper(exchangeId, newAllowedSwapper)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for activate\n * @param {String} account\n * @param {String} exchangeId ExchangeId\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estActivate(\n account: string,\n exchangeId: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await fixedRate.methods\n .toggleExchangeState(exchangeId)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Activate an exchange\n * @param {String} exchangeId ExchangeId\n * @param {String} address User address\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async activate(\n address: string,\n exchangeId: string\n ): Promise<TransactionReceipt> {\n const exchange = await this.getExchange(exchangeId)\n if (!exchange) return null\n if (exchange.active === true) return null\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n\n const estGas = await this.estActivate(address, exchangeId)\n const trxReceipt = await this.contract.methods.toggleExchangeState(exchangeId).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for deactivate\n * @param {String} account\n * @param {String} exchangeId ExchangeId\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estDeactivate(\n account: string,\n exchangeId: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await fixedRate.methods\n .toggleExchangeState(exchangeId)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Deactivate an exchange\n * @param {String} exchangeId ExchangeId\n * @param {String} address User address\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async deactivate(\n address: string,\n exchangeId: string\n ): Promise<TransactionReceipt> {\n const exchange = await this.getExchange(exchangeId)\n if (!exchange) return null\n if (exchange.active === false) return null\n\n const estGas = await this.estDeactivate(address, exchangeId)\n\n const trxReceipt = await this.contract.methods.toggleExchangeState(exchangeId).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Get Rate\n * @param {String} exchangeId ExchangeId\n * @return {Promise<string>} Rate (converted from wei)\n */\n public async getRate(exchangeId: string): Promise<string> {\n const weiRate = await this.contract.methods.getRate(exchangeId).call()\n return this.web3.utils.fromWei(weiRate)\n }\n\n /**\n * Get Datatoken Supply in the exchange\n * @param {String} exchangeId ExchangeId\n * @return {Promise<string>} dt supply formatted\n */\n public async getDTSupply(exchangeId: string): Promise<string> {\n const dtSupply = await this.contract.methods.getDTSupply(exchangeId).call()\n return await this.unitsToAmount(\n (\n await this.getExchange(exchangeId)\n ).datatoken,\n dtSupply\n )\n }\n\n /**\n * Get BaseToken Supply in the exchange\n * @param {String} exchangeId ExchangeId\n * @return {Promise<string>} dt supply formatted\n */\n public async getBTSupply(exchangeId: string): Promise<string> {\n const btSupply = await this.contract.methods.getBTSupply(exchangeId).call()\n return await this.unitsToAmount(\n (\n await this.getExchange(exchangeId)\n ).baseToken,\n btSupply\n )\n }\n\n /**\n * Get Allower Swapper (if set this is the only account which can use this exchange, else is set at address(0))\n * @param {String} exchangeId ExchangeId\n * @return {Promise<string>} address of allowedSwapper\n */\n public async getAllowedSwapper(exchangeId: string): Promise<string> {\n return await this.contract.methods.getAllowedSwapper(exchangeId).call()\n }\n\n /**\n * getBTNeeded - returns amount in baseToken that user will pay for datatokenAmount\n * @param {String} exchangeId ExchangeId\n * @param {Number} datatokenAmount Amount of datatokens user wants to buy\n * @return {Promise<string>} Amount of baseToken needed for buying\n */\n public async getAmountBTIn(\n exchangeId: string,\n datatokenAmount: string\n ): Promise<string> {\n const result = await this.contract.methods\n .calcBaseInGivenOutDT(\n exchangeId,\n await this.amountToUnits(\n (\n await this.getExchange(exchangeId)\n ).datatoken,\n datatokenAmount\n )\n )\n .call()\n\n return await this.unitsToAmount(\n (\n await this.getExchange(exchangeId)\n ).baseToken,\n result.baseTokenAmount\n )\n }\n\n /**\n * getBTOut - returns amount in baseToken that user will receive for datatokenAmount sold\n * @param {String} exchangeId ExchangeId\n * @param {Number} datatokenAmount Amount of datatokens\n * @return {Promise<string>} Amount of baseTokens user will receive\n */\n public async getAmountBTOut(\n exchangeId: string,\n datatokenAmount: string\n ): Promise<string> {\n const result = await this.contract.methods\n .calcBaseOutGivenInDT(\n exchangeId,\n await this.amountToUnits(\n (\n await this.getExchange(exchangeId)\n ).datatoken,\n datatokenAmount\n )\n )\n .call()\n\n return await this.unitsToAmount(\n (\n await this.getExchange(exchangeId)\n ).baseToken,\n result.baseTokenAmount\n )\n }\n\n /**\n * Get exchange details\n * @param {String} exchangeId ExchangeId\n * @return {Promise<FixedPricedExchange>} Exchange details\n */\n public async getExchange(exchangeId: string): Promise<FixedPriceExchange> {\n const result: FixedPriceExchange = await this.contract.methods\n .getExchange(exchangeId)\n .call()\n result.dtDecimals = result.dtDecimals.toString()\n result.btDecimals = result.btDecimals.toString()\n result.dtBalance = await this.unitsToAmount(result.datatoken, result.dtBalance)\n result.btBalance = await this.unitsToAmount(result.baseToken, result.btBalance)\n result.dtSupply = await this.unitsToAmount(result.datatoken, result.dtSupply)\n result.btSupply = await this.unitsToAmount(result.baseToken, result.btSupply)\n result.fixedRate = this.web3.utils.fromWei(result.fixedRate)\n result.exchangeId = exchangeId\n return result\n }\n\n /**\n * Get fee details for an exchange\n * @param {String} exchangeId ExchangeId\n * @return {Promise<FixedPricedExchange>} Exchange details\n */\n public async getFeesInfo(exchangeId: string): Promise<FeesInfo> {\n const result: FeesInfo = await this.contract.methods.getFeesInfo(exchangeId).call()\n result.opfFee = this.web3.utils.fromWei(result.opfFee.toString())\n result.marketFee = this.web3.utils.fromWei(result.marketFee.toString())\n\n result.marketFeeAvailable = await this.unitsToAmount(\n (\n await this.getExchange(exchangeId)\n ).baseToken,\n result.marketFeeAvailable\n )\n result.oceanFeeAvailable = await this.unitsToAmount(\n (\n await this.getExchange(exchangeId)\n ).baseToken,\n result.oceanFeeAvailable\n )\n\n result.exchangeId = exchangeId\n return result\n }\n\n /**\n * Get all exchanges\n * @param {String} exchangeId ExchangeId\n * @return {Promise<String[]>} Exchanges list\n */\n public async getExchanges(): Promise<string[]> {\n return await this.contract.methods.getExchanges().call()\n }\n\n /**\n * Check if an exchange is active\n * @param {String} exchangeId ExchangeId\n * @return {Promise<Boolean>} Result\n */\n public async isActive(exchangeId: string): Promise<boolean> {\n const result = await this.contract.methods.isActive(exchangeId).call()\n return result\n }\n\n /**\n * Estimate gas cost for activate\n * @param {String} account\n * @param {String} exchangeId ExchangeId\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estActivateMint(\n account: string,\n exchangeId: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await fixedRate.methods\n .toggleMintState(exchangeId, true)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Activate minting option for fixed rate contract\n * @param {String} exchangeId ExchangeId\n * @param {String} address User address\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async activateMint(\n address: string,\n exchangeId: string\n ): Promise<TransactionReceipt> {\n const exchange = await this.getExchange(exchangeId)\n if (!exchange) return null\n if (exchange.withMint === true) return null\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n\n const estGas = await this.estActivateMint(address, exchangeId)\n const trxReceipt = await this.contract.methods\n .toggleMintState(exchangeId, true)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for deactivate\n * @param {String} account\n * @param {String} exchangeId ExchangeId\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estDeactivateMint(\n account: string,\n exchangeId: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await fixedRate.methods\n .toggleMintState(exchangeId)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Deactivate minting for fixed rate\n * @param {String} exchangeId ExchangeId\n * @param {String} address User address\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async deactivateMint(\n address: string,\n exchangeId: string\n ): Promise<TransactionReceipt> {\n const exchange = await this.getExchange(exchangeId)\n if (!exchange) return null\n if (exchange.withMint === false) return null\n\n const estGas = await this.estDeactivate(address, exchangeId)\n\n const trxReceipt = await this.contract.methods\n .toggleMintState(exchangeId, false)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for collectBT\n * @param {String} account\n * @param {String} exchangeId ExchangeId\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estCollectBT(\n account: string,\n exchangeId: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await fixedRate.methods\n .collectBT(exchangeId)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Collect BaseTokens in the contract (only exchange owner)\n * @param {String} exchangeId ExchangeId\n * @param {String} address User address\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async collectBT(\n address: string,\n exchangeId: string\n ): Promise<TransactionReceipt> {\n const exchange = await this.getExchange(exchangeId)\n if (!exchange) return null\n\n const estGas = await this.estCollectBT(address, exchangeId)\n const trxReceipt = await this.contract.methods.collectBT(exchangeId).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for collecDT\n * @param {String} account\n * @param {String} exchangeId ExchangeId\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estCollectDT(\n account: string,\n exchangeId: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await fixedRate.methods\n .collectDT(exchangeId)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Collect datatokens in the contract (only exchange owner)\n * @param {String} exchangeId ExchangeId\n * @param {String} address User address\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async collectDT(\n address: string,\n exchangeId: string\n ): Promise<TransactionReceipt> {\n const exchange = await this.getExchange(exchangeId)\n if (!exchange) return null\n\n const estGas = await this.estCollectDT(address, exchangeId)\n const trxReceipt = await this.contract.methods.collectDT(exchangeId).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for collecMarketFee\n * @param {String} account\n * @param {String} exchangeId ExchangeId\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estCollectMarketFee(\n account: string,\n exchangeId: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await fixedRate.methods\n .collectMarketFee(exchangeId)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Collect market fee and send it to marketFeeCollector (anyone can call it)\n * @param {String} exchangeId ExchangeId\n * @param {String} address User address\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async collectMarketFee(\n address: string,\n exchangeId: string\n ): Promise<TransactionReceipt> {\n const exchange = await this.getExchange(exchangeId)\n if (!exchange) return null\n\n const estGas = await this.estCollectMarketFee(address, exchangeId)\n const trxReceipt = await this.contract.methods.collectMarketFee(exchangeId).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for collectOceanFee\n * @param {String} account\n * @param {String} exchangeId ExchangeId\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estCollectOceanFee(\n account: string,\n exchangeId: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await fixedRate.methods\n .collectMarketFee(exchangeId)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Collect ocean fee and send it to OPF collector (anyone can call it)\n * @param {String} exchangeId ExchangeId\n * @param {String} address User address\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async collectOceanFee(\n address: string,\n exchangeId: string\n ): Promise<TransactionReceipt> {\n const exchange = await this.getExchange(exchangeId)\n if (!exchange) return null\n\n const estGas = await this.estCollectOceanFee(address, exchangeId)\n const trxReceipt = await this.contract.methods.collectOceanFee(exchangeId).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n\n /**\n * Get OPF Collector of fixed rate contract\n * @return {String}\n */\n async getOPFCollector(): Promise<string> {\n let result = null\n try {\n result = await this.contract.methods.opfCollector().call()\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to get OPF Collector address: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get Router address set in fixed rate contract\n * @return {String}\n */\n async getRouter(): Promise<string> {\n let result = null\n try {\n result = await this.contract.methods.router().call()\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to get Router address: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get Exchange Owner given an exchangeId\n * @param {String} exchangeId ExchangeId\n * @return {String} return exchange owner\n */\n async getExchangeOwner(exchangeId: string): Promise<string> {\n let result = null\n try {\n result = await (await this.getExchange(exchangeId)).exchangeOwner\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to get OPF Collector address: ${e.message}`)\n }\n return result\n }\n\n /**\n * Estimate gas cost for updateMarketFee\n * @param {String} account\n * @param {String} exchangeId ExchangeId\n * @param {String} newMarketFee New market fee\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estUpdateMarketFee(\n account: string,\n exchangeId: string,\n newMarketFee: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await fixedRate.methods\n .updateMarketFee(exchangeId, newMarketFee)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Set new market fee, only market fee collector can update it\n * @param {String} address user address\n * @param {String} exchangeId ExchangeId\n * @param {String} newMarketFee New market fee\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async updateMarketFee(\n address: string,\n exchangeId: string,\n newMarketFee: string\n ): Promise<TransactionReceipt> {\n const estGas = await this.estSetRate(\n address,\n exchangeId,\n this.web3.utils.toWei(newMarketFee)\n )\n const trxReceipt = await this.contract.methods\n .updateMarketFee(exchangeId, this.web3.utils.toWei(newMarketFee))\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for updateMarketFeeCollector\n * @param {String} account\n * @param {String} exchangeId ExchangeId\n * @param {String} newMarketFee New market fee collector\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estUpdateMarketFeeCollector(\n account: string,\n exchangeId: string,\n newMarketFeeCollector: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await fixedRate.methods\n .updateMarketFeeCollector(exchangeId, newMarketFeeCollector)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Set new market fee collector, only market fee collector can update it\n * @param {String} address user address\n * @param {String} exchangeId ExchangeId\n * @param {String} newMarketFeeCollector New market fee collector\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async updateMarketFeeCollector(\n address: string,\n exchangeId: string,\n newMarketFeeCollector: string\n ): Promise<TransactionReceipt> {\n const estGas = await this.estUpdateMarketFeeCollector(\n address,\n exchangeId,\n newMarketFeeCollector\n )\n const trxReceipt = await this.contract.methods\n .updateMarketFeeCollector(exchangeId, newMarketFeeCollector)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n}\n","import Web3 from 'web3'\nimport { AbiItem } from 'web3-utils'\nimport { TransactionReceipt } from 'web3-eth'\nimport defaultNftAbi from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC721Template.sol/ERC721Template.json'\nimport {\n LoggerInstance,\n getFairGasPrice,\n generateDtName,\n setContractDefaults,\n configHelperNetworks\n} from '../utils'\nimport { Contract } from 'web3-eth-contract'\nimport { MetadataProof } from '../../src/@types'\nimport { Config } from '../models/index.js'\n\n/**\n * ERC721 ROLES\n */\ninterface Roles {\n manager: boolean\n deployERC20: boolean\n updateMetadata: boolean\n store: boolean\n}\n\nexport class Nft {\n public GASLIMIT_DEFAULT = 1000000\n public factory721Address: string\n public factory721Abi: AbiItem | AbiItem[]\n public nftAbi: AbiItem | AbiItem[]\n public web3: Web3\n public startBlock: number\n public config: Config\n\n constructor(web3: Web3, nftAbi?: AbiItem | AbiItem[], config?: Config) {\n this.nftAbi = nftAbi || (defaultNftAbi.abi as AbiItem[])\n this.web3 = web3\n this.config = config || configHelperNetworks[0]\n }\n\n /**\n * Estimate gas cost for createERC20 token creation\n * @param {String} nftAddress ERC721 addreess\n * @param {String} address User address\n * @param {String} minter User set as initial minter for the ERC20\n * @param {String} feeManager initial feeManager for this DT\n * @param {String} mpFeeAddress Consume marketplace fee address\n * @param {String} feeToken address of the token marketplace wants to add fee on top\n * @param {String} feeAmount amount of feeToken to be transferred to mpFeeAddress on top, will be converted to WEI\n * @param {String} cap Maximum cap (Number) - will be converted to wei\n * @param {String} name Token name\n * @param {String} symbol Token symbol\n * @param {Number} templateIndex NFT template index\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasCreateErc20(\n nftAddress: string,\n address: string,\n minter: string,\n feeManager: string,\n mpFeeAddress: string,\n feeToken: string,\n feeAmount: string,\n cap: string,\n name?: string,\n symbol?: string,\n templateIndex?: number,\n contractInstance?: Contract\n ): Promise<any> {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .createERC20(\n templateIndex,\n [name, symbol],\n [minter, feeManager, mpFeeAddress, feeToken],\n [this.web3.utils.toWei(cap), this.web3.utils.toWei(feeAmount)],\n []\n )\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Create new ERC20 datatoken - only user with ERC20Deployer permission can succeed\n * @param {String} nftAddress ERC721 addreess\n * @param {String} address User address\n * @param {String} minter User set as initial minter for the ERC20\n * @param {String} feeManager initial feeManager for this DT\n * @param {String} mpFeeAddress Consume marketplace fee address\n * @param {String} feeToken address of the token marketplace wants to add fee on top\n * @param {String} feeAmount amount of feeToken to be transferred to mpFeeAddress on top, will be converted to WEI\n * @param {String} cap Maximum cap (Number) - will be converted to wei\n * @param {String} name Token name\n * @param {String} symbol Token symbol\n * @param {Number} templateIndex NFT template index\n * @return {Promise<string>} ERC20 datatoken address\n */\n public async createErc20(\n nftAddress: string,\n address: string,\n minter: string,\n feeManager: string,\n mpFeeAddress: string,\n feeToken: string,\n feeAmount: string,\n cap: string,\n name?: string,\n symbol?: string,\n templateIndex?: number\n ): Promise<string> {\n if ((await this.getNftPermissions(nftAddress, address)).deployERC20 !== true) {\n throw new Error(`Caller is not ERC20Deployer`)\n }\n if (!templateIndex) templateIndex = 1\n\n // Generate name & symbol if not present\n if (!name || !symbol) {\n ;({ name, symbol } = generateDtName())\n }\n\n // Create 721contract object\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const estGas = await this.estGasCreateErc20(\n nftAddress,\n address,\n minter,\n feeManager,\n mpFeeAddress,\n feeToken,\n feeAmount,\n cap,\n name,\n symbol,\n templateIndex,\n nftContract\n )\n\n // Call createERC20 token function of the contract\n const trxReceipt = await nftContract.methods\n .createERC20(\n templateIndex,\n [name, symbol],\n [minter, feeManager, mpFeeAddress, feeToken],\n [this.web3.utils.toWei(cap), this.web3.utils.toWei(feeAmount)],\n []\n )\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n let tokenAddress = null\n try {\n tokenAddress = trxReceipt.events.TokenCreated.returnValues[0]\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to create datatoken : ${e.message}`)\n }\n return tokenAddress\n }\n\n /**\n * Estimate gas cost for add manager call\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Owner adress\n * @param {String} manager User adress which is going to be assing manager\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasAddManager(\n nftAddress: string,\n address: string,\n manager: string,\n contractInstance?: Contract\n ) {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .addManager(manager)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Add Manager for NFT Contract (only NFT Owner can succeed)\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Owner adress\n * @param {String} manager User adress which is going to be assing manager\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async addManager(nftAddress: string, address: string, manager: string) {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n if ((await this.getNftOwner(nftAddress)) !== address) {\n throw new Error(`Caller is not NFT Owner`)\n }\n\n const estGas = await this.estGasAddManager(nftAddress, address, manager, nftContract)\n\n // Invoke addManager function of the contract\n const trxReceipt = await nftContract.methods.addManager(manager).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for removeManager method\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Owner adress\n * @param {String} manager User adress which is going to be removed as manager\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasRemoveManager(\n nftAddress: string,\n address: string,\n manager: string,\n contractInstance?: Contract\n ) {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .removeManager(manager)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Removes a specific manager for NFT Contract (only NFT Owner can succeed)\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Owner adress\n * @param {String} manager User adress which is going to be removed as manager\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async removeManager(nftAddress: string, address: string, manager: string) {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n if ((await this.getNftOwner(nftAddress)) !== address) {\n throw new Error(`Caller is not NFT Owner`)\n }\n\n const estGas = await this.estGasRemoveManager(\n nftAddress,\n address,\n manager,\n nftContract\n )\n\n // Invoke removeManager function of the contract\n const trxReceipt = await nftContract.methods.removeManager(manager).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for addToCreateERC20List method\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Manager adress\n * @param {String} erc20Deployer User adress which is going to have erc20Deployer permission\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasAddErc20Deployer(\n nftAddress: string,\n address: string,\n erc20Deployer: string,\n contractInstance?: Contract\n ): Promise<any> {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .addToCreateERC20List(erc20Deployer)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * Add ERC20Deployer permission - only Manager can succeed\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Manager adress\n * @param {String} erc20Deployer User adress which is going to have erc20Deployer permission\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async addErc20Deployer(\n nftAddress: string,\n address: string,\n erc20Deployer: string\n ): Promise<TransactionReceipt> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n if ((await this.getNftPermissions(nftAddress, address)).manager !== true) {\n throw new Error(`Caller is not Manager`)\n }\n\n // Estimate gas for addToCreateERC20List method\n const estGas = await this.estGasAddErc20Deployer(\n nftAddress,\n address,\n erc20Deployer,\n nftContract\n )\n\n // Invoke addToCreateERC20List function of the contract\n const trxReceipt = await nftContract.methods\n .addToCreateERC20List(erc20Deployer)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for removeFromCreateERC20List method\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Manager adress\n * @param {String} erc20Deployer Address of the user to be revoked ERC20Deployer Permission\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasRemoveErc20Deployer(\n nftAddress: string,\n address: string,\n erc20Deployer: string,\n contractInstance?: Contract\n ): Promise<any> {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .removeFromCreateErc20List(erc20Deployer)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * Remove ERC20Deployer permission - only Manager can succeed\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Manager adress\n * @param {String} erc20Deployer Address of the user to be revoked ERC20Deployer Permission\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async removeErc20Deployer(\n nftAddress: string,\n address: string,\n erc20Deployer: string\n ): Promise<TransactionReceipt> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n if (\n (await this.getNftPermissions(nftAddress, address)).manager !== true ||\n (address === erc20Deployer &&\n (await this.getNftPermissions(nftAddress, address)).deployERC20 !== true)\n ) {\n throw new Error(`Caller is not Manager nor ERC20Deployer`)\n }\n const estGas = await this.estGasRemoveErc20Deployer(\n nftAddress,\n address,\n erc20Deployer,\n nftContract\n )\n\n // Call removeFromCreateERC20List function of the contract\n const trxReceipt = await nftContract.methods\n .removeFromCreateERC20List(erc20Deployer)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for addToMetadataList method\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Manager adress\n * @param {String} metadataUpdater User adress which is going to have Metadata Updater permission\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasAddMetadataUpdater(\n nftAddress: string,\n address: string,\n metadataUpdater: string,\n contractInstance?: Contract\n ): Promise<any> {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .addToMetadataList(metadataUpdater)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Add Metadata Updater permission - only Manager can succeed\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Manager adress\n * @param {String} metadataUpdater User adress which is going to have Metadata Updater permission\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async addMetadataUpdater(\n nftAddress: string,\n address: string,\n metadataUpdater: string\n ): Promise<TransactionReceipt> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n if ((await this.getNftPermissions(nftAddress, address)).manager !== true) {\n throw new Error(`Caller is not Manager`)\n }\n\n const estGas = await this.estGasAddMetadataUpdater(\n nftAddress,\n address,\n metadataUpdater,\n nftContract\n )\n\n // Call addToMetadataList function of the contract\n const trxReceipt = await nftContract.methods.addToMetadataList(metadataUpdater).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for removeFromMetadataList method\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Manager adress\n * @param {String} metadataUpdater Address of the user to be revoked Metadata updater Permission\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async esGasRemoveMetadataUpdater(\n nftAddress: string,\n address: string,\n metadataUpdater: string,\n contractInstance?: Contract\n ): Promise<any> {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .removeFromMetadataList(metadataUpdater)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * Remove Metadata Updater permission - only Manager can succeed\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Manager adress\n * @param {String} metadataUpdater Address of the user to be revoked Metadata updater Permission\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async removeMetadataUpdater(\n nftAddress: string,\n address: string,\n metadataUpdater: string\n ): Promise<TransactionReceipt> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n if (\n (await this.getNftPermissions(nftAddress, address)).manager !== true ||\n (address !== metadataUpdater &&\n (await this.getNftPermissions(nftAddress, address)).updateMetadata !== true)\n ) {\n throw new Error(`Caller is not Manager nor Metadata Updater`)\n }\n\n const estGas = await this.esGasRemoveMetadataUpdater(\n nftAddress,\n address,\n metadataUpdater,\n nftContract\n )\n\n // Call removeFromMetadataList function of the contract\n const trxReceipt = await nftContract.methods\n .removeFromMetadataList(metadataUpdater)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for addTo725StoreList method\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Manager adress\n * @param {String} storeUpdater User adress which is going to have Store Updater permission\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasAddStoreUpdater(\n nftAddress: string,\n address: string,\n storeUpdater: string,\n contractInstance?: Contract\n ): Promise<any> {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .addTo725StoreList(storeUpdater)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Add Store Updater permission - only Manager can succeed\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Manager adress\n * @param {String} storeUpdater User adress which is going to have Store Updater permission\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async addStoreUpdater(\n nftAddress: string,\n address: string,\n storeUpdater: string\n ): Promise<TransactionReceipt> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n if ((await this.getNftPermissions(nftAddress, address)).manager !== true) {\n throw new Error(`Caller is not Manager`)\n }\n\n const estGas = await this.estGasAddStoreUpdater(\n nftAddress,\n address,\n storeUpdater,\n nftContract\n )\n\n // Call addTo725StoreList function of the contract\n const trxReceipt = await nftContract.methods.addTo725StoreList(storeUpdater).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for removeFrom725StoreList method\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Manager adress\n * @param {String} storeUpdater Address of the user to be revoked Store Updater Permission\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasRemoveStoreUpdater(\n nftAddress: string,\n address: string,\n storeUpdater: string,\n contractInstance?: Contract\n ): Promise<any> {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .removeFrom725StoreList(storeUpdater)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Remove Store Updater permission - only Manager can succeed\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Manager adress\n * @param {String} storeUpdater Address of the user to be revoked Store Updater Permission\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async removeStoreUpdater(\n nftAddress: string,\n address: string,\n storeUpdater: string\n ): Promise<TransactionReceipt> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n if (\n (await this.getNftPermissions(nftAddress, address)).manager !== true ||\n (address !== storeUpdater &&\n (await this.getNftPermissions(nftAddress, address)).store !== true)\n ) {\n throw new Error(`Caller is not Manager nor storeUpdater`)\n }\n\n const estGas = await this.estGasRemoveStoreUpdater(\n nftAddress,\n address,\n storeUpdater,\n nftContract\n )\n\n // Call removeFrom725StoreList function of the contract\n const trxReceipt = await nftContract.methods\n .removeFrom725StoreList(storeUpdater)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for cleanPermissions method\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Owner adress\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasCleanPermissions(\n nftAddress: string,\n address: string,\n contractInstance?: Contract\n ): Promise<any> {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .cleanPermissions()\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * This function allows to remove all ROLES at erc721 level: Managers, ERC20Deployer, MetadataUpdater, StoreUpdater\n * Even NFT Owner has to readd himself as Manager\n * Permissions at erc20 level stay.\n * Only NFT Owner can call it.\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Owner adress\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n\n public async cleanPermissions(\n nftAddress: string,\n address: string\n ): Promise<TransactionReceipt> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n if ((await this.getNftOwner(nftAddress)) !== address) {\n throw new Error(`Caller is not NFT Owner`)\n }\n\n const estGas = await this.estGasCleanPermissions(nftAddress, address, nftContract)\n\n // Call cleanPermissions function of the contract\n const trxReceipt = await nftContract.methods.cleanPermissions().send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for transfer NFT method\n * @param {String} nftAddress erc721 contract adress\n * @param {String} nftOwner Current NFT Owner adress\n * @param {String} nftReceiver User which will receive the NFT, will also be set as Manager\n * @param {Number} tokenId The id of the token to be transfered\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasTransferNft(\n nftAddress: string,\n nftOwner: string,\n nftReceiver: string,\n tokenId: number,\n contractInstance?: Contract\n ): Promise<any> {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .transferFrom(nftOwner, nftReceiver, tokenId)\n .estimateGas({ from: nftOwner }, (err, estGas) =>\n err ? gasLimitDefault : estGas\n )\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * Transfers the NFT\n * will clean all permissions both on erc721 and erc20 level.\n * @param {String} nftAddress erc721 contract adress\n * @param {String} nftOwner Current NFT Owner adress\n * @param {String} nftReceiver User which will receive the NFT, will also be set as Manager\n * @param {Number} tokenId The id of the token to be transfered\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async transferNft(\n nftAddress: string,\n nftOwner: string,\n nftReceiver: string,\n tokenId?: number\n ): Promise<TransactionReceipt> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n if ((await this.getNftOwner(nftAddress)) !== nftOwner) {\n throw new Error(`Caller is not NFT Owner`)\n }\n\n const tokenIdentifier = tokenId || 1\n\n const estGas = await this.estGasTransferNft(\n nftAddress,\n nftOwner,\n nftReceiver,\n tokenIdentifier,\n nftContract\n )\n\n // Call transferFrom function of the contract\n const trxReceipt = await nftContract.methods\n .transferFrom(nftOwner, nftReceiver, tokenIdentifier)\n .send({\n from: nftOwner,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for safeTransfer NFT method\n * @param {String} nftAddress erc721 contract adress\n * @param {String} nftOwner Current NFT Owner adress\n * @param {String} nftReceiver User which will receive the NFT, will also be set as Manager\n * @param {Number} tokenId The id of the token to be transfered\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasSafeTransferNft(\n nftAddress: string,\n nftOwner: string,\n nftReceiver: string,\n tokenId: number,\n contractInstance?: Contract\n ): Promise<any> {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .safeTransferFrom(nftOwner, nftReceiver, tokenId)\n .estimateGas({ from: nftOwner }, (err, estGas) =>\n err ? gasLimitDefault : estGas\n )\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * safeTransferNFT Used for transferring the NFT, can be used by an approved relayer\n * will clean all permissions both on erc721 and erc20 level.\n * @param {String} nftAddress erc721 contract adress\n * @param {String} nftOwner Current NFT Owner adress\n * @param {String} nftReceiver User which will receive the NFT, will also be set as Manager\n * @param {Number} tokenId The id of the token to be transfered\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async safeTransferNft(\n nftAddress: string,\n nftOwner: string,\n nftReceiver: string,\n tokenId?: number\n ): Promise<TransactionReceipt> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n if ((await this.getNftOwner(nftAddress)) !== nftOwner) {\n throw new Error(`Caller is not NFT Owner`)\n }\n\n const tokenIdentifier = tokenId || 1\n\n const estGas = await this.estGasSafeTransferNft(\n nftAddress,\n nftOwner,\n nftReceiver,\n tokenIdentifier,\n nftContract\n )\n\n // Call transferFrom function of the contract\n const trxReceipt = await nftContract.methods\n .safeTransferFrom(nftOwner, nftReceiver, tokenIdentifier)\n .send({\n from: nftOwner,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n // TODO: Finish this description\n /**\n * Estimate gas cost for setMetadata method\n * @param {String} nftAddress erc721 contract adress\n * @param {String} metadataUpdater metadataUpdater address\n * @param {Number} metadataState User which will receive the NFT, will also be set as Manager\n * @param {String} metaDataDecryptorUrl\n * @param {Number} tokenId The id of the token to be transfered\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasSetMetadata(\n nftAddress: string,\n metadataUpdater: string,\n metadataState: number,\n metaDataDecryptorUrl: string,\n metaDataDecryptorAddress: string,\n flags: string,\n data: string,\n metadataHash: string,\n metadataProofs?: MetadataProof[],\n contractInstance?: Contract\n ): Promise<any> {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .setMetaData(\n metadataState,\n metaDataDecryptorUrl,\n metaDataDecryptorAddress,\n flags,\n data,\n metadataHash,\n metadataProofs\n )\n .estimateGas({ from: metadataUpdater }, (err, estGas) =>\n err ? gasLimitDefault : estGas\n )\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * safeTransferNFT Used for transferring the NFT, can be used by an approved relayer\n * will clean all permissions both on erc721 and erc20 level.\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address Caller address NFT Owner adress\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async setMetadata(\n nftAddress: string,\n address: string,\n metadataState: number,\n metaDataDecryptorUrl: string,\n metaDataDecryptorAddress: string,\n flags: string,\n data: string,\n metadataHash: string,\n metadataProofs?: MetadataProof[]\n ): Promise<TransactionReceipt> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n if (!metadataProofs) metadataProofs = []\n if (!(await this.getNftPermissions(nftAddress, address)).updateMetadata) {\n throw new Error(`Caller is not Metadata updater`)\n }\n const estGas = await this.estGasSetMetadata(\n nftAddress,\n address,\n metadataState,\n metaDataDecryptorUrl,\n metaDataDecryptorAddress,\n flags,\n data,\n metadataHash,\n metadataProofs,\n nftContract\n )\n const trxReceipt = await nftContract.methods\n .setMetaData(\n metadataState,\n metaDataDecryptorUrl,\n metaDataDecryptorAddress,\n flags,\n data,\n metadataHash,\n metadataProofs\n )\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for setMetadataState method\n * @param {String} nftAddress erc721 contract adress\n * @param {String} nftOwner Current NFT Owner adress\n * @param {Number} metadataState new metadata state\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasSetMetadataState(\n nftAddress: string,\n metadataUpdater: string,\n metadataState: number,\n contractInstance?: Contract\n ): Promise<any> {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .setMetaDataState(metadataState)\n .estimateGas({ from: metadataUpdater }, (err, estGas) =>\n err ? gasLimitDefault : estGas\n )\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * setMetadataState Used for updating the metadata State\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address Caller address => metadata updater\n * @param {Number} metadataState new metadata state\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async setMetadataState(\n nftAddress: string,\n address: string,\n metadataState: number\n ): Promise<TransactionReceipt> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n if (!(await this.getNftPermissions(nftAddress, address)).updateMetadata) {\n throw new Error(`Caller is not Metadata updater`)\n }\n\n const estGas = await this.estGasSetMetadataState(nftAddress, address, metadataState)\n\n // Call transferFrom function of the contract\n const trxReceipt = await nftContract.methods.setMetaDataState(metadataState).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /** Estimate gas cost for setTokenURI method\n * @param nftAddress erc721 contract adress\n * @param address user adress\n * @param data input data for TokenURI\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async estSetTokenURI(\n nftAddress: string,\n address: string,\n data: string\n ): Promise<any> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .setTokenURI('1', data)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /** set TokenURI on an nft\n * @param nftAddress erc721 contract adress\n * @param address user adress\n * @param data input data for TokenURI\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async setTokenURI(\n nftAddress: string,\n address: string,\n data: string\n ): Promise<any> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const estGas = await this.estSetTokenURI(nftAddress, address, data)\n const trxReceipt = await nftContract.methods.setTokenURI('1', data).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n\n /** Get Owner\n * @param {String} nftAddress erc721 contract adress\n * @return {Promise<string>} string\n */\n public async getNftOwner(nftAddress: string): Promise<string> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n const trxReceipt = await nftContract.methods.ownerOf(1).call()\n return trxReceipt\n }\n\n /** Get users NFT Permissions\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address user adress\n * @return {Promise<Roles>}\n */\n public async getNftPermissions(nftAddress: string, address: string): Promise<Roles> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n const roles = await nftContract.methods.getPermissions(address).call()\n return roles\n }\n\n /** Get users Metadata, return Metadata details\n * @param {String} nftAddress erc721 contract adress\n * @return {Promise<Objecta>}\n */\n public async getMetadata(nftAddress: string): Promise<Object> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n return await nftContract.methods.getMetaData().call()\n }\n\n /** Get users ERC20Deployer role\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address user adress\n * @return {Promise<Roles>}\n */\n public async isErc20Deployer(nftAddress: string, address: string): Promise<boolean> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n const isERC20Deployer = await nftContract.methods.isERC20Deployer(address).call()\n return isERC20Deployer\n }\n\n /** Gets data at a given `key`\n * @param {String} nftAddress erc721 contract adress\n * @param {String} key the key which value to retrieve\n * @return {Promise<string>} The data stored at the key\n */\n public async getData(nftAddress: string, key: string): Promise<string> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n const data = await nftContract.methods.getData(key).call()\n return data\n }\n\n /** Gets data at a given `key`\n * @param {String} nftAddress erc721 contract adress\n * @param {String} id\n * @return {Promise<string>} The data stored at the key\n */\n public async getTokenURI(nftAddress: string, id: number): Promise<string> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n const data = await nftContract.methods.tokenURI(id).call()\n return data\n }\n}\n","import Web3 from 'web3'\nimport { AbiItem } from 'web3-utils'\nimport { TransactionReceipt } from 'web3-eth'\nimport { Contract } from 'web3-eth-contract'\nimport Decimal from 'decimal.js'\nimport defaultDatatokensAbi from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json'\nimport defaultDatatokensEnterpriseAbi from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20TemplateEnterprise.sol/ERC20TemplateEnterprise.json'\nimport {\n LoggerInstance,\n getFairGasPrice,\n setContractDefaults,\n configHelperNetworks\n} from '../utils'\nimport { FreOrderParams, FreCreationParams } from '../interfaces'\nimport { Nft } from './NFT'\nimport { Config } from '../models/index.js'\nimport { ProviderFees } from '../@types/Provider.js'\n/**\n * ERC20 ROLES\n */\ninterface Roles {\n minter: boolean\n paymentManager: boolean\n}\n\nexport interface OrderParams {\n consumer: string\n serviceIndex: number\n _providerFees: ProviderFees\n}\n\nexport interface DispenserParams {\n maxTokens: string\n maxBalance: string\n withMint?: boolean // true if we want to allow the dispenser to be a minter\n allowedSwapper?: string // only account that can ask tokens. set address(0) if not required\n}\n\nexport class Datatoken {\n public GASLIMIT_DEFAULT = 1000000\n public factoryAddress: string\n public factoryABI: AbiItem | AbiItem[]\n public datatokensAbi: AbiItem | AbiItem[]\n public datatokensEnterpriseAbi: AbiItem | AbiItem[]\n public web3: Web3\n public config: Config\n public nft: Nft\n\n /**\n * Instantiate ERC20 Datatokens\n * @param {AbiItem | AbiItem[]} datatokensAbi\n * @param {Web3} web3\n */\n constructor(\n web3: Web3,\n datatokensAbi?: AbiItem | AbiItem[],\n datatokensEnterpriseAbi?: AbiItem | AbiItem[],\n config?: Config\n ) {\n this.web3 = web3\n this.datatokensAbi = datatokensAbi || (defaultDatatokensAbi.abi as AbiItem[])\n this.datatokensEnterpriseAbi =\n datatokensEnterpriseAbi || (defaultDatatokensEnterpriseAbi.abi as AbiItem[])\n this.config = config || configHelperNetworks[0]\n this.nft = new Nft(this.web3)\n }\n\n /**\n * Estimate gas cost for mint method\n * @param {String} dtAddress Datatoken address\n * @param {String} spender Spender address\n * @param {string} amount Number of datatokens, as number. Will be converted to wei\n * @param {String} address User adress\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasApprove(\n dtAddress: string,\n spender: string,\n amount: string,\n address: string,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n // Estimate gas cost for mint method\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await dtContract.methods\n .approve(spender, this.web3.utils.toWei(amount))\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Approve\n * @param {String} dtAddress Datatoken address\n * @param {String} spender Spender address\n * @param {string} amount Number of datatokens, as number. Will be converted to wei\n * @param {String} address User adress\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async approve(\n dtAddress: string,\n spender: string,\n amount: string,\n address: string\n ): Promise<TransactionReceipt> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n const estGas = await this.estGasApprove(\n dtAddress,\n spender,\n amount,\n address,\n dtContract\n )\n\n // Call mint contract method\n const trxReceipt = await dtContract.methods\n .approve(spender, this.web3.utils.toWei(amount))\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for mint method\n * @param {String} dtAddress Datatoken address\n * @param {String} address Minter address\n * @param {String} amount Number of datatokens, as number. Will be converted to wei\n * @param {String} toAddress only if toAddress is different from the minter\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasMint(\n dtAddress: string,\n address: string,\n amount: string,\n toAddress?: string,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await dtContract.methods\n .mint(toAddress || address, this.web3.utils.toWei(amount))\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * Estimate gas cost for createFixedRate method\n * @param {String} dtAddress Datatoken address\n * @param {String} address Caller address\n * @param {String} fixedPriceAddress\n * @param {FixedRateParams} fixedRateParams\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasCreateFixedRate(\n dtAddress: string,\n address: string,\n fixedRateParams: FreCreationParams,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n\n if (!fixedRateParams.allowedConsumer)\n fixedRateParams.allowedConsumer = '0x0000000000000000000000000000000000000000'\n const withMint = fixedRateParams.withMint ? 1 : 0\n\n let estGas\n try {\n estGas = await dtContract.methods\n .createFixedRate(\n fixedRateParams.fixedRateAddress,\n [\n fixedRateParams.baseTokenAddress,\n address,\n fixedRateParams.marketFeeCollector,\n fixedRateParams.allowedConsumer\n ],\n [\n fixedRateParams.baseTokenDecimals,\n fixedRateParams.datatokenDecimals,\n fixedRateParams.fixedRate,\n fixedRateParams.marketFee,\n withMint\n ]\n )\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * Creates a new FixedRateExchange setup.\n * @param {String} dtAddress Datatoken address\n * @param {String} address Caller address\n * @param {String} fixedPriceAddress\n * @param {FixedRateParams} fixedRateParams\n * @return {Promise<TransactionReceipt>} transactionId\n */\n public async createFixedRate(\n dtAddress: string,\n address: string,\n fixedRateParams: FreCreationParams\n ): Promise<TransactionReceipt> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n if (!(await this.isERC20Deployer(dtAddress, address))) {\n throw new Error(`User is not ERC20 Deployer`)\n }\n if (!fixedRateParams.allowedConsumer)\n fixedRateParams.allowedConsumer = '0x0000000000000000000000000000000000000000'\n\n const withMint = fixedRateParams.withMint ? 1 : 0\n\n // should check ERC20Deployer role using erc721 level ..\n\n const estGas = await this.estGasCreateFixedRate(\n dtAddress,\n address,\n fixedRateParams,\n dtContract\n )\n\n // Call createFixedRate contract method\n const trxReceipt = await dtContract.methods\n .createFixedRate(\n fixedRateParams.fixedRateAddress,\n [\n fixedRateParams.baseTokenAddress,\n fixedRateParams.owner,\n fixedRateParams.marketFeeCollector,\n fixedRateParams.allowedConsumer\n ],\n [\n fixedRateParams.baseTokenDecimals,\n fixedRateParams.datatokenDecimals,\n fixedRateParams.fixedRate,\n fixedRateParams.marketFee,\n withMint\n ]\n )\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for createDispenser method\n * @param {String} dtAddress Datatoken address\n * @param {String} address Caller address\n * @param {String} dispenserAddress ispenser contract address\n * @param {String} dispenserParams\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasCreateDispenser(\n dtAddress: string,\n address: string,\n dispenserAddress: string,\n dispenserParams: DispenserParams,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n if (!dispenserParams.allowedSwapper)\n dispenserParams.allowedSwapper = '0x0000000000000000000000000000000000000000'\n\n if (!dispenserParams.withMint) dispenserParams.withMint = false\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await dtContract.methods\n .createDispenser(\n dispenserAddress,\n dispenserParams.maxTokens,\n dispenserParams.maxBalance,\n dispenserParams.withMint,\n dispenserParams.allowedSwapper\n )\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * Creates a new Dispenser\n * @param {String} dtAddress Datatoken address\n * @param {String} address Caller address\n * @param {String} dispenserAddress ispenser contract address\n * @param {String} dispenserParams\n * @return {Promise<TransactionReceipt>} transactionId\n */\n public async createDispenser(\n dtAddress: string,\n address: string,\n dispenserAddress: string,\n dispenserParams: DispenserParams\n ): Promise<TransactionReceipt> {\n if (!(await this.isERC20Deployer(dtAddress, address))) {\n throw new Error(`User is not ERC20 Deployer`)\n }\n\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n if (!dispenserParams.allowedSwapper)\n dispenserParams.allowedSwapper = '0x0000000000000000000000000000000000000000'\n\n if (!dispenserParams.withMint) dispenserParams.withMint = false\n\n // should check ERC20Deployer role using erc721 level ..\n\n const estGas = await this.estGasCreateDispenser(\n dtAddress,\n address,\n dispenserAddress,\n dispenserParams,\n dtContract\n )\n\n // Call createFixedRate contract method\n const trxReceipt = await dtContract.methods\n .createDispenser(\n dispenserAddress,\n dispenserParams.maxTokens,\n dispenserParams.maxBalance,\n dispenserParams.withMint,\n dispenserParams.allowedSwapper\n )\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n\n /**\n * Mint\n * @param {String} dtAddress Datatoken address\n * @param {String} address Minter address\n * @param {String} amount Number of datatokens, as number. Will be converted to wei\n * @param {String} toAddress only if toAddress is different from the minter\n * @return {Promise<TransactionReceipt>} transactionId\n */\n public async mint(\n dtAddress: string,\n address: string,\n amount: string,\n toAddress?: string\n ): Promise<TransactionReceipt> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n if ((await this.getDTPermissions(dtAddress, address)).minter !== true) {\n throw new Error(`Caller is not Minter`)\n }\n\n const capAvailble = await this.getCap(dtAddress)\n if (new Decimal(capAvailble).gte(amount)) {\n const estGas = await this.estGasMint(\n dtAddress,\n address,\n amount,\n toAddress,\n dtContract\n )\n\n // Call mint contract method\n const trxReceipt = await dtContract.methods\n .mint(toAddress || address, this.web3.utils.toWei(amount))\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n } else {\n throw new Error(`Mint amount exceeds cap available`)\n }\n }\n\n /**\n * Estimate gas cost for addMinter method\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address\n * @param {String} minter User which is going to be a Minter\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasAddMinter(\n dtAddress: string,\n address: string,\n minter: string,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n // Estimate gas cost for addMinter method\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await dtContract.methods\n .addMinter(minter)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Add Minter for an ERC20 datatoken\n * only ERC20Deployer can succeed\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address\n * @param {String} minter User which is going to be a Minter\n * @return {Promise<TransactionReceipt>} transactionId\n */\n public async addMinter(\n dtAddress: string,\n address: string,\n minter: string\n ): Promise<TransactionReceipt> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n if ((await this.isERC20Deployer(dtAddress, address)) !== true) {\n throw new Error(`Caller is not ERC20Deployer`)\n }\n // Estimate gas cost for addMinter method\n const estGas = await this.estGasAddMinter(dtAddress, address, minter, dtContract)\n\n // Call addMinter function of the contract\n const trxReceipt = await dtContract.methods.addMinter(minter).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas for removeMinter method\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address\n * @param {String} minter User which will be removed from Minter permission\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasRemoveMinter(\n dtAddress: string,\n address: string,\n minter: string,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n // should check ERC20Deployer role using erc721 level ..\n\n // Estimate gas for removeMinter method\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await dtContract.methods\n .removeMinter(minter)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * Revoke Minter permission for an ERC20 datatoken\n * only ERC20Deployer can succeed\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address\n * @param {String} minter User which will be removed from Minter permission\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async removeMinter(\n dtAddress: string,\n address: string,\n minter: string\n ): Promise<TransactionReceipt> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n if ((await this.isERC20Deployer(dtAddress, address)) !== true) {\n throw new Error(`Caller is not ERC20Deployer`)\n }\n\n const estGas = await this.estGasRemoveMinter(dtAddress, address, minter, dtContract)\n\n // Call dtContract function of the contract\n const trxReceipt = await dtContract.methods.removeMinter(minter).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas for addPaymentManager method\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address\n * @param {String} paymentManager User which is going to be a Minter\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasAddPaymentManager(\n dtAddress: string,\n address: string,\n paymentManager: string,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n // Estimate gas for addFeeManager method\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await dtContract.methods\n .addPaymentManager(paymentManager)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * Add addPaymentManager (can set who's going to collect fee when consuming orders)\n * only ERC20Deployer can succeed\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address\n * @param {String} paymentManager User which is going to be a Minter\n * @return {Promise<TransactionReceipt>} transactionId\n */\n public async addPaymentManager(\n dtAddress: string,\n address: string,\n paymentManager: string\n ): Promise<TransactionReceipt> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n if ((await this.isERC20Deployer(dtAddress, address)) !== true) {\n throw new Error(`Caller is not ERC20Deployer`)\n }\n\n const estGas = await this.estGasAddPaymentManager(\n dtAddress,\n address,\n paymentManager,\n dtContract\n )\n\n // Call addPaymentManager function of the contract\n const trxReceipt = await dtContract.methods.addPaymentManager(paymentManager).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas for removePaymentManager method\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address\n * @param {String} paymentManager User which will be removed from paymentManager permission\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasRemovePaymentManager(\n dtAddress: string,\n address: string,\n paymentManager: string,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await dtContract.methods\n .removePaymentManager(paymentManager)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Revoke paymentManager permission for an ERC20 datatoken\n * only ERC20Deployer can succeed\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address\n * @param {String} paymentManager User which will be removed from paymentManager permission\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async removePaymentManager(\n dtAddress: string,\n address: string,\n paymentManager: string\n ): Promise<TransactionReceipt> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n if ((await this.isERC20Deployer(dtAddress, address)) !== true) {\n throw new Error(`Caller is not ERC20Deployer`)\n }\n\n const estGas = await this.estGasRemovePaymentManager(\n dtAddress,\n address,\n paymentManager,\n dtContract\n )\n\n // Call removeFeeManager function of the contract\n const trxReceipt = await dtContract.methods\n .removePaymentManager(paymentManager)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas for setPaymentCollector method\n * @param dtAddress datatoken address\n * @param address Caller address\n * @param paymentCollector User to be set as new payment collector\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasSetPaymentCollector(\n dtAddress: string,\n address: string,\n paymentCollector: string,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await dtContract.methods\n .setPaymentCollector(paymentCollector)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * This function allows to set a new PaymentCollector (receives DT when consuming)\n * If not set the paymentCollector is the NFT Owner\n * only NFT owner can call\n * @param dtAddress datatoken address\n * @param address Caller address\n * @param paymentCollector User to be set as new payment collector\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async setPaymentCollector(\n dtAddress: string,\n address: string,\n paymentCollector: string\n ): Promise<TransactionReceipt> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n if ((await this.getDTPermissions(dtAddress, address)).paymentManager !== true) {\n throw new Error(`Caller is not Fee Manager`)\n }\n\n const estGas = await this.estGasSetPaymentCollector(\n dtAddress,\n address,\n paymentCollector,\n dtContract\n )\n\n // Call setFeeCollector method of the contract\n const trxReceipt = await dtContract.methods\n .setPaymentCollector(paymentCollector)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /** getPaymentCollector - It returns the current paymentCollector\n * @param dtAddress datatoken address\n * @return {Promise<string>}\n */\n public async getPaymentCollector(dtAddress: string): Promise<string> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n const paymentCollector = await dtContract.methods.getPaymentCollector().call()\n return paymentCollector\n }\n\n /**\n * Transfer as number from address to toAddress\n * @param {String} dtAddress Datatoken address\n * @param {String} toAddress Receiver address\n * @param {String} amount Number of datatokens, as number. To be converted to wei.\n * @param {String} address User adress\n * @return {Promise<TransactionReceipt>} transactionId\n */\n public async transfer(\n dtAddress: string,\n toAddress: string,\n amount: string,\n address: string\n ): Promise<TransactionReceipt> {\n const weiAmount = this.web3.utils.toWei(amount)\n return this.transferWei(dtAddress, toAddress, weiAmount, address)\n }\n\n /**\n * Estimate gas for transfer method\n * @param {String} dtAddress Datatoken address\n * @param {String} toAddress Receiver address\n * @param {String} amount Number of datatokens, as number. Expressed as wei\n * @param {String} address User adress\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasTransfer(\n dtAddress: string,\n toAddress: string,\n amount: string,\n address: string,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await dtContract.methods\n .transfer(toAddress, amount)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Transfer in wei from address to toAddress\n * @param {String} dtAddress Datatoken address\n * @param {String} toAddress Receiver address\n * @param {String} amount Number of datatokens, as number. Expressed as wei\n * @param {String} address User adress\n * @return {Promise<TransactionReceipt>} transactionId\n */\n public async transferWei(\n dtAddress: string,\n toAddress: string,\n amount: string,\n address: string\n ): Promise<TransactionReceipt> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n try {\n const estGas = await this.estGasTransfer(\n dtAddress,\n toAddress,\n amount,\n address,\n dtContract\n )\n // Call transfer function of the contract\n const trxReceipt = await dtContract.methods.transfer(toAddress, amount).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to transfer tokens: ${e.message}`)\n throw new Error(`Failed Failed to transfer tokens: ${e.message}`)\n }\n }\n\n /** Estimate gas cost for startOrder method\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address which calls\n * @param {String} consumer Consumer Address\n * @param {Number} serviceIndex Service index in the metadata\n * @param {providerFees} providerFees provider fees\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasStartOrder(\n dtAddress: string,\n address: string,\n consumer: string,\n serviceIndex: number,\n providerFees: ProviderFees,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n // Estimate gas for startOrder method\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await dtContract.methods\n .startOrder(consumer, serviceIndex, providerFees)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /** Start Order: called by payer or consumer prior ordering a service consume on a marketplace.\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address which calls\n * @param {String} consumer Consumer Address\n * @param {Number} serviceIndex Service index in the metadata\n * @param {providerFees} providerFees provider fees\n * @return {Promise<TransactionReceipt>} string\n */\n public async startOrder(\n dtAddress: string,\n address: string,\n consumer: string,\n serviceIndex: number,\n providerFees: ProviderFees\n ): Promise<TransactionReceipt> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n try {\n const estGas = await this.estGasStartOrder(\n dtAddress,\n address,\n consumer,\n serviceIndex,\n providerFees,\n dtContract\n )\n\n const trxReceipt = await dtContract.methods\n .startOrder(consumer, serviceIndex, providerFees)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to start order : ${e.message}`)\n throw new Error(`Failed to start order: ${e.message}`)\n }\n }\n\n /** Estimate gas cost for buyFromFreAndOrder method\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address which calls\n * @param {OrderParams} orderParams Consumer Address\n * @param {FreParams} freParams Amount of tokens that is going to be transfered\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasBuyFromFreAndOrder(\n dtAddress: string,\n address: string,\n orderParams: OrderParams,\n freParams: FreOrderParams,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n new this.web3.eth.Contract(this.datatokensEnterpriseAbi, dtAddress)\n\n // Estimate gas for startOrder method\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await dtContract.methods\n .buyFromFreAndOrder(orderParams, freParams)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /** Buys 1 DT from the FRE and then startsOrder, while burning that DT\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address which calls\n * @param {OrderParams} orderParams Consumer Address\n * @param {FreParams} freParams Amount of tokens that is going to be transfered\n * @return {Promise<TransactionReceipt>}\n */\n public async buyFromFreAndOrder(\n dtAddress: string,\n address: string,\n orderParams: OrderParams,\n freParams: FreOrderParams\n ): Promise<TransactionReceipt> {\n const dtContract = new this.web3.eth.Contract(this.datatokensEnterpriseAbi, dtAddress)\n try {\n const estGas = await this.estGasBuyFromFreAndOrder(\n dtAddress,\n address,\n orderParams,\n freParams,\n dtContract\n )\n\n const trxReceipt = await dtContract.methods\n .buyFromFreAndOrder(orderParams, freParams)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to buy DT From Fre And Order : ${e.message}`)\n throw new Error(`Failed to buy DT From Fre And Order: ${e.message}`)\n }\n }\n\n /** Estimate gas cost for buyFromFreAndOrder method\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address which calls\n * @param {OrderParams} orderParams\n * @param {String} dispenserContract\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasBuyFromDispenserAndOrder(\n dtAddress: string,\n address: string,\n orderParams: OrderParams,\n dispenserContract: string,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n new this.web3.eth.Contract(this.datatokensEnterpriseAbi, dtAddress)\n\n // Estimate gas for startOrder method\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await dtContract.methods\n .buyFromDispenserAndOrder(orderParams, dispenserContract)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /** Gets DT from dispenser and then startsOrder, while burning that DT\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address which calls\n * @param {OrderParams} orderParams\n * @param {String} dispenserContract\n * @return {Promise<TransactionReceipt>}\n */\n public async buyFromDispenserAndOrder(\n dtAddress: string,\n address: string,\n orderParams: OrderParams,\n dispenserContract: string\n ): Promise<TransactionReceipt> {\n const dtContract = new this.web3.eth.Contract(this.datatokensEnterpriseAbi, dtAddress)\n try {\n const estGas = await this.estGasBuyFromDispenserAndOrder(\n dtAddress,\n address,\n orderParams,\n dispenserContract,\n dtContract\n )\n\n const trxReceipt = await dtContract.methods\n .buyFromDispenserAndOrder(orderParams, dispenserContract)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to buy DT From Fre And Order : ${e.message}`)\n throw new Error(`Failed to buy DT From Fre And Order: ${e.message}`)\n }\n }\n\n /** Estimate gas for setData method\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address\n * @param {String} value Data to be stored into 725Y standard\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasSetData(\n dtAddress: string,\n address: string,\n value: string,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await dtContract.methods\n .setData(value)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /** setData\n * This function allows to store data with a preset key (keccak256(ERC20Address)) into NFT 725 Store\n * only ERC20Deployer can succeed\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address\n * @param {String} value Data to be stored into 725Y standard\n * @return {Promise<TransactionReceipt>} transactionId\n */\n public async setData(\n dtAddress: string,\n address: string,\n value: string\n ): Promise<TransactionReceipt> {\n if (!(await this.isERC20Deployer(dtAddress, address))) {\n throw new Error(`User is not ERC20 Deployer`)\n }\n\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n const estGas = await this.estGasSetData(dtAddress, address, value, dtContract)\n\n // Call setData function of the contract\n const trxReceipt = await dtContract.methods.setData(value).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /** Estimate gas for cleanPermissions method\n * @param dtAddress Datatoken address where we want to clean permissions\n * @param address User adress\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasCleanPermissions(\n dtAddress: string,\n address: string,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await dtContract.methods\n .cleanPermissions()\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * Clean erc20level Permissions (minters, paymentManager and reset the paymentCollector) for an ERC20 datatoken\n * Only NFT Owner (at 721 level) can call it.\n * @param dtAddress Datatoken address where we want to clean permissions\n * @param address User adress\n * @return {Promise<TransactionReceipt>} transactionId\n */\n public async cleanPermissions(\n dtAddress: string,\n address: string\n ): Promise<TransactionReceipt> {\n if ((await this.nft.getNftOwner(await this.getNFTAddress(dtAddress))) !== address) {\n throw new Error('Caller is NOT Nft Owner')\n }\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n const estGas = await this.estGasCleanPermissions(dtAddress, address, dtContract)\n\n // Call cleanPermissions function of the contract\n const trxReceipt = await dtContract.methods.cleanPermissions().send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /** Returns ERC20 user's permissions for a datatoken\n * @param {String} dtAddress Datatoken adress\n * @param {String} address user adress\n * @return {Promise<Roles>}\n */\n public async getDTPermissions(dtAddress: string, address: string): Promise<Roles> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n const roles = await dtContract.methods.permissions(address).call()\n return roles\n }\n\n /** Returns the Datatoken capital\n * @param {String} dtAddress Datatoken adress\n * @return {Promise<string>}\n */\n public async getCap(dtAddress: string): Promise<string> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n const cap = await dtContract.methods.cap().call()\n return this.web3.utils.fromWei(cap)\n }\n\n /** It returns the token decimals, how many supported decimal points\n * @param {String} dtAddress Datatoken adress\n * @return {Promise<number>}\n */\n public async getDecimals(dtAddress: string): Promise<string> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n const decimals = await dtContract.methods.decimals().call()\n return decimals\n }\n\n /** It returns the token decimals, how many supported decimal points\n * @param {String} dtAddress Datatoken adress\n * @return {Promise<number>}\n */\n public async getNFTAddress(dtAddress: string): Promise<string> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n const nftAddress = await dtContract.methods.getERC721Address().call()\n return nftAddress\n }\n\n /** Returns true if address has deployERC20 role\n * @param {String} dtAddress Datatoken adress\n * @param {String} dtAddress Datatoken adress\n * @return {Promise<boolean>}\n */\n public async isERC20Deployer(dtAddress: string, address: string): Promise<boolean> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n const isERC20Deployer = await dtContract.methods.isERC20Deployer(address).call()\n return isERC20Deployer\n }\n\n /**\n * Get Address Balance for datatoken\n * @param {String} dtAddress Datatoken adress\n * @param {String} address user adress\n * @return {Promise<String>} balance Number of datatokens. Will be converted from wei\n */\n public async balance(datatokenAddress: string, address: string): Promise<string> {\n const dtContract = new this.web3.eth.Contract(this.datatokensAbi, datatokenAddress, {\n from: address\n })\n const balance = await dtContract.methods.balanceOf(address).call()\n return this.web3.utils.fromWei(balance)\n }\n}\n","import { Contract } from 'web3-eth-contract'\nimport Web3 from 'web3'\nimport { TransactionReceipt } from 'web3-core'\nimport { AbiItem } from 'web3-utils'\nimport defaultFactory721Abi from '@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json'\nimport {\n LoggerInstance,\n getFairGasPrice,\n generateDtName,\n getFreCreationParams,\n getErcCreationParams,\n getPoolCreationParams,\n configHelperNetworks,\n setContractDefaults\n} from '../utils'\nimport {\n FreCreationParams,\n Erc20CreateParams,\n PoolCreationParams,\n DispenserCreationParams\n} from '../interfaces'\nimport { Config } from '../models/index.js'\nimport { ProviderFees } from '../@types/index.js'\n\ninterface Template {\n templateAddress: string\n isActive: boolean\n}\n\nexport interface TokenOrder {\n tokenAddress: string\n consumer: string\n serviceIndex: number\n _providerFees: ProviderFees\n}\n\nexport interface NftCreateData {\n name: string\n symbol: string\n templateIndex: number\n tokenURI: string\n}\n\nconst addressZERO = '0x0000000000000000000000000000000000000000'\n/**\n * Provides an interface for NFT Factory contract\n */\nexport class NftFactory {\n public GASLIMIT_DEFAULT = 1000000\n public factory721Address: string\n public factory721Abi: AbiItem | AbiItem[]\n public web3: Web3\n public config: Config\n public factory721: Contract\n\n /**\n * Instantiate Datatokens.\n * @param {String} factory721Address\n * @param {AbiItem | AbiItem[]} factory721ABI\n * @param {Web3} web3\n */\n constructor(\n factory721Address: string,\n web3: Web3,\n factory721Abi?: AbiItem | AbiItem[],\n config?: Config\n ) {\n this.factory721Address = factory721Address\n this.factory721Abi = factory721Abi || (defaultFactory721Abi.abi as AbiItem[])\n this.web3 = web3\n this.config = config || configHelperNetworks[0]\n this.factory721 = setContractDefaults(\n new this.web3.eth.Contract(this.factory721Abi, this.factory721Address),\n this.config\n )\n }\n\n /**\n * Get estimated gas cost for deployERC721Contract value\n * @param {String} address\n * @param {String} nftData\n * @return {Promise<string>} NFT datatoken address\n */\n public async estGasCreateNFT(address: string, nftData: NftCreateData): Promise<string> {\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await this.factory721.methods\n .deployERC721Contract(\n nftData.name,\n nftData.symbol,\n nftData.templateIndex,\n addressZERO,\n nftData.tokenURI\n )\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Create new NFT\n * @param {String} address\n * @param {NFTCreateData} nftData\n * @return {Promise<string>} NFT datatoken address\n */\n public async createNFT(address: string, nftData: NftCreateData): Promise<string> {\n if (!nftData.templateIndex) nftData.templateIndex = 1\n\n if (!nftData.name || !nftData.symbol) {\n const { name, symbol } = generateDtName()\n nftData.name = name\n nftData.symbol = symbol\n }\n if (nftData.templateIndex > (await this.getCurrentNFTTemplateCount())) {\n throw new Error(`Template index doesnt exist`)\n }\n\n if (nftData.templateIndex === 0) {\n throw new Error(`Template index cannot be ZERO`)\n }\n if ((await this.getNFTTemplate(nftData.templateIndex)).isActive === false) {\n throw new Error(`Template is not active`)\n }\n const estGas = await this.estGasCreateNFT(address, nftData)\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.factory721.methods\n .deployERC721Contract(\n nftData.name,\n nftData.symbol,\n nftData.templateIndex,\n addressZERO,\n nftData.tokenURI\n )\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n let tokenAddress = null\n try {\n tokenAddress = trxReceipt.events.NFTCreated.returnValues[0]\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to create datatoken : ${e.message}`)\n }\n return tokenAddress\n }\n\n /** Get Current NFT Count (NFT created)\n * @return {Promise<number>} Number of NFT created from this factory\n */\n public async getCurrentNFTCount(): Promise<number> {\n const trxReceipt = await this.factory721.methods.getCurrentNFTCount().call()\n return trxReceipt\n }\n\n /** Get Current Datatoken Count\n * @return {Promise<number>} Number of DTs created from this factory\n */\n public async getCurrentTokenCount(): Promise<number> {\n const trxReceipt = await this.factory721.methods.getCurrentTokenCount().call()\n return trxReceipt\n }\n\n /** Get Factory Owner\n * @return {Promise<string>} Factory Owner address\n */\n public async getOwner(): Promise<string> {\n const trxReceipt = await this.factory721.methods.owner().call()\n return trxReceipt\n }\n\n /** Get Current NFT Template Count\n * @return {Promise<number>} Number of NFT Template added to this factory\n */\n public async getCurrentNFTTemplateCount(): Promise<number> {\n const count = await this.factory721.methods.getCurrentNFTTemplateCount().call()\n return count\n }\n\n /** Get Current Template Datatoken (ERC20) Count\n * @return {Promise<number>} Number of ERC20 Template added to this factory\n */\n public async getCurrentTokenTemplateCount(): Promise<number> {\n const count = await this.factory721.methods.getCurrentTemplateCount().call()\n return count\n }\n\n /** Get NFT Template\n * @param {Number} index Template index\n * @return {Promise<Template>} Number of Template added to this factory\n */\n public async getNFTTemplate(index: number): Promise<Template> {\n if (index > (await this.getCurrentNFTTemplateCount())) {\n throw new Error(`Template index doesnt exist`)\n }\n\n if (index === 0) {\n throw new Error(`Template index cannot be ZERO`)\n }\n const template = await this.factory721.methods.getNFTTemplate(index).call()\n return template\n }\n\n /** Get Datatoken(erc20) Template\n * @param {Number} index Template index\n * @return {Promise<Template>} DT Template info\n */\n public async getTokenTemplate(index: number): Promise<Template> {\n const template = await this.factory721.methods.getTokenTemplate(index).call()\n return template\n }\n\n /** Check if ERC20 is deployed from the factory\n * @param {String} datatoken Datatoken address we want to check\n * @return {Promise<Boolean>} return true if deployed from this factory\n */\n public async checkDatatoken(datatoken: string): Promise<Boolean> {\n const isDeployed = await this.factory721.methods.erc20List(datatoken).call()\n return isDeployed\n }\n\n /** Check if NFT is deployed from the factory\n * @param {String} nftAddress nftAddress address we want to check\n * @return {Promise<String>} return address(0) if it's not, or the nftAddress if true\n */\n public async checkNFT(nftAddress: string): Promise<String> {\n const confirmAddress = await this.factory721.methods.erc721List(nftAddress).call()\n return confirmAddress\n }\n\n /**\n * Estimate gas cost for add721TokenTemplate method\n * @param {String} address\n * @param {String} templateAddress template address to add\n * @return {Promise<TransactionReceipt>}\n */\n public async estGasAddNFTTemplate(\n address: string,\n templateAddress: string\n ): Promise<any> {\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await this.factory721.methods\n .add721TokenTemplate(templateAddress)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Add a new erc721 token template - only factory Owner\n * @param {String} address\n * @param {String} templateAddress template address to add\n * @return {Promise<TransactionReceipt>}\n */\n public async addNFTTemplate(\n address: string,\n templateAddress: string\n ): Promise<TransactionReceipt> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Factory Owner`)\n }\n if (templateAddress === addressZERO) {\n throw new Error(`Template cannot be ZERO address`)\n }\n\n const estGas = await this.estGasAddNFTTemplate(address, templateAddress)\n\n // Invoke add721TokenTemplate function of the contract\n const trxReceipt = await this.factory721.methods\n .add721TokenTemplate(templateAddress)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for disable721TokenTemplate method\n * @param {String} address\n * @param {Number} templateIndex index of the template we want to disable\n * @return {Promise<TransactionReceipt>} current token template count\n */\n public async estGasDisableNFTTemplate(\n address: string,\n templateIndex: number\n ): Promise<any> {\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await this.factory721.methods\n .disable721TokenTemplate(templateIndex)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Disable token template - only factory Owner\n * @param {String} address\n * @param {Number} templateIndex index of the template we want to disable\n * @return {Promise<TransactionReceipt>} current token template count\n */\n public async disableNFTTemplate(\n address: string,\n templateIndex: number\n ): Promise<TransactionReceipt> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Factory Owner`)\n }\n if (templateIndex > (await this.getCurrentNFTTemplateCount())) {\n throw new Error(`Template index doesnt exist`)\n }\n\n if (templateIndex === 0) {\n throw new Error(`Template index cannot be ZERO`)\n }\n const estGas = await this.estGasDisableNFTTemplate(address, templateIndex)\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.factory721.methods\n .disable721TokenTemplate(templateIndex)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Reactivate a previously disabled token template - only factory Owner\n * @param {String} address\n * @param {Number} templateIndex index of the template we want to reactivate\n * @return {Promise<TransactionReceipt>} current token template count\n */\n public async estGasReactivateNFTTemplate(\n address: string,\n templateIndex: number\n ): Promise<any> {\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await this.factory721.methods\n .reactivate721TokenTemplate(templateIndex)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Reactivate a previously disabled token template - only factory Owner\n * @param {String} address\n * @param {Number} templateIndex index of the template we want to reactivate\n * @return {Promise<TransactionReceipt>} current token template count\n */\n public async reactivateNFTTemplate(\n address: string,\n templateIndex: number\n ): Promise<TransactionReceipt> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Factory Owner`)\n }\n if (templateIndex > (await this.getCurrentNFTTemplateCount())) {\n throw new Error(`Template index doesnt exist`)\n }\n\n if (templateIndex === 0) {\n throw new Error(`Template index cannot be ZERO`)\n }\n\n const estGas = await this.estGasReactivateNFTTemplate(address, templateIndex)\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.factory721.methods\n .reactivate721TokenTemplate(templateIndex)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for addTokenTemplate method\n * @param {String} address\n * @param {String} templateAddress template address to add\n * @return {Promise<TransactionReceipt>}\n */\n public async estGasAddTokenTemplate(\n address: string,\n templateAddress: string\n ): Promise<any> {\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await this.factory721.methods\n .addTokenTemplate(templateAddress)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * Add a new erc721 token template - only factory Owner\n * @param {String} address\n * @param {String} templateAddress template address to add\n * @return {Promise<TransactionReceipt>}\n */\n public async addTokenTemplate(\n address: string,\n templateAddress: string\n ): Promise<TransactionReceipt> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Factory Owner`)\n }\n if (templateAddress === addressZERO) {\n throw new Error(`Template cannot be address ZERO`)\n }\n\n const estGas = await this.estGasAddTokenTemplate(address, templateAddress)\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.factory721.methods\n .addTokenTemplate(templateAddress)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for disableTokenTemplate method\n * @param {String} address\n * @param {Number} templateIndex index of the template we want to disable\n * @return {Promise<TransactionReceipt>} current token template count\n */\n public async estGasDisableTokenTemplate(\n address: string,\n templateIndex: number\n ): Promise<any> {\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await this.factory721.methods\n .disableTokenTemplate(templateIndex)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Disable token template - only factory Owner\n * @param {String} address\n * @param {Number} templateIndex index of the template we want to disable\n * @return {Promise<TransactionReceipt>} current token template count\n */\n public async disableTokenTemplate(\n address: string,\n templateIndex: number\n ): Promise<TransactionReceipt> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Factory Owner`)\n }\n if (templateIndex > (await this.getCurrentNFTTemplateCount())) {\n throw new Error(`Template index doesnt exist`)\n }\n\n if (templateIndex === 0) {\n throw new Error(`Template index cannot be ZERO`)\n }\n if ((await this.getNFTTemplate(templateIndex)).isActive === false) {\n throw new Error(`Template is already disabled`)\n }\n const estGas = await this.estGasDisableTokenTemplate(address, templateIndex)\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.factory721.methods\n .disableTokenTemplate(templateIndex)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for reactivateTokenTemplate method\n * @param {String} address\n * @param {Number} templateIndex index of the template we want to reactivate\n * @return {Promise<TransactionReceipt>} current token template count\n */\n public async estGasReactivateTokenTemplate(\n address: string,\n templateIndex: number\n ): Promise<any> {\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await this.factory721.methods\n .reactivateTokenTemplate(templateIndex)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Reactivate a previously disabled token template - only factory Owner\n * @param {String} address\n * @param {Number} templateIndex index of the template we want to reactivate\n * @return {Promise<TransactionReceipt>} current token template count\n */\n public async reactivateTokenTemplate(\n address: string,\n templateIndex: number\n ): Promise<TransactionReceipt> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Factory Owner`)\n }\n if (templateIndex > (await this.getCurrentNFTTemplateCount())) {\n throw new Error(`Template index doesnt exist`)\n }\n\n if (templateIndex === 0) {\n throw new Error(`Template index cannot be ZERO`)\n }\n if ((await this.getTokenTemplate(templateIndex)).isActive === true) {\n throw new Error(`Template is already active`)\n }\n\n const estGas = await this.estGasReactivateTokenTemplate(address, templateIndex)\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.factory721.methods\n .reactivateTokenTemplate(templateIndex)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /** Estimate gas cost for startMultipleTokenOrder method\n * @param address Caller address\n * @param orders an array of struct tokenOrder\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async estGasStartMultipleTokenOrder(\n address: string,\n orders: TokenOrder[]\n ): Promise<any> {\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await this.factory721.methods\n .startMultipleTokenOrder(orders)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * @dev startMultipleTokenOrder\n * Used as a proxy to order multiple services\n * Users can have inifinite approvals for fees for factory instead of having one approval/ erc20 contract\n * Requires previous approval of all :\n * - consumeFeeTokens\n * - publishMarketFeeTokens\n * - erc20 datatokens\n * @param address Caller address\n * @param orders an array of struct tokenOrder\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async startMultipleTokenOrder(\n address: string,\n orders: TokenOrder[]\n ): Promise<TransactionReceipt> {\n if (orders.length > 50) {\n throw new Error(`Too many orders`)\n }\n\n const estGas = await this.estGasStartMultipleTokenOrder(address, orders)\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.factory721.methods\n .startMultipleTokenOrder(orders)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for createNftWithErc method\n * @param address Caller address\n * @param _NftCreateData input data for nft creation\n * @param _ErcCreateData input data for erc20 creation\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n\n public async estGasCreateNftWithErc(\n address: string,\n nftCreateData: NftCreateData,\n ercParams: Erc20CreateParams\n ): Promise<any> {\n // Get estimated gas value\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n const ercCreateData = getErcCreationParams(ercParams)\n estGas = await this.factory721.methods\n .createNftWithErc(nftCreateData, ercCreateData)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * @dev createNftWithErc\n * Creates a new NFT, then a ERC20,all in one call\n * @param address Caller address\n * @param _NftCreateData input data for nft creation\n * @param _ErcCreateData input data for erc20 creation\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n\n public async createNftWithErc(\n address: string,\n nftCreateData: NftCreateData,\n ercParams: Erc20CreateParams\n ): Promise<TransactionReceipt> {\n const ercCreateData = getErcCreationParams(ercParams)\n\n const estGas = await this.estGasCreateNftWithErc(address, nftCreateData, ercParams)\n // Invoke createToken function of the contract\n const trxReceipt = await this.factory721.methods\n .createNftWithErc(nftCreateData, ercCreateData)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for createNftErcWithPool method\n * @param address Caller address\n * @param nftCreateData input data for NFT Creation\n * @param ercParams input data for ERC20 Creation\n * @param poolParams input data for Pool Creation\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async estGasCreateNftErcWithPool(\n address: string,\n nftCreateData: NftCreateData,\n ercParams: Erc20CreateParams,\n poolParams: PoolCreationParams\n ): Promise<any> {\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n const ercCreateData = getErcCreationParams(ercParams)\n const poolData = getPoolCreationParams(poolParams)\n estGas = await this.factory721.methods\n .createNftErcWithPool(nftCreateData, ercCreateData, poolData)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * @dev createNftErcWithPool\n * Creates a new NFT, then a ERC20, then a Pool, all in one call\n * Use this carefully, because if Pool creation fails, you are still going to pay a lot of gas\n * @param address Caller address\n * @param nftCreateData input data for NFT Creation\n * @param ercParams input data for ERC20 Creation\n * @param poolParams input data for Pool Creation\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async createNftErcWithPool(\n address: string,\n nftCreateData: NftCreateData,\n ercParams: Erc20CreateParams,\n poolParams: PoolCreationParams\n ): Promise<TransactionReceipt> {\n const estGas = await this.estGasCreateNftErcWithPool(\n address,\n nftCreateData,\n ercParams,\n poolParams\n )\n const ercCreateData = getErcCreationParams(ercParams)\n const poolData = getPoolCreationParams(poolParams)\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.factory721.methods\n .createNftErcWithPool(nftCreateData, ercCreateData, poolData)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /** Estimate gas cost for createNftErcWithFixedRate method\n * @param address Caller address\n * @param nftCreateData input data for NFT Creation\n * @param ercParams input data for ERC20 Creation\n * @param freParams input data for FixedRate Creation\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async estGasCreateNftErcWithFixedRate(\n address: string,\n nftCreateData: NftCreateData,\n ercParams: Erc20CreateParams,\n freParams: FreCreationParams\n ): Promise<any> {\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n\n const ercCreateData = getErcCreationParams(ercParams)\n\n const fixedData = getFreCreationParams(freParams)\n\n try {\n estGas = await this.factory721.methods\n .createNftErcWithFixedRate(nftCreateData, ercCreateData, fixedData)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * @dev createNftErcWithFixedRate\n * Creates a new NFT, then a ERC20, then a FixedRateExchange, all in one call\n * Use this carefully, because if Fixed Rate creation fails, you are still going to pay a lot of gas\n * @param address Caller address\n * @param nftCreateData input data for NFT Creation\n * @param ercParams input data for ERC20 Creation\n * @param freParams input data for FixedRate Creation\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async createNftErcWithFixedRate(\n address: string,\n nftCreateData: NftCreateData,\n ercParams: Erc20CreateParams,\n freParams: FreCreationParams\n ): Promise<TransactionReceipt> {\n const ercCreateData = getErcCreationParams(ercParams)\n const fixedData = getFreCreationParams(freParams)\n\n const estGas = await this.estGasCreateNftErcWithFixedRate(\n address,\n nftCreateData,\n ercParams,\n freParams\n )\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.factory721.methods\n .createNftErcWithFixedRate(nftCreateData, ercCreateData, fixedData)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /** Estimate gas cost for createNftErcWithFixedRate method\n * @param address Caller address\n * @param nftCreateData input data for NFT Creation\n * @param ercParams input data for ERC20 Creation\n * @param dispenserParams input data for Dispenser Creation\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async estGasCreateNftErcWithDispenser(\n address: string,\n nftCreateData: NftCreateData,\n ercParams: Erc20CreateParams,\n dispenserParams: DispenserCreationParams\n ): Promise<any> {\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n\n const ercCreateData = getErcCreationParams(ercParams)\n\n try {\n estGas = await this.factory721.methods\n .createNftErcWithDispenser(nftCreateData, ercCreateData, dispenserParams)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n LoggerInstance.error('Failed to estimate gas for createNftErcWithDispenser', e)\n }\n return estGas\n }\n\n /**\n * @dev createNftErcWithDispenser\n * Creates a new NFT, then a ERC20, then a Dispenser, all in one call\n * Use this carefully, because if Dispenser creation fails, you are still going to pay a lot of gas\n * @param address Caller address\n * @param nftCreateData input data for NFT Creation\n * @param ercParams input data for ERC20 Creation\n * @param dispenserParams input data for Dispenser Creation\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async createNftErcWithDispenser(\n address: string,\n nftCreateData: NftCreateData,\n ercParams: Erc20CreateParams,\n dispenserParams: DispenserCreationParams\n ): Promise<TransactionReceipt> {\n const ercCreateData = getErcCreationParams(ercParams)\n\n const estGas = await this.estGasCreateNftErcWithDispenser(\n address,\n nftCreateData,\n ercParams,\n dispenserParams\n )\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.factory721.methods\n .createNftErcWithDispenser(nftCreateData, ercCreateData, dispenserParams)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n}\n","import { LogLevel } from '../utils/Logger'\nimport { AbiItem } from 'web3-utils/types'\n\nexport class Config {\n /**\n * Ethereum node URL.\n * @type {string}\n */\n public nodeUri?: string\n\n /**\n * Address of Provider.\n * @type {string}\n */\n public providerAddress?: string\n\n /**\n * Metadata Store URL.\n * @type {string}\n */\n public metadataCacheUri?: string\n\n /**\n * Provider URL.\n * @type {string}\n */\n public providerUri?: string\n\n /**\n * Web3 Provider.\n * @type {any}\n */\n public web3Provider?: any\n\n /**\n * Ocean Token address\n * @type {string}\n */\n public oceanTokenAddress?: string\n\n /**\n * Factory address\n * @type {string}\n */\n public erc721FactoryAddress?: string\n\n /**\n * Factory ABI\n * @type {string}\n */\n public erc721FFactoryABI?: AbiItem | AbiItem[]\n\n /**\n * datatokens ABI\n * @type {string}\n */\n public datatokensABI?: AbiItem | AbiItem[]\n\n /**\n * Pool Template address\n * @type {string}\n */\n public poolTemplateAddress?: string\n\n /**\n * Pool Factory ABI\n * @type {string}\n */\n public poolFactoryABI?: AbiItem | AbiItem[]\n\n /**\n * Pool ABI\n * @type {string}\n */\n public poolABI?: AbiItem | AbiItem[]\n\n /**\n * FixedRateExchangeAddress\n * @type {string}\n */\n public fixedRateExchangeAddress?: string\n\n /**\n * FixedRateExchangeAddressABI\n * @type {any}\n */\n public fixedRateExchangeAddressABI?: AbiItem | AbiItem[]\n\n /**\n * DispenserAddress\n * @type {string}\n */\n public dispenserAddress?: string\n\n /**\n * DispenserABI\n * @type {any}\n */\n public dispenserABI?: AbiItem | AbiItem[]\n\n /**\n * OPFCommunityFeeCollector\n * @type {string}\n */\n public opfCommunityFeeCollector?: string\n\n /**\n * SideStaking address\n * @type {string}\n */\n public sideStakingAddress?: string\n\n /**\n * block number of the deployment\n * @type {number}\n */\n public startBlock?: number\n /**\n * Log level.\n * @type {boolean | LogLevel}\n */\n public verbose?: boolean | LogLevel\n\n /**\n * Message shown when the user creates its own token.\n * @type {string}\n */\n public authMessage?: string\n\n /**\n * Token expiration time in ms.\n * @type {number}\n */\n public authTokenExpiration?: number\n\n /**\n * Parity config\n * @type {string}\n */\n public parityUri?: string\n\n public threshold?: number\n\n /**\n * Chain ID\n * @type {number}\n */\n chainId: number\n\n /**\n * Network name ex: mainnet, rinkeby, polygon\n * @type {string}\n */\n network: string\n\n /**\n * Url of the relevant subgraph instance ex: https://subgraph.mainnet.oceanprotocol.com\n * @type {string}\n */\n subgraphUri: string\n\n /**\n * Url of the blockchain exporer ex: https://etherscan.io\n * @type {string}\n */\n explorerUri: string\n\n /**\n * Ocean toke symbol on the chain, it's used just for convenience to reduce number of calls\n * @type {string}\n */\n oceanTokenSymbol: string\n\n /**\n * Specify the transaction Block Timeout\n * @type {number}\n */\n transactionBlockTimeout: number\n\n /**\n * Specify the transaction Confirmation Blocks\n * @type {number}\n */\n transactionConfirmationBlocks: number\n\n /**\n * Specify the transaction Polling Blocks Timeout\n * @type {number}\n */\n transactionPollingTimeout: number\n\n /**\n * Specify the multiplier for the gas fee\n * @type {number}\n */\n gasFeeMultiplier: number\n}\n\nexport default Config\n","import { LoggerInstance } from './Logger'\n\nexport const zeroX = (input: string): string => zeroXTransformer(input, true)\nexport const noZeroX = (input: string): string => zeroXTransformer(input, false)\nexport function zeroXTransformer(input = '', zeroOutput: boolean): string {\n const { valid, output } = inputMatch(input, /^(?:0x)*([a-f0-9]+)$/i, 'zeroXTransformer')\n return (zeroOutput && valid ? '0x' : '') + output\n}\n\n// Shared functions\nfunction inputMatch(\n input: string,\n regexp: RegExp,\n conversorName: string\n): { valid: boolean; output: string } {\n if (typeof input !== 'string') {\n LoggerInstance.debug('Not input string:')\n LoggerInstance.debug(input)\n throw new Error(`[${conversorName}] Expected string, input type: ${typeof input}`)\n }\n const match = input.match(regexp)\n if (!match) {\n LoggerInstance.warn(`[${conversorName}] Input transformation failed.`)\n return { valid: false, output: input }\n }\n return { valid: true, output: match[1] }\n}\n","import Web3 from 'web3'\nimport { LoggerInstance, getData, crossFetchGeneric } from '../utils'\nimport {\n FileMetadata,\n ComputeJob,\n ComputeOutput,\n ComputeAlgorithm,\n ComputeAsset,\n ProviderInitialize\n} from '../@types/'\nimport { noZeroX } from '../utils/ConversionTypeHelper'\nimport { signText, signWithHash } from '../utils/SignatureUtils'\n\nexport interface ServiceEndpoint {\n serviceName: string\n method: string\n urlPath: string\n}\nexport interface UserCustomParameters {\n [key: string]: any\n}\n\nexport class Provider {\n /**\n * Returns the provider endpoints\n * @param {any} fetchMethod\n * @return {Promise<ServiceEndpoint[]>}\n */\n async getEndpoints(providerUri: string): Promise<any> {\n try {\n const endpoints = await getData(providerUri)\n return await endpoints.json()\n } catch (e) {\n LoggerInstance.error('Finding the service endpoints failed:', e)\n return null\n }\n }\n\n getEndpointURL(\n servicesEndpoints: ServiceEndpoint[],\n serviceName: string\n ): ServiceEndpoint {\n if (!servicesEndpoints) return null\n return servicesEndpoints.find((s) => s.serviceName === serviceName) as ServiceEndpoint\n }\n\n /**\n * Returns the service endpoints that exist in provider.\n * @param {any} endpoints\n * @return {Promise<ServiceEndpoint[]>}\n */\n public async getServiceEndpoints(providerEndpoint: string, endpoints: any) {\n const serviceEndpoints: ServiceEndpoint[] = []\n for (const i in endpoints.serviceEndpoints) {\n const endpoint: ServiceEndpoint = {\n serviceName: i,\n method: endpoints.serviceEndpoints[i][0],\n urlPath: providerEndpoint + endpoints.serviceEndpoints[i][1]\n }\n serviceEndpoints.push(endpoint)\n }\n return serviceEndpoints\n }\n\n /** Encrypt DDO using the Provider's own symmetric key\n * @param {string} providerUri provider uri address\n * @param {string} consumerAddress Publisher address\n * @param {string} fetchMethod fetch client instance\n * @param {string} providerEndpoints Identifier of the asset to be registered in ocean\n * @param {string} serviceEndpoints document description object (DDO)=\n * @return {Promise<string>} urlDetails\n */\n public async getNonce(\n providerUri: string,\n consumerAddress: string,\n fetchMethod?: any,\n providerEndpoints?: any,\n serviceEndpoints?: ServiceEndpoint[]\n ): Promise<string> {\n const preferedFetch = fetchMethod || crossFetchGeneric\n if (!providerEndpoints) {\n providerEndpoints = await this.getEndpoints(providerUri)\n }\n if (!serviceEndpoints) {\n serviceEndpoints = await this.getServiceEndpoints(providerUri, providerEndpoints)\n }\n const path = this.getEndpointURL(serviceEndpoints, 'nonce')\n ? this.getEndpointURL(serviceEndpoints, 'nonce').urlPath\n : null\n if (!path) return null\n try {\n const response = await preferedFetch(\n 'GET',\n path + `?userAddress=${consumerAddress}`,\n null,\n {\n 'Content-Type': 'application/json'\n }\n )\n return String((await response.json()).nonce)\n } catch (e) {\n LoggerInstance.error(e)\n throw new Error('HTTP request failed')\n }\n }\n\n public async createSignature(\n web3: Web3,\n accountId: string,\n agreementId: string\n ): Promise<string> {\n const signature = await signText(web3, noZeroX(agreementId), accountId)\n return signature\n }\n\n public async createHashSignature(\n web3: Web3,\n accountId: string,\n message: string\n ): Promise<string> {\n const signature = await signWithHash(web3, message, accountId)\n return signature\n }\n\n /** Encrypt data using the Provider's own symmetric key\n * @param {string} data data in json format that needs to be sent , it can either be a DDO or a File array\n * @param {string} providerUri provider uri address\n * @param {string} postMethod http post method\n * @return {Promise<string>} urlDetails\n */\n public async encrypt(data: any, providerUri: string, postMethod?: any): Promise<any> {\n const preferedFetch = postMethod || crossFetchGeneric\n const providerEndpoints = await this.getEndpoints(providerUri)\n const serviceEndpoints = await this.getServiceEndpoints(\n providerUri,\n providerEndpoints\n )\n const path = this.getEndpointURL(serviceEndpoints, 'encrypt')\n ? this.getEndpointURL(serviceEndpoints, 'encrypt').urlPath\n : null\n\n if (!path) return null\n try {\n const response = await preferedFetch(\n 'POST',\n path,\n decodeURI(JSON.stringify(data)),\n {\n 'Content-Type': 'application/octet-stream'\n }\n )\n return response\n } catch (e) {\n LoggerInstance.error(e)\n throw new Error('HTTP request failed')\n }\n }\n\n /** Get DDO File details (if possible)\n * @param {string} did did\n * @param {number} serviceId the id of the service for which to check the files\n * @param {string} providerUri uri of the provider that will be used to check the file\n * @param {string} fetchMethod fetch client instance\n * @return {Promise<FileMetadata[]>} urlDetails\n */\n public async checkDidFiles(\n did: string,\n serviceId: number,\n providerUri: string,\n fetchMethod?: any\n ): Promise<FileMetadata[]> {\n const preferedFetch = fetchMethod || crossFetchGeneric\n const providerEndpoints = await this.getEndpoints(providerUri)\n const serviceEndpoints = await this.getServiceEndpoints(\n providerUri,\n providerEndpoints\n )\n const args = { did: did, serviceId: serviceId }\n const files: FileMetadata[] = []\n const path = this.getEndpointURL(serviceEndpoints, 'fileinfo')\n ? this.getEndpointURL(serviceEndpoints, 'fileinfo').urlPath\n : null\n if (!path) return null\n try {\n const response = await preferedFetch('POST', path, JSON.stringify(args), {\n 'Content-Type': 'application/json'\n })\n const results: FileMetadata[] = response.data\n ? response.data\n : await response.json()\n for (const result of results) {\n files.push(result)\n }\n return files\n } catch (e) {\n return null\n }\n }\n\n /** Get URL details (if possible)\n * @param {string} url or did\n * @param {string} providerUri uri of the provider that will be used to check the file\n * @param {string} fetchMethod fetch client instance\n * @return {Promise<FileMetadata[]>} urlDetails\n */\n public async checkFileUrl(\n url: string,\n providerUri: string,\n fetchMethod?: any\n ): Promise<FileMetadata[]> {\n const preferedFetch = fetchMethod || crossFetchGeneric\n const providerEndpoints = await this.getEndpoints(providerUri)\n const serviceEndpoints = await this.getServiceEndpoints(\n providerUri,\n providerEndpoints\n )\n const args = { url: url, type: 'url' }\n const files: FileMetadata[] = []\n const path = this.getEndpointURL(serviceEndpoints, 'fileinfo')\n ? this.getEndpointURL(serviceEndpoints, 'fileinfo').urlPath\n : null\n if (!path) return null\n try {\n const response = await preferedFetch('POST', path, JSON.stringify(args), {\n 'Content-Type': 'application/json'\n })\n const results: FileMetadata[] = response.data\n ? response.data\n : await response.json()\n for (const result of results) {\n files.push(result)\n }\n return files\n } catch (e) {\n return null\n }\n }\n\n /** Initialize a service request.\n * @param {DDO | string} asset\n * @param {number} serviceIndex\n * @param {string} serviceType\n * @param {string} consumerAddress\n * @param {UserCustomParameters} userCustomParameters\n * @param {string} providerUri Identifier of the asset to be registered in ocean\n * @param {string} fetchMethod fetch client instance\n * @return {Promise<ProviderInitialize>} ProviderInitialize data\n */\n public async initialize(\n did: string,\n serviceId: string,\n fileIndex: number,\n consumerAddress: string,\n providerUri: string,\n fetchMethod?: any,\n userCustomParameters?: UserCustomParameters,\n computeEnv?: string,\n validUntil?: number\n ): Promise<ProviderInitialize> {\n const preferedFetch = fetchMethod || crossFetchGeneric\n const providerEndpoints = await this.getEndpoints(providerUri)\n const serviceEndpoints = await this.getServiceEndpoints(\n providerUri,\n providerEndpoints\n )\n let initializeUrl = this.getEndpointURL(serviceEndpoints, 'initialize')\n ? this.getEndpointURL(serviceEndpoints, 'initialize').urlPath\n : null\n\n if (!initializeUrl) return null\n initializeUrl += `?documentId=${did}`\n initializeUrl += `&serviceId=${serviceId}`\n initializeUrl += `&fileIndex=${fileIndex}`\n initializeUrl += `&consumerAddress=${consumerAddress}`\n if (userCustomParameters)\n initializeUrl += '&userdata=' + encodeURI(JSON.stringify(userCustomParameters))\n if (computeEnv) initializeUrl += '&computeEnv=' + encodeURI(computeEnv)\n if (validUntil) initializeUrl += '&validUntil=' + validUntil\n try {\n const response = await preferedFetch('GET', initializeUrl, null, {\n 'Content-Type': 'application/json'\n })\n const results: ProviderInitialize = response.data\n ? response.data\n : await response.json()\n return results\n } catch (e) {\n LoggerInstance.error(e)\n throw new Error('Asset URL not found or not available.')\n }\n }\n\n /** Gets fully signed URL for download\n * @param {string} did\n * @param {string} accountId\n * @param {string} serviceId\n * @param {number} fileIndex\n * @param {string} providerUri\n * @param {Web3} web3\n * @param {any} fetchMethod\n * @param {UserCustomParameters} userCustomParameters\n * @return {Promise<string>}\n */\n public async getDownloadUrl(\n did: string,\n accountId: string,\n serviceId: string,\n fileIndex: number,\n transferTxId: string,\n providerUri: string,\n web3: Web3,\n userCustomParameters?: UserCustomParameters\n ): Promise<any> {\n const providerEndpoints = await this.getEndpoints(providerUri)\n const serviceEndpoints = await this.getServiceEndpoints(\n providerUri,\n providerEndpoints\n )\n const downloadUrl = this.getEndpointURL(serviceEndpoints, 'download')\n ? this.getEndpointURL(serviceEndpoints, 'download').urlPath\n : null\n if (!downloadUrl) return null\n const nonce = Date.now()\n const signature = await this.createSignature(web3, accountId, did + nonce)\n\n let consumeUrl = downloadUrl\n consumeUrl += `?fileIndex=${fileIndex}`\n consumeUrl += `&documentId=${did}`\n consumeUrl += `&transferTxId=${transferTxId}`\n consumeUrl += `&serviceId=${serviceId}`\n consumeUrl += `&consumerAddress=${accountId}`\n consumeUrl += `&nonce=${nonce}`\n consumeUrl += `&signature=${signature}`\n if (userCustomParameters)\n consumeUrl += '&userdata=' + encodeURI(JSON.stringify(userCustomParameters))\n return consumeUrl\n }\n\n /** Instruct the provider to start a compute job\n * @param {string} did\n * @param {string} consumerAddress\n * @param {ComputeAlgorithm} algorithm\n * @param {string} providerUri\n * @param {Web3} web3\n * @param {any} fetchMethod\n * @param {ComputeOutput} output\n * @return {Promise<ComputeJob | ComputeJob[]>}\n */\n public async computeStart(\n providerUri: string,\n web3: Web3,\n consumerAddress: string,\n computeEnv: string,\n dataset: ComputeAsset,\n algorithm: ComputeAlgorithm,\n fetchMethod?: any,\n additionalDatasets?: ComputeAsset[],\n output?: ComputeOutput\n ): Promise<ComputeJob | ComputeJob[]> {\n const preferedFetch = fetchMethod || crossFetchGeneric\n const providerEndpoints = await this.getEndpoints(providerUri)\n const serviceEndpoints = await this.getServiceEndpoints(\n providerUri,\n providerEndpoints\n )\n const computeStartUrl = this.getEndpointURL(serviceEndpoints, 'computeStart')\n ? this.getEndpointURL(serviceEndpoints, 'computeStart').urlPath\n : null\n\n const nonce = Date.now()\n let signatureMessage = consumerAddress\n signatureMessage += dataset.documentId\n signatureMessage += nonce\n const signature = await this.createHashSignature(\n web3,\n consumerAddress,\n signatureMessage\n )\n\n const payload = Object()\n payload.consumerAddress = consumerAddress\n payload.signature = signature\n payload.nonce = nonce\n payload.computeEnv = computeEnv\n payload.dataset = dataset\n payload.algorithm = algorithm\n if (payload.additionalDatasets) payload.additionalDatasets = additionalDatasets\n if (output) payload.output = output\n if (!computeStartUrl) return null\n try {\n const response = await preferedFetch(\n 'POST',\n computeStartUrl,\n JSON.stringify(payload),\n {\n 'Content-Type': 'application/json'\n }\n )\n if (response?.ok) {\n const params = response.data ? response.data : await response.json()\n return params\n }\n console.error('Compute start failed:', response.status, response.statusText)\n LoggerInstance.error('Payload was:', payload)\n return null\n } catch (e) {\n LoggerInstance.error('Compute start failed:')\n LoggerInstance.error(e)\n LoggerInstance.error('Payload was:', payload)\n return null\n }\n }\n\n /** Instruct the provider to Stop the execution of a to stop a compute job.\n * @param {string} did\n * @param {string} consumerAddress\n * @param {string} jobId\n * @param {string} providerUri\n * @param {Web3} web3\n * @param {any} fetchMethod\n * @return {Promise<ComputeJob | ComputeJob[]>}\n */\n public async computeStop(\n did: string,\n consumerAddress: string,\n jobId: string,\n providerUri: string,\n web3: Web3,\n fetchMethod?: any\n ): Promise<ComputeJob | ComputeJob[]> {\n const preferedFetch = fetchMethod || crossFetchGeneric\n const providerEndpoints = await this.getEndpoints(providerUri)\n const serviceEndpoints = await this.getServiceEndpoints(\n providerUri,\n providerEndpoints\n )\n const computeStopUrl = this.getEndpointURL(serviceEndpoints, 'computeStop')\n ? this.getEndpointURL(serviceEndpoints, 'computeStop').urlPath\n : null\n\n const nonce = await this.getNonce(\n providerUri,\n consumerAddress,\n fetchMethod,\n providerEndpoints,\n serviceEndpoints\n )\n\n let signatureMessage = consumerAddress\n signatureMessage += jobId || ''\n signatureMessage += (did && `${noZeroX(did)}`) || ''\n signatureMessage += nonce\n const signature = await this.createHashSignature(\n web3,\n consumerAddress,\n signatureMessage\n )\n\n const payload = Object()\n payload.signature = signature\n payload.documentId = noZeroX(did)\n payload.consumerAddress = consumerAddress\n if (jobId) payload.jobId = jobId\n\n if (!computeStopUrl) return null\n try {\n const response = await preferedFetch(\n 'PUT',\n computeStopUrl,\n JSON.stringify(payload),\n {\n 'Content-Type': 'application/json'\n }\n )\n if (response?.ok) {\n const params = response.data ? response.data : await response.json()\n return params\n }\n LoggerInstance.error('Compute stop failed:', response.status, response.statusText)\n LoggerInstance.error('Payload was:', payload)\n return null\n } catch (e) {\n LoggerInstance.error('Compute stop failed:')\n LoggerInstance.error(e)\n LoggerInstance.error('Payload was:', payload)\n return null\n }\n }\n\n /** Get status for a specific jobId/documentId/owner.\n * @param {string} did\n * @param {string} consumerAddress\n * @param {string} providerUri\n * @param {Web3} web3\n * @param {any} fetchMethod\n * @param {string} jobId\n * @return {Promise<ComputeJob | ComputeJob[]>}\n */\n public async computeStatus(\n providerUri: string,\n fetchMethod?: any,\n jobId?: string,\n did?: string,\n consumerAddress?: string\n ): Promise<ComputeJob | ComputeJob[]> {\n if (!jobId && !did && !consumerAddress) {\n throw new Error('You need at least one of jobId, did, consumerAddress')\n }\n const preferedFetch = fetchMethod || crossFetchGeneric\n\n const providerEndpoints = await this.getEndpoints(providerUri)\n const serviceEndpoints = await this.getServiceEndpoints(\n providerUri,\n providerEndpoints\n )\n const computeStatusUrl = this.getEndpointURL(serviceEndpoints, 'computeStatus')\n ? this.getEndpointURL(serviceEndpoints, 'computeStatus').urlPath\n : null\n\n let url = '?documentId=' + noZeroX(did)\n url += `&consumerAddress=${consumerAddress}`\n url += (jobId && `&jobId=${jobId}`) || ''\n\n if (!computeStatusUrl) return null\n try {\n const response = await preferedFetch('GET', computeStatusUrl + url, null, {\n 'Content-Type': 'application/json'\n })\n if (response?.ok) {\n const params = response.data ? response.data : await response.json()\n return params\n }\n LoggerInstance.error(\n 'Get compute status failed:',\n response.status,\n response.statusText\n )\n return null\n } catch (e) {\n LoggerInstance.error('Get compute status failed')\n LoggerInstance.error(e)\n return null\n }\n }\n\n /** Get status for a specific jobId/documentId/owner.\n * @param {string} jobId\n * @param {number} index\n * @param {string} providerUri\n * @param {string} destination\n * @param {Web3} web3\n * @param {any} fetchMethod\n * @return {Promise<ComputeJob | ComputeJob[]>}\n */\n public async computeResult(\n jobId: string,\n index: number,\n destination: string,\n accountId: string,\n providerUri: string,\n web3: Web3,\n fetchMethod: any\n ): Promise<any> {\n const providerEndpoints = await this.getEndpoints(providerUri)\n const serviceEndpoints = await this.getServiceEndpoints(\n providerUri,\n providerEndpoints\n )\n const computeResultUrl = this.getEndpointURL(serviceEndpoints, 'computeResult')\n ? this.getEndpointURL(serviceEndpoints, 'computeResult').urlPath\n : null\n\n const nonce = await this.getNonce(\n providerUri,\n accountId,\n fetchMethod,\n providerEndpoints,\n serviceEndpoints\n )\n\n let signatureMessage = accountId\n signatureMessage += jobId\n signatureMessage += String(index)\n signatureMessage += nonce\n const signature = await this.createHashSignature(web3, accountId, signatureMessage)\n\n let consumeUrl = computeResultUrl\n consumeUrl += `?consumerAddress=${accountId}`\n consumeUrl += `&jobId=${jobId}`\n consumeUrl += `&index=${String(index)}`\n consumeUrl += (signature && `&signature=${signature}`) || ''\n\n if (!computeResultUrl) return null\n try {\n !destination\n ? await fetchMethod.downloadFileBrowser(consumeUrl)\n : await fetchMethod.downloadFile(consumeUrl, destination, index)\n } catch (e) {\n LoggerInstance.error('Error getting job result')\n LoggerInstance.error(e)\n throw e\n }\n return destination\n }\n\n /** Deletes a compute job.\n * @param {string} did\n * @param {string} consumerAddress\n * @param {string} jobId\n * @param {string} providerUri\n * @param {Web3} web3\n * @param {any} fetchMethod\n * @return {Promise<ComputeJob | ComputeJob[]>}\n */\n public async computeDelete(\n did: string,\n consumerAddress: string,\n jobId: string,\n providerUri: string,\n web3: Web3,\n fetchMethod?: any\n ): Promise<ComputeJob | ComputeJob[]> {\n const preferedFetch = fetchMethod || crossFetchGeneric\n const providerEndpoints = await this.getEndpoints(providerUri)\n const serviceEndpoints = await this.getServiceEndpoints(\n providerUri,\n providerEndpoints\n )\n const computeDeleteUrl = this.getEndpointURL(serviceEndpoints, 'computeDelete')\n ? this.getEndpointURL(serviceEndpoints, 'computeDelete').urlPath\n : null\n\n const nonce = await this.getNonce(\n providerUri,\n consumerAddress,\n fetchMethod,\n providerEndpoints,\n serviceEndpoints\n )\n\n let signatureMessage = consumerAddress\n signatureMessage += jobId || ''\n signatureMessage += (did && `${noZeroX(did)}`) || ''\n signatureMessage += nonce\n const signature = await this.createHashSignature(\n web3,\n consumerAddress,\n signatureMessage\n )\n\n const payload = Object()\n payload.documentId = noZeroX(did)\n payload.consumerAddress = consumerAddress\n payload.jobId = jobId\n if (signature) payload.signature = signature\n\n if (!computeDeleteUrl) return null\n try {\n const response = await preferedFetch(\n 'DELETE',\n computeDeleteUrl,\n JSON.stringify(payload),\n {\n 'Content-Type': 'application/json'\n }\n )\n if (response?.ok) {\n const params = response.data ? response.data : await response.json()\n return params\n }\n LoggerInstance.error(\n 'Delete compute job failed:',\n response.status,\n response.statusText\n )\n LoggerInstance.error('Payload was:', payload)\n return null\n } catch (e) {\n LoggerInstance.error('Delete compute job failed:')\n LoggerInstance.error(e)\n LoggerInstance.error('Payload was:', payload)\n return null\n }\n }\n\n /** Check for a valid provider at URL\n * @param {String} url provider uri address\n * @param {String} fetchMethod fetch client instance\n * @return {Promise<boolean>} string\n */\n public async isValidProvider(url: string, fetchMethod?: any): Promise<boolean> {\n try {\n const preferedFetch = fetchMethod || crossFetchGeneric\n const response = await preferedFetch('GET', url, null, {\n 'Content-Type': 'application/json'\n })\n if (response?.ok) {\n const params = response.data ? response.data : await response.json()\n if (params && params.providerAddress) return true\n }\n return false\n } catch (error) {\n LoggerInstance.error(`Error validating provider: ${error.message}`)\n return false\n }\n }\n}\n\nexport const ProviderInstance = new Provider()\nexport default ProviderInstance\n"],"names":["LogLevel","Logger","logLevel","Error","this","setLevel","bypass","dispatch","Infinity","debug","Verbose","log","Log","warn","Warn","error","verb","level","console","LoggerInstance","generateDtName","wordList","list","wordListDefault","random1","Math","floor","random","adjectives","length","random2","nouns","indexNumber","adjective","replace","c","toUpperCase","noun","name","symbol","substring","getFairGasPrice","web3","config","eth","getGasPrice","x","BigNumber","gasFeeMultiplier","multipliedBy","integerValue","ROUND_DOWN","toString","setContractDefaults","contract","transactionBlockTimeout","transactionConfirmationBlocks","transactionPollingTimeout","getErcCreationParams","ercParams","templateIndex","strings","addresses","minter","feeManager","mpFeeAddress","feeToken","uints","Web3","utils","toWei","cap","feeAmount","bytess","getFreCreationParams","freParams","allowedConsumer","fixedPriceAddress","fixedRateAddress","baseTokenAddress","owner","marketFeeCollector","baseTokenDecimals","datatokenDecimals","fixedRate","marketFee","withMint","getPoolCreationParams","poolParams","ssContract","baseTokenSender","publisherAddress","poolTemplateAddress","ssParams","rate","vestingAmount","vestedBlocks","initialBaseTokenLiquidity","swapFees","swapFeeLiquidityProvider","swapFeeMarketRunner","crossFetchGeneric","method","url","body","headers","fetch","postData","payload","postWithHeaders","getData","downloadFile","destination","index","response","ok","filename","get","match","split","pop","fs","mkdirSync","recursive","writeFileSync","text","_writeFileSync2","arrayBuffer","save","fetchData","opts","result","_error2","configHelperNetworksBase","chainId","network","metadataCacheUri","nodeUri","providerUri","subgraphUri","explorerUri","oceanTokenAddress","oceanTokenSymbol","fixedRateExchangeAddress","dispenserAddress","startBlock","configHelperNetworks","ConfigHelper","getAddressesFromEnv","configAddresses","DefaultContractsAddresses","erc721FactoryAddress","ERC721Factory","sideStakingAddress","Staking","opfCommunityFeeCollector","OPFCommunityFeeCollector","poolTemplate","FixedPrice","Dispenser","Ocean","process","env","AQUARIUS_URI","ADDRESS_FILE","JSON","parse","readFileSync","e","getConfig","infuraProjectId","filterBy","find","generateDid","erc721Address","toChecksumAddress","sha256","getHash","data","ZERO_ADDRESS","signWithHash","publicKey","password","hash","utf8ToHex","isMetaMask","currentProvider","personal","sign","e2","signHash","message","address","signedMessage","r","substr","slice","s","v","signText","_catch","then","MaxUint256","prototype","state","value","_this","thenable","shouldContinue","Pool","logger","poolAbi","GASLIMIT_DEFAULT","PoolTemplate","abi","estApprove","account","tokenAddress","spender","amount","contractInstance","estGas","tokenContract","Contract","defaultErc20Abi","_this2","gasLimitDefault","methods","approve","estimateGas","from","err","allowance","datatoken","_this4","call","trxReceipt","unitsToAmount","force","_this6","amountToUnits","amountFormatted","token","_token$methods$approv2","send","gas","gasPrice","constant","inputs","type","outputs","payable","stateMutability","currentAllowence","Decimal","greaterThanOrEqualTo","sharesBalance","poolAddress","_this8","balanceOf","balance","fromWei","estSetSwapFee","fee","poolContract","_this10","setSwapFee","pool","_this12","_pool$methods$setSwap2","getNumTokens","_this14","getPoolSharesTotalSupply","_this16","totalSupply","getCurrentTokens","_this18","getFinalTokens","_this20","getController","_this22","getBaseToken","_this24","getBaseTokenAddress","getDatatoken","_this26","getDatatokenAddress","getMarketFeeCollector","_this28","_publishMarketCollector","getOPFCollector","_this30","_opfCollector","isBound","_this32","getReserve","_this34","getBalance","isFinalized","_this36","getSwapFee","_this38","getNormalizedWeight","_this40","weight","getDenormalizedWeight","_this42","getTotalDenormalizedWeight","_this44","getMarketFees","_this46","publishMarketFees","getCurrentMarketFees","_this48","getCurrentOPFFees","_this50","getCommunityFees","_this52","communityFees","estCollectOPF","_this54","collectOPF","_this56","_pool$methods$collect2","estCollectMarketFee","_this58","collectMarketFee","_this60","_this59$getMarketFeeC","_pool$methods$collect4","estUpdateMarketFeeCollector","newCollector","_this62","updateMarketFeeCollector","_this64","_this63$getMarketFeeC","_pool$methods$updateM2","_this66","decimals","parseInt","EXPONENTIAL_AT","_this68","estSwapExactAmountIn","tokenInOutMarket","amountsInOutMaxFee","_this70","maxPrice","swapExactAmountIn","tokenIn","tokenOut","marketFeeAddress","tokenAmountIn","minAmountOut","swapMarketFee","_this72","_pool$methods$swapExa2","estSwapExactAmountOut","_this74","swapExactAmountOut","maxAmountIn","tokenAmountOut","_this76","_pool$methods$swapExa4","estJoinPool","poolAmountOut","maxAmountsIn","_this78","joinPool","_this80","weiMaxAmountsIn","tokens","_pool$methods$joinPoo2","i","push","estExitPool","poolAmountIn","minAmountsOut","_this82","exitPool","_this84","weiMinAmountsOut","_pool$methods$exitPoo2","estJoinswapExternAmountIn","minPoolAmountOut","_this86","joinswapExternAmountIn","_this88","amountInFormatted","_pool$methods$joinswa2","estJoinswapPoolAmountOut","_this90","joinswapPoolAmountOut","_this92","maxAmountInFormatted","_pool$methods$joinswa4","estExitswapPoolAmountIn","minTokenAmountOut","_this94","exitswapPoolAmountIn","_this96","minTokenOutFormatted","_pool$methods$exitswa2","estExitswapExternAmountOut","maxPoolAmountIn","_this98","exitswapExternAmountOut","_this100","_pool$methods$exitswa4","getSpotPrice","decimalsDiff","decimalsTokenIn","decimalsTokenOut","price","_this102","tokenOutContract","tokenInContract","getAmountInExactOut","_this104","amountOutFormatted","getAmountOutExactIn","_this106","calcPoolOutGivenSingleIn","_this108","_pool$methods","calcPoolOutSingleIn","_calcPoolOutSingleIn","calcSingleInGivenPoolOut","_this110","calcSingleInPoolOut","calcSingleOutGivenPoolIn","_this112","_pool$methods2","calcSingleOutPoolIn","_calcSingleOutPoolIn","calcPoolInGivenSingleOut","_this114","_pool$methods3","calcPoolInSingleOut","_calcPoolInSingleOut","getSwapEventSignature","eventdata","o","encodeEventSignature","getJoinEventSignature","getExitEventSignature","FixedRateCreateProgressStep","dispenserAbi","dispenserContract","defaultDispenserAbi","status","dtAdress","maxTokens","maxBalance","_exit2","estGasCreate","dtAddress","allowedSwapper","create","_this5$dispenserContr","estGasActivate","activate","_this9$dispenserContr","estGasDeactivate","deactivate","_this13$dispenserCont","estGasSetAllowedSwapper","newAllowedSwapper","setAllowedSwapper","_this17$dispenserCont","estGasDispense","dispense","_this21$dispenserCont","estGasOwnerWithdraw","ownerWithdraw","_this25$dispenserCont","isDispensable","active","String","greaterThan","isMinter","FixedRateExchange","fixedRateExchangeAbi","oceanAddress","fixedRateContract","ssAbi","defaultFixedRateExchangeAbi","generateExchangeId","baseToken","estBuyDT","datatokenAddress","dtAmount","maxBaseTokenAmount","buyDT","exchangeId","datatokenAmount","getExchange","_this9$getExchange2","dtAmountFormatted","_this9$getExchange","maxBtFormatted","_this9$contract$metho","estSellDT","sellDT","minBaseTokenAmount","_this13$getExchange2","_this13$getExchange","minBtFormatted","_this13$contract$meth","getNumberOfExchanges","estSetRate","newRate","setRate","_this19$contract$meth","estSetAllowedSwapper","_this23$contract$meth","estActivate","toggleExchangeState","exchange","_this27$contract$meth","estDeactivate","_this31$contract$meth","getRate","weiRate","getDTSupply","dtSupply","_this35$getExchange","getBTSupply","btSupply","_this37$getExchange","getAllowedSwapper","getAmountBTIn","_this41$contract$meth2","calcBaseInGivenOutDT","_this41$getExchange2","_calcBaseInGivenOutDT2","_this41$getExchange","baseTokenAmount","getAmountBTOut","_this43$contract$meth2","calcBaseOutGivenInDT","_this43$getExchange2","_calcBaseOutGivenInDT2","_this43$getExchange","dtDecimals","btDecimals","dtBalance","btBalance","getFeesInfo","opfFee","_this47$getExchange2","marketFeeAvailable","_this47$getExchange","oceanFeeAvailable","getExchanges","isActive","estActivateMint","toggleMintState","activateMint","_this55$contract$meth","estDeactivateMint","deactivateMint","_this59$contract$meth","estCollectBT","collectBT","_this63$contract$meth","estCollectDT","collectDT","_this67$contract$meth","_this71$contract$meth","estCollectOceanFee","collectOceanFee","_this75$contract$meth","opfCollector","getRouter","router","getExchangeOwner","_this81$getExchange","exchangeOwner","estUpdateMarketFee","newMarketFee","updateMarketFee","_this85$contract$meth","newMarketFeeCollector","_this89$contract$meth","Nft","nftAbi","factory721Address","factory721Abi","defaultNftAbi","estGasCreateErc20","nftAddress","nftContract","createERC20","createErc20","getNftPermissions","_this3$getNftPermissi","deployERC20","_nftContract$methods$2","events","TokenCreated","returnValues","estGasAddManager","manager","addManager","getNftOwner","_this7$getNftOwner","_nftContract$methods$4","estGasRemoveManager","removeManager","_this11$getNftOwner","_nftContract$methods$6","estGasAddErc20Deployer","erc20Deployer","addToCreateERC20List","addErc20Deployer","_this15$getNftPermiss","_nftContract$methods$8","estGasRemoveErc20Deployer","removeFromCreateErc20List","removeErc20Deployer","_temp11","_this19$getNftPermiss2","removeFromCreateERC20List","_nftContract$methods$10","_this19$getNftPermiss","estGasAddMetadataUpdater","metadataUpdater","addToMetadataList","addMetadataUpdater","_this23$getNftPermiss","_nftContract$methods$12","esGasRemoveMetadataUpdater","removeFromMetadataList","removeMetadataUpdater","_temp17","_this27$getNftPermiss2","updateMetadata","_nftContract$methods$14","_this27$getNftPermiss","estGasAddStoreUpdater","storeUpdater","addTo725StoreList","addStoreUpdater","_this31$getNftPermiss","_nftContract$methods$16","estGasRemoveStoreUpdater","removeFrom725StoreList","removeStoreUpdater","_temp23","_this35$getNftPermiss2","store","_nftContract$methods$18","_this35$getNftPermiss","estGasCleanPermissions","cleanPermissions","_this39$getNftOwner","_nftContract$methods$20","estGasTransferNft","nftOwner","nftReceiver","tokenId","transferFrom","transferNft","_this43$getNftOwner","tokenIdentifier","_nftContract$methods$22","estGasSafeTransferNft","safeTransferFrom","safeTransferNft","_this47$getNftOwner","_nftContract$methods$24","estGasSetMetadata","metadataState","metaDataDecryptorUrl","metaDataDecryptorAddress","flags","metadataHash","metadataProofs","setMetaData","setMetadata","_this51$getNftPermiss","_nftContract$methods$26","estGasSetMetadataState","setMetaDataState","setMetadataState","_this55$getNftPermiss","_nftContract$methods$28","estSetTokenURI","setTokenURI","_nftContract$methods$30","ownerOf","getPermissions","getMetadata","getMetaData","isErc20Deployer","isERC20Deployer","key","getTokenURI","id","tokenURI","Datatoken","datatokensAbi","datatokensEnterpriseAbi","factoryAddress","factoryABI","nft","defaultDatatokensAbi","defaultDatatokensEnterpriseAbi","estGasApprove","dtContract","_dtContract$methods$a2","estGasMint","toAddress","mint","estGasCreateFixedRate","fixedRateParams","createFixedRate","_dtContract$methods$c2","estGasCreateDispenser","dispenserParams","createDispenser","_dtContract$methods$c4","getDTPermissions","_this15$getDTPermissi","getCap","capAvailble","gte","_dtContract$methods$m2","estGasAddMinter","addMinter","_this19$isERC20Deploy","_dtContract$methods$a4","estGasRemoveMinter","removeMinter","_this23$isERC20Deploy","_dtContract$methods$r2","estGasAddPaymentManager","paymentManager","addPaymentManager","_this27$isERC20Deploy","_dtContract$methods$a6","estGasRemovePaymentManager","removePaymentManager","_this31$isERC20Deploy","_dtContract$methods$r4","estGasSetPaymentCollector","paymentCollector","setPaymentCollector","_this35$getDTPermissi","_dtContract$methods$s2","getPaymentCollector","transfer","weiAmount","transferWei","estGasTransfer","_dtContract$methods$t2","estGasStartOrder","consumer","serviceIndex","providerFees","startOrder","_dtContract$methods$s4","estGasBuyFromFreAndOrder","orderParams","buyFromFreAndOrder","_dtContract$methods$b2","estGasBuyFromDispenserAndOrder","buyFromDispenserAndOrder","_dtContract$methods$b4","estGasSetData","setData","_dtContract$methods$s6","_this63$nft2","getNFTAddress","_this63$nft$getNftOwn","_dtContract$methods$c6","permissions","getDecimals","getERC721Address","addressZERO","NftFactory","factory721","defaultFactory721Abi","estGasCreateNFT","nftData","deployERC721Contract","createNFT","getCurrentNFTTemplateCount","_nftData$templateInde2","getNFTTemplate","_this3$getNFTTemplate","_this3$factory721$met","NFTCreated","getCurrentNFTCount","getCurrentTokenCount","getOwner","getCurrentTokenTemplateCount","getCurrentTemplateCount","getTokenTemplate","checkDatatoken","erc20List","checkNFT","erc721List","estGasAddNFTTemplate","templateAddress","add721TokenTemplate","addNFTTemplate","_this25$getOwner","_this25$factory721$me","estGasDisableNFTTemplate","disable721TokenTemplate","disableNFTTemplate","_this29$getOwner","_this29$factory721$me","estGasReactivateNFTTemplate","reactivate721TokenTemplate","reactivateNFTTemplate","_this33$getOwner","_this33$factory721$me","estGasAddTokenTemplate","addTokenTemplate","_this37$getOwner","_this37$factory721$me","estGasDisableTokenTemplate","disableTokenTemplate","_this41$getOwner","_this41$getNFTTemplat","_this41$factory721$me","estGasReactivateTokenTemplate","reactivateTokenTemplate","_this45$getOwner","_this45$getTokenTempl","_this45$factory721$me","estGasStartMultipleTokenOrder","orders","startMultipleTokenOrder","_this49$factory721$me","estGasCreateNftWithErc","nftCreateData","ercCreateData","createNftWithErc","_this53$factory721$me","estGasCreateNftErcWithPool","poolData","createNftErcWithPool","_this57$factory721$me","estGasCreateNftErcWithFixedRate","fixedData","createNftErcWithFixedRate","_this61$factory721$me","estGasCreateNftErcWithDispenser","createNftErcWithDispenser","_this65$factory721$me","Config","providerAddress","web3Provider","erc721FFactoryABI","datatokensABI","poolFactoryABI","poolABI","fixedRateExchangeAddressABI","dispenserABI","verbose","authMessage","authTokenExpiration","parityUri","threshold","noZeroX","input","zeroOutput","regexp","conversorName","valid","output","inputMatch","zeroXTransformer","Provider","getEndpoints","endpoints","json","getEndpointURL","servicesEndpoints","serviceName","getServiceEndpoints","providerEndpoint","serviceEndpoints","urlPath","getNonce","consumerAddress","fetchMethod","providerEndpoints","path","preferedFetch","_response$json","nonce","createSignature","accountId","agreementId","createHashSignature","encrypt","postMethod","decodeURI","stringify","checkDidFiles","did","serviceId","args","files","results","checkFileUrl","initialize","fileIndex","userCustomParameters","computeEnv","validUntil","initializeUrl","encodeURI","getDownloadUrl","transferTxId","downloadUrl","Date","now","signature","consumeUrl","computeStart","dataset","algorithm","additionalDatasets","computeStartUrl","signatureMessage","documentId","Object","statusText","params","computeStop","jobId","computeStopUrl","computeStatus","computeStatusUrl","computeResult","computeResultUrl","downloadFileBrowser","computeDelete","computeDeleteUrl","isValidProvider","ProviderInstance"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"lib.module.js","sources":["../src/utils/Logger.ts","../src/utils/DatatokenName.ts","../src/utils/minAbi.ts","../src/utils/ContractUtils.ts","../src/utils/FetchHelper.ts","../src/utils/ConfigHelper.ts","../src/utils/DdoHelpers.ts","../src/utils/Constants.ts","../src/utils/SignatureUtils.ts","../src/utils/TokenUtils.ts","../src/pools/balancer/Pool.ts","../src/pools/dispenser/Dispenser.ts","../src/pools/fixedRate/FixedRateExchange.ts","../src/tokens/NFT.ts","../src/tokens/Datatoken.ts","../src/factories/NFTFactory.ts","../src/models/Config.ts","../src/utils/ConversionTypeHelper.ts","../src/provider/Provider.ts"],"sourcesContent":["export enum LogLevel {\n None = -1,\n Error = 0,\n Warn = 1,\n Log = 2,\n Verbose = 3\n}\n\nexport class Logger {\n constructor(private logLevel: LogLevel = LogLevel.Error) {}\n\n public setLevel(logLevel: LogLevel): void {\n this.logLevel = logLevel\n }\n\n public bypass(...args: any[]): void {\n this.dispatch('log', -Infinity as any, ...args)\n }\n\n public debug(...args: any[]): void {\n this.dispatch('debug', LogLevel.Verbose, ...args)\n }\n\n public log(...args: any[]): void {\n this.dispatch('log', LogLevel.Log, ...args)\n }\n\n public warn(...args: any[]): void {\n this.dispatch('warn', LogLevel.Warn, ...args)\n }\n\n public error(...args: any[]): void {\n this.dispatch('error', LogLevel.Error, ...args)\n }\n\n private dispatch(verb: string, level: LogLevel, ...args: any[]) {\n if (this.logLevel >= level) {\n console[verb](...args)\n }\n }\n}\n\nexport const LoggerInstance = new Logger()\nexport default LoggerInstance\n","import wordListDefault from '../data/words.json'\n\n/**\n * Generate new datatoken name & symbol from a word list\n * @return {<{ name: String; symbol: String }>} datatoken name & symbol. Produces e.g. \"Endemic Jellyfish Token\" & \"ENDJEL-45\"\n */\nexport function generateDtName(wordList?: { nouns: string[]; adjectives: string[] }): {\n name: string\n symbol: string\n} {\n const list = wordList || wordListDefault\n const random1 = Math.floor(Math.random() * list.adjectives.length)\n const random2 = Math.floor(Math.random() * list.nouns.length)\n const indexNumber = Math.floor(Math.random() * 100)\n\n // Capitalized adjective & noun\n const adjective = list.adjectives[random1].replace(/^\\w/, (c) => c.toUpperCase())\n const noun = list.nouns[random2].replace(/^\\w/, (c) => c.toUpperCase())\n\n const name = `${adjective} ${noun} Token`\n // use first 3 letters of name, uppercase it, and add random number\n const symbol = `${(\n adjective.substring(0, 3) + noun.substring(0, 3)\n ).toUpperCase()}-${indexNumber}`\n\n return { name, symbol }\n}\n","import { AbiItem } from 'web3-utils/types'\n\nexport const minAbi = [\n {\n constant: true,\n inputs: [],\n name: 'name',\n outputs: [\n {\n name: '',\n type: 'string'\n }\n ],\n payable: false,\n stateMutability: 'view',\n type: 'function'\n },\n {\n constant: false,\n inputs: [\n {\n name: '_spender',\n type: 'address'\n },\n {\n name: '_value',\n type: 'uint256'\n }\n ],\n name: 'approve',\n outputs: [\n {\n name: '',\n type: 'bool'\n }\n ],\n payable: false,\n stateMutability: 'nonpayable',\n type: 'function'\n },\n {\n constant: true,\n inputs: [],\n name: 'totalSupply',\n outputs: [\n {\n name: '',\n type: 'uint256'\n }\n ],\n payable: false,\n stateMutability: 'view',\n type: 'function'\n },\n {\n constant: false,\n inputs: [\n {\n name: '_from',\n type: 'address'\n },\n {\n name: '_to',\n type: 'address'\n },\n {\n name: '_value',\n type: 'uint256'\n }\n ],\n name: 'transferFrom',\n outputs: [\n {\n name: '',\n type: 'bool'\n }\n ],\n payable: false,\n stateMutability: 'nonpayable',\n type: 'function'\n },\n {\n constant: true,\n inputs: [],\n name: 'decimals',\n outputs: [\n {\n name: '',\n type: 'uint8'\n }\n ],\n payable: false,\n stateMutability: 'view',\n type: 'function'\n },\n {\n constant: true,\n inputs: [\n {\n name: '_owner',\n type: 'address'\n }\n ],\n name: 'balanceOf',\n outputs: [\n {\n name: 'balance',\n type: 'uint256'\n }\n ],\n payable: false,\n stateMutability: 'view',\n type: 'function'\n },\n {\n constant: true,\n inputs: [],\n name: 'symbol',\n outputs: [\n {\n name: '',\n type: 'string'\n }\n ],\n payable: false,\n stateMutability: 'view',\n type: 'function'\n },\n {\n constant: false,\n inputs: [\n {\n name: '_to',\n type: 'address'\n },\n {\n name: '_value',\n type: 'uint256'\n }\n ],\n name: 'transfer',\n outputs: [\n {\n name: '',\n type: 'bool'\n }\n ],\n payable: false,\n stateMutability: 'nonpayable',\n type: 'function'\n },\n {\n constant: true,\n inputs: [\n {\n name: '_owner',\n type: 'address'\n },\n {\n name: '_spender',\n type: 'address'\n }\n ],\n name: 'allowance',\n outputs: [\n {\n name: '',\n type: 'uint256'\n }\n ],\n payable: false,\n stateMutability: 'view',\n type: 'function'\n },\n {\n payable: true,\n stateMutability: 'payable',\n type: 'fallback'\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n name: 'owner',\n type: 'address'\n },\n {\n indexed: true,\n name: 'spender',\n type: 'address'\n },\n {\n indexed: false,\n name: 'value',\n type: 'uint256'\n }\n ],\n name: 'Approval',\n type: 'event'\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n name: 'from',\n type: 'address'\n },\n {\n indexed: true,\n name: 'to',\n type: 'address'\n },\n {\n indexed: false,\n name: 'value',\n type: 'uint256'\n }\n ],\n name: 'Transfer',\n type: 'event'\n }\n] as AbiItem[]\n","import Web3 from 'web3'\nimport BigNumber from 'bignumber.js'\nimport { Contract } from 'web3-eth-contract'\nimport { generateDtName } from './DatatokenName'\nimport { Erc20CreateParams, FreCreationParams, PoolCreationParams } from '../interfaces'\nimport { Config } from '../models'\nimport { AbiItem } from 'web3-utils/types'\nimport { minAbi } from './minAbi'\n\nexport function setContractDefaults(contract: Contract, config: Config): Contract {\n if (config) {\n if (config.transactionBlockTimeout)\n contract.transactionBlockTimeout = config.transactionBlockTimeout\n if (config.transactionConfirmationBlocks)\n contract.transactionConfirmationBlocks = config.transactionConfirmationBlocks\n if (config.transactionPollingTimeout)\n contract.transactionPollingTimeout = config.transactionPollingTimeout\n }\n return contract\n}\n\nexport async function getFairGasPrice(web3: Web3, config: Config): Promise<string> {\n const x = new BigNumber(await web3.eth.getGasPrice())\n if (config && config.gasFeeMultiplier)\n return x\n .multipliedBy(config.gasFeeMultiplier)\n .integerValue(BigNumber.ROUND_DOWN)\n .toString(10)\n else return x.toString(10)\n}\n\nexport function getErcCreationParams(ercParams: Erc20CreateParams): any {\n let name: string, symbol: string\n // Generate name & symbol if not present\n if (!ercParams.name || !ercParams.symbol) {\n ;({ name, symbol } = generateDtName())\n }\n return {\n templateIndex: ercParams.templateIndex,\n strings: [ercParams.name || name, ercParams.symbol || symbol],\n addresses: [\n ercParams.minter,\n ercParams.feeManager,\n ercParams.mpFeeAddress,\n ercParams.feeToken\n ],\n uints: [Web3.utils.toWei(ercParams.cap), Web3.utils.toWei(ercParams.feeAmount)],\n bytess: []\n }\n}\n\nexport function getFreCreationParams(freParams: FreCreationParams): any {\n if (!freParams.allowedConsumer)\n freParams.allowedConsumer = '0x0000000000000000000000000000000000000000'\n const withMint = freParams.withMint ? 1 : 0\n\n return {\n fixedPriceAddress: freParams.fixedRateAddress,\n addresses: [\n freParams.baseTokenAddress,\n freParams.owner,\n freParams.marketFeeCollector,\n freParams.allowedConsumer\n ],\n uints: [\n freParams.baseTokenDecimals,\n freParams.datatokenDecimals,\n freParams.fixedRate,\n freParams.marketFee,\n withMint\n ]\n }\n}\n\nexport function getPoolCreationParams(poolParams: PoolCreationParams): any {\n return {\n addresses: [\n poolParams.ssContract,\n poolParams.baseTokenAddress,\n poolParams.baseTokenSender,\n poolParams.publisherAddress,\n poolParams.marketFeeCollector,\n poolParams.poolTemplateAddress\n ],\n ssParams: [\n Web3.utils.toWei(poolParams.rate),\n poolParams.baseTokenDecimals,\n Web3.utils.toWei(poolParams.vestingAmount),\n poolParams.vestedBlocks,\n Web3.utils.toWei(poolParams.initialBaseTokenLiquidity)\n ],\n swapFees: [poolParams.swapFeeLiquidityProvider, poolParams.swapFeeMarketRunner]\n }\n}\nexport async function unitsToAmount(\n web3: Web3,\n token: string,\n amount: string\n): Promise<string> {\n try {\n const tokenContract = new web3.eth.Contract(minAbi, token)\n let decimals = await tokenContract.methods.decimals().call()\n if (decimals === '0') {\n decimals = 18\n }\n const amountFormatted = new BigNumber(parseInt(amount) / 10 ** decimals)\n BigNumber.config({ EXPONENTIAL_AT: 50 })\n return amountFormatted.toString()\n } catch (e) {\n this.logger.error('ERROR: FAILED TO CALL DECIMALS(), USING 18')\n }\n}\n\nexport async function amountToUnits(\n web3: Web3,\n token: string,\n amount: string\n): Promise<string> {\n try {\n const tokenContract = new web3.eth.Contract(minAbi, token)\n let decimals = await tokenContract.methods.decimals().call()\n if (decimals === '0') {\n decimals = 18\n }\n const amountFormatted = new BigNumber(parseInt(amount) * 10 ** decimals)\n BigNumber.config({ EXPONENTIAL_AT: 50 })\n return amountFormatted.toString()\n } catch (e) {\n this.logger.error('ERROR: FAILED TO CALL DECIMALS(), USING 18')\n }\n}\n","import fetch from 'cross-fetch'\nimport LoggerInstance from './Logger'\nimport { DownloadResponse } from '../@types/DownloadResponse'\n\nexport async function fetchData(url: string, opts: RequestInit): Promise<Response> {\n const result = await fetch(url, opts)\n if (!result.ok) {\n LoggerInstance.error(`Error requesting [${opts.method}] ${url}`)\n LoggerInstance.error(`Response message: \\n${await result.text()}`)\n throw result\n }\n return result\n}\n\nexport async function downloadFileBrowser(url: string): Promise<void> {\n const anchor = document.createElement('a')\n anchor.download = ''\n anchor.href = url\n anchor.click()\n}\n\nexport async function downloadFile(\n url: string,\n index?: number\n): Promise<DownloadResponse> {\n const response = await fetch(url)\n if (!response.ok) {\n throw new Error('Response error.')\n }\n let filename: string\n try {\n filename = response.headers\n .get('content-disposition')\n .match(/attachment;filename=(.+)/)[1]\n } catch {\n try {\n filename = url.split('/').pop()\n } catch {\n filename = `file${index}`\n }\n }\n\n return { data: await response.arrayBuffer(), filename }\n}\n\nexport async function getData(url: string): Promise<Response> {\n return fetch(url, {\n method: 'GET',\n headers: {\n 'Content-type': 'application/json'\n }\n })\n}\n\nasync function postWithHeaders(\n url: string,\n payload: BodyInit,\n headers: any\n): Promise<Response> {\n if (payload != null) {\n return fetch(url, {\n method: 'POST',\n body: payload,\n headers\n })\n } else {\n return fetch(url, {\n method: 'POST'\n })\n }\n}\n\nexport async function postData(url: string, payload: BodyInit): Promise<Response> {\n const headers = {\n 'Content-type': 'application/json'\n }\n return postWithHeaders(url, payload, headers)\n}\n","import Config from '../models/Config'\n// eslint-disable-next-line import/no-named-default\nimport { default as DefaultContractsAddresses } from '@oceanprotocol/contracts/addresses/address.json'\nimport LoggerInstance from './Logger'\n\nconst configHelperNetworksBase: Config = {\n chainId: null,\n network: 'unknown',\n metadataCacheUri: 'https://aquarius.oceanprotocol.com',\n nodeUri: 'http://localhost:8545',\n providerUri: 'http://127.0.0.1:8030',\n subgraphUri: null,\n explorerUri: null,\n oceanTokenAddress: null,\n oceanTokenSymbol: 'OCEAN',\n poolTemplateAddress: null,\n fixedRateExchangeAddress: null,\n dispenserAddress: null,\n startBlock: 0,\n transactionBlockTimeout: 50,\n transactionConfirmationBlocks: 1,\n transactionPollingTimeout: 750,\n gasFeeMultiplier: 1\n}\n\nexport const configHelperNetworks: Config[] = [\n {\n ...configHelperNetworksBase\n },\n {\n // barge\n ...configHelperNetworksBase,\n chainId: 8996,\n network: 'development',\n metadataCacheUri: 'http://127.0.0.1:5000'\n },\n {\n ...configHelperNetworksBase,\n chainId: 3,\n network: 'ropsten',\n nodeUri: 'https://ropsten.infura.io/v3',\n providerUri: 'https://provider.ropsten.oceanprotocol.com',\n subgraphUri: 'https://subgraph.ropsten.oceanprotocol.com',\n explorerUri: 'https://ropsten.etherscan.io',\n startBlock: 9227563\n },\n {\n ...configHelperNetworksBase,\n chainId: 4,\n network: 'rinkeby',\n nodeUri: 'https://rinkeby.infura.io/v3',\n providerUri: 'https://providerv4.rinkeby.oceanprotocol.com',\n subgraphUri: 'https://subgraphv4.rinkeby.oceanprotocol.com',\n explorerUri: 'https://rinkeby.etherscan.io',\n startBlock: 7294090\n },\n {\n ...configHelperNetworksBase,\n chainId: 1,\n network: 'mainnet',\n nodeUri: 'https://mainnet.infura.io/v3',\n providerUri: 'https://provider.mainnet.oceanprotocol.com',\n subgraphUri: 'https://subgraph.mainnet.oceanprotocol.com',\n explorerUri: 'https://etherscan.io',\n startBlock: 11105459,\n transactionBlockTimeout: 150,\n transactionConfirmationBlocks: 5,\n transactionPollingTimeout: 1750,\n gasFeeMultiplier: 1.05\n },\n {\n ...configHelperNetworksBase,\n chainId: 137,\n network: 'polygon',\n nodeUri: 'https://polygon-mainnet.infura.io/v3',\n providerUri: 'https://provider.polygon.oceanprotocol.com',\n subgraphUri: 'https://subgraph.polygon.oceanprotocol.com',\n explorerUri: 'https://polygonscan.com',\n oceanTokenSymbol: 'mOCEAN',\n startBlock: 11005222\n },\n {\n ...configHelperNetworksBase,\n chainId: 1287,\n network: 'moonbeamalpha',\n nodeUri: 'https://rpc.testnet.moonbeam.network',\n providerUri: 'https://provider.moonbeamalpha.oceanprotocol.com',\n subgraphUri: 'https://subgraph.moonbeamalpha.oceanprotocol.com',\n explorerUri: 'https://moonbase-blockscout.testnet.moonbeam.network/',\n startBlock: 90707\n },\n {\n ...configHelperNetworksBase,\n chainId: 2021000,\n network: 'gaiaxtestnet',\n nodeUri: 'https://rpc.gaiaxtestnet.oceanprotocol.com',\n providerUri: 'https://provider.gaiaxtestnet.oceanprotocol.com',\n subgraphUri: 'https://subgraph.gaiaxtestnet.oceanprotocol.com',\n explorerUri: 'https://blockscout.gaiaxtestnet.oceanprotocol.com'\n },\n {\n ...configHelperNetworksBase,\n chainId: 2021001,\n network: 'catenaxtestnet',\n nodeUri: 'https://rpc.catenaxtestnet.oceanprotocol.com',\n providerUri: 'https://provider.catenaxtestnet.oceanprotocol.com',\n subgraphUri: 'https://subgraph.catenaxtestnet.oceanprotocol.com',\n explorerUri: 'https://blockscout.catenaxtestnet.oceanprotocol.com',\n metadataCacheUri: 'https://aquarius.catenaxtestnet.oceanprotocol.com'\n },\n {\n ...configHelperNetworksBase,\n chainId: 80001,\n network: 'mumbai',\n nodeUri: 'https://polygon-mumbai.infura.io/v3',\n providerUri: 'https://provider.mumbai.oceanprotocol.com',\n subgraphUri: 'https://subgraph.mumbai.oceanprotocol.com',\n explorerUri: 'https://mumbai.polygonscan.com'\n },\n {\n ...configHelperNetworksBase,\n chainId: 56,\n network: 'bsc',\n nodeUri: 'https://bsc-dataseed.binance.org',\n providerUri: 'https://provider.bsc.oceanprotocol.com',\n subgraphUri: 'https://subgraph.bsc.oceanprotocol.com',\n explorerUri: 'https://bscscan.com/',\n gasFeeMultiplier: 1.05\n },\n {\n ...configHelperNetworksBase,\n chainId: 44787,\n network: 'celoalfajores',\n nodeUri: 'https://alfajores-forno.celo-testnet.org',\n providerUri: 'https://provider.celoalfajores.oceanprotocol.com',\n subgraphUri: 'https://subgraph.celoalfajores.oceanprotocol.com',\n explorerUri: 'https://alfajores-blockscout.celo-testnet.org'\n },\n {\n ...configHelperNetworksBase,\n chainId: 246,\n network: 'energyweb',\n nodeUri: 'https://rpc.energyweb.org',\n providerUri: 'https://provider.energyweb.oceanprotocol.com',\n subgraphUri: 'https://subgraph.energyweb.oceanprotocol.com',\n explorerUri: 'https://explorer.energyweb.org',\n gasFeeMultiplier: 1.05\n },\n {\n ...configHelperNetworksBase,\n chainId: 1285,\n network: 'moonriver',\n nodeUri: 'https://moonriver.api.onfinality.io/public',\n providerUri: 'https://provider.moonriver.oceanprotocol.com',\n subgraphUri: 'https://subgraph.moonriver.oceanprotocol.com',\n explorerUri: 'https://blockscout.moonriver.moonbeam.network',\n gasFeeMultiplier: 1.05\n }\n]\n\nexport class ConfigHelper {\n /* Load contract addresses from env ADDRESS_FILE (generated by ocean-contracts) */\n public getAddressesFromEnv(network: string, customAddresses?: any): Partial<Config> {\n // use the defaults first\n let configAddresses: Partial<Config>\n\n // load from custom addresses structure\n if (customAddresses) {\n try {\n const {\n FixedPrice,\n Dispenser,\n Staking,\n poolTemplate,\n ERC721Factory,\n OPFCommunityFeeCollector,\n Ocean,\n chainId,\n startBlock\n } = customAddresses[network]\n configAddresses = {\n erc721FactoryAddress: ERC721Factory,\n sideStakingAddress: Staking,\n opfCommunityFeeCollector: OPFCommunityFeeCollector,\n poolTemplateAddress: poolTemplate,\n fixedRateExchangeAddress: FixedPrice,\n dispenserAddress: Dispenser,\n oceanTokenAddress: Ocean,\n chainId: chainId,\n startBlock: startBlock,\n ...(process.env.AQUARIUS_URI && { metadataCacheUri: process.env.AQUARIUS_URI })\n }\n } catch (e) {\n // console.error(`ERROR: Could not load local contract address file: ${e.message}`)\n // return null\n }\n } else {\n // no custom addresses structure was passed, trying to load default\n if (DefaultContractsAddresses[network]) {\n const {\n FixedPrice,\n Dispenser,\n Staking,\n poolTemplate,\n OPFCommunityFeeCollector,\n ERC721Factory,\n Ocean,\n chainId,\n startBlock\n } = DefaultContractsAddresses[network]\n configAddresses = {\n erc721FactoryAddress: ERC721Factory,\n sideStakingAddress: Staking,\n opfCommunityFeeCollector: OPFCommunityFeeCollector,\n poolTemplateAddress: poolTemplate,\n fixedRateExchangeAddress: FixedPrice,\n dispenserAddress: Dispenser,\n oceanTokenAddress: Ocean,\n chainId: chainId,\n startBlock: startBlock,\n ...(process.env.AQUARIUS_URI && { metadataCacheUri: process.env.AQUARIUS_URI })\n }\n }\n }\n return configAddresses\n }\n\n public getConfig(network: string | number, infuraProjectId?: string): Config {\n const filterBy = typeof network === 'string' ? 'network' : 'chainId'\n let config = configHelperNetworks.find((c) => c[filterBy] === network)\n\n if (!config) {\n LoggerInstance.error(`No config found for given network '${network}'`)\n return null\n }\n\n const contractAddressesConfig = this.getAddressesFromEnv(config.network)\n config = { ...config, ...contractAddressesConfig }\n\n const nodeUri = infuraProjectId\n ? `${config.nodeUri}/${infuraProjectId}`\n : config.nodeUri\n\n return { ...config, nodeUri }\n }\n}\n","import sha256 from 'crypto-js/sha256'\nimport Web3 from 'web3'\n\nexport function generateDid(erc721Address: string, chainId: number): string {\n erc721Address = Web3.utils.toChecksumAddress(erc721Address)\n const checksum = sha256(erc721Address + chainId.toString(10))\n return `did:op:${checksum.toString()}`\n}\n\nexport function getHash(data: any): string {\n return sha256(data).toString()\n}\n","export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'\nexport const GASLIMIT_DEFAULT = 1000000\n","import Web3 from 'web3'\nimport { LoggerInstance } from './Logger'\n\nexport async function signText(\n web3: Web3,\n text: string,\n publicKey: string,\n password?: string\n): Promise<string> {\n const isMetaMask =\n web3 && web3.currentProvider && (web3.currentProvider as any).isMetaMask\n try {\n return await web3.eth.personal.sign(text, publicKey, password)\n } catch (e) {\n if (isMetaMask) {\n throw e\n }\n LoggerInstance.warn('Error on personal sign.')\n LoggerInstance.warn(e)\n try {\n return await web3.eth.sign(text, publicKey)\n } catch (e2) {\n LoggerInstance.error('Error on sign.')\n LoggerInstance.error(e2)\n throw new Error('Error executing personal sign')\n }\n }\n}\n\nexport async function signHash(web3: Web3, message: string, address: string) {\n let signedMessage = await web3.eth.sign(message, address)\n signedMessage = signedMessage.substr(2) // remove 0x\n const r = '0x' + signedMessage.slice(0, 64)\n const s = '0x' + signedMessage.slice(64, 128)\n let v = '0x' + signedMessage.slice(128, 130)\n // make sure we obey 27 and 28 standards\n if (v === '0x00') v = '0x1b'\n if (v === '0x01') v = '0x1c'\n return { v, r, s }\n}\n\nexport async function signWithHash(\n web3: Web3,\n text: string,\n publicKey: string,\n password?: string\n): Promise<string> {\n const hash = web3.utils.utf8ToHex(text)\n const isMetaMask =\n web3 && web3.currentProvider && (web3.currentProvider as any).isMetaMask\n try {\n return await web3.eth.personal.sign(hash, publicKey, password)\n } catch (e) {\n if (isMetaMask) {\n throw e\n }\n LoggerInstance.warn('Error on personal sign.')\n LoggerInstance.warn(e)\n try {\n return await web3.eth.sign(hash, publicKey)\n } catch (e2) {\n LoggerInstance.error('Error on sign.')\n LoggerInstance.error(e2)\n throw new Error('Error executing personal sign')\n }\n }\n}\n","import Decimal from 'decimal.js'\nimport { Contract } from 'web3-eth-contract'\nimport { amountToUnits, getFairGasPrice, unitsToAmount } from './ContractUtils'\nimport { minAbi } from './minAbi'\nimport LoggerInstance from './Logger'\nimport { TransactionReceipt } from 'web3-core'\nimport Web3 from 'web3'\nimport { GASLIMIT_DEFAULT } from '.'\n\n/**\n * Estimate gas cost for approval function\n * @param {String} account\n * @param {String} tokenAddress\n * @param {String} spender\n * @param {String} amount\n * @param {String} force\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\nexport async function estApprove(\n web3: Web3,\n account: string,\n tokenAddress: string,\n spender: string,\n amount: string,\n contractInstance?: Contract\n): Promise<number> {\n const tokenContract = contractInstance || new web3.eth.Contract(minAbi, tokenAddress)\n\n const gasLimitDefault = GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await tokenContract.methods\n .approve(spender, amount)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n LoggerInstance.error('estimate gas failed for approve!', e)\n }\n return estGas\n}\n\n/**\n * Approve spender to spent amount tokens\n * @param {String} account\n * @param {String} tokenAddress\n * @param {String} spender\n * @param {String} amount (always expressed as wei)\n * @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\n */\nexport async function approve(\n web3: Web3,\n account: string,\n tokenAddress: string,\n spender: string,\n amount: string,\n force = false\n): Promise<TransactionReceipt | string> {\n const tokenContract = new web3.eth.Contract(minAbi, tokenAddress)\n if (!force) {\n const currentAllowence = await allowance(web3, tokenAddress, account, spender)\n if (new Decimal(currentAllowence).greaterThanOrEqualTo(new Decimal(amount))) {\n return currentAllowence\n }\n }\n let result = null\n const amountFormatted = await amountToUnits(web3, tokenAddress, amount)\n const estGas = await estApprove(\n web3,\n account,\n tokenAddress,\n spender,\n amountFormatted,\n tokenContract\n )\n\n try {\n result = await tokenContract.methods.approve(spender, amountFormatted).send({\n from: account,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(web3, null)\n })\n } catch (e) {\n LoggerInstance.error(\n `ERRPR: Failed to approve spender to spend tokens : ${e.message}`\n )\n }\n return result\n}\n\n/**\n * Get Allowance for any erc20\n * @param {Web3} web3\n * @param {String } tokenAdress\n * @param {String} account\n * @param {String} spender\n */\nexport async function allowance(\n web3: Web3,\n tokenAddress: string,\n account: string,\n spender: string\n): Promise<string> {\n const tokenContract = new web3.eth.Contract(minAbi, tokenAddress)\n const trxReceipt = await tokenContract.methods.allowance(account, spender).call()\n\n return await unitsToAmount(web3, tokenAddress, trxReceipt)\n}\n\n/**\n * Get balance for any erc20\n * @param {Web3} web3\n * @param {String} tokenAdress\n * @param {String} owner\n * @param {String} spender\n */\nexport async function balance(\n web3: Web3,\n tokenAddress: string,\n account: string\n): Promise<string> {\n const tokenContract = new web3.eth.Contract(minAbi, tokenAddress)\n const trxReceipt = await tokenContract.methods.balanceOf(account).call()\n\n return await unitsToAmount(web3, tokenAddress, trxReceipt)\n}\n","import Web3 from 'web3'\nimport { AbiItem } from 'web3-utils/types'\nimport { TransactionReceipt } from 'web3-core'\nimport { Contract } from 'web3-eth-contract'\nimport {\n Logger,\n getFairGasPrice,\n configHelperNetworks,\n setContractDefaults,\n unitsToAmount,\n amountToUnits\n} from '../../utils'\nimport BigNumber from 'bignumber.js'\nimport PoolTemplate from '@oceanprotocol/contracts/artifacts/contracts/pools/balancer/BPool.sol/BPool.json'\nimport defaultErc20Abi from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json'\n\nimport {\n CurrentFees,\n TokenInOutMarket,\n AmountsInMaxFee,\n AmountsOutMaxFee\n} from '../../interfaces'\nimport { Config } from '../../models'\nimport { minAbi } from '../../utils/minAbi'\nconst MaxUint256 =\n '115792089237316195423570985008687907853269984665640564039457584007913129639934'\n\n/**\n * Provides an interface to Ocean friendly fork from Balancer BPool\n */\nexport class Pool {\n public poolAbi: AbiItem | AbiItem[]\n public web3: Web3\n public GASLIMIT_DEFAULT = 1000000\n private logger: Logger\n private config: Config\n\n constructor(\n web3: Web3,\n logger: Logger,\n poolAbi: AbiItem | AbiItem[] = null,\n config?: Config\n ) {\n if (poolAbi) this.poolAbi = poolAbi\n else this.poolAbi = PoolTemplate.abi as AbiItem[]\n this.web3 = web3\n this.logger = logger\n this.config = config || configHelperNetworks[0]\n }\n\n /**\n * Get user shares of pool tokens\n * @param {String} account\n * @param {String} poolAddress\n * @return {String}\n */\n async sharesBalance(account: string, poolAddress: string): Promise<string> {\n let result = null\n try {\n const token = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n const balance = await token.methods.balanceOf(account).call()\n result = this.web3.utils.fromWei(balance)\n } catch (e) {\n this.logger.error(`ERROR: Failed to get shares of pool : ${e.message}`)\n }\n return result\n }\n\n /**\n * Estimate gas cost for setSwapFee\n * @param {String} account\n * @param {String} tokenAddress\n * @param {String} spender\n * @param {String} amount\n * @param {String} force\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estSetSwapFee(\n account: string,\n poolAddress: string,\n fee: string,\n contractInstance?: Contract\n ): Promise<number> {\n const poolContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(defaultErc20Abi.abi as AbiItem[], poolAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await poolContract.methods\n .setSwapFee(fee)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Set pool fee\n * @param {String} account\n * @param {String} poolAddress\n * @param {String} fee 0.1=10% fee(max allowed)\n */\n async setSwapFee(\n account: string,\n poolAddress: string,\n fee: string\n ): Promise<TransactionReceipt> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress, {\n from: account\n }),\n this.config\n )\n let result = null\n const estGas = await this.estSetSwapFee(account, poolAddress, fee)\n\n try {\n result = await pool.methods.setSwapFee(this.web3.utils.toWei(fee)).send({\n from: account,\n gas: estGas,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n this.logger.error(`ERROR: Failed to set pool swap fee: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get number of tokens composing this pool\n * @param {String} poolAddress\n * @return {String}\n */\n async getNumTokens(poolAddress: string): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n try {\n result = await pool.methods.getNumTokens().call()\n } catch (e) {\n this.logger.error(`ERROR: Failed to get number of tokens: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get total supply of pool shares\n * @param {String} poolAddress\n * @return {String}\n */\n async getPoolSharesTotalSupply(poolAddress: string): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let amount = null\n try {\n const result = await pool.methods.totalSupply().call()\n amount = this.web3.utils.fromWei(result)\n } catch (e) {\n this.logger.error(`ERROR: Failed to get total supply of pool shares: ${e.message}`)\n }\n return amount\n }\n\n /**\n * Get tokens composing this pool\n * @param {String} poolAddress\n * @return {String[]}\n */\n async getCurrentTokens(poolAddress: string): Promise<string[]> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n try {\n result = await pool.methods.getCurrentTokens().call()\n } catch (e) {\n this.logger.error(`ERROR: Failed to get tokens composing this pool: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get the final tokens composing this pool\n * @param {String} poolAddress\n * @return {String[]}\n */\n async getFinalTokens(poolAddress: string): Promise<string[]> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n try {\n result = await pool.methods.getFinalTokens().call()\n } catch (e) {\n this.logger.error(`ERROR: Failed to get the final tokens composing this pool`)\n }\n return result\n }\n\n /**\n * Get controller address of this pool\n * @param {String} poolAddress\n * @return {String}\n */\n async getController(poolAddress: string): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n try {\n result = await pool.methods.getController().call()\n } catch (e) {\n this.logger.error(`ERROR: Failed to get pool controller address: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get baseToken address of this pool\n * @param {String} poolAddress\n * @return {String}\n */\n async getBaseToken(poolAddress: string): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n try {\n result = await pool.methods.getBaseTokenAddress().call()\n } catch (e) {\n this.logger.error(`ERROR: Failed to get baseToken address: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get datatoken address of this pool\n * @param {String} poolAddress\n * @return {String}\n */\n async getDatatoken(poolAddress: string): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n try {\n result = await pool.methods.getDatatokenAddress().call()\n } catch (e) {\n this.logger.error(`ERROR: Failed to get datatoken address: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get marketFeeCollector of this pool\n * @param {String} poolAddress\n * @return {String}\n */\n async getMarketFeeCollector(poolAddress: string): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n try {\n result = await pool.methods._publishMarketCollector().call()\n } catch (e) {\n this.logger.error(`ERROR: Failed to get marketFeeCollector address: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get OPF Collector of this pool\n * @param {String} poolAddress\n * @return {String}\n */\n async getOPFCollector(poolAddress: string): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n try {\n result = await pool.methods._opfCollector().call()\n } catch (e) {\n this.logger.error(`ERROR: Failed to get OPF Collector address: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get if a token is bounded to a pool\n * @param {String} poolAddress\n * @param {String} token Address of the token\n * @return {Boolean}\n */\n async isBound(poolAddress: string, token: string): Promise<boolean> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n try {\n result = await pool.methods.isBound(token).call()\n } catch (e) {\n this.logger.error(`ERROR: Failed to check whether a token \\\n bounded to a pool. ${e.message}`)\n }\n return result\n }\n\n /**\n * Get how many tokens are in the pool\n * @param {String} poolAddress\n * @param {String} token Address of the token\n * @return {String}\n */\n async getReserve(poolAddress: string, token: string): Promise<string> {\n let amount = null\n try {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n const result = await pool.methods.getBalance(token).call()\n amount = await unitsToAmount(this.web3, token, result)\n } catch (e) {\n this.logger.error(`ERROR: Failed to get how many tokens \\\n are in the pool: ${e.message}`)\n }\n return amount.toString()\n }\n\n /**\n * Get if a pool is finalized\n * @param {String} poolAddress\n * @return {Boolean}\n */\n async isFinalized(poolAddress: string): Promise<boolean> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n try {\n result = await pool.methods.isFinalized().call()\n } catch (e) {\n this.logger.error(`ERROR: Failed to check whether pool is finalized: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get pool fee\n * @param {String} poolAddress\n * @return {String} Swap fee. To get the percentage value, substract by 100. E.g. `0.1` represents a 10% swap fee.\n */\n async getSwapFee(poolAddress: string): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let fee = null\n try {\n const result = await pool.methods.getSwapFee().call()\n fee = this.web3.utils.fromWei(result)\n } catch (e) {\n this.logger.error(`ERROR: Failed to get pool fee: ${e.message}`)\n }\n return fee\n }\n\n /**\n * The normalized weight of a token. The combined normalized weights of all tokens will sum up to 1. (Note: the actual sum may be 1 plus or minus a few wei due to division precision loss)\n * @param {String} poolAddress\n * @param {String} token\n * @return {String}\n */\n async getNormalizedWeight(poolAddress: string, token: string): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let weight = null\n try {\n const result = await pool.methods.getNormalizedWeight(token).call()\n weight = this.web3.utils.fromWei(result)\n } catch (e) {\n this.logger.error(`ERROR: Failed to get normalized weight of a token: ${e.message}`)\n }\n return weight\n }\n\n /**\n * getDenormalizedWeight of a token in pool\n * @param {String} poolAddress\n * @param {String} token\n * @return {String}\n */\n async getDenormalizedWeight(poolAddress: string, token: string): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let weight = null\n try {\n const result = await pool.methods.getDenormalizedWeight(token).call()\n weight = this.web3.utils.fromWei(result)\n } catch (e) {\n this.logger.error('ERROR: Failed to get denormalized weight of a token in pool')\n }\n return weight\n }\n\n /**\n * getTotalDenormalizedWeight in pool\n * @param {String} poolAddress\n * @return {String}\n */\n async getTotalDenormalizedWeight(poolAddress: string): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let weight = null\n try {\n const result = await pool.methods.getTotalDenormalizedWeight().call()\n weight = this.web3.utils.fromWei(result)\n } catch (e) {\n this.logger.error('ERROR: Failed to get total denormalized weight in pool')\n }\n return weight\n }\n\n /**\n * Get Market Fees available to be collected for a specific token\n * @param {String} poolAddress\n * @param {String} token token we want to check fees\n * @return {String}\n */\n async getMarketFees(poolAddress: string, token: string): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let weight = null\n try {\n const result = await pool.methods.publishMarketFees(token).call()\n weight = await unitsToAmount(this.web3, token, result)\n } catch (e) {\n this.logger.error(`ERROR: Failed to get market fees for a token: ${e.message}`)\n }\n return weight\n }\n\n /**\n * Get Community Get the current amount of fees which can be withdrawned by the Market\n * @return {CurrentFees}\n */\n async getCurrentMarketFees(poolAddress: string): Promise<CurrentFees> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n try {\n const currentMarketFees = await pool.methods.getCurrentOPFFees().call()\n return currentMarketFees\n } catch (e) {\n this.logger.error(`ERROR: Failed to get community fees for a token: ${e.message}`)\n }\n }\n\n /**\n * Get getCurrentOPFFees Get the current amount of fees which can be withdrawned by OPF\n * @return {CurrentFees}\n */\n async getCurrentOPFFees(poolAddress: string): Promise<CurrentFees> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n try {\n const currentMarketFees = await pool.methods.getCurrentOPFFees().call()\n return currentMarketFees\n } catch (e) {\n this.logger.error(`ERROR: Failed to get community fees for a token: ${e.message}`)\n }\n }\n\n /**\n * Get Community Fees available to be collected for a specific token\n * @param {String} poolAddress\n * @param {String} token token we want to check fees\n * @return {String}\n */\n async getCommunityFees(poolAddress: string, token: string): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let weight = null\n try {\n const result = await pool.methods.communityFees(token).call()\n weight = await unitsToAmount(this.web3, token, result)\n } catch (e) {\n this.logger.error(`ERROR: Failed to get community fees for a token: ${e.message}`)\n }\n return weight\n }\n\n /**\n * Estimate gas cost for collectOPF\n * @param {String} address\n * @param {String} poolAddress\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estCollectOPF(\n address: string,\n poolAddress: string,\n contractInstance?: Contract\n ): Promise<number> {\n const poolContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi as AbiItem[], poolAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await poolContract.methods\n .collectOPF()\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * collectOPF - collect opf fee - can be called by anyone\n * @param {String} address\n * @param {String} poolAddress\n * @return {TransactionReceipt}\n */\n async collectOPF(address: string, poolAddress: string): Promise<TransactionReceipt> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n const estGas = await this.estCollectOPF(address, poolAddress)\n\n try {\n result = await pool.methods.collectOPF().send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n this.logger.error(`ERROR: Failed to swap exact amount in : ${e.message}`)\n }\n return result\n }\n\n /**\n * Estimate gas cost for collectMarketFee\n * @param {String} address\n * @param {String} poolAddress\n * @param {String} to address that will receive fees\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estCollectMarketFee(\n address: string,\n poolAddress: string,\n contractInstance?: Contract\n ): Promise<number> {\n const poolContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi as AbiItem[], poolAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await poolContract.methods\n .collectMarketFee()\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * collectOPF - collect market fees - can be called by the publishMarketCollector\n * @param {String} address\n * @param {String} poolAddress\n * @param {String} to address that will receive fees\n * @return {TransactionReceipt}\n */\n async collectMarketFee(\n address: string,\n poolAddress: string\n ): Promise<TransactionReceipt> {\n if ((await this.getMarketFeeCollector(poolAddress)) !== address) {\n throw new Error(`Caller is not MarketFeeCollector`)\n }\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n const estGas = await this.estCollectMarketFee(address, poolAddress)\n\n try {\n result = await pool.methods.collectMarketFee().send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n this.logger.error(`ERROR: Failed to swap exact amount in : ${e.message}`)\n }\n return result\n }\n\n /**\n * Estimate gas cost for updateMarketFeeCollector\n * @param {String} address\n * @param {String} poolAddress\n * @param {String} newCollector new market fee collector address\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estUpdateMarketFeeCollector(\n address: string,\n poolAddress: string,\n newCollector: string,\n contractInstance?: Contract\n ): Promise<number> {\n const poolContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi as AbiItem[], poolAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await poolContract.methods\n .updateMarketFeeCollector(newCollector)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * updateMarketFeeCollector - updates marketFeeCollector - can be called only by the marketFeeCollector\n * @param {String} address\n * @param {String} poolAddress\n * @param {String} newCollector new market fee collector address\n * @return {TransactionReceipt}\n */\n async updateMarketFeeCollector(\n address: string,\n poolAddress: string,\n newCollector: string\n ): Promise<TransactionReceipt> {\n if ((await this.getMarketFeeCollector(poolAddress)) !== address) {\n throw new Error(`Caller is not MarketFeeCollector`)\n }\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n const estGas = await this.estUpdateMarketFeeCollector(\n address,\n poolAddress,\n newCollector\n )\n\n try {\n result = await pool.methods.updateMarketFeeCollector(newCollector).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n this.logger.error(`ERROR: Failed to swap exact amount in : ${e.message}`)\n }\n return result\n }\n\n /**\n * Estimate gas cost for swapExactAmountIn\n * @param {String} address\n * @param {String} poolAddress\n * @param {TokenInOutMarket} tokenInOutMarket\n * @param {AmountsInMaxFee} amountsInOutMaxFee\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estSwapExactAmountIn(\n address: string,\n poolAddress: string,\n tokenInOutMarket: TokenInOutMarket,\n amountsInOutMaxFee: AmountsInMaxFee,\n contractInstance?: Contract\n ): Promise<number> {\n const poolContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi as AbiItem[], poolAddress),\n this.config\n )\n\n const maxPrice = amountsInOutMaxFee.maxPrice\n ? this.web3.utils.toWei(amountsInOutMaxFee.maxPrice)\n : MaxUint256\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await poolContract.methods\n .swapExactAmountIn(\n [\n tokenInOutMarket.tokenIn,\n tokenInOutMarket.tokenOut,\n tokenInOutMarket.marketFeeAddress\n ],\n [\n amountsInOutMaxFee.tokenAmountIn,\n amountsInOutMaxFee.minAmountOut,\n maxPrice,\n this.web3.utils.toWei(amountsInOutMaxFee.swapMarketFee)\n ]\n )\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * swapExactAmountIn - Trades an exact tokenAmountIn of tokenIn taken from the caller by the pool,\n * in exchange for at least minAmountOut of tokenOut given to the caller from the pool, with a maximum marginal price of maxPrice.\n * Returns (tokenAmountOut, spotPriceAfter), where tokenAmountOut is the amount of token that came out of the pool,\n * and spotPriceAfter is the new marginal spot price, ie, the result of getSpotPrice after the call.\n * (These values are what are limited by the arguments; you are guaranteed tokenAmountOut >= minAmountOut and spotPriceAfter <= maxPrice).\n * @param {String} address\n * @param {String} poolAddress\n * @param {TokenInOutMarket} tokenInOutMarket\n * @param {AmountsInMaxFee} amountsInOutMaxFee\n * @return {TransactionReceipt}\n */\n async swapExactAmountIn(\n address: string,\n poolAddress: string,\n tokenInOutMarket: TokenInOutMarket,\n amountsInOutMaxFee: AmountsInMaxFee\n ): Promise<TransactionReceipt> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n\n amountsInOutMaxFee.tokenAmountIn = await amountToUnits(\n this.web3,\n tokenInOutMarket.tokenIn,\n amountsInOutMaxFee.tokenAmountIn\n )\n\n amountsInOutMaxFee.minAmountOut = await amountToUnits(\n this.web3,\n tokenInOutMarket.tokenOut,\n amountsInOutMaxFee.minAmountOut\n )\n\n let result = null\n\n const estGas = await this.estSwapExactAmountIn(\n address,\n poolAddress,\n tokenInOutMarket,\n amountsInOutMaxFee\n )\n\n const maxPrice = amountsInOutMaxFee.maxPrice\n ? this.web3.utils.toWei(amountsInOutMaxFee.maxPrice)\n : MaxUint256\n\n try {\n result = await pool.methods\n .swapExactAmountIn(\n [\n tokenInOutMarket.tokenIn,\n tokenInOutMarket.tokenOut,\n tokenInOutMarket.marketFeeAddress\n ],\n [\n amountsInOutMaxFee.tokenAmountIn,\n amountsInOutMaxFee.minAmountOut,\n maxPrice,\n this.web3.utils.toWei(amountsInOutMaxFee.swapMarketFee)\n ]\n )\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n this.logger.error(`ERROR: Failed to swap exact amount in : ${e.message}`)\n }\n\n return result\n }\n\n /**\n * Estimate gas cost for swapExactAmountOut\n * @param {String} address\n * @param {String} poolAddress\n * @param {TokenInOutMarket} tokenInOutMarket\n * @param {AmountsOutMaxFee} amountsInOutMaxFee\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estSwapExactAmountOut(\n address: string,\n poolAddress: string,\n tokenInOutMarket: TokenInOutMarket,\n amountsInOutMaxFee: AmountsOutMaxFee,\n contractInstance?: Contract\n ): Promise<number> {\n const poolContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi as AbiItem[], poolAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n\n const maxPrice = amountsInOutMaxFee.maxPrice\n ? this.web3.utils.toWei(amountsInOutMaxFee.maxPrice)\n : MaxUint256\n\n let estGas\n try {\n estGas = await poolContract.methods\n .swapExactAmountOut(\n [\n tokenInOutMarket.tokenIn,\n tokenInOutMarket.tokenOut,\n tokenInOutMarket.marketFeeAddress\n ],\n [\n amountsInOutMaxFee.maxAmountIn,\n amountsInOutMaxFee.tokenAmountOut,\n maxPrice,\n this.web3.utils.toWei(amountsInOutMaxFee.swapMarketFee)\n ]\n )\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * swapExactAmountOut\n * @param {String} account\n * @param {String} poolAddress\n * @param {TokenInOutMarket} tokenInOutMarket\n * @param {AmountsOutMaxFee} amountsInOutMaxFee\n * @return {TransactionReceipt}\n */\n async swapExactAmountOut(\n account: string,\n poolAddress: string,\n tokenInOutMarket: TokenInOutMarket,\n amountsInOutMaxFee: AmountsOutMaxFee\n ): Promise<TransactionReceipt> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n\n amountsInOutMaxFee.maxAmountIn = await amountToUnits(\n this.web3,\n tokenInOutMarket.tokenIn,\n amountsInOutMaxFee.maxAmountIn\n )\n\n amountsInOutMaxFee.tokenAmountOut = await amountToUnits(\n this.web3,\n tokenInOutMarket.tokenOut,\n amountsInOutMaxFee.tokenAmountOut\n )\n\n const estGas = await this.estSwapExactAmountOut(\n account,\n poolAddress,\n tokenInOutMarket,\n amountsInOutMaxFee\n )\n\n const maxPrice = amountsInOutMaxFee.maxPrice\n ? this.web3.utils.toWei(amountsInOutMaxFee.maxPrice)\n : MaxUint256\n\n try {\n result = await pool.methods\n .swapExactAmountOut(\n [\n tokenInOutMarket.tokenIn,\n tokenInOutMarket.tokenOut,\n tokenInOutMarket.marketFeeAddress\n ],\n [\n amountsInOutMaxFee.maxAmountIn,\n amountsInOutMaxFee.tokenAmountOut,\n maxPrice,\n this.web3.utils.toWei(amountsInOutMaxFee.swapMarketFee)\n ]\n )\n .send({\n from: account,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n this.logger.error(`ERROR: Failed to swap exact amount out: ${e.message}`)\n }\n return result\n }\n\n /**\n * Estimate gas cost for swapExactAmountOut\n * @param {String} address\n * @param {String} poolAddress\n * @param {String} poolAmountOut will be converted to wei\n * @param {String[]} maxAmountsIn array holding maxAmount per each token, will be converted to wei\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estJoinPool(\n address: string,\n poolAddress: string,\n poolAmountOut: string,\n maxAmountsIn: string[],\n contractInstance?: Contract\n ): Promise<number> {\n const poolContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi as AbiItem[], poolAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await poolContract.methods\n .joinPool(poolAmountOut, maxAmountsIn)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Join the pool, getting poolAmountOut pool tokens. This will pull some of each of the currently trading tokens in the pool, meaning you must have called approve for each token for this pool. These values are limited by the array of maxAmountsIn in the order of the pool tokens.\n * @param {String} address\n * @param {String} poolAddress\n * @param {String} poolAmountOut will be converted to wei\n * @param {String[]} maxAmountsIn array holding maxAmount per each token, will be converted to wei\n * @return {TransactionReceipt}\n */\n async joinPool(\n address: string,\n poolAddress: string,\n poolAmountOut: string,\n maxAmountsIn: string[]\n ): Promise<TransactionReceipt> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n const weiMaxAmountsIn = []\n const tokens = await this.getFinalTokens(poolAddress)\n\n for (let i = 0; i < 2; i++) {\n const amount = await amountToUnits(this.web3, tokens[i], maxAmountsIn[i])\n weiMaxAmountsIn.push(amount)\n }\n\n let result = null\n\n const estGas = await this.estJoinPool(\n address,\n poolAddress,\n this.web3.utils.toWei(poolAmountOut),\n weiMaxAmountsIn\n )\n\n try {\n result = await pool.methods\n .joinPool(this.web3.utils.toWei(poolAmountOut), weiMaxAmountsIn)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n this.logger.error(`ERROR: Failed to join pool: ${e.message}`)\n }\n return result\n }\n\n /**\n * Estimate gas cost for exitPool\n* @param {String} address\n * @param {String} poolAddress\n ``* @param {String} poolAmountIn will be converted to wei\n * @param {String[]} minAmountsOut array holding minAmount per each token, will be converted to wei\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estExitPool(\n address: string,\n poolAddress: string,\n poolAmountIn: string,\n minAmountsOut: string[],\n contractInstance?: Contract\n ): Promise<number> {\n const poolContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi as AbiItem[], poolAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await poolContract.methods\n .exitPool(poolAmountIn, minAmountsOut)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Exit the pool, paying poolAmountIn pool tokens and getting some of each of the currently trading tokens in return. These values are limited by the array of minAmountsOut in the order of the pool tokens.\n * @param {String} account\n * @param {String} poolAddress\n * @param {String} poolAmountIn will be converted to wei\n * @param {String[]} minAmountsOut array holding minAmount per each token, will be converted to wei\n * @return {TransactionReceipt}\n */\n async exitPool(\n account: string,\n poolAddress: string,\n poolAmountIn: string,\n minAmountsOut: string[]\n ): Promise<TransactionReceipt> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n const weiMinAmountsOut = []\n const tokens = await this.getFinalTokens(poolAddress)\n\n for (let i = 0; i < 2; i++) {\n const amount = await amountToUnits(this.web3, tokens[i], minAmountsOut[i])\n weiMinAmountsOut.push(amount)\n }\n let result = null\n const estGas = await this.estExitPool(\n account,\n poolAddress,\n this.web3.utils.toWei(poolAmountIn),\n weiMinAmountsOut\n )\n\n try {\n result = await pool.methods\n .exitPool(this.web3.utils.toWei(poolAmountIn), weiMinAmountsOut)\n .send({\n from: account,\n gas: estGas,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n this.logger.error(`ERROR: Failed to exit pool: ${e.message}`)\n }\n return result\n }\n\n /**\n * Estimate gas cost for joinswapExternAmountIn\n * @param {String} address\n * @param {String} poolAddress\n * @param {String} tokenIn\n * @param {String} tokenAmountIn will be converted to wei\n * @param {String} minPoolAmountOut will be converted to wei\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estJoinswapExternAmountIn(\n address: string,\n poolAddress: string,\n tokenIn: string,\n tokenAmountIn: string,\n minPoolAmountOut: string,\n contractInstance?: Contract\n ): Promise<number> {\n const poolContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi as AbiItem[], poolAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await poolContract.methods\n .joinswapExternAmountIn(tokenIn, tokenAmountIn, minPoolAmountOut)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Pay tokenAmountIn of token tokenIn to join the pool, getting poolAmountOut of the pool shares.\n * @param {String} account\n * @param {String} poolAddress\n * @param {String} tokenIn\n * @param {String} tokenAmountIn will be converted to wei\n * @param {String} minPoolAmountOut will be converted to wei\n * @return {TransactionReceipt}\n */\n async joinswapExternAmountIn(\n account: string,\n poolAddress: string,\n tokenIn: string,\n tokenAmountIn: string,\n minPoolAmountOut: string\n ): Promise<TransactionReceipt> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n\n const amountInFormatted = await amountToUnits(this.web3, tokenIn, tokenAmountIn)\n const estGas = await this.estJoinswapExternAmountIn(\n account,\n poolAddress,\n tokenIn,\n amountInFormatted,\n this.web3.utils.toWei(minPoolAmountOut)\n )\n\n try {\n result = await pool.methods\n .joinswapExternAmountIn(\n tokenIn,\n amountInFormatted,\n this.web3.utils.toWei(minPoolAmountOut)\n )\n .send({\n from: account,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n this.logger.error(`ERROR: Failed to pay tokens in order to \\\n join the pool: ${e.message}`)\n }\n return result\n }\n\n /**\n * Estimate gas cost for joinswapPoolAmountOut\n * @param {String} address\n * @param {String} poolAddress\n * @param {String} tokenIn\n * @param {String} poolAmountOut will be converted to wei\n * @param {String} maxAmountIn will be converted to wei\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estJoinswapPoolAmountOut(\n address: string,\n poolAddress: string,\n tokenIn: string,\n poolAmountOut: string,\n maxAmountIn: string,\n contractInstance?: Contract\n ): Promise<number> {\n const poolContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi as AbiItem[], poolAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await poolContract.methods\n .joinswapPoolAmountOut(tokenIn, poolAmountOut, maxAmountIn)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Specify poolAmountOut pool shares that you want to get, and a token tokenIn to pay with. This costs tokenAmountIn tokens (these went into the pool).\n * @param {String} account\n * @param {String} poolAddress\n * @param {String} tokenIn\n * @param {String} poolAmountOut will be converted to wei\n * @param {String} maxAmountIn will be converted to wei\n * @return {TransactionReceipt}\n */\n async joinswapPoolAmountOut(\n account: string,\n poolAddress: string,\n tokenIn: string,\n poolAmountOut: string,\n maxAmountIn: string\n ): Promise<TransactionReceipt> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n\n const maxAmountInFormatted = await amountToUnits(this.web3, tokenIn, maxAmountIn)\n const estGas = await this.estJoinswapPoolAmountOut(\n account,\n poolAddress,\n tokenIn,\n this.web3.utils.toWei(poolAmountOut),\n maxAmountInFormatted\n )\n\n try {\n result = await pool.methods\n .joinswapPoolAmountOut(\n tokenIn,\n this.web3.utils.toWei(poolAmountOut),\n maxAmountInFormatted\n )\n .send({\n from: account,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n this.logger.error('ERROR: Failed to join swap pool amount out')\n }\n return result\n }\n\n /**\n * Estimate gas cost for joinswapExternAmountIn\n * @param {String} address\n @param {String} poolAddress\n * @param {String} tokenOut\n * @param {String} poolAmountIn will be converted to wei\n * @param {String} minTokenAmountOut will be converted to wei\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estExitswapPoolAmountIn(\n address: string,\n poolAddress: string,\n tokenOut: string,\n poolAmountIn: string,\n minTokenAmountOut: string,\n contractInstance?: Contract\n ): Promise<number> {\n const poolContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi as AbiItem[], poolAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await poolContract.methods\n .exitswapPoolAmountIn(tokenOut, poolAmountIn, minTokenAmountOut)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Pay poolAmountIn pool shares into the pool, getting minTokenAmountOut of the given token tokenOut out of the pool.\n * @param {String} account\n * @param {String} poolAddress\n * @param {String} tokenOut\n * @param {String} poolAmountIn will be converted to wei\n * @param {String} minTokenAmountOut will be converted to wei\n * @return {TransactionReceipt}\n */\n async exitswapPoolAmountIn(\n account: string,\n poolAddress: string,\n tokenOut: string,\n poolAmountIn: string,\n minTokenAmountOut: string\n ): Promise<TransactionReceipt> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n\n const minTokenOutFormatted = await amountToUnits(\n this.web3,\n tokenOut,\n minTokenAmountOut\n )\n const estGas = await this.estExitswapPoolAmountIn(\n account,\n poolAddress,\n tokenOut,\n this.web3.utils.toWei(poolAmountIn),\n minTokenOutFormatted\n )\n\n try {\n result = await pool.methods\n .exitswapPoolAmountIn(\n tokenOut,\n this.web3.utils.toWei(poolAmountIn),\n minTokenOutFormatted\n )\n .send({\n from: account,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n this.logger.error(`ERROR: Failed to pay pool shares into the pool: ${e.message}`)\n }\n return result\n }\n\n /**\n * Estimate gas cost for joinswapExternAmountIn\n * @param {String} address\n * @param {String} poolAddress\n * @param {String} tokenOut\n * @param {String} tokenAmountOut will be converted to wei\n * @param {String} maxPoolAmountIn will be converted to wei\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estExitswapExternAmountOut(\n address: string,\n poolAddress: string,\n tokenOut: string,\n tokenAmountOut: string,\n maxPoolAmountIn: string,\n contractInstance?: Contract\n ): Promise<number> {\n const poolContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi as AbiItem[], poolAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await poolContract.methods\n .exitswapExternAmountOut(tokenOut, tokenAmountOut, maxPoolAmountIn)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Specify tokenAmountOut of token tokenOut that you want to get out of the pool. This costs poolAmountIn pool shares (these went into the pool).\n * @param {String} account\n * @param {String} poolAddress\n * @param {String} tokenOut\n * @param {String} tokenAmountOut will be converted to wei\n * @param {String} maxPoolAmountIn will be converted to wei\n * @return {TransactionReceipt}\n */\n async exitswapExternAmountOut(\n account: string,\n poolAddress: string,\n tokenOut: string,\n tokenAmountOut: string,\n maxPoolAmountIn: string\n ): Promise<TransactionReceipt> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let result = null\n\n const estGas = await this.estExitswapExternAmountOut(\n account,\n poolAddress,\n tokenOut,\n this.web3.utils.toWei(tokenAmountOut),\n this.web3.utils.toWei(maxPoolAmountIn)\n )\n\n try {\n result = await pool.methods\n .exitswapExternAmountOut(\n tokenOut,\n this.web3.utils.toWei(tokenAmountOut),\n this.web3.utils.toWei(maxPoolAmountIn)\n )\n .send({\n from: account,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n this.logger.error('ERROR: Failed to exitswapExternAmountOut')\n }\n return result\n }\n\n /**\n * Get Spot Price of swaping tokenIn to tokenOut\n * @param {String} poolAddress\n * @param {String} tokenIn\n * @param {String} tokenOut\n * @param {String} swapMarketFe\n * @return {String}\n */\n async getSpotPrice(\n poolAddress: string,\n tokenIn: string,\n tokenOut: string,\n swapMarketFee: string\n ): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let decimalsTokenIn = 18\n let decimalsTokenOut = 18\n\n const tokenInContract = setContractDefaults(\n new this.web3.eth.Contract(defaultErc20Abi.abi as AbiItem[], tokenIn),\n this.config\n )\n const tokenOutContract = setContractDefaults(\n new this.web3.eth.Contract(defaultErc20Abi.abi as AbiItem[], tokenOut),\n this.config\n )\n try {\n decimalsTokenIn = await tokenInContract.methods.decimals().call()\n } catch (e) {\n this.logger.error('ERROR: FAILED TO CALL DECIMALS(), USING 18')\n }\n try {\n decimalsTokenOut = await tokenOutContract.methods.decimals().call()\n } catch (e) {\n this.logger.error('ERROR: FAILED TO CALL DECIMALS(), USING 18')\n }\n\n let price = null\n try {\n price = await pool.methods\n .getSpotPrice(tokenIn, tokenOut, this.web3.utils.toWei(swapMarketFee))\n .call()\n price = new BigNumber(price.toString())\n } catch (e) {\n this.logger.error('ERROR: Failed to get spot price of swapping tokenIn to tokenOut')\n }\n\n let decimalsDiff\n if (decimalsTokenIn > decimalsTokenOut) {\n decimalsDiff = decimalsTokenIn - decimalsTokenOut\n price = new BigNumber(price / 10 ** decimalsDiff)\n price = price / 10 ** decimalsTokenOut\n } else {\n decimalsDiff = decimalsTokenOut - decimalsTokenIn\n price = new BigNumber(price * 10 ** (2 * decimalsDiff))\n price = price / 10 ** decimalsTokenOut\n }\n\n return price.toString()\n }\n\n public async getAmountInExactOut(\n poolAddress: string,\n tokenIn: string,\n tokenOut: string,\n tokenAmountOut: string,\n swapMarketFee: string\n ): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n\n const amountOutFormatted = await amountToUnits(this.web3, tokenOut, tokenAmountOut)\n\n let amount = null\n\n try {\n const result = await pool.methods\n .getAmountInExactOut(\n tokenIn,\n tokenOut,\n amountOutFormatted,\n this.web3.utils.toWei(swapMarketFee)\n )\n .call()\n amount = await unitsToAmount(this.web3, tokenIn, result)\n } catch (e) {\n this.logger.error('ERROR: Failed to calcInGivenOut')\n }\n return amount\n }\n\n public async getAmountOutExactIn(\n poolAddress: string,\n tokenIn: string,\n tokenOut: string,\n tokenAmountIn: string,\n swapMarketFee: string\n ): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n\n const amountInFormatted = await amountToUnits(this.web3, tokenIn, tokenAmountIn)\n\n let amount = null\n\n try {\n const result = await pool.methods\n .getAmountOutExactIn(\n tokenIn,\n tokenOut,\n amountInFormatted,\n this.web3.utils.toWei(swapMarketFee)\n )\n .call()\n\n amount = await unitsToAmount(this.web3, tokenOut, result)\n } catch (e) {\n this.logger.error('ERROR: Failed to calcOutGivenIn')\n }\n return amount\n }\n\n public async calcPoolOutGivenSingleIn(\n poolAddress: string,\n tokenIn: string,\n tokenAmountIn: string\n ): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let amount = null\n\n try {\n const result = await pool.methods\n .calcPoolOutSingleIn(\n tokenIn,\n await amountToUnits(this.web3, tokenIn, tokenAmountIn)\n )\n .call()\n\n amount = await unitsToAmount(this.web3, poolAddress, result)\n } catch (e) {\n this.logger.error(`ERROR: Failed to calculate PoolOutGivenSingleIn : ${e.message}`)\n }\n return amount\n }\n\n public async calcSingleInGivenPoolOut(\n poolAddress: string,\n tokenIn: string,\n poolAmountOut: string\n ): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let amount = null\n const amountFormatted = await amountToUnits(this.web3, poolAddress, poolAmountOut)\n try {\n const result = await pool.methods\n .calcSingleInPoolOut(tokenIn, amountFormatted)\n\n .call()\n\n amount = await unitsToAmount(this.web3, tokenIn, result)\n } catch (e) {\n this.logger.error(`ERROR: Failed to calculate SingleInGivenPoolOut : ${e.message}`)\n }\n return amount\n }\n\n public async calcSingleOutGivenPoolIn(\n poolAddress: string,\n tokenOut: string,\n poolAmountIn: string\n ): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let amount = null\n\n try {\n const result = await pool.methods\n .calcSingleOutPoolIn(\n tokenOut,\n await amountToUnits(this.web3, poolAddress, poolAmountIn)\n )\n .call()\n amount = await unitsToAmount(this.web3, tokenOut, result)\n } catch (e) {\n this.logger.error(`ERROR: Failed to calculate SingleOutGivenPoolIn : ${e}`)\n }\n return amount\n }\n\n public async calcPoolInGivenSingleOut(\n poolAddress: string,\n tokenOut: string,\n tokenAmountOut: string\n ): Promise<string> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n let amount = null\n\n try {\n const result = await pool.methods\n .calcPoolInSingleOut(\n tokenOut,\n await amountToUnits(this.web3, tokenOut, tokenAmountOut)\n )\n .call()\n\n amount = await unitsToAmount(this.web3, poolAddress, result)\n } catch (e) {\n this.logger.error(`ERROR: Failed to calculate PoolInGivenSingleOut : ${e.message}`)\n }\n return amount\n }\n\n /**\n * Get LOG_SWAP encoded topic\n * @return {String}\n */\n public getSwapEventSignature(): string {\n const abi = this.poolAbi as AbiItem[]\n const eventdata = abi.find(function (o) {\n if (o.name === 'LOG_SWAP' && o.type === 'event') return o\n })\n const topic = this.web3.eth.abi.encodeEventSignature(eventdata as any)\n return topic\n }\n\n /**\n * Get LOG_JOIN encoded topic\n * @return {String}\n */\n public getJoinEventSignature(): string {\n const abi = this.poolAbi as AbiItem[]\n const eventdata = abi.find(function (o) {\n if (o.name === 'LOG_JOIN' && o.type === 'event') return o\n })\n const topic = this.web3.eth.abi.encodeEventSignature(eventdata as any)\n return topic\n }\n\n /**\n * Get LOG_EXIT encoded topic\n * @return {String}\n */\n public getExitEventSignature(): string {\n const abi = this.poolAbi as AbiItem[]\n const eventdata = abi.find(function (o) {\n if (o.name === 'LOG_EXIT' && o.type === 'event') return o\n })\n const topic = this.web3.eth.abi.encodeEventSignature(eventdata as any)\n return topic\n }\n}\n","import Web3 from 'web3'\nimport { AbiItem } from 'web3-utils'\nimport { Contract } from 'web3-eth-contract'\nimport { TransactionReceipt } from 'web3-eth'\nimport Decimal from 'decimal.js'\nimport defaultDispenserAbi from '@oceanprotocol/contracts/artifacts/contracts/pools/dispenser/Dispenser.sol/Dispenser.json'\nimport {\n LoggerInstance as logger,\n getFairGasPrice,\n configHelperNetworks,\n setContractDefaults\n} from '../../utils/'\nimport { Datatoken } from '../../tokens'\nimport { Config } from '../../models/index.js'\n\nexport interface DispenserToken {\n active: boolean\n owner: string\n maxTokens: string\n maxBalance: string\n balance: string\n isMinter: boolean\n allowedSwapper: string\n}\n\nexport class Dispenser {\n public GASLIMIT_DEFAULT = 1000000\n public web3: Web3 = null\n public dispenserAddress: string\n public config: Config\n public dispenserAbi: AbiItem | AbiItem[]\n public dispenserContract: Contract\n\n /**\n * Instantiate Dispenser\n * @param {any} web3\n * @param {String} dispenserAddress\n * @param {any} dispenserABI\n */\n constructor(\n web3: Web3,\n dispenserAddress: string = null,\n dispenserAbi: AbiItem | AbiItem[] = null,\n config?: Config\n ) {\n this.web3 = web3\n this.dispenserAddress = dispenserAddress\n this.dispenserAbi = dispenserAbi || (defaultDispenserAbi.abi as AbiItem[])\n this.config = config || configHelperNetworks[0]\n if (web3)\n this.dispenserContract = setContractDefaults(\n new this.web3.eth.Contract(this.dispenserAbi, this.dispenserAddress),\n this.config\n )\n }\n\n /**\n * Get information about a datatoken dispenser\n * @param {String} dtAddress\n * @return {Promise<FixedPricedExchange>} Exchange details\n */\n public async status(dtAdress: string): Promise<DispenserToken> {\n try {\n const result: DispenserToken = await this.dispenserContract.methods\n .status(dtAdress)\n .call()\n result.maxTokens = this.web3.utils.fromWei(result.maxTokens)\n result.maxBalance = this.web3.utils.fromWei(result.maxBalance)\n result.balance = this.web3.utils.fromWei(result.balance)\n return result\n } catch (e) {\n logger.warn(`No dispenser available for datatoken: ${dtAdress}`)\n }\n return null\n }\n\n /**\n * Estimate gas cost for create method\n * @param {String} dtAddress Datatoken address\n * @param {String} address Owner address\n * @param {String} maxTokens max tokens to dispense\n * @param {String} maxBalance max balance of requester\n * @param {String} allowedSwapper if !=0, only this address can request DTs\n * @return {Promise<any>}\n */\n public async estGasCreate(\n dtAddress: string,\n address: string,\n maxTokens: string,\n maxBalance: string,\n allowedSwapper: string\n ): Promise<any> {\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await this.dispenserContract.methods\n .create(\n dtAddress,\n this.web3.utils.toWei(maxTokens),\n this.web3.utils.toWei(maxBalance),\n address,\n allowedSwapper\n )\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * Creates a new Dispenser\n * @param {String} dtAddress Datatoken address\n * @param {String} address Owner address\n * @param {String} maxTokens max tokens to dispense\n * @param {String} maxBalance max balance of requester\n * @param {String} allowedSwapper only account that can ask tokens. set address(0) if not required\n * @return {Promise<TransactionReceipt>} transactionId\n */\n public async create(\n dtAddress: string,\n address: string,\n maxTokens: string,\n maxBalance: string,\n allowedSwapper: string\n ): Promise<TransactionReceipt> {\n const estGas = await this.estGasCreate(\n dtAddress,\n address,\n maxTokens,\n maxBalance,\n allowedSwapper\n )\n\n // Call createFixedRate contract method\n const trxReceipt = await this.dispenserContract.methods\n .create(\n dtAddress,\n this.web3.utils.toWei(maxTokens),\n this.web3.utils.toWei(maxBalance),\n address,\n allowedSwapper\n )\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n\n /**\n * Estimate gas for activate method\n * @param {String} dtAddress\n * @param {Number} maxTokens max amount of tokens to dispense\n * @param {Number} maxBalance max balance of user. If user balance is >, then dispense will be rejected\n * @param {String} address User address (must be owner of the datatoken)\n * @return {Promise<any>}\n */\n public async estGasActivate(\n dtAddress: string,\n maxTokens: string,\n maxBalance: string,\n address: string\n ): Promise<any> {\n let estGas\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n try {\n estGas = await this.dispenserContract.methods\n .activate(\n dtAddress,\n this.web3.utils.toWei(maxTokens),\n this.web3.utils.toWei(maxBalance)\n )\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Activates a new dispener.\n * @param {String} dtAddress refers to datatoken address.\n * @param {Number} maxTokens max amount of tokens to dispense\n * @param {Number} maxBalance max balance of user. If user balance is >, then dispense will be rejected\n * @param {String} address User address (must be owner of the datatoken)\n * @return {Promise<TransactionReceipt>} TransactionReceipt\n */\n public async activate(\n dtAddress: string,\n maxTokens: string,\n maxBalance: string,\n address: string\n ): Promise<TransactionReceipt> {\n try {\n const estGas = await this.estGasActivate(dtAddress, maxTokens, maxBalance, address)\n const trxReceipt = await this.dispenserContract.methods\n .activate(\n dtAddress,\n this.web3.utils.toWei(maxTokens),\n this.web3.utils.toWei(maxBalance)\n )\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n } catch (e) {\n logger.error(`ERROR: Failed to activate dispenser: ${e.message}`)\n }\n return null\n }\n\n /**\n * Estimate gas for deactivate method\n * @param {String} dtAddress\n * @param {String} address User address (must be owner of the datatoken)\n * @return {Promise<any>}\n */\n public async estGasDeactivate(dtAddress: string, address: string): Promise<any> {\n let estGas\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n try {\n estGas = await this.dispenserContract.methods\n .deactivate(dtAddress)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Deactivate an existing dispenser.\n * @param {String} dtAddress refers to datatoken address.\n * @param {String} address User address (must be owner of the datatoken)\n * @return {Promise<TransactionReceipt>} TransactionReceipt\n */\n public async deactivate(\n dtAddress: string,\n address: string\n ): Promise<TransactionReceipt> {\n try {\n const estGas = await this.estGasDeactivate(dtAddress, address)\n const trxReceipt = await this.dispenserContract.methods.deactivate(dtAddress).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n } catch (e) {\n logger.error(`ERROR: Failed to activate dispenser: ${e.message}`)\n }\n return null\n }\n\n /**\n * Estimate gas for setAllowedSwapper method\n * @param {String} dtAddress refers to datatoken address.\n * @param {String} address User address (must be owner of the datatoken)\n * @param {String} newAllowedSwapper refers to the new allowedSwapper\n * @return {Promise<any>}\n */\n public async estGasSetAllowedSwapper(\n dtAddress: string,\n address: string,\n newAllowedSwapper: string\n ): Promise<any> {\n let estGas\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n try {\n estGas = await this.dispenserContract.methods\n .setAllowedSwapper(dtAddress, newAllowedSwapper)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Sets a new allowedSwapper.\n * @param {String} dtAddress refers to datatoken address.\n * @param {String} address User address (must be owner of the datatoken)\n * @param {String} newAllowedSwapper refers to the new allowedSwapper\n * @return {Promise<TransactionReceipt>} TransactionReceipt\n */\n public async setAllowedSwapper(\n dtAddress: string,\n address: string,\n newAllowedSwapper: string\n ): Promise<TransactionReceipt> {\n try {\n const estGas = await this.estGasSetAllowedSwapper(\n dtAddress,\n address,\n newAllowedSwapper\n )\n const trxReceipt = await this.dispenserContract.methods\n .setAllowedSwapper(dtAddress, newAllowedSwapper)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n } catch (e) {\n logger.error(`ERROR: Failed to activate dispenser: ${e.message}`)\n }\n return null\n }\n\n /**\n * Estimate gas for dispense method\n * @param {String} dtAddress refers to datatoken address.\n * @param {String} address User address (must be owner of the datatoken)\n * @param {String} newAllowedSwapper refers to the new allowedSwapper\n * @return {Promise<any>}\n */\n public async estGasDispense(\n dtAddress: string,\n address: string,\n amount: string = '1',\n destination: string\n ): Promise<any> {\n let estGas\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n try {\n estGas = await this.dispenserContract.methods\n .dispense(dtAddress, this.web3.utils.toWei(amount), destination)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Dispense datatokens to caller.\n * The dispenser must be active, hold enough DT (or be able to mint more)\n * and respect maxTokens/maxBalance requirements\n * @param {String} dtAddress refers to datatoken address.\n * @param {String} address User address\n * @param {String} amount amount of datatokens required.\n * @param {String} destination who will receive the tokens\n * @return {Promise<TransactionReceipt>} TransactionReceipt\n */\n public async dispense(\n dtAddress: string,\n address: string,\n amount: string = '1',\n destination: string\n ): Promise<TransactionReceipt> {\n const estGas = await this.estGasDispense(dtAddress, address, amount, destination)\n try {\n const trxReceipt = await this.dispenserContract.methods\n .dispense(dtAddress, this.web3.utils.toWei(amount), destination)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n } catch (e) {\n logger.error(`ERROR: Failed to dispense tokens: ${e.message}`)\n }\n return null\n }\n\n /**\n * Estimate gas for ownerWithdraw method\n * @param {String} dtAddress refers to datatoken address.\n * @param {String} address User address (must be owner of the datatoken)\n * @param {String} newAllowedSwapper refers to the new allowedSwapper\n * @return {Promise<any>}\n */\n public async estGasOwnerWithdraw(dtAddress: string, address: string): Promise<any> {\n let estGas\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n try {\n estGas = await this.dispenserContract.methods\n .ownerWithdraw(dtAddress)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Withdraw all tokens from the dispenser\n * @param {String} dtAddress refers to datatoken address.\n * @param {String} address User address (must be owner of the dispenser)\n * @return {Promise<TransactionReceipt>} TransactionReceipt\n */\n public async ownerWithdraw(\n dtAddress: string,\n address: string\n ): Promise<TransactionReceipt> {\n const estGas = await this.estGasOwnerWithdraw(dtAddress, address)\n try {\n const trxReceipt = await this.dispenserContract.methods\n .ownerWithdraw(dtAddress)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n } catch (e) {\n logger.error(`ERROR: Failed to withdraw tokens: ${e.message}`)\n }\n return null\n }\n\n /**\n * Check if tokens can be dispensed\n * @param {String} dtAddress\n * @param {String} address User address that will receive datatokens\n * @param {String} amount amount of datatokens required.\n * @return {Promise<Boolean>}\n */\n public async isDispensable(\n dtAddress: string,\n datatoken: Datatoken,\n address: string,\n amount: string = '1'\n ): Promise<Boolean> {\n const status = await this.status(dtAddress)\n if (!status) return false\n // check active\n if (status.active === false) return false\n // check maxBalance\n const userBalance = new Decimal(await datatoken.balance(dtAddress, address))\n if (userBalance.greaterThanOrEqualTo(status.maxBalance)) return false\n // check maxAmount\n if (new Decimal(String(amount)).greaterThan(status.maxTokens)) return false\n // check dispenser balance\n const contractBalance = new Decimal(status.balance)\n if (contractBalance.greaterThanOrEqualTo(amount) || status.isMinter === true)\n return true\n return false\n }\n}\n","import defaultFixedRateExchangeAbi from '@oceanprotocol/contracts/artifacts/contracts/pools/fixedRate/FixedRateExchange.sol/FixedRateExchange.json'\nimport defaultErc20Abi from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json'\nimport BigNumber from 'bignumber.js'\nimport { TransactionReceipt } from 'web3-core'\nimport { Contract } from 'web3-eth-contract'\nimport { AbiItem } from 'web3-utils/types'\nimport Web3 from 'web3'\nimport {\n LoggerInstance,\n getFairGasPrice,\n configHelperNetworks,\n setContractDefaults\n} from '../../utils'\nimport { Config } from '../../models/index.js'\n\nexport interface FixedPriceExchange {\n active: boolean\n exchangeOwner: string\n datatoken: string\n baseToken: string\n fixedRate: string\n dtDecimals: string\n btDecimals: string\n dtBalance: string\n btBalance: string\n dtSupply: string\n btSupply: string\n withMint: boolean\n allowedSwapper: string\n exchangeId?: string\n}\n\nexport interface FeesInfo {\n opfFee: string\n marketFee: string\n marketFeeCollector: string\n marketFeeAvailable: string\n oceanFeeAvailable: string\n exchangeId: string\n}\nexport interface FixedPriceSwap {\n exchangeId: string\n caller: string\n baseTokenAmount: string\n datatokenAmount: string\n}\n\nexport enum FixedRateCreateProgressStep {\n CreatingExchange,\n ApprovingDatatoken\n}\n\nexport class FixedRateExchange {\n public GASLIMIT_DEFAULT = 1000000\n /** Ocean related functions */\n public oceanAddress: string = null\n public fixedRateAddress: string\n public fixedRateExchangeAbi: AbiItem | AbiItem[]\n public fixedRateContract: Contract\n public web3: Web3\n public contract: Contract = null\n\n public config: Config\n public ssAbi: AbiItem | AbiItem[]\n\n /**\n * Instantiate FixedRateExchange\n * @param {any} web3\n * @param {any} fixedRateExchangeAbi\n */\n constructor(\n web3: Web3,\n fixedRateAddress: string,\n fixedRateExchangeAbi: AbiItem | AbiItem[] = null,\n oceanAddress: string = null,\n config?: Config\n ) {\n this.web3 = web3\n this.config = config || configHelperNetworks[0]\n this.fixedRateExchangeAbi =\n fixedRateExchangeAbi || (defaultFixedRateExchangeAbi.abi as AbiItem[])\n this.oceanAddress = oceanAddress\n this.fixedRateAddress = fixedRateAddress\n this.contract = setContractDefaults(\n new this.web3.eth.Contract(this.fixedRateExchangeAbi, this.fixedRateAddress),\n this.config\n )\n }\n\n async amountToUnits(token: string, amount: string): Promise<string> {\n let decimals = 18\n const tokenContract = setContractDefaults(\n new this.web3.eth.Contract(defaultErc20Abi.abi as AbiItem[], token),\n this.config\n )\n\n try {\n decimals = await tokenContract.methods.decimals().call()\n } catch (e) {\n LoggerInstance.error('ERROR: FAILED TO CALL DECIMALS(), USING 18')\n }\n\n const amountFormatted = new BigNumber(parseInt(amount) * 10 ** decimals)\n\n return amountFormatted.toString()\n }\n\n async unitsToAmount(token: string, amount: string): Promise<string> {\n let decimals = 18\n const tokenContract = setContractDefaults(\n new this.web3.eth.Contract(defaultErc20Abi.abi as AbiItem[], token),\n this.config\n )\n try {\n decimals = await tokenContract.methods.decimals().call()\n } catch (e) {\n LoggerInstance.error('ERROR: FAILED TO CALL DECIMALS(), USING 18')\n }\n\n const amountFormatted = new BigNumber(parseInt(amount) / 10 ** decimals)\n\n return amountFormatted.toString()\n }\n\n /**\n * Creates unique exchange identifier.\n * @param {String} datatoken Datatoken contract address\n * @param {String} owner Owner of the exchange\n * @return {Promise<string>} exchangeId\n */\n public async generateExchangeId(\n baseToken: string,\n datatoken: string,\n owner: string\n ): Promise<string> {\n const exchangeId = await this.contract.methods\n .generateExchangeId(baseToken, datatoken, owner)\n .call()\n return exchangeId\n }\n\n /**\n * Estimate gas cost for buyDT\n * @param {String} account\n * @param {String} dtAmount datatoken amount we want to buy\n * @param {String} datatokenAddress datatokenAddress\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estBuyDT(\n account: string,\n datatokenAddress: string,\n dtAmount: string,\n maxBaseTokenAmount: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await fixedRate.methods\n .buyDT(datatokenAddress, dtAmount.toString(), maxBaseTokenAmount.toString())\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Atomic swap\n * @param {String} exchangeId ExchangeId\n * @param {String} datatokenAmount Amount of datatokens\n * @param {String} maxBaseTokenAmount max amount of baseToken we want to pay for datatokenAmount\n * @param {String} address User address\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async buyDT(\n address: string,\n exchangeId: string,\n datatokenAmount: string,\n maxBaseTokenAmount: string\n ): Promise<TransactionReceipt> {\n const dtAmountFormatted = await this.amountToUnits(\n (\n await this.getExchange(exchangeId)\n ).datatoken,\n datatokenAmount\n )\n const maxBtFormatted = await this.amountToUnits(\n (\n await this.getExchange(exchangeId)\n ).baseToken,\n maxBaseTokenAmount\n )\n\n const estGas = await this.estBuyDT(\n address,\n exchangeId,\n dtAmountFormatted,\n maxBtFormatted\n )\n try {\n const trxReceipt = await this.contract.methods\n .buyDT(exchangeId, dtAmountFormatted, maxBtFormatted)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to buy datatokens: ${e.message}`)\n return null\n }\n }\n\n /**\n * Estimate gas cost for sellDT\n * @param {String} account\n * @param {String} dtAmount datatoken amount we want to sell\n * @param {String} datatokenAddress datatokenAddress\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estSellDT(\n account: string,\n datatokenAddress: string,\n dtAmount: string,\n maxBaseTokenAmount: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await fixedRate.methods\n .sellDT(datatokenAddress, dtAmount, maxBaseTokenAmount)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Atomic swap\n * @param {String} exchangeId ExchangeId\n * @param {String} datatokenAmount Amount of datatokens\n * @param {String} minBaseTokenAmount min amount of baseToken we want to receive back\n * @param {String} address User address\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async sellDT(\n address: string,\n exchangeId: string,\n datatokenAmount: string,\n minBaseTokenAmount: string\n ): Promise<TransactionReceipt> {\n const dtAmountFormatted = await this.amountToUnits(\n (\n await this.getExchange(exchangeId)\n ).datatoken,\n datatokenAmount\n )\n const minBtFormatted = await this.amountToUnits(\n (\n await this.getExchange(exchangeId)\n ).baseToken,\n minBaseTokenAmount\n )\n const estGas = await this.estBuyDT(\n address,\n exchangeId,\n dtAmountFormatted,\n minBtFormatted\n )\n try {\n const trxReceipt = await this.contract.methods\n .sellDT(exchangeId, dtAmountFormatted, minBtFormatted)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to sell datatokens: ${e.message}`)\n return null\n }\n }\n\n /**\n * Gets total number of exchanges\n * @param {String} exchangeId ExchangeId\n * @param {Number} datatokenAmount Amount of datatokens\n * @return {Promise<Number>} no of available exchanges\n */\n public async getNumberOfExchanges(): Promise<number> {\n const numExchanges = await this.contract.methods.getNumberOfExchanges().call()\n return numExchanges\n }\n\n /**\n * Estimate gas cost for setRate\n * @param {String} account\n * @param {String} exchangeId ExchangeId\n * @param {Number} newRate New rate\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estSetRate(\n account: string,\n exchangeId: string,\n newRate: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await fixedRate.methods\n .setRate(exchangeId, newRate)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Set new rate\n * @param {String} exchangeId ExchangeId\n * @param {Number} newRate New rate\n * @param {String} address User account\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async setRate(\n address: string,\n exchangeId: string,\n newRate: string\n ): Promise<TransactionReceipt> {\n const estGas = await this.estSetRate(\n address,\n exchangeId,\n this.web3.utils.toWei(String(newRate))\n )\n const trxReceipt = await this.contract.methods\n .setRate(exchangeId, this.web3.utils.toWei(newRate))\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for setRate\n * @param {String} account\n * @param {String} exchangeId ExchangeId\n * @param {String} newAllowedSwapper new allowed swapper address\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estSetAllowedSwapper(\n account: string,\n exchangeId: string,\n newAllowedSwapper: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await fixedRate.methods\n .setRate(exchangeId, newAllowedSwapper)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Set new rate\n * @param {String} exchangeId ExchangeId\n * @param {String} newAllowedSwapper newAllowedSwapper (set address zero if we want to remove allowed swapper)\n * @param {String} address User account\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async setAllowedSwapper(\n address: string,\n exchangeId: string,\n newAllowedSwapper: string\n ): Promise<TransactionReceipt> {\n const estGas = await this.estSetAllowedSwapper(address, exchangeId, newAllowedSwapper)\n const trxReceipt = await this.contract.methods\n .setAllowedSwapper(exchangeId, newAllowedSwapper)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for activate\n * @param {String} account\n * @param {String} exchangeId ExchangeId\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estActivate(\n account: string,\n exchangeId: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await fixedRate.methods\n .toggleExchangeState(exchangeId)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Activate an exchange\n * @param {String} exchangeId ExchangeId\n * @param {String} address User address\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async activate(\n address: string,\n exchangeId: string\n ): Promise<TransactionReceipt> {\n const exchange = await this.getExchange(exchangeId)\n if (!exchange) return null\n if (exchange.active === true) return null\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n\n const estGas = await this.estActivate(address, exchangeId)\n const trxReceipt = await this.contract.methods.toggleExchangeState(exchangeId).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for deactivate\n * @param {String} account\n * @param {String} exchangeId ExchangeId\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estDeactivate(\n account: string,\n exchangeId: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await fixedRate.methods\n .toggleExchangeState(exchangeId)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Deactivate an exchange\n * @param {String} exchangeId ExchangeId\n * @param {String} address User address\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async deactivate(\n address: string,\n exchangeId: string\n ): Promise<TransactionReceipt> {\n const exchange = await this.getExchange(exchangeId)\n if (!exchange) return null\n if (exchange.active === false) return null\n\n const estGas = await this.estDeactivate(address, exchangeId)\n\n const trxReceipt = await this.contract.methods.toggleExchangeState(exchangeId).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Get Rate\n * @param {String} exchangeId ExchangeId\n * @return {Promise<string>} Rate (converted from wei)\n */\n public async getRate(exchangeId: string): Promise<string> {\n const weiRate = await this.contract.methods.getRate(exchangeId).call()\n return this.web3.utils.fromWei(weiRate)\n }\n\n /**\n * Get Datatoken Supply in the exchange\n * @param {String} exchangeId ExchangeId\n * @return {Promise<string>} dt supply formatted\n */\n public async getDTSupply(exchangeId: string): Promise<string> {\n const dtSupply = await this.contract.methods.getDTSupply(exchangeId).call()\n return await this.unitsToAmount(\n (\n await this.getExchange(exchangeId)\n ).datatoken,\n dtSupply\n )\n }\n\n /**\n * Get BaseToken Supply in the exchange\n * @param {String} exchangeId ExchangeId\n * @return {Promise<string>} dt supply formatted\n */\n public async getBTSupply(exchangeId: string): Promise<string> {\n const btSupply = await this.contract.methods.getBTSupply(exchangeId).call()\n return await this.unitsToAmount(\n (\n await this.getExchange(exchangeId)\n ).baseToken,\n btSupply\n )\n }\n\n /**\n * Get Allower Swapper (if set this is the only account which can use this exchange, else is set at address(0))\n * @param {String} exchangeId ExchangeId\n * @return {Promise<string>} address of allowedSwapper\n */\n public async getAllowedSwapper(exchangeId: string): Promise<string> {\n return await this.contract.methods.getAllowedSwapper(exchangeId).call()\n }\n\n /**\n * getBTNeeded - returns amount in baseToken that user will pay for datatokenAmount\n * @param {String} exchangeId ExchangeId\n * @param {Number} datatokenAmount Amount of datatokens user wants to buy\n * @return {Promise<string>} Amount of baseToken needed for buying\n */\n public async getAmountBTIn(\n exchangeId: string,\n datatokenAmount: string\n ): Promise<string> {\n const result = await this.contract.methods\n .calcBaseInGivenOutDT(\n exchangeId,\n await this.amountToUnits(\n (\n await this.getExchange(exchangeId)\n ).datatoken,\n datatokenAmount\n )\n )\n .call()\n\n return await this.unitsToAmount(\n (\n await this.getExchange(exchangeId)\n ).baseToken,\n result.baseTokenAmount\n )\n }\n\n /**\n * getBTOut - returns amount in baseToken that user will receive for datatokenAmount sold\n * @param {String} exchangeId ExchangeId\n * @param {Number} datatokenAmount Amount of datatokens\n * @return {Promise<string>} Amount of baseTokens user will receive\n */\n public async getAmountBTOut(\n exchangeId: string,\n datatokenAmount: string\n ): Promise<string> {\n const result = await this.contract.methods\n .calcBaseOutGivenInDT(\n exchangeId,\n await this.amountToUnits(\n (\n await this.getExchange(exchangeId)\n ).datatoken,\n datatokenAmount\n )\n )\n .call()\n\n return await this.unitsToAmount(\n (\n await this.getExchange(exchangeId)\n ).baseToken,\n result.baseTokenAmount\n )\n }\n\n /**\n * Get exchange details\n * @param {String} exchangeId ExchangeId\n * @return {Promise<FixedPricedExchange>} Exchange details\n */\n public async getExchange(exchangeId: string): Promise<FixedPriceExchange> {\n const result: FixedPriceExchange = await this.contract.methods\n .getExchange(exchangeId)\n .call()\n result.dtDecimals = result.dtDecimals.toString()\n result.btDecimals = result.btDecimals.toString()\n result.dtBalance = await this.unitsToAmount(result.datatoken, result.dtBalance)\n result.btBalance = await this.unitsToAmount(result.baseToken, result.btBalance)\n result.dtSupply = await this.unitsToAmount(result.datatoken, result.dtSupply)\n result.btSupply = await this.unitsToAmount(result.baseToken, result.btSupply)\n result.fixedRate = this.web3.utils.fromWei(result.fixedRate)\n result.exchangeId = exchangeId\n return result\n }\n\n /**\n * Get fee details for an exchange\n * @param {String} exchangeId ExchangeId\n * @return {Promise<FixedPricedExchange>} Exchange details\n */\n public async getFeesInfo(exchangeId: string): Promise<FeesInfo> {\n const result: FeesInfo = await this.contract.methods.getFeesInfo(exchangeId).call()\n result.opfFee = this.web3.utils.fromWei(result.opfFee.toString())\n result.marketFee = this.web3.utils.fromWei(result.marketFee.toString())\n\n result.marketFeeAvailable = await this.unitsToAmount(\n (\n await this.getExchange(exchangeId)\n ).baseToken,\n result.marketFeeAvailable\n )\n result.oceanFeeAvailable = await this.unitsToAmount(\n (\n await this.getExchange(exchangeId)\n ).baseToken,\n result.oceanFeeAvailable\n )\n\n result.exchangeId = exchangeId\n return result\n }\n\n /**\n * Get all exchanges\n * @param {String} exchangeId ExchangeId\n * @return {Promise<String[]>} Exchanges list\n */\n public async getExchanges(): Promise<string[]> {\n return await this.contract.methods.getExchanges().call()\n }\n\n /**\n * Check if an exchange is active\n * @param {String} exchangeId ExchangeId\n * @return {Promise<Boolean>} Result\n */\n public async isActive(exchangeId: string): Promise<boolean> {\n const result = await this.contract.methods.isActive(exchangeId).call()\n return result\n }\n\n /**\n * Estimate gas cost for activate\n * @param {String} account\n * @param {String} exchangeId ExchangeId\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estActivateMint(\n account: string,\n exchangeId: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await fixedRate.methods\n .toggleMintState(exchangeId, true)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Activate minting option for fixed rate contract\n * @param {String} exchangeId ExchangeId\n * @param {String} address User address\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async activateMint(\n address: string,\n exchangeId: string\n ): Promise<TransactionReceipt> {\n const exchange = await this.getExchange(exchangeId)\n if (!exchange) return null\n if (exchange.withMint === true) return null\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n\n const estGas = await this.estActivateMint(address, exchangeId)\n const trxReceipt = await this.contract.methods\n .toggleMintState(exchangeId, true)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for deactivate\n * @param {String} account\n * @param {String} exchangeId ExchangeId\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estDeactivateMint(\n account: string,\n exchangeId: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await fixedRate.methods\n .toggleMintState(exchangeId)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Deactivate minting for fixed rate\n * @param {String} exchangeId ExchangeId\n * @param {String} address User address\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async deactivateMint(\n address: string,\n exchangeId: string\n ): Promise<TransactionReceipt> {\n const exchange = await this.getExchange(exchangeId)\n if (!exchange) return null\n if (exchange.withMint === false) return null\n\n const estGas = await this.estDeactivate(address, exchangeId)\n\n const trxReceipt = await this.contract.methods\n .toggleMintState(exchangeId, false)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for collectBT\n * @param {String} account\n * @param {String} exchangeId ExchangeId\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estCollectBT(\n account: string,\n exchangeId: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await fixedRate.methods\n .collectBT(exchangeId)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Collect BaseTokens in the contract (only exchange owner)\n * @param {String} exchangeId ExchangeId\n * @param {String} address User address\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async collectBT(\n address: string,\n exchangeId: string\n ): Promise<TransactionReceipt> {\n const exchange = await this.getExchange(exchangeId)\n if (!exchange) return null\n\n const estGas = await this.estCollectBT(address, exchangeId)\n const trxReceipt = await this.contract.methods.collectBT(exchangeId).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for collecDT\n * @param {String} account\n * @param {String} exchangeId ExchangeId\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estCollectDT(\n account: string,\n exchangeId: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await fixedRate.methods\n .collectDT(exchangeId)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Collect datatokens in the contract (only exchange owner)\n * @param {String} exchangeId ExchangeId\n * @param {String} address User address\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async collectDT(\n address: string,\n exchangeId: string\n ): Promise<TransactionReceipt> {\n const exchange = await this.getExchange(exchangeId)\n if (!exchange) return null\n\n const estGas = await this.estCollectDT(address, exchangeId)\n const trxReceipt = await this.contract.methods.collectDT(exchangeId).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for collecMarketFee\n * @param {String} account\n * @param {String} exchangeId ExchangeId\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estCollectMarketFee(\n account: string,\n exchangeId: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await fixedRate.methods\n .collectMarketFee(exchangeId)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Collect market fee and send it to marketFeeCollector (anyone can call it)\n * @param {String} exchangeId ExchangeId\n * @param {String} address User address\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async collectMarketFee(\n address: string,\n exchangeId: string\n ): Promise<TransactionReceipt> {\n const exchange = await this.getExchange(exchangeId)\n if (!exchange) return null\n\n const estGas = await this.estCollectMarketFee(address, exchangeId)\n const trxReceipt = await this.contract.methods.collectMarketFee(exchangeId).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for collectOceanFee\n * @param {String} account\n * @param {String} exchangeId ExchangeId\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estCollectOceanFee(\n account: string,\n exchangeId: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await fixedRate.methods\n .collectMarketFee(exchangeId)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Collect ocean fee and send it to OPF collector (anyone can call it)\n * @param {String} exchangeId ExchangeId\n * @param {String} address User address\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async collectOceanFee(\n address: string,\n exchangeId: string\n ): Promise<TransactionReceipt> {\n const exchange = await this.getExchange(exchangeId)\n if (!exchange) return null\n\n const estGas = await this.estCollectOceanFee(address, exchangeId)\n const trxReceipt = await this.contract.methods.collectOceanFee(exchangeId).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n\n /**\n * Get OPF Collector of fixed rate contract\n * @return {String}\n */\n async getOPFCollector(): Promise<string> {\n let result = null\n try {\n result = await this.contract.methods.opfCollector().call()\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to get OPF Collector address: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get Router address set in fixed rate contract\n * @return {String}\n */\n async getRouter(): Promise<string> {\n let result = null\n try {\n result = await this.contract.methods.router().call()\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to get Router address: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get Exchange Owner given an exchangeId\n * @param {String} exchangeId ExchangeId\n * @return {String} return exchange owner\n */\n async getExchangeOwner(exchangeId: string): Promise<string> {\n let result = null\n try {\n result = await (await this.getExchange(exchangeId)).exchangeOwner\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to get OPF Collector address: ${e.message}`)\n }\n return result\n }\n\n /**\n * Estimate gas cost for updateMarketFee\n * @param {String} account\n * @param {String} exchangeId ExchangeId\n * @param {String} newMarketFee New market fee\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estUpdateMarketFee(\n account: string,\n exchangeId: string,\n newMarketFee: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await fixedRate.methods\n .updateMarketFee(exchangeId, newMarketFee)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Set new market fee, only market fee collector can update it\n * @param {String} address user address\n * @param {String} exchangeId ExchangeId\n * @param {String} newMarketFee New market fee\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async updateMarketFee(\n address: string,\n exchangeId: string,\n newMarketFee: string\n ): Promise<TransactionReceipt> {\n const estGas = await this.estSetRate(\n address,\n exchangeId,\n this.web3.utils.toWei(newMarketFee)\n )\n const trxReceipt = await this.contract.methods\n .updateMarketFee(exchangeId, this.web3.utils.toWei(newMarketFee))\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for updateMarketFeeCollector\n * @param {String} account\n * @param {String} exchangeId ExchangeId\n * @param {String} newMarketFee New market fee collector\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estUpdateMarketFeeCollector(\n account: string,\n exchangeId: string,\n newMarketFeeCollector: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await fixedRate.methods\n .updateMarketFeeCollector(exchangeId, newMarketFeeCollector)\n .estimateGas({ from: account }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Set new market fee collector, only market fee collector can update it\n * @param {String} address user address\n * @param {String} exchangeId ExchangeId\n * @param {String} newMarketFeeCollector New market fee collector\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async updateMarketFeeCollector(\n address: string,\n exchangeId: string,\n newMarketFeeCollector: string\n ): Promise<TransactionReceipt> {\n const estGas = await this.estUpdateMarketFeeCollector(\n address,\n exchangeId,\n newMarketFeeCollector\n )\n const trxReceipt = await this.contract.methods\n .updateMarketFeeCollector(exchangeId, newMarketFeeCollector)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n}\n","import Web3 from 'web3'\nimport { AbiItem } from 'web3-utils'\nimport { TransactionReceipt } from 'web3-eth'\nimport defaultNftAbi from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC721Template.sol/ERC721Template.json'\nimport {\n LoggerInstance,\n getFairGasPrice,\n generateDtName,\n setContractDefaults,\n configHelperNetworks\n} from '../utils'\nimport { Contract } from 'web3-eth-contract'\nimport { MetadataProof } from '../../src/@types'\nimport { Config } from '../models/index.js'\nimport { MetadataAndTokenURI } from '../interfaces/Erc721Interface'\n\n/**\n * ERC721 ROLES\n */\ninterface Roles {\n manager: boolean\n deployERC20: boolean\n updateMetadata: boolean\n store: boolean\n}\n\nexport class Nft {\n public GASLIMIT_DEFAULT = 1000000\n public factory721Address: string\n public factory721Abi: AbiItem | AbiItem[]\n public nftAbi: AbiItem | AbiItem[]\n public web3: Web3\n public startBlock: number\n public config: Config\n\n constructor(web3: Web3, nftAbi?: AbiItem | AbiItem[], config?: Config) {\n this.nftAbi = nftAbi || (defaultNftAbi.abi as AbiItem[])\n this.web3 = web3\n this.config = config || configHelperNetworks[0]\n }\n\n /**\n * Estimate gas cost for createERC20 token creation\n * @param {String} nftAddress ERC721 addreess\n * @param {String} address User address\n * @param {String} minter User set as initial minter for the ERC20\n * @param {String} feeManager initial feeManager for this DT\n * @param {String} mpFeeAddress Consume marketplace fee address\n * @param {String} feeToken address of the token marketplace wants to add fee on top\n * @param {String} feeAmount amount of feeToken to be transferred to mpFeeAddress on top, will be converted to WEI\n * @param {String} cap Maximum cap (Number) - will be converted to wei\n * @param {String} name Token name\n * @param {String} symbol Token symbol\n * @param {Number} templateIndex NFT template index\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasCreateErc20(\n nftAddress: string,\n address: string,\n minter: string,\n feeManager: string,\n mpFeeAddress: string,\n feeToken: string,\n feeAmount: string,\n cap: string,\n name?: string,\n symbol?: string,\n templateIndex?: number,\n contractInstance?: Contract\n ): Promise<any> {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .createERC20(\n templateIndex,\n [name, symbol],\n [minter, feeManager, mpFeeAddress, feeToken],\n [this.web3.utils.toWei(cap), this.web3.utils.toWei(feeAmount)],\n []\n )\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Create new ERC20 datatoken - only user with ERC20Deployer permission can succeed\n * @param {String} nftAddress ERC721 addreess\n * @param {String} address User address\n * @param {String} minter User set as initial minter for the ERC20\n * @param {String} feeManager initial feeManager for this DT\n * @param {String} mpFeeAddress Consume marketplace fee address\n * @param {String} feeToken address of the token marketplace wants to add fee on top\n * @param {String} feeAmount amount of feeToken to be transferred to mpFeeAddress on top, will be converted to WEI\n * @param {String} cap Maximum cap (Number) - will be converted to wei\n * @param {String} name Token name\n * @param {String} symbol Token symbol\n * @param {Number} templateIndex NFT template index\n * @return {Promise<string>} ERC20 datatoken address\n */\n public async createErc20(\n nftAddress: string,\n address: string,\n minter: string,\n feeManager: string,\n mpFeeAddress: string,\n feeToken: string,\n feeAmount: string,\n cap: string,\n name?: string,\n symbol?: string,\n templateIndex?: number\n ): Promise<string> {\n if ((await this.getNftPermissions(nftAddress, address)).deployERC20 !== true) {\n throw new Error(`Caller is not ERC20Deployer`)\n }\n if (!templateIndex) templateIndex = 1\n\n // Generate name & symbol if not present\n if (!name || !symbol) {\n ;({ name, symbol } = generateDtName())\n }\n\n // Create 721contract object\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const estGas = await this.estGasCreateErc20(\n nftAddress,\n address,\n minter,\n feeManager,\n mpFeeAddress,\n feeToken,\n feeAmount,\n cap,\n name,\n symbol,\n templateIndex,\n nftContract\n )\n\n // Call createERC20 token function of the contract\n const trxReceipt = await nftContract.methods\n .createERC20(\n templateIndex,\n [name, symbol],\n [minter, feeManager, mpFeeAddress, feeToken],\n [this.web3.utils.toWei(cap), this.web3.utils.toWei(feeAmount)],\n []\n )\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n let tokenAddress = null\n try {\n tokenAddress = trxReceipt.events.TokenCreated.returnValues[0]\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to create datatoken : ${e.message}`)\n }\n return tokenAddress\n }\n\n /**\n * Estimate gas cost for add manager call\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Owner adress\n * @param {String} manager User adress which is going to be assing manager\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasAddManager(\n nftAddress: string,\n address: string,\n manager: string,\n contractInstance?: Contract\n ) {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .addManager(manager)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Add Manager for NFT Contract (only NFT Owner can succeed)\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Owner adress\n * @param {String} manager User adress which is going to be assing manager\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async addManager(nftAddress: string, address: string, manager: string) {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n if ((await this.getNftOwner(nftAddress)) !== address) {\n throw new Error(`Caller is not NFT Owner`)\n }\n\n const estGas = await this.estGasAddManager(nftAddress, address, manager, nftContract)\n\n // Invoke addManager function of the contract\n const trxReceipt = await nftContract.methods.addManager(manager).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for removeManager method\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Owner adress\n * @param {String} manager User adress which is going to be removed as manager\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasRemoveManager(\n nftAddress: string,\n address: string,\n manager: string,\n contractInstance?: Contract\n ) {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .removeManager(manager)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Removes a specific manager for NFT Contract (only NFT Owner can succeed)\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Owner adress\n * @param {String} manager User adress which is going to be removed as manager\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async removeManager(nftAddress: string, address: string, manager: string) {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n if ((await this.getNftOwner(nftAddress)) !== address) {\n throw new Error(`Caller is not NFT Owner`)\n }\n\n const estGas = await this.estGasRemoveManager(\n nftAddress,\n address,\n manager,\n nftContract\n )\n\n // Invoke removeManager function of the contract\n const trxReceipt = await nftContract.methods.removeManager(manager).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for addToCreateERC20List method\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Manager adress\n * @param {String} erc20Deployer User adress which is going to have erc20Deployer permission\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasAddErc20Deployer(\n nftAddress: string,\n address: string,\n erc20Deployer: string,\n contractInstance?: Contract\n ): Promise<any> {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .addToCreateERC20List(erc20Deployer)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * Add ERC20Deployer permission - only Manager can succeed\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Manager adress\n * @param {String} erc20Deployer User adress which is going to have erc20Deployer permission\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async addErc20Deployer(\n nftAddress: string,\n address: string,\n erc20Deployer: string\n ): Promise<TransactionReceipt> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n if ((await this.getNftPermissions(nftAddress, address)).manager !== true) {\n throw new Error(`Caller is not Manager`)\n }\n\n // Estimate gas for addToCreateERC20List method\n const estGas = await this.estGasAddErc20Deployer(\n nftAddress,\n address,\n erc20Deployer,\n nftContract\n )\n\n // Invoke addToCreateERC20List function of the contract\n const trxReceipt = await nftContract.methods\n .addToCreateERC20List(erc20Deployer)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for removeFromCreateERC20List method\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Manager adress\n * @param {String} erc20Deployer Address of the user to be revoked ERC20Deployer Permission\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasRemoveErc20Deployer(\n nftAddress: string,\n address: string,\n erc20Deployer: string,\n contractInstance?: Contract\n ): Promise<any> {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .removeFromCreateErc20List(erc20Deployer)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * Remove ERC20Deployer permission - only Manager can succeed\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Manager adress\n * @param {String} erc20Deployer Address of the user to be revoked ERC20Deployer Permission\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async removeErc20Deployer(\n nftAddress: string,\n address: string,\n erc20Deployer: string\n ): Promise<TransactionReceipt> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n if (\n (await this.getNftPermissions(nftAddress, address)).manager !== true ||\n (address === erc20Deployer &&\n (await this.getNftPermissions(nftAddress, address)).deployERC20 !== true)\n ) {\n throw new Error(`Caller is not Manager nor ERC20Deployer`)\n }\n const estGas = await this.estGasRemoveErc20Deployer(\n nftAddress,\n address,\n erc20Deployer,\n nftContract\n )\n\n // Call removeFromCreateERC20List function of the contract\n const trxReceipt = await nftContract.methods\n .removeFromCreateERC20List(erc20Deployer)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for addToMetadataList method\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Manager adress\n * @param {String} metadataUpdater User adress which is going to have Metadata Updater permission\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasAddMetadataUpdater(\n nftAddress: string,\n address: string,\n metadataUpdater: string,\n contractInstance?: Contract\n ): Promise<any> {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .addToMetadataList(metadataUpdater)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Add Metadata Updater permission - only Manager can succeed\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Manager adress\n * @param {String} metadataUpdater User adress which is going to have Metadata Updater permission\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async addMetadataUpdater(\n nftAddress: string,\n address: string,\n metadataUpdater: string\n ): Promise<TransactionReceipt> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n if ((await this.getNftPermissions(nftAddress, address)).manager !== true) {\n throw new Error(`Caller is not Manager`)\n }\n\n const estGas = await this.estGasAddMetadataUpdater(\n nftAddress,\n address,\n metadataUpdater,\n nftContract\n )\n\n // Call addToMetadataList function of the contract\n const trxReceipt = await nftContract.methods.addToMetadataList(metadataUpdater).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for removeFromMetadataList method\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Manager adress\n * @param {String} metadataUpdater Address of the user to be revoked Metadata updater Permission\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async esGasRemoveMetadataUpdater(\n nftAddress: string,\n address: string,\n metadataUpdater: string,\n contractInstance?: Contract\n ): Promise<any> {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .removeFromMetadataList(metadataUpdater)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * Remove Metadata Updater permission - only Manager can succeed\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Manager adress\n * @param {String} metadataUpdater Address of the user to be revoked Metadata updater Permission\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async removeMetadataUpdater(\n nftAddress: string,\n address: string,\n metadataUpdater: string\n ): Promise<TransactionReceipt> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n if (\n (await this.getNftPermissions(nftAddress, address)).manager !== true ||\n (address !== metadataUpdater &&\n (await this.getNftPermissions(nftAddress, address)).updateMetadata !== true)\n ) {\n throw new Error(`Caller is not Manager nor Metadata Updater`)\n }\n\n const estGas = await this.esGasRemoveMetadataUpdater(\n nftAddress,\n address,\n metadataUpdater,\n nftContract\n )\n\n // Call removeFromMetadataList function of the contract\n const trxReceipt = await nftContract.methods\n .removeFromMetadataList(metadataUpdater)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for addTo725StoreList method\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Manager adress\n * @param {String} storeUpdater User adress which is going to have Store Updater permission\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasAddStoreUpdater(\n nftAddress: string,\n address: string,\n storeUpdater: string,\n contractInstance?: Contract\n ): Promise<any> {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .addTo725StoreList(storeUpdater)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Add Store Updater permission - only Manager can succeed\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Manager adress\n * @param {String} storeUpdater User adress which is going to have Store Updater permission\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async addStoreUpdater(\n nftAddress: string,\n address: string,\n storeUpdater: string\n ): Promise<TransactionReceipt> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n if ((await this.getNftPermissions(nftAddress, address)).manager !== true) {\n throw new Error(`Caller is not Manager`)\n }\n\n const estGas = await this.estGasAddStoreUpdater(\n nftAddress,\n address,\n storeUpdater,\n nftContract\n )\n\n // Call addTo725StoreList function of the contract\n const trxReceipt = await nftContract.methods.addTo725StoreList(storeUpdater).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for removeFrom725StoreList method\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Manager adress\n * @param {String} storeUpdater Address of the user to be revoked Store Updater Permission\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasRemoveStoreUpdater(\n nftAddress: string,\n address: string,\n storeUpdater: string,\n contractInstance?: Contract\n ): Promise<any> {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .removeFrom725StoreList(storeUpdater)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Remove Store Updater permission - only Manager can succeed\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Manager adress\n * @param {String} storeUpdater Address of the user to be revoked Store Updater Permission\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async removeStoreUpdater(\n nftAddress: string,\n address: string,\n storeUpdater: string\n ): Promise<TransactionReceipt> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n if (\n (await this.getNftPermissions(nftAddress, address)).manager !== true ||\n (address !== storeUpdater &&\n (await this.getNftPermissions(nftAddress, address)).store !== true)\n ) {\n throw new Error(`Caller is not Manager nor storeUpdater`)\n }\n\n const estGas = await this.estGasRemoveStoreUpdater(\n nftAddress,\n address,\n storeUpdater,\n nftContract\n )\n\n // Call removeFrom725StoreList function of the contract\n const trxReceipt = await nftContract.methods\n .removeFrom725StoreList(storeUpdater)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for cleanPermissions method\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Owner adress\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasCleanPermissions(\n nftAddress: string,\n address: string,\n contractInstance?: Contract\n ): Promise<any> {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .cleanPermissions()\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * This function allows to remove all ROLES at erc721 level: Managers, ERC20Deployer, MetadataUpdater, StoreUpdater\n * Even NFT Owner has to readd himself as Manager\n * Permissions at erc20 level stay.\n * Only NFT Owner can call it.\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address NFT Owner adress\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n\n public async cleanPermissions(\n nftAddress: string,\n address: string\n ): Promise<TransactionReceipt> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n if ((await this.getNftOwner(nftAddress)) !== address) {\n throw new Error(`Caller is not NFT Owner`)\n }\n\n const estGas = await this.estGasCleanPermissions(nftAddress, address, nftContract)\n\n // Call cleanPermissions function of the contract\n const trxReceipt = await nftContract.methods.cleanPermissions().send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for transfer NFT method\n * @param {String} nftAddress erc721 contract adress\n * @param {String} nftOwner Current NFT Owner adress\n * @param {String} nftReceiver User which will receive the NFT, will also be set as Manager\n * @param {Number} tokenId The id of the token to be transfered\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasTransferNft(\n nftAddress: string,\n nftOwner: string,\n nftReceiver: string,\n tokenId: number,\n contractInstance?: Contract\n ): Promise<any> {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .transferFrom(nftOwner, nftReceiver, tokenId)\n .estimateGas({ from: nftOwner }, (err, estGas) =>\n err ? gasLimitDefault : estGas\n )\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * Transfers the NFT\n * will clean all permissions both on erc721 and erc20 level.\n * @param {String} nftAddress erc721 contract adress\n * @param {String} nftOwner Current NFT Owner adress\n * @param {String} nftReceiver User which will receive the NFT, will also be set as Manager\n * @param {Number} tokenId The id of the token to be transfered\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async transferNft(\n nftAddress: string,\n nftOwner: string,\n nftReceiver: string,\n tokenId?: number\n ): Promise<TransactionReceipt> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n if ((await this.getNftOwner(nftAddress)) !== nftOwner) {\n throw new Error(`Caller is not NFT Owner`)\n }\n\n const tokenIdentifier = tokenId || 1\n\n const estGas = await this.estGasTransferNft(\n nftAddress,\n nftOwner,\n nftReceiver,\n tokenIdentifier,\n nftContract\n )\n\n // Call transferFrom function of the contract\n const trxReceipt = await nftContract.methods\n .transferFrom(nftOwner, nftReceiver, tokenIdentifier)\n .send({\n from: nftOwner,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for safeTransfer NFT method\n * @param {String} nftAddress erc721 contract adress\n * @param {String} nftOwner Current NFT Owner adress\n * @param {String} nftReceiver User which will receive the NFT, will also be set as Manager\n * @param {Number} tokenId The id of the token to be transfered\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasSafeTransferNft(\n nftAddress: string,\n nftOwner: string,\n nftReceiver: string,\n tokenId: number,\n contractInstance?: Contract\n ): Promise<any> {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .safeTransferFrom(nftOwner, nftReceiver, tokenId)\n .estimateGas({ from: nftOwner }, (err, estGas) =>\n err ? gasLimitDefault : estGas\n )\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * safeTransferNFT Used for transferring the NFT, can be used by an approved relayer\n * will clean all permissions both on erc721 and erc20 level.\n * @param {String} nftAddress erc721 contract adress\n * @param {String} nftOwner Current NFT Owner adress\n * @param {String} nftReceiver User which will receive the NFT, will also be set as Manager\n * @param {Number} tokenId The id of the token to be transfered\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async safeTransferNft(\n nftAddress: string,\n nftOwner: string,\n nftReceiver: string,\n tokenId?: number\n ): Promise<TransactionReceipt> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n if ((await this.getNftOwner(nftAddress)) !== nftOwner) {\n throw new Error(`Caller is not NFT Owner`)\n }\n\n const tokenIdentifier = tokenId || 1\n\n const estGas = await this.estGasSafeTransferNft(\n nftAddress,\n nftOwner,\n nftReceiver,\n tokenIdentifier,\n nftContract\n )\n\n // Call transferFrom function of the contract\n const trxReceipt = await nftContract.methods\n .safeTransferFrom(nftOwner, nftReceiver, tokenIdentifier)\n .send({\n from: nftOwner,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n // TODO: Finish this description\n /**\n * Estimate gas cost for setMetadata method\n * @param {String} nftAddress erc721 contract adress\n * @param {String} metadataUpdater metadataUpdater address\n * @param {Number} metadataState User which will receive the NFT, will also be set as Manager\n * @param {String} metadataDecryptorUrl\n * @param {Number} tokenId The id of the token to be transfered\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasSetMetadata(\n nftAddress: string,\n metadataUpdater: string,\n metadataState: number,\n metadataDecryptorUrl: string,\n metadataDecryptorAddress: string,\n flags: string,\n data: string,\n metadataHash: string,\n metadataProofs?: MetadataProof[],\n contractInstance?: Contract\n ): Promise<any> {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .setMetaData(\n metadataState,\n metadataDecryptorUrl,\n metadataDecryptorAddress,\n flags,\n data,\n metadataHash,\n metadataProofs\n )\n .estimateGas({ from: metadataUpdater }, (err, estGas) =>\n err ? gasLimitDefault : estGas\n )\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * safeTransferNFT Used for transferring the NFT, can be used by an approved relayer\n * will clean all permissions both on erc721 and erc20 level.\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address Caller address NFT Owner adress\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async setMetadata(\n nftAddress: string,\n address: string,\n metadataState: number,\n metadataDecryptorUrl: string,\n metadataDecryptorAddress: string,\n flags: string,\n data: string,\n metadataHash: string,\n metadataProofs?: MetadataProof[]\n ): Promise<TransactionReceipt> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n if (!metadataProofs) metadataProofs = []\n if (!(await this.getNftPermissions(nftAddress, address)).updateMetadata) {\n throw new Error(`Caller is not Metadata updater`)\n }\n const estGas = await this.estGasSetMetadata(\n nftAddress,\n address,\n metadataState,\n metadataDecryptorUrl,\n metadataDecryptorAddress,\n flags,\n data,\n metadataHash,\n metadataProofs,\n nftContract\n )\n const trxReceipt = await nftContract.methods\n .setMetaData(\n metadataState,\n metadataDecryptorUrl,\n metadataDecryptorAddress,\n flags,\n data,\n metadataHash,\n metadataProofs\n )\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for setMetadata method\n * @param {String} nftAddress erc721 contract adress\n * @param {String} metadataUpdater metadataUpdater address\n * @param {MetaDataAndTokenURI} metadataAndTokenURI metaDataAndTokenURI object\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasSetMetadataAndTokenURI(\n nftAddress: string,\n metadataUpdater: string,\n metadataAndTokenURI: MetadataAndTokenURI,\n contractInstance?: Contract\n ): Promise<any> {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .setMetaDataAndTokenURI(metadataAndTokenURI)\n .estimateGas({ from: metadataUpdater }, (err, estGas) =>\n err ? gasLimitDefault : estGas\n )\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * Helper function to improve UX sets both MetaData & TokenURI in one tx\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address Caller address\n * @param {MetadataAndTokenURI} metadataAndTokenURI metaDataAndTokenURI object\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async setMetadataAndTokenURI(\n nftAddress: string,\n metadataUpdater: string,\n metadataAndTokenURI: MetadataAndTokenURI\n ): Promise<TransactionReceipt> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n if (!(await this.getNftPermissions(nftAddress, metadataUpdater)).updateMetadata) {\n throw new Error(`Caller is not Metadata updater`)\n }\n const estGas = await this.estGasSetMetadataAndTokenURI(\n nftAddress,\n metadataUpdater,\n metadataAndTokenURI,\n nftContract\n )\n const trxReceipt = await nftContract.methods\n .setMetaDataAndTokenURI(metadataAndTokenURI)\n .send({\n from: metadataUpdater,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for setMetadataState method\n * @param {String} nftAddress erc721 contract adress\n * @param {String} nftOwner Current NFT Owner adress\n * @param {Number} metadataState new metadata state\n * @param {Contract} nftContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasSetMetadataState(\n nftAddress: string,\n metadataUpdater: string,\n metadataState: number,\n contractInstance?: Contract\n ): Promise<any> {\n const nftContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .setMetaDataState(metadataState)\n .estimateGas({ from: metadataUpdater }, (err, estGas) =>\n err ? gasLimitDefault : estGas\n )\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * setMetadataState Used for updating the metadata State\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address Caller address => metadata updater\n * @param {Number} metadataState new metadata state\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async setMetadataState(\n nftAddress: string,\n address: string,\n metadataState: number\n ): Promise<TransactionReceipt> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n if (!(await this.getNftPermissions(nftAddress, address)).updateMetadata) {\n throw new Error(`Caller is not Metadata updater`)\n }\n\n const estGas = await this.estGasSetMetadataState(nftAddress, address, metadataState)\n\n // Call transferFrom function of the contract\n const trxReceipt = await nftContract.methods.setMetaDataState(metadataState).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /** Estimate gas cost for setTokenURI method\n * @param nftAddress erc721 contract adress\n * @param address user adress\n * @param data input data for TokenURI\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async estSetTokenURI(\n nftAddress: string,\n address: string,\n data: string\n ): Promise<any> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await nftContract.methods\n .setTokenURI('1', data)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /** set TokenURI on an nft\n * @param nftAddress erc721 contract adress\n * @param address user adress\n * @param data input data for TokenURI\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async setTokenURI(\n nftAddress: string,\n address: string,\n data: string\n ): Promise<any> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const estGas = await this.estSetTokenURI(nftAddress, address, data)\n const trxReceipt = await nftContract.methods.setTokenURI('1', data).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n\n /** Get Owner\n * @param {String} nftAddress erc721 contract adress\n * @return {Promise<string>} string\n */\n public async getNftOwner(nftAddress: string): Promise<string> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n const trxReceipt = await nftContract.methods.ownerOf(1).call()\n return trxReceipt\n }\n\n /** Get users NFT Permissions\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address user adress\n * @return {Promise<Roles>}\n */\n public async getNftPermissions(nftAddress: string, address: string): Promise<Roles> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n const roles = await nftContract.methods.getPermissions(address).call()\n return roles\n }\n\n /** Get users Metadata, return Metadata details\n * @param {String} nftAddress erc721 contract adress\n * @return {Promise<Objecta>}\n */\n public async getMetadata(nftAddress: string): Promise<Object> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n return await nftContract.methods.getMetaData().call()\n }\n\n /** Get users ERC20Deployer role\n * @param {String} nftAddress erc721 contract adress\n * @param {String} address user adress\n * @return {Promise<Roles>}\n */\n public async isErc20Deployer(nftAddress: string, address: string): Promise<boolean> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n const isERC20Deployer = await nftContract.methods.isERC20Deployer(address).call()\n return isERC20Deployer\n }\n\n /** Gets data at a given `key`\n * @param {String} nftAddress erc721 contract adress\n * @param {String} key the key which value to retrieve\n * @return {Promise<string>} The data stored at the key\n */\n public async getData(nftAddress: string, key: string): Promise<string> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n const data = await nftContract.methods.getData(key).call()\n return data\n }\n\n /** Gets data at a given `key`\n * @param {String} nftAddress erc721 contract adress\n * @param {String} id\n * @return {Promise<string>} The data stored at the key\n */\n public async getTokenURI(nftAddress: string, id: number): Promise<string> {\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n const data = await nftContract.methods.tokenURI(id).call()\n return data\n }\n}\n","import Web3 from 'web3'\nimport { AbiItem } from 'web3-utils'\nimport { TransactionReceipt } from 'web3-eth'\nimport { Contract } from 'web3-eth-contract'\nimport Decimal from 'decimal.js'\nimport defaultDatatokensAbi from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json'\nimport defaultDatatokensEnterpriseAbi from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20TemplateEnterprise.sol/ERC20TemplateEnterprise.json'\nimport {\n LoggerInstance,\n getFairGasPrice,\n setContractDefaults,\n configHelperNetworks\n} from '../utils'\nimport { FreOrderParams, FreCreationParams } from '../interfaces'\nimport { Nft } from './NFT'\nimport { Config } from '../models/index.js'\nimport { ProviderFees } from '../@types/Provider.js'\n/**\n * ERC20 ROLES\n */\ninterface Roles {\n minter: boolean\n paymentManager: boolean\n}\n\nexport interface OrderParams {\n consumer: string\n serviceIndex: number\n _providerFees: ProviderFees\n}\n\nexport interface DispenserParams {\n maxTokens: string\n maxBalance: string\n withMint?: boolean // true if we want to allow the dispenser to be a minter\n allowedSwapper?: string // only account that can ask tokens. set address(0) if not required\n}\n\nexport class Datatoken {\n public GASLIMIT_DEFAULT = 1000000\n public factoryAddress: string\n public factoryABI: AbiItem | AbiItem[]\n public datatokensAbi: AbiItem | AbiItem[]\n public datatokensEnterpriseAbi: AbiItem | AbiItem[]\n public web3: Web3\n public config: Config\n public nft: Nft\n\n /**\n * Instantiate ERC20 Datatokens\n * @param {AbiItem | AbiItem[]} datatokensAbi\n * @param {Web3} web3\n */\n constructor(\n web3: Web3,\n datatokensAbi?: AbiItem | AbiItem[],\n datatokensEnterpriseAbi?: AbiItem | AbiItem[],\n config?: Config\n ) {\n this.web3 = web3\n this.datatokensAbi = datatokensAbi || (defaultDatatokensAbi.abi as AbiItem[])\n this.datatokensEnterpriseAbi =\n datatokensEnterpriseAbi || (defaultDatatokensEnterpriseAbi.abi as AbiItem[])\n this.config = config || configHelperNetworks[0]\n this.nft = new Nft(this.web3)\n }\n\n /**\n * Estimate gas cost for mint method\n * @param {String} dtAddress Datatoken address\n * @param {String} spender Spender address\n * @param {string} amount Number of datatokens, as number. Will be converted to wei\n * @param {String} address User adress\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasApprove(\n dtAddress: string,\n spender: string,\n amount: string,\n address: string,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n // Estimate gas cost for mint method\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await dtContract.methods\n .approve(spender, this.web3.utils.toWei(amount))\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Approve\n * @param {String} dtAddress Datatoken address\n * @param {String} spender Spender address\n * @param {string} amount Number of datatokens, as number. Will be converted to wei\n * @param {String} address User adress\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async approve(\n dtAddress: string,\n spender: string,\n amount: string,\n address: string\n ): Promise<TransactionReceipt> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n const estGas = await this.estGasApprove(\n dtAddress,\n spender,\n amount,\n address,\n dtContract\n )\n\n // Call mint contract method\n const trxReceipt = await dtContract.methods\n .approve(spender, this.web3.utils.toWei(amount))\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for mint method\n * @param {String} dtAddress Datatoken address\n * @param {String} address Minter address\n * @param {String} amount Number of datatokens, as number. Will be converted to wei\n * @param {String} toAddress only if toAddress is different from the minter\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasMint(\n dtAddress: string,\n address: string,\n amount: string,\n toAddress?: string,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await dtContract.methods\n .mint(toAddress || address, this.web3.utils.toWei(amount))\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * Estimate gas cost for createFixedRate method\n * @param {String} dtAddress Datatoken address\n * @param {String} address Caller address\n * @param {String} fixedPriceAddress\n * @param {FixedRateParams} fixedRateParams\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasCreateFixedRate(\n dtAddress: string,\n address: string,\n fixedRateParams: FreCreationParams,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n\n if (!fixedRateParams.allowedConsumer)\n fixedRateParams.allowedConsumer = '0x0000000000000000000000000000000000000000'\n const withMint = fixedRateParams.withMint ? 1 : 0\n\n let estGas\n try {\n estGas = await dtContract.methods\n .createFixedRate(\n fixedRateParams.fixedRateAddress,\n [\n fixedRateParams.baseTokenAddress,\n address,\n fixedRateParams.marketFeeCollector,\n fixedRateParams.allowedConsumer\n ],\n [\n fixedRateParams.baseTokenDecimals,\n fixedRateParams.datatokenDecimals,\n fixedRateParams.fixedRate,\n fixedRateParams.marketFee,\n withMint\n ]\n )\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * Creates a new FixedRateExchange setup.\n * @param {String} dtAddress Datatoken address\n * @param {String} address Caller address\n * @param {String} fixedPriceAddress\n * @param {FixedRateParams} fixedRateParams\n * @return {Promise<TransactionReceipt>} transactionId\n */\n public async createFixedRate(\n dtAddress: string,\n address: string,\n fixedRateParams: FreCreationParams\n ): Promise<TransactionReceipt> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n if (!(await this.isERC20Deployer(dtAddress, address))) {\n throw new Error(`User is not ERC20 Deployer`)\n }\n if (!fixedRateParams.allowedConsumer)\n fixedRateParams.allowedConsumer = '0x0000000000000000000000000000000000000000'\n\n const withMint = fixedRateParams.withMint ? 1 : 0\n\n // should check ERC20Deployer role using erc721 level ..\n\n const estGas = await this.estGasCreateFixedRate(\n dtAddress,\n address,\n fixedRateParams,\n dtContract\n )\n\n // Call createFixedRate contract method\n const trxReceipt = await dtContract.methods\n .createFixedRate(\n fixedRateParams.fixedRateAddress,\n [\n fixedRateParams.baseTokenAddress,\n fixedRateParams.owner,\n fixedRateParams.marketFeeCollector,\n fixedRateParams.allowedConsumer\n ],\n [\n fixedRateParams.baseTokenDecimals,\n fixedRateParams.datatokenDecimals,\n fixedRateParams.fixedRate,\n fixedRateParams.marketFee,\n withMint\n ]\n )\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for createDispenser method\n * @param {String} dtAddress Datatoken address\n * @param {String} address Caller address\n * @param {String} dispenserAddress ispenser contract address\n * @param {String} dispenserParams\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasCreateDispenser(\n dtAddress: string,\n address: string,\n dispenserAddress: string,\n dispenserParams: DispenserParams,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n if (!dispenserParams.allowedSwapper)\n dispenserParams.allowedSwapper = '0x0000000000000000000000000000000000000000'\n\n if (!dispenserParams.withMint) dispenserParams.withMint = false\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await dtContract.methods\n .createDispenser(\n dispenserAddress,\n dispenserParams.maxTokens,\n dispenserParams.maxBalance,\n dispenserParams.withMint,\n dispenserParams.allowedSwapper\n )\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * Creates a new Dispenser\n * @param {String} dtAddress Datatoken address\n * @param {String} address Caller address\n * @param {String} dispenserAddress ispenser contract address\n * @param {String} dispenserParams\n * @return {Promise<TransactionReceipt>} transactionId\n */\n public async createDispenser(\n dtAddress: string,\n address: string,\n dispenserAddress: string,\n dispenserParams: DispenserParams\n ): Promise<TransactionReceipt> {\n if (!(await this.isERC20Deployer(dtAddress, address))) {\n throw new Error(`User is not ERC20 Deployer`)\n }\n\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n if (!dispenserParams.allowedSwapper)\n dispenserParams.allowedSwapper = '0x0000000000000000000000000000000000000000'\n\n if (!dispenserParams.withMint) dispenserParams.withMint = false\n\n // should check ERC20Deployer role using erc721 level ..\n\n const estGas = await this.estGasCreateDispenser(\n dtAddress,\n address,\n dispenserAddress,\n dispenserParams,\n dtContract\n )\n\n // Call createFixedRate contract method\n const trxReceipt = await dtContract.methods\n .createDispenser(\n dispenserAddress,\n dispenserParams.maxTokens,\n dispenserParams.maxBalance,\n dispenserParams.withMint,\n dispenserParams.allowedSwapper\n )\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n }\n\n /**\n * Mint\n * @param {String} dtAddress Datatoken address\n * @param {String} address Minter address\n * @param {String} amount Number of datatokens, as number. Will be converted to wei\n * @param {String} toAddress only if toAddress is different from the minter\n * @return {Promise<TransactionReceipt>} transactionId\n */\n public async mint(\n dtAddress: string,\n address: string,\n amount: string,\n toAddress?: string\n ): Promise<TransactionReceipt> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n if ((await this.getDTPermissions(dtAddress, address)).minter !== true) {\n throw new Error(`Caller is not Minter`)\n }\n\n const capAvailble = await this.getCap(dtAddress)\n if (new Decimal(capAvailble).gte(amount)) {\n const estGas = await this.estGasMint(\n dtAddress,\n address,\n amount,\n toAddress,\n dtContract\n )\n\n // Call mint contract method\n const trxReceipt = await dtContract.methods\n .mint(toAddress || address, this.web3.utils.toWei(amount))\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n } else {\n throw new Error(`Mint amount exceeds cap available`)\n }\n }\n\n /**\n * Estimate gas cost for addMinter method\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address\n * @param {String} minter User which is going to be a Minter\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasAddMinter(\n dtAddress: string,\n address: string,\n minter: string,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n // Estimate gas cost for addMinter method\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await dtContract.methods\n .addMinter(minter)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Add Minter for an ERC20 datatoken\n * only ERC20Deployer can succeed\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address\n * @param {String} minter User which is going to be a Minter\n * @return {Promise<TransactionReceipt>} transactionId\n */\n public async addMinter(\n dtAddress: string,\n address: string,\n minter: string\n ): Promise<TransactionReceipt> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n if ((await this.isERC20Deployer(dtAddress, address)) !== true) {\n throw new Error(`Caller is not ERC20Deployer`)\n }\n // Estimate gas cost for addMinter method\n const estGas = await this.estGasAddMinter(dtAddress, address, minter, dtContract)\n\n // Call addMinter function of the contract\n const trxReceipt = await dtContract.methods.addMinter(minter).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas for removeMinter method\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address\n * @param {String} minter User which will be removed from Minter permission\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasRemoveMinter(\n dtAddress: string,\n address: string,\n minter: string,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n // should check ERC20Deployer role using erc721 level ..\n\n // Estimate gas for removeMinter method\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await dtContract.methods\n .removeMinter(minter)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * Revoke Minter permission for an ERC20 datatoken\n * only ERC20Deployer can succeed\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address\n * @param {String} minter User which will be removed from Minter permission\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async removeMinter(\n dtAddress: string,\n address: string,\n minter: string\n ): Promise<TransactionReceipt> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n if ((await this.isERC20Deployer(dtAddress, address)) !== true) {\n throw new Error(`Caller is not ERC20Deployer`)\n }\n\n const estGas = await this.estGasRemoveMinter(dtAddress, address, minter, dtContract)\n\n // Call dtContract function of the contract\n const trxReceipt = await dtContract.methods.removeMinter(minter).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas for addPaymentManager method\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address\n * @param {String} paymentManager User which is going to be a Minter\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasAddPaymentManager(\n dtAddress: string,\n address: string,\n paymentManager: string,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n // Estimate gas for addFeeManager method\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await dtContract.methods\n .addPaymentManager(paymentManager)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * Add addPaymentManager (can set who's going to collect fee when consuming orders)\n * only ERC20Deployer can succeed\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address\n * @param {String} paymentManager User which is going to be a Minter\n * @return {Promise<TransactionReceipt>} transactionId\n */\n public async addPaymentManager(\n dtAddress: string,\n address: string,\n paymentManager: string\n ): Promise<TransactionReceipt> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n if ((await this.isERC20Deployer(dtAddress, address)) !== true) {\n throw new Error(`Caller is not ERC20Deployer`)\n }\n\n const estGas = await this.estGasAddPaymentManager(\n dtAddress,\n address,\n paymentManager,\n dtContract\n )\n\n // Call addPaymentManager function of the contract\n const trxReceipt = await dtContract.methods.addPaymentManager(paymentManager).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas for removePaymentManager method\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address\n * @param {String} paymentManager User which will be removed from paymentManager permission\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasRemovePaymentManager(\n dtAddress: string,\n address: string,\n paymentManager: string,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await dtContract.methods\n .removePaymentManager(paymentManager)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Revoke paymentManager permission for an ERC20 datatoken\n * only ERC20Deployer can succeed\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address\n * @param {String} paymentManager User which will be removed from paymentManager permission\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async removePaymentManager(\n dtAddress: string,\n address: string,\n paymentManager: string\n ): Promise<TransactionReceipt> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n if ((await this.isERC20Deployer(dtAddress, address)) !== true) {\n throw new Error(`Caller is not ERC20Deployer`)\n }\n\n const estGas = await this.estGasRemovePaymentManager(\n dtAddress,\n address,\n paymentManager,\n dtContract\n )\n\n // Call removeFeeManager function of the contract\n const trxReceipt = await dtContract.methods\n .removePaymentManager(paymentManager)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas for setPaymentCollector method\n * @param dtAddress datatoken address\n * @param address Caller address\n * @param paymentCollector User to be set as new payment collector\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasSetPaymentCollector(\n dtAddress: string,\n address: string,\n paymentCollector: string,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await dtContract.methods\n .setPaymentCollector(paymentCollector)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * This function allows to set a new PaymentCollector (receives DT when consuming)\n * If not set the paymentCollector is the NFT Owner\n * only NFT owner can call\n * @param dtAddress datatoken address\n * @param address Caller address\n * @param paymentCollector User to be set as new payment collector\n * @return {Promise<TransactionReceipt>} trxReceipt\n */\n public async setPaymentCollector(\n dtAddress: string,\n address: string,\n paymentCollector: string\n ): Promise<TransactionReceipt> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n if ((await this.getDTPermissions(dtAddress, address)).paymentManager !== true) {\n throw new Error(`Caller is not Fee Manager`)\n }\n\n const estGas = await this.estGasSetPaymentCollector(\n dtAddress,\n address,\n paymentCollector,\n dtContract\n )\n\n // Call setFeeCollector method of the contract\n const trxReceipt = await dtContract.methods\n .setPaymentCollector(paymentCollector)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /** getPaymentCollector - It returns the current paymentCollector\n * @param dtAddress datatoken address\n * @return {Promise<string>}\n */\n public async getPaymentCollector(dtAddress: string): Promise<string> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n const paymentCollector = await dtContract.methods.getPaymentCollector().call()\n return paymentCollector\n }\n\n /**\n * Transfer as number from address to toAddress\n * @param {String} dtAddress Datatoken address\n * @param {String} toAddress Receiver address\n * @param {String} amount Number of datatokens, as number. To be converted to wei.\n * @param {String} address User adress\n * @return {Promise<TransactionReceipt>} transactionId\n */\n public async transfer(\n dtAddress: string,\n toAddress: string,\n amount: string,\n address: string\n ): Promise<TransactionReceipt> {\n const weiAmount = this.web3.utils.toWei(amount)\n return this.transferWei(dtAddress, toAddress, weiAmount, address)\n }\n\n /**\n * Estimate gas for transfer method\n * @param {String} dtAddress Datatoken address\n * @param {String} toAddress Receiver address\n * @param {String} amount Number of datatokens, as number. Expressed as wei\n * @param {String} address User adress\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasTransfer(\n dtAddress: string,\n toAddress: string,\n amount: string,\n address: string,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await dtContract.methods\n .transfer(toAddress, amount)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Transfer in wei from address to toAddress\n * @param {String} dtAddress Datatoken address\n * @param {String} toAddress Receiver address\n * @param {String} amount Number of datatokens, as number. Expressed as wei\n * @param {String} address User adress\n * @return {Promise<TransactionReceipt>} transactionId\n */\n public async transferWei(\n dtAddress: string,\n toAddress: string,\n amount: string,\n address: string\n ): Promise<TransactionReceipt> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n try {\n const estGas = await this.estGasTransfer(\n dtAddress,\n toAddress,\n amount,\n address,\n dtContract\n )\n // Call transfer function of the contract\n const trxReceipt = await dtContract.methods.transfer(toAddress, amount).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to transfer tokens: ${e.message}`)\n throw new Error(`Failed Failed to transfer tokens: ${e.message}`)\n }\n }\n\n /** Estimate gas cost for startOrder method\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address which calls\n * @param {String} consumer Consumer Address\n * @param {Number} serviceIndex Service index in the metadata\n * @param {providerFees} providerFees provider fees\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasStartOrder(\n dtAddress: string,\n address: string,\n consumer: string,\n serviceIndex: number,\n providerFees: ProviderFees,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n // Estimate gas for startOrder method\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await dtContract.methods\n .startOrder(consumer, serviceIndex, providerFees)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /** Start Order: called by payer or consumer prior ordering a service consume on a marketplace.\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address which calls\n * @param {String} consumer Consumer Address\n * @param {Number} serviceIndex Service index in the metadata\n * @param {providerFees} providerFees provider fees\n * @return {Promise<TransactionReceipt>} string\n */\n public async startOrder(\n dtAddress: string,\n address: string,\n consumer: string,\n serviceIndex: number,\n providerFees: ProviderFees\n ): Promise<TransactionReceipt> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n try {\n const estGas = await this.estGasStartOrder(\n dtAddress,\n address,\n consumer,\n serviceIndex,\n providerFees,\n dtContract\n )\n\n const trxReceipt = await dtContract.methods\n .startOrder(consumer, serviceIndex, providerFees)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to start order : ${e.message}`)\n throw new Error(`Failed to start order: ${e.message}`)\n }\n }\n\n /** Estimate gas cost for buyFromFreAndOrder method\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address which calls\n * @param {OrderParams} orderParams Consumer Address\n * @param {FreParams} freParams Amount of tokens that is going to be transfered\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasBuyFromFreAndOrder(\n dtAddress: string,\n address: string,\n orderParams: OrderParams,\n freParams: FreOrderParams,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n new this.web3.eth.Contract(this.datatokensEnterpriseAbi, dtAddress)\n\n // Estimate gas for startOrder method\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await dtContract.methods\n .buyFromFreAndOrder(orderParams, freParams)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /** Buys 1 DT from the FRE and then startsOrder, while burning that DT\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address which calls\n * @param {OrderParams} orderParams Consumer Address\n * @param {FreParams} freParams Amount of tokens that is going to be transfered\n * @return {Promise<TransactionReceipt>}\n */\n public async buyFromFreAndOrder(\n dtAddress: string,\n address: string,\n orderParams: OrderParams,\n freParams: FreOrderParams\n ): Promise<TransactionReceipt> {\n const dtContract = new this.web3.eth.Contract(this.datatokensEnterpriseAbi, dtAddress)\n try {\n const estGas = await this.estGasBuyFromFreAndOrder(\n dtAddress,\n address,\n orderParams,\n freParams,\n dtContract\n )\n\n const trxReceipt = await dtContract.methods\n .buyFromFreAndOrder(orderParams, freParams)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to buy DT From Fre And Order : ${e.message}`)\n throw new Error(`Failed to buy DT From Fre And Order: ${e.message}`)\n }\n }\n\n /** Estimate gas cost for buyFromFreAndOrder method\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address which calls\n * @param {OrderParams} orderParams\n * @param {String} dispenserContract\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasBuyFromDispenserAndOrder(\n dtAddress: string,\n address: string,\n orderParams: OrderParams,\n dispenserContract: string,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n new this.web3.eth.Contract(this.datatokensEnterpriseAbi, dtAddress)\n\n // Estimate gas for startOrder method\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await dtContract.methods\n .buyFromDispenserAndOrder(orderParams, dispenserContract)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /** Gets DT from dispenser and then startsOrder, while burning that DT\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address which calls\n * @param {OrderParams} orderParams\n * @param {String} dispenserContract\n * @return {Promise<TransactionReceipt>}\n */\n public async buyFromDispenserAndOrder(\n dtAddress: string,\n address: string,\n orderParams: OrderParams,\n dispenserContract: string\n ): Promise<TransactionReceipt> {\n const dtContract = new this.web3.eth.Contract(this.datatokensEnterpriseAbi, dtAddress)\n try {\n const estGas = await this.estGasBuyFromDispenserAndOrder(\n dtAddress,\n address,\n orderParams,\n dispenserContract,\n dtContract\n )\n\n const trxReceipt = await dtContract.methods\n .buyFromDispenserAndOrder(orderParams, dispenserContract)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n return trxReceipt\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to buy DT From Fre And Order : ${e.message}`)\n throw new Error(`Failed to buy DT From Fre And Order: ${e.message}`)\n }\n }\n\n /** Estimate gas for setData method\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address\n * @param {String} value Data to be stored into 725Y standard\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasSetData(\n dtAddress: string,\n address: string,\n value: string,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await dtContract.methods\n .setData(value)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /** setData\n * This function allows to store data with a preset key (keccak256(ERC20Address)) into NFT 725 Store\n * only ERC20Deployer can succeed\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address\n * @param {String} value Data to be stored into 725Y standard\n * @return {Promise<TransactionReceipt>} transactionId\n */\n public async setData(\n dtAddress: string,\n address: string,\n value: string\n ): Promise<TransactionReceipt> {\n if (!(await this.isERC20Deployer(dtAddress, address))) {\n throw new Error(`User is not ERC20 Deployer`)\n }\n\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n const estGas = await this.estGasSetData(dtAddress, address, value, dtContract)\n\n // Call setData function of the contract\n const trxReceipt = await dtContract.methods.setData(value).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /** Estimate gas for cleanPermissions method\n * @param dtAddress Datatoken address where we want to clean permissions\n * @param address User adress\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasCleanPermissions(\n dtAddress: string,\n address: string,\n contractInstance?: Contract\n ): Promise<any> {\n const dtContract =\n contractInstance ||\n setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await dtContract.methods\n .cleanPermissions()\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * Clean erc20level Permissions (minters, paymentManager and reset the paymentCollector) for an ERC20 datatoken\n * Only NFT Owner (at 721 level) can call it.\n * @param dtAddress Datatoken address where we want to clean permissions\n * @param address User adress\n * @return {Promise<TransactionReceipt>} transactionId\n */\n public async cleanPermissions(\n dtAddress: string,\n address: string\n ): Promise<TransactionReceipt> {\n if ((await this.nft.getNftOwner(await this.getNFTAddress(dtAddress))) !== address) {\n throw new Error('Caller is NOT Nft Owner')\n }\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n\n const estGas = await this.estGasCleanPermissions(dtAddress, address, dtContract)\n\n // Call cleanPermissions function of the contract\n const trxReceipt = await dtContract.methods.cleanPermissions().send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /** Returns ERC20 user's permissions for a datatoken\n * @param {String} dtAddress Datatoken adress\n * @param {String} address user adress\n * @return {Promise<Roles>}\n */\n public async getDTPermissions(dtAddress: string, address: string): Promise<Roles> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n const roles = await dtContract.methods.permissions(address).call()\n return roles\n }\n\n /** Returns the Datatoken capital\n * @param {String} dtAddress Datatoken adress\n * @return {Promise<string>}\n */\n public async getCap(dtAddress: string): Promise<string> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n const cap = await dtContract.methods.cap().call()\n return this.web3.utils.fromWei(cap)\n }\n\n /** It returns the token decimals, how many supported decimal points\n * @param {String} dtAddress Datatoken adress\n * @return {Promise<number>}\n */\n public async getDecimals(dtAddress: string): Promise<string> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n const decimals = await dtContract.methods.decimals().call()\n return decimals\n }\n\n /** It returns the token decimals, how many supported decimal points\n * @param {String} dtAddress Datatoken adress\n * @return {Promise<number>}\n */\n public async getNFTAddress(dtAddress: string): Promise<string> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n const nftAddress = await dtContract.methods.getERC721Address().call()\n return nftAddress\n }\n\n /** Returns true if address has deployERC20 role\n * @param {String} dtAddress Datatoken adress\n * @param {String} dtAddress Datatoken adress\n * @return {Promise<boolean>}\n */\n public async isERC20Deployer(dtAddress: string, address: string): Promise<boolean> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n const isERC20Deployer = await dtContract.methods.isERC20Deployer(address).call()\n return isERC20Deployer\n }\n\n /**\n * Get Address Balance for datatoken\n * @param {String} dtAddress Datatoken adress\n * @param {String} address user adress\n * @return {Promise<String>} balance Number of datatokens. Will be converted from wei\n */\n public async balance(datatokenAddress: string, address: string): Promise<string> {\n const dtContract = new this.web3.eth.Contract(this.datatokensAbi, datatokenAddress, {\n from: address\n })\n const balance = await dtContract.methods.balanceOf(address).call()\n return this.web3.utils.fromWei(balance)\n }\n}\n","import { Contract } from 'web3-eth-contract'\nimport Web3 from 'web3'\nimport { TransactionReceipt } from 'web3-core'\nimport { AbiItem } from 'web3-utils'\nimport defaultFactory721Abi from '@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json'\nimport {\n LoggerInstance,\n getFairGasPrice,\n generateDtName,\n getFreCreationParams,\n getErcCreationParams,\n getPoolCreationParams,\n configHelperNetworks,\n setContractDefaults\n} from '../utils'\nimport {\n FreCreationParams,\n Erc20CreateParams,\n PoolCreationParams,\n DispenserCreationParams\n} from '../interfaces'\nimport { Config } from '../models/index.js'\nimport { ProviderFees } from '../@types/index.js'\n\ninterface Template {\n templateAddress: string\n isActive: boolean\n}\n\nexport interface TokenOrder {\n tokenAddress: string\n consumer: string\n serviceIndex: number\n _providerFees: ProviderFees\n}\n\nexport interface NftCreateData {\n name: string\n symbol: string\n templateIndex: number\n tokenURI: string\n}\n\nconst addressZERO = '0x0000000000000000000000000000000000000000'\n/**\n * Provides an interface for NFT Factory contract\n */\nexport class NftFactory {\n public GASLIMIT_DEFAULT = 1000000\n public factory721Address: string\n public factory721Abi: AbiItem | AbiItem[]\n public web3: Web3\n public config: Config\n public factory721: Contract\n\n /**\n * Instantiate Datatokens.\n * @param {String} factory721Address\n * @param {AbiItem | AbiItem[]} factory721ABI\n * @param {Web3} web3\n */\n constructor(\n factory721Address: string,\n web3: Web3,\n factory721Abi?: AbiItem | AbiItem[],\n config?: Config\n ) {\n this.factory721Address = factory721Address\n this.factory721Abi = factory721Abi || (defaultFactory721Abi.abi as AbiItem[])\n this.web3 = web3\n this.config = config || configHelperNetworks[0]\n this.factory721 = setContractDefaults(\n new this.web3.eth.Contract(this.factory721Abi, this.factory721Address),\n this.config\n )\n }\n\n /**\n * Get estimated gas cost for deployERC721Contract value\n * @param {String} address\n * @param {String} nftData\n * @return {Promise<string>} NFT datatoken address\n */\n public async estGasCreateNFT(address: string, nftData: NftCreateData): Promise<string> {\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await this.factory721.methods\n .deployERC721Contract(\n nftData.name,\n nftData.symbol,\n nftData.templateIndex,\n addressZERO,\n nftData.tokenURI\n )\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Create new NFT\n * @param {String} address\n * @param {NFTCreateData} nftData\n * @return {Promise<string>} NFT datatoken address\n */\n public async createNFT(address: string, nftData: NftCreateData): Promise<string> {\n if (!nftData.templateIndex) nftData.templateIndex = 1\n\n if (!nftData.name || !nftData.symbol) {\n const { name, symbol } = generateDtName()\n nftData.name = name\n nftData.symbol = symbol\n }\n if (nftData.templateIndex > (await this.getCurrentNFTTemplateCount())) {\n throw new Error(`Template index doesnt exist`)\n }\n\n if (nftData.templateIndex === 0) {\n throw new Error(`Template index cannot be ZERO`)\n }\n if ((await this.getNFTTemplate(nftData.templateIndex)).isActive === false) {\n throw new Error(`Template is not active`)\n }\n const estGas = await this.estGasCreateNFT(address, nftData)\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.factory721.methods\n .deployERC721Contract(\n nftData.name,\n nftData.symbol,\n nftData.templateIndex,\n addressZERO,\n nftData.tokenURI\n )\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n let tokenAddress = null\n try {\n tokenAddress = trxReceipt.events.NFTCreated.returnValues[0]\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to create datatoken : ${e.message}`)\n }\n return tokenAddress\n }\n\n /** Get Current NFT Count (NFT created)\n * @return {Promise<number>} Number of NFT created from this factory\n */\n public async getCurrentNFTCount(): Promise<number> {\n const trxReceipt = await this.factory721.methods.getCurrentNFTCount().call()\n return trxReceipt\n }\n\n /** Get Current Datatoken Count\n * @return {Promise<number>} Number of DTs created from this factory\n */\n public async getCurrentTokenCount(): Promise<number> {\n const trxReceipt = await this.factory721.methods.getCurrentTokenCount().call()\n return trxReceipt\n }\n\n /** Get Factory Owner\n * @return {Promise<string>} Factory Owner address\n */\n public async getOwner(): Promise<string> {\n const trxReceipt = await this.factory721.methods.owner().call()\n return trxReceipt\n }\n\n /** Get Current NFT Template Count\n * @return {Promise<number>} Number of NFT Template added to this factory\n */\n public async getCurrentNFTTemplateCount(): Promise<number> {\n const count = await this.factory721.methods.getCurrentNFTTemplateCount().call()\n return count\n }\n\n /** Get Current Template Datatoken (ERC20) Count\n * @return {Promise<number>} Number of ERC20 Template added to this factory\n */\n public async getCurrentTokenTemplateCount(): Promise<number> {\n const count = await this.factory721.methods.getCurrentTemplateCount().call()\n return count\n }\n\n /** Get NFT Template\n * @param {Number} index Template index\n * @return {Promise<Template>} Number of Template added to this factory\n */\n public async getNFTTemplate(index: number): Promise<Template> {\n if (index > (await this.getCurrentNFTTemplateCount())) {\n throw new Error(`Template index doesnt exist`)\n }\n\n if (index === 0) {\n throw new Error(`Template index cannot be ZERO`)\n }\n const template = await this.factory721.methods.getNFTTemplate(index).call()\n return template\n }\n\n /** Get Datatoken(erc20) Template\n * @param {Number} index Template index\n * @return {Promise<Template>} DT Template info\n */\n public async getTokenTemplate(index: number): Promise<Template> {\n const template = await this.factory721.methods.getTokenTemplate(index).call()\n return template\n }\n\n /** Check if ERC20 is deployed from the factory\n * @param {String} datatoken Datatoken address we want to check\n * @return {Promise<Boolean>} return true if deployed from this factory\n */\n public async checkDatatoken(datatoken: string): Promise<Boolean> {\n const isDeployed = await this.factory721.methods.erc20List(datatoken).call()\n return isDeployed\n }\n\n /** Check if NFT is deployed from the factory\n * @param {String} nftAddress nftAddress address we want to check\n * @return {Promise<String>} return address(0) if it's not, or the nftAddress if true\n */\n public async checkNFT(nftAddress: string): Promise<String> {\n const confirmAddress = await this.factory721.methods.erc721List(nftAddress).call()\n return confirmAddress\n }\n\n /**\n * Estimate gas cost for add721TokenTemplate method\n * @param {String} address\n * @param {String} templateAddress template address to add\n * @return {Promise<TransactionReceipt>}\n */\n public async estGasAddNFTTemplate(\n address: string,\n templateAddress: string\n ): Promise<any> {\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await this.factory721.methods\n .add721TokenTemplate(templateAddress)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Add a new erc721 token template - only factory Owner\n * @param {String} address\n * @param {String} templateAddress template address to add\n * @return {Promise<TransactionReceipt>}\n */\n public async addNFTTemplate(\n address: string,\n templateAddress: string\n ): Promise<TransactionReceipt> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Factory Owner`)\n }\n if (templateAddress === addressZERO) {\n throw new Error(`Template cannot be ZERO address`)\n }\n\n const estGas = await this.estGasAddNFTTemplate(address, templateAddress)\n\n // Invoke add721TokenTemplate function of the contract\n const trxReceipt = await this.factory721.methods\n .add721TokenTemplate(templateAddress)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for disable721TokenTemplate method\n * @param {String} address\n * @param {Number} templateIndex index of the template we want to disable\n * @return {Promise<TransactionReceipt>} current token template count\n */\n public async estGasDisableNFTTemplate(\n address: string,\n templateIndex: number\n ): Promise<any> {\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await this.factory721.methods\n .disable721TokenTemplate(templateIndex)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Disable token template - only factory Owner\n * @param {String} address\n * @param {Number} templateIndex index of the template we want to disable\n * @return {Promise<TransactionReceipt>} current token template count\n */\n public async disableNFTTemplate(\n address: string,\n templateIndex: number\n ): Promise<TransactionReceipt> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Factory Owner`)\n }\n if (templateIndex > (await this.getCurrentNFTTemplateCount())) {\n throw new Error(`Template index doesnt exist`)\n }\n\n if (templateIndex === 0) {\n throw new Error(`Template index cannot be ZERO`)\n }\n const estGas = await this.estGasDisableNFTTemplate(address, templateIndex)\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.factory721.methods\n .disable721TokenTemplate(templateIndex)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Reactivate a previously disabled token template - only factory Owner\n * @param {String} address\n * @param {Number} templateIndex index of the template we want to reactivate\n * @return {Promise<TransactionReceipt>} current token template count\n */\n public async estGasReactivateNFTTemplate(\n address: string,\n templateIndex: number\n ): Promise<any> {\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await this.factory721.methods\n .reactivate721TokenTemplate(templateIndex)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Reactivate a previously disabled token template - only factory Owner\n * @param {String} address\n * @param {Number} templateIndex index of the template we want to reactivate\n * @return {Promise<TransactionReceipt>} current token template count\n */\n public async reactivateNFTTemplate(\n address: string,\n templateIndex: number\n ): Promise<TransactionReceipt> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Factory Owner`)\n }\n if (templateIndex > (await this.getCurrentNFTTemplateCount())) {\n throw new Error(`Template index doesnt exist`)\n }\n\n if (templateIndex === 0) {\n throw new Error(`Template index cannot be ZERO`)\n }\n\n const estGas = await this.estGasReactivateNFTTemplate(address, templateIndex)\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.factory721.methods\n .reactivate721TokenTemplate(templateIndex)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for addTokenTemplate method\n * @param {String} address\n * @param {String} templateAddress template address to add\n * @return {Promise<TransactionReceipt>}\n */\n public async estGasAddTokenTemplate(\n address: string,\n templateAddress: string\n ): Promise<any> {\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await this.factory721.methods\n .addTokenTemplate(templateAddress)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n\n return estGas\n }\n\n /**\n * Add a new erc721 token template - only factory Owner\n * @param {String} address\n * @param {String} templateAddress template address to add\n * @return {Promise<TransactionReceipt>}\n */\n public async addTokenTemplate(\n address: string,\n templateAddress: string\n ): Promise<TransactionReceipt> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Factory Owner`)\n }\n if (templateAddress === addressZERO) {\n throw new Error(`Template cannot be address ZERO`)\n }\n\n const estGas = await this.estGasAddTokenTemplate(address, templateAddress)\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.factory721.methods\n .addTokenTemplate(templateAddress)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for disableTokenTemplate method\n * @param {String} address\n * @param {Number} templateIndex index of the template we want to disable\n * @return {Promise<TransactionReceipt>} current token template count\n */\n public async estGasDisableTokenTemplate(\n address: string,\n templateIndex: number\n ): Promise<any> {\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await this.factory721.methods\n .disableTokenTemplate(templateIndex)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Disable token template - only factory Owner\n * @param {String} address\n * @param {Number} templateIndex index of the template we want to disable\n * @return {Promise<TransactionReceipt>} current token template count\n */\n public async disableTokenTemplate(\n address: string,\n templateIndex: number\n ): Promise<TransactionReceipt> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Factory Owner`)\n }\n if (templateIndex > (await this.getCurrentNFTTemplateCount())) {\n throw new Error(`Template index doesnt exist`)\n }\n\n if (templateIndex === 0) {\n throw new Error(`Template index cannot be ZERO`)\n }\n if ((await this.getNFTTemplate(templateIndex)).isActive === false) {\n throw new Error(`Template is already disabled`)\n }\n const estGas = await this.estGasDisableTokenTemplate(address, templateIndex)\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.factory721.methods\n .disableTokenTemplate(templateIndex)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for reactivateTokenTemplate method\n * @param {String} address\n * @param {Number} templateIndex index of the template we want to reactivate\n * @return {Promise<TransactionReceipt>} current token template count\n */\n public async estGasReactivateTokenTemplate(\n address: string,\n templateIndex: number\n ): Promise<any> {\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await this.factory721.methods\n .reactivateTokenTemplate(templateIndex)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * Reactivate a previously disabled token template - only factory Owner\n * @param {String} address\n * @param {Number} templateIndex index of the template we want to reactivate\n * @return {Promise<TransactionReceipt>} current token template count\n */\n public async reactivateTokenTemplate(\n address: string,\n templateIndex: number\n ): Promise<TransactionReceipt> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Factory Owner`)\n }\n if (templateIndex > (await this.getCurrentNFTTemplateCount())) {\n throw new Error(`Template index doesnt exist`)\n }\n\n if (templateIndex === 0) {\n throw new Error(`Template index cannot be ZERO`)\n }\n if ((await this.getTokenTemplate(templateIndex)).isActive === true) {\n throw new Error(`Template is already active`)\n }\n\n const estGas = await this.estGasReactivateTokenTemplate(address, templateIndex)\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.factory721.methods\n .reactivateTokenTemplate(templateIndex)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /** Estimate gas cost for startMultipleTokenOrder method\n * @param address Caller address\n * @param orders an array of struct tokenOrder\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async estGasStartMultipleTokenOrder(\n address: string,\n orders: TokenOrder[]\n ): Promise<any> {\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n estGas = await this.factory721.methods\n .startMultipleTokenOrder(orders)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * @dev startMultipleTokenOrder\n * Used as a proxy to order multiple services\n * Users can have inifinite approvals for fees for factory instead of having one approval/ erc20 contract\n * Requires previous approval of all :\n * - consumeFeeTokens\n * - publishMarketFeeTokens\n * - erc20 datatokens\n * @param address Caller address\n * @param orders an array of struct tokenOrder\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async startMultipleTokenOrder(\n address: string,\n orders: TokenOrder[]\n ): Promise<TransactionReceipt> {\n if (orders.length > 50) {\n throw new Error(`Too many orders`)\n }\n\n const estGas = await this.estGasStartMultipleTokenOrder(address, orders)\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.factory721.methods\n .startMultipleTokenOrder(orders)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for createNftWithErc method\n * @param address Caller address\n * @param _NftCreateData input data for nft creation\n * @param _ErcCreateData input data for erc20 creation\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n\n public async estGasCreateNftWithErc(\n address: string,\n nftCreateData: NftCreateData,\n ercParams: Erc20CreateParams\n ): Promise<any> {\n // Get estimated gas value\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n const ercCreateData = getErcCreationParams(ercParams)\n estGas = await this.factory721.methods\n .createNftWithErc(nftCreateData, ercCreateData)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * @dev createNftWithErc\n * Creates a new NFT, then a ERC20,all in one call\n * @param address Caller address\n * @param _NftCreateData input data for nft creation\n * @param _ErcCreateData input data for erc20 creation\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n\n public async createNftWithErc(\n address: string,\n nftCreateData: NftCreateData,\n ercParams: Erc20CreateParams\n ): Promise<TransactionReceipt> {\n const ercCreateData = getErcCreationParams(ercParams)\n\n const estGas = await this.estGasCreateNftWithErc(address, nftCreateData, ercParams)\n // Invoke createToken function of the contract\n const trxReceipt = await this.factory721.methods\n .createNftWithErc(nftCreateData, ercCreateData)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /**\n * Estimate gas cost for createNftErcWithPool method\n * @param address Caller address\n * @param nftCreateData input data for NFT Creation\n * @param ercParams input data for ERC20 Creation\n * @param poolParams input data for Pool Creation\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async estGasCreateNftErcWithPool(\n address: string,\n nftCreateData: NftCreateData,\n ercParams: Erc20CreateParams,\n poolParams: PoolCreationParams\n ): Promise<any> {\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n try {\n const ercCreateData = getErcCreationParams(ercParams)\n const poolData = getPoolCreationParams(poolParams)\n estGas = await this.factory721.methods\n .createNftErcWithPool(nftCreateData, ercCreateData, poolData)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * @dev createNftErcWithPool\n * Creates a new NFT, then a ERC20, then a Pool, all in one call\n * Use this carefully, because if Pool creation fails, you are still going to pay a lot of gas\n * @param address Caller address\n * @param nftCreateData input data for NFT Creation\n * @param ercParams input data for ERC20 Creation\n * @param poolParams input data for Pool Creation\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async createNftErcWithPool(\n address: string,\n nftCreateData: NftCreateData,\n ercParams: Erc20CreateParams,\n poolParams: PoolCreationParams\n ): Promise<TransactionReceipt> {\n const estGas = await this.estGasCreateNftErcWithPool(\n address,\n nftCreateData,\n ercParams,\n poolParams\n )\n const ercCreateData = getErcCreationParams(ercParams)\n const poolData = getPoolCreationParams(poolParams)\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.factory721.methods\n .createNftErcWithPool(nftCreateData, ercCreateData, poolData)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /** Estimate gas cost for createNftErcWithFixedRate method\n * @param address Caller address\n * @param nftCreateData input data for NFT Creation\n * @param ercParams input data for ERC20 Creation\n * @param freParams input data for FixedRate Creation\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async estGasCreateNftErcWithFixedRate(\n address: string,\n nftCreateData: NftCreateData,\n ercParams: Erc20CreateParams,\n freParams: FreCreationParams\n ): Promise<any> {\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n\n const ercCreateData = getErcCreationParams(ercParams)\n\n const fixedData = getFreCreationParams(freParams)\n\n try {\n estGas = await this.factory721.methods\n .createNftErcWithFixedRate(nftCreateData, ercCreateData, fixedData)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n }\n return estGas\n }\n\n /**\n * @dev createNftErcWithFixedRate\n * Creates a new NFT, then a ERC20, then a FixedRateExchange, all in one call\n * Use this carefully, because if Fixed Rate creation fails, you are still going to pay a lot of gas\n * @param address Caller address\n * @param nftCreateData input data for NFT Creation\n * @param ercParams input data for ERC20 Creation\n * @param freParams input data for FixedRate Creation\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async createNftErcWithFixedRate(\n address: string,\n nftCreateData: NftCreateData,\n ercParams: Erc20CreateParams,\n freParams: FreCreationParams\n ): Promise<TransactionReceipt> {\n const ercCreateData = getErcCreationParams(ercParams)\n const fixedData = getFreCreationParams(freParams)\n\n const estGas = await this.estGasCreateNftErcWithFixedRate(\n address,\n nftCreateData,\n ercParams,\n freParams\n )\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.factory721.methods\n .createNftErcWithFixedRate(nftCreateData, ercCreateData, fixedData)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /** Estimate gas cost for createNftErcWithFixedRate method\n * @param address Caller address\n * @param nftCreateData input data for NFT Creation\n * @param ercParams input data for ERC20 Creation\n * @param dispenserParams input data for Dispenser Creation\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async estGasCreateNftErcWithDispenser(\n address: string,\n nftCreateData: NftCreateData,\n ercParams: Erc20CreateParams,\n dispenserParams: DispenserCreationParams\n ): Promise<any> {\n const gasLimitDefault = this.GASLIMIT_DEFAULT\n let estGas\n\n const ercCreateData = getErcCreationParams(ercParams)\n\n try {\n estGas = await this.factory721.methods\n .createNftErcWithDispenser(nftCreateData, ercCreateData, dispenserParams)\n .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas))\n } catch (e) {\n estGas = gasLimitDefault\n LoggerInstance.error('Failed to estimate gas for createNftErcWithDispenser', e)\n }\n return estGas\n }\n\n /**\n * @dev createNftErcWithDispenser\n * Creates a new NFT, then a ERC20, then a Dispenser, all in one call\n * Use this carefully, because if Dispenser creation fails, you are still going to pay a lot of gas\n * @param address Caller address\n * @param nftCreateData input data for NFT Creation\n * @param ercParams input data for ERC20 Creation\n * @param dispenserParams input data for Dispenser Creation\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async createNftErcWithDispenser(\n address: string,\n nftCreateData: NftCreateData,\n ercParams: Erc20CreateParams,\n dispenserParams: DispenserCreationParams\n ): Promise<TransactionReceipt> {\n const ercCreateData = getErcCreationParams(ercParams)\n\n const estGas = await this.estGasCreateNftErcWithDispenser(\n address,\n nftCreateData,\n ercParams,\n dispenserParams\n )\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.factory721.methods\n .createNftErcWithDispenser(nftCreateData, ercCreateData, dispenserParams)\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n}\n","import { LogLevel } from '../utils/Logger'\nimport { AbiItem } from 'web3-utils/types'\n\nexport class Config {\n /**\n * Ethereum node URL.\n * @type {string}\n */\n public nodeUri?: string\n\n /**\n * Address of Provider.\n * @type {string}\n */\n public providerAddress?: string\n\n /**\n * Metadata Store URL.\n * @type {string}\n */\n public metadataCacheUri?: string\n\n /**\n * Provider URL.\n * @type {string}\n */\n public providerUri?: string\n\n /**\n * Web3 Provider.\n * @type {any}\n */\n public web3Provider?: any\n\n /**\n * Ocean Token address\n * @type {string}\n */\n public oceanTokenAddress?: string\n\n /**\n * Factory address\n * @type {string}\n */\n public erc721FactoryAddress?: string\n\n /**\n * Factory ABI\n * @type {string}\n */\n public erc721FFactoryABI?: AbiItem | AbiItem[]\n\n /**\n * datatokens ABI\n * @type {string}\n */\n public datatokensABI?: AbiItem | AbiItem[]\n\n /**\n * Pool Template address\n * @type {string}\n */\n public poolTemplateAddress?: string\n\n /**\n * Pool Factory ABI\n * @type {string}\n */\n public poolFactoryABI?: AbiItem | AbiItem[]\n\n /**\n * Pool ABI\n * @type {string}\n */\n public poolABI?: AbiItem | AbiItem[]\n\n /**\n * FixedRateExchangeAddress\n * @type {string}\n */\n public fixedRateExchangeAddress?: string\n\n /**\n * FixedRateExchangeAddressABI\n * @type {any}\n */\n public fixedRateExchangeAddressABI?: AbiItem | AbiItem[]\n\n /**\n * DispenserAddress\n * @type {string}\n */\n public dispenserAddress?: string\n\n /**\n * DispenserABI\n * @type {any}\n */\n public dispenserABI?: AbiItem | AbiItem[]\n\n /**\n * OPFCommunityFeeCollector\n * @type {string}\n */\n public opfCommunityFeeCollector?: string\n\n /**\n * SideStaking address\n * @type {string}\n */\n public sideStakingAddress?: string\n\n /**\n * block number of the deployment\n * @type {number}\n */\n public startBlock?: number\n /**\n * Log level.\n * @type {boolean | LogLevel}\n */\n public verbose?: boolean | LogLevel\n\n /**\n * Message shown when the user creates its own token.\n * @type {string}\n */\n public authMessage?: string\n\n /**\n * Token expiration time in ms.\n * @type {number}\n */\n public authTokenExpiration?: number\n\n /**\n * Parity config\n * @type {string}\n */\n public parityUri?: string\n\n public threshold?: number\n\n /**\n * Chain ID\n * @type {number}\n */\n chainId: number\n\n /**\n * Network name ex: mainnet, rinkeby, polygon\n * @type {string}\n */\n network: string\n\n /**\n * Url of the relevant subgraph instance ex: https://subgraph.mainnet.oceanprotocol.com\n * @type {string}\n */\n subgraphUri: string\n\n /**\n * Url of the blockchain exporer ex: https://etherscan.io\n * @type {string}\n */\n explorerUri: string\n\n /**\n * Ocean toke symbol on the chain, it's used just for convenience to reduce number of calls\n * @type {string}\n */\n oceanTokenSymbol: string\n\n /**\n * Specify the transaction Block Timeout\n * @type {number}\n */\n transactionBlockTimeout: number\n\n /**\n * Specify the transaction Confirmation Blocks\n * @type {number}\n */\n transactionConfirmationBlocks: number\n\n /**\n * Specify the transaction Polling Blocks Timeout\n * @type {number}\n */\n transactionPollingTimeout: number\n\n /**\n * Specify the multiplier for the gas fee\n * @type {number}\n */\n gasFeeMultiplier: number\n}\n\nexport default Config\n","import { LoggerInstance } from './Logger'\n\nexport const zeroX = (input: string): string => zeroXTransformer(input, true)\nexport const noZeroX = (input: string): string => zeroXTransformer(input, false)\nexport function zeroXTransformer(input = '', zeroOutput: boolean): string {\n const { valid, output } = inputMatch(input, /^(?:0x)*([a-f0-9]+)$/i, 'zeroXTransformer')\n return (zeroOutput && valid ? '0x' : '') + output\n}\n\n// Shared functions\nfunction inputMatch(\n input: string,\n regexp: RegExp,\n conversorName: string\n): { valid: boolean; output: string } {\n if (typeof input !== 'string') {\n LoggerInstance.debug('Not input string:')\n LoggerInstance.debug(input)\n throw new Error(`[${conversorName}] Expected string, input type: ${typeof input}`)\n }\n const match = input.match(regexp)\n if (!match) {\n LoggerInstance.warn(`[${conversorName}] Input transformation failed.`)\n return { valid: false, output: input }\n }\n return { valid: true, output: match[1] }\n}\n","import Web3 from 'web3'\nimport { LoggerInstance, getData, downloadFile, downloadFileBrowser } from '../utils'\nimport {\n FileMetadata,\n ComputeJob,\n ComputeOutput,\n ComputeAlgorithm,\n ComputeAsset,\n ProviderInitialize\n} from '../@types/'\nimport { noZeroX } from '../utils/ConversionTypeHelper'\nimport { signText, signWithHash } from '../utils/SignatureUtils'\nimport fetch from 'cross-fetch'\nimport { DownloadResponse } from '../@types/DownloadResponse'\nexport interface HttpCallback {\n (httpMethod: string, url: string, body: string, header: any): Promise<any>\n}\n\nexport interface ServiceEndpoint {\n serviceName: string\n method: string\n urlPath: string\n}\nexport interface UserCustomParameters {\n [key: string]: any\n}\n\nexport class Provider {\n /**\n * Returns the provider endpoints\n * @return {Promise<ServiceEndpoint[]>}\n */\n async getEndpoints(providerUri: string): Promise<any> {\n try {\n const endpoints = await getData(providerUri)\n return await endpoints.json()\n } catch (e) {\n LoggerInstance.error('Finding the service endpoints failed:', e)\n return null\n }\n }\n\n getEndpointURL(\n servicesEndpoints: ServiceEndpoint[],\n serviceName: string\n ): ServiceEndpoint {\n if (!servicesEndpoints) return null\n return servicesEndpoints.find((s) => s.serviceName === serviceName) as ServiceEndpoint\n }\n\n /**\n * Returns the service endpoints that exist in provider.\n * @param {any} endpoints\n * @return {Promise<ServiceEndpoint[]>}\n */\n public async getServiceEndpoints(providerEndpoint: string, endpoints: any) {\n const serviceEndpoints: ServiceEndpoint[] = []\n for (const i in endpoints.serviceEndpoints) {\n const endpoint: ServiceEndpoint = {\n serviceName: i,\n method: endpoints.serviceEndpoints[i][0],\n urlPath: providerEndpoint + endpoints.serviceEndpoints[i][1]\n }\n serviceEndpoints.push(endpoint)\n }\n return serviceEndpoints\n }\n\n /** Encrypt DDO using the Provider's own symmetric key\n * @param {string} providerUri provider uri address\n * @param {string} consumerAddress Publisher address\n * @param {AbortSignal} signal abort signal\n * @param {string} providerEndpoints Identifier of the asset to be registered in ocean\n * @param {string} serviceEndpoints document description object (DDO)=\n * @return {Promise<string>} urlDetails\n */\n public async getNonce(\n providerUri: string,\n consumerAddress: string,\n signal?: AbortSignal,\n providerEndpoints?: any,\n serviceEndpoints?: ServiceEndpoint[]\n ): Promise<string> {\n if (!providerEndpoints) {\n providerEndpoints = await this.getEndpoints(providerUri)\n }\n if (!serviceEndpoints) {\n serviceEndpoints = await this.getServiceEndpoints(providerUri, providerEndpoints)\n }\n const path = this.getEndpointURL(serviceEndpoints, 'nonce')\n ? this.getEndpointURL(serviceEndpoints, 'nonce').urlPath\n : null\n if (!path) return null\n try {\n const response = await fetch(path + `?userAddress=${consumerAddress}`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json'\n },\n signal: signal\n })\n return String((await response.json()).nonce)\n } catch (e) {\n LoggerInstance.error(e)\n throw new Error('HTTP request failed')\n }\n }\n\n public async createSignature(\n web3: Web3,\n accountId: string,\n agreementId: string\n ): Promise<string> {\n const signature = await signText(web3, noZeroX(agreementId), accountId)\n return signature\n }\n\n public async createHashSignature(\n web3: Web3,\n accountId: string,\n message: string\n ): Promise<string> {\n const signature = await signWithHash(web3, message, accountId)\n return signature\n }\n\n /** Encrypt data using the Provider's own symmetric key\n * @param {string} data data in json format that needs to be sent , it can either be a DDO or a File array\n * @param {string} providerUri provider uri address\n * @param {AbortSignal} signal abort signal\n * @return {Promise<string>} urlDetails\n */\n public async encrypt(\n data: any,\n providerUri: string,\n signal?: AbortSignal\n ): Promise<string> {\n const providerEndpoints = await this.getEndpoints(providerUri)\n const serviceEndpoints = await this.getServiceEndpoints(\n providerUri,\n providerEndpoints\n )\n const path = this.getEndpointURL(serviceEndpoints, 'encrypt')\n ? this.getEndpointURL(serviceEndpoints, 'encrypt').urlPath\n : null\n\n if (!path) return null\n try {\n const response = await fetch(path, {\n method: 'POST',\n body: decodeURI(JSON.stringify(data)),\n headers: {\n 'Content-Type': 'application/octet-stream'\n },\n signal: signal\n })\n return await response.text()\n } catch (e) {\n LoggerInstance.error(e)\n throw new Error('HTTP request failed')\n }\n }\n\n /** Get DDO File details (if possible)\n * @param {string} did did\n * @param {number} serviceId the id of the service for which to check the files\n * @param {string} providerUri uri of the provider that will be used to check the file\n * @param {AbortSignal} signal abort signal\n * @return {Promise<FileMetadata[]>} urlDetails\n */\n public async checkDidFiles(\n did: string,\n serviceId: number,\n providerUri: string,\n signal?: AbortSignal\n ): Promise<FileMetadata[]> {\n const providerEndpoints = await this.getEndpoints(providerUri)\n const serviceEndpoints = await this.getServiceEndpoints(\n providerUri,\n providerEndpoints\n )\n const args = { did: did, serviceId: serviceId }\n const files: FileMetadata[] = []\n const path = this.getEndpointURL(serviceEndpoints, 'fileinfo')\n ? this.getEndpointURL(serviceEndpoints, 'fileinfo').urlPath\n : null\n if (!path) return null\n try {\n const response = await fetch(path, {\n method: 'POST',\n body: JSON.stringify(args),\n headers: {\n 'Content-Type': 'application/json'\n },\n signal: signal\n })\n const results: FileMetadata[] = await response.json()\n for (const result of results) {\n files.push(result)\n }\n return files\n } catch (e) {\n return null\n }\n }\n\n /** Get URL details (if possible)\n * @param {string} url or did\n * @param {string} providerUri uri of the provider that will be used to check the file\n * @param {AbortSignal} signal abort signal\n * @return {Promise<FileMetadata[]>} urlDetails\n */\n public async checkFileUrl(\n url: string,\n providerUri: string,\n signal?: AbortSignal\n ): Promise<FileMetadata[]> {\n const providerEndpoints = await this.getEndpoints(providerUri)\n const serviceEndpoints = await this.getServiceEndpoints(\n providerUri,\n providerEndpoints\n )\n const args = { url: url, type: 'url' }\n const files: FileMetadata[] = []\n const path = this.getEndpointURL(serviceEndpoints, 'fileinfo')\n ? this.getEndpointURL(serviceEndpoints, 'fileinfo').urlPath\n : null\n if (!path) return null\n try {\n const response = await fetch(path, {\n method: 'POST',\n body: JSON.stringify(args),\n headers: {\n 'Content-Type': 'application/json'\n },\n signal: signal\n })\n const results: FileMetadata[] = await response.json()\n for (const result of results) {\n files.push(result)\n }\n return files\n } catch (e) {\n return null\n }\n }\n\n /** Initialize a service request.\n * @param {DDO | string} asset\n * @param {number} serviceIndex\n * @param {string} serviceType\n * @param {string} consumerAddress\n * @param {UserCustomParameters} userCustomParameters\n * @param {string} providerUri Identifier of the asset to be registered in ocean\n * @param {AbortSignal} signal abort signal\n * @return {Promise<ProviderInitialize>} ProviderInitialize data\n */\n public async initialize(\n did: string,\n serviceId: string,\n fileIndex: number,\n consumerAddress: string,\n providerUri: string,\n signal?: AbortSignal,\n userCustomParameters?: UserCustomParameters,\n computeEnv?: string,\n validUntil?: number\n ): Promise<ProviderInitialize> {\n const providerEndpoints = await this.getEndpoints(providerUri)\n const serviceEndpoints = await this.getServiceEndpoints(\n providerUri,\n providerEndpoints\n )\n let initializeUrl = this.getEndpointURL(serviceEndpoints, 'initialize')\n ? this.getEndpointURL(serviceEndpoints, 'initialize').urlPath\n : null\n\n if (!initializeUrl) return null\n initializeUrl += `?documentId=${did}`\n initializeUrl += `&serviceId=${serviceId}`\n initializeUrl += `&fileIndex=${fileIndex}`\n initializeUrl += `&consumerAddress=${consumerAddress}`\n if (userCustomParameters)\n initializeUrl += '&userdata=' + encodeURI(JSON.stringify(userCustomParameters))\n if (computeEnv) initializeUrl += '&computeEnv=' + encodeURI(computeEnv)\n if (validUntil) initializeUrl += '&validUntil=' + validUntil\n try {\n const response = await fetch(initializeUrl, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json'\n },\n signal: signal\n })\n const results: ProviderInitialize = await response.json()\n return results\n } catch (e) {\n LoggerInstance.error(e)\n throw new Error('Asset URL not found or not available.')\n }\n }\n\n /** Gets fully signed URL for download\n * @param {string} did\n * @param {string} accountId\n * @param {string} serviceId\n * @param {number} fileIndex\n * @param {string} providerUri\n * @param {Web3} web3\n * @param {UserCustomParameters} userCustomParameters\n * @return {Promise<string>}\n */\n public async getDownloadUrl(\n did: string,\n accountId: string,\n serviceId: string,\n fileIndex: number,\n transferTxId: string,\n providerUri: string,\n web3: Web3,\n userCustomParameters?: UserCustomParameters\n ): Promise<any> {\n const providerEndpoints = await this.getEndpoints(providerUri)\n const serviceEndpoints = await this.getServiceEndpoints(\n providerUri,\n providerEndpoints\n )\n const downloadUrl = this.getEndpointURL(serviceEndpoints, 'download')\n ? this.getEndpointURL(serviceEndpoints, 'download').urlPath\n : null\n if (!downloadUrl) return null\n const nonce = Date.now()\n const signature = await this.createSignature(web3, accountId, did + nonce)\n\n let consumeUrl = downloadUrl\n consumeUrl += `?fileIndex=${fileIndex}`\n consumeUrl += `&documentId=${did}`\n consumeUrl += `&transferTxId=${transferTxId}`\n consumeUrl += `&serviceId=${serviceId}`\n consumeUrl += `&consumerAddress=${accountId}`\n consumeUrl += `&nonce=${nonce}`\n consumeUrl += `&signature=${signature}`\n if (userCustomParameters)\n consumeUrl += '&userdata=' + encodeURI(JSON.stringify(userCustomParameters))\n return consumeUrl\n }\n\n /** Instruct the provider to start a compute job\n * @param {string} did\n * @param {string} consumerAddress\n * @param {ComputeAlgorithm} algorithm\n * @param {string} providerUri\n * @param {Web3} web3\n * @param {AbortSignal} signal abort signal\n * @param {ComputeOutput} output\n * @return {Promise<ComputeJob | ComputeJob[]>}\n */\n public async computeStart(\n providerUri: string,\n web3: Web3,\n consumerAddress: string,\n computeEnv: string,\n dataset: ComputeAsset,\n algorithm: ComputeAlgorithm,\n signal?: AbortSignal,\n additionalDatasets?: ComputeAsset[],\n output?: ComputeOutput\n ): Promise<ComputeJob | ComputeJob[]> {\n const providerEndpoints = await this.getEndpoints(providerUri)\n const serviceEndpoints = await this.getServiceEndpoints(\n providerUri,\n providerEndpoints\n )\n const computeStartUrl = this.getEndpointURL(serviceEndpoints, 'computeStart')\n ? this.getEndpointURL(serviceEndpoints, 'computeStart').urlPath\n : null\n\n const nonce = Date.now()\n let signatureMessage = consumerAddress\n signatureMessage += dataset.documentId\n signatureMessage += nonce\n const signature = await this.createHashSignature(\n web3,\n consumerAddress,\n signatureMessage\n )\n\n const payload = Object()\n payload.consumerAddress = consumerAddress\n payload.signature = signature\n payload.nonce = nonce\n payload.computeEnv = computeEnv\n payload.dataset = dataset\n payload.algorithm = algorithm\n if (payload.additionalDatasets) payload.additionalDatasets = additionalDatasets\n if (output) payload.output = output\n if (!computeStartUrl) return null\n try {\n const response = await fetch(computeStartUrl, {\n method: 'POST',\n body: JSON.stringify(payload),\n headers: {\n 'Content-Type': 'application/json'\n },\n signal: signal\n })\n\n if (response?.ok) {\n const params = await response.json()\n return params\n }\n console.error('Compute start failed:', response.status, response.statusText)\n LoggerInstance.error('Payload was:', payload)\n return null\n } catch (e) {\n LoggerInstance.error('Compute start failed:')\n LoggerInstance.error(e)\n LoggerInstance.error('Payload was:', payload)\n return null\n }\n }\n\n /** Instruct the provider to Stop the execution of a to stop a compute job.\n * @param {string} did\n * @param {string} consumerAddress\n * @param {string} jobId\n * @param {string} providerUri\n * @param {Web3} web3\n * @param {AbortSignal} signal abort signal\n * @return {Promise<ComputeJob | ComputeJob[]>}\n */\n public async computeStop(\n did: string,\n consumerAddress: string,\n jobId: string,\n providerUri: string,\n web3: Web3,\n signal?: AbortSignal\n ): Promise<ComputeJob | ComputeJob[]> {\n const providerEndpoints = await this.getEndpoints(providerUri)\n const serviceEndpoints = await this.getServiceEndpoints(\n providerUri,\n providerEndpoints\n )\n const computeStopUrl = this.getEndpointURL(serviceEndpoints, 'computeStop')\n ? this.getEndpointURL(serviceEndpoints, 'computeStop').urlPath\n : null\n\n const nonce = await this.getNonce(\n providerUri,\n consumerAddress,\n signal,\n providerEndpoints,\n serviceEndpoints\n )\n\n let signatureMessage = consumerAddress\n signatureMessage += jobId || ''\n signatureMessage += (did && `${noZeroX(did)}`) || ''\n signatureMessage += nonce\n const signature = await this.createHashSignature(\n web3,\n consumerAddress,\n signatureMessage\n )\n\n const payload = Object()\n payload.signature = signature\n payload.documentId = noZeroX(did)\n payload.consumerAddress = consumerAddress\n if (jobId) payload.jobId = jobId\n\n if (!computeStopUrl) return null\n try {\n const response = await fetch(computeStopUrl, {\n method: 'PUT',\n body: JSON.stringify(payload),\n headers: {\n 'Content-Type': 'application/json'\n },\n signal: signal\n })\n\n if (response?.ok) {\n const params = await response.json()\n return params\n }\n LoggerInstance.error('Compute stop failed:', response.status, response.statusText)\n LoggerInstance.error('Payload was:', payload)\n return null\n } catch (e) {\n LoggerInstance.error('Compute stop failed:')\n LoggerInstance.error(e)\n LoggerInstance.error('Payload was:', payload)\n return null\n }\n }\n\n /** Get status for a specific jobId/documentId/owner.\n * @param {string} did\n * @param {string} consumerAddress\n * @param {string} providerUri\n * @param {Web3} web3\n * @param {AbortSignal} signal abort signal\n * @param {string} jobId\n * @return {Promise<ComputeJob | ComputeJob[]>}\n */\n public async computeStatus(\n providerUri: string,\n signal?: AbortSignal,\n jobId?: string,\n did?: string,\n consumerAddress?: string\n ): Promise<ComputeJob | ComputeJob[]> {\n if (!jobId && !did && !consumerAddress) {\n throw new Error('You need at least one of jobId, did, consumerAddress')\n }\n\n const providerEndpoints = await this.getEndpoints(providerUri)\n const serviceEndpoints = await this.getServiceEndpoints(\n providerUri,\n providerEndpoints\n )\n const computeStatusUrl = this.getEndpointURL(serviceEndpoints, 'computeStatus')\n ? this.getEndpointURL(serviceEndpoints, 'computeStatus').urlPath\n : null\n\n let url = '?documentId=' + noZeroX(did)\n url += `&consumerAddress=${consumerAddress}`\n url += (jobId && `&jobId=${jobId}`) || ''\n\n if (!computeStatusUrl) return null\n try {\n const response = await fetch(computeStatusUrl + url, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json'\n },\n signal: signal\n })\n\n if (response?.ok) {\n const params = await response.json()\n return params\n }\n LoggerInstance.error(\n 'Get compute status failed:',\n response.status,\n response.statusText\n )\n return null\n } catch (e) {\n LoggerInstance.error('Get compute status failed')\n LoggerInstance.error(e)\n return null\n }\n }\n\n /** Get status for a specific jobId/documentId/owner.\n * @param {string} jobId\n * @param {number} index\n * @param {string} providerUri\n * @param {string} destination\n * @param {Web3} web3\n * @param {AbortSignal} signal abort signal\n * @return {Promise<ComputeJob | ComputeJob[]>}\n */\n public async computeResult(\n jobId: string,\n index: number,\n accountId: string,\n providerUri: string,\n web3: Web3,\n signal?: AbortSignal\n ): Promise<DownloadResponse | void> {\n const providerEndpoints = await this.getEndpoints(providerUri)\n const serviceEndpoints = await this.getServiceEndpoints(\n providerUri,\n providerEndpoints\n )\n const computeResultUrl = this.getEndpointURL(serviceEndpoints, 'computeResult')\n ? this.getEndpointURL(serviceEndpoints, 'computeResult').urlPath\n : null\n\n const nonce = await this.getNonce(\n providerUri,\n accountId,\n signal,\n providerEndpoints,\n serviceEndpoints\n )\n\n let signatureMessage = accountId\n signatureMessage += jobId\n signatureMessage += String(index)\n signatureMessage += nonce\n const signature = await this.createHashSignature(web3, accountId, signatureMessage)\n\n let consumeUrl = computeResultUrl\n consumeUrl += `?consumerAddress=${accountId}`\n consumeUrl += `&jobId=${jobId}`\n consumeUrl += `&index=${String(index)}`\n consumeUrl += (signature && `&signature=${signature}`) || ''\n\n if (!computeResultUrl) return null\n try {\n if (document) {\n await downloadFileBrowser(consumeUrl)\n } else {\n return await downloadFile(consumeUrl, index)\n }\n } catch (e) {\n LoggerInstance.error('Error getting job result')\n LoggerInstance.error(e)\n throw e\n }\n }\n\n /** Deletes a compute job.\n * @param {string} did\n * @param {string} consumerAddress\n * @param {string} jobId\n * @param {string} providerUri\n * @param {Web3} web3\n * @param {AbortSignal} signal abort signal\n * @return {Promise<ComputeJob | ComputeJob[]>}\n */\n public async computeDelete(\n did: string,\n consumerAddress: string,\n jobId: string,\n providerUri: string,\n web3: Web3,\n signal?: AbortSignal\n ): Promise<ComputeJob | ComputeJob[]> {\n const providerEndpoints = await this.getEndpoints(providerUri)\n const serviceEndpoints = await this.getServiceEndpoints(\n providerUri,\n providerEndpoints\n )\n const computeDeleteUrl = this.getEndpointURL(serviceEndpoints, 'computeDelete')\n ? this.getEndpointURL(serviceEndpoints, 'computeDelete').urlPath\n : null\n\n const nonce = await this.getNonce(\n providerUri,\n consumerAddress,\n signal,\n providerEndpoints,\n serviceEndpoints\n )\n\n let signatureMessage = consumerAddress\n signatureMessage += jobId || ''\n signatureMessage += (did && `${noZeroX(did)}`) || ''\n signatureMessage += nonce\n const signature = await this.createHashSignature(\n web3,\n consumerAddress,\n signatureMessage\n )\n\n const payload = Object()\n payload.documentId = noZeroX(did)\n payload.consumerAddress = consumerAddress\n payload.jobId = jobId\n if (signature) payload.signature = signature\n\n if (!computeDeleteUrl) return null\n try {\n const response = await fetch(computeDeleteUrl, {\n method: 'DELETE',\n body: JSON.stringify(payload),\n headers: {\n 'Content-Type': 'application/json'\n },\n signal: signal\n })\n\n if (response?.ok) {\n const params = await response.json()\n return params\n }\n LoggerInstance.error(\n 'Delete compute job failed:',\n response.status,\n response.statusText\n )\n LoggerInstance.error('Payload was:', payload)\n return null\n } catch (e) {\n LoggerInstance.error('Delete compute job failed:')\n LoggerInstance.error(e)\n LoggerInstance.error('Payload was:', payload)\n return null\n }\n }\n\n /** Check for a valid provider at URL\n * @param {String} url provider uri address\n * @param {AbortSignal} signal abort signal\n * @return {Promise<boolean>} string\n */\n public async isValidProvider(url: string, signal?: AbortSignal): Promise<boolean> {\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json'\n },\n signal: signal\n })\n if (response?.ok) {\n const params = await response.json()\n if (params && params.providerAddress) return true\n }\n return false\n } catch (error) {\n LoggerInstance.error(`Error validating provider: ${error.message}`)\n return false\n }\n }\n}\n\nexport const ProviderInstance = new Provider()\nexport default ProviderInstance\n"],"names":["LogLevel","Logger","logLevel","Error","this","setLevel","bypass","dispatch","Infinity","debug","Verbose","log","Log","warn","Warn","error","verb","level","console","LoggerInstance","generateDtName","wordList","list","wordListDefault","random1","Math","floor","random","adjectives","length","random2","nouns","indexNumber","adjective","replace","c","toUpperCase","noun","name","symbol","substring","minAbi","constant","inputs","outputs","type","payable","stateMutability","anonymous","indexed","amountToUnits","web3","token","amount","tokenContract","eth","Contract","methods","decimals","call","amountFormatted","BigNumber","parseInt","config","EXPONENTIAL_AT","toString","_this4","logger","unitsToAmount","_this2","getFairGasPrice","getGasPrice","x","gasFeeMultiplier","multipliedBy","integerValue","ROUND_DOWN","setContractDefaults","contract","transactionBlockTimeout","transactionConfirmationBlocks","transactionPollingTimeout","getErcCreationParams","ercParams","templateIndex","strings","addresses","minter","feeManager","mpFeeAddress","feeToken","uints","Web3","utils","toWei","cap","feeAmount","bytess","getFreCreationParams","freParams","allowedConsumer","fixedPriceAddress","fixedRateAddress","baseTokenAddress","owner","marketFeeCollector","baseTokenDecimals","datatokenDecimals","fixedRate","marketFee","withMint","getPoolCreationParams","poolParams","ssContract","baseTokenSender","publisherAddress","poolTemplateAddress","ssParams","rate","vestingAmount","vestedBlocks","initialBaseTokenLiquidity","swapFees","swapFeeLiquidityProvider","swapFeeMarketRunner","postData","url","payload","postWithHeaders","headers","fetch","method","body","getData","downloadFile","index","response","ok","filename","get","match","split","pop","arrayBuffer","data","downloadFileBrowser","anchor","document","createElement","download","href","click","fetchData","opts","result","text","_error2","configHelperNetworksBase","chainId","network","metadataCacheUri","nodeUri","providerUri","subgraphUri","explorerUri","oceanTokenAddress","oceanTokenSymbol","fixedRateExchangeAddress","dispenserAddress","startBlock","configHelperNetworks","ConfigHelper","getAddressesFromEnv","customAddresses","configAddresses","erc721FactoryAddress","ERC721Factory","sideStakingAddress","Staking","opfCommunityFeeCollector","OPFCommunityFeeCollector","poolTemplate","FixedPrice","Dispenser","Ocean","process","env","AQUARIUS_URI","e","DefaultContractsAddresses","getConfig","infuraProjectId","filterBy","find","generateDid","erc721Address","toChecksumAddress","sha256","getHash","ZERO_ADDRESS","GASLIMIT_DEFAULT","signWithHash","publicKey","password","hash","utf8ToHex","isMetaMask","currentProvider","personal","sign","e2","signHash","message","address","signedMessage","r","substr","slice","s","v","signText","balance","tokenAddress","account","balanceOf","trxReceipt","allowance","spender","approve","force","estApprove","estGas","_tokenContract$method3","send","from","gas","gasPrice","currentAllowence","Decimal","greaterThanOrEqualTo","contractInstance","gasLimitDefault","estimateGas","err","then","MaxUint256","_settle","value","prototype","callback","_this","thenable","shouldContinue","stage","updateValue","_resumeAfterBody","Pool","poolAbi","PoolTemplate","abi","sharesBalance","poolAddress","fromWei","estSetSwapFee","fee","poolContract","defaultErc20Abi","setSwapFee","pool","_this6","_pool$methods$setSwap2","getNumTokens","_this8","getPoolSharesTotalSupply","_this10","totalSupply","getCurrentTokens","_this12","getFinalTokens","_this14","getController","_this16","getBaseToken","_this18","getBaseTokenAddress","getDatatoken","_this20","getDatatokenAddress","getMarketFeeCollector","_this22","_publishMarketCollector","getOPFCollector","_this24","_opfCollector","isBound","_this26","getReserve","_this28","getBalance","isFinalized","_this30","getSwapFee","_this32","getNormalizedWeight","_this34","weight","getDenormalizedWeight","_this36","getTotalDenormalizedWeight","_this38","getMarketFees","_this40","publishMarketFees","getCurrentMarketFees","_this42","getCurrentOPFFees","_this44","getCommunityFees","_this46","communityFees","estCollectOPF","_this48","collectOPF","_this50","_pool$methods$collect2","estCollectMarketFee","_this52","collectMarketFee","_this54","_this53$getMarketFeeC","_pool$methods$collect4","estUpdateMarketFeeCollector","newCollector","_this56","updateMarketFeeCollector","_this58","_this57$getMarketFeeC","_pool$methods$updateM2","estSwapExactAmountIn","tokenInOutMarket","amountsInOutMaxFee","_this60","maxPrice","swapExactAmountIn","tokenIn","tokenOut","marketFeeAddress","tokenAmountIn","minAmountOut","swapMarketFee","_this62","_pool$methods$swapExa2","estSwapExactAmountOut","_this64","swapExactAmountOut","maxAmountIn","tokenAmountOut","_this66","_pool$methods$swapExa4","estJoinPool","poolAmountOut","maxAmountsIn","_this68","joinPool","_this70","weiMaxAmountsIn","tokens","_pool$methods$joinPoo2","i","push","estExitPool","poolAmountIn","minAmountsOut","_this72","exitPool","_this74","weiMinAmountsOut","_pool$methods$exitPoo2","estJoinswapExternAmountIn","minPoolAmountOut","_this76","joinswapExternAmountIn","_this78","amountInFormatted","_pool$methods$joinswa2","estJoinswapPoolAmountOut","_this80","joinswapPoolAmountOut","_this82","maxAmountInFormatted","_pool$methods$joinswa4","estExitswapPoolAmountIn","minTokenAmountOut","_this84","exitswapPoolAmountIn","_this86","minTokenOutFormatted","_pool$methods$exitswa2","estExitswapExternAmountOut","maxPoolAmountIn","_this88","exitswapExternAmountOut","_this90","_pool$methods$exitswa4","getSpotPrice","decimalsDiff","decimalsTokenIn","decimalsTokenOut","price","_this92","tokenOutContract","tokenInContract","getAmountInExactOut","_this94","amountOutFormatted","getAmountOutExactIn","_this96","calcPoolOutGivenSingleIn","_this98","_pool$methods","calcPoolOutSingleIn","_calcPoolOutSingleIn","calcSingleInGivenPoolOut","_this100","calcSingleInPoolOut","calcSingleOutGivenPoolIn","_this102","_pool$methods2","calcSingleOutPoolIn","_calcSingleOutPoolIn","calcPoolInGivenSingleOut","_this104","_pool$methods3","calcPoolInSingleOut","_calcPoolInSingleOut","getSwapEventSignature","eventdata","o","encodeEventSignature","getJoinEventSignature","getExitEventSignature","FixedRateCreateProgressStep","dispenserAbi","dispenserContract","defaultDispenserAbi","status","dtAdress","maxTokens","maxBalance","_exit2","estGasCreate","dtAddress","allowedSwapper","create","_this5$dispenserContr","estGasActivate","activate","_this9$dispenserContr","estGasDeactivate","deactivate","_this13$dispenserCont","estGasSetAllowedSwapper","newAllowedSwapper","setAllowedSwapper","_this17$dispenserCont","estGasDispense","destination","dispense","_this21$dispenserCont","estGasOwnerWithdraw","ownerWithdraw","_this25$dispenserCont","isDispensable","datatoken","active","String","greaterThan","isMinter","FixedRateExchange","fixedRateExchangeAbi","oceanAddress","fixedRateContract","ssAbi","defaultFixedRateExchangeAbi","generateExchangeId","baseToken","estBuyDT","datatokenAddress","dtAmount","maxBaseTokenAmount","buyDT","exchangeId","datatokenAmount","getExchange","_this9$getExchange2","dtAmountFormatted","_this9$getExchange","maxBtFormatted","_this9$contract$metho","estSellDT","sellDT","minBaseTokenAmount","_this13$getExchange2","_this13$getExchange","minBtFormatted","_this13$contract$meth","getNumberOfExchanges","estSetRate","newRate","setRate","_this19$contract$meth","estSetAllowedSwapper","_this23$contract$meth","estActivate","toggleExchangeState","exchange","_this27$contract$meth","estDeactivate","_this31$contract$meth","getRate","weiRate","getDTSupply","dtSupply","_this35$getExchange","getBTSupply","btSupply","_this37$getExchange","getAllowedSwapper","getAmountBTIn","_this41$contract$meth2","calcBaseInGivenOutDT","_this41$getExchange2","_calcBaseInGivenOutDT2","_this41$getExchange","baseTokenAmount","getAmountBTOut","_this43$contract$meth2","calcBaseOutGivenInDT","_this43$getExchange2","_calcBaseOutGivenInDT2","_this43$getExchange","dtDecimals","btDecimals","dtBalance","btBalance","getFeesInfo","opfFee","_this47$getExchange2","marketFeeAvailable","_this47$getExchange","oceanFeeAvailable","getExchanges","isActive","estActivateMint","toggleMintState","activateMint","_this55$contract$meth","estDeactivateMint","deactivateMint","_this59$contract$meth","estCollectBT","collectBT","_this63$contract$meth","estCollectDT","collectDT","_this67$contract$meth","_this71$contract$meth","estCollectOceanFee","collectOceanFee","_this75$contract$meth","opfCollector","getRouter","router","getExchangeOwner","_this81$getExchange","exchangeOwner","estUpdateMarketFee","newMarketFee","updateMarketFee","_this85$contract$meth","newMarketFeeCollector","_this89$contract$meth","Nft","nftAbi","factory721Address","factory721Abi","defaultNftAbi","estGasCreateErc20","nftAddress","nftContract","createERC20","createErc20","getNftPermissions","_this3$getNftPermissi","deployERC20","_nftContract$methods$2","events","TokenCreated","returnValues","estGasAddManager","manager","addManager","getNftOwner","_this7$getNftOwner","_nftContract$methods$4","estGasRemoveManager","removeManager","_this11$getNftOwner","_nftContract$methods$6","estGasAddErc20Deployer","erc20Deployer","addToCreateERC20List","addErc20Deployer","_this15$getNftPermiss","_nftContract$methods$8","estGasRemoveErc20Deployer","removeFromCreateErc20List","removeErc20Deployer","_temp11","_this19$getNftPermiss2","removeFromCreateERC20List","_nftContract$methods$10","_this19$getNftPermiss","estGasAddMetadataUpdater","metadataUpdater","addToMetadataList","addMetadataUpdater","_this23$getNftPermiss","_nftContract$methods$12","esGasRemoveMetadataUpdater","removeFromMetadataList","removeMetadataUpdater","_temp17","_this27$getNftPermiss2","updateMetadata","_nftContract$methods$14","_this27$getNftPermiss","estGasAddStoreUpdater","storeUpdater","addTo725StoreList","addStoreUpdater","_this31$getNftPermiss","_nftContract$methods$16","estGasRemoveStoreUpdater","removeFrom725StoreList","removeStoreUpdater","_temp23","_this35$getNftPermiss2","store","_nftContract$methods$18","_this35$getNftPermiss","estGasCleanPermissions","cleanPermissions","_this39$getNftOwner","_nftContract$methods$20","estGasTransferNft","nftOwner","nftReceiver","tokenId","transferFrom","transferNft","_this43$getNftOwner","tokenIdentifier","_nftContract$methods$22","estGasSafeTransferNft","safeTransferFrom","safeTransferNft","_this47$getNftOwner","_nftContract$methods$24","estGasSetMetadata","metadataState","metadataDecryptorUrl","metadataDecryptorAddress","flags","metadataHash","metadataProofs","setMetaData","setMetadata","_this51$getNftPermiss","_nftContract$methods$26","estGasSetMetadataAndTokenURI","metadataAndTokenURI","setMetaDataAndTokenURI","setMetadataAndTokenURI","_this55$getNftPermiss","_nftContract$methods$28","estGasSetMetadataState","setMetaDataState","setMetadataState","_this59$getNftPermiss","_nftContract$methods$30","estSetTokenURI","setTokenURI","_nftContract$methods$32","ownerOf","getPermissions","getMetadata","getMetaData","isErc20Deployer","isERC20Deployer","key","getTokenURI","id","tokenURI","Datatoken","datatokensAbi","datatokensEnterpriseAbi","factoryAddress","factoryABI","nft","defaultDatatokensAbi","defaultDatatokensEnterpriseAbi","estGasApprove","dtContract","_dtContract$methods$a2","estGasMint","toAddress","mint","estGasCreateFixedRate","fixedRateParams","createFixedRate","_dtContract$methods$c2","estGasCreateDispenser","dispenserParams","createDispenser","_dtContract$methods$c4","getDTPermissions","_this15$getDTPermissi","getCap","capAvailble","gte","_dtContract$methods$m2","estGasAddMinter","addMinter","_this19$isERC20Deploy","_dtContract$methods$a4","estGasRemoveMinter","removeMinter","_this23$isERC20Deploy","_dtContract$methods$r2","estGasAddPaymentManager","paymentManager","addPaymentManager","_this27$isERC20Deploy","_dtContract$methods$a6","estGasRemovePaymentManager","removePaymentManager","_this31$isERC20Deploy","_dtContract$methods$r4","estGasSetPaymentCollector","paymentCollector","setPaymentCollector","_this35$getDTPermissi","_dtContract$methods$s2","getPaymentCollector","transfer","weiAmount","transferWei","estGasTransfer","_dtContract$methods$t2","estGasStartOrder","consumer","serviceIndex","providerFees","startOrder","_dtContract$methods$s4","estGasBuyFromFreAndOrder","orderParams","buyFromFreAndOrder","_dtContract$methods$b2","estGasBuyFromDispenserAndOrder","buyFromDispenserAndOrder","_dtContract$methods$b4","estGasSetData","setData","_dtContract$methods$s6","_this63$nft2","getNFTAddress","_this63$nft$getNftOwn","_dtContract$methods$c6","permissions","getDecimals","getERC721Address","addressZERO","NftFactory","factory721","defaultFactory721Abi","estGasCreateNFT","nftData","deployERC721Contract","createNFT","getCurrentNFTTemplateCount","_nftData$templateInde2","getNFTTemplate","_this3$getNFTTemplate","_this3$factory721$met","NFTCreated","getCurrentNFTCount","getCurrentTokenCount","getOwner","getCurrentTokenTemplateCount","getCurrentTemplateCount","getTokenTemplate","checkDatatoken","erc20List","checkNFT","erc721List","estGasAddNFTTemplate","templateAddress","add721TokenTemplate","addNFTTemplate","_this25$getOwner","_this25$factory721$me","estGasDisableNFTTemplate","disable721TokenTemplate","disableNFTTemplate","_this29$getOwner","_this29$factory721$me","estGasReactivateNFTTemplate","reactivate721TokenTemplate","reactivateNFTTemplate","_this33$getOwner","_this33$factory721$me","estGasAddTokenTemplate","addTokenTemplate","_this37$getOwner","_this37$factory721$me","estGasDisableTokenTemplate","disableTokenTemplate","_this41$getOwner","_this41$getNFTTemplat","_this41$factory721$me","estGasReactivateTokenTemplate","reactivateTokenTemplate","_this45$getOwner","_this45$getTokenTempl","_this45$factory721$me","estGasStartMultipleTokenOrder","orders","startMultipleTokenOrder","_this49$factory721$me","estGasCreateNftWithErc","nftCreateData","ercCreateData","createNftWithErc","_this53$factory721$me","estGasCreateNftErcWithPool","poolData","createNftErcWithPool","_this57$factory721$me","estGasCreateNftErcWithFixedRate","fixedData","createNftErcWithFixedRate","_this61$factory721$me","estGasCreateNftErcWithDispenser","createNftErcWithDispenser","_this65$factory721$me","Config","providerAddress","web3Provider","erc721FFactoryABI","datatokensABI","poolFactoryABI","poolABI","fixedRateExchangeAddressABI","dispenserABI","verbose","authMessage","authTokenExpiration","parityUri","threshold","noZeroX","input","zeroOutput","regexp","conversorName","valid","output","inputMatch","zeroXTransformer","Provider","getEndpoints","endpoints","json","getEndpointURL","servicesEndpoints","serviceName","getServiceEndpoints","providerEndpoint","serviceEndpoints","urlPath","getNonce","consumerAddress","signal","providerEndpoints","path","_response$json","nonce","createSignature","accountId","agreementId","createHashSignature","encrypt","decodeURI","JSON","stringify","checkDidFiles","did","serviceId","args","files","results","checkFileUrl","initialize","fileIndex","userCustomParameters","computeEnv","validUntil","initializeUrl","encodeURI","getDownloadUrl","transferTxId","downloadUrl","Date","now","signature","consumeUrl","computeStart","dataset","algorithm","additionalDatasets","computeStartUrl","signatureMessage","documentId","Object","statusText","params","computeStop","jobId","computeStopUrl","computeStatus","computeStatusUrl","computeResult","computeResultUrl","computeDelete","computeDeleteUrl","isValidProvider","ProviderInstance"],"mappings":"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"}
|