@oceanprotocol/lib 1.1.8 → 2.0.0-next.3

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.
Files changed (83) hide show
  1. package/CHANGELOG.md +47 -16
  2. package/CodeExamples.md +28 -315
  3. package/README.md +4 -7
  4. package/dist/lib.js +1 -1
  5. package/dist/lib.js.map +1 -1
  6. package/dist/lib.modern.js +1 -1
  7. package/dist/lib.modern.js.map +1 -1
  8. package/dist/lib.module.js +1 -1
  9. package/dist/lib.module.js.map +1 -1
  10. package/dist/lib.umd.js +1 -1
  11. package/dist/lib.umd.js.map +1 -1
  12. package/dist/src/@types/Asset.d.ts +4 -4
  13. package/dist/src/@types/Compute.d.ts +1 -1
  14. package/dist/src/@types/DDO/DDO.d.ts +2 -5
  15. package/dist/src/@types/{Erc20.d.ts → Datatoken.d.ts} +18 -1
  16. package/dist/src/@types/Dispenser.d.ts +9 -0
  17. package/dist/src/@types/FixedPrice.d.ts +24 -0
  18. package/dist/src/@types/{Erc721.d.ts → NFT.d.ts} +6 -0
  19. package/dist/src/@types/NFTFactory.d.ts +20 -0
  20. package/dist/src/@types/Provider.d.ts +8 -0
  21. package/dist/src/@types/ReturnTypes.d.ts +2 -0
  22. package/dist/src/@types/Router.d.ts +1 -1
  23. package/dist/src/@types/index.d.ts +11 -8
  24. package/dist/src/{models → config}/Config.d.ts +2 -23
  25. package/dist/src/{utils → config}/ConfigHelper.d.ts +1 -1
  26. package/dist/src/config/index.d.ts +2 -0
  27. package/dist/src/contracts/Datatoken.d.ts +232 -0
  28. package/dist/src/contracts/Dispenser.d.ts +73 -0
  29. package/dist/src/contracts/FixedRateExchange.d.ts +212 -0
  30. package/dist/src/contracts/NFT.d.ts +197 -0
  31. package/dist/src/contracts/NFTFactory.d.ts +144 -0
  32. package/dist/src/contracts/Router.d.ts +92 -0
  33. package/dist/src/contracts/SmartContract.d.ts +22 -0
  34. package/dist/src/contracts/SmartContractWithAddress.d.ts +18 -0
  35. package/dist/src/contracts/df/DfRewards.d.ts +32 -0
  36. package/dist/src/contracts/df/DfStrategyV1.d.ts +23 -0
  37. package/dist/src/contracts/index.d.ts +13 -0
  38. package/dist/src/contracts/ve/VeAllocate.d.ts +41 -0
  39. package/dist/src/contracts/ve/VeFeeDistributor.d.ts +30 -0
  40. package/dist/src/contracts/ve/VeOcean.d.ts +69 -0
  41. package/dist/src/index.d.ts +4 -7
  42. package/dist/src/{aquarius → services}/Aquarius.d.ts +2 -3
  43. package/dist/src/{provider → services}/Provider.d.ts +5 -13
  44. package/dist/src/services/index.d.ts +2 -0
  45. package/dist/src/utils/Constants.d.ts +2 -0
  46. package/dist/src/utils/ContractUtils.d.ts +14 -8
  47. package/dist/src/utils/DdoHelpers.d.ts +1 -1
  48. package/dist/src/utils/FetchHelper.d.ts +1 -4
  49. package/dist/src/utils/Logger.d.ts +0 -1
  50. package/dist/src/utils/TokenUtils.d.ts +17 -39
  51. package/dist/src/utils/index.d.ts +6 -7
  52. package/dist/test/TestContractHandler.d.ts +4 -4
  53. package/dist/test/config.d.ts +1 -1
  54. package/dist/test/unit/{factories/NftFactory.test.d.ts → DFRewards.test.d.ts} +0 -0
  55. package/dist/test/unit/{tokens/Datatoken.test.d.ts → Datatoken.test.d.ts} +0 -0
  56. package/dist/test/unit/{pools/dispenser/Dispenser.test.d.ts → Dispenser.test.d.ts} +0 -0
  57. package/dist/test/unit/{pools/fixedRate/FixedRateExchange.test.d.ts → FixedRateExchange.test.d.ts} +0 -0
  58. package/dist/test/unit/{tokens/Nft.test.d.ts → Nft.test.d.ts} +0 -0
  59. package/dist/test/unit/{pools/Router.test.d.ts → NftFactory.test.d.ts} +0 -0
  60. package/dist/test/unit/{pools/balancer/Pool.test.d.ts → Router.test.d.ts} +0 -0
  61. package/dist/test/unit/{pools/ssContracts/SideStaking.test.d.ts → veOcean.test.d.ts} +0 -0
  62. package/package.json +6 -19
  63. package/dist/src/@types/Pool.d.ts +0 -45
  64. package/dist/src/aquarius/index.d.ts +0 -1
  65. package/dist/src/factories/NFTFactory.d.ts +0 -275
  66. package/dist/src/factories/index.d.ts +0 -1
  67. package/dist/src/models/index.d.ts +0 -1
  68. package/dist/src/pools/Router.d.ts +0 -228
  69. package/dist/src/pools/balancer/Pool.d.ts +0 -395
  70. package/dist/src/pools/balancer/index.d.ts +0 -1
  71. package/dist/src/pools/dispenser/Dispenser.d.ts +0 -145
  72. package/dist/src/pools/dispenser/index.d.ts +0 -1
  73. package/dist/src/pools/fixedRate/FixedRateExchange.d.ts +0 -388
  74. package/dist/src/pools/fixedRate/index.d.ts +0 -1
  75. package/dist/src/pools/index.d.ts +0 -5
  76. package/dist/src/pools/ssContracts/SideStaking.d.ts +0 -133
  77. package/dist/src/pools/ssContracts/index.d.ts +0 -1
  78. package/dist/src/provider/index.d.ts +0 -1
  79. package/dist/src/tokens/Datatoken.d.ts +0 -413
  80. package/dist/src/tokens/NFT.d.ts +0 -364
  81. package/dist/src/tokens/index.d.ts +0 -2
  82. package/dist/src/utils/ConversionTypeHelper.d.ts +0 -3
  83. package/dist/src/utils/PoolHelpers.d.ts +0 -8
package/dist/lib.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"lib.js","sources":["../src/utils/Logger.ts","../src/utils/DatatokenName.ts","../src/utils/minAbi.ts","../src/utils/Constants.ts","../src/utils/ContractUtils.ts","../src/utils/FetchHelper.ts","../src/utils/ConfigHelper.ts","../src/utils/TokenUtils.ts","../src/utils/General.ts","../src/utils/PoolHelpers.ts","../src/aquarius/Aquarius.ts","../src/pools/balancer/Pool.ts","../src/pools/dispenser/Dispenser.ts","../src/pools/fixedRate/FixedRateExchange.ts","../src/pools/ssContracts/SideStaking.ts","../src/pools/Router.ts","../src/tokens/NFT.ts","../src/tokens/Datatoken.ts","../src/factories/NFTFactory.ts","../src/utils/ConversionTypeHelper.ts","../src/provider/Provider.ts","../src/models/Config.ts","../src/utils/DdoHelpers.ts","../src/utils/SignatureUtils.ts"],"sourcesContent":["/* eslint-disable no-unused-vars */\nexport enum LogLevel {\n None = -1,\n Error = 0,\n Warn = 1,\n Log = 2,\n Verbose = 3\n}\n/* eslint-enable no-unused-vars */\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","export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'\nexport const GASLIMIT_DEFAULT = 1000000\n","import Web3 from 'web3'\nimport BigNumber from 'bignumber.js'\nimport { Contract } from 'web3-eth-contract'\nimport { generateDtName } from './DatatokenName'\nimport {\n Erc20CreateParams,\n FreCreationParams,\n FreOrderParams,\n PoolCreationParams\n} from '../@types'\nimport { Config } from '../models'\nimport { minAbi } from './minAbi'\nimport LoggerInstance from './Logger'\nimport { GASLIMIT_DEFAULT, ZERO_ADDRESS } from './Constants'\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.paymentCollector,\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 async function getFreOrderParams(\n web3: Web3,\n freParams: FreOrderParams\n): Promise<any> {\n return {\n exchangeContract: freParams.exchangeContract,\n exchangeId: freParams.exchangeId,\n maxBaseTokenAmount: await amountToUnits(\n web3,\n freParams.baseTokenAddress,\n freParams.maxBaseTokenAmount,\n freParams.baseTokenDecimals\n ),\n swapMarketFee: await amountToUnits(\n web3,\n freParams.baseTokenAddress,\n freParams.swapMarketFee,\n freParams.baseTokenDecimals\n ),\n marketFeeAddress: freParams.marketFeeAddress\n }\n}\n\nexport function getFreCreationParams(freParams: FreCreationParams): any {\n if (!freParams.allowedConsumer) freParams.allowedConsumer = ZERO_ADDRESS\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 Web3.utils.toWei(freParams.fixedRate),\n Web3.utils.toWei(freParams.marketFee),\n withMint\n ]\n }\n}\n\nexport async function getPoolCreationParams(\n web3: Web3,\n poolParams: PoolCreationParams\n): Promise<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 await amountToUnits(\n web3,\n poolParams.baseTokenAddress,\n poolParams.initialBaseTokenLiquidity\n )\n ],\n swapFees: [\n Web3.utils.toWei(poolParams.swapFeeLiquidityProvider),\n Web3.utils.toWei(poolParams.swapFeeMarketRunner)\n ]\n }\n}\n\nexport async function unitsToAmount(\n web3: Web3,\n token: string,\n amount: string,\n tokenDecimals?: number\n): Promise<string> {\n try {\n const tokenContract = new web3.eth.Contract(minAbi, token)\n let decimals = tokenDecimals || (await tokenContract.methods.decimals().call())\n if (decimals === '0') {\n decimals = 18\n }\n\n const amountFormatted = new BigNumber(amount).div(\n new BigNumber(10).exponentiatedBy(decimals)\n )\n\n BigNumber.config({ EXPONENTIAL_AT: 50 })\n return amountFormatted.toString()\n } catch (e) {\n LoggerInstance.error(`ERROR: FAILED TO CALL DECIMALS(), USING 18' : ${e.message}`)\n }\n}\n\nexport async function amountToUnits(\n web3: Web3,\n token: string,\n amount: string,\n tokenDecimals?: number\n): Promise<string> {\n try {\n const tokenContract = new web3.eth.Contract(minAbi, token)\n let decimals = tokenDecimals || (await tokenContract.methods.decimals().call())\n if (decimals === '0') {\n decimals = 18\n }\n BigNumber.config({ EXPONENTIAL_AT: 50 })\n\n const amountFormatted = new BigNumber(amount).times(\n new BigNumber(10).exponentiatedBy(decimals)\n )\n return amountFormatted.toFixed(0)\n } catch (e) {\n LoggerInstance.error(`ERROR: FAILED TO CALL DECIMALS(), USING 18', ${e.message}`)\n }\n}\n\n/**\n * Estimates the gas used when a function would be executed on chain\n * @param {string} from account that calls the function\n * @param {Function} functionToEstimateGas function that we need to estimate the gas\n * @param {...any[]} args arguments of the function\n * @return {Promise<number>} gas cost of the function\n */\nexport async function estimateGas(\n from: string,\n functionToEstimateGas: Function,\n ...args: any[]\n): Promise<any> {\n let estimatedGas = GASLIMIT_DEFAULT\n try {\n estimatedGas = await functionToEstimateGas.apply(null, args).estimateGas(\n {\n from: from\n },\n (err, estGas) => (err ? GASLIMIT_DEFAULT : estGas)\n )\n } catch (e) {\n LoggerInstance.error(`ERROR: Estimate gas failed!`, e)\n }\n return estimatedGas\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 headResponse = await fetch(url, { method: 'HEAD' })\n const contentHeader = headResponse.headers.get('content-disposition')\n const fileName = contentHeader.split('=')[1]\n const xhr = new XMLHttpRequest()\n xhr.responseType = 'blob'\n xhr.open('GET', url)\n xhr.onload = () => {\n const blobURL = window.URL.createObjectURL(xhr.response)\n const a = document.createElement('a')\n a.href = blobURL\n a.setAttribute('download', fileName)\n document.body.appendChild(a)\n a.click()\n a.remove()\n window.URL.revokeObjectURL(blobURL)\n }\n xhr.send(null)\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://v4.aquarius.oceanprotocol.com',\n nodeUri: 'http://127.0.0.1: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 providerUri: 'http://172.15.0.4:8030'\n },\n {\n ...configHelperNetworksBase,\n chainId: 3,\n network: 'ropsten',\n nodeUri: 'https://ropsten.infura.io/v3',\n providerUri: 'https://v4.provider.ropsten.oceanprotocol.com',\n subgraphUri: 'https://v4.subgraph.ropsten.oceanprotocol.com',\n explorerUri: 'https://ropsten.etherscan.io',\n gasFeeMultiplier: 1.1\n },\n {\n ...configHelperNetworksBase,\n chainId: 4,\n network: 'rinkeby',\n nodeUri: 'https://rinkeby.infura.io/v3',\n providerUri: 'https://v4.provider.rinkeby.oceanprotocol.com',\n subgraphUri: 'https://v4.subgraph.rinkeby.oceanprotocol.com',\n explorerUri: 'https://rinkeby.etherscan.io',\n gasFeeMultiplier: 1.1\n },\n {\n ...configHelperNetworksBase,\n chainId: 1,\n network: 'mainnet',\n nodeUri: 'https://mainnet.infura.io/v3',\n providerUri: 'https://v4.provider.mainnet.oceanprotocol.com',\n subgraphUri: 'https://v4.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://v4.provider.polygon.oceanprotocol.com',\n subgraphUri: 'https://v4.subgraph.polygon.oceanprotocol.com',\n explorerUri: 'https://polygonscan.com',\n oceanTokenSymbol: 'mOCEAN'\n },\n {\n ...configHelperNetworksBase,\n chainId: 1287,\n network: 'moonbase',\n nodeUri: 'https://rpc.api.moonbase.moonbeam.network',\n providerUri: 'https://v4.provider.moonbase.oceanprotocol.com',\n subgraphUri: 'https://v4.subgraph.moonbase.oceanprotocol.com',\n explorerUri: 'https://moonbase.moonscan.io/',\n gasFeeMultiplier: 1.1\n },\n {\n ...configHelperNetworksBase,\n chainId: 2021000,\n network: 'gaiaxtestnet',\n nodeUri: 'https://rpc.gaiaxtestnet.oceanprotocol.com',\n providerUri: 'https://v4.provider.gaiaxtestnet.oceanprotocol.com',\n subgraphUri: 'https://v4.subgraph.gaiaxtestnet.oceanprotocol.com',\n explorerUri: 'https://blockscout.gaiaxtestnet.oceanprotocol.com'\n },\n {\n ...configHelperNetworksBase,\n chainId: 80001,\n network: 'mumbai',\n nodeUri: 'https://polygon-mumbai.infura.io/v3',\n providerUri: 'https://v4.provider.mumbai.oceanprotocol.com',\n subgraphUri: 'https://v4.subgraph.mumbai.oceanprotocol.com',\n explorerUri: 'https://mumbai.polygonscan.com',\n gasFeeMultiplier: 1.1\n },\n {\n ...configHelperNetworksBase,\n chainId: 56,\n network: 'bsc',\n nodeUri: 'https://bsc-dataseed.binance.org',\n providerUri: 'https://v4.provider.bsc.oceanprotocol.com',\n subgraphUri: 'https://v4.subgraph.bsc.oceanprotocol.com',\n explorerUri: 'https://bscscan.com/',\n gasFeeMultiplier: 1.05\n },\n {\n ...configHelperNetworksBase,\n chainId: 246,\n network: 'energyweb',\n nodeUri: 'https://rpc.energyweb.org',\n providerUri: 'https://v4.provider.energyweb.oceanprotocol.com',\n subgraphUri: 'https://v4.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://v4.provider.moonriver.oceanprotocol.com',\n subgraphUri: 'https://v4.subgraph.moonriver.oceanprotocol.com',\n explorerUri: 'https://moonriver.moonscan.io/',\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 Decimal from 'decimal.js'\nimport { Contract } from 'web3-eth-contract'\nimport {\n amountToUnits,\n estimateGas,\n getFairGasPrice,\n unitsToAmount\n} from './ContractUtils'\nimport { minAbi } from './minAbi'\nimport LoggerInstance from './Logger'\nimport { TransactionReceipt } from 'web3-core'\nimport Web3 from 'web3'\nimport BigNumber from 'bignumber.js'\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 return estimateGas(account, tokenContract.methods.approve, spender, amount)\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 amount of ERC20 tokens (always expressed as wei)\n * @param {boolean} force if true, will overwrite any previous allowence. Else, will check if allowence is enough and will not send a transaction if it's not needed\n * @param {number} tokenDecimals optional number of decimals of the token\n */\nexport async function approve(\n web3: Web3,\n account: string,\n tokenAddress: string,\n spender: string,\n amount: string,\n force = false,\n tokenDecimals?: number\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, tokenDecimals)\n const estGas = await estimateGas(\n account,\n tokenContract.methods.approve,\n spender,\n amountFormatted\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 `ERROR: Failed to approve spender to spend tokens : ${e.message}`\n )\n }\n return result\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 amount of ERC20 tokens (always expressed as wei)\n * @param {boolean} force if true, will overwrite any previous allowence. Else, will check if allowence is enough and will not send a transaction if it's not needed\n */\nexport async function approveWei(\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 allowanceWei(web3, tokenAddress, account, spender)\n if (new BigNumber(currentAllowence).gt(new BigNumber(amount))) {\n return currentAllowence\n }\n }\n let result = null\n const estGas = await estimateGas(\n account,\n tokenContract.methods.approve,\n spender,\n amount\n )\n\n try {\n result = await tokenContract.methods.approve(spender, amount).send({\n from: account,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(web3, null)\n })\n } catch (e) {\n LoggerInstance.error(\n `ERROR: Failed to approve spender to spend tokens : ${e.message}`\n )\n }\n return result\n}\n/**\n * Estimate gas cost for transfer function\n * @param {String} account\n * @param {String} tokenAddress\n * @param {String} recipient\n * @param {String} amount\n * @param {String} force\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\nexport async function estTransfer(\n web3: Web3,\n account: string,\n tokenAddress: string,\n recipient: string,\n amount: string,\n contractInstance?: Contract\n): Promise<number> {\n const tokenContract = contractInstance || new web3.eth.Contract(minAbi, tokenAddress)\n\n return estimateGas(account, tokenContract.methods.transfer, recipient, amount)\n}\n\n/**\n * Moves amount tokens from the caller’s account to recipient.\n * @param {String} account\n * @param {String} tokenAddress\n * @param {String} recipient\n * @param {String} amount amount of ERC20 tokens (not 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 transfer(\n web3: Web3,\n account: string,\n tokenAddress: string,\n recipient: string,\n amount: string\n): Promise<TransactionReceipt | string> {\n const tokenContract = new web3.eth.Contract(minAbi, tokenAddress)\n\n let result = null\n const amountFormatted = await amountToUnits(web3, tokenAddress, amount)\n const estGas = await estimateGas(\n account,\n tokenContract.methods.transfer,\n recipient,\n amountFormatted\n )\n\n try {\n result = await tokenContract.methods.transfer(recipient, amountFormatted).send({\n from: account,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(web3, null)\n })\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to transfer tokens : ${e.message}`)\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 * @param {number} tokenDecimals optional number of decimals of the token\n */\nexport async function allowance(\n web3: Web3,\n tokenAddress: string,\n account: string,\n spender: string,\n tokenDecimals?: number\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, tokenDecimals)\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 allowanceWei(\n web3: Web3,\n tokenAddress: string,\n account: string,\n spender: string,\n tokenDecimals?: number\n): Promise<string> {\n const tokenContract = new web3.eth.Contract(minAbi, tokenAddress)\n return await tokenContract.methods.allowance(account, spender).call()\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 * @param {number} tokenDecimals optional number of decimals of the token\n */\nexport async function balance(\n web3: Web3,\n tokenAddress: string,\n account: string,\n tokenDecimals?: number\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, tokenDecimals)\n}\n\n/**\n * Get decimals for any erc20\n * @param {Web3} web3\n * @param {String} tokenAdress\n * @return {Promise<number>} Number of decimals of the token\n */\nexport async function decimals(web3: Web3, tokenAddress: string): Promise<number> {\n const tokenContract = new web3.eth.Contract(minAbi, tokenAddress)\n return await tokenContract.methods.decimals().call()\n}\n","/**\n * Simple blocking sleep function\n */\nexport async function sleep(ms: number) {\n return new Promise((resolve) => {\n setTimeout(resolve, ms)\n })\n}\n","import Decimal from 'decimal.js'\nimport { Pool } from '..'\n\nexport function calcMaxExactOut(balance: string): Decimal {\n return new Decimal(balance).div(2)\n}\n\nexport function calcMaxExactIn(balance: string): Decimal {\n return new Decimal(balance).div(2)\n}\nexport async function getMaxSwapExactOut(\n poolInstance: Pool,\n poolAddress: string,\n tokenAddress: string\n): Promise<Decimal> {\n const reserve = await poolInstance.getReserve(poolAddress, tokenAddress)\n return calcMaxExactOut(reserve)\n}\n\nexport async function getMaxSwapExactIn(\n poolInstance: Pool,\n poolAddress: string,\n tokenAddress: string\n): Promise<Decimal> {\n const reserve = await poolInstance.getReserve(poolAddress, tokenAddress)\n return calcMaxExactIn(reserve)\n}\n\nexport async function getMaxAddLiquidity(\n poolInstance: Pool,\n poolAddress: string,\n tokenAddress: string\n): Promise<Decimal> {\n const reserve = await poolInstance.getReserve(poolAddress, tokenAddress)\n\n return calcMaxExactIn(reserve)\n}\n\nexport async function getMaxRemoveLiquidity(\n poolInstance: Pool,\n poolAddress: string,\n tokenAddress: string\n): Promise<Decimal> {\n const reserve = await poolInstance.getReserve(poolAddress, tokenAddress)\n\n return calcMaxExactIn(reserve)\n}\n","import { LoggerInstance, sleep } from '../utils'\nimport { Asset, DDO, ValidateMetadata } from '../@types/'\nimport fetch from 'cross-fetch'\n\nexport interface SearchQuery {\n from?: number\n size?: number\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n query: any\n sort?: { [jsonPath: string]: string }\n aggs?: any\n}\n\nexport class Aquarius {\n public aquariusURL\n /**\n * Instantiate Aquarius\n * @param {String} aquariusURL\n */\n constructor(aquariusURL: string) {\n this.aquariusURL = aquariusURL\n }\n\n /** Resolves a DID\n * @param {string} did\n * @param {AbortSignal} signal abort signal\n * @return {Promise<Asset>} Asset\n */\n public async resolve(did: string, signal?: AbortSignal): Promise<Asset> {\n const path = this.aquariusURL + '/api/aquarius/assets/ddo/' + did\n try {\n const response = await fetch(path, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json'\n },\n signal: signal\n })\n\n if (response.ok) {\n const raw = await response.json()\n return raw as Asset\n } else {\n throw new Error('HTTP request failed with status ' + response.status)\n }\n } catch (e) {\n LoggerInstance.error(e)\n throw new Error('HTTP request failed')\n }\n }\n\n /**\n * Blocks until Aqua will cache the did (or the update for that did) or timeouts\n \n * @param {string} did DID of the asset.\n * @param {string} txid used when the did exists and we expect an update with that txid.\n * @param {AbortSignal} signal abort signal\n * @return {Promise<DDO>} DDO of the asset.\n */\n public async waitForAqua(\n did: string,\n txid?: string,\n signal?: AbortSignal\n ): Promise<Asset> {\n let tries = 0\n do {\n try {\n const path = this.aquariusURL + '/api/aquarius/assets/ddo/' + did\n const response = await fetch(path, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json'\n },\n signal: signal\n })\n if (response.ok) {\n const ddo = await response.json()\n if (txid) {\n // check tx\n if (ddo.event && ddo.event.txid === txid) return ddo as Asset\n } else return ddo as Asset\n }\n } catch (e) {\n // do nothing\n }\n await sleep(1500)\n tries++\n } while (tries < 100)\n return null\n }\n\n /**\n * Validate DDO content\n * @param {DDO} ddo DID Descriptor Object content.\n * @param {AbortSignal} signal abort signal\n * @return {Promise<ValidateMetadata>}.\n */\n public async validate(ddo: DDO, signal?: AbortSignal): Promise<ValidateMetadata> {\n const status: ValidateMetadata = {\n valid: false\n }\n let jsonResponse\n try {\n const path = this.aquariusURL + '/api/aquarius/assets/ddo/validate'\n\n const response = await fetch(path, {\n method: 'POST',\n body: JSON.stringify(ddo),\n headers: {\n 'Content-Type': 'application/octet-stream'\n },\n signal: signal\n })\n\n jsonResponse = await response.json()\n if (response.status === 200) {\n status.valid = true\n status.hash = jsonResponse.hash\n status.proof = {\n validatorAddress: jsonResponse.publicKey,\n r: jsonResponse.r[0],\n s: jsonResponse.s[0],\n v: jsonResponse.v\n }\n } else {\n status.errors = jsonResponse\n LoggerInstance.error('validate Metadata failed:', response.status, status.errors)\n }\n } catch (error) {\n LoggerInstance.error('Error validating metadata: ', error)\n }\n return status\n }\n\n /**\n * Search over the DDOs using a query.\n * @param {string} did DID of the asset\n * @param {AbortSignal} signal abort signal\n * @return {Promise<QueryResult>}\n */\n public async getAssetMetadata(did: string, signal?: AbortSignal): Promise<any> {\n const path = this.aquariusURL + '/api/aquarius/assets/metadata/' + did\n\n try {\n const response = await fetch(path, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json'\n },\n signal: signal\n })\n\n if (response.ok) {\n return response.json()\n } else {\n throw new Error(\n 'getAssetMetadata failed: ' + response.status + response.statusText\n )\n }\n } catch (error) {\n LoggerInstance.error('Error getting metadata: ', error)\n throw new Error('Error getting metadata: ' + error)\n }\n }\n\n /**\n * Search over the DDOs using a query.\n * @param {SearchQuery} query Query to filter the DDOs.\n * @param {AbortSignal} signal abort signal\n * @return {Promise<QueryResult>}\n */\n public async querySearch(query: SearchQuery, signal?: AbortSignal): Promise<any> {\n const path = this.aquariusURL + '/api/aquarius/assets/query'\n\n try {\n const response = await fetch(path, {\n method: 'POST',\n body: JSON.stringify(query),\n headers: {\n 'Content-Type': 'application/json'\n },\n signal: signal\n })\n\n if (response.ok) {\n return response.json()\n } else {\n throw new Error('querySearch failed: ' + response.status + response.statusText)\n }\n } catch (error) {\n LoggerInstance.error('Error querying metadata: ', error)\n throw new Error('Error querying metadata: ' + error)\n }\n }\n}\n\nexport default Aquarius\n","import Web3 from 'web3'\nimport { AbiItem } from 'web3-utils/types'\nimport { TransactionReceipt } from 'web3-core'\nimport { Contract } from 'web3-eth-contract'\nimport {\n getFairGasPrice,\n setContractDefaults,\n unitsToAmount,\n amountToUnits,\n LoggerInstance,\n estimateGas,\n ConfigHelper\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 {\n CurrentFees,\n TokenInOutMarket,\n AmountsInMaxFee,\n AmountsOutMaxFee,\n PoolPriceAndFees\n} from '../../@types'\nimport { Config } from '../../models'\nimport {\n getMaxAddLiquidity,\n getMaxRemoveLiquidity,\n getMaxSwapExactIn,\n getMaxSwapExactOut\n} from '../../utils/PoolHelpers'\nimport Decimal from 'decimal.js'\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 private config: Config\n\n constructor(\n web3: Web3,\n network?: string | number,\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.config = config || new ConfigHelper().getConfig(network || 'unknown')\n }\n\n async amountToUnits(\n token: string,\n amount: string,\n tokenDecimals?: number\n ): Promise<string> {\n return amountToUnits(this.web3, token, amount, tokenDecimals)\n }\n\n async unitsToAmount(\n token: string,\n amount: string,\n tokenDecimals?: number\n ): Promise<string> {\n return unitsToAmount(this.web3, token, amount, tokenDecimals)\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 LoggerInstance.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 return estimateGas(account, poolContract.methods.setSwapFee, fee)\n }\n\n /**\n * Allows controller to change the swapFee\n * @param {String} account\n * @param {String} poolAddress\n * @param {String} fee swap fee (1e17 = 10 % , 1e16 = 1% , 1e15 = 0.1%, 1e14 = 0.01%)\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 estimateGas(account, pool.methods.setSwapFee, 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 LoggerInstance.error(`ERROR: Failed to set pool swap fee: ${e.message}`)\n }\n return result\n }\n\n /**\n * Returns number of tokens bounded to 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 LoggerInstance.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 LoggerInstance.error(\n `ERROR: Failed to get total supply of pool shares: ${e.message}`\n )\n }\n return amount\n }\n\n /**\n * Get tokens composing this poo\n * Returns tokens bounded to pool, before the pool is finalizedl\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 LoggerInstance.error(\n `ERROR: Failed to get tokens composing this pool: ${e.message}`\n )\n }\n return result\n }\n\n /**\n * Get the final tokens composing this pool\n * Returns tokens bounded to pool, after the pool was finalized\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 LoggerInstance.error(\n `ERROR: Failed to get the final tokens composing this pool ${e.message}`\n )\n }\n return result\n }\n\n /**\n * Returns the current controller address (ssBot)\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 LoggerInstance.error(`ERROR: Failed to get pool controller address: ${e.message}`)\n }\n return result\n }\n\n /**\n * Returns the current baseToken address of the 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 LoggerInstance.error(`ERROR: Failed to get baseToken address: ${e.message}`)\n }\n return result\n }\n\n /**\n * Returns the current datatoken address\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 LoggerInstance.error(`ERROR: Failed to get datatoken address: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get getMarketFee\n * @param {String} poolAddress\n * @return {String}\n */\n async getMarketFee(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.getMarketFee().call()\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to get getMarketFee: ${e.message}`)\n }\n return this.web3.utils.fromWei(result).toString()\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 LoggerInstance.error(\n `ERROR: Failed to get marketFeeCollector address: ${e.message}`\n )\n }\n return result\n }\n\n /**\n * Get if a token is bounded to a pool\n * Returns true if token is bound\n * @param {String} poolAddress\n * @param {String} token Address of the token to be checked\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 LoggerInstance.error(`ERROR: Failed to check whether a token \\\n bounded to a pool. ${e.message}`)\n }\n return result\n }\n\n /**\n * Returns the current token reserve amount\n * @param {String} poolAddress\n * @param {String} token Address of the token to be checked\n * @param {number} tokenDecimals optional number of decimals of the token\n * @return {String}\n */\n async getReserve(\n poolAddress: string,\n token: string,\n tokenDecimals?: number\n ): 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, tokenDecimals)\n } catch (e) {\n LoggerInstance.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 * Returns true if 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 LoggerInstance.error(\n `ERROR: Failed to check whether pool is finalized: ${e.message}`\n )\n }\n return result\n }\n\n /**\n * Returns the current Liquidity Providers swap 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 LoggerInstance.error(`ERROR: Failed to get pool fee: ${e.message}`)\n }\n return fee\n }\n\n /**\n * Returns normalized weight of a token.\n * The combined normalized weights of all tokens will sum up to 1.\n * (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 token to be checked\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 LoggerInstance.error(\n `ERROR: Failed to get normalized weight of a token: ${e.message}`\n )\n }\n return weight\n }\n\n /**\n * Returns denormalized weight of a token\n * @param {String} poolAddress\n * @param {String} token token to be checked\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 LoggerInstance.error(\n `ERROR: Failed to get denormalized weight of a token in pool ${e.message}`\n )\n }\n return weight\n }\n\n /**\n * getTotalDenormalizedWeight\n * Returns total denormalized weught of the 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 LoggerInstance.error(\n `ERROR: Failed to get total denormalized weight in pool ${e.message}`\n )\n }\n return weight\n }\n\n /**\n * Returns the current fee of publishingMarket\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 * @param {number} tokenDecimals optional number of decimals of the token\n * @return {String}\n */\n async getMarketFees(\n poolAddress: string,\n token: string,\n tokenDecimals?: number\n ): 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, tokenDecimals)\n } catch (e) {\n LoggerInstance.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.getCurrentOPCFees().call()\n return currentMarketFees\n } catch (e) {\n LoggerInstance.error(\n `ERROR: Failed to get community fees for a token: ${e.message}`\n )\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 getCurrentOPCFees(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.getCurrentOPCFees().call()\n return currentMarketFees\n } catch (e) {\n LoggerInstance.error(\n `ERROR: Failed to get community fees for a token: ${e.message}`\n )\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 * @param {number} tokenDecimals optional number of decimals of the token\n * @return {String}\n */\n async getCommunityFees(\n poolAddress: string,\n token: string,\n tokenDecimals?: number\n ): 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, tokenDecimals)\n } catch (e) {\n LoggerInstance.error(\n `ERROR: Failed to get community fees for a token: ${e.message}`\n )\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 estCollectOPC(\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 return estimateGas(address, poolContract.methods.collectOPC)\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 collectOPC(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 estimateGas(address, pool.methods.collectOPC)\n\n try {\n result = await pool.methods.collectOPC().send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n LoggerInstance.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 return estimateGas(address, poolContract.methods.collectMarketFee)\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 estimateGas(address, pool.methods.collectMarketFee)\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 LoggerInstance.error(`ERROR: Failed to swap exact amount in : ${e.message}`)\n }\n return result\n }\n\n /**\n * Estimate gas cost for updatePublishMarketFee\n * @param {String} address\n * @param {String} poolAddress\n * @param {String} newPublishMarketAddress new market address\n * @param {String} newPublishMarketSwapFee new market swap fee\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estUpdatePublishMarketFee(\n address: string,\n poolAddress: string,\n newPublishMarketAddress: string,\n newPublishMarketSwapFee: 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 return estimateGas(\n address,\n poolContract.methods.updatePublishMarketFee,\n newPublishMarketAddress,\n this.web3.utils.toWei(newPublishMarketSwapFee)\n )\n }\n\n /**\n * updatePublishMarketFee - sets a new newPublishMarketAddress and new newPublishMarketSwapFee- can be called only by the marketFeeCollector\n * @param {String} address\n * @param {String} poolAddress\n * @param {String} newPublishMarketAddress new market fee collector address\n * @param {String} newPublishMarketSwapFee fee recieved by the publisher market when a dt is swaped from a pool, percent\n * @return {TransactionReceipt}\n */\n async updatePublishMarketFee(\n address: string,\n poolAddress: string,\n newPublishMarketAddress: string,\n newPublishMarketSwapFee: 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\n const estGas = await estimateGas(\n address,\n pool.methods.updatePublishMarketFee,\n newPublishMarketAddress,\n this.web3.utils.toWei(newPublishMarketSwapFee)\n )\n try {\n result = await pool.methods\n .updatePublishMarketFee(\n newPublishMarketAddress,\n this.web3.utils.toWei(newPublishMarketSwapFee)\n )\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to updatePublishMarketFee : ${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 object contianing addresses like tokenIn, tokenOut, consumeMarketFeeAddress\n * @param {AmountsInMaxFee} amountsInOutMaxFee object contianing tokenAmountIn, minAmountOut, maxPrice, consumeMarketSwapFee\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 tokenAmountIn = await this.amountToUnits(\n tokenInOutMarket.tokenIn,\n amountsInOutMaxFee.tokenAmountIn,\n tokenInOutMarket.tokenInDecimals\n )\n\n const minAmountOut = await this.amountToUnits(\n tokenInOutMarket.tokenOut,\n amountsInOutMaxFee.minAmountOut,\n tokenInOutMarket.tokenOutDecimals\n )\n\n const maxPrice = amountsInOutMaxFee.maxPrice\n ? this.amountToUnits(\n await this.getBaseToken(poolAddress),\n amountsInOutMaxFee.maxPrice\n )\n : MaxUint256\n\n return estimateGas(\n address,\n poolContract.methods.swapExactAmountIn,\n [\n tokenInOutMarket.tokenIn,\n tokenInOutMarket.tokenOut,\n tokenInOutMarket.marketFeeAddress\n ],\n [\n tokenAmountIn,\n minAmountOut,\n maxPrice,\n this.web3.utils.toWei(amountsInOutMaxFee.swapMarketFee)\n ]\n )\n }\n\n /**\n * Swaps an exact amount of tokensIn to get a mimum amount of tokenOut\n * 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 object contianing addresses like tokenIn, tokenOut, consumeMarketFeeAddress\n * @param {AmountsInMaxFee} amountsInOutMaxFee object contianing tokenAmountIn, minAmountOut, maxPrice, consumeMarketSwapFee\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 const maxSwap = await getMaxSwapExactIn(this, poolAddress, tokenInOutMarket.tokenIn)\n if (new Decimal(amountsInOutMaxFee.tokenAmountIn).greaterThan(maxSwap)) {\n throw new Error(`tokenAmountIn is greater than ${maxSwap.toString()}`)\n }\n\n const tokenAmountIn = await this.amountToUnits(\n tokenInOutMarket.tokenIn,\n amountsInOutMaxFee.tokenAmountIn,\n tokenInOutMarket.tokenInDecimals\n )\n\n const minAmountOut = await this.amountToUnits(\n tokenInOutMarket.tokenOut,\n amountsInOutMaxFee.minAmountOut,\n tokenInOutMarket.tokenOutDecimals\n )\n\n const maxPrice = amountsInOutMaxFee.maxPrice\n ? await this.amountToUnits(\n await this.getBaseToken(poolAddress),\n amountsInOutMaxFee.maxPrice\n )\n : MaxUint256\n\n const estGas = await estimateGas(\n address,\n pool.methods.swapExactAmountIn,\n [\n tokenInOutMarket.tokenIn,\n tokenInOutMarket.tokenOut,\n tokenInOutMarket.marketFeeAddress\n ],\n [\n tokenAmountIn,\n minAmountOut,\n maxPrice,\n this.web3.utils.toWei(amountsInOutMaxFee.swapMarketFee)\n ]\n )\n\n let result = null\n try {\n result = await pool.methods\n .swapExactAmountIn(\n [\n tokenInOutMarket.tokenIn,\n tokenInOutMarket.tokenOut,\n tokenInOutMarket.marketFeeAddress\n ],\n [\n tokenAmountIn,\n 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 LoggerInstance.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 maxAmountIn = await this.amountToUnits(\n tokenInOutMarket.tokenIn,\n amountsInOutMaxFee.maxAmountIn,\n tokenInOutMarket.tokenInDecimals\n )\n\n const tokenAmountOut = await this.amountToUnits(\n tokenInOutMarket.tokenOut,\n amountsInOutMaxFee.tokenAmountOut,\n tokenInOutMarket.tokenOutDecimals\n )\n\n const maxPrice = amountsInOutMaxFee.maxPrice\n ? await this.amountToUnits(\n await this.getBaseToken(poolAddress),\n amountsInOutMaxFee.maxPrice\n )\n : MaxUint256\n\n return estimateGas(\n address,\n poolContract.methods.swapExactAmountOut,\n [\n tokenInOutMarket.tokenIn,\n tokenInOutMarket.tokenOut,\n tokenInOutMarket.marketFeeAddress\n ],\n [\n maxAmountIn,\n tokenAmountOut,\n maxPrice,\n this.web3.utils.toWei(amountsInOutMaxFee.swapMarketFee)\n ]\n )\n }\n\n /**\n * Swaps a maximum maxAmountIn of tokensIn to get an exact amount of tokenOut\n * @param {String} account\n * @param {String} poolAddress\n * @param {TokenInOutMarket} tokenInOutMarket Object containing addresses like tokenIn, tokenOut, consumeMarketFeeAddress\n * @param {AmountsOutMaxFee} amountsInOutMaxFee Object containging maxAmountIn,tokenAmountOut,maxPrice, consumeMarketSwapFee]\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 const maxSwap = await getMaxSwapExactOut(this, poolAddress, tokenInOutMarket.tokenOut)\n if (new Decimal(amountsInOutMaxFee.tokenAmountOut).greaterThan(maxSwap)) {\n throw new Error(`tokenAmountOut is greater than ${maxSwap.toString()}`)\n }\n\n const maxAmountIn = await this.amountToUnits(\n tokenInOutMarket.tokenIn,\n amountsInOutMaxFee.maxAmountIn,\n tokenInOutMarket.tokenInDecimals\n )\n\n const tokenAmountOut = await this.amountToUnits(\n tokenInOutMarket.tokenOut,\n amountsInOutMaxFee.tokenAmountOut,\n tokenInOutMarket.tokenOutDecimals\n )\n\n const maxPrice = amountsInOutMaxFee.maxPrice\n ? this.amountToUnits(\n await this.getBaseToken(poolAddress),\n amountsInOutMaxFee.maxPrice\n )\n : MaxUint256\n\n const estGas = await estimateGas(\n account,\n pool.methods.swapExactAmountOut,\n [\n tokenInOutMarket.tokenIn,\n tokenInOutMarket.tokenOut,\n tokenInOutMarket.marketFeeAddress\n ],\n [\n maxAmountIn,\n tokenAmountOut,\n maxPrice,\n this.web3.utils.toWei(amountsInOutMaxFee.swapMarketFee)\n ]\n )\n\n try {\n result = await pool.methods\n .swapExactAmountOut(\n [\n tokenInOutMarket.tokenIn,\n tokenInOutMarket.tokenOut,\n tokenInOutMarket.marketFeeAddress\n ],\n [\n maxAmountIn,\n 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 LoggerInstance.error(`ERROR: Failed to swap exact amount out: ${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 exact number of base tokens to spend\n * @param {String} minPoolAmountOut minimum of pool shares expectex\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estJoinswapExternAmountIn(\n address: string,\n poolAddress: 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 return estimateGas(\n address,\n poolContract.methods.joinswapExternAmountIn,\n tokenAmountIn,\n minPoolAmountOut\n )\n }\n\n /**\n * Single side add liquidity to the pool,\n * expecting a minPoolAmountOut of shares for spending tokenAmountIn basetokens.\n * Pay tokenAmountIn of baseToken to join the pool, getting poolAmountOut of the pool shares.\n * @param {String} account\n * @param {String} poolAddress\n * @param {String} tokenAmountIn exact number of base tokens to spend\n * @param {String} minPoolAmountOut minimum of pool shares expectex\n * @param {number} tokenInDecimals optional number of decimals of the token\n * @return {TransactionReceipt}\n */\n async joinswapExternAmountIn(\n account: string,\n poolAddress: string,\n tokenAmountIn: string,\n minPoolAmountOut: string,\n tokenInDecimals?: number\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 const tokenIn = await this.getBaseToken(poolAddress)\n const maxSwap = await getMaxAddLiquidity(this, poolAddress, tokenIn)\n if (new Decimal(tokenAmountIn).greaterThan(maxSwap)) {\n throw new Error(`tokenAmountOut is greater than ${maxSwap.toString()}`)\n }\n\n const amountInFormatted = await this.amountToUnits(\n tokenIn,\n tokenAmountIn,\n tokenInDecimals\n )\n const estGas = await estimateGas(\n account,\n pool.methods.joinswapExternAmountIn,\n amountInFormatted,\n this.web3.utils.toWei(minPoolAmountOut)\n )\n\n try {\n result = await pool.methods\n .joinswapExternAmountIn(\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 LoggerInstance.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 exitswapPoolAmountIn\n * @param {String} address\n * @param {String} poolAddress\n * @param {String} poolAmountIn exact number of pool shares to spend\n * @param {String} minTokenAmountOut minimum amount of basetokens expected\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estExitswapPoolAmountIn(\n address: string,\n poolAddress: 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 return estimateGas(\n address,\n poolContract.methods.exitswapPoolAmountIn,\n poolAmountIn,\n minTokenAmountOut\n )\n }\n\n /**\n * Single side remove liquidity from the pool,\n * expecting a minAmountOut of basetokens for spending poolAmountIn pool shares\n * Pay poolAmountIn pool shares into the pool, getting minTokenAmountOut of the baseToken\n * @param {String} account\n * @param {String} poolAddress\n * @param {String} poolAmountIn exact number of pool shares to spend\n * @param {String} minTokenAmountOut minimum amount of basetokens expected\n * @param {number} poolDecimals optional number of decimals of the poool\n * @return {TransactionReceipt}\n */\n async exitswapPoolAmountIn(\n account: string,\n poolAddress: string,\n poolAmountIn: string,\n minTokenAmountOut: string,\n poolDecimals?: number\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 const tokenOut = await this.getBaseToken(poolAddress)\n\n const tokenAmountOut = await this.calcSingleOutGivenPoolIn(\n poolAddress,\n tokenOut,\n poolAmountIn\n )\n\n const maxSwap = await getMaxRemoveLiquidity(this, poolAddress, tokenOut)\n if (new Decimal(tokenAmountOut).greaterThan(maxSwap)) {\n throw new Error(`tokenAmountOut is greater than ${maxSwap.toString()}`)\n }\n\n const minTokenOutFormatted = await this.amountToUnits(\n await this.getBaseToken(poolAddress),\n minTokenAmountOut,\n poolDecimals\n )\n const estGas = await estimateGas(\n account,\n pool.methods.exitswapPoolAmountIn,\n this.web3.utils.toWei(poolAmountIn),\n minTokenOutFormatted\n )\n\n try {\n result = await pool.methods\n .exitswapPoolAmountIn(this.web3.utils.toWei(poolAmountIn), minTokenOutFormatted)\n .send({\n from: account,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to pay pool shares into the pool: ${e.message}`)\n }\n return result\n }\n\n /**\n * Return the spot price of swapping tokenIn to tokenOut\n * @param {String} poolAddress\n * @param {String} tokenIn in token\n * @param {String} tokenOut out token\n * @param {String} swapMarketFe consume market swap fee\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 LoggerInstance.error(`ERROR: FAILED TO CALL DECIMALS(), USING 18 ${e.message}`)\n }\n try {\n decimalsTokenOut = await tokenOutContract.methods.decimals().call()\n } catch (e) {\n LoggerInstance.error(`ERROR: FAILED TO CALL DECIMALS(), USING 18 ${e.message}`)\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 LoggerInstance.error(\n 'ERROR: Failed to get spot price of swapping tokenIn to tokenOut'\n )\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 /**\n * How many tokensIn do you need in order to get exact tokenAmountOut.\n * Returns: tokenAmountIn, swapFee, opcFee , consumeMarketSwapFee, publishMarketSwapFee\n * Returns: tokenAmountIn, LPFee, opcFee , publishMarketSwapFee, consumeMarketSwapFee\n * @param tokenIn token to be swaped\n * @param tokenOut token to get\n * @param tokenAmountOut exact amount of tokenOut\n * @param swapMarketFee consume market swap fee\n * @param {number} tokenInDecimals optional number of decimals of the token to be swaped\n * @param {number} tokenOutDecimals optional number of decimals of the token to get\n */\n public async getAmountInExactOut(\n poolAddress: string,\n tokenIn: string,\n tokenOut: string,\n tokenAmountOut: string,\n swapMarketFee: string,\n tokenInDecimals?: number,\n tokenOutDecimals?: number\n ): Promise<PoolPriceAndFees> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n\n const maxSwap = await getMaxSwapExactOut(this, poolAddress, tokenOut)\n\n if (new Decimal(tokenAmountOut).greaterThan(maxSwap)) {\n throw new Error(`tokenAmountOut is greater than ${maxSwap.toString()}`)\n }\n\n const amountOutFormatted = await this.amountToUnits(\n tokenOut,\n tokenAmountOut,\n tokenOutDecimals\n )\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 = {\n tokenAmount: await this.unitsToAmount(\n tokenOut,\n result.tokenAmountIn,\n tokenInDecimals\n ),\n liquidityProviderSwapFeeAmount: await this.unitsToAmount(\n tokenIn,\n result.lpFeeAmount,\n tokenInDecimals\n ),\n oceanFeeAmount: await this.unitsToAmount(\n tokenIn,\n result.oceanFeeAmount,\n tokenInDecimals\n ),\n publishMarketSwapFeeAmount: await this.unitsToAmount(\n tokenIn,\n result.publishMarketSwapFeeAmount,\n tokenInDecimals\n ),\n consumeMarketSwapFeeAmount: await this.unitsToAmount(\n tokenIn,\n result.consumeMarketSwapFeeAmount,\n tokenInDecimals\n )\n }\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to calcInGivenOut ${e.message}`)\n }\n return amount\n }\n\n /**\n * How many tokensOut you will get for a exact tokenAmountIn\n * Returns: tokenAmountOut, LPFee, opcFee , publishMarketSwapFee, consumeMarketSwapFee\n * @param tokenIn token to be swaped\n * @param tokenOut token to get\n * @param tokenAmountIn exact amount of tokenIn\n * @param swapMarketFee\n * @param {number} tokenInDecimals optional number of decimals of the token to be swaped\n * @param {number} tokenOutDecimals optional number of decimals of the token to get\n */\n public async getAmountOutExactIn(\n poolAddress: string,\n tokenIn: string,\n tokenOut: string,\n tokenAmountIn: string,\n swapMarketFee: string,\n tokenInDecimals?: number,\n tokenOutDecimals?: number\n ): Promise<PoolPriceAndFees> {\n const pool = setContractDefaults(\n new this.web3.eth.Contract(this.poolAbi, poolAddress),\n this.config\n )\n\n const maxSwap = await getMaxSwapExactIn(this, poolAddress, tokenIn)\n if (new Decimal(tokenAmountIn).greaterThan(maxSwap)) {\n throw new Error(`tokenAmountIn is greater than ${maxSwap.toString()}`)\n }\n\n const amountInFormatted = await this.amountToUnits(\n tokenIn,\n tokenAmountIn,\n tokenInDecimals\n )\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 = {\n tokenAmount: await this.unitsToAmount(\n tokenOut,\n result.tokenAmountOut,\n tokenOutDecimals\n ),\n liquidityProviderSwapFeeAmount: await this.unitsToAmount(\n tokenIn,\n result.lpFeeAmount,\n tokenInDecimals\n ),\n oceanFeeAmount: await this.unitsToAmount(\n tokenIn,\n result.oceanFeeAmount,\n tokenInDecimals\n ),\n publishMarketSwapFeeAmount: await this.unitsToAmount(\n tokenIn,\n result.publishMarketSwapFeeAmount,\n tokenInDecimals\n ),\n consumeMarketSwapFeeAmount: await this.unitsToAmount(\n tokenIn,\n result.consumeMarketSwapFeeAmount,\n tokenInDecimals\n )\n }\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to calcOutGivenIn ${e.message}`)\n }\n return amount\n }\n\n /**\n * Returns number of poolshares obtain by staking exact tokenAmountIn tokens\n * @param tokenIn tokenIn\n * @param tokenAmountIn exact number of tokens staked\n * @param {number} poolDecimals optional number of decimals of the poool\n * @param {number} tokenInDecimals optional number of decimals of the token\n */\n public async calcPoolOutGivenSingleIn(\n poolAddress: string,\n tokenIn: string,\n tokenAmountIn: string,\n poolDecimals?: number,\n tokenInDecimals?: number\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 this.amountToUnits(tokenIn, tokenAmountIn, tokenInDecimals)\n )\n .call()\n\n amount = await this.unitsToAmount(poolAddress, result, poolDecimals)\n } catch (e) {\n LoggerInstance.error(\n `ERROR: Failed to calculate PoolOutGivenSingleIn : ${e.message}`\n )\n }\n return amount\n }\n\n /**\n * Returns number of tokens to be staked to the pool in order to get an exact number of poolshares\n * @param tokenIn tokenIn\n * @param poolAmountOut expected amount of pool shares\n * @param {number} poolDecimals optional number of decimals of the pool\n * @param {number} tokenInDecimals optional number of decimals of the token\n */\n public async calcSingleInGivenPoolOut(\n poolAddress: string,\n tokenIn: string,\n poolAmountOut: string,\n poolDecimals?: number,\n tokenInDecimals?: number\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(\n poolAddress,\n poolAmountOut,\n poolDecimals\n )\n try {\n const result = await pool.methods\n .calcSingleInPoolOut(tokenIn, amountFormatted)\n .call()\n\n amount = await this.unitsToAmount(tokenIn, result, tokenInDecimals)\n } catch (e) {\n LoggerInstance.error(\n `ERROR: Failed to calculate SingleInGivenPoolOut : ${e.message}`\n )\n }\n return amount\n }\n\n /**\n * Returns expected amount of tokenOut for removing exact poolAmountIn pool shares from the pool\n * @param tokenOut tokenOut\n * @param poolAmountIn amount of shares spent\n * @param {number} poolDecimals optional number of decimals of the pool\n * @param {number} tokenOutDecimals optional number of decimals of the token\n */\n public async calcSingleOutGivenPoolIn(\n poolAddress: string,\n tokenOut: string,\n poolAmountIn: string,\n poolDecimals?: number,\n tokenOutDecimals?: number\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, poolDecimals)\n )\n .call()\n amount = await this.unitsToAmount(tokenOut, result, tokenOutDecimals)\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to calculate SingleOutGivenPoolIn : ${e}`)\n }\n return amount\n }\n\n /**\n * Returns number of poolshares needed to withdraw exact tokenAmountOut tokens\n * @param tokenOut tokenOut\n * @param tokenAmountOut expected amount of tokensOut\n * @param {number} poolDecimals optional number of decimals of the pool\n * @param {number} tokenOutDecimals optional number of decimals of the token\n */\n public async calcPoolInGivenSingleOut(\n poolAddress: string,\n tokenOut: string,\n tokenAmountOut: string,\n poolDecimals?: number,\n tokenOutDecimals?: number\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 this.amountToUnits(tokenOut, tokenAmountOut, tokenOutDecimals)\n )\n .call()\n\n amount = await this.unitsToAmount(poolAddress, result, poolDecimals)\n } catch (e) {\n LoggerInstance.error(\n `ERROR: Failed to calculate PoolInGivenSingleOut : ${e.message}`\n )\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(\n ({ name, type }) => type === 'event' && name === 'LOG_SWAP'\n )\n const topic = this.web3.eth.abi.encodeEventSignature(eventdata)\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(\n ({ name, type }) => type === 'event' && name === 'LOG_JOIN'\n )\n const topic = this.web3.eth.abi.encodeEventSignature(eventdata)\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(\n ({ name, type }) => type === 'event' && name === 'LOG_EXIT'\n )\n const topic = this.web3.eth.abi.encodeEventSignature(eventdata)\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 setContractDefaults,\n estimateGas,\n ConfigHelper\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 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 network?: string | number,\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 || new ConfigHelper().getConfig(network || 'unknown')\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 return estimateGas(\n address,\n this.dispenserContract.methods.create,\n dtAddress,\n this.web3.utils.toWei(maxTokens),\n this.web3.utils.toWei(maxBalance),\n address,\n allowedSwapper\n )\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 estimateGas(\n address,\n this.dispenserContract.methods.create,\n dtAddress,\n this.web3.utils.toWei(maxTokens),\n this.web3.utils.toWei(maxBalance),\n address,\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 return estimateGas(\n address,\n this.dispenserContract.methods.activate,\n dtAddress,\n this.web3.utils.toWei(maxTokens),\n this.web3.utils.toWei(maxBalance)\n )\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 estimateGas(\n address,\n this.dispenserContract.methods.activate,\n dtAddress,\n this.web3.utils.toWei(maxTokens),\n this.web3.utils.toWei(maxBalance)\n )\n\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 return estimateGas(address, this.dispenserContract.methods.deactivate, dtAddress)\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 estimateGas(\n address,\n this.dispenserContract.methods.deactivate,\n dtAddress\n )\n\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 return estimateGas(\n address,\n this.dispenserContract.methods.setAllowedSwapper,\n dtAddress,\n newAllowedSwapper\n )\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 estimateGas(\n address,\n this.dispenserContract.methods.setAllowedSwapper,\n dtAddress,\n newAllowedSwapper\n )\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 return estimateGas(\n address,\n this.dispenserContract.methods.dispense,\n dtAddress,\n this.web3.utils.toWei(amount),\n destination\n )\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 estimateGas(\n address,\n this.dispenserContract.methods.dispense,\n dtAddress,\n this.web3.utils.toWei(amount),\n destination\n )\n\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 return estimateGas(address, this.dispenserContract.methods.ownerWithdraw, dtAddress)\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 estimateGas(\n address,\n this.dispenserContract.methods.ownerWithdraw,\n dtAddress\n )\n\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 { 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 setContractDefaults,\n amountToUnits,\n unitsToAmount,\n estimateGas,\n ZERO_ADDRESS,\n ConfigHelper\n} from '../../utils'\nimport { Config } from '../../models/index.js'\nimport { PriceAndFees } from '../..'\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 opcFee: 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\n/* eslint-disable no-unused-vars */\nexport enum FixedRateCreateProgressStep {\n CreatingExchange,\n ApprovingDatatoken\n}\n/* eslint-enable no-unused-vars */\n\nexport class FixedRateExchange {\n /** Ocean related functions */\n public oceanAddress: string = null\n public fixedRateAddress: string\n public fixedRateExchangeAbi: AbiItem | AbiItem[]\n public web3: Web3\n public fixedRateContract: 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 network?: string | number,\n fixedRateExchangeAbi: AbiItem | AbiItem[] = null,\n oceanAddress: string = null,\n config?: Config\n ) {\n this.web3 = web3\n this.config = config || new ConfigHelper().getConfig(network || 'unknown')\n this.fixedRateExchangeAbi =\n fixedRateExchangeAbi || (defaultFixedRateExchangeAbi.abi as AbiItem[])\n this.oceanAddress = oceanAddress\n this.fixedRateAddress = fixedRateAddress\n this.fixedRateContract = setContractDefaults(\n new this.web3.eth.Contract(this.fixedRateExchangeAbi, this.fixedRateAddress),\n this.config\n )\n }\n\n async amountToUnits(\n token: string,\n amount: string,\n tokenDecimals: number\n ): Promise<string> {\n return amountToUnits(this.web3, token, amount, tokenDecimals)\n }\n\n async unitsToAmount(\n token: string,\n amount: string,\n tokenDecimals: number\n ): Promise<string> {\n return unitsToAmount(this.web3, token, amount, tokenDecimals)\n }\n\n /**\n * Creates unique exchange identifier.\n * @param {String} baseToken baseToken contract address\n * @param {String} datatoken Datatoken contract address\n * @return {Promise<string>} exchangeId\n */\n public async generateExchangeId(baseToken: string, datatoken: string): Promise<string> {\n const exchangeId = await this.fixedRateContract.methods\n .generateExchangeId(baseToken, datatoken)\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 {String} consumeMarketAddress consumeMarketAddress\n * @param {String} consumeMarketFee fee recieved by the consume market when a dt is bought from a fixed rate exchange, percent\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 consumeMarketAddress: string,\n consumeMarketFee: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n\n return estimateGas(\n account,\n fixedRate.methods.buyDT,\n datatokenAddress,\n dtAmount,\n maxBaseTokenAmount,\n consumeMarketAddress,\n consumeMarketFee\n )\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 * @param {String} consumeMarketAddress consumeMarketAddress\n * @param {String} consumeMarketFee consumeMarketFee in fraction\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async buyDT(\n address: string,\n exchangeId: string,\n datatokenAmount: string,\n maxBaseTokenAmount: string,\n consumeMarketAddress: string = ZERO_ADDRESS,\n consumeMarketFee: string = '0'\n ): Promise<TransactionReceipt> {\n const exchange = await this.getExchange(exchangeId)\n const consumeMarketFeeFormatted = this.web3.utils.toWei(consumeMarketFee)\n const dtAmountFormatted = await this.amountToUnits(\n exchange.datatoken,\n datatokenAmount,\n +exchange.dtDecimals\n )\n const maxBtFormatted = await this.amountToUnits(\n exchange.baseToken,\n maxBaseTokenAmount,\n +exchange.btDecimals\n )\n\n const estGas = await estimateGas(\n address,\n this.fixedRateContract.methods.buyDT,\n exchangeId,\n dtAmountFormatted,\n maxBtFormatted,\n consumeMarketAddress,\n consumeMarketFeeFormatted\n )\n try {\n const trxReceipt = await this.fixedRateContract.methods\n .buyDT(\n exchangeId,\n dtAmountFormatted,\n maxBtFormatted,\n consumeMarketAddress,\n consumeMarketFeeFormatted\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 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 {String} consumeMarketAddress consumeMarketAddress\n * @param {String} consumeMarketFee consumeMarketFee\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 consumeMarketAddress: string,\n consumeMarketFee: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n\n return estimateGas(\n account,\n fixedRate.methods.sellDT,\n datatokenAddress,\n dtAmount,\n maxBaseTokenAmount,\n consumeMarketAddress,\n consumeMarketFee\n )\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 * @param {String} consumeMarketAddress consumeMarketAddress\n * @param {String} consumeMarketFee consumeMarketFee in fraction\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async sellDT(\n address: string,\n exchangeId: string,\n datatokenAmount: string,\n minBaseTokenAmount: string,\n consumeMarketAddress: string = ZERO_ADDRESS,\n consumeMarketFee: string = '0'\n ): Promise<TransactionReceipt> {\n const exchange = await this.getExchange(exchangeId)\n const consumeMarketFeeFormatted = this.web3.utils.toWei(consumeMarketFee)\n const dtAmountFormatted = await this.amountToUnits(\n exchange.datatoken,\n datatokenAmount,\n +exchange.dtDecimals\n )\n const minBtFormatted = await this.amountToUnits(\n exchange.baseToken,\n minBaseTokenAmount,\n +exchange.btDecimals\n )\n const estGas = await estimateGas(\n address,\n this.fixedRateContract.methods.sellDT,\n exchangeId,\n dtAmountFormatted,\n minBtFormatted,\n consumeMarketAddress,\n consumeMarketFeeFormatted\n )\n try {\n const trxReceipt = await this.fixedRateContract.methods\n .sellDT(\n exchangeId,\n dtAmountFormatted,\n minBtFormatted,\n consumeMarketAddress,\n consumeMarketFeeFormatted\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 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.fixedRateContract.methods\n .getNumberOfExchanges()\n .call()\n return numExchanges\n }\n\n /**\n * Estimate gas cost for setRate\n * @param {String} account\n * @param {String} exchangeId ExchangeId\n * @param {String} 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\n return estimateGas(\n account,\n fixedRate.methods.setRate,\n exchangeId,\n await this.web3.utils.toWei(newRate)\n )\n }\n\n /**\n * Set new rate\n * @param {String} exchangeId ExchangeId\n * @param {String} 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 estimateGas(\n address,\n this.fixedRateContract.methods.setRate,\n exchangeId,\n this.web3.utils.toWei(newRate)\n )\n const trxReceipt = await this.fixedRateContract.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\n return estimateGas(\n account,\n fixedRate.methods.setAllowedSwapper,\n exchangeId,\n newAllowedSwapper\n )\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 estimateGas(\n address,\n this.fixedRateContract.methods.setAllowedSwapper,\n exchangeId,\n newAllowedSwapper\n )\n const trxReceipt = await this.fixedRateContract.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\n return estimateGas(account, fixedRate.methods.toggleExchangeState, exchangeId)\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 estGas = await estimateGas(\n address,\n this.fixedRateContract.methods.toggleExchangeState,\n exchangeId\n )\n const trxReceipt = await this.fixedRateContract.methods\n .toggleExchangeState(exchangeId)\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 estDeactivate(\n account: string,\n exchangeId: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n\n return estimateGas(account, fixedRate.methods.toggleExchangeState, exchangeId)\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 estimateGas(\n address,\n this.fixedRateContract.methods.toggleExchangeState,\n exchangeId\n )\n\n const trxReceipt = await this.fixedRateContract.methods\n .toggleExchangeState(exchangeId)\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 * 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.fixedRateContract.methods.getRate(exchangeId).call()\n const rate = await this.web3.utils.fromWei(weiRate)\n return rate\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.fixedRateContract.methods.getDTSupply(exchangeId).call()\n const exchange = await this.getExchange(exchangeId)\n return await this.unitsToAmount(exchange.datatoken, dtSupply, +exchange.dtDecimals)\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.fixedRateContract.methods.getBTSupply(exchangeId).call()\n const exchange = await this.getExchange(exchangeId)\n return await this.unitsToAmount(exchange.baseToken, btSupply, +exchange.btDecimals)\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.fixedRateContract.methods.getAllowedSwapper(exchangeId).call()\n }\n\n /**\n * calcBaseInGivenOutDT - Calculates how many base tokens are needed to get specified amount of datatokens\n * @param {String} exchangeId ExchangeId\n * @param {string} datatokenAmount Amount of datatokens user wants to buy\n * @param {String} consumeMarketFee consumeMarketFee in fraction\n * @return {Promise<PriceAndFees>} how many base tokens are needed and fees\n */\n public async calcBaseInGivenOutDT(\n exchangeId: string,\n datatokenAmount: string,\n consumeMarketFee: string = '0'\n ): Promise<PriceAndFees> {\n const fixedRateExchange = await this.getExchange(exchangeId)\n const result = await this.fixedRateContract.methods\n .calcBaseInGivenOutDT(\n exchangeId,\n await this.amountToUnits(\n fixedRateExchange.datatoken,\n datatokenAmount,\n +fixedRateExchange.dtDecimals\n ),\n this.web3.utils.toWei(consumeMarketFee)\n )\n .call()\n\n const priceAndFees = {\n baseTokenAmount: await this.unitsToAmount(\n fixedRateExchange.baseToken,\n result.baseTokenAmount,\n +fixedRateExchange.btDecimals\n ),\n marketFeeAmount: await this.unitsToAmount(\n fixedRateExchange.baseToken,\n result.marketFeeAmount,\n +fixedRateExchange.btDecimals\n ),\n oceanFeeAmount: await this.unitsToAmount(\n fixedRateExchange.baseToken,\n result.oceanFeeAmount,\n +fixedRateExchange.btDecimals\n ),\n consumeMarketFeeAmount: await this.unitsToAmount(\n fixedRateExchange.baseToken,\n result.consumeMarketFeeAmount,\n +fixedRateExchange.btDecimals\n )\n } as PriceAndFees\n return priceAndFees\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 * @param {String} consumeMarketFee consumeMarketFee in fraction\n * @return {Promise<string>} Amount of baseTokens user will receive\n */\n public async getAmountBTOut(\n exchangeId: string,\n datatokenAmount: string,\n consumeMarketFee: string = '0'\n ): Promise<string> {\n const exchange = await this.getExchange(exchangeId)\n const result = await this.fixedRateContract.methods\n .calcBaseOutGivenInDT(\n exchangeId,\n await this.amountToUnits(\n exchange.datatoken,\n datatokenAmount,\n +exchange.dtDecimals\n ),\n this.web3.utils.toWei(consumeMarketFee)\n )\n .call()\n\n return await this.unitsToAmount(exchange.baseToken, result[0], +exchange.btDecimals)\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.fixedRateContract.methods\n .getExchange(exchangeId)\n .call()\n result.dtDecimals = result.dtDecimals.toString()\n result.btDecimals = result.btDecimals.toString()\n result.dtBalance = await this.unitsToAmount(\n result.datatoken,\n result.dtBalance,\n +result.dtDecimals\n )\n result.btBalance = await this.unitsToAmount(\n result.baseToken,\n result.btBalance,\n +result.btDecimals\n )\n result.dtSupply = await this.unitsToAmount(\n result.datatoken,\n result.dtSupply,\n +result.dtDecimals\n )\n result.btSupply = await this.unitsToAmount(\n result.baseToken,\n result.btSupply,\n +result.btDecimals\n )\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.fixedRateContract.methods\n .getFeesInfo(exchangeId)\n .call()\n result.opcFee = this.web3.utils.fromWei(result.opcFee.toString())\n result.marketFee = this.web3.utils.fromWei(result.marketFee.toString())\n\n const exchange = await this.getExchange(exchangeId)\n result.marketFeeAvailable = await this.unitsToAmount(\n exchange.baseToken,\n result.marketFeeAvailable,\n +exchange.btDecimals\n )\n result.oceanFeeAvailable = await this.unitsToAmount(\n exchange.baseToken,\n result.oceanFeeAvailable,\n +exchange.btDecimals\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.fixedRateContract.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.fixedRateContract.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\n return estimateGas(account, fixedRate.methods.toggleMintState, exchangeId, true)\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\n const estGas = await estimateGas(\n address,\n this.fixedRateContract.methods.toggleMintState,\n exchangeId,\n true\n )\n const trxReceipt = await this.fixedRateContract.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\n return estimateGas(\n account,\n fixedRate.methods.toggleMintState(exchangeId, false),\n exchangeId,\n false\n )\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 estimateGas(\n address,\n this.fixedRateContract.methods.toggleMintState,\n exchangeId,\n false\n )\n\n const trxReceipt = await this.fixedRateContract.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 {String} amount amount to be collected\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estCollectBT(\n account: string,\n exchangeId: string,\n amount: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const fixedrate: FixedPriceExchange = await this.fixedRateContract.methods\n .getExchange(exchangeId)\n .call()\n const amountWei = await this.amountToUnits(\n fixedrate.baseToken,\n amount,\n +fixedrate.btDecimals\n )\n return estimateGas(account, fixedRate.methods.collectBT, exchangeId, amountWei)\n }\n\n /**\n * Collect BaseTokens in the contract (anyone can call this, funds are sent to erc20.paymentCollector)\n * @param {String} address User address\n * @param {String} exchangeId ExchangeId\n * @param {String} amount amount to be collected\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async collectBT(\n address: string,\n exchangeId: string,\n amount: string\n ): Promise<TransactionReceipt> {\n const exchange = await this.getExchange(exchangeId)\n if (!exchange) return null\n\n const fixedrate: FixedPriceExchange = await this.fixedRateContract.methods\n .getExchange(exchangeId)\n .call()\n const amountWei = await this.amountToUnits(\n fixedrate.baseToken,\n amount,\n +fixedrate.btDecimals\n )\n\n const estGas = await estimateGas(\n address,\n this.fixedRateContract.methods.collectBT,\n exchangeId,\n amountWei\n )\n\n const trxReceipt = await this.fixedRateContract.methods\n .collectBT(exchangeId, amountWei)\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 collecDT\n * @param {String} account\n * @param {String} exchangeId ExchangeId\n * @param {String} amount amount to be collected\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estCollectDT(\n account: string,\n exchangeId: string,\n amount: string,\n contractInstance?: Contract\n ): Promise<number> {\n const fixedRate = contractInstance || this.fixedRateContract\n const fixedrate: FixedPriceExchange = await this.fixedRateContract.methods\n .getExchange(exchangeId)\n .call()\n\n const amountWei = await this.amountToUnits(\n fixedrate.datatoken,\n amount,\n +fixedrate.dtDecimals\n )\n return estimateGas(account, fixedRate.methods.collectDT, exchangeId, amountWei)\n }\n\n /**\n * Collect datatokens in the contract (anyone can call this, funds are sent to erc20.paymentCollector)\n * @param {String} address User address\n * @param {String} exchangeId ExchangeId\n * @param {String} amount amount to be collected\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async collectDT(\n address: string,\n exchangeId: string,\n amount: string\n ): Promise<TransactionReceipt> {\n const exchange = await this.getExchange(exchangeId)\n if (!exchange) return null\n\n const fixedrate: FixedPriceExchange = await this.fixedRateContract.methods\n .getExchange(exchangeId)\n .call()\n const amountWei = await this.amountToUnits(\n fixedrate.datatoken,\n amount,\n +fixedrate.dtDecimals\n )\n\n const estGas = await estimateGas(\n address,\n this.fixedRateContract.methods.collectDT,\n exchangeId,\n amountWei\n )\n\n const trxReceipt = await this.fixedRateContract.methods\n .collectDT(exchangeId, amountWei)\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 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\n return estimateGas(account, fixedRate.methods.collectMarketFee, exchangeId)\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 estimateGas(\n address,\n this.fixedRateContract.methods.collectMarketFee,\n exchangeId\n )\n const trxReceipt = await this.fixedRateContract.methods\n .collectMarketFee(exchangeId)\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 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\n return estimateGas(account, fixedRate.methods.collectMarketFee, exchangeId)\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 estimateGas(\n address,\n this.fixedRateContract.methods.collectOceanFee,\n exchangeId\n )\n const trxReceipt = await this.fixedRateContract.methods\n .collectOceanFee(exchangeId)\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 * Get OPF Collector of fixed rate contract\n * @return {String}\n */\n async getOPCCollector(): Promise<string> {\n let result = null\n try {\n result = await this.fixedRateContract.methods.opcCollector().call()\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to get OPC 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.fixedRateContract.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\n return estimateGas(\n account,\n fixedRate.methods.updateMarketFee,\n exchangeId,\n newMarketFee\n )\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 estimateGas(\n address,\n this.fixedRateContract.methods.updateMarketFee,\n exchangeId,\n this.web3.utils.toWei(newMarketFee)\n )\n const trxReceipt = await this.fixedRateContract.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\n return estimateGas(\n account,\n fixedRate.methods.updateMarketFeeCollector,\n exchangeId,\n newMarketFeeCollector\n )\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 estimateGas(\n address,\n this.fixedRateContract.methods.updateMarketFeeCollector,\n exchangeId,\n newMarketFeeCollector\n )\n const trxReceipt = await this.fixedRateContract.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/types'\nimport { TransactionReceipt } from 'web3-core'\nimport { Contract } from 'web3-eth-contract'\nimport {\n LoggerInstance,\n getFairGasPrice,\n ConfigHelper,\n estimateGas,\n unitsToAmount\n} from '../../utils'\nimport SideStakingTemplate from '@oceanprotocol/contracts/artifacts/contracts/pools/ssContracts/SideStaking.sol/SideStaking.json'\nimport { Config } from '../../models'\n\nexport class SideStaking {\n public ssAbi: AbiItem | AbiItem[]\n public web3: Web3\n public config: Config\n\n constructor(\n web3: Web3,\n network?: string | number,\n ssAbi: AbiItem | AbiItem[] = null,\n config?: Config\n ) {\n if (ssAbi) this.ssAbi = ssAbi\n else this.ssAbi = SideStakingTemplate.abi as AbiItem[]\n this.web3 = web3\n this.config = config || new ConfigHelper().getConfig(network || 'unknown')\n }\n\n async unitsToAmount(\n token: string,\n amount: string,\n tokenDecimals?: number\n ): Promise<string> {\n return unitsToAmount(this.web3, token, amount, tokenDecimals)\n }\n\n /**\n * Get (total vesting amount + token released from the contract when adding liquidity)\n * @param {String} ssAddress side staking contract address\n * @param {String} datatokenAddress datatoken address\n * @return {String}\n */\n async getDatatokenCirculatingSupply(\n ssAddress: string,\n datatokenAddress: string\n ): Promise<string> {\n const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)\n let result = null\n try {\n result = await sideStaking.methods\n .getDatatokenCirculatingSupply(datatokenAddress)\n .call()\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)\n }\n return result.toString()\n }\n\n /**\n * Get actual dts in circulation (vested token withdrawn from the contract +\n token released from the contract when adding liquidity)\n * @param {String} ssAddress side staking contract address\n * @param {String} datatokenAddress datatoken address\n * @return {String}\n */\n async getDatatokenCurrentCirculatingSupply(\n ssAddress: string,\n datatokenAddress: string\n ): Promise<string> {\n try {\n const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)\n let result = null\n result = await sideStaking.methods\n .getDatatokenCurrentCirculatingSupply(datatokenAddress)\n .call()\n return result.toString()\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)\n }\n }\n\n /**\n * Get Publisher address\n * @param {String} ssAddress side staking contract address\n * @param {String} datatokenAddress datatoken address\n * @return {String}\n */\n async getPublisherAddress(\n ssAddress: string,\n datatokenAddress: string\n ): Promise<string> {\n const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)\n let result = null\n try {\n result = await sideStaking.methods.getPublisherAddress(datatokenAddress).call()\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get\n * @param {String} ssAddress side staking contract address\n * @param {String} datatokenAddress datatokenAddress\n * @return {String}\n */\n async getBaseToken(ssAddress: string, datatokenAddress: string): Promise<string> {\n const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)\n let result = null\n try {\n result = await sideStaking.methods.getBaseTokenAddress(datatokenAddress).call()\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get Pool Address\n * @param {String} ssAddress side staking contract address\n * @param {String} datatokenAddress datatokenAddress\n * @return {String}\n */\n async getPoolAddress(ssAddress: string, datatokenAddress: string): Promise<string> {\n const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)\n let result = null\n try {\n result = await sideStaking.methods.getPoolAddress(datatokenAddress).call()\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get baseToken balance in the contract\n * @param {String} ssAddress side staking contract address\n * @param {String} datatokenAddress datatokenAddress\n * @return {String}\n */\n async getBaseTokenBalance(\n ssAddress: string,\n datatokenAddress: string\n ): Promise<string> {\n const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)\n let result = null\n try {\n result = await sideStaking.methods.getBaseTokenBalance(datatokenAddress).call()\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get dt balance in the staking contract available for being added as liquidity\n * @param {String} ssAddress side staking contract address\n * @param {String} datatokenAddress datatokenAddress\n * @param {number} tokenDecimals optional number of decimals of the token\n * @return {String}\n */\n async getDatatokenBalance(\n ssAddress: string,\n datatokenAddress: string,\n tokenDecimals?: number\n ): Promise<string> {\n const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)\n let result = null\n try {\n result = await sideStaking.methods.getDatatokenBalance(datatokenAddress).call()\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)\n }\n result = await this.unitsToAmount(datatokenAddress, result, tokenDecimals)\n return result\n }\n\n /**\n * Get block when vesting ends\n * @param {String} ssAddress side staking contract address\n * @param {String} datatokenAddress datatokenAddress\n * @return {String} end block for vesting amount\n */\n async getvestingEndBlock(ssAddress: string, datatokenAddress: string): Promise<string> {\n const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)\n let result = null\n try {\n result = await sideStaking.methods.getvestingEndBlock(datatokenAddress).call()\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get total amount vesting\n * @param {String} ssAddress side staking contract address\n * @param {String} datatokenAddress datatokenAddress\n * @param {number} tokenDecimals optional number of decimals of the token\n * @return {String}\n */\n async getvestingAmount(\n ssAddress: string,\n datatokenAddress: string,\n tokenDecimals?: number\n ): Promise<string> {\n const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)\n let result = null\n try {\n result = await sideStaking.methods.getvestingAmount(datatokenAddress).call()\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)\n }\n result = await this.unitsToAmount(datatokenAddress, result, tokenDecimals)\n return result\n }\n\n /**\n * Get last block publisher got some vested tokens\n * @param {String} ssAddress side staking contract address\n * @param {String} datatokenAddress datatokenAddress\n * @return {String}\n */\n async getvestingLastBlock(\n ssAddress: string,\n datatokenAddress: string\n ): Promise<string> {\n const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)\n let result = null\n try {\n result = await sideStaking.methods.getvestingLastBlock(datatokenAddress).call()\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)\n }\n return result\n }\n\n /**\n * Get how much has been taken from the vesting amount\n * @param {String} ssAddress side staking contract address\n * @param {String} datatokenAddress datatokenAddress\n * @param {number} tokenDecimals optional number of decimals of the token\n * @return {String}\n */\n async getvestingAmountSoFar(\n ssAddress: string,\n datatokenAddress: string,\n tokenDecimals?: number\n ): Promise<string> {\n const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)\n let result = null\n try {\n result = await sideStaking.methods.getvestingAmountSoFar(datatokenAddress).call()\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)\n }\n result = await this.unitsToAmount(datatokenAddress, result, tokenDecimals)\n return result\n }\n\n /**\n * Estimate gas cost for getVesting\n * @param {String} account\n * @param {String} ssAddress side staking contract address\n * @param {String} datatokenAddress datatokenAddress\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estGetVesting(\n account: string,\n ssAddress: string,\n datatokenAddress: string,\n contractInstance?: Contract\n ): Promise<number> {\n const sideStaking =\n contractInstance || new this.web3.eth.Contract(this.ssAbi as AbiItem[], ssAddress)\n\n return estimateGas(account, sideStaking.methods.getVesting, datatokenAddress)\n }\n\n /** Send vested tokens available to the publisher address, can be called by anyone\n *\n * @param {String} account\n * @param {String} ssAddress side staking contract address\n * @param {String} datatokenAddress datatokenAddress\n * @return {TransactionReceipt}\n */\n async getVesting(\n account: string,\n ssAddress: string,\n datatokenAddress: string\n ): Promise<TransactionReceipt> {\n const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)\n let result = null\n\n const estGas = await estimateGas(\n account,\n sideStaking.methods.getVesting,\n datatokenAddress\n )\n\n try {\n result = await sideStaking.methods.getVesting(datatokenAddress).send({\n from: account,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n LoggerInstance.error('ERROR: Failed to join swap pool amount out')\n }\n return result\n }\n\n /**\n * Estimate gas cost for getVesting\n * @param {String} account\n * @param {String} ssAddress side staking contract address\n * @param {String} datatokenAddress datatokenAddress\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<number>}\n */\n public async estSetPoolSwapFee(\n account: string,\n ssAddress: string,\n datatokenAddress: string,\n poolAddress: string,\n swapFee: number,\n contractInstance?: Contract\n ): Promise<number> {\n const sideStaking =\n contractInstance || new this.web3.eth.Contract(this.ssAbi as AbiItem[], ssAddress)\n\n return estimateGas(\n account,\n sideStaking.methods.setPoolSwapFee,\n datatokenAddress,\n poolAddress,\n swapFee\n )\n }\n\n /** Send vested tokens available to the publisher address, can be called by anyone\n *\n * @param {String} account\n * @param {String} ssAddress side staking contract address\n * @param {String} datatokenAddress datatokenAddress\n * @return {TransactionReceipt}\n */\n async setPoolSwapFee(\n account: string,\n ssAddress: string,\n datatokenAddress: string,\n poolAddress: string,\n swapFee: number\n ): Promise<TransactionReceipt> {\n const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)\n let result = null\n\n const estGas = await estimateGas(\n account,\n sideStaking.methods.setPoolSwapFee,\n datatokenAddress,\n poolAddress,\n swapFee\n )\n\n try {\n result = await sideStaking.methods\n .setPoolSwapFee(datatokenAddress, poolAddress, swapFee)\n .send({\n from: account,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n } catch (e) {\n LoggerInstance.error('ERROR: Failed to join swap pool amount out')\n }\n return result\n }\n\n /**\n * Get Router address set in side staking contract\n * @param {String} ssAddress side staking contract address\n * @return {String}\n */\n async getRouter(ssAddress: string): Promise<string> {\n const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)\n let result = null\n try {\n result = await sideStaking.methods.router().call()\n } catch (e) {\n LoggerInstance.error(`ERROR: Failed to get Router address: ${e.message}`)\n }\n return result\n }\n}\n","import { Contract } from 'web3-eth-contract'\nimport Web3 from 'web3'\nimport { TransactionReceipt } from 'web3-core'\nimport { AbiItem } from 'web3-utils'\nimport defaultRouter from '@oceanprotocol/contracts/artifacts/contracts/pools/FactoryRouter.sol/FactoryRouter.json'\nimport { getFairGasPrice, setContractDefaults, ConfigHelper, estimateGas } from '../utils'\nimport { Operation } from '../@types/Router'\nimport { Config } from '../models/index.js'\n\n/**\n * Provides an interface for FactoryRouter contract\n */\nexport class Router {\n public routerAddress: string\n public RouterAbi: AbiItem | AbiItem[]\n public web3: Web3\n public config: Config\n public router: Contract\n\n /**\n * Instantiate Router.\n * @param {String} routerAddress\n * @param {AbiItem | AbiItem[]} Router\n * @param {Web3} web3\n */\n constructor(\n routerAddress: string,\n web3: Web3,\n network?: string | number,\n RouterAbi?: AbiItem | AbiItem[],\n config?: Config\n ) {\n this.routerAddress = routerAddress\n this.RouterAbi = RouterAbi || (defaultRouter.abi as AbiItem[])\n this.web3 = web3\n this.config = config || new ConfigHelper().getConfig(network || 'unknown')\n this.router = setContractDefaults(\n new this.web3.eth.Contract(this.RouterAbi, this.routerAddress),\n this.config\n )\n }\n\n /**\n * Estimate gas cost for buyDTBatch method\n * @param {String} address\n * @param {Operation} operations Operations objects array\n * @return {Promise<TransactionReceipt>} Transaction receipt\n */\n public async estGasBuyDTBatch(address: string, operations: Operation[]): Promise<any> {\n return estimateGas(address, this.router.methods.buyDTBatch, operations)\n }\n\n /**\n * BuyDTBatch\n * @param {String} address\n * @param {Operation} operations Operations objects array\n * @return {Promise<TransactionReceipt>} Transaction receipt\n */\n public async buyDTBatch(\n address: string,\n operations: Operation[]\n ): Promise<TransactionReceipt> {\n const estGas = await estimateGas(address, this.router.methods.buyDTBatch, operations)\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.router.methods.buyDTBatch(operations).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n\n return trxReceipt\n }\n\n /** Check if a token is on approved tokens list, if true opfFee is lower in pools with that token/DT\n * @return {Promise<boolean>} true if is on the list.\n */\n public async isApprovedToken(address: string): Promise<boolean> {\n return await this.router.methods.isApprovedToken(address).call()\n }\n\n /** Check if an address is a side staking contract.\n * @return {Promise<boolean>} true if is a SS contract\n */\n public async isSideStaking(address: string): Promise<boolean> {\n return await this.router.methods.isSSContract(address).call()\n }\n\n /** Check if an address is a Fixed Rate contract.\n * @return {Promise<boolean>} true if is a Fixed Rate contract\n */\n public async isFixedPrice(address: string): Promise<boolean> {\n return await this.router.methods.isFixedRateContract(address).call()\n }\n\n /** Get Router Owner\n * @return {Promise<string>} Router Owner address\n */\n public async getOwner(): Promise<string> {\n return await this.router.methods.routerOwner().call()\n }\n\n /** Get NFT Factory address\n * @return {Promise<string>} NFT Factory address\n */\n public async getNFTFactory(): Promise<string> {\n return await this.router.methods.factory().call()\n }\n\n /** Check if an address is a pool template contract.\n * @return {Promise<boolean>} true if is a Template\n */\n public async isPoolTemplate(address: string): Promise<boolean> {\n return await this.router.methods.isPoolTemplate(address).call()\n }\n\n /**\n * Estimate gas cost for addApprovedToken\n * @param {String} address\n * @param {String} tokenAddress token address we want to add\n * @param {Contract} routerContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasAddApprovedToken(\n address: string,\n tokenAddress: string,\n contractInstance?: Contract\n ): Promise<any> {\n return estimateGas(address, this.router.methods.addApprovedToken, tokenAddress)\n }\n\n /**\n * Add a new token to oceanTokens list, pools with baseToken in this list have NO opf Fee\n * @param {String} address caller address\n * @param {String} tokenAddress token address to add\n * @return {Promise<TransactionReceipt>}\n */\n public async addApprovedToken(\n address: string,\n tokenAddress: string\n ): Promise<TransactionReceipt> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Router Owner`)\n }\n\n const estGas = await estimateGas(\n address,\n this.router.methods.addApprovedToken,\n tokenAddress\n )\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.router.methods.addApprovedToken(tokenAddress).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 removeApprovedToken\n * @param {String} address caller address\n * @param {String} tokenAddress token address we want to add\n * @param {Contract} routerContract optional contract instance\n * @return {Promise<any>}\n */\n public async estGasRemoveApprovedToken(\n address: string,\n tokenAddress: string,\n contractInstance?: Contract\n ): Promise<any> {\n return estimateGas(address, this.router.methods.removeApprovedToken, tokenAddress)\n }\n\n /**\n * Remove a token from oceanTokens list, pools without baseToken in this list have a opf Fee\n * @param {String} address\n * @param {String} tokenAddress address to remove\n * @return {Promise<TransactionReceipt>}\n */\n public async removeApprovedToken(\n address: string,\n tokenAddress: string\n ): Promise<TransactionReceipt> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Router Owner`)\n }\n\n const estGas = await estimateGas(\n address,\n this.router.methods.removeApprovedToken,\n tokenAddress\n )\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.router.methods.removeApprovedToken(tokenAddress).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 addSSContract method\n * @param {String} address\n * @param {String} tokenAddress contract address to add\n * @return {Promise<TransactionReceipt>}\n */\n public async estGasAddSSContract(address: string, tokenAddress: string): Promise<any> {\n return estimateGas(address, this.router.methods.addSSContract, tokenAddress)\n }\n\n /**\n * Add a new contract to ssContract list, after is added, can be used when deploying a new pool\n * @param {String} address\n * @param {String} tokenAddress contract address to add\n * @return {Promise<TransactionReceipt>}\n */\n public async addSSContract(\n address: string,\n tokenAddress: string\n ): Promise<TransactionReceipt> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Router Owner`)\n }\n\n const estGas = await estimateGas(\n address,\n this.router.methods.addSSContract,\n tokenAddress\n )\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.router.methods.addSSContract(tokenAddress).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 removeSSContract method\n * @param {String} address caller address\n * @param {String} tokenAddress contract address to add\n * @return {Promise<TransactionReceipt>}\n */\n public async estGasRemoveSSContract(\n address: string,\n tokenAddress: string\n ): Promise<any> {\n return estimateGas(address, this.router.methods.removeSSContract, tokenAddress)\n }\n\n /**\n * Removes a new contract from ssContract list\n * @param {String} address caller address\n * @param {String} tokenAddress contract address to removed\n * @return {Promise<TransactionReceipt>}\n */\n public async removeSSContract(\n address: string,\n tokenAddress: string\n ): Promise<TransactionReceipt> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Router Owner`)\n }\n\n const estGas = await estimateGas(\n address,\n this.router.methods.removeSSContract,\n tokenAddress\n )\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.router.methods.removeSSContract(tokenAddress).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 addFixedRateContract method\n * @param {String} address\n * @param {String} tokenAddress contract address to add\n * @return {Promise<TransactionReceipt>}\n */\n public async estGasAddFixedRateContract(\n address: string,\n tokenAddress: string\n ): Promise<any> {\n return estimateGas(address, this.router.methods.addFixedRateContract, tokenAddress)\n }\n\n /**\n * Add a new contract to fixedRate list, after is added, can be used when deploying a new pool\n * @param {String} address\n * @param {String} tokenAddress contract address to add\n * @return {Promise<TransactionReceipt>}\n */\n public async addFixedRateContract(\n address: string,\n tokenAddress: string\n ): Promise<TransactionReceipt> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Router Owner`)\n }\n\n const estGas = await estimateGas(\n address,\n this.router.methods.addFixedRateContract,\n tokenAddress\n )\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.router.methods.addFixedRateContract(tokenAddress).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 addFixedRateContract method\n * @param {String} address\n * @param {String} tokenAddress contract address to add\n * @return {Promise<TransactionReceipt>}\n */\n public async estGasRemoveFixedRateContract(\n address: string,\n tokenAddress: string\n ): Promise<any> {\n return estimateGas(address, this.router.methods.removeFixedRateContract, tokenAddress)\n }\n\n /**\n * Removes a contract from fixedRate list\n * @param {String} address\n * @param {String} tokenAddress contract address to add\n * @return {Promise<TransactionReceipt>}\n */\n public async removeFixedRateContract(\n address: string,\n tokenAddress: string\n ): Promise<TransactionReceipt> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Router Owner`)\n }\n\n const estGas = await estimateGas(\n address,\n this.router.methods.removeFixedRateContract,\n tokenAddress\n )\n\n // Invoke removeFixedRateContract function of the contract\n const trxReceipt = await this.router.methods\n .removeFixedRateContract(tokenAddress)\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 addDispenserContract method\n * @param {String} address\n * @param {String} tokenAddress contract address to add\n * @return {Promise<TransactionReceipt>}\n */\n public async estGasAddDispenserContract(\n address: string,\n tokenAddress: string\n ): Promise<any> {\n return estimateGas(address, this.router.methods.addDispenserContract, tokenAddress)\n }\n\n /**\n * Add a new contract to dispenser list, after is added, can be used when deploying a new pool\n * @param {String} address\n * @param {String} tokenAddress contract address to add\n * @return {Promise<TransactionReceipt>}\n */\n public async addDispenserContract(\n address: string,\n tokenAddress: string\n ): Promise<TransactionReceipt> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Router Owner`)\n }\n\n const estGas = await estimateGas(\n address,\n this.router.methods.addDispenserContract,\n tokenAddress\n )\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.router.methods.addDispenserContract(tokenAddress).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 addDispenserContract method\n * @param {String} address\n * @param {String} tokenAddress contract address to add\n * @return {Promise<TransactionReceipt>}\n */\n public async estGasRemoveDispenserContract(\n address: string,\n tokenAddress: string\n ): Promise<any> {\n return estimateGas(address, this.router.methods.removeDispenserContract, tokenAddress)\n }\n\n /**\n * Add a new contract to dispenser list, after is added, can be used when deploying a new pool\n * @param {String} address\n * @param {String} tokenAddress contract address to add\n * @return {Promise<TransactionReceipt>}\n */\n public async removeDispenserContract(\n address: string,\n tokenAddress: string\n ): Promise<TransactionReceipt> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Router Owner`)\n }\n\n const estGas = await estimateGas(\n address,\n this.router.methods.removeDispenserContract,\n tokenAddress\n )\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.router.methods\n .removeDispenserContract(tokenAddress)\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 /** Get OPF Fee per token\n * @return {Promise<number>} OPC fee for a specific baseToken\n */\n public async getOPCFee(baseToken: string): Promise<number> {\n return await this.router.methods.getOPCFee(baseToken).call()\n }\n\n /** Get Current OPF Fee\n * @return {Promise<number>} OPF fee\n */\n public async getCurrentOPCFee(): Promise<number> {\n return await this.router.methods.swapOceanFee().call()\n }\n\n /**\n * Estimate gas cost for updateOPFFee method\n * @param {String} address\n * @param {String} newFee new OPF Fee\n * @return {Promise<TransactionReceipt>}\n */\n public async estGasUpdateOPCFee(\n address: string,\n newSwapOceanFee: number,\n newSwapNonOceanFee: number,\n newConsumeFee: number,\n newProviderFee: number\n ): Promise<any> {\n return estimateGas(\n address,\n this.router.methods.updateOPCFee,\n newSwapOceanFee,\n newSwapNonOceanFee,\n newConsumeFee,\n newProviderFee\n )\n }\n\n /**\n * Add a new contract to fixedRate list, after is added, can be used when deploying a new pool\n * @param {String} address\n * @param {number} newSwapOceanFee Amount charged for swapping with ocean approved tokens\n * @param {number} newSwapNonOceanFee Amount charged for swapping with non ocean approved tokens\n * @param {number} newConsumeFee Amount charged from consumeFees\n * @param {number} newProviderFee Amount charged for providerFees\n * @return {Promise<TransactionReceipt>}\n */\n public async updateOPCFee(\n address: string,\n newSwapOceanFee: number,\n newSwapNonOceanFee: number,\n newConsumeFee: number,\n newProviderFee: number\n ): Promise<TransactionReceipt> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Router Owner`)\n }\n\n const estGas = await estimateGas(\n address,\n this.router.methods.updateOPCFee,\n newSwapOceanFee,\n newSwapNonOceanFee,\n newConsumeFee,\n newProviderFee\n )\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.router.methods\n .updateOPCFee(newSwapOceanFee, newSwapNonOceanFee, newConsumeFee, newProviderFee)\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 addPoolTemplate method\n * @param {String} address\n * @param {String} templateAddress template address to add\n * @return {Promise<TransactionReceipt>}\n */\n public async estGasAddPoolTemplate(\n address: string,\n templateAddress: string\n ): Promise<any> {\n return estimateGas(address, this.router.methods.addPoolTemplate, templateAddress)\n }\n\n /**\n * Add a new template to poolTemplates mapping, after template is added,it can be used\n * @param {String} address\n * @param {String} templateAddress template address to add\n * @return {Promise<TransactionReceipt>}\n */\n public async addPoolTemplate(\n address: string,\n templateAddress: string\n ): Promise<TransactionReceipt> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Router Owner`)\n }\n\n const estGas = await estimateGas(\n address,\n this.router.methods.addPoolTemplate,\n templateAddress\n )\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.router.methods.addPoolTemplate(templateAddress).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 removePoolTemplate method\n * @param {String} address\n * @param {String} templateAddress template address to remove\n * @return {Promise<TransactionReceipt>}\n */\n public async estGasRemovePoolTemplate(\n address: string,\n templateAddress: string\n ): Promise<any> {\n return estimateGas(address, this.router.methods.removePoolTemplate, templateAddress)\n }\n\n /**\n * Remove template from poolTemplates mapping, after template is removed,it can be used anymore\n * @param {String} address\n * @param {String} templateAddress template address to remove\n * @return {Promise<TransactionReceipt>}\n */\n public async removePoolTemplate(\n address: string,\n templateAddress: string\n ): Promise<TransactionReceipt> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Router Owner`)\n }\n\n const estGas = await estimateGas(\n address,\n this.router.methods.removePoolTemplate,\n templateAddress\n )\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.router.methods\n .removePoolTemplate(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","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 estimateGas,\n ConfigHelper\n} from '../utils'\nimport { Contract } from 'web3-eth-contract'\nimport { MetadataProof } from '../../src/@types'\nimport { Config } from '../models/index.js'\nimport { MetadataAndTokenURI } from '../@types'\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 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(\n web3: Web3,\n network?: string | number,\n nftAbi?: AbiItem | AbiItem[],\n config?: Config\n ) {\n this.nftAbi = nftAbi || (defaultNftAbi.abi as AbiItem[])\n this.web3 = web3\n this.config = config || new ConfigHelper().getConfig(network || 'unknown')\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} paymentCollector initial paymentCollector 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 paymentCollector: 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 return estimateGas(\n address,\n nftContract.methods.createERC20,\n templateIndex,\n [name, symbol],\n [minter, paymentCollector, mpFeeAddress, feeToken],\n [this.web3.utils.toWei(cap), this.web3.utils.toWei(feeAmount)],\n []\n )\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} paymentCollector initial paymentCollector 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 paymentCollector: 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 estimateGas(\n address,\n nftContract.methods.createERC20,\n templateIndex,\n [name, symbol],\n [minter, paymentCollector, mpFeeAddress, feeToken],\n [this.web3.utils.toWei(cap), this.web3.utils.toWei(feeAmount)],\n []\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, paymentCollector, 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 return estimateGas(address, nftContract.methods.addManager, manager)\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 estimateGas(address, nftContract.methods.addManager, manager)\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 return estimateGas(address, nftContract.methods.removeManager, manager)\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 estimateGas(address, nftContract.methods.removeManager, manager)\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 return estimateGas(address, nftContract.methods.addToCreateERC20List, erc20Deployer)\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 estimateGas(\n address,\n nftContract.methods.addToCreateERC20List,\n erc20Deployer\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 return estimateGas(\n address,\n nftContract.methods.removeFromCreateERC20List,\n erc20Deployer\n )\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 estimateGas(\n address,\n nftContract.methods.removeFromCreateERC20List,\n erc20Deployer\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 return estimateGas(address, nftContract.methods.addToMetadataList, metadataUpdater)\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 estimateGas(\n address,\n nftContract.methods.addToMetadataList,\n metadataUpdater\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 return estimateGas(\n address,\n nftContract.methods.removeFromMetadataList,\n metadataUpdater\n )\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 return estimateGas(address, nftContract.methods.addTo725StoreList, storeUpdater)\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 estimateGas(\n address,\n nftContract.methods.addTo725StoreList,\n storeUpdater\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 return estimateGas(address, nftContract.methods.removeFrom725StoreList, storeUpdater)\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 estimateGas(\n address,\n nftContract.methods.removeFrom725StoreList,\n storeUpdater\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 return estimateGas(address, nftContract.methods.cleanPermissions)\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 estimateGas(address, nftContract.methods.cleanPermissions)\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 return estimateGas(\n nftOwner,\n nftContract.methods.transferFrom,\n nftOwner,\n nftReceiver,\n tokenId\n )\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 estimateGas(\n nftOwner,\n nftContract.methods.transferFrom,\n nftOwner,\n nftReceiver,\n tokenIdentifier\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 return estimateGas(\n nftOwner,\n nftContract.methods.safeTransferFrom,\n nftOwner,\n nftReceiver,\n tokenId\n )\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 estimateGas(\n nftOwner,\n nftContract.methods.safeTransferFrom,\n nftOwner,\n nftReceiver,\n tokenIdentifier\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 if (!metadataProofs) metadataProofs = []\n return estimateGas(\n metadataUpdater,\n nftContract.methods.setMetaData,\n metadataState,\n metadataDecryptorUrl,\n metadataDecryptorAddress,\n flags,\n data,\n metadataHash,\n metadataProofs\n )\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 estimateGas(\n address,\n nftContract.methods.setMetaData,\n metadataState,\n metadataDecryptorUrl,\n metadataDecryptorAddress,\n flags,\n data,\n metadataHash,\n metadataProofs\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 sanitizedMetadataAndTokenURI = {\n ...metadataAndTokenURI,\n metadataProofs: metadataAndTokenURI.metadataProofs || []\n }\n return estimateGas(\n metadataUpdater,\n nftContract.methods.setMetaDataAndTokenURI,\n sanitizedMetadataAndTokenURI\n )\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 sanitizedMetadataAndTokenURI = {\n ...metadataAndTokenURI,\n metadataProofs: metadataAndTokenURI.metadataProofs || []\n }\n const estGas = await estimateGas(\n metadataUpdater,\n nftContract.methods.setMetaDataAndTokenURI,\n sanitizedMetadataAndTokenURI\n )\n const trxReceipt = await nftContract.methods\n .setMetaDataAndTokenURI(sanitizedMetadataAndTokenURI)\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 return estimateGas(\n metadataUpdater,\n nftContract.methods.setMetaDataState,\n metadataState\n )\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 estimateGas(\n address,\n nftContract.methods.setMetaDataState,\n metadataState\n )\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 return estimateGas(address, nftContract.methods.setTokenURI, '1', data)\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 estimateGas(address, nftContract.methods.setTokenURI, '1', 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 /** 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 nftAddress erc721 contract adress\n * @param address user adress\n * @param key Key of the data to be stored into 725Y standard\n * @param value Data to be stored into 725Y standard\n * @return {Promise<TransactionReceipt>} transactionId\n */\n public async setData(\n nftAddress: string,\n address: string,\n key: string,\n value: string\n ): Promise<TransactionReceipt> {\n if ((await this.getNftPermissions(nftAddress, address)).store !== true) {\n throw new Error(`User is not ERC20 store updater`)\n }\n\n const nftContract = setContractDefaults(\n new this.web3.eth.Contract(this.nftAbi, nftAddress),\n this.config\n )\n\n const keyHash = this.web3.utils.keccak256(key)\n const valueHex = this.web3.utils.asciiToHex(value)\n\n const estGas = await estimateGas(\n address,\n nftContract.methods.setNewData,\n keyHash,\n valueHex\n )\n\n // Call setData function of the contract\n const trxReceipt = await nftContract.methods.setNewData(keyHash, valueHex).send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\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 keyHash = this.web3.utils.keccak256(key)\n const data = await nftContract.methods.getData(keyHash).call()\n return data ? this.web3.utils.hexToAscii(data) : null\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 getFreOrderParams,\n estimateGas,\n ZERO_ADDRESS,\n ConfigHelper\n} from '../utils'\nimport {\n ConsumeMarketFee,\n FreOrderParams,\n FreCreationParams,\n ProviderFees,\n PublishingMarketFee\n} from '../@types'\nimport { Nft } from './NFT'\nimport { Config } from '../models/index.js'\n\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 _providerFee: ProviderFees\n _consumeMarketFee: ConsumeMarketFee\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 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 network?: string | number,\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 || new ConfigHelper().getConfig(network || 'unknown')\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 return estimateGas(\n address,\n dtContract.methods.approve,\n spender,\n this.web3.utils.toWei(amount)\n )\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 estimateGas(\n address,\n dtContract.methods.approve,\n spender,\n this.web3.utils.toWei(amount)\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 return estimateGas(\n address,\n dtContract.methods.mint,\n toAddress || address,\n this.web3.utils.toWei(amount)\n )\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 if (!fixedRateParams.allowedConsumer) fixedRateParams.allowedConsumer = ZERO_ADDRESS\n const withMint = fixedRateParams.withMint ? 1 : 0\n\n return estimateGas(\n address,\n dtContract.methods.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 }\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) fixedRateParams.allowedConsumer = ZERO_ADDRESS\n\n const withMint = fixedRateParams.withMint ? 1 : 0\n\n // should check ERC20Deployer role using erc721 level ..\n\n const estGas = await estimateGas(\n address,\n dtContract.methods.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\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) dispenserParams.allowedSwapper = ZERO_ADDRESS\n\n if (!dispenserParams.withMint) dispenserParams.withMint = false\n\n return estimateGas(\n address,\n dtContract.methods.createDispenser,\n dispenserAddress,\n dispenserParams.maxTokens,\n dispenserParams.maxBalance,\n dispenserParams.withMint,\n dispenserParams.allowedSwapper\n )\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) dispenserParams.allowedSwapper = ZERO_ADDRESS\n\n if (!dispenserParams.withMint) dispenserParams.withMint = false\n\n // should check ERC20Deployer role using erc721 level ..\n\n const estGas = await estimateGas(\n address,\n dtContract.methods.createDispenser,\n dispenserAddress,\n dispenserParams.maxTokens,\n dispenserParams.maxBalance,\n dispenserParams.withMint,\n dispenserParams.allowedSwapper\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 estimateGas(\n address,\n dtContract.methods.mint,\n toAddress || address,\n this.web3.utils.toWei(amount)\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 return estimateGas(address, dtContract.methods.addMinter, minter)\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 estimateGas(address, dtContract.methods.addMinter, minter)\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 return estimateGas(address, dtContract.methods.removeMinter, minter)\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 estimateGas(address, dtContract.methods.removeMinter, minter)\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 return estimateGas(address, dtContract.methods.addPaymentManager, paymentManager)\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 estimateGas(\n address,\n dtContract.methods.addPaymentManager,\n paymentManager\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 return estimateGas(address, dtContract.methods.removePaymentManager, paymentManager)\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 estimateGas(\n address,\n dtContract.methods.removePaymentManager,\n paymentManager\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 return estimateGas(address, dtContract.methods.setPaymentCollector, paymentCollector)\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 const isPaymentManager = (await this.getDTPermissions(dtAddress, address))\n .paymentManager\n const nftAddress = !isPaymentManager && (await this.getNFTAddress(dtAddress))\n const isNftOwner = nftAddress && (await this.nft.getNftOwner(nftAddress)) === address\n const nftPermissions =\n nftAddress && !isNftOwner && (await this.nft.getNftPermissions(nftAddress, address))\n const isErc20Deployer = nftPermissions?.deployERC20\n if (!isPaymentManager && !isNftOwner && !isErc20Deployer) {\n throw new Error(`Caller is not Fee Manager, owner or erc20 Deployer`)\n }\n\n const estGas = await estimateGas(\n address,\n dtContract.methods.setPaymentCollector,\n paymentCollector\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 return estimateGas(address, dtContract.methods.transfer, toAddress, amount)\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 estimateGas(\n address,\n dtContract.methods.transfer,\n toAddress,\n amount\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 {consumeMarketFee} ConsumeMarketFee consume market 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 consumeMarketFee?: ConsumeMarketFee,\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 return estimateGas(\n address,\n dtContract.methods.startOrder,\n consumer,\n serviceIndex,\n providerFees,\n consumeMarketFee\n )\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 * @param {consumeMarketFee} ConsumeMarketFee consume market 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 consumeMarketFee?: ConsumeMarketFee\n ): Promise<TransactionReceipt> {\n const dtContract = setContractDefaults(\n new this.web3.eth.Contract(this.datatokensAbi, dtAddress),\n this.config\n )\n if (!consumeMarketFee) {\n consumeMarketFee = {\n consumeMarketFeeAddress: ZERO_ADDRESS,\n consumeMarketFeeToken: ZERO_ADDRESS,\n consumeMarketFeeAmount: '0'\n }\n }\n try {\n const estGas = await estimateGas(\n address,\n dtContract.methods.startOrder,\n consumer,\n serviceIndex,\n providerFees,\n consumeMarketFee\n )\n\n const trxReceipt = await dtContract.methods\n .startOrder(consumer, serviceIndex, providerFees, consumeMarketFee)\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 reuseOrder method\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address which calls\n * @param {String} orderTxId previous valid order\n * @param {providerFees} providerFees provider fees\n * @param {Contract} contractInstance optional contract instance\n * @return {Promise<any>}\n */\n public async estGasReuseOrder(\n dtAddress: string,\n address: string,\n orderTxId: string,\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 return estimateGas(address, dtContract.methods.reuseOrder, orderTxId, providerFees)\n }\n\n /** Reuse Order: called by payer or consumer having a valid order, but with expired provider access.\n * Pays the provider fee again, but it will not require a new datatoken payment\n * Requires previous approval of provider fee.\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address which calls\n * @param {String} orderTxId previous valid order\n * @param {providerFees} providerFees provider fees\n * @return {Promise<TransactionReceipt>} string\n */\n public async reuseOrder(\n dtAddress: string,\n address: string,\n orderTxId: string,\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 estimateGas(\n address,\n dtContract.methods.reuseOrder,\n orderTxId,\n providerFees\n )\n\n const trxReceipt = await dtContract.methods\n .reuseOrder(orderTxId, 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 call reuse order 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 return estimateGas(\n address,\n dtContract.methods.buyFromFreAndOrder,\n orderParams,\n freParams\n )\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 freContractParams = await getFreOrderParams(this.web3, freParams)\n\n const estGas = await estimateGas(\n address,\n dtContract.methods.buyFromFreAndOrder,\n orderParams,\n freContractParams\n )\n\n const trxReceipt = await dtContract.methods\n .buyFromFreAndOrder(orderParams, freContractParams)\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 return estimateGas(\n address,\n dtContract.methods.buyFromDispenserAndOrder,\n orderParams,\n dispenserContract\n )\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 estimateGas(\n address,\n dtContract.methods.buyFromDispenserAndOrder,\n orderParams,\n dispenserContract\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 return estimateGas(address, dtContract.methods.setData, value)\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 valueHex = this.web3.utils.asciiToHex(value)\n\n const estGas = await estimateGas(address, dtContract.methods.setData, valueHex)\n\n // Call setData function of the contract\n const trxReceipt = await dtContract.methods.setData(valueHex).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 return estimateGas(address, dtContract.methods.cleanPermissions)\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 estimateGas(address, dtContract.methods.cleanPermissions)\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 /**\n * @dev estGasSetPublishingMarketFee\n * Estimating gas for publishMarketFeeAddress method\n * @param {string} datatokenAddress Datatoken adress\n * @param {string} publishMarketFeeAddress new publish Market Fee Address\n * @param {string} publishMarketFeeToken new publish Market Fee Token\n * @param {string} publishMarketFeeAmount new fee amount\n * @param {String} address user adress\n */\n public async estGasSetPublishingMarketFee(\n datatokenAddress: string,\n publishMarketFeeAddress: string,\n publishMarketFeeToken: string,\n publishMarketFeeAmount: string,\n address: string\n ): Promise<number> {\n // Estimate gas cost for publishMarketFeeAddress method\n const dtContract = new this.web3.eth.Contract(this.datatokensAbi, datatokenAddress, {\n from: address\n })\n return estimateGas(\n address,\n dtContract.methods.setPublishingMarketFee,\n publishMarketFeeAddress,\n publishMarketFeeToken,\n publishMarketFeeAmount\n )\n }\n\n /**\n * @dev setPublishingMarketFee\n * Only publishMarketFeeAddress can call it\n * This function allows to set the fee required by the publisherMarket\n * @param {string} datatokenAddress Datatoken adress\n * @param {string} publishMarketFeeAddress new publish Market Fee Address\n * @param {string} publishMarketFeeToken new publish Market Fee Token\n * @param {string} publishMarketFeeAmount new fee amount\n * @param {String} address user adress\n */\n public async setPublishingMarketFee(\n datatokenAddress: string,\n publishMarketFeeAddress: string,\n publishMarketFeeToken: string,\n publishMarketFeeAmount: string,\n address: string\n ) {\n const dtContract = new this.web3.eth.Contract(this.datatokensAbi, datatokenAddress, {\n from: address\n })\n const mktFeeAddress = (await dtContract.methods.getPublishingMarketFee().call())[0]\n if (mktFeeAddress !== address) {\n throw new Error(`Caller is not the Publishing Market Fee Address`)\n }\n const estGas = await this.estGasSetPublishingMarketFee(\n datatokenAddress,\n publishMarketFeeAddress,\n publishMarketFeeToken,\n publishMarketFeeAmount,\n address\n )\n await dtContract.methods\n .setPublishingMarketFee(\n publishMarketFeeAddress,\n publishMarketFeeToken,\n publishMarketFeeAmount\n )\n .send({\n from: address,\n gas: estGas + 1,\n gasPrice: await getFairGasPrice(this.web3, this.config)\n })\n }\n\n /**\n * @dev getPublishingMarketFee\n * Get publishingMarket Fee\n * This function allows to get the current fee set by the publishing market\n * @param {String} datatokenAddress Datatoken adress\n * @param {String} address user adress\n * @return {Promise<PublishingMarketFee>} Current fee set by the publishing market\n */\n public async getPublishingMarketFee(\n datatokenAddress: string,\n address: string\n ): Promise<PublishingMarketFee> {\n const dtContract = new this.web3.eth.Contract(this.datatokensAbi, datatokenAddress, {\n from: address\n })\n\n const publishingMarketFee = await dtContract.methods.getPublishingMarketFee().call()\n const returnValues = {\n publishMarketFeeAddress: publishingMarketFee[0],\n publishMarketFeeToken: publishingMarketFee[1],\n publishMarketFeeAmount: publishingMarketFee[2]\n }\n return returnValues\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 setContractDefaults,\n estimateGas,\n ZERO_ADDRESS,\n ConfigHelper\n} from '../utils'\nimport { Config } from '../models/index.js'\nimport {\n ProviderFees,\n FreCreationParams,\n Erc20CreateParams,\n PoolCreationParams,\n DispenserCreationParams,\n ConsumeMarketFee\n} 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 _providerFee: ProviderFees\n _consumeMarketFee: ConsumeMarketFee\n}\n\nexport interface NftCreateData {\n name: string\n symbol: string\n templateIndex: number\n tokenURI: string\n transferable: boolean\n owner: string\n}\n\n/**\n * Provides an interface for NFT Factory contract\n */\nexport class NftFactory {\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 network?: string | number,\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 || new ConfigHelper().getConfig(network || 'unknown')\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 return estimateGas(\n address,\n this.factory721.methods.deployERC721Contract,\n nftData.name,\n nftData.symbol,\n nftData.templateIndex,\n ZERO_ADDRESS,\n ZERO_ADDRESS,\n nftData.tokenURI,\n nftData.transferable,\n nftData.owner\n )\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 estimateGas(\n address,\n this.factory721.methods.deployERC721Contract,\n nftData.name,\n nftData.symbol,\n nftData.templateIndex,\n ZERO_ADDRESS,\n ZERO_ADDRESS,\n nftData.tokenURI,\n nftData.transferable,\n nftData.owner\n )\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 ZERO_ADDRESS,\n ZERO_ADDRESS,\n nftData.tokenURI,\n nftData.transferable,\n nftData.owner\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 return estimateGas(\n address,\n this.factory721.methods.add721TokenTemplate,\n templateAddress\n )\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 === ZERO_ADDRESS) {\n throw new Error(`Template cannot be ZERO address`)\n }\n\n const estGas = await estimateGas(\n address,\n this.factory721.methods.add721TokenTemplate,\n templateAddress\n )\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 return estimateGas(\n address,\n this.factory721.methods.disable721TokenTemplate,\n templateIndex\n )\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 estimateGas(\n address,\n this.factory721.methods.disable721TokenTemplate,\n templateIndex\n )\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 return estimateGas(\n address,\n this.factory721.methods.reactivate721TokenTemplate,\n templateIndex\n )\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 estimateGas(\n address,\n this.factory721.methods.reactivate721TokenTemplate,\n templateIndex\n )\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 return estimateGas(address, this.factory721.methods.addTokenTemplate, templateAddress)\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 === ZERO_ADDRESS) {\n throw new Error(`Template cannot be address ZERO`)\n }\n\n const estGas = await estimateGas(\n address,\n this.factory721.methods.addTokenTemplate,\n templateAddress\n )\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 return estimateGas(\n address,\n this.factory721.methods.disableTokenTemplate,\n templateIndex\n )\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.getCurrentTokenTemplateCount())) {\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 === false) {\n throw new Error(`Template is already disabled`)\n }\n const estGas = await estimateGas(\n address,\n this.factory721.methods.disableTokenTemplate,\n templateIndex\n )\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 return estimateGas(\n address,\n this.factory721.methods.reactivateTokenTemplate,\n templateIndex\n )\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.getCurrentTokenTemplateCount())) {\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 estimateGas(\n address,\n this.factory721.methods.reactivateTokenTemplate,\n templateIndex\n )\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 return estimateGas(address, this.factory721.methods.startMultipleTokenOrder, orders)\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 estimateGas(\n address,\n this.factory721.methods.startMultipleTokenOrder,\n orders\n )\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 createNftWithErc20 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 estGasCreateNftWithErc20(\n address: string,\n nftCreateData: NftCreateData,\n ercParams: Erc20CreateParams\n ): Promise<any> {\n const ercCreateData = getErcCreationParams(ercParams)\n return estimateGas(\n address,\n this.factory721.methods.createNftWithErc20,\n nftCreateData,\n ercCreateData\n )\n }\n\n /**\n * @dev createNftWithErc20\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 createNftWithErc20(\n address: string,\n nftCreateData: NftCreateData,\n ercParams: Erc20CreateParams\n ): Promise<TransactionReceipt> {\n const ercCreateData = getErcCreationParams(ercParams)\n\n const estGas = await estimateGas(\n address,\n this.factory721.methods.createNftWithErc20,\n nftCreateData,\n ercCreateData\n )\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.factory721.methods\n .createNftWithErc20(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 createNftErc20WithPool 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 estGasCreateNftErc20WithPool(\n address: string,\n nftCreateData: NftCreateData,\n ercParams: Erc20CreateParams,\n poolParams: PoolCreationParams\n ): Promise<any> {\n const ercCreateData = getErcCreationParams(ercParams)\n const poolData = await getPoolCreationParams(this.web3, poolParams)\n return estimateGas(\n address,\n this.factory721.methods.createNftWithErc20WithPool,\n nftCreateData,\n ercCreateData,\n poolData\n )\n }\n\n /**\n * @dev createNftErc20WithPool\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 createNftErc20WithPool(\n address: string,\n nftCreateData: NftCreateData,\n ercParams: Erc20CreateParams,\n poolParams: PoolCreationParams\n ): Promise<TransactionReceipt> {\n const ercCreateData = getErcCreationParams(ercParams)\n const poolData = await getPoolCreationParams(this.web3, poolParams)\n\n const estGas = await estimateGas(\n address,\n this.factory721.methods.createNftWithErc20WithPool,\n nftCreateData,\n ercCreateData,\n poolData\n )\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.factory721.methods\n .createNftWithErc20WithPool(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 createNftErc20WithFixedRate 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 estGasCreateNftErc20WithFixedRate(\n address: string,\n nftCreateData: NftCreateData,\n ercParams: Erc20CreateParams,\n freParams: FreCreationParams\n ): Promise<any> {\n const ercCreateData = getErcCreationParams(ercParams)\n const fixedData = await getFreCreationParams(freParams)\n return estimateGas(\n address,\n this.factory721.methods.createNftWithErc20WithFixedRate,\n nftCreateData,\n ercCreateData,\n fixedData\n )\n }\n\n /**\n * @dev createNftErc20WithFixedRate\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 createNftErc20WithFixedRate(\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 estimateGas(\n address,\n this.factory721.methods.createNftWithErc20WithFixedRate,\n nftCreateData,\n ercCreateData,\n fixedData\n )\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.factory721.methods\n .createNftWithErc20WithFixedRate(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 createNftErc20WithFixedRate 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 estGasCreateNftErc20WithDispenser(\n address: string,\n nftCreateData: NftCreateData,\n ercParams: Erc20CreateParams,\n dispenserParams: DispenserCreationParams\n ): Promise<any> {\n const ercCreateData = getErcCreationParams(ercParams)\n return estimateGas(\n address,\n this.factory721.methods.createNftWithErc20WithDispenser,\n nftCreateData,\n ercCreateData,\n dispenserParams\n )\n }\n\n /**\n * @dev createNftErc20WithDispenser\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 createNftErc20WithDispenser(\n address: string,\n nftCreateData: NftCreateData,\n ercParams: Erc20CreateParams,\n dispenserParams: DispenserCreationParams\n ): Promise<TransactionReceipt> {\n const ercCreateData = getErcCreationParams(ercParams)\n\n dispenserParams.maxBalance = Web3.utils.toWei(dispenserParams.maxBalance)\n dispenserParams.maxTokens = Web3.utils.toWei(dispenserParams.maxTokens)\n\n const estGas = await estimateGas(\n address,\n this.factory721.methods.createNftWithErc20WithDispenser,\n nftCreateData,\n ercCreateData,\n dispenserParams\n )\n\n // Invoke createToken function of the contract\n const trxReceipt = await this.factory721.methods\n .createNftWithErc20WithDispenser(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 { 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 } from '../utils'\nimport {\n FileInfo,\n ComputeJob,\n ComputeOutput,\n ComputeAlgorithm,\n ComputeAsset,\n ComputeEnvironment,\n ProviderInitialize,\n ProviderComputeInitializeResults\n} from '../@types/'\nimport { noZeroX } from '../utils/ConversionTypeHelper'\nimport fetch from 'cross-fetch'\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 /** Gets current nonce\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 (await response.json()).nonce.toString()\n } catch (e) {\n LoggerInstance.error(e)\n throw new Error('HTTP request failed')\n }\n }\n\n public async signProviderRequest(\n web3: Web3,\n accountId: string,\n message: string,\n password?: string\n ): Promise<string> {\n const consumerMessage = web3.utils.soliditySha3({\n t: 'bytes',\n v: web3.utils.utf8ToHex(message)\n })\n const isMetaMask =\n web3 && web3.currentProvider && (web3.currentProvider as any).isMetaMask\n if (isMetaMask)\n return await web3.eth.personal.sign(consumerMessage, accountId, password)\n else return await web3.eth.sign(consumerMessage, accountId)\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 if (!path) return null\n try {\n const response = await fetch(path, {\n method: 'POST',\n body: 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<FileInfo[]>} urlDetails\n */\n public async checkDidFiles(\n did: string,\n serviceId: string,\n providerUri: string,\n withChecksum: boolean = false,\n signal?: AbortSignal\n ): Promise<FileInfo[]> {\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, checksum: withChecksum }\n const files: FileInfo[] = []\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: FileInfo[] = 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<FileInfo[]>} urlDetails\n */\n public async checkFileUrl(\n url: string,\n providerUri: string,\n signal?: AbortSignal\n ): Promise<FileInfo[]> {\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: FileInfo[] = []\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: FileInfo[] = 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 Compute Environments\n * @return {Promise<ComputeEnvironment[]>} urlDetails\n */\n public async getComputeEnvironments(\n providerUri: string,\n signal?: AbortSignal\n ): Promise<ComputeEnvironment[]> {\n const providerEndpoints = await this.getEndpoints(providerUri)\n const serviceEndpoints = await this.getServiceEndpoints(\n providerUri,\n providerEndpoints\n )\n const path = this.getEndpointURL(serviceEndpoints, 'computeEnvironments')?.urlPath\n if (!path) return null\n try {\n const response = await fetch(path, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json'\n },\n signal: signal\n })\n const envs: ComputeEnvironment[] = await response.json()\n return envs\n } catch (e) {\n LoggerInstance.error(e.message)\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 += '&environment=' + 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 /** Initialize a compute request.\n * @param {ComputeAsset} assets\n * @param {ComputeAlgorithmber} algorithm\n * @param {string} computeEnv\n * @param {number} validUntil\n * @param {string} providerUri Identifier of the asset to be registered in ocean\n * @param {string} accountId\n * @param {AbortSignal} signal abort signal\n * @return {Promise<ProviderComputeInitialize>} ProviderComputeInitialize data\n */\n public async initializeCompute(\n assets: ComputeAsset[],\n algorithm: ComputeAlgorithm,\n computeEnv: string,\n validUntil: number,\n providerUri: string,\n accountId: string,\n signal?: AbortSignal\n ): Promise<ProviderComputeInitializeResults> {\n const providerEndpoints = await this.getEndpoints(providerUri)\n const serviceEndpoints = await this.getServiceEndpoints(\n providerUri,\n providerEndpoints\n )\n const providerData = {\n datasets: assets,\n algorithm: algorithm,\n compute: {\n env: computeEnv,\n validUntil: validUntil\n },\n consumerAddress: accountId\n }\n const initializeUrl = this.getEndpointURL(serviceEndpoints, 'initializeCompute')\n ? this.getEndpointURL(serviceEndpoints, 'initializeCompute').urlPath\n : null\n if (!initializeUrl) return null\n try {\n const response = await fetch(initializeUrl, {\n method: 'POST',\n body: JSON.stringify(providerData),\n headers: {\n 'Content-Type': 'application/json'\n },\n signal: signal\n })\n const results = await response.json()\n return results\n } catch (e) {\n LoggerInstance.error(e)\n throw new Error('ComputeJob cannot be initialized')\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.signProviderRequest(web3, accountId, did + nonce)\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 {string} computeEnv\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.signProviderRequest(\n web3,\n consumerAddress,\n signatureMessage\n )\n const payload = Object()\n payload.consumerAddress = consumerAddress\n payload.signature = signature\n payload.nonce = nonce\n payload.environment = 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 LoggerInstance.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.signProviderRequest(\n web3,\n consumerAddress,\n signatureMessage\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 compute status for a specific jobId/documentId/owner.\n * @param {string} providerUri The URI of the provider we want to query\n * @param {string} consumerAddress The consumer ethereum address\n * @param {string} jobId The ID of a compute job.\n * @param {string} did The ID of the asset\n * @param {AbortSignal} signal abort signal\n * @return {Promise<ComputeJob | ComputeJob[]>}\n */\n public async computeStatus(\n providerUri: string,\n consumerAddress: string,\n jobId?: string,\n did?: string,\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 computeStatusUrl = this.getEndpointURL(serviceEndpoints, 'computeStatus')\n ? this.getEndpointURL(serviceEndpoints, 'computeStatus').urlPath\n : null\n\n let url = `?consumerAddress=${consumerAddress}`\n url += (did && `&documentId=${noZeroX(did)}`) || ''\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 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 compute result url\n * @param {string} providerUri The URI of the provider we want to query\n * @param {Web3} web3 Web3 instance\n * @param {string} consumerAddress The consumer ethereum address\n * @param {string} jobId The ID of a compute job.\n * @param {number} index Result index\n * @return {Promise<string>}\n */\n public async getComputeResultUrl(\n providerUri: string,\n web3: Web3,\n consumerAddress: string,\n jobId: string,\n index: number\n ): Promise<string> {\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 = Date.now()\n let signatureMessage = consumerAddress\n signatureMessage += jobId\n signatureMessage += index.toString()\n signatureMessage += nonce\n const signature = await this.signProviderRequest(\n web3,\n consumerAddress,\n signatureMessage\n )\n if (!computeResultUrl) return null\n let resultUrl = computeResultUrl\n resultUrl += `?consumerAddress=${consumerAddress}`\n resultUrl += `&jobId=${jobId}`\n resultUrl += `&index=${index.toString()}`\n resultUrl += `&nonce=${nonce}`\n resultUrl += (signature && `&signature=${signature}`) || ''\n return resultUrl\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.signProviderRequest(\n web3,\n consumerAddress,\n signatureMessage\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","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 sha256 from 'crypto-js/sha256'\nimport Web3 from 'web3'\nimport LoggerInstance from './Logger'\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 try {\n return sha256(data).toString()\n } catch (e) {\n LoggerInstance.error('getHash error: ', e.message)\n }\n}\n","import Web3 from 'web3'\nimport { LoggerInstance } from './Logger'\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"],"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","ZERO_ADDRESS","estimateGas","from","functionToEstimateGas","estimatedGas","apply","err","estGas","e","amountToUnits","web3","token","amount","tokenDecimals","decimals","BigNumber","config","EXPONENTIAL_AT","times","exponentiatedBy","toFixed","tokenContract","eth","Contract","methods","call","message","unitsToAmount","amountFormatted","div","toString","getPoolCreationParams","poolParams","ssContract","baseTokenAddress","baseTokenSender","publisherAddress","marketFeeCollector","poolTemplateAddress","vestedBlocks","Web3","utils","toWei","vestingAmount","baseTokenDecimals","rate","initialBaseTokenLiquidity","addresses","ssParams","swapFees","swapFeeLiquidityProvider","swapFeeMarketRunner","getFreOrderParams","freParams","exchangeId","exchangeContract","maxBaseTokenAmount","swapMarketFee","marketFeeAddress","getFairGasPrice","getGasPrice","x","gasFeeMultiplier","multipliedBy","integerValue","ROUND_DOWN","setContractDefaults","contract","transactionBlockTimeout","transactionConfirmationBlocks","transactionPollingTimeout","getErcCreationParams","ercParams","templateIndex","strings","minter","paymentCollector","mpFeeAddress","feeToken","uints","cap","feeAmount","bytess","getFreCreationParams","allowedConsumer","withMint","fixedPriceAddress","fixedRateAddress","owner","datatokenDecimals","fixedRate","marketFee","postData","getData","url","fetch","method","headers","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","DefaultContractsAddresses","getConfig","infuraProjectId","filterBy","find","allowanceWei","tokenAddress","account","spender","allowance","trxReceipt","sleep","ms","Promise","resolve","setTimeout","getMaxRemoveLiquidity","poolInstance","poolAddress","getReserve","calcMaxExactIn","getMaxAddLiquidity","getMaxSwapExactIn","getMaxSwapExactOut","calcMaxExactOut","balance","Decimal","bind","pact","_settle","result","Aquarius","aquariusURL","did","signal","path","response","ok","json","status","waitForAqua","txid","tries","_this4","ddo","event","validate","jsonResponse","valid","_this6","body","JSON","stringify","hash","proof","validatorAddress","publicKey","r","s","v","errors","getAssetMetadata","statusText","querySearch","query","recover","then","MaxUint256","Pool","poolAbi","PoolTemplate","abi","sharesBalance","balanceOf","fromWei","estSetSwapFee","fee","contractInstance","poolContract","defaultErc20Abi","setSwapFee","pool","_this10","_pool$methods$setSwap2","send","gas","gasPrice","getNumTokens","_this12","getPoolSharesTotalSupply","_this14","totalSupply","getCurrentTokens","_this16","getFinalTokens","_this18","getController","_this20","getBaseToken","_this22","getBaseTokenAddress","getDatatoken","_this24","getDatatokenAddress","getMarketFee","_this26","getMarketFeeCollector","_this28","_publishMarketCollector","isBound","_this30","_this32","getBalance","isFinalized","_this34","getSwapFee","_this36","getNormalizedWeight","_this38","weight","getDenormalizedWeight","_this40","getTotalDenormalizedWeight","_this42","getMarketFees","_this44","publishMarketFees","getCurrentMarketFees","_this46","getCurrentOPCFees","_this48","getCommunityFees","_this50","communityFees","estCollectOPC","address","_this52","collectOPC","_this54","_pool$methods$collect2","estCollectMarketFee","_this56","collectMarketFee","_this58","_this57$getMarketFeeC","_pool$methods$collect4","estUpdatePublishMarketFee","newPublishMarketAddress","newPublishMarketSwapFee","_this60","updatePublishMarketFee","_this62","_this61$getMarketFeeC","_pool$methods$updateP2","estSwapExactAmountIn","tokenInOutMarket","amountsInOutMaxFee","_this64","tokenIn","tokenAmountIn","tokenInDecimals","tokenOut","minAmountOut","tokenOutDecimals","maxPrice","_amountsInOutMaxFee$m","swapExactAmountIn","_this66","maxSwap","greaterThan","_pool$methods$swapExa2","estSwapExactAmountOut","_this68","maxAmountIn","tokenAmountOut","swapExactAmountOut","_this70","_amountsInOutMaxFee$m4","_pool$methods$swapExa4","estJoinswapExternAmountIn","minPoolAmountOut","_this72","joinswapExternAmountIn","_this74","amountInFormatted","_pool$methods$joinswa2","estExitswapPoolAmountIn","poolAmountIn","minTokenAmountOut","_this76","exitswapPoolAmountIn","poolDecimals","_this78","calcSingleOutGivenPoolIn","minTokenOutFormatted","_pool$methods$exitswa2","getSpotPrice","decimalsDiff","decimalsTokenIn","decimalsTokenOut","price","_this80","tokenOutContract","tokenInContract","getAmountInExactOut","_this82","amountOutFormatted","lpFeeAmount","oceanFeeAmount","publishMarketSwapFeeAmount","consumeMarketSwapFeeAmount","tokenAmount","liquidityProviderSwapFeeAmount","getAmountOutExactIn","_this84","calcPoolOutGivenSingleIn","_this86","_pool$methods","calcPoolOutSingleIn","_calcPoolOutSingleIn","calcSingleInGivenPoolOut","poolAmountOut","_this88","calcSingleInPoolOut","_this90","_pool$methods2","calcSingleOutPoolIn","_calcSingleOutPoolIn","calcPoolInGivenSingleOut","_this92","_pool$methods3","calcPoolInSingleOut","_calcPoolInSingleOut","getSwapEventSignature","eventdata","encodeEventSignature","getJoinEventSignature","getExitEventSignature","FixedRateCreateProgressStep","dispenserAbi","dispenserContract","defaultDispenserAbi","dtAdress","_this2","maxTokens","maxBalance","_exit2","logger","estGasCreate","dtAddress","allowedSwapper","create","_this5$dispenserContr","estGasActivate","_this8","activate","_this9$dispenserContr","estGasDeactivate","deactivate","_this13$dispenserCont","estGasSetAllowedSwapper","newAllowedSwapper","setAllowedSwapper","_this17$dispenserCont","estGasDispense","destination","dispense","_this21$dispenserCont","estGasOwnerWithdraw","ownerWithdraw","_this25$dispenserCont","isDispensable","datatoken","active","greaterThanOrEqualTo","String","isMinter","FixedRateExchange","fixedRateExchangeAbi","oceanAddress","fixedRateContract","ssAbi","defaultFixedRateExchangeAbi","generateExchangeId","baseToken","estBuyDT","datatokenAddress","dtAmount","consumeMarketAddress","consumeMarketFee","buyDT","datatokenAmount","getExchange","exchange","consumeMarketFeeFormatted","dtDecimals","dtAmountFormatted","btDecimals","maxBtFormatted","_this9$fixedRateContr","estSellDT","sellDT","minBaseTokenAmount","minBtFormatted","_this13$fixedRateCont","getNumberOfExchanges","estSetRate","newRate","setRate","_this19$fixedRateCont","estSetAllowedSwapper","_this23$fixedRateCont","estActivate","toggleExchangeState","_this27$fixedRateCont","estDeactivate","_this31$fixedRateCont","getRate","weiRate","getDTSupply","dtSupply","getBTSupply","btSupply","getAllowedSwapper","calcBaseInGivenOutDT","fixedRateExchange","_this41$fixedRateCont","_calcBaseInGivenOutDT","baseTokenAmount","marketFeeAmount","consumeMarketFeeAmount","getAmountBTOut","_this43$fixedRateCont","calcBaseOutGivenInDT","_calcBaseOutGivenInDT","dtBalance","btBalance","getFeesInfo","opcFee","marketFeeAvailable","oceanFeeAvailable","getExchanges","isActive","estActivateMint","toggleMintState","activateMint","_this55$fixedRateCont","estDeactivateMint","deactivateMint","_this59$fixedRateCont","estCollectBT","fixedrate","amountWei","collectBT","_this63$fixedRateCont","estCollectDT","collectDT","_this67$fixedRateCont","_this71$fixedRateCont","estCollectOceanFee","collectOceanFee","_this75$fixedRateCont","getOPCCollector","opcCollector","getRouter","router","getExchangeOwner","_this81$getExchange","exchangeOwner","estUpdateMarketFee","newMarketFee","updateMarketFee","_this85$fixedRateCont","estUpdateMarketFeeCollector","newMarketFeeCollector","updateMarketFeeCollector","_this89$fixedRateCont","SideStaking","SideStakingTemplate","getDatatokenCirculatingSupply","ssAddress","sideStaking","getDatatokenCurrentCirculatingSupply","getPublisherAddress","getPoolAddress","getBaseTokenBalance","getDatatokenBalance","getvestingEndBlock","getvestingAmount","getvestingLastBlock","getvestingAmountSoFar","estGetVesting","getVesting","_sideStaking$methods$13","estSetPoolSwapFee","swapFee","setPoolSwapFee","_sideStaking$methods$15","Router","routerAddress","RouterAbi","defaultRouter","estGasBuyDTBatch","operations","buyDTBatch","_this3$router$methods","isApprovedToken","isSideStaking","isSSContract","isFixedPrice","isFixedRateContract","getOwner","routerOwner","getNFTFactory","factory","isPoolTemplate","estGasAddApprovedToken","addApprovedToken","_this19$getOwner","_this19$router$method","estGasRemoveApprovedToken","removeApprovedToken","_this23$getOwner","_this23$router$method","estGasAddSSContract","addSSContract","_this27$getOwner","_this27$router$method","estGasRemoveSSContract","removeSSContract","_this31$getOwner","_this31$router$method","estGasAddFixedRateContract","addFixedRateContract","_this35$getOwner","_this35$router$method","estGasRemoveFixedRateContract","removeFixedRateContract","_this39$getOwner","_this39$router$method","estGasAddDispenserContract","addDispenserContract","_this43$getOwner","_this43$router$method","estGasRemoveDispenserContract","removeDispenserContract","_this47$getOwner","_this47$router$method","getOPCFee","getCurrentOPCFee","swapOceanFee","estGasUpdateOPCFee","newSwapOceanFee","newSwapNonOceanFee","newConsumeFee","newProviderFee","updateOPCFee","_this55$getOwner","_this55$router$method","estGasAddPoolTemplate","templateAddress","addPoolTemplate","_this59$getOwner","_this59$router$method","estGasRemovePoolTemplate","removePoolTemplate","_this63$getOwner","_this63$router$method","Nft","nftAbi","factory721Address","factory721Abi","defaultNftAbi","estGasCreateErc20","nftAddress","nftContract","createERC20","createErc20","getNftPermissions","_this3$getNftPermissi","deployERC20","_nftContract$methods$","events","TokenCreated","returnValues","estGasAddManager","manager","addManager","getNftOwner","_this7$getNftOwner","_nftContract$methods$2","estGasRemoveManager","removeManager","_this11$getNftOwner","_nftContract$methods$3","estGasAddErc20Deployer","erc20Deployer","addToCreateERC20List","addErc20Deployer","_this15$getNftPermiss","_nftContract$methods$4","estGasRemoveErc20Deployer","removeFromCreateERC20List","removeErc20Deployer","_temp","_this19$getNftPermiss2","_nftContract$methods$5","_this19$getNftPermiss","estGasAddMetadataUpdater","metadataUpdater","addToMetadataList","addMetadataUpdater","_this23$getNftPermiss","_nftContract$methods$6","esGasRemoveMetadataUpdater","removeFromMetadataList","removeMetadataUpdater","_temp3","_this27$getNftPermiss2","updateMetadata","_nftContract$methods$7","_this27$getNftPermiss","estGasAddStoreUpdater","storeUpdater","addTo725StoreList","addStoreUpdater","_this31$getNftPermiss","_nftContract$methods$8","estGasRemoveStoreUpdater","removeFrom725StoreList","removeStoreUpdater","_temp5","_this35$getNftPermiss2","store","_nftContract$methods$9","_this35$getNftPermiss","estGasCleanPermissions","cleanPermissions","_this39$getNftOwner","_nftContract$methods$10","estGasTransferNft","nftOwner","nftReceiver","tokenId","transferFrom","transferNft","_this43$getNftOwner","tokenIdentifier","_nftContract$methods$11","estGasSafeTransferNft","safeTransferFrom","safeTransferNft","_this47$getNftOwner","_nftContract$methods$12","estGasSetMetadata","metadataState","metadataDecryptorUrl","metadataDecryptorAddress","flags","data","metadataHash","metadataProofs","setMetaData","setMetadata","_this51$getNftPermiss","_nftContract$methods$13","estGasSetMetadataAndTokenURI","metadataAndTokenURI","sanitizedMetadataAndTokenURI","setMetaDataAndTokenURI","setMetadataAndTokenURI","_this55$getNftPermiss","_nftContract$methods$14","estGasSetMetadataState","setMetaDataState","setMetadataState","_this59$getNftPermiss","_nftContract$methods$15","estSetTokenURI","setTokenURI","_nftContract$methods$16","setData","key","value","_this65$getNftPermiss","keyHash","keccak256","valueHex","asciiToHex","setNewData","_nftContract$methods$17","ownerOf","getPermissions","getMetadata","getMetaData","isErc20Deployer","isERC20Deployer","hexToAscii","getTokenURI","id","tokenURI","Datatoken","datatokensAbi","datatokensEnterpriseAbi","factoryAddress","factoryABI","nft","defaultDatatokensAbi","defaultDatatokensEnterpriseAbi","estGasApprove","dtContract","approve","_dtContract$methods$a","estGasMint","toAddress","mint","estGasCreateFixedRate","fixedRateParams","createFixedRate","_dtContract$methods$c","estGasCreateDispenser","dispenserParams","createDispenser","_dtContract$methods$c2","getDTPermissions","_this15$getDTPermissi","getCap","capAvailble","gte","_dtContract$methods$m","estGasAddMinter","addMinter","_this19$isERC20Deploy","_dtContract$methods$a2","estGasRemoveMinter","removeMinter","_this23$isERC20Deploy","_dtContract$methods$r","estGasAddPaymentManager","paymentManager","addPaymentManager","_this27$isERC20Deploy","_dtContract$methods$a3","estGasRemovePaymentManager","removePaymentManager","_this31$isERC20Deploy","_dtContract$methods$r2","estGasSetPaymentCollector","setPaymentCollector","nftPermissions","isPaymentManager","isNftOwner","_dtContract$methods$s","_this35$nft$getNftOwn","_this35$getDTPermissi","getNFTAddress","getPaymentCollector","transfer","weiAmount","transferWei","estGasTransfer","_dtContract$methods$t","estGasStartOrder","consumer","serviceIndex","providerFees","startOrder","consumeMarketFeeAddress","consumeMarketFeeToken","_dtContract$methods$s2","estGasReuseOrder","orderTxId","reuseOrder","_dtContract$methods$r3","estGasBuyFromFreAndOrder","orderParams","buyFromFreAndOrder","freContractParams","_dtContract$methods$b","estGasBuyFromDispenserAndOrder","buyFromDispenserAndOrder","_dtContract$methods$b2","estGasSetData","_dtContract$methods$s3","_this67$nft2","_this67$nft$getNftOwn","_dtContract$methods$c3","permissions","getDecimals","getERC721Address","estGasSetPublishingMarketFee","publishMarketFeeAddress","publishMarketFeeToken","publishMarketFeeAmount","setPublishingMarketFee","getPublishingMarketFee","_dtContract$methods$g","_dtContract$methods$s4","publishingMarketFee","NftFactory","factory721","defaultFactory721Abi","estGasCreateNFT","nftData","deployERC721Contract","transferable","createNFT","getCurrentNFTTemplateCount","_nftData$templateInde2","getNFTTemplate","_this3$getNFTTemplate","_this3$factory721$met","NFTCreated","getCurrentNFTCount","getCurrentTokenCount","getCurrentTokenTemplateCount","getCurrentTemplateCount","index","getTokenTemplate","checkDatatoken","erc20List","checkNFT","erc721List","estGasAddNFTTemplate","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$getTokenTempl","_this41$factory721$me","estGasReactivateTokenTemplate","reactivateTokenTemplate","_this45$getOwner","_this45$getTokenTempl","_this45$factory721$me","estGasStartMultipleTokenOrder","orders","startMultipleTokenOrder","_this49$factory721$me","estGasCreateNftWithErc20","nftCreateData","ercCreateData","createNftWithErc20","_this53$factory721$me","estGasCreateNftErc20WithPool","poolData","createNftWithErc20WithPool","createNftErc20WithPool","_this57$factory721$me","estGasCreateNftErc20WithFixedRate","fixedData","createNftWithErc20WithFixedRate","createNftErc20WithFixedRate","_this61$factory721$me","estGasCreateNftErc20WithDispenser","createNftWithErc20WithDispenser","createNftErc20WithDispenser","_this65$factory721$me","noZeroX","input","zeroOutput","regexp","conversorName","match","output","inputMatch","zeroXTransformer","Provider","getEndpoints","endpoints","getEndpointURL","servicesEndpoints","serviceName","getServiceEndpoints","providerEndpoint","serviceEndpoints","i","push","urlPath","getNonce","consumerAddress","providerEndpoints","nonce","signProviderRequest","accountId","password","consumerMessage","soliditySha3","t","utf8ToHex","currentProvider","isMetaMask","personal","sign","encrypt","text","checkDidFiles","serviceId","withChecksum","args","checksum","files","results","checkFileUrl","getComputeEnvironments","_this10$getEndpointUR","initialize","fileIndex","userCustomParameters","computeEnv","validUntil","initializeUrl","encodeURI","initializeCompute","assets","algorithm","providerData","datasets","compute","getDownloadUrl","transferTxId","downloadUrl","Date","now","signature","consumeUrl","computeStart","dataset","additionalDatasets","computeStartUrl","signatureMessage","documentId","payload","Object","environment","params","computeStop","jobId","computeStopUrl","computeStatus","computeStatusUrl","getComputeResultUrl","computeResultUrl","resultUrl","computeDelete","computeDeleteUrl","isValidProvider","providerAddress","ProviderInstance","web3Provider","erc721FFactoryABI","datatokensABI","poolFactoryABI","poolABI","fixedRateExchangeAddressABI","dispenserABI","verbose","authMessage","authTokenExpiration","parityUri","threshold","force","_tokenContract$method2","currentAllowence","_tokenContract$method4","gt","filename","get","split","pop","arrayBuffer","headResponse","fileName","xhr","XMLHttpRequest","responseType","open","onload","blobURL","window","URL","createObjectURL","a","document","createElement","href","setAttribute","appendChild","click","remove","revokeObjectURL","recipient","opts","_error2","erc721Address","toChecksumAddress","sha256","postWithHeaders","signedMessage","substr","slice","_tokenContract$method6"],"mappings":"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"}
1
+ {"version":3,"file":"lib.js","sources":["../src/utils/Constants.ts","../src/utils/ContractUtils.ts","../src/utils/DatatokenName.ts","../src/utils/FetchHelper.ts","../src/utils/Logger.ts","../src/utils/General.ts","../src/utils/minAbi.ts","../src/utils/TokenUtils.ts","../src/config/ConfigHelper.ts","../src/contracts/SmartContract.ts","../src/contracts/SmartContractWithAddress.ts","../src/contracts/Dispenser.ts","../src/contracts/FixedRateExchange.ts","../src/contracts/Router.ts","../src/contracts/NFT.ts","../src/contracts/Datatoken.ts","../src/contracts/NFTFactory.ts","../src/contracts/ve/VeOcean.ts","../src/contracts/ve/VeFeeDistributor.ts","../src/contracts/ve/VeAllocate.ts","../src/contracts/df/DfRewards.ts","../src/contracts/df/DfStrategyV1.ts","../src/services/Aquarius.ts","../src/services/Provider.ts","../src/config/Config.ts","../src/utils/DdoHelpers.ts","../src/utils/SignatureUtils.ts"],"sourcesContent":["export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'\nexport const GASLIMIT_DEFAULT = 1000000\nexport const MAX_UINT_256 =\n '115792089237316195423570985008687907853269984665640564039457584007913129639934'\nexport const FEE_HISTORY_NOT_SUPPORTED =\n 'Returned error: Method eth_feeHistory not supported.'\n","import Web3 from 'web3'\nimport BigNumber from 'bignumber.js'\nimport { Contract } from 'web3-eth-contract'\nimport { Config } from '../config'\nimport { minAbi, GASLIMIT_DEFAULT, LoggerInstance, FEE_HISTORY_NOT_SUPPORTED } from '.'\nimport { TransactionReceipt } from 'web3-core'\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(\n web3: Web3,\n gasFeeMultiplier: number\n): Promise<string> {\n const x = new BigNumber(await web3.eth.getGasPrice())\n if (gasFeeMultiplier)\n return x\n .multipliedBy(gasFeeMultiplier)\n .integerValue(BigNumber.ROUND_DOWN)\n .toString(10)\n else return x.toString(10)\n}\n\nexport async function unitsToAmount(\n web3: Web3,\n token: string,\n amount: string,\n tokenDecimals?: number\n): Promise<string> {\n const tokenContract = new web3.eth.Contract(minAbi, token)\n let decimals = tokenDecimals || (await tokenContract.methods.decimals().call())\n if (decimals === '0') {\n decimals = 18\n }\n\n const amountFormatted = new BigNumber(amount).div(\n new BigNumber(10).exponentiatedBy(decimals)\n )\n\n BigNumber.config({ EXPONENTIAL_AT: 50 })\n return amountFormatted.toString()\n}\n\nexport async function amountToUnits(\n web3: Web3,\n token: string,\n amount: string,\n tokenDecimals?: number\n): Promise<string> {\n const tokenContract = new web3.eth.Contract(minAbi, token)\n let decimals = tokenDecimals || (await tokenContract.methods.decimals().call())\n if (decimals === '0') {\n decimals = 18\n }\n BigNumber.config({ EXPONENTIAL_AT: 50 })\n\n const amountFormatted = new BigNumber(amount).times(\n new BigNumber(10).exponentiatedBy(decimals)\n )\n return amountFormatted.toFixed(0)\n}\n\n/**\n * Estimates the gas used when a function would be executed on chain\n * @param {string} from account that calls the function\n * @param {Function} functionToEstimateGas function that we need to estimate the gas\n * @param {...any[]} args arguments of the function\n * @return {Promise<number>} gas cost of the function\n */\nexport async function calculateEstimatedGas(\n from: string,\n functionToEstimateGas: Function,\n ...args: any[]\n): Promise<number> {\n const estimatedGas = await functionToEstimateGas\n .apply(null, args)\n .estimateGas({ from }, (err, estGas) => (err ? GASLIMIT_DEFAULT : estGas))\n return estimatedGas\n}\n\n/**\n * Send the transation on chain\n * @param {string} from account that calls the function\n * @param {any} estGas estimated gas for the transaction\n * @param {Web3} web3 web3 objcet\n * @param {Function} functionToSend function that we need to send\n * @param {...any[]} args arguments of the function\n * @return {Promise<any>} transaction receipt\n */\nexport async function sendTx(\n from: string,\n estGas: number,\n web3: Web3,\n gasFeeMultiplier: number,\n functionToSend: Function,\n ...args: any[]\n): Promise<TransactionReceipt> {\n const sendTxValue: Record<string, any> = {\n from,\n gas: estGas + 1\n }\n try {\n const feeHistory = await web3.eth.getFeeHistory(1, 'latest', [75])\n if (feeHistory && feeHistory?.baseFeePerGas?.[0] && feeHistory?.reward?.[0]?.[0]) {\n let aggressiveFee = new BigNumber(feeHistory?.reward?.[0]?.[0])\n if (gasFeeMultiplier > 1) {\n aggressiveFee = aggressiveFee.multipliedBy(gasFeeMultiplier)\n }\n\n sendTxValue.maxPriorityFeePerGas = aggressiveFee\n .integerValue(BigNumber.ROUND_DOWN)\n .toString(10)\n\n sendTxValue.maxFeePerGas = aggressiveFee\n .plus(new BigNumber(feeHistory?.baseFeePerGas?.[0]).multipliedBy(2))\n .integerValue(BigNumber.ROUND_DOWN)\n .toString(10)\n } else {\n sendTxValue.gasPrice = await getFairGasPrice(web3, gasFeeMultiplier)\n }\n } catch (err) {\n err?.message === FEE_HISTORY_NOT_SUPPORTED &&\n LoggerInstance.log(\n 'Not able to use EIP 1559, getFeeHistory method not suported by network.'\n )\n sendTxValue.gasPrice = await getFairGasPrice(web3, gasFeeMultiplier)\n }\n\n const trxReceipt = await functionToSend.apply(null, args).send(sendTxValue)\n return trxReceipt\n}\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 fetch from 'cross-fetch'\nimport { DownloadResponse } from '../@types'\n\nexport async function downloadFileBrowser(url: string): Promise<void> {\n const headResponse = await fetch(url, { method: 'HEAD' })\n const contentHeader = headResponse.headers.get('content-disposition')\n const fileName = contentHeader.split('=')[1]\n const xhr = new XMLHttpRequest()\n xhr.responseType = 'blob'\n xhr.open('GET', url)\n xhr.onload = () => {\n const blobURL = window.URL.createObjectURL(xhr.response)\n const a = document.createElement('a')\n a.href = blobURL\n a.setAttribute('download', fileName)\n document.body.appendChild(a)\n a.click()\n a.remove()\n window.URL.revokeObjectURL(blobURL)\n }\n xhr.send(null)\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","/* eslint-disable no-unused-vars */\nexport enum LogLevel {\n None = -1,\n Error = 0,\n Warn = 1,\n Log = 2,\n Verbose = 3\n}\n/* eslint-enable no-unused-vars */\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()\n","/**\n * Simple blocking sleep function\n */\nexport async function sleep(ms: number) {\n return new Promise((resolve) => {\n setTimeout(resolve, ms)\n })\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 Decimal from 'decimal.js'\nimport Web3 from 'web3'\nimport BigNumber from 'bignumber.js'\nimport {\n amountToUnits,\n calculateEstimatedGas,\n unitsToAmount,\n minAbi,\n sendTx,\n LoggerInstance\n} from '.'\nimport { Config } from '../config'\nimport { ReceiptOrEstimate } from '../@types'\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 amount of ERC20 Datatokens (always expressed as wei)\n * @param {boolean} force if true, will overwrite any previous allowence. Else, will check if allowence is enough and will not send a transaction if it's not needed\n * @param {number} tokenDecimals optional number of decimals of the token\n */\nexport async function approve<G extends boolean = false>(\n web3: Web3,\n config: Config,\n account: string,\n tokenAddress: string,\n spender: string,\n amount: string,\n force = false,\n tokenDecimals?: number,\n estimateGas?: G\n): Promise<ReceiptOrEstimate<G>> {\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 null\n }\n }\n const amountFormatted = await amountToUnits(web3, tokenAddress, amount, tokenDecimals)\n const estGas = await calculateEstimatedGas(\n account,\n tokenContract.methods.approve,\n spender,\n amountFormatted\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n account,\n estGas + 1,\n web3,\n config?.gasFeeMultiplier,\n tokenContract.methods.approve,\n spender,\n amountFormatted\n )\n return <ReceiptOrEstimate<G>>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 amount of ERC20 tokens (always expressed as wei)\n * @param {boolean} force if true, will overwrite any previous allowence. Else, will check if allowence is enough and will not send a transaction if it's not needed\n */\nexport async function approveWei<G extends boolean = false>(\n web3: Web3,\n config: Config,\n account: string,\n tokenAddress: string,\n spender: string,\n amount: string,\n force = false,\n estimateGas?: G\n): Promise<ReceiptOrEstimate<G>> {\n const tokenContract = new web3.eth.Contract(minAbi, tokenAddress)\n if (!force) {\n const currentAllowence = await allowanceWei(web3, tokenAddress, account, spender)\n if (new BigNumber(currentAllowence).gt(new BigNumber(amount))) {\n return null\n }\n }\n let result = null\n\n const estGas = await calculateEstimatedGas(\n account,\n tokenContract.methods.approve,\n spender,\n amount\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n try {\n result = await sendTx(\n account,\n estGas + 1,\n web3,\n config?.gasFeeMultiplier,\n tokenContract.methods.approve,\n spender,\n amount\n )\n } catch (e) {\n LoggerInstance.error(\n `ERROR: Failed to approve spender to spend tokens : ${e.message}`\n )\n }\n return result\n}\n\n/**\n * Moves amount tokens from the caller’s account to recipient.\n * @param {String} account\n * @param {String} tokenAddress\n * @param {String} recipient\n * @param {String} amount amount of ERC20 Datatokens (not 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 transfer<G extends boolean = false>(\n web3: Web3,\n config: Config,\n account: string,\n tokenAddress: string,\n recipient: string,\n amount: string,\n estimateGas?: G\n): Promise<ReceiptOrEstimate<G>> {\n const tokenContract = new web3.eth.Contract(minAbi, tokenAddress)\n\n const amountFormatted = await amountToUnits(web3, tokenAddress, amount)\n const estGas = await calculateEstimatedGas(\n account,\n tokenContract.methods.transfer,\n recipient,\n amountFormatted\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n account,\n estGas + 1,\n web3,\n config?.gasFeeMultiplier,\n tokenContract.methods.transfer,\n recipient,\n amountFormatted\n )\n return <ReceiptOrEstimate<G>>trxReceipt\n}\n\n/**\n * Get Allowance for any Datatoken\n * @param {Web3} web3\n * @param {String } tokenAdress\n * @param {String} account\n * @param {String} spender\n * @param {number} tokenDecimals optional number of decimals of the token\n */\nexport async function allowance(\n web3: Web3,\n tokenAddress: string,\n account: string,\n spender: string,\n tokenDecimals?: number\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, tokenDecimals)\n}\n\n/**\n * Get balance for any Datatoken\n * @param {Web3} web3\n * @param {String} tokenAdress\n * @param {String} owner\n * @param {String} spender\n * @param {number} tokenDecimals optional number of decimals of the token\n */\nexport async function balance(\n web3: Web3,\n tokenAddress: string,\n account: string,\n tokenDecimals?: number\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, tokenDecimals)\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 allowanceWei(\n web3: Web3,\n tokenAddress: string,\n account: string,\n spender: string,\n tokenDecimals?: number\n): Promise<string> {\n const tokenContract = new web3.eth.Contract(minAbi, tokenAddress)\n return await tokenContract.methods.allowance(account, spender).call()\n}\n\n/**\n * Get decimals for any Datatoken\n * @param {Web3} web3\n * @param {String} tokenAdress\n * @return {Promise<number>} Number of decimals of the token\n */\nexport async function decimals(web3: Web3, tokenAddress: string): Promise<number> {\n const tokenContract = new web3.eth.Contract(minAbi, tokenAddress)\n return await tokenContract.methods.decimals().call()\n}\n","// eslint-disable-next-line import/no-named-default\nimport { default as DefaultContractsAddresses } from '@oceanprotocol/contracts/addresses/address.json'\nimport { Config } from '.'\nimport { LoggerInstance } from '../utils'\n\nconst configHelperNetworksBase: Config = {\n chainId: null,\n network: 'unknown',\n metadataCacheUri: 'https://v4.aquarius.oceanprotocol.com',\n nodeUri: 'http://127.0.0.1:8545',\n providerUri: 'http://127.0.0.1:8030',\n subgraphUri: null,\n explorerUri: null,\n oceanTokenAddress: null,\n oceanTokenSymbol: 'OCEAN',\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 providerUri: 'http://172.15.0.4:8030'\n },\n {\n ...configHelperNetworksBase,\n chainId: 3,\n network: 'ropsten',\n nodeUri: 'https://ropsten.infura.io/v3',\n providerUri: 'https://v4.provider.ropsten.oceanprotocol.com',\n subgraphUri: 'https://v4.subgraph.ropsten.oceanprotocol.com',\n explorerUri: 'https://ropsten.etherscan.io',\n gasFeeMultiplier: 1.1\n },\n {\n ...configHelperNetworksBase,\n chainId: 4,\n network: 'rinkeby',\n nodeUri: 'https://rinkeby.infura.io/v3',\n providerUri: 'https://v4.provider.rinkeby.oceanprotocol.com',\n subgraphUri: 'https://v4.subgraph.rinkeby.oceanprotocol.com',\n explorerUri: 'https://rinkeby.etherscan.io',\n gasFeeMultiplier: 1.1\n },\n {\n ...configHelperNetworksBase,\n chainId: 1,\n network: 'mainnet',\n nodeUri: 'https://mainnet.infura.io/v3',\n providerUri: 'https://v4.provider.mainnet.oceanprotocol.com',\n subgraphUri: 'https://v4.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://v4.provider.polygon.oceanprotocol.com',\n subgraphUri: 'https://v4.subgraph.polygon.oceanprotocol.com',\n explorerUri: 'https://polygonscan.com',\n oceanTokenSymbol: 'mOCEAN'\n },\n {\n ...configHelperNetworksBase,\n chainId: 1287,\n network: 'moonbase',\n nodeUri: 'https://rpc.api.moonbase.moonbeam.network',\n providerUri: 'https://v4.provider.moonbase.oceanprotocol.com',\n subgraphUri: 'https://v4.subgraph.moonbase.oceanprotocol.com',\n explorerUri: 'https://moonbase.moonscan.io/',\n gasFeeMultiplier: 1.1\n },\n {\n ...configHelperNetworksBase,\n chainId: 2021000,\n network: 'gaiaxtestnet',\n nodeUri: 'https://rpc.gaiaxtestnet.oceanprotocol.com',\n providerUri: 'https://v4.provider.gaiaxtestnet.oceanprotocol.com',\n subgraphUri: 'https://v4.subgraph.gaiaxtestnet.oceanprotocol.com',\n explorerUri: 'https://blockscout.gaiaxtestnet.oceanprotocol.com'\n },\n {\n ...configHelperNetworksBase,\n chainId: 80001,\n network: 'mumbai',\n nodeUri: 'https://polygon-mumbai.infura.io/v3',\n providerUri: 'https://v4.provider.mumbai.oceanprotocol.com',\n subgraphUri: 'https://v4.subgraph.mumbai.oceanprotocol.com',\n explorerUri: 'https://mumbai.polygonscan.com',\n gasFeeMultiplier: 1.1\n },\n {\n ...configHelperNetworksBase,\n chainId: 56,\n network: 'bsc',\n nodeUri: 'https://bsc-dataseed.binance.org',\n providerUri: 'https://v4.provider.bsc.oceanprotocol.com',\n subgraphUri: 'https://v4.subgraph.bsc.oceanprotocol.com',\n explorerUri: 'https://bscscan.com/',\n gasFeeMultiplier: 1.05\n },\n {\n ...configHelperNetworksBase,\n chainId: 246,\n network: 'energyweb',\n nodeUri: 'https://rpc.energyweb.org',\n providerUri: 'https://v4.provider.energyweb.oceanprotocol.com',\n subgraphUri: 'https://v4.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://v4.provider.moonriver.oceanprotocol.com',\n subgraphUri: 'https://v4.subgraph.moonriver.oceanprotocol.com',\n explorerUri: 'https://moonriver.moonscan.io/',\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 const {\n FixedPrice,\n Dispenser,\n ERC721Factory,\n OPFCommunityFeeCollector,\n Ocean,\n chainId,\n startBlock\n } = customAddresses[network]\n configAddresses = {\n nftFactoryAddress: ERC721Factory,\n opfCommunityFeeCollector: OPFCommunityFeeCollector,\n fixedRateExchangeAddress: FixedPrice,\n dispenserAddress: Dispenser,\n oceanTokenAddress: Ocean,\n chainId,\n startBlock,\n ...(process.env.AQUARIUS_URI && { metadataCacheUri: process.env.AQUARIUS_URI })\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 OPFCommunityFeeCollector,\n ERC721Factory,\n Ocean,\n chainId,\n startBlock\n } = DefaultContractsAddresses[network]\n configAddresses = {\n nftFactoryAddress: ERC721Factory,\n opfCommunityFeeCollector: OPFCommunityFeeCollector,\n fixedRateExchangeAddress: FixedPrice,\n dispenserAddress: Dispenser,\n oceanTokenAddress: Ocean,\n chainId,\n 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 Web3 from 'web3'\nimport { Contract } from 'web3-eth-contract'\nimport { AbiItem } from 'web3-utils'\nimport { Config, ConfigHelper } from '../config'\nimport {\n amountToUnits,\n getFairGasPrice,\n setContractDefaults,\n unitsToAmount\n} from '../utils'\n\nexport abstract class SmartContract {\n public web3: Web3\n public config: Config\n public abi: AbiItem | AbiItem[]\n\n abstract getDefaultAbi(): AbiItem | AbiItem[]\n\n /**\n * Instantiate the smart contract.\n * @param {Web3} web3\n * @param {string | number} network Network id or name\n * @param {Config} config Configutation of the smart contract\n * @param {AbiItem | AbiItem[]} abi ABI of the smart contract\n */\n constructor(\n web3: Web3,\n network?: string | number,\n config?: Config,\n abi?: AbiItem | AbiItem[]\n ) {\n this.web3 = web3\n this.config = config || new ConfigHelper().getConfig(network || 'unknown')\n this.abi = abi || (this.getDefaultAbi() as AbiItem[])\n }\n\n protected async amountToUnits(\n token: string,\n amount: string,\n tokenDecimals?: number\n ): Promise<string> {\n return amountToUnits(this.web3, token, amount, tokenDecimals)\n }\n\n protected async unitsToAmount(\n token: string,\n amount: string,\n tokenDecimals?: number\n ): Promise<string> {\n return unitsToAmount(this.web3, token, amount, tokenDecimals)\n }\n\n protected async getFairGasPrice(): Promise<string> {\n return getFairGasPrice(this.web3, this.config?.gasFeeMultiplier)\n }\n\n protected getContract(\n address: string,\n account?: string,\n abi?: AbiItem | AbiItem[]\n ): Contract {\n const contract = new this.web3.eth.Contract(abi || this.abi, address, {\n from: account\n })\n return setContractDefaults(contract, this.config)\n }\n}\n","import Web3 from 'web3'\nimport { Contract } from 'web3-eth-contract'\nimport { AbiItem } from 'web3-utils'\nimport { Config } from '../config'\nimport { SmartContract } from './SmartContract'\n\nexport abstract class SmartContractWithAddress extends SmartContract {\n public address: string\n public contract: Contract\n\n /**\n * Instantiate the smart contract.\n * @param {string} address Address of the smart contract\n * @param {Web3} web3\n * @param {string | number} network Network id or name\n * @param {Config} config Configutation of the smart contract\n * @param {AbiItem | AbiItem[]} abi ABI of the smart contract\n */\n constructor(\n address: string,\n web3: Web3,\n network?: string | number,\n config?: Config,\n abi?: AbiItem | AbiItem[]\n ) {\n super(web3, network, config, abi)\n this.address = address\n this.contract = this.getContract(this.address)\n }\n}\n","import { AbiItem } from 'web3-utils'\nimport Decimal from 'decimal.js'\nimport DispenserAbi from '@oceanprotocol/contracts/artifacts/contracts/pools/dispenser/Dispenser.sol/Dispenser.json'\nimport { calculateEstimatedGas, sendTx } from '../utils'\nimport { Datatoken } from './Datatoken'\nimport { SmartContractWithAddress } from './SmartContractWithAddress'\nimport { DispenserToken, ReceiptOrEstimate } from '../@types'\n\nexport class Dispenser extends SmartContractWithAddress {\n getDefaultAbi(): AbiItem | AbiItem[] {\n return DispenserAbi.abi as AbiItem[]\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 const status: DispenserToken = await this.contract.methods.status(dtAdress).call()\n if (!status) {\n throw new Error(`Np dispenser found for the given datatoken address`)\n }\n status.maxTokens = this.web3.utils.fromWei(status.maxTokens)\n status.maxBalance = this.web3.utils.fromWei(status.maxBalance)\n status.balance = this.web3.utils.fromWei(status.balance)\n return status\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<ReceiptOrEstimate>} transactionId\n */\n public async create<G extends boolean = false>(\n dtAddress: string,\n address: string,\n maxTokens: string,\n maxBalance: string,\n allowedSwapper: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.create,\n dtAddress,\n this.web3.utils.toWei(maxTokens),\n this.web3.utils.toWei(maxBalance),\n address,\n allowedSwapper\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n // Call createFixedRate contract method\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.create,\n dtAddress,\n this.web3.utils.toWei(maxTokens),\n this.web3.utils.toWei(maxBalance),\n address,\n allowedSwapper\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\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<ReceiptOrEstimate>} TransactionReceipt\n */\n public async activate<G extends boolean = false>(\n dtAddress: string,\n maxTokens: string,\n maxBalance: string,\n address: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.activate,\n dtAddress,\n this.web3.utils.toWei(maxTokens),\n this.web3.utils.toWei(maxBalance)\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.activate,\n dtAddress,\n this.web3.utils.toWei(maxTokens),\n this.web3.utils.toWei(maxBalance)\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\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<ReceiptOrEstimate>} TransactionReceipt\n */\n public async deactivate<G extends boolean = false>(\n dtAddress: string,\n address: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.deactivate,\n dtAddress\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.deactivate,\n dtAddress\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\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<ReceiptOrEstimate>} TransactionReceipt\n */\n public async setAllowedSwapper<G extends boolean = false>(\n dtAddress: string,\n address: string,\n newAllowedSwapper: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.setAllowedSwapper,\n dtAddress,\n newAllowedSwapper\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.setAllowedSwapper,\n dtAddress,\n newAllowedSwapper\n )\n return <ReceiptOrEstimate<G>>trxReceipt\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<ReceiptOrEstimate>} TransactionReceipt\n */\n public async dispense<G extends boolean = false>(\n dtAddress: string,\n address: string,\n amount: string = '1',\n destination: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.dispense,\n dtAddress,\n this.web3.utils.toWei(amount),\n destination\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.dispense,\n dtAddress,\n this.web3.utils.toWei(amount),\n destination\n )\n return <ReceiptOrEstimate<G>>trxReceipt\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<ReceiptOrEstimate>} TransactionReceipt\n */\n public async ownerWithdraw<G extends boolean = false>(\n dtAddress: string,\n address: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.ownerWithdraw,\n dtAddress\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.ownerWithdraw,\n dtAddress\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\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 FixedRateExchangeAbi from '@oceanprotocol/contracts/artifacts/contracts/pools/fixedRate/FixedRateExchange.sol/FixedRateExchange.json'\nimport { AbiItem } from 'web3-utils/types'\nimport { calculateEstimatedGas, sendTx, ZERO_ADDRESS } from '../utils'\nimport { PriceAndFees, FeesInfo, FixedPriceExchange, ReceiptOrEstimate } from '../@types'\nimport { SmartContractWithAddress } from './SmartContractWithAddress'\n\nexport class FixedRateExchange extends SmartContractWithAddress {\n getDefaultAbi(): AbiItem | AbiItem[] {\n return FixedRateExchangeAbi.abi as AbiItem[]\n }\n\n /**\n * Creates unique exchange identifier.\n * @param {String} baseToken baseToken contract address\n * @param {String} datatoken Datatoken contract address\n * @return {Promise<string>} exchangeId\n */\n public async generateExchangeId(baseToken: string, datatoken: string): Promise<string> {\n const exchangeId = await this.contract.methods\n .generateExchangeId(baseToken, datatoken)\n .call()\n return exchangeId\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 * @param {String} consumeMarketAddress consumeMarketAddress\n * @param {String} consumeMarketFee consumeMarketFee in fraction\n * @return {Promise<ReceiptOrEstimate>} transaction receipt\n */\n public async buyDatatokens<G extends boolean = false>(\n address: string,\n exchangeId: string,\n datatokenAmount: string,\n maxBaseTokenAmount: string,\n consumeMarketAddress: string = ZERO_ADDRESS,\n consumeMarketFee: string = '0',\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const exchange = await this.getExchange(exchangeId)\n const consumeMarketFeeFormatted = this.web3.utils.toWei(consumeMarketFee)\n const dtAmountFormatted = await this.amountToUnits(\n exchange.datatoken,\n datatokenAmount,\n +exchange.dtDecimals\n )\n const maxBtFormatted = await this.amountToUnits(\n exchange.baseToken,\n maxBaseTokenAmount,\n +exchange.btDecimals\n )\n\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.buyDT,\n exchangeId,\n dtAmountFormatted,\n maxBtFormatted,\n consumeMarketAddress,\n consumeMarketFeeFormatted\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.buyDT,\n exchangeId,\n dtAmountFormatted,\n maxBtFormatted,\n consumeMarketAddress,\n consumeMarketFeeFormatted\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Sell datatokenAmount while expecting at least minBaseTokenAmount\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 * @param {String} consumeMarketAddress consumeMarketAddress\n * @param {String} consumeMarketFee consumeMarketFee in fraction\n * @return {Promise<ReceiptOrEstimate>} transaction receipt\n */\n public async sellDatatokens<G extends boolean = false>(\n address: string,\n exchangeId: string,\n datatokenAmount: string,\n minBaseTokenAmount: string,\n consumeMarketAddress: string = ZERO_ADDRESS,\n consumeMarketFee: string = '0',\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const exchange = await this.getExchange(exchangeId)\n const consumeMarketFeeFormatted = this.web3.utils.toWei(consumeMarketFee)\n const dtAmountFormatted = await this.amountToUnits(\n exchange.datatoken,\n datatokenAmount,\n +exchange.dtDecimals\n )\n const minBtFormatted = await this.amountToUnits(\n exchange.baseToken,\n minBaseTokenAmount,\n +exchange.btDecimals\n )\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.sellDT,\n exchangeId,\n dtAmountFormatted,\n minBtFormatted,\n consumeMarketAddress,\n consumeMarketFeeFormatted\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.sellDT,\n exchangeId,\n dtAmountFormatted,\n minBtFormatted,\n consumeMarketAddress,\n consumeMarketFeeFormatted\n )\n return <ReceiptOrEstimate<G>>trxReceipt\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 * Set new rate\n * @param {String} exchangeId ExchangeId\n * @param {String} newRate New rate\n * @param {String} address User account\n * @return {Promise<ReceiptOrEstimate>} transaction receipt\n */\n public async setRate<G extends boolean = false>(\n address: string,\n exchangeId: string,\n newRate: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.setRate,\n exchangeId,\n this.web3.utils.toWei(newRate)\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.setRate,\n exchangeId,\n this.web3.utils.toWei(newRate)\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Sets a new allowedSwapper\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<ReceiptOrEstimate>} transaction receipt\n */\n public async setAllowedSwapper<G extends boolean = false>(\n address: string,\n exchangeId: string,\n newAllowedSwapper: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.setAllowedSwapper,\n exchangeId,\n newAllowedSwapper\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.setAllowedSwapper,\n exchangeId,\n newAllowedSwapper\n )\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Activate an exchange\n * @param {String} exchangeId ExchangeId\n * @param {String} address User address\n * @return {Promise<ReceiptOrEstimate>} transaction receipt\n */\n public async activate<G extends boolean = false>(\n address: string,\n exchangeId: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const exchange = await this.getExchange(exchangeId)\n if (!exchange) return null\n if (exchange.active === true) return null\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.toggleExchangeState,\n exchangeId\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.toggleExchangeState,\n exchangeId\n )\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Deactivate an exchange\n * @param {String} exchangeId ExchangeId\n * @param {String} address User address\n * @return {Promise<ReceiptOrEstimate>} transaction receipt\n */\n public async deactivate<G extends boolean = false>(\n address: string,\n exchangeId: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const exchange = await this.getExchange(exchangeId)\n if (!exchange) return null\n if (exchange.active === false) return null\n\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.toggleExchangeState,\n exchangeId\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.toggleExchangeState,\n exchangeId\n )\n return <ReceiptOrEstimate<G>>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 const rate = await this.web3.utils.fromWei(weiRate)\n return rate\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 getDatatokenSupply(exchangeId: string): Promise<string> {\n const dtSupply = await this.contract.methods.getDTSupply(exchangeId).call()\n const exchange = await this.getExchange(exchangeId)\n return await this.unitsToAmount(exchange.datatoken, dtSupply, +exchange.dtDecimals)\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 getBasetokenSupply(exchangeId: string): Promise<string> {\n const btSupply = await this.contract.methods.getBTSupply(exchangeId).call()\n const exchange = await this.getExchange(exchangeId)\n return await this.unitsToAmount(exchange.baseToken, btSupply, +exchange.btDecimals)\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 * calcBaseInGivenDatatokensOut - Calculates how many base tokens are needed to get specified amount of datatokens\n * @param {String} exchangeId ExchangeId\n * @param {string} datatokenAmount Amount of datatokens user wants to buy\n * @param {String} consumeMarketFee consumeMarketFee in fraction\n * @return {Promise<PriceAndFees>} how many base tokens are needed and fees\n */\n public async calcBaseInGivenDatatokensOut(\n exchangeId: string,\n datatokenAmount: string,\n consumeMarketFee: string = '0'\n ): Promise<PriceAndFees> {\n const fixedRateExchange = await this.getExchange(exchangeId)\n const outDT = await this.contract.methods\n .calcBaseInGivenOutDT(\n exchangeId,\n await this.amountToUnits(\n fixedRateExchange.datatoken,\n datatokenAmount,\n +fixedRateExchange.dtDecimals\n ),\n this.web3.utils.toWei(consumeMarketFee)\n )\n .call()\n\n const priceAndFees = {\n baseTokenAmount: await this.unitsToAmount(\n fixedRateExchange.baseToken,\n outDT.baseTokenAmount,\n +fixedRateExchange.btDecimals\n ),\n marketFeeAmount: await this.unitsToAmount(\n fixedRateExchange.baseToken,\n outDT.marketFeeAmount,\n +fixedRateExchange.btDecimals\n ),\n oceanFeeAmount: await this.unitsToAmount(\n fixedRateExchange.baseToken,\n outDT.oceanFeeAmount,\n +fixedRateExchange.btDecimals\n ),\n consumeMarketFeeAmount: await this.unitsToAmount(\n fixedRateExchange.baseToken,\n outDT.consumeMarketFeeAmount,\n +fixedRateExchange.btDecimals\n )\n } as PriceAndFees\n return priceAndFees\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 * @param {String} consumeMarketFee consumeMarketFee in fraction\n * @return {Promise<string>} Amount of baseTokens user will receive\n */\n public async getAmountBasetokensOut(\n exchangeId: string,\n datatokenAmount: string,\n consumeMarketFee: string = '0'\n ): Promise<string> {\n const exchange = await this.getExchange(exchangeId)\n const amount = await this.contract.methods\n .calcBaseOutGivenInDT(\n exchangeId,\n await this.amountToUnits(\n exchange.datatoken,\n datatokenAmount,\n +exchange.dtDecimals\n ),\n this.web3.utils.toWei(consumeMarketFee)\n )\n .call()\n\n return await this.unitsToAmount(exchange.baseToken, amount[0], +exchange.btDecimals)\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 exchange: FixedPriceExchange = await this.contract.methods\n .getExchange(exchangeId)\n .call()\n exchange.dtDecimals = exchange.dtDecimals.toString()\n exchange.btDecimals = exchange.btDecimals.toString()\n exchange.dtBalance = await this.unitsToAmount(\n exchange.datatoken,\n exchange.dtBalance,\n +exchange.dtDecimals\n )\n exchange.btBalance = await this.unitsToAmount(\n exchange.baseToken,\n exchange.btBalance,\n +exchange.btDecimals\n )\n exchange.dtSupply = await this.unitsToAmount(\n exchange.datatoken,\n exchange.dtSupply,\n +exchange.dtDecimals\n )\n exchange.btSupply = await this.unitsToAmount(\n exchange.baseToken,\n exchange.btSupply,\n +exchange.btDecimals\n )\n exchange.fixedRate = this.web3.utils.fromWei(exchange.fixedRate)\n exchange.exchangeId = exchangeId\n return exchange\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 feesInfo: FeesInfo = await this.contract.methods.getFeesInfo(exchangeId).call()\n feesInfo.opcFee = this.web3.utils.fromWei(feesInfo.opcFee.toString())\n feesInfo.marketFee = this.web3.utils.fromWei(feesInfo.marketFee.toString())\n\n const exchange = await this.getExchange(exchangeId)\n feesInfo.marketFeeAvailable = await this.unitsToAmount(\n exchange.baseToken,\n feesInfo.marketFeeAvailable,\n +exchange.btDecimals\n )\n feesInfo.oceanFeeAvailable = await this.unitsToAmount(\n exchange.baseToken,\n feesInfo.oceanFeeAvailable,\n +exchange.btDecimals\n )\n\n feesInfo.exchangeId = exchangeId\n return feesInfo\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 active = await this.contract.methods.isActive(exchangeId).call()\n return active\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<ReceiptOrEstimate>} transaction receipt\n */\n public async activateMint<G extends boolean = false>(\n address: string,\n exchangeId: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const exchange = await this.getExchange(exchangeId)\n if (!exchange) return null\n if (exchange.withMint === true) return null\n\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.toggleMintState,\n exchangeId,\n true\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.toggleMintState,\n exchangeId,\n true\n )\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Deactivate minting for fixed rate\n * @param {String} exchangeId ExchangeId\n * @param {String} address User address\n * @return {Promise<ReceiptOrEstimate>} transaction receipt\n */\n public async deactivateMint<G extends boolean = false>(\n address: string,\n exchangeId: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const exchange = await this.getExchange(exchangeId)\n if (!exchange) return null\n if (exchange.withMint === false) return null\n\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.toggleMintState,\n exchangeId,\n false\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.toggleMintState,\n exchangeId,\n false\n )\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Collect BaseTokens in the contract (anyone can call this, funds are sent to Datatoken.paymentCollector)\n * @param {String} address User address\n * @param {String} exchangeId ExchangeId\n * @param {String} amount amount to be collected\n * @return {Promise<ReceiptOrEstimate>} transaction receipt\n */\n public async collectBasetokens<G extends boolean = false>(\n address: string,\n exchangeId: string,\n amount: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const exchange = await this.getExchange(exchangeId)\n if (!exchange) return null\n\n const fixedrate: FixedPriceExchange = await this.contract.methods\n .getExchange(exchangeId)\n .call()\n const amountWei = await this.amountToUnits(\n fixedrate.baseToken,\n amount,\n +fixedrate.btDecimals\n )\n\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.collectBT,\n exchangeId,\n amountWei\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.collectBT,\n exchangeId,\n amountWei\n )\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Collect datatokens in the contract (anyone can call this, funds are sent to Datatoken.paymentCollector)\n * @param {String} address User address\n * @param {String} exchangeId ExchangeId\n * @param {String} amount amount to be collected\n * @return {Promise<ReceiptOrEstimate>} transaction receipt\n */\n public async collectDatatokens<G extends boolean = false>(\n address: string,\n exchangeId: string,\n amount: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const exchange = await this.getExchange(exchangeId)\n if (!exchange) return null\n\n const fixedrate: FixedPriceExchange = await this.contract.methods\n .getExchange(exchangeId)\n .call()\n const amountWei = await this.amountToUnits(\n fixedrate.datatoken,\n amount,\n +fixedrate.dtDecimals\n )\n\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.collectDT,\n exchangeId,\n amountWei\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.collectDT,\n exchangeId,\n amountWei\n )\n return <ReceiptOrEstimate<G>>trxReceipt\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<ReceiptOrEstimate>} transaction receipt\n */\n public async collectMarketFee<G extends boolean = false>(\n address: string,\n exchangeId: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const exchange = await this.getExchange(exchangeId)\n if (!exchange) return null\n\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.collectMarketFee,\n exchangeId\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.collectMarketFee,\n exchangeId\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\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<ReceiptOrEstimate>} transaction receipt\n */\n public async collectOceanFee<G extends boolean = false>(\n address: string,\n exchangeId: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const exchange = await this.getExchange(exchangeId)\n if (!exchange) return null\n\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.collectOceanFee,\n exchangeId\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.collectOceanFee,\n exchangeId\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Get OPF Collector of fixed rate contract\n * @return {String}\n */\n async getOPCCollector(): Promise<string> {\n const address = await this.contract.methods.opcCollector().call()\n return address\n }\n\n /**\n * Get Router address set in fixed rate contract\n * @return {String}\n */\n public async getRouter(): Promise<string> {\n const address = await this.contract.methods.router().call()\n return address\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 const address = await (await this.getExchange(exchangeId)).exchangeOwner\n return address\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<ReceiptOrEstimate>} transaction receipt\n */\n public async updateMarketFee<G extends boolean = false>(\n address: string,\n exchangeId: string,\n newMarketFee: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.updateMarketFee,\n exchangeId,\n this.web3.utils.toWei(newMarketFee)\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.updateMarketFee,\n exchangeId,\n this.web3.utils.toWei(newMarketFee)\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\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<ReceiptOrEstimate>} transaction receipt\n */\n public async updateMarketFeeCollector<G extends boolean = false>(\n address: string,\n exchangeId: string,\n newMarketFeeCollector: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.updateMarketFeeCollector,\n exchangeId,\n newMarketFeeCollector\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.updateMarketFeeCollector,\n exchangeId,\n newMarketFeeCollector\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n}\n","import { AbiItem } from 'web3-utils'\nimport FactoryRouter from '@oceanprotocol/contracts/artifacts/contracts/pools/FactoryRouter.sol/FactoryRouter.json'\nimport { calculateEstimatedGas, sendTx } from '../utils'\nimport { Operation, ReceiptOrEstimate } from '../@types'\nimport { SmartContractWithAddress } from './SmartContractWithAddress'\n\n/**\n * Provides an interface for FactoryRouter contract\n */\nexport class Router extends SmartContractWithAddress {\n getDefaultAbi(): AbiItem | AbiItem[] {\n return FactoryRouter.abi as AbiItem[]\n }\n\n /**\n * buyDatatokenBatch\n * @param {String} address\n * @param {Operation} operations Operations objects array\n * @return {Promise<ReceiptOrEstimate>} Transaction receipt\n */\n public async buyDatatokenBatch<G extends boolean = false>(\n address: string,\n operations: Operation[],\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.buyDTBatch,\n operations\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.buyDTBatch,\n operations\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /** Check if a token is on approved tokens list, if true opfFee is lower in pools with that token/DT\n * @return {Promise<boolean>} true if is on the list.\n */\n public async isApprovedToken(address: string): Promise<boolean> {\n return await this.contract.methods.isApprovedToken(address).call()\n }\n\n /** Check if an address is a Fixed Rate contract.\n * @return {Promise<boolean>} true if is a Fixed Rate contract\n */\n public async isFixedPrice(address: string): Promise<boolean> {\n return await this.contract.methods.isFixedRateContract(address).call()\n }\n\n /** Get Router Owner\n * @return {Promise<string>} Router Owner address\n */\n public async getOwner(): Promise<string> {\n return await this.contract.methods.routerOwner().call()\n }\n\n /** Get NFT Factory address\n * @return {Promise<string>} NFT Factory address\n */\n public async getNFTFactory(): Promise<string> {\n return await this.contract.methods.factory().call()\n }\n\n /**\n * Adds a token to the list of tokens with reduced fees\n * @param {String} address caller address\n * @param {String} tokenAddress token address to add\n * @return {Promise<ReceiptOrEstimate>}\n */\n public async addApprovedToken<G extends boolean = false>(\n address: string,\n tokenAddress: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Router Owner`)\n }\n\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.addApprovedToken,\n tokenAddress\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.addApprovedToken,\n tokenAddress\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Removes a token if exists from the list of tokens with reduced fees\n * @param {String} address\n * @param {String} tokenAddress address to remove\n * @return {Promise<ReceiptOrEstimate>}\n */\n public async removeApprovedToken<G extends boolean = false>(\n address: string,\n tokenAddress: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Router Owner`)\n }\n\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.removeApprovedToken,\n tokenAddress\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.removeApprovedToken,\n tokenAddress\n )\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Adds an address to the list of fixed rate contracts\n * @param {String} address\n * @param {String} tokenAddress contract address to add\n * @return {Promise<ReceiptOrEstimate>}\n */\n public async addFixedRateContract<G extends boolean = false>(\n address: string,\n tokenAddress: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Router Owner`)\n }\n\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.addFixedRateContract,\n tokenAddress\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.addFixedRateContract,\n tokenAddress\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Removes an address from the list of fixed rate contracts\n * @param {String} address\n * @param {String} tokenAddress contract address to add\n * @return {Promise<ReceiptOrEstimate>}\n */\n public async removeFixedRateContract<G extends boolean = false>(\n address: string,\n tokenAddress: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Router Owner`)\n }\n\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.removeFixedRateContract,\n tokenAddress\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.removeFixedRateContract,\n tokenAddress\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Adds an address to the list of dispensers\n * @param {String} address\n * @param {String} tokenAddress contract address to add\n * @return {Promise<ReceiptOrEstimate>}\n */\n public async addDispenserContract<G extends boolean = false>(\n address: string,\n tokenAddress: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Router Owner`)\n }\n\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.addDispenserContract,\n tokenAddress\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.addDispenserContract,\n tokenAddress\n )\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Removes an address from the list of dispensers\n * @param {String} address\n * @param {String} tokenAddress address Contract to be removed\n * @return {Promise<ReceiptOrEstimate>}\n */\n public async removeDispenserContract<G extends boolean = false>(\n address: string,\n tokenAddress: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Router Owner`)\n }\n\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.removeDispenserContract,\n tokenAddress\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.removeDispenserContract,\n tokenAddress\n )\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /** Get OPF Fee per token\n * @return {Promise<number>} OPC fee for a specific baseToken\n */\n public async getOPCFee(baseToken: string): Promise<number> {\n return await this.contract.methods.getOPCFee(baseToken).call()\n }\n\n /** Get Current OPF Fee\n * @return {Promise<number>} OPF fee\n */\n public async getCurrentOPCFee(): Promise<number> {\n return await this.contract.methods.swapOceanFee().call()\n }\n\n /**\n * Updates OP Community Fees\n * @param {String} address\n * @param {number} newSwapOceanFee Amount charged for swapping with ocean approved tokens\n * @param {number} newSwapNonOceanFee Amount charged for swapping with non ocean approved tokens\n * @param {number} newConsumeFee Amount charged from consumeFees\n * @param {number} newProviderFee Amount charged for providerFees\n * @return {Promise<ReceiptOrEstimate>}\n */\n public async updateOPCFee<G extends boolean = false>(\n address: string,\n newSwapOceanFee: number,\n newSwapNonOceanFee: number,\n newConsumeFee: number,\n newProviderFee: number,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Router Owner`)\n }\n\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.updateOPCFee,\n newSwapOceanFee,\n newSwapNonOceanFee,\n newConsumeFee,\n newProviderFee\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.updateOPCFee,\n newSwapOceanFee,\n newSwapNonOceanFee,\n newConsumeFee,\n newProviderFee\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n}\n","import { AbiItem } from 'web3-utils'\nimport { TransactionReceipt } from 'web3-eth'\nimport ERC721Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC721Template.sol/ERC721Template.json'\nimport { generateDtName, calculateEstimatedGas, sendTx } from '../utils'\nimport {\n MetadataProof,\n MetadataAndTokenURI,\n NftRoles,\n ReceiptOrEstimate\n} from '../@types'\nimport { SmartContract } from './SmartContract'\n\nexport class Nft extends SmartContract {\n getDefaultAbi(): AbiItem | AbiItem[] {\n return ERC721Template.abi as AbiItem[]\n }\n\n /**\n * Create new ERC20 Datatoken - only user with DatatokenDeployer permission can succeed\n * @param {String} nftAddress NFT address\n * @param {String} address User address\n * @param {String} minter User set as initial minter for the Datatoken\n * @param {String} paymentCollector initial paymentCollector 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 createDatatoken<G extends boolean = false>(\n nftAddress: string,\n address: string,\n minter: string,\n paymentCollector: string,\n mpFeeAddress: string,\n feeToken: string,\n feeAmount: string,\n cap: string,\n name?: string,\n symbol?: string,\n templateIndex?: number,\n estimateGas?: G\n ): Promise<G extends false ? string : number> {\n if ((await this.getNftPermissions(nftAddress, address)).deployERC20 !== true) {\n throw new Error(`Caller is not DatatokenDeployer`)\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 = this.getContract(nftAddress)\n\n const estGas = await calculateEstimatedGas(\n address,\n nftContract.methods.createERC20,\n templateIndex,\n [name, symbol],\n [minter, paymentCollector, mpFeeAddress, feeToken],\n [this.web3.utils.toWei(cap), this.web3.utils.toWei(feeAmount)],\n []\n )\n if (estimateGas) return <G extends false ? string : number>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n nftContract.methods.createERC20,\n templateIndex,\n [name, symbol],\n [minter, paymentCollector, mpFeeAddress, feeToken],\n [this.web3.utils.toWei(cap), this.web3.utils.toWei(feeAmount)],\n []\n )\n\n return trxReceipt?.events?.TokenCreated?.returnValues?.[0]\n }\n\n /**\n * Add Manager for NFT Contract (only NFT Owner can succeed)\n * @param {String} nftAddress NFT contract address\n * @param {String} address NFT Owner adress\n * @param {String} manager User adress which is going to be assing manager\n * @return {Promise<ReceiptOrEstimate>} trxReceipt\n */\n public async addManager<G extends boolean = false>(\n nftAddress: string,\n address: string,\n manager: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const nftContract = this.getContract(nftAddress)\n\n if ((await this.getNftOwner(nftAddress)) !== address) {\n throw new Error(`Caller is not NFT Owner`)\n }\n\n const estGas = await calculateEstimatedGas(\n address,\n nftContract.methods.addManager,\n manager\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n nftContract.methods.addManager,\n manager\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Removes a specific manager for NFT Contract (only NFT Owner can succeed)\n * @param {String} nftAddress NFT contract address\n * @param {String} address NFT Owner adress\n * @param {String} manager User adress which is going to be removed as manager\n * @return {Promise<ReceiptOrEstimate>} trxReceipt\n */\n public async removeManager<G extends boolean = false>(\n nftAddress: string,\n address: string,\n manager: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const nftContract = this.getContract(nftAddress)\n\n if ((await this.getNftOwner(nftAddress)) !== address) {\n throw new Error(`Caller is not NFT Owner`)\n }\n\n const estGas = await calculateEstimatedGas(\n address,\n nftContract.methods.removeManager,\n manager\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n nftContract.methods.removeManager,\n manager\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Add DatatokenDeployer permission - only Manager can succeed\n * @param {String} nftAddress NFT contract address\n * @param {String} address NFT Manager adress\n * @param {String} datatokenDeployer User adress which is going to have DatatokenDeployer permission\n * @return {Promise<ReceiptOrEstimate>} trxReceipt\n */\n public async addDatatokenDeployer<G extends boolean = false>(\n nftAddress: string,\n address: string,\n datatokenDeployer: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const nftContract = this.getContract(nftAddress)\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 calculateEstimatedGas(\n address,\n nftContract.methods.addToCreateERC20List,\n datatokenDeployer\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n nftContract.methods.addToCreateERC20List,\n datatokenDeployer\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Remove DatatokenDeployer permission - only Manager can succeed\n * @param {String} nftAddress NFT contract address\n * @param {String} address NFT Manager adress\n * @param {String} datatokenDeployer Address of the user to be revoked DatatokenDeployer Permission\n * @return {Promise<ReceiptOrEstimate>} trxReceipt\n */\n public async removeDatatokenDeployer<G extends boolean = false>(\n nftAddress: string,\n address: string,\n datatokenDeployer: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const nftContract = this.getContract(nftAddress)\n\n if (\n (await this.getNftPermissions(nftAddress, address)).manager !== true ||\n (address === datatokenDeployer &&\n (await this.getNftPermissions(nftAddress, address)).deployERC20 !== true)\n ) {\n throw new Error(`Caller is not Manager nor DatatokenDeployer`)\n }\n const estGas = await calculateEstimatedGas(\n address,\n nftContract.methods.removeFromCreateERC20List,\n datatokenDeployer\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n nftContract.methods.removeFromCreateERC20List,\n datatokenDeployer\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Add Metadata Updater permission - only Manager can succeed\n * @param {String} nftAddress NFT contract address\n * @param {String} address NFT Manager adress\n * @param {String} metadataUpdater User adress which is going to have Metadata Updater permission\n * @return {Promise<ReceiptOrEstimate>} trxReceipt\n */\n public async addMetadataUpdater<G extends boolean = false>(\n nftAddress: string,\n address: string,\n metadataUpdater: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const nftContract = this.getContract(nftAddress)\n\n if ((await this.getNftPermissions(nftAddress, address)).manager !== true) {\n throw new Error(`Caller is not Manager`)\n }\n\n const estGas = await calculateEstimatedGas(\n address,\n nftContract.methods.addToMetadataList,\n metadataUpdater\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n nftContract.methods.addToMetadataList,\n metadataUpdater\n )\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Remove Metadata Updater permission - only Manager can succeed\n * @param {String} nftAddress NFT contract address\n * @param {String} address NFT Manager adress\n * @param {String} metadataUpdater Address of the user to be revoked Metadata updater Permission\n * @return {Promise<ReceiptOrEstimate>} trxReceipt\n */\n public async removeMetadataUpdater<G extends boolean = false>(\n nftAddress: string,\n address: string,\n metadataUpdater: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const nftContract = this.getContract(nftAddress)\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 calculateEstimatedGas(\n address,\n nftContract.methods.removeFromMetadataList,\n metadataUpdater\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n nftContract.methods.removeFromMetadataList,\n metadataUpdater\n )\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Add Store Updater permission - only Manager can succeed\n * @param {String} nftAddress NFT contract address\n * @param {String} address NFT Manager adress\n * @param {String} storeUpdater User adress which is going to have Store Updater permission\n * @return {Promise<ReceiptOrEstimate>} trxReceipt\n */\n public async addStoreUpdater<G extends boolean = false>(\n nftAddress: string,\n address: string,\n storeUpdater: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const nftContract = this.getContract(nftAddress)\n\n if ((await this.getNftPermissions(nftAddress, address)).manager !== true) {\n throw new Error(`Caller is not Manager`)\n }\n\n const estGas = await calculateEstimatedGas(\n address,\n nftContract.methods.addTo725StoreList,\n storeUpdater\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n nftContract.methods.addTo725StoreList,\n storeUpdater\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Remove Store Updater permission - only Manager can succeed\n * @param {String} nftAddress NFT contract address\n * @param {String} address NFT Manager adress\n * @param {String} storeUpdater Address of the user to be revoked Store Updater Permission\n * @return {Promise<ReceiptOrEstimate>} trxReceipt\n */\n public async removeStoreUpdater<G extends boolean = false>(\n nftAddress: string,\n address: string,\n storeUpdater: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const nftContract = this.getContract(nftAddress)\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 calculateEstimatedGas(\n address,\n nftContract.methods.removeFrom725StoreList,\n storeUpdater\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n nftContract.methods.removeFrom725StoreList,\n storeUpdater\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * This function allows to remove all ROLES at NFT level: Managers, DatatokenDeployer, MetadataUpdater, StoreUpdater\n * Even NFT Owner has to readd himself as Manager\n * Permissions at Datatoken level stay.\n * Only NFT Owner can call it.\n * @param {String} nftAddress NFT contract address\n * @param {String} address NFT Owner adress\n * @return {Promise<ReceiptOrEstimate>} trxReceipt\n */\n public async cleanPermissions<G extends boolean = false>(\n nftAddress: string,\n address: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const nftContract = this.getContract(nftAddress)\n\n if ((await this.getNftOwner(nftAddress)) !== address) {\n throw new Error(`Caller is not NFT Owner`)\n }\n\n const estGas = await calculateEstimatedGas(\n address,\n nftContract.methods.cleanPermissions\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n nftContract.methods.cleanPermissions\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Transfers the NFT\n * will clean all permissions both on NFT and Datatoken level.\n * @param {String} nftAddress NFT contract address\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<ReceiptOrEstimate>} trxReceipt\n */\n public async transferNft<G extends boolean = false>(\n nftAddress: string,\n nftOwner: string,\n nftReceiver: string,\n tokenId?: number,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const nftContract = this.getContract(nftAddress)\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 calculateEstimatedGas(\n nftOwner,\n nftContract.methods.transferFrom,\n nftOwner,\n nftReceiver,\n tokenIdentifier\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n nftOwner,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n nftContract.methods.transferFrom,\n nftOwner,\n nftReceiver,\n tokenIdentifier\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * safeTransferNFT Used for transferring the NFT, can be used by an approved relayer\n * will clean all permissions both on NFT and Datatoken level.\n * @param {String} nftAddress NFT contract address\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<ReceiptOrEstimate>} trxReceipt\n */\n public async safeTransferNft<G extends boolean = false>(\n nftAddress: string,\n nftOwner: string,\n nftReceiver: string,\n tokenId?: number,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const nftContract = this.getContract(nftAddress)\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 calculateEstimatedGas(\n nftOwner,\n nftContract.methods.safeTransferFrom,\n nftOwner,\n nftReceiver,\n tokenIdentifier\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n nftOwner,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n nftContract.methods.safeTransferFrom,\n nftOwner,\n nftReceiver,\n tokenIdentifier\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Creates or update Metadata cached by Aquarius. Also, updates the METADATA_DECRYPTOR key\n * @param {String} nftAddress NFT contract address\n * @param {String} address Caller address NFT Owner adress\n * @param {String} address Caller address NFT Owner adress\n * @param {String} address Caller address NFT Owner adress\n * @param {String} address Caller address NFT Owner adress\n * @param {String} address Caller address NFT Owner adress\n * @param {String} address Caller address NFT Owner adress\n * @param {String} address Caller address NFT Owner adress\n * @return {Promise<ReceiptOrEstimate>} trxReceipt\n */\n public async setMetadata<G extends boolean = false>(\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 estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const nftContract = this.getContract(nftAddress)\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 calculateEstimatedGas(\n address,\n nftContract.methods.setMetaData,\n metadataState,\n metadataDecryptorUrl,\n metadataDecryptorAddress,\n flags,\n data,\n metadataHash,\n metadataProofs\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n nftContract.methods.setMetaData,\n metadataState,\n metadataDecryptorUrl,\n metadataDecryptorAddress,\n flags,\n data,\n metadataHash,\n metadataProofs\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Helper function to improve UX sets both MetaData & TokenURI in one tx\n * @param {String} nftAddress NFT contract address\n * @param {String} address Caller address\n * @param {MetadataAndTokenURI} metadataAndTokenURI metaDataAndTokenURI object\n * @return {Promise<ReceiptOrEstimate>} trxReceipt\n */\n public async setMetadataAndTokenURI<G extends boolean = false>(\n nftAddress: string,\n metadataUpdater: string,\n metadataAndTokenURI: MetadataAndTokenURI,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const nftContract = this.getContract(nftAddress)\n if (!(await this.getNftPermissions(nftAddress, metadataUpdater)).updateMetadata) {\n throw new Error(`Caller is not Metadata updater`)\n }\n const sanitizedMetadataAndTokenURI = {\n ...metadataAndTokenURI,\n metadataProofs: metadataAndTokenURI.metadataProofs || []\n }\n const estGas = await calculateEstimatedGas(\n metadataUpdater,\n nftContract.methods.setMetaDataAndTokenURI,\n sanitizedMetadataAndTokenURI\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n metadataUpdater,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n nftContract.methods.setMetaDataAndTokenURI,\n sanitizedMetadataAndTokenURI\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * setMetadataState Used for updating the metadata State\n * @param {String} nftAddress NFT contract address\n * @param {String} address Caller address => metadata updater\n * @param {Number} metadataState new metadata state\n * @return {Promise<ReceiptOrEstimate>} trxReceipt\n */\n public async setMetadataState<G extends boolean = false>(\n nftAddress: string,\n address: string,\n metadataState: number,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const nftContract = this.getContract(nftAddress)\n\n if (!(await this.getNftPermissions(nftAddress, address)).updateMetadata) {\n throw new Error(`Caller is not Metadata updater`)\n }\n\n const estGas = await calculateEstimatedGas(\n address,\n nftContract.methods.setMetaDataState,\n metadataState\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n nftContract.methods.setMetaDataState,\n metadataState\n )\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /** set TokenURI on an nft\n * @param nftAddress NFT contract address\n * @param address user adress\n * @param data input data for TokenURI\n * @return {Promise<ReceiptOrEstimate>} transaction receipt\n */\n public async setTokenURI<G extends boolean = false>(\n nftAddress: string,\n address: string,\n data: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const nftContract = this.getContract(nftAddress)\n\n const estGas = await calculateEstimatedGas(\n address,\n nftContract.methods.setTokenURI,\n '1',\n data\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n nftContract.methods.setTokenURI,\n '1',\n data\n )\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /** Get Owner\n * @param {String} nftAddress NFT contract address\n * @return {Promise<string>} string\n */\n public async getNftOwner(nftAddress: string): Promise<string> {\n const nftContract = this.getContract(nftAddress)\n const trxReceipt = await nftContract.methods.ownerOf(1).call()\n return trxReceipt\n }\n\n /** Get users NFT Permissions\n * @param {String} nftAddress NFT contract address\n * @param {String} address user adress\n * @return {Promise<NftRoles>}\n */\n public async getNftPermissions(nftAddress: string, address: string): Promise<NftRoles> {\n const nftContract = this.getContract(nftAddress)\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 NFT contract address\n * @return {Promise<Objecta>}\n */\n public async getMetadata(nftAddress: string): Promise<Object> {\n const nftContract = this.getContract(nftAddress)\n return await nftContract.methods.getMetaData().call()\n }\n\n /** Get users DatatokenDeployer role\n * @param {String} nftAddress NFT contract address\n * @param {String} address user adress\n * @return {Promise<boolean>}\n */\n public async isDatatokenDeployer(\n nftAddress: string,\n address: string\n ): Promise<boolean> {\n const nftContract = this.getContract(nftAddress)\n const isDatatokenDeployer = await nftContract.methods.isERC20Deployer(address).call()\n return isDatatokenDeployer\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 nftAddress erc721 contract adress\n * @param address user adress\n * @param key Key of the data to be stored into 725Y standard\n * @param value Data to be stored into 725Y standard\n * @return {Promise<ReceiptOrEstimate>} transactionId\n */\n public async setData(\n nftAddress: string,\n address: string,\n key: string,\n value: string\n ): Promise<TransactionReceipt> {\n if ((await this.getNftPermissions(nftAddress, address)).store !== true) {\n throw new Error(`User is not ERC20 store updater`)\n }\n\n const nftContract = this.getContract(nftAddress)\n\n const keyHash = this.web3.utils.keccak256(key)\n const valueHex = this.web3.utils.asciiToHex(value)\n\n const estGas = await calculateEstimatedGas(\n address,\n nftContract.methods.setNewData,\n keyHash,\n valueHex\n )\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n nftContract.methods.setNewData,\n keyHash,\n valueHex\n )\n\n return trxReceipt\n }\n\n /** Gets data at a given `key`\n * @param {String} nftAddress NFT contract address\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 = this.getContract(nftAddress)\n const keyHash = this.web3.utils.keccak256(key)\n const data = await nftContract.methods.getData(keyHash).call()\n return data ? this.web3.utils.hexToAscii(data) : null\n }\n\n /** Gets data at a given `key`\n * @param {String} nftAddress NFT contract address\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 = this.getContract(nftAddress)\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 Decimal from 'decimal.js'\nimport ERC20Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json'\nimport ERC20TemplateEnterprise from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20TemplateEnterprise.sol/ERC20TemplateEnterprise.json'\nimport { amountToUnits, sendTx, calculateEstimatedGas, ZERO_ADDRESS } from '../utils'\nimport {\n ConsumeMarketFee,\n FreOrderParams,\n FreCreationParams,\n ProviderFees,\n PublishingMarketFee,\n DispenserParams,\n OrderParams,\n DatatokenRoles,\n ReceiptOrEstimate\n} from '../@types'\nimport { Nft } from './NFT'\nimport { Config } from '../config'\nimport { SmartContract } from './SmartContract'\n\nexport class Datatoken extends SmartContract {\n public abiEnterprise: AbiItem | AbiItem[]\n public nft: Nft\n\n getDefaultAbi(): AbiItem | AbiItem[] {\n return ERC20Template.abi as AbiItem[]\n }\n\n /**\n * Instantiate ERC20 Datatokens\n * @param {AbiItem | AbiItem[]} datatokensAbi\n * @param {Web3} web3\n */\n constructor(\n web3: Web3,\n network?: string | number,\n config?: Config,\n abi?: AbiItem | AbiItem[],\n abiEnterprise?: AbiItem | AbiItem[]\n ) {\n super(web3, network, config, abi)\n this.abiEnterprise = abiEnterprise || (ERC20TemplateEnterprise.abi as AbiItem[])\n this.nft = new Nft(this.web3)\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<ReceiptOrEstimate>} trxReceipt\n */\n public async approve<G extends boolean = false>(\n dtAddress: string,\n spender: string,\n amount: string,\n address: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const dtContract = this.getContract(dtAddress)\n\n const estGas = await calculateEstimatedGas(\n address,\n dtContract.methods.approve,\n spender,\n this.web3.utils.toWei(amount)\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n dtContract.methods.approve,\n spender,\n this.web3.utils.toWei(amount)\n )\n return <ReceiptOrEstimate<G>>trxReceipt\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<ReceiptOrEstimate>} transactionId\n */\n public async createFixedRate<G extends boolean = false>(\n dtAddress: string,\n address: string,\n fixedRateParams: FreCreationParams,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const dtContract = this.getContract(dtAddress)\n if (!(await this.isDatatokenDeployer(dtAddress, address))) {\n throw new Error(`User is not Datatoken Deployer`)\n }\n if (!fixedRateParams.allowedConsumer) fixedRateParams.allowedConsumer = ZERO_ADDRESS\n\n const withMint = fixedRateParams.withMint ? 1 : 0\n\n // should check DatatokenDeployer role using NFT level ..\n\n const estGas = await calculateEstimatedGas(\n address,\n dtContract.methods.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 if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n dtContract.methods.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 return <ReceiptOrEstimate<G>>trxReceipt\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<ReceiptOrEstimate>} transactionId\n */\n public async createDispenser<G extends boolean = false>(\n dtAddress: string,\n address: string,\n dispenserAddress: string,\n dispenserParams: DispenserParams,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n if (!(await this.isDatatokenDeployer(dtAddress, address))) {\n throw new Error(`User is not Datatoken Deployer`)\n }\n\n const dtContract = this.getContract(dtAddress)\n\n if (!dispenserParams.allowedSwapper) dispenserParams.allowedSwapper = ZERO_ADDRESS\n\n if (!dispenserParams.withMint) dispenserParams.withMint = false\n\n // should check DatatokenDeployer role using NFT level ..\n\n const estGas = await calculateEstimatedGas(\n address,\n dtContract.methods.createDispenser,\n dispenserAddress,\n dispenserParams.maxTokens,\n dispenserParams.maxBalance,\n dispenserParams.withMint,\n dispenserParams.allowedSwapper\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n dtContract.methods.createDispenser,\n dispenserAddress,\n dispenserParams.maxTokens,\n dispenserParams.maxBalance,\n dispenserParams.withMint,\n dispenserParams.allowedSwapper\n )\n return <ReceiptOrEstimate<G>>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<ReceiptOrEstimate>} transactionId\n */\n public async mint<G extends boolean = false>(\n dtAddress: string,\n address: string,\n amount: string,\n toAddress?: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const dtContract = this.getContract(dtAddress)\n\n if ((await this.getPermissions(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 calculateEstimatedGas(\n address,\n dtContract.methods.mint,\n toAddress || address,\n this.web3.utils.toWei(amount)\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n dtContract.methods.mint,\n toAddress || address,\n this.web3.utils.toWei(amount)\n )\n return <ReceiptOrEstimate<G>>trxReceipt\n } else {\n throw new Error(`Mint amount exceeds cap available`)\n }\n }\n\n /**\n * Add Minter for an ERC20 Datatoken\n * only DatatokenDeployer 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<ReceiptOrEstimate>} transactionId\n */\n public async addMinter<G extends boolean = false>(\n dtAddress: string,\n address: string,\n minter: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const dtContract = this.getContract(dtAddress)\n\n if ((await this.isDatatokenDeployer(dtAddress, address)) !== true) {\n throw new Error(`Caller is not DatatokenDeployer`)\n }\n // Estimate gas cost for addMinter method\n const estGas = await calculateEstimatedGas(\n address,\n dtContract.methods.addMinter,\n minter\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n dtContract.methods.addMinter,\n minter\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Revoke Minter permission for an ERC20 Datatoken\n * only DatatokenDeployer 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<G extends boolean = false>(\n dtAddress: string,\n address: string,\n minter: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const dtContract = this.getContract(dtAddress)\n\n if ((await this.isDatatokenDeployer(dtAddress, address)) !== true) {\n throw new Error(`Caller is not DatatokenDeployer`)\n }\n\n const estGas = await calculateEstimatedGas(\n address,\n dtContract.methods.removeMinter,\n minter\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n dtContract.methods.removeMinter,\n minter\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Add addPaymentManager (can set who's going to collect fee when consuming orders)\n * only DatatokenDeployer 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<ReceiptOrEstimate>} transactionId\n */\n public async addPaymentManager<G extends boolean = false>(\n dtAddress: string,\n address: string,\n paymentManager: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const dtContract = this.getContract(dtAddress)\n\n if ((await this.isDatatokenDeployer(dtAddress, address)) !== true) {\n throw new Error(`Caller is not DatatokenDeployer`)\n }\n\n const estGas = await calculateEstimatedGas(\n address,\n dtContract.methods.addPaymentManager,\n paymentManager\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n dtContract.methods.addPaymentManager,\n paymentManager\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Revoke paymentManager permission for an ERC20 Datatoken\n * only DatatokenDeployer 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<ReceiptOrEstimate>} trxReceipt\n */\n public async removePaymentManager<G extends boolean = false>(\n dtAddress: string,\n address: string,\n paymentManager: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const dtContract = this.getContract(dtAddress)\n\n if ((await this.isDatatokenDeployer(dtAddress, address)) !== true) {\n throw new Error(`Caller is not DatatokenDeployer`)\n }\n\n const estGas = await calculateEstimatedGas(\n address,\n dtContract.methods.removePaymentManager,\n paymentManager\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n dtContract.methods.removePaymentManager,\n paymentManager\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\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<ReceiptOrEstimate>} trxReceipt\n */\n public async setPaymentCollector<G extends boolean = false>(\n dtAddress: string,\n address: string,\n paymentCollector: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const dtContract = this.getContract(dtAddress)\n const isPaymentManager = (await this.getPermissions(dtAddress, address))\n .paymentManager\n const nftAddress = !isPaymentManager && (await this.getNFTAddress(dtAddress))\n const isNftOwner = nftAddress && (await this.nft.getNftOwner(nftAddress)) === address\n const nftPermissions =\n nftAddress && !isNftOwner && (await this.nft.getNftPermissions(nftAddress, address))\n const isDatatokenDeployer = nftPermissions?.deployERC20\n if (!isPaymentManager && !isNftOwner && !isDatatokenDeployer) {\n throw new Error(`Caller is not Fee Manager, owner or Datatoken Deployer`)\n }\n\n const estGas = await calculateEstimatedGas(\n address,\n dtContract.methods.setPaymentCollector,\n paymentCollector\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n dtContract.methods.setPaymentCollector,\n paymentCollector\n )\n return <ReceiptOrEstimate<G>>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 = this.getContract(dtAddress)\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<ReceiptOrEstimate>} 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 * 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<ReceiptOrEstimate>} transactionId\n */\n public async transferWei<G extends boolean = false>(\n dtAddress: string,\n toAddress: string,\n amount: string,\n address: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const dtContract = this.getContract(dtAddress)\n\n const estGas = await calculateEstimatedGas(\n address,\n dtContract.methods.transfer,\n toAddress,\n amount\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n dtContract.methods.transfer,\n toAddress,\n amount\n )\n return <ReceiptOrEstimate<G>>trxReceipt\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 * @param {consumeMarketFee} ConsumeMarketFee consume market fees\n * @return {Promise<ReceiptOrEstimate>} string\n */\n public async startOrder<G extends boolean = false>(\n dtAddress: string,\n address: string,\n consumer: string,\n serviceIndex: number,\n providerFees: ProviderFees,\n consumeMarketFee?: ConsumeMarketFee,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const dtContract = this.getContract(dtAddress)\n if (!consumeMarketFee) {\n consumeMarketFee = {\n consumeMarketFeeAddress: ZERO_ADDRESS,\n consumeMarketFeeToken: ZERO_ADDRESS,\n consumeMarketFeeAmount: '0'\n }\n }\n\n const estGas = await calculateEstimatedGas(\n address,\n dtContract.methods.startOrder,\n consumer,\n serviceIndex,\n providerFees,\n consumeMarketFee\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n dtContract.methods.startOrder,\n consumer,\n serviceIndex,\n providerFees,\n consumeMarketFee\n )\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /** Reuse Order: called by payer or consumer having a valid order, but with expired provider access.\n * Pays the provider fee again, but it will not require a new datatoken payment\n * Requires previous approval of provider fee.\n * @param {String} dtAddress Datatoken address\n * @param {String} address User address which calls\n * @param {String} orderTxId previous valid order\n * @param {providerFees} providerFees provider fees\n * @return {Promise<ReceiptOrEstimate>} string\n */\n public async reuseOrder<G extends boolean = false>(\n dtAddress: string,\n address: string,\n orderTxId: string,\n providerFees: ProviderFees,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const dtContract = this.getContract(dtAddress)\n\n const estGas = await calculateEstimatedGas(\n address,\n dtContract.methods.reuseOrder,\n orderTxId,\n providerFees\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n dtContract.methods.reuseOrder,\n orderTxId,\n providerFees\n )\n return <ReceiptOrEstimate<G>>trxReceipt\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<ReceiptOrEstimate>}\n */\n public async buyFromFreAndOrder<G extends boolean = false>(\n dtAddress: string,\n address: string,\n orderParams: OrderParams,\n freParams: FreOrderParams,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const dtContract = this.getContract(dtAddress, null, this.abiEnterprise)\n\n const freContractParams = await this.getFreOrderParams(freParams)\n\n const estGas = await calculateEstimatedGas(\n address,\n dtContract.methods.buyFromFreAndOrder,\n orderParams,\n freContractParams\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n dtContract.methods.buyFromFreAndOrder,\n orderParams,\n freContractParams\n )\n return <ReceiptOrEstimate<G>>trxReceipt\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<ReceiptOrEstimate>}\n */\n public async buyFromDispenserAndOrder<G extends boolean = false>(\n dtAddress: string,\n address: string,\n orderParams: OrderParams,\n dispenserContract: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const dtContract = this.getContract(dtAddress, null, this.abiEnterprise)\n\n const estGas = await calculateEstimatedGas(\n address,\n dtContract.methods.buyFromDispenserAndOrder,\n orderParams,\n dispenserContract\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n dtContract.methods.buyFromDispenserAndOrder,\n orderParams,\n dispenserContract\n )\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /** setData\n * This function allows to store data with a preset key (keccak256(dtAddress)) into NFT 725 Store\n * only DatatokenDeployer 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<ReceiptOrEstimate>} transactionId\n */\n public async setData<G extends boolean = false>(\n dtAddress: string,\n address: string,\n value: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n if (!(await this.isDatatokenDeployer(dtAddress, address))) {\n throw new Error(`User is not Datatoken Deployer`)\n }\n\n const dtContract = this.getContract(dtAddress)\n\n const valueHex = this.web3.utils.asciiToHex(value)\n\n const estGas = await calculateEstimatedGas(\n address,\n dtContract.methods.setData,\n valueHex\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n dtContract.methods.setData,\n valueHex\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Clean Datatoken level 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<ReceiptOrEstimate>} transactionId\n */\n public async cleanPermissions<G extends boolean = false>(\n dtAddress: string,\n address: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n if ((await this.nft.getNftOwner(await this.getNFTAddress(dtAddress))) !== address) {\n throw new Error('Caller is NOT Nft Owner')\n }\n const dtContract = this.getContract(dtAddress)\n\n const estGas = await calculateEstimatedGas(\n address,\n dtContract.methods.cleanPermissions\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n dtContract.methods.cleanPermissions\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /** Returns ERC20 Datatoken user's permissions for a datatoken\n * @param {String} dtAddress Datatoken adress\n * @param {String} address user adress\n * @return {Promise<DatatokenRoles>}\n */\n public async getPermissions(\n dtAddress: string,\n address: string\n ): Promise<DatatokenRoles> {\n const dtContract = this.getContract(dtAddress)\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 = this.getContract(dtAddress)\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 = this.getContract(dtAddress)\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 = this.getContract(dtAddress)\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 isDatatokenDeployer(dtAddress: string, address: string): Promise<boolean> {\n const dtContract = this.getContract(dtAddress)\n const isDatatokenDeployer = await dtContract.methods.isERC20Deployer(address).call()\n return isDatatokenDeployer\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 = this.getContract(datatokenAddress, address)\n const balance = await dtContract.methods.balanceOf(address).call()\n return this.web3.utils.fromWei(balance)\n }\n\n /**\n * @dev setPublishingMarketFee\n * Only publishMarketFeeAddress can call it\n * This function allows to set the fee required by the publisherMarket\n * @param {string} datatokenAddress Datatoken adress\n * @param {string} publishMarketFeeAddress new publish Market Fee Address\n * @param {string} publishMarketFeeToken new publish Market Fee Token\n * @param {string} publishMarketFeeAmount new fee amount\n * @param {String} address user adress\n */\n public async setPublishingMarketFee<G extends boolean = false>(\n datatokenAddress: string,\n publishMarketFeeAddress: string,\n publishMarketFeeToken: string,\n publishMarketFeeAmount: string,\n address: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const dtContract = this.getContract(datatokenAddress, address)\n const mktFeeAddress = (await dtContract.methods.getPublishingMarketFee().call())[0]\n if (mktFeeAddress !== address) {\n throw new Error(`Caller is not the Publishing Market Fee Address`)\n }\n const estGas = await calculateEstimatedGas(\n address,\n dtContract.methods.setPublishingMarketFee,\n publishMarketFeeAddress,\n publishMarketFeeToken,\n publishMarketFeeAmount\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n dtContract.methods.setPublishingMarketFee,\n publishMarketFeeAddress,\n publishMarketFeeToken,\n publishMarketFeeAmount\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * @dev getPublishingMarketFee\n * Get publishingMarket Fee\n * This function allows to get the current fee set by the publishing market\n * @param {String} datatokenAddress Datatoken adress\n * @param {String} address user adress\n * @return {Promise<PublishingMarketFee>} Current fee set by the publishing market\n */\n public async getPublishingMarketFee(\n datatokenAddress: string,\n address: string\n ): Promise<PublishingMarketFee> {\n const dtContract = this.getContract(datatokenAddress, address)\n\n const publishingMarketFee = await dtContract.methods.getPublishingMarketFee().call()\n const returnValues = {\n publishMarketFeeAddress: publishingMarketFee[0],\n publishMarketFeeToken: publishingMarketFee[1],\n publishMarketFeeAmount: publishingMarketFee[2]\n }\n return returnValues\n }\n\n private async getFreOrderParams(freParams: FreOrderParams): Promise<any> {\n return {\n exchangeContract: freParams.exchangeContract,\n exchangeId: freParams.exchangeId,\n maxBaseTokenAmount: await amountToUnits(\n this.web3,\n freParams.baseTokenAddress,\n freParams.maxBaseTokenAmount,\n freParams.baseTokenDecimals\n ),\n swapMarketFee: await amountToUnits(\n this.web3,\n freParams.baseTokenAddress,\n freParams.swapMarketFee,\n freParams.baseTokenDecimals\n ),\n\n marketFeeAddress: freParams.marketFeeAddress\n }\n }\n}\n","import Web3 from 'web3'\nimport { AbiItem } from 'web3-utils'\nimport ERC721Factory from '@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json'\nimport { generateDtName, calculateEstimatedGas, ZERO_ADDRESS, sendTx } from '../utils'\nimport {\n FreCreationParams,\n DatatokenCreateParams,\n DispenserCreationParams,\n NftCreateData,\n Template,\n TokenOrder,\n ReceiptOrEstimate\n} from '../@types'\nimport { SmartContractWithAddress } from './SmartContractWithAddress'\n\n/**\n * Provides an interface for NFT Factory contract\n */\nexport class NftFactory extends SmartContractWithAddress {\n getDefaultAbi(): AbiItem | AbiItem[] {\n return ERC721Factory.abi as AbiItem[]\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<G extends boolean = false>(\n address: string,\n nftData: NftCreateData,\n estimateGas?: G\n ): Promise<G extends false ? string : number> {\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 calculateEstimatedGas(\n address,\n this.contract.methods.deployERC721Contract,\n nftData.name,\n nftData.symbol,\n nftData.templateIndex,\n ZERO_ADDRESS,\n ZERO_ADDRESS,\n nftData.tokenURI,\n nftData.transferable,\n nftData.owner\n )\n if (estimateGas) return <G extends false ? string : number>estGas\n\n // Invoke createToken function of the contract\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.deployERC721Contract,\n nftData.name,\n nftData.symbol,\n nftData.templateIndex,\n ZERO_ADDRESS,\n ZERO_ADDRESS,\n nftData.tokenURI,\n nftData.transferable,\n nftData.owner\n )\n return trxReceipt?.events?.NFTCreated?.returnValues?.[0]\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 nftCount = await this.contract.methods.getCurrentNFTCount().call()\n return nftCount\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 tokenCount = await this.contract.methods.getCurrentTokenCount().call()\n return tokenCount\n }\n\n /** Get Factory Owner\n * @return {Promise<string>} Factory Owner address\n */\n public async getOwner(): Promise<string> {\n const owner = await this.contract.methods.owner().call()\n return owner\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.contract.methods.getCurrentNFTTemplateCount().call()\n return count\n }\n\n /** Get Current Template Datatoken (ERC20) Count\n * @return {Promise<number>} Number of Datatoken Template added to this factory\n */\n public async getCurrentTokenTemplateCount(): Promise<number> {\n const count = await this.contract.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.contract.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.contract.methods.getTokenTemplate(index).call()\n return template\n }\n\n /** Check if Datatoken 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.contract.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.contract.methods.erc721List(nftAddress).call()\n return confirmAddress\n }\n\n /**\n * Add a new NFT token template - only factory Owner\n * @param {String} address\n * @param {String} templateAddress template address to add\n * @return {Promise<ReceiptOrEstimate>}\n */\n public async addNFTTemplate<G extends boolean = false>(\n address: string,\n templateAddress: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Factory Owner`)\n }\n if (templateAddress === ZERO_ADDRESS) {\n throw new Error(`Template cannot be ZERO address`)\n }\n\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.add721TokenTemplate,\n templateAddress\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.add721TokenTemplate,\n templateAddress\n )\n return <ReceiptOrEstimate<G>>trxReceipt\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<ReceiptOrEstimate>} current token template count\n */\n public async disableNFTTemplate<G extends boolean = false>(\n address: string,\n templateIndex: number,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\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 calculateEstimatedGas(\n address,\n this.contract.methods.disable721TokenTemplate,\n templateIndex\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.disable721TokenTemplate,\n templateIndex\n )\n\n return <ReceiptOrEstimate<G>>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<ReceiptOrEstimate>} current token template count\n */\n public async reactivateNFTTemplate<G extends boolean = false>(\n address: string,\n templateIndex: number,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\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 calculateEstimatedGas(\n address,\n this.contract.methods.reactivate721TokenTemplate,\n templateIndex\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.reactivate721TokenTemplate,\n templateIndex\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Add a new NFT token template - only factory Owner\n * @param {String} address\n * @param {String} templateAddress template address to add\n * @return {Promise<ReceiptOrEstimate>}\n */\n public async addTokenTemplate<G extends boolean = false>(\n address: string,\n templateAddress: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Factory Owner`)\n }\n if (templateAddress === ZERO_ADDRESS) {\n throw new Error(`Template cannot be address ZERO`)\n }\n\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.addTokenTemplate,\n templateAddress\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.addTokenTemplate,\n templateAddress\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\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<ReceiptOrEstimate>} current token template count\n */\n public async disableTokenTemplate<G extends boolean = false>(\n address: string,\n templateIndex: number,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Factory Owner`)\n }\n if (templateIndex > (await this.getCurrentTokenTemplateCount())) {\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 === false) {\n throw new Error(`Template is already disabled`)\n }\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.disableTokenTemplate,\n templateIndex\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.disableTokenTemplate,\n templateIndex\n )\n\n return <ReceiptOrEstimate<G>>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<ReceiptOrEstimate>} current token template count\n */\n public async reactivateTokenTemplate<G extends boolean = false>(\n address: string,\n templateIndex: number,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n if ((await this.getOwner()) !== address) {\n throw new Error(`Caller is not Factory Owner`)\n }\n if (templateIndex > (await this.getCurrentTokenTemplateCount())) {\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 calculateEstimatedGas(\n address,\n this.contract.methods.reactivateTokenTemplate,\n templateIndex\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.reactivateTokenTemplate,\n templateIndex\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\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/ Datatoken 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<ReceiptOrEstimate>} transaction receipt\n */\n public async startMultipleTokenOrder<G extends boolean = false>(\n address: string,\n orders: TokenOrder[],\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n if (orders.length > 50) {\n throw new Error(`Too many orders`)\n }\n\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.startMultipleTokenOrder,\n orders\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.startMultipleTokenOrder,\n orders\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * @dev createNftWithDatatoken\n * Creates a new NFT, then a Datatoken,all in one call\n * @param address Caller address\n * @param _NftCreateData input data for nft creation\n * @param _ErcCreateData input data for Datatoken creation\n * @return {Promise<ReceiptOrEstimate>} transaction receipt\n */\n\n public async createNftWithDatatoken<G extends boolean = false>(\n address: string,\n nftCreateData: NftCreateData,\n dtParams: DatatokenCreateParams,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const ercCreateData = this.getErcCreationParams(dtParams)\n\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.createNftWithErc20,\n nftCreateData,\n ercCreateData\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.createNftWithErc20,\n nftCreateData,\n ercCreateData\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * @dev createNftWithDatatokenWithFixedRate\n * Creates a new NFT, then a Datatoken, 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 dtParams input data for Datatoken Creation\n * @param freParams input data for FixedRate Creation\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async createNftWithDatatokenWithFixedRate<G extends boolean = false>(\n address: string,\n nftCreateData: NftCreateData,\n dtParams: DatatokenCreateParams,\n freParams: FreCreationParams,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const ercCreateData = this.getErcCreationParams(dtParams)\n const fixedData = this.getFreCreationParams(freParams)\n\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.createNftWithErc20WithFixedRate,\n nftCreateData,\n ercCreateData,\n fixedData\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.createNftWithErc20WithFixedRate,\n nftCreateData,\n ercCreateData,\n fixedData\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * @dev createNftWithDatatokenWithDispenser\n * Creates a new NFT, then a Datatoken, 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 dtParams input data for Datatoken Creation\n * @param dispenserParams input data for Dispenser Creation\n * @return {Promise<TransactionReceipt>} transaction receipt\n */\n public async createNftWithDatatokenWithDispenser<G extends boolean = false>(\n address: string,\n nftCreateData: NftCreateData,\n dtParams: DatatokenCreateParams,\n dispenserParams: DispenserCreationParams,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const ercCreateData = this.getErcCreationParams(dtParams)\n\n dispenserParams.maxBalance = Web3.utils.toWei(dispenserParams.maxBalance)\n dispenserParams.maxTokens = Web3.utils.toWei(dispenserParams.maxTokens)\n\n const estGas = await calculateEstimatedGas(\n address,\n this.contract.methods.createNftWithErc20WithDispenser,\n nftCreateData,\n ercCreateData,\n dispenserParams\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n const trxReceipt = await sendTx(\n address,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.createNftWithErc20WithDispenser,\n nftCreateData,\n ercCreateData,\n dispenserParams\n )\n\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n private getErcCreationParams(dtParams: DatatokenCreateParams): any {\n let name: string, symbol: string\n // Generate name & symbol if not present\n if (!dtParams.name || !dtParams.symbol) {\n ;({ name, symbol } = generateDtName())\n }\n return {\n templateIndex: dtParams.templateIndex,\n strings: [dtParams.name || name, dtParams.symbol || symbol],\n addresses: [\n dtParams.minter,\n dtParams.paymentCollector,\n dtParams.mpFeeAddress,\n dtParams.feeToken\n ],\n uints: [Web3.utils.toWei(dtParams.cap), Web3.utils.toWei(dtParams.feeAmount)],\n bytess: []\n }\n }\n\n private getFreCreationParams(freParams: FreCreationParams): any {\n if (!freParams.allowedConsumer) freParams.allowedConsumer = ZERO_ADDRESS\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 Web3.utils.toWei(freParams.fixedRate),\n Web3.utils.toWei(freParams.marketFee),\n withMint\n ]\n }\n }\n}\n","import { AbiItem } from 'web3-utils'\nimport veOceanABI from '@oceanprotocol/contracts/artifacts/contracts/ve/veOCEAN.vy/veOCEAN.json'\nimport { calculateEstimatedGas, sendTx } from '../../utils'\nimport { SmartContractWithAddress } from '../SmartContractWithAddress'\nimport { ReceiptOrEstimate } from '../../@types'\n/**\n * Provides an interface for veOcean contract\n */\nexport class VeOcean extends SmartContractWithAddress {\n getDefaultAbi(): AbiItem | AbiItem[] {\n return veOceanABI.abi as AbiItem[]\n }\n\n /**\n * Deposit `amount` tokens for `userAddress` and lock until `unlockTime`\n * @param {String} userAddress user address\n * @param {String} amount Amount of tokens to be locked\n * @param {Number} unlockTime Timestamp for unlock\n * @return {Promise<ReceiptOrEstimate>}\n */\n public async lockTokens<G extends boolean = false>(\n userAddress: string,\n amount: string,\n unlockTime: number,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const amountFormatted = await this.amountToUnits(await this.getToken(), amount)\n const estGas = await calculateEstimatedGas(\n userAddress,\n this.contract.methods.create_lock,\n amountFormatted,\n unlockTime\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n // Invoke function of the contract\n const trxReceipt = await sendTx(\n userAddress,\n estGas + 20000, // sometimes, it's not enough\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.create_lock,\n amountFormatted,\n unlockTime\n )\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Deposit `amount` tokens for `toAddress` and add to the existing lock\n * Anyone (even a smart contract) can deposit for someone else, but cannot extend their locktime and deposit for a brand new user\n * @param {String} fromUserAddress user address that sends the tx\n * @param {String} toAddress user address to deposit for\n * @param {String} amount Amount of tokens to be locked\n * @return {Promise<ReceiptOrEstimate>}\n */\n public async depositFor<G extends boolean = false>(\n fromUserAddress: string,\n toAddress: string,\n amount: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const amountFormatted = await this.amountToUnits(await this.getToken(), amount)\n const estGas = await calculateEstimatedGas(\n fromUserAddress,\n this.contract.methods.deposit_for,\n toAddress,\n amountFormatted\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n // Invoke function of the contract\n const trxReceipt = await sendTx(\n fromUserAddress,\n estGas + 20000, // sometimes, it's not enough\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.deposit_for,\n toAddress,\n amountFormatted\n )\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Deposit `amount` additional tokens for `userAddress` without modifying the unlock time\n * @param {String} userAddress user address that sends the tx\n * @param {String} amount Amount of tokens to be locked\n * @return {Promise<ReceiptOrEstimate>}\n */\n public async increaseAmount<G extends boolean = false>(\n userAddress: string,\n amount: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const amountFormatted = await this.amountToUnits(await this.getToken(), amount)\n const estGas = await calculateEstimatedGas(\n userAddress,\n this.contract.methods.increase_amount,\n amountFormatted\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n // Invoke function of the contract\n const trxReceipt = await sendTx(\n userAddress,\n estGas + 20000, // sometimes, it's not enough\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.increase_amount,\n amountFormatted\n )\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Extend the unlock time for `userAddress` to `unlockTime`\n * @param {String} userAddress user address that sends the tx\n * @param {Number} unlockTime Timestamp for new unlock time\n * @return {Promise<ReceiptOrEstimate>}\n */\n public async increaseUnlockTime<G extends boolean = false>(\n userAddress: string,\n unlockTime: number,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const estGas = await calculateEstimatedGas(\n userAddress,\n this.contract.methods.increase_unlock_time,\n unlockTime\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n // Invoke function of the contract\n const trxReceipt = await sendTx(\n userAddress,\n estGas + 20000, // sometimes, it's not enough\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.increase_unlock_time,\n unlockTime\n )\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Withdraw all tokens for `userAddress`\n * @param {String} userAddress user address that sends the tx\n * @return {Promise<ReceiptOrEstimate>}\n */\n public async withdraw<G extends boolean = false>(\n userAddress: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const estGas = await calculateEstimatedGas(\n userAddress,\n this.contract.methods.withdraw\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n // Invoke function of the contract\n const trxReceipt = await sendTx(\n userAddress,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.withdraw\n )\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /** Get voting power for address\n * @param {String} userAddress user address\n * @return {Promise<number>}\n */\n public async getVotingPower(userAddress: string): Promise<number> {\n const balance = await this.contract.methods.balanceOf(userAddress).call()\n return balance\n }\n\n /** Get locked balance\n * @param {String} userAddress user address\n * @return {Promise<string>}\n */\n public async getLockedAmount(userAddress: string): Promise<string> {\n const balance = await this.contract.methods.locked(userAddress).call()\n const balanceFormated = await this.unitsToAmount(\n await this.getToken(),\n balance.amount\n )\n\n return balanceFormated\n }\n\n /** Get untilLock for address\n * @param {String} userAddress user address\n * @return {Promise<number>}\n */\n public async lockEnd(userAddress: string): Promise<number> {\n const untilLock = await this.contract.methods.locked__end(userAddress).call()\n return untilLock\n }\n\n /** Get total supply\n * @return {Promise<number>}\n */\n public async totalSupply(): Promise<string> {\n const supplyFormated = await this.unitsToAmount(\n await this.getToken(),\n await this.contract.methods.totalSupply().call()\n )\n return supplyFormated\n }\n\n /** Get token\n * @return {Promise<string>}\n */\n public async getToken(): Promise<string> {\n const tokenAddress = await this.contract.methods.token().call()\n return tokenAddress\n }\n}\n","import { AbiItem } from 'web3-utils'\nimport veFeeABI from '@oceanprotocol/contracts/artifacts/contracts/ve/veFeeDistributor.vy/veFeeDistributor.json'\nimport { calculateEstimatedGas, sendTx } from '../../utils'\nimport { SmartContractWithAddress } from '../SmartContractWithAddress'\nimport { ReceiptOrEstimate } from '../../@types'\n/**\n * Provides an interface for veOcean contract\n */\nexport class VeFeeDistributor extends SmartContractWithAddress {\n getDefaultAbi(): AbiItem | AbiItem[] {\n return veFeeABI.abi as AbiItem[]\n }\n\n /**\n * Claim fees for `userAddress`\n * Each call to claim look at a maximum of 50 user veOCEAN points.\n For accounts with many veOCEAN related actions, this function\n may need to be called more than once to claim all available\n fees. In the `Claimed` event that fires, if `claim_epoch` is\n less than `max_epoch`, the account may claim again\n * @param {String} userAddress user address\n * @return {Promise<ReceiptOrEstimate>}\n */\n public async claim<G extends boolean = false>(\n userAddress: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const estGas = await calculateEstimatedGas(userAddress, this.contract.methods.claim)\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n // Invoke function of the contract\n const trxReceipt = await sendTx(\n userAddress,\n estGas + 20000,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.claim\n )\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * Make multiple fee claims in a single call\n Used to claim for many accounts at once, or to make\n multiple claims for the same address when that address\n has significant veOCEAN history\n * @param {String} fromUserAddress user address that sends the tx\n * @param {String} addresses array of addresses to claim\n * @return {Promise<ReceiptOrEstimate>}\n */\n public async claimMany<G extends boolean = false>(\n fromUserAddress: string,\n addresses: string[],\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const estGas = await calculateEstimatedGas(\n fromUserAddress,\n this.contract.methods.claim_many,\n addresses\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n // Invoke function of the contract\n const trxReceipt = await sendTx(\n fromUserAddress,\n estGas + 20000,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.claim_many,\n addresses\n )\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n}\n","import { AbiItem } from 'web3-utils'\nimport veAllocateABI from '@oceanprotocol/contracts/artifacts/contracts/ve/veAllocate.sol/veAllocate.json'\nimport { calculateEstimatedGas, sendTx } from '../../utils'\nimport { SmartContractWithAddress } from '../SmartContractWithAddress'\nimport { ReceiptOrEstimate } from '../../@types'\n/**\n * Provides an interface for veOcean contract\n */\nexport class VeAllocate extends SmartContractWithAddress {\n getDefaultAbi(): AbiItem | AbiItem[] {\n return veAllocateABI.abi as AbiItem[]\n }\n\n /**\n * set a specific percentage of veOcean to a specific nft\n * Maximum allocated percentage is 10000, so 1% is specified as 100\n * @param {String} userAddress user address\n * @param {String} amount Percentage used\n * @param {String} nft NFT address to allocate to\n * @param {String} chainId chainId of NFT\n * @return {Promise<ReceiptOrEstimate>}\n */\n public async setAllocation<G extends boolean = false>(\n userAddress: string,\n amount: string,\n nft: string,\n chainId: number,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const estGas = await calculateEstimatedGas(\n userAddress,\n this.contract.methods.setAllocation,\n amount,\n nft,\n chainId\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n // Invoke function of the contract\n const trxReceipt = await sendTx(\n userAddress,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.setAllocation,\n amount,\n nft,\n chainId\n )\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * set specific percetage of veOcean to multiple nfts\n * Maximum allocated percentage is 10000, so 1% is specified as 100\n * @param {String} userAddress user address\n * @param {String[]} amount Array of percentages used\n * @param {String[]} nft Array of NFT addresses\n * @param {String[]} chainId Array of chainIds\n * @return {Promise<ReceiptOrEstimate>}\n */\n public async setBatchAllocation<G extends boolean = false>(\n userAddress: string,\n amount: string[],\n nft: string[],\n chainId: number[],\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const estGas = await calculateEstimatedGas(\n userAddress,\n this.contract.methods.setBatchAllocation,\n amount,\n nft,\n chainId\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n // Invoke function of the contract\n const trxReceipt = await sendTx(\n userAddress,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.setBatchAllocation,\n amount,\n nft,\n chainId\n )\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /** Get totalAllocation for address\n * @param {String} userAddress user address\n * @return {Promise<number>}\n */\n public async getTotalAllocation(userAddress: string): Promise<number> {\n const allocation = await this.contract.methods.getTotalAllocation(userAddress).call()\n return allocation\n }\n\n /** Get getveAllocation for address, nft, chainId\n * @param {String} userAddress user address\n * @param {String} nft NFT address to allocate to\n * @param {String} chainId chainId of NFT\n * @return {Promise<number>}\n */\n public async getVeAllocation(\n userAddress: string,\n nft: string,\n chainId: string\n ): Promise<number> {\n const allocation = await this.contract.methods\n .getveAllocation(userAddress, nft, chainId)\n .call()\n return allocation\n }\n}\n","import { AbiItem } from 'web3-utils'\nimport dfRewardsABI from '@oceanprotocol/contracts/artifacts/contracts/df/DFRewards.sol/DFRewards.json'\nimport { calculateEstimatedGas, sendTx } from '../../utils'\nimport { SmartContractWithAddress } from '../SmartContractWithAddress'\nimport { ReceiptOrEstimate } from '../../@types'\n\n/**\n * Provides an interface for DFRewards contract\n */\nexport class DfRewards extends SmartContractWithAddress {\n getDefaultAbi(): AbiItem | AbiItem[] {\n return dfRewardsABI.abi as AbiItem[]\n }\n\n /** Get available DF Rewards for a token\n * @param {String} userAddress user address\n * @param {String} tokenAddress token address\n * @return {Promise<string>}\n */\n public async getAvailableRewards(\n userAddress: string,\n tokenAddress: string\n ): Promise<string> {\n const rewards = await this.contract.methods\n .claimable(userAddress, tokenAddress)\n .call()\n const rewardsFormated = await this.unitsToAmount(tokenAddress, rewards)\n\n return rewardsFormated\n }\n\n /**\n * claim rewards for any address\n * @param {String} fromUserAddress user that generates the tx\n * @param {String} userAddress user address to claim\n * @param {String} tokenAddress token address\n * @return {Promise<ReceiptOrEstimate>}\n */\n public async claimRewards<G extends boolean = false>(\n fromUserAddress: string,\n userAddress: string,\n tokenAddress: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const estGas = await calculateEstimatedGas(\n fromUserAddress,\n this.contract.methods.claimFor,\n userAddress,\n tokenAddress\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n // Invoke function of the contract\n const trxReceipt = await sendTx(\n fromUserAddress,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.claimFor,\n userAddress,\n tokenAddress\n )\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n\n /**\n * allocate rewards to address. An approve must exist before calling this function.\n * @param {String} fromUserAddress user that generates the tx\n * @param {String[]} userAddresses array of users that will receive rewards\n * @param {String[]} amounts array of amounts\n * @param {String} tokenAddress token address\n * @return {Promise<ReceiptOrEstimate>}\n */\n public async allocateRewards<G extends boolean = false>(\n fromUserAddress: string,\n userAddresses: string[],\n amounts: string[],\n tokenAddress: string,\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n for (let i = 0; i < amounts.length; i++) {\n amounts[i] = await this.amountToUnits(tokenAddress, amounts[i])\n }\n const estGas = await calculateEstimatedGas(\n fromUserAddress,\n this.contract.methods.allocate,\n userAddresses,\n amounts,\n tokenAddress\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n // Invoke function of the contract\n const trxReceipt = await sendTx(\n fromUserAddress,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.allocate,\n userAddresses,\n amounts,\n tokenAddress\n )\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n}\n","import { AbiItem } from 'web3-utils'\nimport dfStrategyV1ABI from '@oceanprotocol/contracts/artifacts/contracts/df/DFStrategyV1.sol/DFStrategyV1.json'\nimport { calculateEstimatedGas, sendTx } from '../../utils'\nimport { SmartContractWithAddress } from '../SmartContractWithAddress'\nimport { ReceiptOrEstimate } from '../../@types'\n\n/**\n * Provides an interface for dfStrategyV1 contract\n */\nexport class DfStrategyV1 extends SmartContractWithAddress {\n getDefaultAbi(): AbiItem | AbiItem[] {\n return dfStrategyV1ABI.abi as AbiItem[]\n }\n\n /** Get available DF Rewards for multiple tokens\n * @param {String} userAddress user address\n * @param {String} tokenAddresses array of tokens\n * @return {Promise<string[]>}\n */\n public async getMultipleAvailableRewards(\n userAddress: string,\n tokenAddresses: string[]\n ): Promise<string[]> {\n const rewards = await this.contract.methods\n .claimables(userAddress, tokenAddresses)\n .call()\n const rewardsFormated: string[] = []\n for (let i = 0; i < rewards.length; i++) {\n rewardsFormated.push(await this.unitsToAmount(tokenAddresses[i], rewards[i]))\n }\n return rewardsFormated\n }\n\n /**\n * claim multiple token rewards for any address\n * @param {String} fromUserAddress user that generates the tx\n * @param {String} userAddress user address to claim\n * @param {String} tokenAddresses array of tokens\n * @return {Promise<ReceiptOrEstimate>}\n */\n public async claimMultipleRewards<G extends boolean = false>(\n fromUserAddress: string,\n userAddress: string,\n tokenAddresses: string[],\n estimateGas?: G\n ): Promise<ReceiptOrEstimate<G>> {\n const estGas = await calculateEstimatedGas(\n fromUserAddress,\n this.contract.methods.claimMultiple,\n userAddress,\n tokenAddresses\n )\n if (estimateGas) return <ReceiptOrEstimate<G>>estGas\n\n // Invoke function of the contract\n const trxReceipt = await sendTx(\n fromUserAddress,\n estGas + 1,\n this.web3,\n this.config?.gasFeeMultiplier,\n this.contract.methods.claimMultiple,\n userAddress,\n tokenAddresses\n )\n return <ReceiptOrEstimate<G>>trxReceipt\n }\n}\n","import fetch from 'cross-fetch'\nimport { LoggerInstance, sleep } from '../utils'\nimport { Asset, DDO, ValidateMetadata } from '../@types'\n\nexport interface SearchQuery {\n from?: number\n size?: number\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n query: any\n sort?: { [jsonPath: string]: string }\n aggs?: any\n}\n\nexport class Aquarius {\n public aquariusURL: string\n\n /**\n * Instantiate Aquarius\n * @param {String} aquariusURL\n */\n constructor(aquariusURL: string) {\n this.aquariusURL = aquariusURL\n }\n\n /** Resolves a DID\n * @param {string} did\n * @param {AbortSignal} signal abort signal\n * @return {Promise<Asset>} Asset\n */\n public async resolve(did: string, signal?: AbortSignal): Promise<Asset> {\n const path = this.aquariusURL + '/api/aquarius/assets/ddo/' + did\n try {\n const response = await fetch(path, {\n method: 'GET',\n headers: { 'Content-Type': 'application/json' },\n signal\n })\n\n if (response.ok) {\n const raw = await response.json()\n return raw as Asset\n } else {\n throw new Error('HTTP request failed with status ' + response.status)\n }\n } catch (e) {\n LoggerInstance.error(e)\n throw new Error('HTTP request failed')\n }\n }\n\n /**\n * Blocks until Aqua will cache the did (or the update for that did) or timeouts\n \n * @param {string} did DID of the asset.\n * @param {string} txid used when the did exists and we expect an update with that txid.\n * @param {AbortSignal} signal abort signal\n * @return {Promise<DDO>} DDO of the asset.\n */\n public async waitForAqua(\n did: string,\n txid?: string,\n signal?: AbortSignal\n ): Promise<Asset> {\n let tries = 0\n do {\n try {\n const path = this.aquariusURL + '/api/aquarius/assets/ddo/' + did\n const response = await fetch(path, {\n method: 'GET',\n headers: { 'Content-Type': 'application/json' },\n signal\n })\n if (response.ok) {\n const ddo = await response.json()\n if (txid) {\n // check tx\n if (ddo.event && ddo.event.txid === txid) return ddo as Asset\n } else return ddo as Asset\n }\n } catch (e) {\n // do nothing\n }\n await sleep(1500)\n tries++\n } while (tries < 100)\n return null\n }\n\n /**\n * Validate DDO content\n * @param {DDO} ddo DID Descriptor Object content.\n * @param {AbortSignal} signal abort signal\n * @return {Promise<ValidateMetadata>}.\n */\n public async validate(ddo: DDO, signal?: AbortSignal): Promise<ValidateMetadata> {\n const status: ValidateMetadata = {\n valid: false\n }\n let jsonResponse\n try {\n const path = this.aquariusURL + '/api/aquarius/assets/ddo/validate'\n\n const response = await fetch(path, {\n method: 'POST',\n body: JSON.stringify(ddo),\n headers: { 'Content-Type': 'application/octet-stream' },\n signal\n })\n\n jsonResponse = await response.json()\n if (response.status === 200) {\n status.valid = true\n status.hash = jsonResponse.hash\n status.proof = {\n validatorAddress: jsonResponse.publicKey,\n r: jsonResponse.r[0],\n s: jsonResponse.s[0],\n v: jsonResponse.v\n }\n } else {\n status.errors = jsonResponse\n LoggerInstance.error('validate Metadata failed:', response.status, status.errors)\n }\n } catch (error) {\n LoggerInstance.error('Error validating metadata: ', error)\n }\n return status\n }\n\n /**\n * Search over the DDOs using a query.\n * @param {string} did DID of the asset\n * @param {AbortSignal} signal abort signal\n * @return {Promise<QueryResult>}\n */\n public async getAssetMetadata(did: string, signal?: AbortSignal): Promise<any> {\n const path = this.aquariusURL + '/api/aquarius/assets/metadata/' + did\n\n try {\n const response = await fetch(path, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json'\n },\n signal\n })\n\n if (response.ok) {\n return response.json()\n } else {\n throw new Error(\n 'getAssetMetadata failed: ' + response.status + response.statusText\n )\n }\n } catch (error) {\n LoggerInstance.error('Error getting metadata: ', error)\n throw new Error('Error getting metadata: ' + error)\n }\n }\n\n /**\n * Search over the DDOs using a query.\n * @param {SearchQuery} query Query to filter the DDOs.\n * @param {AbortSignal} signal abort signal\n * @return {Promise<QueryResult>}\n */\n public async querySearch(query: SearchQuery, signal?: AbortSignal): Promise<any> {\n const path = this.aquariusURL + '/api/aquarius/assets/query'\n\n try {\n const response = await fetch(path, {\n method: 'POST',\n body: JSON.stringify(query),\n headers: {\n 'Content-Type': 'application/json'\n },\n signal\n })\n\n if (response.ok) {\n return response.json()\n } else {\n throw new Error('querySearch failed: ' + response.status + response.statusText)\n }\n } catch (error) {\n LoggerInstance.error('Error querying metadata: ', error)\n throw new Error('Error querying metadata: ' + error)\n }\n }\n}\n","import Web3 from 'web3'\nimport fetch from 'cross-fetch'\nimport { LoggerInstance } from '../utils'\nimport {\n FileInfo,\n ComputeJob,\n ComputeOutput,\n ComputeAlgorithm,\n ComputeAsset,\n ComputeEnvironment,\n ProviderInitialize,\n ProviderComputeInitializeResults,\n ServiceEndpoint,\n UserCustomParameters\n} from '../@types'\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 this.getData(providerUri)\n return await endpoints.json()\n } catch (e) {\n LoggerInstance.error('Finding the service endpoints failed:', e)\n throw new Error('HTTP request failed calling Provider')\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 /** Gets current nonce\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: { 'Content-Type': 'application/json' },\n signal\n })\n return (await response.json()).nonce.toString()\n } catch (e) {\n LoggerInstance.error(e)\n throw new Error('HTTP request failed calling Provider')\n }\n }\n\n public async signProviderRequest(\n web3: Web3,\n accountId: string,\n message: string,\n password?: string\n ): Promise<string> {\n const consumerMessage = web3.utils.soliditySha3({\n t: 'bytes',\n v: web3.utils.utf8ToHex(message)\n })\n const isMetaMask =\n web3 && web3.currentProvider && (web3.currentProvider as any).isMetaMask\n if (isMetaMask)\n return await web3.eth.personal.sign(consumerMessage, accountId, password)\n else return await web3.eth.sign(consumerMessage, accountId)\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 if (!path) return null\n try {\n const response = await fetch(path, {\n method: 'POST',\n body: JSON.stringify(data),\n headers: { 'Content-Type': 'application/octet-stream' },\n signal\n })\n return await response.text()\n } catch (e) {\n LoggerInstance.error(e)\n throw new Error('HTTP request failed calling Provider')\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<FileInfo[]>} urlDetails\n */\n public async checkDidFiles(\n did: string,\n serviceId: string,\n providerUri: string,\n withChecksum: boolean = false,\n signal?: AbortSignal\n ): Promise<FileInfo[]> {\n const providerEndpoints = await this.getEndpoints(providerUri)\n const serviceEndpoints = await this.getServiceEndpoints(\n providerUri,\n providerEndpoints\n )\n const args = { did, serviceId, checksum: withChecksum }\n const files: FileInfo[] = []\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: { 'Content-Type': 'application/json' },\n signal\n })\n const results: FileInfo[] = await response.json()\n for (const result of results) {\n files.push(result)\n }\n return files\n } catch (e) {\n LoggerInstance.error(e)\n throw new Error('HTTP request failed calling Provider')\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<FileInfo[]>} urlDetails\n */\n public async checkFileUrl(\n url: string,\n providerUri: string,\n signal?: AbortSignal\n ): Promise<FileInfo[]> {\n const providerEndpoints = await this.getEndpoints(providerUri)\n const serviceEndpoints = await this.getServiceEndpoints(\n providerUri,\n providerEndpoints\n )\n const args = { url, type: 'url' }\n const files: FileInfo[] = []\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: { 'Content-Type': 'application/json' },\n signal\n })\n const results: FileInfo[] = await response.json()\n for (const result of results) {\n files.push(result)\n }\n return files\n } catch (e) {\n LoggerInstance.error(e)\n throw new Error('HTTP request failed calling Provider')\n }\n }\n\n /** Get Compute Environments\n * @return {Promise<ComputeEnvironment[]>} urlDetails\n */\n public async getComputeEnvironments(\n providerUri: string,\n signal?: AbortSignal\n ): Promise<ComputeEnvironment[]> {\n const providerEndpoints = await this.getEndpoints(providerUri)\n const serviceEndpoints = await this.getServiceEndpoints(\n providerUri,\n providerEndpoints\n )\n const path = this.getEndpointURL(serviceEndpoints, 'computeEnvironments')?.urlPath\n if (!path) return null\n try {\n const response = await fetch(path, {\n method: 'GET',\n headers: { 'Content-Type': 'application/json' },\n signal\n })\n const envs: ComputeEnvironment[] = await response.json()\n return envs\n } catch (e) {\n LoggerInstance.error(e)\n throw new Error('HTTP request failed calling Provider')\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 += '&environment=' + encodeURI(computeEnv)\n if (validUntil) initializeUrl += '&validUntil=' + validUntil\n try {\n const response = await fetch(initializeUrl, {\n method: 'GET',\n headers: { 'Content-Type': 'application/json' },\n 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 /** Initialize a compute request.\n * @param {ComputeAsset} assets\n * @param {ComputeAlgorithmber} algorithm\n * @param {string} computeEnv\n * @param {number} validUntil\n * @param {string} providerUri Identifier of the asset to be registered in ocean\n * @param {string} accountId\n * @param {AbortSignal} signal abort signal\n * @return {Promise<ProviderComputeInitialize>} ProviderComputeInitialize data\n */\n public async initializeCompute(\n assets: ComputeAsset[],\n algorithm: ComputeAlgorithm,\n computeEnv: string,\n validUntil: number,\n providerUri: string,\n accountId: string,\n signal?: AbortSignal\n ): Promise<ProviderComputeInitializeResults> {\n const providerEndpoints = await this.getEndpoints(providerUri)\n const serviceEndpoints = await this.getServiceEndpoints(\n providerUri,\n providerEndpoints\n )\n const providerData = {\n datasets: assets,\n algorithm,\n compute: { env: computeEnv, validUntil },\n consumerAddress: accountId\n }\n const initializeUrl = this.getEndpointURL(serviceEndpoints, 'initializeCompute')\n ? this.getEndpointURL(serviceEndpoints, 'initializeCompute').urlPath\n : null\n if (!initializeUrl) return null\n try {\n const response = await fetch(initializeUrl, {\n method: 'POST',\n body: JSON.stringify(providerData),\n headers: { 'Content-Type': 'application/json' },\n signal\n })\n const results = await response.json()\n return results\n } catch (e) {\n LoggerInstance.error(e)\n throw new Error('ComputeJob cannot be initialized')\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.signProviderRequest(web3, accountId, did + nonce)\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 {string} computeEnv\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.signProviderRequest(\n web3,\n consumerAddress,\n signatureMessage\n )\n const payload = Object()\n payload.consumerAddress = consumerAddress\n payload.signature = signature\n payload.nonce = nonce\n payload.environment = 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: { 'Content-Type': 'application/json' },\n signal\n })\n\n if (response?.ok) {\n const params = await response.json()\n return params\n }\n LoggerInstance.error(\n 'Compute start failed: ',\n response.status,\n response.statusText,\n await response.json()\n )\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 throw new Error('HTTP request failed calling Provider')\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 && `${this.noZeroX(did)}`) || ''\n signatureMessage += nonce\n const signature = await this.signProviderRequest(\n web3,\n consumerAddress,\n signatureMessage\n )\n const payload = Object()\n payload.signature = signature\n payload.documentId = this.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: { 'Content-Type': 'application/json' },\n 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 throw new Error('HTTP request failed calling Provider')\n }\n }\n\n /** Get compute status for a specific jobId/documentId/owner.\n * @param {string} providerUri The URI of the provider we want to query\n * @param {string} consumerAddress The consumer ethereum address\n * @param {string} jobId The ID of a compute job.\n * @param {string} did The ID of the asset\n * @param {AbortSignal} signal abort signal\n * @return {Promise<ComputeJob | ComputeJob[]>}\n */\n public async computeStatus(\n providerUri: string,\n consumerAddress: string,\n jobId?: string,\n did?: string,\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 computeStatusUrl = this.getEndpointURL(serviceEndpoints, 'computeStatus')\n ? this.getEndpointURL(serviceEndpoints, 'computeStatus').urlPath\n : null\n\n let url = `?consumerAddress=${consumerAddress}`\n url += (did && `&documentId=${this.noZeroX(did)}`) || ''\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: { 'Content-Type': 'application/json' },\n signal\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 throw new Error('HTTP request failed calling Provider')\n }\n }\n\n /** Get compute result url\n * @param {string} providerUri The URI of the provider we want to query\n * @param {Web3} web3 Web3 instance\n * @param {string} consumerAddress The consumer ethereum address\n * @param {string} jobId The ID of a compute job.\n * @param {number} index Result index\n * @return {Promise<string>}\n */\n public async getComputeResultUrl(\n providerUri: string,\n web3: Web3,\n consumerAddress: string,\n jobId: string,\n index: number\n ): Promise<string> {\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 = Date.now()\n let signatureMessage = consumerAddress\n signatureMessage += jobId\n signatureMessage += index.toString()\n signatureMessage += nonce\n const signature = await this.signProviderRequest(\n web3,\n consumerAddress,\n signatureMessage\n )\n if (!computeResultUrl) return null\n let resultUrl = computeResultUrl\n resultUrl += `?consumerAddress=${consumerAddress}`\n resultUrl += `&jobId=${jobId}`\n resultUrl += `&index=${index.toString()}`\n resultUrl += `&nonce=${nonce}`\n resultUrl += (signature && `&signature=${signature}`) || ''\n return resultUrl\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 && `${this.noZeroX(did)}`) || ''\n signatureMessage += nonce\n const signature = await this.signProviderRequest(\n web3,\n consumerAddress,\n signatureMessage\n )\n const payload = Object()\n payload.documentId = this.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: { 'Content-Type': 'application/json' },\n 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 throw new Error('HTTP request failed calling Provider')\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: { 'Content-Type': 'application/json' },\n 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 private noZeroX(input: string): string {\n return this.zeroXTransformer(input, false)\n }\n\n private zeroXTransformer(input = '', zeroOutput: boolean): string {\n const { valid, output } = this.inputMatch(\n input,\n /^(?:0x)*([a-f0-9]+)$/i,\n 'zeroXTransformer'\n )\n return (zeroOutput && valid ? '0x' : '') + output\n }\n\n // Shared functions\n private 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\n private async getData(url: string): Promise<Response> {\n return fetch(url, {\n method: 'GET',\n headers: {\n 'Content-type': 'application/json'\n }\n })\n }\n}\n\nexport const ProviderInstance = new Provider()\n","import { AbiItem } from 'web3-utils/types'\nimport { LogLevel } from '../utils'\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 nftFactoryAddress?: string\n\n /**\n * datatokens ABI\n * @type {string}\n */\n public datatokensABI?: 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","import sha256 from 'crypto-js/sha256'\nimport Web3 from 'web3'\n\nexport function generateDid(nftAddress: string, chainId: number): string {\n nftAddress = Web3.utils.toChecksumAddress(nftAddress)\n const checksum = sha256(nftAddress + chainId.toString(10))\n return `did:op:${checksum.toString()}`\n}\n\nexport function getHash(data: any): string {\n return sha256(data).toString()\n}\n","import Web3 from 'web3'\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"],"names":["ZERO_ADDRESS","FEE_HISTORY_NOT_SUPPORTED","sendTx","from","estGas","web3","gasFeeMultiplier","functionToSend","apply","send","sendTxValue","gas","eth","getFeeHistory","feeHistory","baseFeePerGas","_feeHistory$baseFeePe","reward","_feeHistory$reward","_feeHistory$reward$","getFairGasPrice","gasPrice","aggressiveFee","BigNumber","_feeHistory$reward2","_feeHistory$reward2$","multipliedBy","maxPriorityFeePerGas","integerValue","ROUND_DOWN","toString","maxFeePerGas","plus","_feeHistory$baseFeePe2","err","message","LoggerInstance","log","calculateEstimatedGas","functionToEstimateGas","estimateGas","amountToUnits","token","amount","tokenDecimals","decimals","config","EXPONENTIAL_AT","times","exponentiatedBy","toFixed","tokenContract","Contract","minAbi","methods","call","unitsToAmount","amountFormatted","div","getGasPrice","x","setContractDefaults","contract","transactionBlockTimeout","transactionConfirmationBlocks","transactionPollingTimeout","generateDtName","wordList","list","wordListDefault","random1","Math","floor","random","adjectives","length","random2","nouns","indexNumber","adjective","replace","c","toUpperCase","noun","name","symbol","substring","downloadFile","LogLevel","sleep","ms","Promise","resolve","setTimeout","Logger","logLevel","Error","this","setLevel","bypass","dispatch","Infinity","debug","Verbose","Log","warn","Warn","error","verb","level","console","constant","inputs","outputs","type","payable","stateMutability","anonymous","indexed","allowanceWei","tokenAddress","account","spender","allowance","trxReceipt","configHelperNetworksBase","chainId","network","metadataCacheUri","nodeUri","providerUri","subgraphUri","explorerUri","oceanTokenAddress","oceanTokenSymbol","fixedRateExchangeAddress","dispenserAddress","startBlock","configHelperNetworks","ConfigHelper","getAddressesFromEnv","customAddresses","configAddresses","nftFactoryAddress","ERC721Factory","opfCommunityFeeCollector","OPFCommunityFeeCollector","FixedPrice","Dispenser","Ocean","process","env","AQUARIUS_URI","DefaultContractsAddresses","getConfig","infuraProjectId","filterBy","find","SmartContract","abi","getDefaultAbi","_this6$config","getContract","address","SmartContractWithAddress","_this","DispenserAbi","status","dtAdress","_this2","maxTokens","utils","fromWei","maxBalance","balance","create","dtAddress","allowedSwapper","_this4","toWei","_this4$config","activate","_this6","deactivate","_this8","_this8$config","setAllowedSwapper","newAllowedSwapper","_this10","_this10$config","dispense","destination","_this12","_this12$config","ownerWithdraw","_this14","_this14$config","isDispensable","datatoken","active","Decimal","greaterThanOrEqualTo","String","greaterThan","isMinter","FixedRateExchange","FixedRateExchangeAbi","generateExchangeId","baseToken","buyDatatokens","exchangeId","datatokenAmount","maxBaseTokenAmount","consumeMarketAddress","consumeMarketFee","getExchange","exchange","consumeMarketFeeFormatted","dtDecimals","dtAmountFormatted","btDecimals","maxBtFormatted","buyDT","sellDatatokens","minBaseTokenAmount","minBtFormatted","sellDT","getNumberOfExchanges","setRate","newRate","toggleExchangeState","_this16","_this16$config","getRate","_this18","weiRate","getDatatokenSupply","_this20","getDTSupply","dtSupply","getBasetokenSupply","_this22","getBTSupply","btSupply","getAllowedSwapper","calcBaseInGivenDatatokensOut","_this26","fixedRateExchange","_this25$contract$meth","calcBaseInGivenOutDT","_calcBaseInGivenOutDT","outDT","baseTokenAmount","marketFeeAmount","oceanFeeAmount","consumeMarketFeeAmount","getAmountBasetokensOut","_this28","_this27$contract$meth","calcBaseOutGivenInDT","_calcBaseOutGivenInDT","_this30","dtBalance","btBalance","fixedRate","getFeesInfo","_this32","feesInfo","opcFee","marketFee","marketFeeAvailable","oceanFeeAvailable","getExchanges","isActive","activateMint","_this38","withMint","toggleMintState","_this38$config","deactivateMint","_this40","_this40$config","collectBasetokens","_this42","fixedrate","amountWei","collectBT","_this42$config","collectDatatokens","_this44","collectDT","_this44$config","collectMarketFee","_this46","_this46$config","collectOceanFee","_this48","_this48$config","getOPCCollector","opcCollector","getRouter","router","getExchangeOwner","_this53$getExchange","exchangeOwner","updateMarketFee","newMarketFee","_this56","_this56$config","updateMarketFeeCollector","newMarketFeeCollector","_this58","_this58$config","Router","FactoryRouter","buyDatatokenBatch","operations","buyDTBatch","_this2$config","isApprovedToken","isFixedPrice","isFixedRateContract","getOwner","routerOwner","getNFTFactory","factory","addApprovedToken","_this11$getOwner","removeApprovedToken","_this13$getOwner","addFixedRateContract","_this15$getOwner","removeFixedRateContract","_this17$getOwner","_this18$config","addDispenserContract","_this19$getOwner","_this20$config","removeDispenserContract","_this21$getOwner","_this22$config","getOPCFee","getCurrentOPCFee","swapOceanFee","updateOPCFee","newSwapOceanFee","newSwapNonOceanFee","newConsumeFee","newProviderFee","_this27$getOwner","_this28$config","Nft","ERC721Template","createDatatoken","nftAddress","minter","paymentCollector","mpFeeAddress","feeToken","feeAmount","cap","templateIndex","getNftPermissions","_this$getNftPermissio","deployERC20","nftContract","createERC20","events","_trxReceipt$events","TokenCreated","_trxReceipt$events$To","returnValues","_trxReceipt$events$To2","addManager","manager","getNftOwner","_this3$getNftOwner","removeManager","_this5$getNftOwner","addDatatokenDeployer","datatokenDeployer","_this7$getNftPermissi","addToCreateERC20List","removeDatatokenDeployer","_temp","_this9$getNftPermissi2","removeFromCreateERC20List","_this9$getNftPermissi","addMetadataUpdater","metadataUpdater","_this11$getNftPermiss","addToMetadataList","removeMetadataUpdater","_temp3","_this13$getNftPermiss2","updateMetadata","removeFromMetadataList","_this13$getNftPermiss","addStoreUpdater","storeUpdater","_this15$getNftPermiss","addTo725StoreList","removeStoreUpdater","_temp5","_this17$getNftPermiss2","store","removeFrom725StoreList","_this17$getNftPermiss","cleanPermissions","_this19$getNftOwner","transferNft","nftOwner","nftReceiver","tokenId","_this21$getNftOwner","tokenIdentifier","transferFrom","safeTransferNft","_this24","_this23$getNftOwner","safeTransferFrom","_this24$config","setMetadata","metadataState","metadataDecryptorUrl","metadataDecryptorAddress","flags","data","metadataHash","metadataProofs","_this25$getNftPermiss","setMetaData","_this26$config","setMetadataAndTokenURI","metadataAndTokenURI","_this27$getNftPermiss","sanitizedMetadataAndTokenURI","setMetaDataAndTokenURI","setMetadataState","_this29$getNftPermiss","setMetaDataState","_this30$config","setTokenURI","_this32$config","ownerOf","getPermissions","getMetadata","getMetaData","isDatatokenDeployer","isERC20Deployer","setData","key","value","_this41$getNftPermiss","keyHash","keccak256","valueHex","asciiToHex","setNewData","getData","hexToAscii","getTokenURI","id","tokenURI","Datatoken","abiEnterprise","nft","ERC20TemplateEnterprise","ERC20Template","_proto","approve","dtContract","_this3","_this3$config","createFixedRate","fixedRateParams","_this5","allowedConsumer","fixedRateAddress","baseTokenAddress","owner","marketFeeCollector","baseTokenDecimals","datatokenDecimals","_this5$config","createDispenser","dispenserParams","_this7","_this7$config","mint","toAddress","_this9","_this8$getPermissions","getCap","capAvailble","gte","_this9$config","addMinter","_this11","_this10$isDatatokenDe","_this11$config","removeMinter","_this13","_this12$isDatatokenDe","_this13$config","addPaymentManager","paymentManager","_this15","_this14$isDatatokenDe","_this15$config","removePaymentManager","_this17","_this16$isDatatokenDe","_this17$config","setPaymentCollector","_this19","nftPermissions","isPaymentManager","isNftOwner","_this19$config","_this18$nft$getNftOwn","_this18$getPermission","getNFTAddress","getPaymentCollector","transfer","weiAmount","transferWei","_this25","_this25$config","startOrder","consumer","serviceIndex","providerFees","_this27","consumeMarketFeeAddress","consumeMarketFeeToken","_this27$config","reuseOrder","orderTxId","_this29","_this29$config","buyFromFreAndOrder","orderParams","freParams","_this31","getFreOrderParams","freContractParams","_this31$config","buyFromDispenserAndOrder","dispenserContract","_this33","_this33$config","_this35","_this35$config","_this37","_this36$nft2","_this36$nft$getNftOwn","_this37$config","permissions","_this41","getDecimals","getERC721Address","datatokenAddress","_this49","balanceOf","setPublishingMarketFee","publishMarketFeeAddress","publishMarketFeeToken","publishMarketFeeAmount","_this51","getPublishingMarketFee","_dtContract$methods$g","_this51$config","publishingMarketFee","exchangeContract","_this55","swapMarketFee","marketFeeAddress","NftFactory","createNFT","nftData","getCurrentNFTTemplateCount","_nftData$templateInde2","getNFTTemplate","_this$getNFTTemplate","deployERC721Contract","transferable","NFTCreated","_trxReceipt$events$NF","_trxReceipt$events$NF2","getCurrentNFTCount","getCurrentTokenCount","getCurrentTokenTemplateCount","getCurrentTemplateCount","index","getTokenTemplate","checkDatatoken","erc20List","checkNFT","erc721List","addNFTTemplate","templateAddress","add721TokenTemplate","disableNFTTemplate","_this23$getOwner","disable721TokenTemplate","reactivateNFTTemplate","_this25$getOwner","reactivate721TokenTemplate","addTokenTemplate","disableTokenTemplate","_this29$getOwner","_this29$getTokenTempl","reactivateTokenTemplate","_this31$getOwner","_this31$getTokenTempl","startMultipleTokenOrder","orders","_this34","_this34$config","createNftWithDatatoken","nftCreateData","dtParams","ercCreateData","_this36","getErcCreationParams","createNftWithErc20","_this36$config","createNftWithDatatokenWithFixedRate","fixedData","getFreCreationParams","createNftWithErc20WithFixedRate","createNftWithDatatokenWithDispenser","Web3","createNftWithErc20WithDispenser","strings","addresses","uints","bytess","fixedPriceAddress","VeOcean","veOceanABI","lockTokens","userAddress","unlockTime","getToken","create_lock","depositFor","fromUserAddress","deposit_for","increaseAmount","increase_amount","increaseUnlockTime","increase_unlock_time","withdraw","getVotingPower","getLockedAmount","locked","lockEnd","locked__end","totalSupply","VeFeeDistributor","veFeeABI","claim","claimMany","claim_many","VeAllocate","veAllocateABI","setAllocation","setBatchAllocation","getTotalAllocation","getVeAllocation","getveAllocation","v","_settle","pact","state","bind","e","DfRewards","dfRewardsABI","getAvailableRewards","claimable","rewards","claimRewards","claimFor","allocateRewards","userAddresses","amounts","allocate","i","DfStrategyV1","dfStrategyV1ABI","getMultipleAvailableRewards","tokenAddresses","claimables","rewardsFormated","push","_push","claimMultipleRewards","claimMultiple","o","result","Aquarius","aquariusURL","did","signal","path","fetch","method","headers","response","ok","json","waitForAqua","txid","tries","ddo","event","validate","jsonResponse","valid","body","JSON","stringify","hash","proof","validatorAddress","publicKey","r","s","errors","getAssetMetadata","statusText","querySearch","query","Provider","getEndpoints","endpoints","getEndpointURL","servicesEndpoints","serviceName","getServiceEndpoints","providerEndpoint","serviceEndpoints","urlPath","getNonce","consumerAddress","providerEndpoints","nonce","signProviderRequest","accountId","password","consumerMessage","soliditySha3","t","utf8ToHex","currentProvider","isMetaMask","personal","sign","encrypt","text","checkDidFiles","serviceId","withChecksum","args","checksum","files","results","checkFileUrl","url","getComputeEnvironments","_this12$getEndpointUR","initialize","fileIndex","userCustomParameters","computeEnv","validUntil","initializeUrl","encodeURI","initializeCompute","assets","algorithm","providerData","datasets","compute","getDownloadUrl","transferTxId","downloadUrl","Date","now","signature","consumeUrl","computeStart","dataset","additionalDatasets","output","computeStartUrl","signatureMessage","documentId","payload","Object","environment","_error","params","computeStop","jobId","computeStopUrl","noZeroX","computeStatus","computeStatusUrl","getComputeResultUrl","computeResultUrl","resultUrl","computeDelete","computeDeleteUrl","isValidProvider","providerAddress","input","zeroXTransformer","zeroOutput","inputMatch","regexp","conversorName","match","ProviderInstance","web3Provider","datatokensABI","fixedRateExchangeAddressABI","dispenserABI","sideStakingAddress","verbose","authMessage","authTokenExpiration","parityUri","threshold","force","currentAllowence","gt","filename","get","split","pop","arrayBuffer","headResponse","fileName","xhr","XMLHttpRequest","responseType","open","onload","blobURL","window","URL","createObjectURL","a","document","createElement","href","setAttribute","appendChild","click","remove","revokeObjectURL","toChecksumAddress","sha256","signedMessage","substr","slice","recipient"],"mappings":"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"}