diff --git a/.env.example b/.env.example index cdace996c..4cf175e40 100644 --- a/.env.example +++ b/.env.example @@ -16,3 +16,15 @@ # Privacy Preference Center #NEXT_PUBLIC_PRIVACY_PREFERENCE_CENTER="true" + +# Development Preference Center +#NEXT_PUBLIC_NFT_FACTORY_ADDRESS='0xxx' +#NEXT_PUBLIC_OPF_COMMUNITY_FEE_COLECTOR='0xxx' +#NEXT_PUBLIC_FIXED_RATE_EXCHANGE_ADDRESS='0xxx' +#NEXT_PUBLIC_DISPENSER_ADDRESS='0xxx' +#NEXT_PUBLIC_OCEAN_TOKEN_ADDRESS='0xxx' +#NEXT_PUBLIC_MARKET_DEVELOPMENT='true' +#NEXT_PUBLIC_PROVIDER_URL="http://xxx:xxx" +#NEXT_PUBLIC_SUBGRAPH_URI="http://xxx:xxx" +#NEXT_PUBLIC_METADATACACHE_URI="http://xxx:xxx" +#NEXT_PUBLIC_RPC_URI="http://xxx:xxx" \ No newline at end of file diff --git a/.jest/__fixtures__/datasetsWithAccessDetails.ts b/.jest/__fixtures__/datasetsWithAccessDetails.ts index 1891734e7..1ee287a98 100644 --- a/.jest/__fixtures__/datasetsWithAccessDetails.ts +++ b/.jest/__fixtures__/datasetsWithAccessDetails.ts @@ -157,9 +157,9 @@ export const assets: AssetExtended[] = [ allocated: 45554.69921875, orders: 1, price: { - value: 3231343254, - tokenAddress: '0xCfDdA22C9837aE76E0faA845354f33C62E03653a', - tokenSymbol: 'OCEAN' + tokenAddress: '0x282d8efCe846A88B159800bd4130ad77443Fa1A1', + tokenSymbol: 'mOCEAN', + value: 100 } }, version: '4.1.0', @@ -1113,9 +1113,7 @@ export const assets: AssetExtended[] = [ allocated: 11159.279296875, orders: 1, price: { - value: 3231343254, - tokenAddress: '0xCfDdA22C9837aE76E0faA845354f33C62E03653a', - tokenSymbol: 'OCEAN' + value: 0 } }, version: '4.1.0', @@ -1198,9 +1196,7 @@ export const assets: AssetExtended[] = [ stats: { orders: 0, price: { - value: 3231343254, - tokenAddress: '0xCfDdA22C9837aE76E0faA845354f33C62E03653a', - tokenSymbol: 'OCEAN' + value: 0 } }, version: '4.1.0', @@ -1448,9 +1444,7 @@ export const assets: AssetExtended[] = [ stats: { orders: 0, price: { - value: 3231343254, - tokenAddress: '0xCfDdA22C9837aE76E0faA845354f33C62E03653a', - tokenSymbol: 'OCEAN' + value: 0 } }, version: '4.1.0', diff --git a/README.md b/README.md index 5bbe2577c..eb821b6cb 100644 --- a/README.md +++ b/README.md @@ -65,34 +65,30 @@ This will start the development server under ### Local components with Barge -If you prefer to connect to locally running components instead of remote connections, you can spin up [`barge`](https://github.com/oceanprotocol/barge) and use a local Ganache network in another terminal before running `npm start`: +Using the `ocean-market` with `barge` components is recommended for advanced users, if you are new we advice you to use the `ocean-market` first with remote networks. If you prefer to connect to locally running components instead of remote connections, you can spin up [`barge`](https://github.com/oceanprotocol/barge) and use a local Ganache network in another terminal before running `npm start`. To fully test all [The Graph](https://thegraph.com) integrations, you have to start barge with the local Graph node: ```bash git clone git@github.com:oceanprotocol/barge.git cd barge -# startup with local Ganache node -./start_ocean.sh +# startup with local Ganache and Graph nodes +./start_ocean.sh --with-thegraph ``` -Barge will deploy contracts to the local Ganache node which will take some time. At the end the compiled artifacts need to be copied over to this project into `node_modules/@oceanprotocol/contracts/artifacts`. This script will do that for you: +Barge will deploy contracts to the local Ganache node which will take some time. At the end the compiled artifacts need to imported over to this project as environment variables. The `set-barge-env` script will do that for you and set the env variables to use this local connection in `.env` in the app. You also need to append the `chainIdsSupported` array with the barge's ganache chainId (`8996`) in the `app.config.js` file. -```bash -./scripts/copy-contracts.sh -``` +If you are using `macOS` operating system you should also make same changes to the provider url since the default barge ip can not be accessed due to some network constraints on `macOs`. So we should be using the `127.0.0.1:8030` (if you have changed the provider port please use that here as well) for each direct call from the market to provider, but we should keep the internal barge url `http://172.15.0.4:8030/` (this is the default ip:port for provider in barge, if changed please use the according url). So on inside `src/@utils/provider.ts` if on `macOS` you can hardcode this env variable `NEXT_PUBLIC_PROVIDER_URL` or set +`127.0.0.1:8030` as `providerUrl` on all the methods that call `ProviderInstance` methods. (eg: `getEncryptedFiles`, `getFileDidInfo`, `downloadFile` etc). You should use the same provider url for `src/@utils/nft.ts` inside `setNFTMetadataAndTokenURI` and `setNftMetadata` and `src/components/Publish/index.tsx` inisde `encrypt` method (if you set the env variable there's no need to do this). You also need to use local ip's for the subgraph (`127.0.0.1` instead of `172.15.0.15`) and the metadatacache (`127.0.0.1` instead of `172.15.0.5`). -Finally, set environment variables to use this local connection in `.env` in the app: +Once you want to switch back to using the market agains remote networks you need to comment or remove the env vars that are set by `set-barge-env` script. ```bash -# modify env variables -cp .env.example .env - +cd market +npm run set-barge-env npm start ``` -To use the app together with MetaMask, importing one of the accounts auto-generated by the Ganache container is the easiest way to have test ETH available. All of them have 100 ETH by default. Upon start, the `ocean_ganache_1` container will print out the private keys of multiple accounts in its logs. Pick one of them and import into MetaMask. - -To fully test all [The Graph](https://thegraph.com) integrations, you have to run your own local Graph node with our [`ocean-subgraph`](https://github.com/oceanprotocol/ocean-subgraph) deployed to it. Barge does not include a local subgraph so by default, the `subgraphUri` is hardcoded to the Goerli subgraph in our [`getDevelopmentConfig` function](https://github.com/oceanprotocol/market/blob/d0b1534d105e5dcb3790c65d4bb04ff1d2dbc575/src/utils/ocean.ts#L31). +To use the app together with MetaMask, importing one of the accounts auto-generated by the Ganache container is the easiest way to have test ETH available. All of them have 100 ETH by default. Upon start, the `ocean_ganache_1` container will print out the private keys of multiple accounts in its logs. Pick one of them and import into MetaMask. Barge private key example : `0xc594c6e5def4bab63ac29eed19a134c130388f74f019bc74b8f4389df2837a58` > Cleaning all Docker images so they are fetched freshly is often a good idea to make sure no issues are caused by old or stale images: `docker system prune --all --volumes` diff --git a/app.config.js b/app.config.js index 5accda37f..42f2a6134 100644 --- a/app.config.js +++ b/app.config.js @@ -23,6 +23,10 @@ module.exports = { // List of all supported chainIds. Used to populate the Chains user preferences list. chainIdsSupported: [100, 80001], + customProviderUrl: process.env.NEXT_PUBLIC_PROVIDER_URL, + + infuraProjectId: process.env.NEXT_PUBLIC_INFURA_PROJECT_ID || 'xxx', + defaultDatatokenTemplateIndex: 2, // The ETH address the marketplace fee will be sent to. marketFeeAddress: diff --git a/package-lock.json b/package-lock.json index 829ab3410..180b6d1e9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "@coingecko/cryptoformat": "^0.5.4", "@loadable/component": "^5.15.3", "@oceanprotocol/art": "^3.2.0", - "@oceanprotocol/lib": "^3.0.2", + "@oceanprotocol/lib": "^3.0.4", "@oceanprotocol/typographies": "^0.1.0", "@oceanprotocol/use-dark-mode": "^2.4.3", "@tippyjs/react": "^4.2.6", @@ -29,7 +29,7 @@ "dom-confetti": "^0.2.2", "ethers": "^5.7.2", "filesize": "^10.0.7", - "formik": "^2.2.9", + "formik": "^2.4.2", "gray-matter": "^4.0.3", "is-ipfs": "^8.0.1", "is-url-superb": "^6.1.0", @@ -103,7 +103,7 @@ "process": "^0.11.10", "serve": "^14.1.2", "stream-http": "^3.2.0", - "tsconfig-paths-webpack-plugin": "^4.0.1", + "tsconfig-paths-webpack-plugin": "^4.1.0", "typescript": "^4.9.3" }, "engines": { @@ -5447,9 +5447,9 @@ "integrity": "sha512-PJih7C6LHaWHHj1qgxZsSkEqKphhJrL3G7WuMOxl4N1daDrF6sooDDU+9dZkcHSVPc7cMjkFqLc5fP58NSAobw==" }, "node_modules/@oceanprotocol/lib": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-3.0.2.tgz", - "integrity": "sha512-yp75eYcFzqqgUAzG+fkLXHrNaA/ZZvogEE25NOy2DI5EAUp1Wm6tZ0q6AIH0i05KCPOfXoIGwqTBlfQa0rh48A==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-3.0.4.tgz", + "integrity": "sha512-HG187KtiT6LV8N5RbupcdKMR+6qsYLEmf43H5gnrIjDflachSayc1R629M7FPC29M8RMgqhfCwKLJJN64U+pmw==", "dependencies": { "@oceanprotocol/contracts": "^1.1.14", "cross-fetch": "^3.1.5", @@ -29715,9 +29715,9 @@ "peer": true }, "node_modules/formik": { - "version": "2.2.9", - "resolved": "https://registry.npmjs.org/formik/-/formik-2.2.9.tgz", - "integrity": "sha512-LQLcISMmf1r5at4/gyJigGn0gOwFbeEAlji+N9InZF6LIMXnFNkO42sCI8Jt84YZggpD4cPWObAZaxpEFtSzNA==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/formik/-/formik-2.4.2.tgz", + "integrity": "sha512-C6nx0hifW2uENP3M6HpPmnAE6HFWCcd8/sqBZEOHZY6lpHJ5qehsfAy43ktpFLEmkBmhiZDei726utcUB9leqg==", "funding": [ { "type": "individual", @@ -29731,7 +29731,7 @@ "lodash-es": "^4.17.21", "react-fast-compare": "^2.0.1", "tiny-warning": "^1.0.2", - "tslib": "^1.10.0" + "tslib": "^2.0.0" }, "peerDependencies": { "react": ">=16.8.0" @@ -29745,11 +29745,6 @@ "node": ">=0.10.0" } }, - "node_modules/formik/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -50383,9 +50378,9 @@ } }, "node_modules/tsconfig-paths-webpack-plugin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.0.1.tgz", - "integrity": "sha512-m5//KzLoKmqu2MVix+dgLKq70MnFi8YL8sdzQZ6DblmCdfuq/y3OqvJd5vMndg2KEVCOeNz8Es4WVZhYInteLw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.1.0.tgz", + "integrity": "sha512-xWFISjviPydmtmgeUAuXp4N1fky+VCtfhOkDUFIv5ea7p4wuTomI4QTrXvFBX2S4jZsmyTSrStQl+E+4w+RzxA==", "dev": true, "dependencies": { "chalk": "^4.1.0", @@ -52600,9 +52595,9 @@ "integrity": "sha512-VgiMCz7BXOiDbgpVhf5iNhK7hurteY5Jv0fDJewUkY0s4fbxQD2iKqfGxNXNTwp2v3bgT8QVu2l5H7YdkZ5WIA==" }, "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", + "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", "dev": true, "engines": { "node": ">=0.10.0" @@ -56762,9 +56757,9 @@ "integrity": "sha512-PJih7C6LHaWHHj1qgxZsSkEqKphhJrL3G7WuMOxl4N1daDrF6sooDDU+9dZkcHSVPc7cMjkFqLc5fP58NSAobw==" }, "@oceanprotocol/lib": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-3.0.2.tgz", - "integrity": "sha512-yp75eYcFzqqgUAzG+fkLXHrNaA/ZZvogEE25NOy2DI5EAUp1Wm6tZ0q6AIH0i05KCPOfXoIGwqTBlfQa0rh48A==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-3.0.4.tgz", + "integrity": "sha512-HG187KtiT6LV8N5RbupcdKMR+6qsYLEmf43H5gnrIjDflachSayc1R629M7FPC29M8RMgqhfCwKLJJN64U+pmw==", "requires": { "@oceanprotocol/contracts": "^1.1.14", "cross-fetch": "^3.1.5", @@ -75840,9 +75835,9 @@ "peer": true }, "formik": { - "version": "2.2.9", - "resolved": "https://registry.npmjs.org/formik/-/formik-2.2.9.tgz", - "integrity": "sha512-LQLcISMmf1r5at4/gyJigGn0gOwFbeEAlji+N9InZF6LIMXnFNkO42sCI8Jt84YZggpD4cPWObAZaxpEFtSzNA==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/formik/-/formik-2.4.2.tgz", + "integrity": "sha512-C6nx0hifW2uENP3M6HpPmnAE6HFWCcd8/sqBZEOHZY6lpHJ5qehsfAy43ktpFLEmkBmhiZDei726utcUB9leqg==", "requires": { "deepmerge": "^2.1.1", "hoist-non-react-statics": "^3.3.0", @@ -75850,18 +75845,13 @@ "lodash-es": "^4.17.21", "react-fast-compare": "^2.0.1", "tiny-warning": "^1.0.2", - "tslib": "^1.10.0" + "tslib": "^2.0.0" }, "dependencies": { "deepmerge": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==" - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" } } }, @@ -91322,9 +91312,9 @@ } }, "tsconfig-paths-webpack-plugin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.0.1.tgz", - "integrity": "sha512-m5//KzLoKmqu2MVix+dgLKq70MnFi8YL8sdzQZ6DblmCdfuq/y3OqvJd5vMndg2KEVCOeNz8Es4WVZhYInteLw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.1.0.tgz", + "integrity": "sha512-xWFISjviPydmtmgeUAuXp4N1fky+VCtfhOkDUFIv5ea7p4wuTomI4QTrXvFBX2S4jZsmyTSrStQl+E+4w+RzxA==", "dev": true, "requires": { "chalk": "^4.1.0", @@ -93067,9 +93057,9 @@ "integrity": "sha512-VgiMCz7BXOiDbgpVhf5iNhK7hurteY5Jv0fDJewUkY0s4fbxQD2iKqfGxNXNTwp2v3bgT8QVu2l5H7YdkZ5WIA==" }, "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", + "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", "dev": true }, "wordwrap": { diff --git a/package.json b/package.json index 0c1002bd4..257f2ffa0 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "build:static": "npm run build && next export", "serve": "serve -s public/", "pregenerate": "bash scripts/pregenerate.sh", + "set-barge-env": "bash scripts/barge-env.sh", "test": "npm run pregenerate && npm run lint && npm run type-check && npm run jest", "jest": "jest -c .jest/jest.config.js", "jest:watch": "jest -c .jest/jest.config.js --watch", @@ -30,7 +31,7 @@ "@coingecko/cryptoformat": "^0.5.4", "@loadable/component": "^5.15.3", "@oceanprotocol/art": "^3.2.0", - "@oceanprotocol/lib": "^3.0.2", + "@oceanprotocol/lib": "^3.0.4", "@oceanprotocol/typographies": "^0.1.0", "@oceanprotocol/use-dark-mode": "^2.4.3", "@tippyjs/react": "^4.2.6", @@ -44,7 +45,7 @@ "dom-confetti": "^0.2.2", "ethers": "^5.7.2", "filesize": "^10.0.7", - "formik": "^2.2.9", + "formik": "^2.4.2", "gray-matter": "^4.0.3", "is-ipfs": "^8.0.1", "is-url-superb": "^6.1.0", @@ -118,7 +119,7 @@ "process": "^0.11.10", "serve": "^14.1.2", "stream-http": "^3.2.0", - "tsconfig-paths-webpack-plugin": "^4.0.1", + "tsconfig-paths-webpack-plugin": "^4.1.0", "typescript": "^4.9.3" }, "overrides": { diff --git a/scripts/barge-env.sh b/scripts/barge-env.sh new file mode 100644 index 000000000..3dfdd23e5 --- /dev/null +++ b/scripts/barge-env.sh @@ -0,0 +1,2 @@ +# Set +node ./scripts/load-development-addresses.js \ No newline at end of file diff --git a/scripts/load-development-addresses.js b/scripts/load-development-addresses.js new file mode 100644 index 000000000..d7bd883a4 --- /dev/null +++ b/scripts/load-development-addresses.js @@ -0,0 +1,76 @@ +const fs = require('fs') +const os = require('os') + +function getLocalAddresses() { + const data = JSON.parse( + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.readFileSync( + `${os.homedir}/.ocean/ocean-contracts/artifacts/address.json`, + 'utf8' + ) + ) + return data.development +} + +function updateEnvVariable(key, value) { + fs.readFile('.env', 'utf8', (err, data) => { + if (err) { + console.error(err) + return + } + + const lines = data.split('\n') + + let keyExists = false + for (let i = 0; i < lines.length; i++) { + const line = lines[i] + if (line.startsWith(key + '=')) { + lines[i] = `${key}=${value}` + keyExists = true + break + } + } + + if (!keyExists) { + lines.push(`${key}=${value}`) + } + + const updatedContent = lines.join('\n') + fs.writeFile('.env', updatedContent, 'utf8', (err) => { + if (err) { + console.error(err) + return + } + console.log( + `Successfully ${ + keyExists ? 'updated' : 'added' + } the ${key} environment variable.` + ) + }) + }) +} + +const addresses = getLocalAddresses() +updateEnvVariable('NEXT_PUBLIC_NFT_FACTORY_ADDRESS', addresses.ERC721Factory) +updateEnvVariable( + 'NEXT_PUBLIC_OPF_COMMUNITY_FEE_COLECTOR', + addresses.OPFCommunityFeeCollector +) +updateEnvVariable( + 'NEXT_PUBLIC_FIXED_RATE_EXCHANGE_ADDRESS', + addresses.FixedPrice +) +updateEnvVariable('NEXT_PUBLIC_DISPENSER_ADDRESS', addresses.Dispenser) +updateEnvVariable('NEXT_PUBLIC_OCEAN_TOKEN_ADDRESS', addresses.Ocean) +updateEnvVariable('NEXT_PUBLIC_MARKET_DEVELOPMENT', true) +updateEnvVariable( + '#NEXT_PUBLIC_PROVIDER_URL', + '"http://127.0.0.1:8030" # only for mac' +) +updateEnvVariable( + `#NEXT_PUBLIC_SUBGRAPH_URI',"http://127.0.0.1:9000" # only for mac` +) +updateEnvVariable( + '#NEXT_PUBLIC_METADATACACHE_URI', + '"http://127.0.0.1:5000" # only for mac' +) diff --git a/scripts/write-networks-metadata.js b/scripts/write-networks-metadata.js index 5f5cd1aca..4401f737d 100644 --- a/scripts/write-networks-metadata.js +++ b/scripts/write-networks-metadata.js @@ -1,6 +1,26 @@ #!/usr/bin/env node 'use strict' +const bargeNetwork = { + name: 'Ethereum Barge', + chain: 'ETH', + icon: 'ethereum', + rpc: ['http://127.0.0.1:8545'], + faucets: [], + nativeCurrency: { + name: 'Ether', + symbol: 'ETH', + decimals: 18 + }, + infoURL: 'https://ethereum.org', + shortName: 'eth', + chainId: 8996, + networkId: 8996, + slip44: 60, + ens: {}, + explorers: [] +} + const axios = require('axios') const { networksMetadata } = require('../networksMetadata.config') const { GEN_X_NETWORK_ID } = require('../chains.config') @@ -9,6 +29,9 @@ const { GEN_X_NETWORK_ID } = require('../chains.config') const chainDataUrl = 'https://chainid.network/chains.json' axios(chainDataUrl).then((response) => { + response.data.push(bargeNetwork) + // const networks ={...response.data, ...bargeNetwork} + // avoid having 2 nodes with the same chainId const filteredData = response.data.filter( (node) => node.chainId !== GEN_X_NETWORK_ID diff --git a/src/@context/Asset.tsx b/src/@context/Asset.tsx index cb803bacc..509599ccf 100644 --- a/src/@context/Asset.tsx +++ b/src/@context/Asset.tsx @@ -11,7 +11,7 @@ import { Config, LoggerInstance, Purgatory } from '@oceanprotocol/lib' import { CancelToken } from 'axios' import { getAsset } from '@utils/aquarius' import { useCancelToken } from '@hooks/useCancelToken' -import { getOceanConfig, getDevelopmentConfig } from '@utils/ocean' +import { getOceanConfig, sanitizeDevelopmentConfig } from '@utils/ocean' import { getAccessDetails } from '@utils/accessDetailsAndPricing' import { useIsMounted } from '@hooks/useIsMounted' import { useMarketMetadata } from './MarketMetadata' @@ -248,13 +248,13 @@ function AssetProvider({ // ----------------------------------- useEffect(() => { if (!asset?.chainId) return - + const config = getOceanConfig(asset?.chainId) const oceanConfig = { - ...getOceanConfig(asset?.chainId), + ...config, // add local dev values ...(asset?.chainId === 8996 && { - ...getDevelopmentConfig() + ...sanitizeDevelopmentConfig(config) }) } setOceanConfig(oceanConfig) diff --git a/src/@context/MarketMetadata/index.tsx b/src/@context/MarketMetadata/index.tsx index e7d7d0441..1623d3fa3 100644 --- a/src/@context/MarketMetadata/index.tsx +++ b/src/@context/MarketMetadata/index.tsx @@ -43,14 +43,13 @@ function MarketMetadataProvider({ null, getQueryContext(appConfig.chainIdsSupported[i]) ) - opcData.push({ chainId: appConfig.chainIdsSupported[i], - approvedTokens: response.data?.opc.approvedTokens.map( + approvedTokens: response.data?.opc?.approvedTokens?.map( (token) => token.address ), - swapApprovedFee: response.data?.opc.swapOceanFee, - swapNotApprovedFee: response.data?.opc.swapNonOceanFee + swapApprovedFee: response.data?.opc?.swapOceanFee, + swapNotApprovedFee: response.data?.opc?.swapNonOceanFee } as OpcFee) } LoggerInstance.log('[MarketMetadata] Got new data.', { diff --git a/src/@utils/accessDetailsAndPricing.ts b/src/@utils/accessDetailsAndPricing.ts index 5dd685144..1360bcf60 100644 --- a/src/@utils/accessDetailsAndPricing.ts +++ b/src/@utils/accessDetailsAndPricing.ts @@ -14,7 +14,8 @@ import { getFixedBuyPrice } from './ocean/fixedRateExchange' import Decimal from 'decimal.js' import { consumeMarketOrderFee, - publisherMarketOrderFee + publisherMarketOrderFee, + customProviderUrl } from '../../app.config' import { Signer } from 'ethers' import { toast } from 'react-toastify' @@ -186,7 +187,7 @@ export async function getOrderPriceAndFees( asset?.services[0].id, 0, accountId, - asset?.services[0].serviceEndpoint + customProviderUrl || asset?.services[0].serviceEndpoint )) } catch (error) { const message = getErrorMessage(JSON.parse(error.message)) diff --git a/src/@utils/nft.ts b/src/@utils/nft.ts index 187eca4ae..4ee6fbd19 100644 --- a/src/@utils/nft.ts +++ b/src/@utils/nft.ts @@ -10,6 +10,7 @@ import { getErrorMessage } from '@oceanprotocol/lib' import { SvgWaves } from './SvgWaves' +import { customProviderUrl } from '../../app.config' import { Signer, ethers } from 'ethers' import { toast } from 'react-toastify' @@ -112,7 +113,7 @@ export async function setNftMetadata( encryptedDdo = await ProviderInstance.encrypt( asset, asset.chainId, - asset.services[0].serviceEndpoint, + customProviderUrl || asset.services[0].serviceEndpoint, signal ) } catch (err) { @@ -154,7 +155,7 @@ export async function setNFTMetadataAndTokenURI( encryptedDdo = await ProviderInstance.encrypt( asset, asset.chainId, - asset.services[0].serviceEndpoint, + customProviderUrl || asset.services[0].serviceEndpoint, signal ) } catch (err) { diff --git a/src/@utils/ocean/index.ts b/src/@utils/ocean/index.ts index 22dd50580..69e4360ef 100644 --- a/src/@utils/ocean/index.ts +++ b/src/@utils/ocean/index.ts @@ -1,16 +1,37 @@ import { ConfigHelper, Config } from '@oceanprotocol/lib' import { chains } from '../../../chains.config' import { ethers } from 'ethers' - import abiDatatoken from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20TemplateEnterprise.sol/ERC20TemplateEnterprise.json' +/** + This function takes a Config object as an input and returns a new sanitized Config object + The new Config object has the same properties as the input object, but with some values replaced by environment variables if they exist + Also adds missing contract addresses deployed when running barge locally + @param {Config} config - The input Config object + @returns {Config} A new Config object +*/ +export function sanitizeDevelopmentConfig(config: Config): Config { + return { + subgraphUri: process.env.NEXT_PUBLIC_SUBGRAPH_URI || config.subgraphUri, + metadataCacheUri: + process.env.NEXT_PUBLIC_METADATACACHE_URI || config.metadataCacheUri, + providerUri: process.env.NEXT_PUBLIC_PROVIDER_URL || config.providerUri, + nodeUri: process.env.NEXT_PUBLIC_RPC_URL || config.nodeUri, + fixedRateExchangeAddress: + process.env.NEXT_PUBLIC_FIXED_RATE_EXCHANGE_ADDRESS, + dispenserAddress: process.env.NEXT_PUBLIC_DISPENSER_ADDRESS, + oceanTokenAddress: process.env.NEXT_PUBLIC_OCEAN_TOKEN_ADDRESS, + nftFactoryAddress: process.env.NEXT_PUBLIC_NFT_FACTORY_ADDRESS + } as Config +} + export function getOceanConfig(network: string | number): Config { const filterBy = typeof network === 'string' ? 'network' : 'chainId' const customConfig = chains.find((c) => c[filterBy] === network) if (network === 100) return customConfig as Config - const config = new ConfigHelper().getConfig( + let config = new ConfigHelper().getConfig( network, network === 'polygon' || network === 'moonbeamalpha' || @@ -18,10 +39,14 @@ export function getOceanConfig(network: string | number): Config { network === 'bsc' || network === 56 || network === 'gaiaxtestnet' || - network === 2021000 + network === 2021000 || + network === 8996 ? undefined : process.env.NEXT_PUBLIC_INFURA_PROJECT_ID ) as Config + if (network === 8996) { + config = { ...config, ...sanitizeDevelopmentConfig(config) } + } return customConfig ? ({ ...config, ...customConfig } as Config) diff --git a/src/@utils/order.ts b/src/@utils/order.ts index b9966af1a..8a8cdcc4b 100644 --- a/src/@utils/order.ts +++ b/src/@utils/order.ts @@ -19,7 +19,8 @@ import { getOceanConfig } from './ocean' import { marketFeeAddress, consumeMarketOrderFee, - consumeMarketFixedSwapFee + consumeMarketFixedSwapFee, + customProviderUrl } from '../../app.config' import { toast } from 'react-toastify' @@ -35,7 +36,7 @@ async function initializeProvider( asset.services[0].id, 0, accountId, - asset.services[0].serviceEndpoint + customProviderUrl || asset.services[0].serviceEndpoint ) return provider } catch (error) { @@ -136,7 +137,7 @@ export async function order( orderParams._consumeMarketFee ) } - if (asset.accessDetails.templateId === 2) { + if (asset.accessDetails?.templateId === 2) { const tx: any = await approve( signer, config, @@ -175,7 +176,7 @@ export async function order( orderParams._consumeMarketFee ) } - if (asset.accessDetails.templateId === 2) { + if (asset.accessDetails?.templateId === 2) { return await datatoken.buyFromDispenserAndOrder( asset.services[0].datatokenAddress, orderParams, diff --git a/src/@utils/provider.ts b/src/@utils/provider.ts index c5ea7cbf1..888a7719e 100644 --- a/src/@utils/provider.ts +++ b/src/@utils/provider.ts @@ -15,6 +15,8 @@ import { AbiItem, getErrorMessage } from '@oceanprotocol/lib' +// if customProviderUrl is set, we need to call provider using this custom endpoint +import { customProviderUrl } from '../../app.config' import { QueryHeader } from '@shared/FormInput/InputElement/Headers' import { Signer } from 'ethers' import { getValidUntilTime } from './compute' @@ -50,7 +52,7 @@ export async function initializeProviderForCompute( computeAlgo, computeEnv?.id, validUntil, - dataset.services[0].serviceEndpoint, + customProviderUrl || dataset.services[0].serviceEndpoint, accountId ) } catch (error) { @@ -69,7 +71,11 @@ export async function getEncryptedFiles( ): Promise { try { // https://github.com/oceanprotocol/provider/blob/v4main/API.md#encrypt-endpoint - const response = await ProviderInstance.encrypt(files, chainId, providerUrl) + const response = await ProviderInstance.encrypt( + files, + chainId, + customProviderUrl || providerUrl + ) return response } catch (error) { const message = getErrorMessage(JSON.parse(error.message)) @@ -88,7 +94,7 @@ export async function getFileDidInfo( const response = await ProviderInstance.checkDidFiles( did, serviceId, - providerUrl, + customProviderUrl || providerUrl, withChecksum ) return response @@ -128,7 +134,7 @@ export async function getFileInfo( try { response = await ProviderInstance.getFileInfo( fileIPFS, - providerUrl, + customProviderUrl || providerUrl, withChecksum ) } catch (error) { @@ -146,7 +152,7 @@ export async function getFileInfo( try { response = await ProviderInstance.getFileInfo( fileArweave, - providerUrl, + customProviderUrl || providerUrl, withChecksum ) } catch (error) { @@ -164,7 +170,10 @@ export async function getFileInfo( query } try { - response = await ProviderInstance.getFileInfo(fileGraphql, providerUrl) + response = await ProviderInstance.getFileInfo( + fileGraphql, + customProviderUrl || providerUrl + ) } catch (error) { const message = getErrorMessage(JSON.parse(error.message)) LoggerInstance.error('[Provider Get File info] Error:', message) @@ -183,7 +192,7 @@ export async function getFileInfo( try { response = await ProviderInstance.getFileInfo( fileSmartContract, - providerUrl + customProviderUrl || providerUrl ) } catch (error) { const message = getErrorMessage(JSON.parse(error.message)) @@ -203,7 +212,7 @@ export async function getFileInfo( try { response = await ProviderInstance.getFileInfo( fileUrl, - providerUrl, + customProviderUrl || providerUrl, withChecksum ) } catch (error) { @@ -230,7 +239,7 @@ export async function downloadFile( asset.services[0].id, 0, validOrderTx || asset.accessDetails.validOrderTx, - asset.services[0].serviceEndpoint, + customProviderUrl || asset.services[0].serviceEndpoint, signer ) } catch (error) { diff --git a/src/components/@shared/atoms/Tags/index.tsx b/src/components/@shared/atoms/Tags/index.tsx index 38c6ed108..ce8e1126b 100644 --- a/src/components/@shared/atoms/Tags/index.tsx +++ b/src/components/@shared/atoms/Tags/index.tsx @@ -38,7 +38,7 @@ export default function Tags({ max = max || items.length const remainder = items.length - max // filter out empty array items, and restrict to `max` - const tags = items.filter((tag) => tag !== '').slice(0, max) + const tags = items?.filter((tag) => tag !== '').slice(0, max) const shouldShowMore = showMore && remainder > 0 const classes = className ? `${styles.tags} ${className}` : styles.tags diff --git a/src/components/Publish/_utils.ts b/src/components/Publish/_utils.ts index 5c0ec1ed5..21a8336c8 100644 --- a/src/components/Publish/_utils.ts +++ b/src/components/Publish/_utils.ts @@ -27,7 +27,8 @@ import { defaultDatatokenTemplateIndex, defaultAccessTerms, complianceApiVersion, - complianceUri + complianceUri, + customProviderUrl } from '../../../app.config' import { sanitizeUrl } from '@utils/url' import { getContainerChecksum } from '@utils/docker' @@ -223,14 +224,15 @@ export async function createTokensAndPricing( values.metadata.transferable ) LoggerInstance.log('[publish] Creating NFT with metadata', nftCreateData) - // TODO: cap is hardcoded for now to 1000, this needs to be discussed at some point const ercParams: DatatokenCreateParams = { templateIndex: defaultDatatokenTemplateIndex, minter: accountId, paymentCollector: accountId, mpFeeAddress: marketFeeAddress, - feeToken: values.pricing.baseToken.address, + feeToken: + process.env.NEXT_PUBLIC_OCEAN_TOKEN_ADDRESS || + values.pricing.baseToken.address, feeAmount: publisherMarketOrderFee, // max number cap: '115792089237316195423570985008687907853269984665640564039457', @@ -246,10 +248,14 @@ export async function createTokensAndPricing( case 'fixed': { const freParams: FreCreationParams = { fixedRateAddress: config.fixedRateExchangeAddress, - baseTokenAddress: values.pricing.baseToken.address, + baseTokenAddress: process.env.NEXT_PUBLIC_OCEAN_TOKEN_ADDRESS + ? process.env.NEXT_PUBLIC_OCEAN_TOKEN_ADDRESS + : values.pricing.baseToken.address, owner: accountId, marketFeeCollector: marketFeeAddress, - baseTokenDecimals: values.pricing.baseToken.decimals, + baseTokenDecimals: process.env.NEXT_PUBLIC_OCEAN_TOKEN_ADDRESS + ? 18 + : values.pricing.baseToken.decimals, datatokenDecimals: 18, fixedRate: values.pricing.price.toString(), marketFee: publisherMarketFixedSwapFee, diff --git a/src/components/Publish/index.tsx b/src/components/Publish/index.tsx index a255fb7a2..effde8695 100644 --- a/src/components/Publish/index.tsx +++ b/src/components/Publish/index.tsx @@ -23,6 +23,7 @@ import { getOceanConfig } from '@utils/ocean' import { validationSchema } from './_validation' import { useAbortController } from '@hooks/useAbortController' import { setNFTMetadataAndTokenURI } from '@utils/nft' +import { customProviderUrl } from '../../../app.config' import { useAccount, useNetwork, useSigner } from 'wagmi' export default function PublishPage({ @@ -144,7 +145,7 @@ export default function PublishPage({ ddoEncrypted = await ProviderInstance.encrypt( ddo, ddo.chainId, - values.services[0].providerUrl.url, + customProviderUrl || values.services[0].providerUrl.url, newAbortController() ) } catch (error) { @@ -165,7 +166,6 @@ export default function PublishPage({ status: 'success' } })) - return { ddo, ddoEncrypted } } catch (error) { LoggerInstance.error('[publish] error', error.message)