@oceanprotocol/lib 2.5.1 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/CodeExamples.md +2 -2
- package/ComputeExamples.md +703 -0
- package/README.md +2 -2
- package/dist/lib.js +1 -1
- package/dist/lib.js.map +1 -1
- package/dist/lib.modern.js +1 -1
- package/dist/lib.modern.js.map +1 -1
- package/dist/lib.module.js +1 -1
- package/dist/lib.module.js.map +1 -1
- package/dist/lib.umd.js +1 -1
- package/dist/lib.umd.js.map +1 -1
- package/dist/src/@types/Asset.d.ts +22 -0
- package/dist/src/@types/File.d.ts +14 -0
- package/dist/src/contracts/Datatoken.d.ts +10 -0
- package/dist/src/services/Provider.d.ts +6 -4
- package/dist/test/integration/ComputeExamples.test.d.ts +1 -0
- package/package.json +10 -8
package/dist/lib.modern.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lib.modern.js","sources":["../src/config/Config.ts","../src/utils/Constants.ts","../src/utils/ContractUtils.ts","../src/utils/Logger.ts","../src/utils/DatatokenName.ts","../src/utils/DdoHelpers.ts","../src/utils/FetchHelper.ts","../src/utils/General.ts","../src/utils/minAbi.ts","../src/utils/SignatureUtils.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/VeFeeEstimate.ts","../src/contracts/ve/VeAllocate.ts","../src/contracts/df/DfRewards.ts","../src/contracts/df/DfStrategyV1.ts","../src/services/Aquarius.ts","../src/services/Provider.ts"],"sourcesContent":["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, goerli, 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 veAllocate?: string\n veOCEAN?: string\n veDelegation?: string\n veFeeDistributor?: string\n veDelegationProxy?: string\n DFRewards?: string\n DFStrategyV1?: string\n veFeeEstimate?: string\n}\n","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","/* 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","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 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 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","/**\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 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","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 {Web3} web3\n * @param {Config} config\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 * @param {boolean} estimateGas if true, returns the estimate gas cost for calling the method\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 <ReceiptOrEstimate<G>>new Decimal(currentAllowence).toNumber()\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 {Web3} web3\n * @param {Config} config\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 {boolean} estimateGas if true, returns the estimate gas cost for calling the method\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 <ReceiptOrEstimate<G>>new Decimal(currentAllowence).toNumber()\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): 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: 5,\n network: 'goerli',\n nodeUri: 'https://goerli.infura.io/v3',\n providerUri: 'https://v4.provider.goerli.oceanprotocol.com',\n subgraphUri: 'https://v4.subgraph.goerli.oceanprotocol.com',\n explorerUri: 'https://goerli.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 gasFeeMultiplier: 1.6\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 veAllocate,\n veOCEAN,\n veDelegation,\n veFeeDistributor,\n veDelegationProxy,\n DFRewards,\n DFStrategyV1,\n veFeeEstimate\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 veAllocate,\n veOCEAN,\n veDelegation,\n veFeeDistributor,\n veDelegationProxy,\n DFRewards,\n DFStrategyV1,\n veFeeEstimate,\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 veAllocate,\n veOCEAN,\n veDelegation,\n veFeeDistributor,\n veDelegationProxy,\n DFRewards,\n DFStrategyV1,\n veFeeEstimate\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 veAllocate,\n veOCEAN,\n veDelegation,\n veFeeDistributor,\n veDelegationProxy,\n DFRewards,\n DFStrategyV1,\n veFeeEstimate,\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 veFeeEstimate from '@oceanprotocol/contracts/artifacts/contracts/ve/veFeeEstimate.vy/veFeeEstimate.json'\nimport { SmartContractWithAddress } from '../SmartContractWithAddress'\nimport { VeOcean } from './VeOcean'\n/**\n * Provides an interface for veOcean contract\n */\nexport class VeFeeEstimate extends SmartContractWithAddress {\n getDefaultAbi(): AbiItem | AbiItem[] {\n return veFeeEstimate.abi as AbiItem[]\n }\n\n /**\n * estimateClaim\n * @param {String} userAddress user address\n * @return {Promise<string>}\n */\n public async estimateClaim(userAddress: string): Promise<string> {\n const amount = await this.contract.methods.estimateClaim(userAddress).call()\n const veOcean = new VeOcean(\n await this.contract.methods.voting_escrow().call(),\n this.web3\n )\n const amountFormated = await this.unitsToAmount(await veOcean.getToken(), amount)\n return amountFormated\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 Arweave,\n FileInfo,\n ComputeJob,\n ComputeOutput,\n ComputeAlgorithm,\n ComputeAsset,\n ComputeEnvironment,\n ProviderInitialize,\n ProviderComputeInitializeResults,\n ServiceEndpoint,\n UrlFile,\n UserCustomParameters,\n Ipfs,\n Smartcontract,\n GraphqlQuery\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 getFileInfo(\n file: UrlFile | Arweave | Ipfs | GraphqlQuery | Smartcontract,\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 = file\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"],"names":["Config","nodeUri","providerAddress","metadataCacheUri","providerUri","web3Provider","oceanTokenAddress","nftFactoryAddress","datatokensABI","fixedRateExchangeAddress","fixedRateExchangeAddressABI","dispenserAddress","dispenserABI","opfCommunityFeeCollector","sideStakingAddress","startBlock","verbose","authMessage","authTokenExpiration","parityUri","threshold","chainId","network","subgraphUri","explorerUri","oceanTokenSymbol","transactionBlockTimeout","transactionConfirmationBlocks","transactionPollingTimeout","gasFeeMultiplier","veAllocate","veOCEAN","veDelegation","veFeeDistributor","veDelegationProxy","DFRewards","DFStrategyV1","veFeeEstimate","ZERO_ADDRESS","GASLIMIT_DEFAULT","MAX_UINT_256","FEE_HISTORY_NOT_SUPPORTED","setContractDefaults","contract","config","getFairGasPrice","web3","x","BigNumber","eth","getGasPrice","multipliedBy","integerValue","ROUND_DOWN","toString","unitsToAmount","token","amount","tokenDecimals","tokenContract","Contract","minAbi","decimals","methods","call","amountFormatted","div","exponentiatedBy","EXPONENTIAL_AT","amountToUnits","times","toFixed","calculateEstimatedGas","from","functionToEstimateGas","args","apply","estimateGas","err","estGas","sendTx","functionToSend","sendTxValue","gas","feeHistory","getFeeHistory","baseFeePerGas","_feeHistory$baseFeePe","reward","_feeHistory$reward","_feeHistory$reward$","aggressiveFee","_feeHistory$reward2","_feeHistory$reward2$","maxPriorityFeePerGas","maxFeePerGas","plus","_feeHistory$baseFeePe2","gasPrice","message","LoggerInstance","log","send","LogLevel","generateDtName","wordList","list","wordListDefault","random1","Math","floor","random","adjectives","length","random2","nouns","indexNumber","adjective","replace","c","toUpperCase","noun","name","symbol","substring","generateDid","nftAddress","Web3","utils","toChecksumAddress","sha256","getHash","data","downloadFileBrowser","url","fileName","fetch","method","headers","get","split","xhr","XMLHttpRequest","responseType","open","onload","blobURL","window","URL","createObjectURL","response","a","document","createElement","href","setAttribute","body","appendChild","click","remove","revokeObjectURL","downloadFile","index","ok","Error","filename","match","pop","arrayBuffer","sleep","ms","Promise","resolve","setTimeout","Logger","constructor","logLevel","this","setLevel","bypass","dispatch","Infinity","debug","Verbose","Log","warn","Warn","error","verb","level","console","constant","inputs","outputs","type","payable","stateMutability","anonymous","indexed","signHash","address","signedMessage","sign","substr","r","slice","s","v","approve","account","tokenAddress","spender","force","currentAllowence","allowance","Decimal","greaterThanOrEqualTo","toNumber","approveWei","allowanceWei","gt","result","e","transfer","recipient","trxReceipt","balance","balanceOf","configHelperNetworksBase","configHelperNetworks","ConfigHelper","getAddressesFromEnv","customAddresses","configAddresses","FixedPrice","Dispenser","ERC721Factory","OPFCommunityFeeCollector","Ocean","process","env","AQUARIUS_URI","DefaultContractsAddresses","getConfig","infuraProjectId","filterBy","find","SmartContract","abi","getDefaultAbi","async","_this$config","getContract","SmartContractWithAddress","super","DispenserAbi","dtAdress","status","maxTokens","fromWei","maxBalance","dtAddress","allowedSwapper","create","toWei","activate","_this$config2","deactivate","_this$config3","newAllowedSwapper","setAllowedSwapper","_this$config4","destination","dispense","_this$config5","ownerWithdraw","_this$config6","datatoken","active","String","greaterThan","isMinter","FixedRateExchange","FixedRateExchangeAbi","baseToken","generateExchangeId","exchangeId","datatokenAmount","maxBaseTokenAmount","consumeMarketAddress","consumeMarketFee","exchange","getExchange","consumeMarketFeeFormatted","dtAmountFormatted","dtDecimals","maxBtFormatted","btDecimals","buyDT","minBaseTokenAmount","minBtFormatted","sellDT","getNumberOfExchanges","newRate","setRate","toggleExchangeState","weiRate","getRate","dtSupply","getDTSupply","btSupply","getBTSupply","getAllowedSwapper","fixedRateExchange","outDT","calcBaseInGivenOutDT","baseTokenAmount","marketFeeAmount","oceanFeeAmount","consumeMarketFeeAmount","calcBaseOutGivenInDT","dtBalance","btBalance","fixedRate","feesInfo","getFeesInfo","opcFee","marketFee","marketFeeAvailable","oceanFeeAvailable","getExchanges","isActive","withMint","toggleMintState","_this$config7","_this$config8","fixedrate","amountWei","collectBT","_this$config9","collectDT","_this$config10","collectMarketFee","_this$config11","collectOceanFee","_this$config12","opcCollector","router","exchangeOwner","newMarketFee","updateMarketFee","_this$config13","newMarketFeeCollector","updateMarketFeeCollector","_this$config14","Router","FactoryRouter","operations","buyDTBatch","isApprovedToken","isFixedRateContract","routerOwner","factory","getOwner","addApprovedToken","removeApprovedToken","addFixedRateContract","removeFixedRateContract","addDispenserContract","removeDispenserContract","getOPCFee","swapOceanFee","newSwapOceanFee","newSwapNonOceanFee","newConsumeFee","newProviderFee","updateOPCFee","Nft","ERC721Template","minter","paymentCollector","mpFeeAddress","feeToken","feeAmount","cap","templateIndex","getNftPermissions","deployERC20","nftContract","createERC20","events","_trxReceipt$events","TokenCreated","_trxReceipt$events$To","returnValues","_trxReceipt$events$To2","manager","getNftOwner","addManager","removeManager","datatokenDeployer","addToCreateERC20List","removeFromCreateERC20List","metadataUpdater","addToMetadataList","updateMetadata","removeFromMetadataList","storeUpdater","addTo725StoreList","store","removeFrom725StoreList","cleanPermissions","nftOwner","nftReceiver","tokenId","tokenIdentifier","transferFrom","safeTransferFrom","metadataState","metadataDecryptorUrl","metadataDecryptorAddress","flags","metadataHash","metadataProofs","setMetaData","metadataAndTokenURI","sanitizedMetadataAndTokenURI","setMetaDataAndTokenURI","setMetaDataState","_this$config15","setTokenURI","_this$config16","ownerOf","getPermissions","getMetaData","isERC20Deployer","key","value","keyHash","keccak256","valueHex","asciiToHex","setNewData","_this$config17","getData","hexToAscii","id","tokenURI","Datatoken","ERC20Template","abiEnterprise","nft","ERC20TemplateEnterprise","dtContract","fixedRateParams","isDatatokenDeployer","allowedConsumer","createFixedRate","fixedRateAddress","baseTokenAddress","owner","marketFeeCollector","baseTokenDecimals","datatokenDecimals","dispenserParams","createDispenser","toAddress","capAvailble","getCap","gte","mint","addMinter","removeMinter","paymentManager","addPaymentManager","removePaymentManager","isPaymentManager","getNFTAddress","isNftOwner","nftPermissions","setPaymentCollector","getPaymentCollector","weiAmount","transferWei","consumer","serviceIndex","providerFees","consumeMarketFeeAddress","consumeMarketFeeToken","startOrder","orderTxId","reuseOrder","orderParams","freParams","freContractParams","getFreOrderParams","buyFromFreAndOrder","dispenserContract","buyFromDispenserAndOrder","setData","permissions","getERC721Address","datatokenAddress","publishMarketFeeAddress","publishMarketFeeToken","publishMarketFeeAmount","getPublishingMarketFee","setPublishingMarketFee","publishingMarketFee","exchangeContract","swapMarketFee","marketFeeAddress","NftFactory","nftData","getCurrentNFTTemplateCount","getNFTTemplate","deployERC721Contract","transferable","NFTCreated","_trxReceipt$events$NF","_trxReceipt$events$NF2","getCurrentNFTCount","getCurrentTokenCount","getCurrentTemplateCount","getTokenTemplate","erc20List","erc721List","templateAddress","add721TokenTemplate","disable721TokenTemplate","reactivate721TokenTemplate","addTokenTemplate","getCurrentTokenTemplateCount","disableTokenTemplate","reactivateTokenTemplate","orders","startMultipleTokenOrder","nftCreateData","dtParams","ercCreateData","getErcCreationParams","createNftWithErc20","fixedData","getFreCreationParams","createNftWithErc20WithFixedRate","createNftWithErc20WithDispenser","strings","addresses","uints","bytess","fixedPriceAddress","VeOcean","veOceanABI","userAddress","unlockTime","getToken","create_lock","fromUserAddress","deposit_for","increase_amount","increase_unlock_time","withdraw","locked","locked__end","totalSupply","VeFeeDistributor","veFeeABI","claim","claim_many","VeFeeEstimate","estimateClaim","veOcean","voting_escrow","VeAllocate","veAllocateABI","setAllocation","setBatchAllocation","getTotalAllocation","getveAllocation","DfRewards","dfRewardsABI","rewards","claimable","claimFor","userAddresses","amounts","i","allocate","DfStrategyV1","dfStrategyV1ABI","tokenAddresses","claimables","rewardsFormated","push","claimMultiple","Aquarius","aquariusURL","did","signal","path","json","txid","tries","ddo","event","valid","jsonResponse","JSON","stringify","hash","proof","validatorAddress","publicKey","errors","statusText","query","Provider","endpoints","getEndpointURL","servicesEndpoints","serviceName","providerEndpoint","serviceEndpoints","urlPath","consumerAddress","providerEndpoints","getEndpoints","getServiceEndpoints","nonce","accountId","password","consumerMessage","soliditySha3","t","utf8ToHex","currentProvider","isMetaMask","personal","text","serviceId","withChecksum","checksum","files","results","file","_this$getEndpointURL","fileIndex","userCustomParameters","computeEnv","validUntil","initializeUrl","encodeURI","assets","algorithm","providerData","datasets","compute","transferTxId","downloadUrl","Date","now","consumeUrl","signProviderRequest","dataset","additionalDatasets","output","computeStartUrl","signatureMessage","documentId","signature","payload","Object","environment","jobId","computeStopUrl","getNonce","noZeroX","computeStatusUrl","computeResultUrl","resultUrl","computeDeleteUrl","params","input","zeroXTransformer","zeroOutput","inputMatch","regexp","conversorName","ProviderInstance"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"lib.modern.js","sources":["../src/config/Config.ts","../src/utils/Constants.ts","../src/utils/ContractUtils.ts","../src/utils/Logger.ts","../src/utils/DatatokenName.ts","../src/utils/DdoHelpers.ts","../src/utils/FetchHelper.ts","../src/utils/General.ts","../src/utils/minAbi.ts","../src/utils/SignatureUtils.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/VeFeeEstimate.ts","../src/contracts/ve/VeAllocate.ts","../src/contracts/df/DfRewards.ts","../src/contracts/df/DfStrategyV1.ts","../src/services/Aquarius.ts","../src/services/Provider.ts"],"sourcesContent":["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, goerli, 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 veAllocate?: string\n veOCEAN?: string\n veDelegation?: string\n veFeeDistributor?: string\n veDelegationProxy?: string\n DFRewards?: string\n DFStrategyV1?: string\n veFeeEstimate?: string\n}\n","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","/* 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","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 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 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","/**\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 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","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 {Web3} web3\n * @param {Config} config\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 * @param {boolean} estimateGas if true, returns the estimate gas cost for calling the method\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 <ReceiptOrEstimate<G>>new Decimal(currentAllowence).toNumber()\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 {Web3} web3\n * @param {Config} config\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 {boolean} estimateGas if true, returns the estimate gas cost for calling the method\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 <ReceiptOrEstimate<G>>new Decimal(currentAllowence).toNumber()\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): 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://172.15.0.5:5000',\n providerUri: 'http://172.15.0.4:8030',\n subgraphUri: 'https://172.15.0.15:9000'\n },\n {\n ...configHelperNetworksBase,\n chainId: 5,\n network: 'goerli',\n nodeUri: 'https://goerli.infura.io/v3',\n providerUri: 'https://v4.provider.goerli.oceanprotocol.com',\n subgraphUri: 'https://v4.subgraph.goerli.oceanprotocol.com',\n explorerUri: 'https://goerli.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 gasFeeMultiplier: 1.6\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 veAllocate,\n veOCEAN,\n veDelegation,\n veFeeDistributor,\n veDelegationProxy,\n DFRewards,\n DFStrategyV1,\n veFeeEstimate\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 veAllocate,\n veOCEAN,\n veDelegation,\n veFeeDistributor,\n veDelegationProxy,\n DFRewards,\n DFStrategyV1,\n veFeeEstimate,\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 veAllocate,\n veOCEAN,\n veDelegation,\n veFeeDistributor,\n veDelegationProxy,\n DFRewards,\n DFStrategyV1,\n veFeeEstimate\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 veAllocate,\n veOCEAN,\n veDelegation,\n veFeeDistributor,\n veDelegationProxy,\n DFRewards,\n DFStrategyV1,\n veFeeEstimate,\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 symbol\n * @param {String} dtAddress Datatoken adress\n * @return {Promise<number>}\n */\n public async getSymbol(dtAddress: string): Promise<string> {\n const dtContract = this.getContract(dtAddress)\n const symbol = await dtContract.methods.symbol().call()\n return symbol\n }\n\n /** It returns the name of the token\n * @param {String} dtAddress Datatoken adress\n * @return {Promise<number>}\n */\n public async getName(dtAddress: string): Promise<string> {\n const dtContract = this.getContract(dtAddress)\n const name = await dtContract.methods.name().call()\n return name\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 veFeeEstimate from '@oceanprotocol/contracts/artifacts/contracts/ve/veFeeEstimate.vy/veFeeEstimate.json'\nimport { SmartContractWithAddress } from '../SmartContractWithAddress'\nimport { VeOcean } from './VeOcean'\n/**\n * Provides an interface for veOcean contract\n */\nexport class VeFeeEstimate extends SmartContractWithAddress {\n getDefaultAbi(): AbiItem | AbiItem[] {\n return veFeeEstimate.abi as AbiItem[]\n }\n\n /**\n * estimateClaim\n * @param {String} userAddress user address\n * @return {Promise<string>}\n */\n public async estimateClaim(userAddress: string): Promise<string> {\n const amount = await this.contract.methods.estimateClaim(userAddress).call()\n const veOcean = new VeOcean(\n await this.contract.methods.voting_escrow().call(),\n this.web3\n )\n const amountFormated = await this.unitsToAmount(await veOcean.getToken(), amount)\n return amountFormated\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 Arweave,\n FileInfo,\n ComputeJob,\n ComputeOutput,\n ComputeAlgorithm,\n ComputeAsset,\n ComputeEnvironment,\n ProviderInitialize,\n ProviderComputeInitializeResults,\n ServiceEndpoint,\n UrlFile,\n UserCustomParameters,\n Ipfs,\n Smartcontract,\n GraphqlQuery\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 {UrlFile | Arweave | Ipfs | GraphqlQuery | Smartcontract} file one of the supported file structures\n * @param {string} 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 {boolean} withChecksum if true, will return checksum of files content\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 {UrlFile | Arweave | Ipfs | GraphqlQuery | Smartcontract} file one of the supported file structures\n * @param {string} providerUri uri of the provider that will be used to check the file\n * @param {boolean} withChecksum if true, will return checksum of files content\n * @param {AbortSignal} signal abort signal\n * @return {Promise<FileInfo[]>} urlDetails\n */\n public async getFileInfo(\n file: UrlFile | Arweave | Ipfs | GraphqlQuery | Smartcontract,\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 = { ...file, 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 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"],"names":["Config","nodeUri","providerAddress","metadataCacheUri","providerUri","web3Provider","oceanTokenAddress","nftFactoryAddress","datatokensABI","fixedRateExchangeAddress","fixedRateExchangeAddressABI","dispenserAddress","dispenserABI","opfCommunityFeeCollector","sideStakingAddress","startBlock","verbose","authMessage","authTokenExpiration","parityUri","threshold","chainId","network","subgraphUri","explorerUri","oceanTokenSymbol","transactionBlockTimeout","transactionConfirmationBlocks","transactionPollingTimeout","gasFeeMultiplier","veAllocate","veOCEAN","veDelegation","veFeeDistributor","veDelegationProxy","DFRewards","DFStrategyV1","veFeeEstimate","ZERO_ADDRESS","GASLIMIT_DEFAULT","MAX_UINT_256","FEE_HISTORY_NOT_SUPPORTED","setContractDefaults","contract","config","getFairGasPrice","web3","x","BigNumber","eth","getGasPrice","multipliedBy","integerValue","ROUND_DOWN","toString","unitsToAmount","token","amount","tokenDecimals","tokenContract","Contract","minAbi","decimals","methods","call","amountFormatted","div","exponentiatedBy","EXPONENTIAL_AT","amountToUnits","times","toFixed","calculateEstimatedGas","from","functionToEstimateGas","args","apply","estimateGas","err","estGas","sendTx","functionToSend","sendTxValue","gas","feeHistory","getFeeHistory","baseFeePerGas","_feeHistory$baseFeePe","reward","_feeHistory$reward","_feeHistory$reward$","aggressiveFee","_feeHistory$reward2","_feeHistory$reward2$","maxPriorityFeePerGas","maxFeePerGas","plus","_feeHistory$baseFeePe2","gasPrice","message","LoggerInstance","log","send","LogLevel","generateDtName","wordList","list","wordListDefault","random1","Math","floor","random","adjectives","length","random2","nouns","indexNumber","adjective","replace","c","toUpperCase","noun","name","symbol","substring","generateDid","nftAddress","Web3","utils","toChecksumAddress","sha256","getHash","data","downloadFileBrowser","url","fileName","fetch","method","headers","get","split","xhr","XMLHttpRequest","responseType","open","onload","blobURL","window","URL","createObjectURL","response","a","document","createElement","href","setAttribute","body","appendChild","click","remove","revokeObjectURL","downloadFile","index","ok","Error","filename","match","pop","arrayBuffer","sleep","ms","Promise","resolve","setTimeout","Logger","constructor","logLevel","this","setLevel","bypass","dispatch","Infinity","debug","Verbose","Log","warn","Warn","error","verb","level","console","constant","inputs","outputs","type","payable","stateMutability","anonymous","indexed","signHash","address","signedMessage","sign","substr","r","slice","s","v","approve","account","tokenAddress","spender","force","currentAllowence","allowance","Decimal","greaterThanOrEqualTo","toNumber","approveWei","allowanceWei","gt","result","e","transfer","recipient","trxReceipt","balance","balanceOf","configHelperNetworksBase","configHelperNetworks","ConfigHelper","getAddressesFromEnv","customAddresses","configAddresses","FixedPrice","Dispenser","ERC721Factory","OPFCommunityFeeCollector","Ocean","process","env","AQUARIUS_URI","DefaultContractsAddresses","getConfig","infuraProjectId","filterBy","find","SmartContract","abi","getDefaultAbi","async","_this$config","getContract","SmartContractWithAddress","super","DispenserAbi","dtAdress","status","maxTokens","fromWei","maxBalance","dtAddress","allowedSwapper","create","toWei","activate","_this$config2","deactivate","_this$config3","newAllowedSwapper","setAllowedSwapper","_this$config4","destination","dispense","_this$config5","ownerWithdraw","_this$config6","datatoken","active","String","greaterThan","isMinter","FixedRateExchange","FixedRateExchangeAbi","baseToken","generateExchangeId","exchangeId","datatokenAmount","maxBaseTokenAmount","consumeMarketAddress","consumeMarketFee","exchange","getExchange","consumeMarketFeeFormatted","dtAmountFormatted","dtDecimals","maxBtFormatted","btDecimals","buyDT","minBaseTokenAmount","minBtFormatted","sellDT","getNumberOfExchanges","newRate","setRate","toggleExchangeState","weiRate","getRate","dtSupply","getDTSupply","btSupply","getBTSupply","getAllowedSwapper","fixedRateExchange","outDT","calcBaseInGivenOutDT","baseTokenAmount","marketFeeAmount","oceanFeeAmount","consumeMarketFeeAmount","calcBaseOutGivenInDT","dtBalance","btBalance","fixedRate","feesInfo","getFeesInfo","opcFee","marketFee","marketFeeAvailable","oceanFeeAvailable","getExchanges","isActive","withMint","toggleMintState","_this$config7","_this$config8","fixedrate","amountWei","collectBT","_this$config9","collectDT","_this$config10","collectMarketFee","_this$config11","collectOceanFee","_this$config12","opcCollector","router","exchangeOwner","newMarketFee","updateMarketFee","_this$config13","newMarketFeeCollector","updateMarketFeeCollector","_this$config14","Router","FactoryRouter","operations","buyDTBatch","isApprovedToken","isFixedRateContract","routerOwner","factory","getOwner","addApprovedToken","removeApprovedToken","addFixedRateContract","removeFixedRateContract","addDispenserContract","removeDispenserContract","getOPCFee","swapOceanFee","newSwapOceanFee","newSwapNonOceanFee","newConsumeFee","newProviderFee","updateOPCFee","Nft","ERC721Template","minter","paymentCollector","mpFeeAddress","feeToken","feeAmount","cap","templateIndex","getNftPermissions","deployERC20","nftContract","createERC20","events","_trxReceipt$events","TokenCreated","_trxReceipt$events$To","returnValues","_trxReceipt$events$To2","manager","getNftOwner","addManager","removeManager","datatokenDeployer","addToCreateERC20List","removeFromCreateERC20List","metadataUpdater","addToMetadataList","updateMetadata","removeFromMetadataList","storeUpdater","addTo725StoreList","store","removeFrom725StoreList","cleanPermissions","nftOwner","nftReceiver","tokenId","tokenIdentifier","transferFrom","safeTransferFrom","metadataState","metadataDecryptorUrl","metadataDecryptorAddress","flags","metadataHash","metadataProofs","setMetaData","metadataAndTokenURI","sanitizedMetadataAndTokenURI","setMetaDataAndTokenURI","setMetaDataState","_this$config15","setTokenURI","_this$config16","ownerOf","getPermissions","getMetaData","isERC20Deployer","key","value","keyHash","keccak256","valueHex","asciiToHex","setNewData","_this$config17","getData","hexToAscii","id","tokenURI","Datatoken","ERC20Template","abiEnterprise","nft","ERC20TemplateEnterprise","dtContract","fixedRateParams","isDatatokenDeployer","allowedConsumer","createFixedRate","fixedRateAddress","baseTokenAddress","owner","marketFeeCollector","baseTokenDecimals","datatokenDecimals","dispenserParams","createDispenser","toAddress","capAvailble","getCap","gte","mint","addMinter","removeMinter","paymentManager","addPaymentManager","removePaymentManager","isPaymentManager","getNFTAddress","isNftOwner","nftPermissions","setPaymentCollector","getPaymentCollector","weiAmount","transferWei","consumer","serviceIndex","providerFees","consumeMarketFeeAddress","consumeMarketFeeToken","startOrder","orderTxId","reuseOrder","orderParams","freParams","freContractParams","getFreOrderParams","buyFromFreAndOrder","dispenserContract","buyFromDispenserAndOrder","setData","permissions","getERC721Address","datatokenAddress","publishMarketFeeAddress","publishMarketFeeToken","publishMarketFeeAmount","getPublishingMarketFee","setPublishingMarketFee","publishingMarketFee","exchangeContract","swapMarketFee","marketFeeAddress","NftFactory","nftData","getCurrentNFTTemplateCount","getNFTTemplate","deployERC721Contract","transferable","NFTCreated","_trxReceipt$events$NF","_trxReceipt$events$NF2","getCurrentNFTCount","getCurrentTokenCount","getCurrentTemplateCount","getTokenTemplate","erc20List","erc721List","templateAddress","add721TokenTemplate","disable721TokenTemplate","reactivate721TokenTemplate","addTokenTemplate","getCurrentTokenTemplateCount","disableTokenTemplate","reactivateTokenTemplate","orders","startMultipleTokenOrder","nftCreateData","dtParams","ercCreateData","getErcCreationParams","createNftWithErc20","fixedData","getFreCreationParams","createNftWithErc20WithFixedRate","createNftWithErc20WithDispenser","strings","addresses","uints","bytess","fixedPriceAddress","VeOcean","veOceanABI","userAddress","unlockTime","getToken","create_lock","fromUserAddress","deposit_for","increase_amount","increase_unlock_time","withdraw","locked","locked__end","totalSupply","VeFeeDistributor","veFeeABI","claim","claim_many","VeFeeEstimate","estimateClaim","veOcean","voting_escrow","VeAllocate","veAllocateABI","setAllocation","setBatchAllocation","getTotalAllocation","getveAllocation","DfRewards","dfRewardsABI","rewards","claimable","claimFor","userAddresses","amounts","i","allocate","DfStrategyV1","dfStrategyV1ABI","tokenAddresses","claimables","rewardsFormated","push","claimMultiple","Aquarius","aquariusURL","did","signal","path","json","txid","tries","ddo","event","valid","jsonResponse","JSON","stringify","hash","proof","validatorAddress","publicKey","errors","statusText","query","Provider","endpoints","getEndpointURL","servicesEndpoints","serviceName","providerEndpoint","serviceEndpoints","urlPath","consumerAddress","providerEndpoints","getEndpoints","getServiceEndpoints","nonce","accountId","password","consumerMessage","soliditySha3","t","utf8ToHex","currentProvider","isMetaMask","personal","text","serviceId","withChecksum","checksum","files","results","file","_this$getEndpointURL","fileIndex","userCustomParameters","computeEnv","validUntil","initializeUrl","encodeURI","assets","algorithm","providerData","datasets","compute","transferTxId","downloadUrl","Date","now","consumeUrl","signProviderRequest","dataset","additionalDatasets","output","computeStartUrl","signatureMessage","documentId","signature","payload","Object","environment","jobId","computeStopUrl","getNonce","noZeroX","computeStatusUrl","computeResultUrl","resultUrl","computeDeleteUrl","params","input","zeroXTransformer","zeroOutput","inputMatch","regexp","conversorName","ProviderInstance"],"mappings":"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"}
|