1
0
mirror of https://github.com/oceanprotocol/market.git synced 2024-12-02 05:57:29 +01:00

Merge branch 'v4' into feature/issue-1344-unit-testing

This commit is contained in:
Enzo Vezzaro 2022-04-25 10:07:20 -04:00
commit ced3fad602
80 changed files with 1191 additions and 871 deletions

View File

@ -134,7 +134,7 @@ const queryLatest = {
} }
function Component() { function Component() {
const { appConfig } = useSiteMetadata() const { appConfig } = useMarketMetadata()
const [result, setResult] = useState<QueryResult>() const [result, setResult] = useState<QueryResult>()
useEffect(() => { useEffect(() => {

View File

@ -2,8 +2,8 @@ module.exports = {
// URI of single metadata cache instance for all networks. // URI of single metadata cache instance for all networks.
// While ocean.js includes this value for each network as part of its ConfigHelper, // While ocean.js includes this value for each network as part of its ConfigHelper,
// it is assumed to be the same for all networks. // it is assumed to be the same for all networks.
// In components can be accessed with the useSiteMetadata hook: // In components can be accessed with the useMarketMetadata hook:
// const { appConfig } = useSiteMetadata() // const { appConfig } = useMarketMetadata()
// return appConfig.metadataCacheUri // return appConfig.metadataCacheUri
metadataCacheUri: metadataCacheUri:
process.env.NEXT_PUBLIC_METADATACACHE_URI || process.env.NEXT_PUBLIC_METADATACACHE_URI ||

View File

@ -61,8 +61,8 @@
"title": "Remove Liquidity", "title": "Remove Liquidity",
"simple": "Set the amount of your pool shares to spend. You will get the equivalent value in OCEAN, limited to maximum amount for pool protection.", "simple": "Set the amount of your pool shares to spend. You will get the equivalent value in OCEAN, limited to maximum amount for pool protection.",
"output": { "output": {
"titleIn": "You will spend", "titleOutExpected": "Expected output",
"titleOut": "You will receive" "titleOutMinimum": "Minimum received"
}, },
"action": "Remove" "action": "Remove"
} }

View File

@ -2,5 +2,5 @@
"title": "Publish", "title": "Publish",
"description": "Highlight the important features of your data set or algorithm to make it more discoverable and catch the interest of data consumers.", "description": "Highlight the important features of your data set or algorithm to make it more discoverable and catch the interest of data consumers.",
"warning": "Publishing into a test network first is strongly recommended. Please familiarize yourself with [the market](https://oceanprotocol.com/technology/marketplaces), [the risks](https://blog.oceanprotocol.com/on-staking-on-data-in-ocean-market-3d8e09eb0a13), and the [Terms of Use](/terms).", "warning": "Publishing into a test network first is strongly recommended. Please familiarize yourself with [the market](https://oceanprotocol.com/technology/marketplaces), [the risks](https://blog.oceanprotocol.com/on-staking-on-data-in-ocean-market-3d8e09eb0a13), and the [Terms of Use](/terms).",
"tooltipNetwork": "Assets are published into the network your wallet is connected to. Switch your wallet's network to publish into another one." "tooltipAvailableNetworks": "Assets are published to the network your wallet is connected to. These networks are currently supported:"
} }

575
package-lock.json generated
View File

@ -13,15 +13,14 @@
"@coingecko/cryptoformat": "^0.4.4", "@coingecko/cryptoformat": "^0.4.4",
"@loadable/component": "^5.15.2", "@loadable/component": "^5.15.2",
"@oceanprotocol/art": "^3.2.0", "@oceanprotocol/art": "^3.2.0",
"@oceanprotocol/lib": "^1.0.0-next.35", "@oceanprotocol/lib": "^1.0.0-next.37",
"@oceanprotocol/typographies": "^0.1.0", "@oceanprotocol/typographies": "^0.1.0",
"@portis/web3": "^4.0.7", "@portis/web3": "^4.0.7",
"@storybook/addon-storyshots": "^6.4.22", "@storybook/addon-storyshots": "^6.4.22",
"@tippyjs/react": "^4.2.6", "@tippyjs/react": "^4.2.6",
"@urql/exchange-refocus": "^0.2.5", "@urql/exchange-refocus": "^0.2.5",
"@walletconnect/web3-provider": "^1.7.6", "@walletconnect/web3-provider": "^1.7.7",
"axios": "^0.26.1", "axios": "^0.26.1",
"bignumber.js": "^9.0.2",
"chart.js": "^3.7.1", "chart.js": "^3.7.1",
"classnames": "^2.3.1", "classnames": "^2.3.1",
"date-fns": "^2.28.0", "date-fns": "^2.28.0",
@ -37,29 +36,29 @@
"lodash.debounce": "^4.0.8", "lodash.debounce": "^4.0.8",
"lodash.omit": "^4.5.0", "lodash.omit": "^4.5.0",
"myetherwallet-blockies": "^0.1.1", "myetherwallet-blockies": "^0.1.1",
"next": "^12.1.0", "next": "^12.1.5",
"query-string": "^7.1.1", "query-string": "^7.1.1",
"react": "^17.0.2", "react": "^17.0.2",
"react-chartjs-2": "^4.0.1", "react-chartjs-2": "^4.1.0",
"react-clipboard.js": "^2.0.16", "react-clipboard.js": "^2.0.16",
"react-data-table-component": "^6.11.7", "react-data-table-component": "^6.11.7",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-dotdotdot": "^1.3.1", "react-dotdotdot": "^1.3.1",
"react-modal": "^3.14.4", "react-modal": "^3.14.4",
"react-paginate": "^8.1.2", "react-paginate": "^8.1.3",
"react-spring": "^9.4.4", "react-spring": "^9.4.4",
"react-tabs": "^3.2.3", "react-tabs": "^3.2.3",
"react-toastify": "^8.1.0", "react-toastify": "^8.2.0",
"remark": "^13.0.0", "remark": "^13.0.0",
"remark-gfm": "^1.0.0", "remark-gfm": "^1.0.0",
"remark-html": "^13.0.1", "remark-html": "^13.0.1",
"remove-markdown": "^0.3.0", "remove-markdown": "^0.3.0",
"slugify": "^1.6.5", "slugify": "^1.6.5",
"swr": "^1.2.2", "swr": "^1.3.0",
"urql": "^2.2.0", "urql": "^2.2.0",
"use-dark-mode": "^2.3.1", "use-dark-mode": "^2.3.1",
"web3": "^1.7.1", "web3": "^1.7.3",
"web3modal": "^1.9.5", "web3modal": "^1.9.7",
"yup": "^0.32.11" "yup": "^0.32.11"
}, },
"devDependencies": { "devDependencies": {
@ -74,7 +73,7 @@
"@testing-library/jest-dom": "^5.16.4", "@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^12.1.5", "@testing-library/react": "^12.1.5",
"@testing-library/user-event": "^14.1.1", "@testing-library/user-event": "^14.1.1",
"@types/chart.js": "^2.9.35", "@types/chart.js": "^2.9.37",
"@types/d3": "^7.1.0", "@types/d3": "^7.1.0",
"@types/js-cookie": "^3.0.1", "@types/js-cookie": "^3.0.1",
"@types/loadable__component": "^5.13.1", "@types/loadable__component": "^5.13.1",
@ -4588,14 +4587,29 @@
"integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=" "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs="
}, },
"node_modules/@next/env": { "node_modules/@next/env": {
"version": "12.1.0", "version": "12.1.5",
"resolved": "https://registry.npmjs.org/@next/env/-/env-12.1.0.tgz", "resolved": "https://registry.npmjs.org/@next/env/-/env-12.1.5.tgz",
"integrity": "sha512-nrIgY6t17FQ9xxwH3jj0a6EOiQ/WDHUos35Hghtr+SWN/ntHIQ7UpuvSi0vaLzZVHQWaDupKI+liO5vANcDeTQ==" "integrity": "sha512-+34yUJslfJi7Lyx6ELuN8nWcOzi27izfYnZIC1Dqv7kmmfiBVxgzR3BXhlvEMTKC2IRJhXVs2FkMY+buQe3k7Q=="
},
"node_modules/@next/swc-android-arm-eabi": {
"version": "12.1.5",
"resolved": "https://registry.npmjs.org/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-12.1.5.tgz",
"integrity": "sha512-SKnGTdYcoN04Y2DvE0/Y7/MjkA+ltsmbuH/y/hR7Ob7tsj+8ZdOYuk+YvW1B8dY20nDPHP58XgDTSm2nA8BzzA==",
"cpu": [
"arm"
],
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">= 10"
}
}, },
"node_modules/@next/swc-android-arm64": { "node_modules/@next/swc-android-arm64": {
"version": "12.1.0", "version": "12.1.5",
"resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-12.1.0.tgz", "resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-12.1.5.tgz",
"integrity": "sha512-/280MLdZe0W03stA69iL+v6I+J1ascrQ6FrXBlXGCsGzrfMaGr7fskMa0T5AhQIVQD4nA/46QQWxG//DYuFBcA==", "integrity": "sha512-YXiqgQ/9Rxg1dXp6brXbeQM1JDx9SwUY/36JiE+36FXqYEmDYbxld9qkX6GEzkc5rbwJ+RCitargnzEtwGW0mw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -4608,9 +4622,9 @@
} }
}, },
"node_modules/@next/swc-darwin-arm64": { "node_modules/@next/swc-darwin-arm64": {
"version": "12.1.0", "version": "12.1.5",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.1.0.tgz", "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.1.5.tgz",
"integrity": "sha512-R8vcXE2/iONJ1Unf5Ptqjk6LRW3bggH+8drNkkzH4FLEQkHtELhvcmJwkXcuipyQCsIakldAXhRbZmm3YN1vXg==", "integrity": "sha512-y8mhldb/WFZ6lFeowkGfi0cO/lBdiBqDk4T4LZLvCpoQp4Or/NzUN6P5NzBQZ5/b4oUHM/wQICEM+1wKA4qIVw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -4623,9 +4637,9 @@
} }
}, },
"node_modules/@next/swc-darwin-x64": { "node_modules/@next/swc-darwin-x64": {
"version": "12.1.0", "version": "12.1.5",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-12.1.0.tgz", "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-12.1.5.tgz",
"integrity": "sha512-ieAz0/J0PhmbZBB8+EA/JGdhRHBogF8BWaeqR7hwveb6SYEIJaDNQy0I+ZN8gF8hLj63bEDxJAs/cEhdnTq+ug==", "integrity": "sha512-wqJ3X7WQdTwSGi0kIDEmzw34QHISRIQ5uvC+VXmsIlCPFcMA+zM5723uh8NfuKGquDMiEMS31a83QgkuHMYbwQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -4638,9 +4652,9 @@
} }
}, },
"node_modules/@next/swc-linux-arm-gnueabihf": { "node_modules/@next/swc-linux-arm-gnueabihf": {
"version": "12.1.0", "version": "12.1.5",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.1.0.tgz", "resolved": "https://registry.npmjs.org/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.1.5.tgz",
"integrity": "sha512-njUd9hpl6o6A5d08dC0cKAgXKCzm5fFtgGe6i0eko8IAdtAPbtHxtpre3VeSxdZvuGFh+hb0REySQP9T1ttkog==", "integrity": "sha512-WnhdM5duONMvt2CncAl+9pim0wBxDS2lHoo7ub/o/i1bRbs11UTzosKzEXVaTDCUkCX2c32lIDi1WcN2ZPkcdw==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -4653,9 +4667,9 @@
} }
}, },
"node_modules/@next/swc-linux-arm64-gnu": { "node_modules/@next/swc-linux-arm64-gnu": {
"version": "12.1.0", "version": "12.1.5",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.1.0.tgz", "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.1.5.tgz",
"integrity": "sha512-OqangJLkRxVxMhDtcb7Qn1xjzFA3s50EIxY7mljbSCLybU+sByPaWAHY4px97ieOlr2y4S0xdPKkQ3BCAwyo6Q==", "integrity": "sha512-Jq2H68yQ4bLUhR/XQnbw3LDW0GMQn355qx6rU36BthDLeGue7YV7MqNPa8GKvrpPocEMW77nWx/1yI6w6J07gw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -4668,9 +4682,9 @@
} }
}, },
"node_modules/@next/swc-linux-arm64-musl": { "node_modules/@next/swc-linux-arm64-musl": {
"version": "12.1.0", "version": "12.1.5",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.1.0.tgz", "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.1.5.tgz",
"integrity": "sha512-hB8cLSt4GdmOpcwRe2UzI5UWn6HHO/vLkr5OTuNvCJ5xGDwpPXelVkYW/0+C3g5axbDW2Tym4S+MQCkkH9QfWA==", "integrity": "sha512-KgPjwdbhDqXI7ghNN8V/WAiLquc9Ebe8KBrNNEL0NQr+yd9CyKJ6KqjayVkmX+hbHzbyvbui/5wh/p3CZQ9xcQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -4683,9 +4697,9 @@
} }
}, },
"node_modules/@next/swc-linux-x64-gnu": { "node_modules/@next/swc-linux-x64-gnu": {
"version": "12.1.0", "version": "12.1.5",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.1.0.tgz", "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.1.5.tgz",
"integrity": "sha512-OKO4R/digvrVuweSw/uBM4nSdyzsBV5EwkUeeG4KVpkIZEe64ZwRpnFB65bC6hGwxIBnTv5NMSnJ+0K/WmG78A==", "integrity": "sha512-O2ErUTvCJ6DkNTSr9pbu1n3tcqykqE/ebty1rwClzIYdOgpB3T2MfEPP+K7GhUR87wmN/hlihO9ch7qpVFDGKw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -4698,9 +4712,9 @@
} }
}, },
"node_modules/@next/swc-linux-x64-musl": { "node_modules/@next/swc-linux-x64-musl": {
"version": "12.1.0", "version": "12.1.5",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.1.0.tgz", "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.1.5.tgz",
"integrity": "sha512-JohhgAHZvOD3rQY7tlp7NlmvtvYHBYgY0x5ZCecUT6eCCcl9lv6iV3nfu82ErkxNk1H893fqH0FUpznZ/H3pSw==", "integrity": "sha512-1eIlZmlO/VRjxxzUBcVosf54AFU3ltAzHi+BJA+9U/lPxCYIsT+R4uO3QksRzRjKWhVQMRjEnlXyyq5SKJm7BA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -4713,9 +4727,9 @@
} }
}, },
"node_modules/@next/swc-win32-arm64-msvc": { "node_modules/@next/swc-win32-arm64-msvc": {
"version": "12.1.0", "version": "12.1.5",
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.1.0.tgz", "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.1.5.tgz",
"integrity": "sha512-T/3gIE6QEfKIJ4dmJk75v9hhNiYZhQYAoYm4iVo1TgcsuaKLFa+zMPh4056AHiG6n9tn2UQ1CFE8EoybEsqsSw==", "integrity": "sha512-oromsfokbEuVb0CBLLE7R9qX3KGXucZpsojLpzUh1QJjuy1QkrPJncwr8xmWQnwgtQ6ecMWXgXPB+qtvizT9Tw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -4728,9 +4742,9 @@
} }
}, },
"node_modules/@next/swc-win32-ia32-msvc": { "node_modules/@next/swc-win32-ia32-msvc": {
"version": "12.1.0", "version": "12.1.5",
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.1.0.tgz", "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.1.5.tgz",
"integrity": "sha512-iwnKgHJdqhIW19H9PRPM9j55V6RdcOo6rX+5imx832BCWzkDbyomWnlzBfr6ByUYfhohb8QuH4hSGEikpPqI0Q==", "integrity": "sha512-a/51L5KzBpeZSW9LbekMo3I3Cwul+V+QKwbEIMA+Qwb2qrlcn1L9h3lt8cHqNTFt2y72ce6aTwDTw1lyi5oIRA==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@ -4743,9 +4757,9 @@
} }
}, },
"node_modules/@next/swc-win32-x64-msvc": { "node_modules/@next/swc-win32-x64-msvc": {
"version": "12.1.0", "version": "12.1.5",
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.1.0.tgz", "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.1.5.tgz",
"integrity": "sha512-aBvcbMwuanDH4EMrL2TthNJy+4nP59Bimn8egqv6GHMVj0a44cU6Au4PjOhLNqEh9l+IpRGBqMTzec94UdC5xg==", "integrity": "sha512-/SoXW1Ntpmpw3AXAzfDRaQidnd8kbZ2oSni8u5z0yw6t4RwJvmdZy1eOaAADRThWKV+2oU90++LSnXJIwBRWYQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -4835,9 +4849,9 @@
"integrity": "sha512-M/yyKfpWmMRHWPTjvKlrRWUcIbfkRWyHhjHUI1kPggJPPX6ADxApTwtzwVXJ/+WyegcaYc7bqwuclqvg9XPqBQ==" "integrity": "sha512-M/yyKfpWmMRHWPTjvKlrRWUcIbfkRWyHhjHUI1kPggJPPX6ADxApTwtzwVXJ/+WyegcaYc7bqwuclqvg9XPqBQ=="
}, },
"node_modules/@oceanprotocol/lib": { "node_modules/@oceanprotocol/lib": {
"version": "1.0.0-next.35", "version": "1.0.0-next.37",
"resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-1.0.0-next.35.tgz", "resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-1.0.0-next.37.tgz",
"integrity": "sha512-HLfg0W/GiPRHyevcKq9tZ+v0rZBaEIpZmIj7cJBNM+x82GxWKsTGqAkLjtWboMvO8/KdxW9nEs6RGuqTC6Lxvw==", "integrity": "sha512-3d3JSSZbBjPnlqzx8LJw6g+Ti4LL96FH/TTOqFCP9D4kbux2gN0KaUdHzI66G6S6vhsxBKOmUyACJcOuH3eBDQ==",
"dependencies": { "dependencies": {
"@oceanprotocol/contracts": "1.0.0-alpha.28", "@oceanprotocol/contracts": "1.0.0-alpha.28",
"bignumber.js": "^9.0.2", "bignumber.js": "^9.0.2",
@ -9396,9 +9410,9 @@
} }
}, },
"node_modules/@types/chart.js": { "node_modules/@types/chart.js": {
"version": "2.9.35", "version": "2.9.37",
"resolved": "https://registry.npmjs.org/@types/chart.js/-/chart.js-2.9.35.tgz", "resolved": "https://registry.npmjs.org/@types/chart.js/-/chart.js-2.9.37.tgz",
"integrity": "sha512-MWx/zZlh4wHBbM4Tm4YsZyYGb1/LkTiFLFwX/FXb0EJCvXX2xWTRHwlJ2RAAEXWxLrOdaAWP8vFtJXny+4CpEw==", "integrity": "sha512-9bosRfHhkXxKYfrw94EmyDQcdjMaQPkU1fH2tDxu8DWXxf1mjzWQAV4laJF51ZbC2ycYwNDvIm1rGez8Bug0vg==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"moment": "^2.10.2" "moment": "^2.10.2"
@ -10445,36 +10459,36 @@
} }
}, },
"node_modules/@walletconnect/browser-utils": { "node_modules/@walletconnect/browser-utils": {
"version": "1.7.6", "version": "1.7.7",
"resolved": "https://registry.npmjs.org/@walletconnect/browser-utils/-/browser-utils-1.7.6.tgz", "resolved": "https://registry.npmjs.org/@walletconnect/browser-utils/-/browser-utils-1.7.7.tgz",
"integrity": "sha512-7dZkvybjxIt59YdGqMCft8ydghlR7axSzZVW3Oy6NOYdq0ztZGCV/hpUcQ3pgC3uhpn93XqVPrBAyKLqt+/u5A==", "integrity": "sha512-6Mt7DSPaG0FKnHhuVzkU1hgtsCpGvl2nfbfRytLpyDY05iWMzMg5uK1DzV+0k4hCt9pVli0JVNt6dh9a6Xm94w==",
"dependencies": { "dependencies": {
"@walletconnect/safe-json": "1.0.0", "@walletconnect/safe-json": "1.0.0",
"@walletconnect/types": "^1.7.6", "@walletconnect/types": "^1.7.7",
"@walletconnect/window-getters": "1.0.0", "@walletconnect/window-getters": "1.0.0",
"@walletconnect/window-metadata": "1.0.0", "@walletconnect/window-metadata": "1.0.0",
"detect-browser": "5.2.0" "detect-browser": "5.2.0"
} }
}, },
"node_modules/@walletconnect/client": { "node_modules/@walletconnect/client": {
"version": "1.7.6", "version": "1.7.7",
"resolved": "https://registry.npmjs.org/@walletconnect/client/-/client-1.7.6.tgz", "resolved": "https://registry.npmjs.org/@walletconnect/client/-/client-1.7.7.tgz",
"integrity": "sha512-ZAcH9aL+p3psXwcsts51liKiqS/Kez05bYM193QC7mfcGwlFhQWMCRWHb38y8yHrWQMUmtOZ+jKotKjrOitDUw==", "integrity": "sha512-UuDkpXDc1Emx09aGXKz2Fg8omNp5J8ZRgNblnQTb8xnoQ8rgOJSyhbFR37PFIFwVpriZZDAgmy8HlqoGwLQ2ug==",
"dependencies": { "dependencies": {
"@walletconnect/core": "^1.7.6", "@walletconnect/core": "^1.7.7",
"@walletconnect/iso-crypto": "^1.7.6", "@walletconnect/iso-crypto": "^1.7.7",
"@walletconnect/types": "^1.7.6", "@walletconnect/types": "^1.7.7",
"@walletconnect/utils": "^1.7.6" "@walletconnect/utils": "^1.7.7"
} }
}, },
"node_modules/@walletconnect/core": { "node_modules/@walletconnect/core": {
"version": "1.7.6", "version": "1.7.7",
"resolved": "https://registry.npmjs.org/@walletconnect/core/-/core-1.7.6.tgz", "resolved": "https://registry.npmjs.org/@walletconnect/core/-/core-1.7.7.tgz",
"integrity": "sha512-gWD80GTgJ/xpYbJ/R5sbto1daDcDqeHl3ODzdtaVbDR2whS16spsEsXxgsM6BXFKqbGJ0r90SkHsNHa8xiekLQ==", "integrity": "sha512-XsF2x4JcBS1V2Nk/Uh38dU7ZlLmW/R5oxHp4+tVgCwTID6nZlo3vUSHBOqM7jgDRblKOHixANollm0r94bM8Cg==",
"dependencies": { "dependencies": {
"@walletconnect/socket-transport": "^1.7.6", "@walletconnect/socket-transport": "^1.7.7",
"@walletconnect/types": "^1.7.6", "@walletconnect/types": "^1.7.7",
"@walletconnect/utils": "^1.7.6" "@walletconnect/utils": "^1.7.7"
} }
}, },
"node_modules/@walletconnect/crypto": { "node_modules/@walletconnect/crypto": {
@ -10504,24 +10518,24 @@
"integrity": "sha512-4BwqyWy6KpSvkocSaV7WR3BlZfrxLbJSLkg+j7Gl6pTDE+U55lLhJvQaMuDVazXYxcjBsG09k7UlH7cGiUI5vQ==" "integrity": "sha512-4BwqyWy6KpSvkocSaV7WR3BlZfrxLbJSLkg+j7Gl6pTDE+U55lLhJvQaMuDVazXYxcjBsG09k7UlH7cGiUI5vQ=="
}, },
"node_modules/@walletconnect/http-connection": { "node_modules/@walletconnect/http-connection": {
"version": "1.7.6", "version": "1.7.7",
"resolved": "https://registry.npmjs.org/@walletconnect/http-connection/-/http-connection-1.7.6.tgz", "resolved": "https://registry.npmjs.org/@walletconnect/http-connection/-/http-connection-1.7.7.tgz",
"integrity": "sha512-G2xgqALcy2naHeiFS1N3VEwsgqIbFrbBv9gYaHE3R6RuEb4VVSIVGy6brpN+CoLmI680Kj2EmiJG7yvpNsHKdg==", "integrity": "sha512-MmhVJfBjvjYcZnrJYnDx4VBwpYM6yh7eX4/8szo6sGwzG4E+8V4YBKU2NF6fA6YXpdAyEYayElqXhB0YBEZFJA==",
"dependencies": { "dependencies": {
"@walletconnect/types": "^1.7.6", "@walletconnect/types": "^1.7.7",
"@walletconnect/utils": "^1.7.6", "@walletconnect/utils": "^1.7.7",
"eventemitter3": "4.0.7", "eventemitter3": "4.0.7",
"xhr2-cookies": "1.1.0" "xhr2-cookies": "1.1.0"
} }
}, },
"node_modules/@walletconnect/iso-crypto": { "node_modules/@walletconnect/iso-crypto": {
"version": "1.7.6", "version": "1.7.7",
"resolved": "https://registry.npmjs.org/@walletconnect/iso-crypto/-/iso-crypto-1.7.6.tgz", "resolved": "https://registry.npmjs.org/@walletconnect/iso-crypto/-/iso-crypto-1.7.7.tgz",
"integrity": "sha512-x80OVfarjPzD02kJgnpmLCxlsFRaymGjlGWzLmtwO8/hp1mrtT/ukFOsl1Fs6Tunp7BdCoJT+9FYFarcvbsG8Q==", "integrity": "sha512-t8RKJZkFtFyWMFrl0jPz/3RAGhM5yext+MLFq3L/KTPxLgMZuT1yFHRUiV7cAN3+LcCmk6Sy/rV1yQPTiB158Q==",
"dependencies": { "dependencies": {
"@walletconnect/crypto": "^1.0.2", "@walletconnect/crypto": "^1.0.2",
"@walletconnect/types": "^1.7.6", "@walletconnect/types": "^1.7.7",
"@walletconnect/utils": "^1.7.6" "@walletconnect/utils": "^1.7.7"
} }
}, },
"node_modules/@walletconnect/jsonrpc-types": { "node_modules/@walletconnect/jsonrpc-types": {
@ -10548,13 +10562,13 @@
"deprecated": "Deprecated in favor of dynamic registry available from: https://github.com/walletconnect/walletconnect-registry" "deprecated": "Deprecated in favor of dynamic registry available from: https://github.com/walletconnect/walletconnect-registry"
}, },
"node_modules/@walletconnect/qrcode-modal": { "node_modules/@walletconnect/qrcode-modal": {
"version": "1.7.6", "version": "1.7.7",
"resolved": "https://registry.npmjs.org/@walletconnect/qrcode-modal/-/qrcode-modal-1.7.6.tgz", "resolved": "https://registry.npmjs.org/@walletconnect/qrcode-modal/-/qrcode-modal-1.7.7.tgz",
"integrity": "sha512-SXx8eTllgyGpArwdB8v1WsmAKbxiizqebJLn32C6KRzWVW5FP4FizzgEi+r6xINWSEpWLX72GbeWAoiQDwFVFw==", "integrity": "sha512-HRzw6g4P8/C4ClJYJShaGfdvjfrTfkXv+eb+IylWGWvC8IQhuiSXCq5+F3t0CXxuZs3ir26abgviEMRFQxGKdA==",
"dependencies": { "dependencies": {
"@walletconnect/browser-utils": "^1.7.6", "@walletconnect/browser-utils": "^1.7.7",
"@walletconnect/mobile-registry": "^1.4.0", "@walletconnect/mobile-registry": "^1.4.0",
"@walletconnect/types": "^1.7.6", "@walletconnect/types": "^1.7.7",
"copy-to-clipboard": "^3.3.1", "copy-to-clipboard": "^3.3.1",
"preact": "10.4.1", "preact": "10.4.1",
"qrcode": "1.4.4" "qrcode": "1.4.4"
@ -10585,29 +10599,29 @@
"integrity": "sha512-QJzp/S/86sUAgWY6eh5MKYmSfZaRpIlmCJdi5uG4DJlKkZrHEF7ye7gA+VtbVzvTtpM/gRwO2plQuiooIeXjfg==" "integrity": "sha512-QJzp/S/86sUAgWY6eh5MKYmSfZaRpIlmCJdi5uG4DJlKkZrHEF7ye7gA+VtbVzvTtpM/gRwO2plQuiooIeXjfg=="
}, },
"node_modules/@walletconnect/socket-transport": { "node_modules/@walletconnect/socket-transport": {
"version": "1.7.6", "version": "1.7.7",
"resolved": "https://registry.npmjs.org/@walletconnect/socket-transport/-/socket-transport-1.7.6.tgz", "resolved": "https://registry.npmjs.org/@walletconnect/socket-transport/-/socket-transport-1.7.7.tgz",
"integrity": "sha512-yH2eKD9P34gnOxOfCarERROl5SkiwBR9UcASjcnp2L7r02ZaXHbhheXHUWzcU5HpEXrvz8DGciE7GBQn+aNgQg==", "integrity": "sha512-RxeFkT+5BqdaZzPtPYIw6+KSVh6Q1NaYqTiAzWWh9RPuvuTajIEsi+fUXizfkpmyi9UTYBvdFXnKcB+eSImpDg==",
"dependencies": { "dependencies": {
"@walletconnect/types": "^1.7.6", "@walletconnect/types": "^1.7.7",
"@walletconnect/utils": "^1.7.6", "@walletconnect/utils": "^1.7.7",
"ws": "7.5.3" "ws": "7.5.3"
} }
}, },
"node_modules/@walletconnect/types": { "node_modules/@walletconnect/types": {
"version": "1.7.6", "version": "1.7.7",
"resolved": "https://registry.npmjs.org/@walletconnect/types/-/types-1.7.6.tgz", "resolved": "https://registry.npmjs.org/@walletconnect/types/-/types-1.7.7.tgz",
"integrity": "sha512-3JVjEzvJgDc5DzaXNxhg4JcdG4U8Qk6HVBELOu+TwiWG31TZRt82uL9CcVZKieFPP/nTWQnj+QkiKSpO7T1KTQ==" "integrity": "sha512-yXJrLxwLLCXtWgd/e8FjfY9v5DKds12Z7EEPzUrPSq6v7WtXpqate577KwlFQ6UYzioQzIEDE8+98j+0aiZbsw=="
}, },
"node_modules/@walletconnect/utils": { "node_modules/@walletconnect/utils": {
"version": "1.7.6", "version": "1.7.7",
"resolved": "https://registry.npmjs.org/@walletconnect/utils/-/utils-1.7.6.tgz", "resolved": "https://registry.npmjs.org/@walletconnect/utils/-/utils-1.7.7.tgz",
"integrity": "sha512-GLneac0Hx52pNHAOkTt/07K+Ht8LmWFaK0nQlHqrLmOJm8WZPnUvMZGMTpSOzgKw47u0cjhE38ipbXOaq8qReA==", "integrity": "sha512-slNlnROS4DEusGFx53hshIBylYhzd5JtGF+AJpza+Tc616+u8ozjQ9aKKUaV85bucnv5Q42bTwLYrYrXiydmuw==",
"dependencies": { "dependencies": {
"@walletconnect/browser-utils": "^1.7.6", "@walletconnect/browser-utils": "^1.7.7",
"@walletconnect/encoding": "^1.0.1", "@walletconnect/encoding": "^1.0.1",
"@walletconnect/jsonrpc-utils": "^1.0.0", "@walletconnect/jsonrpc-utils": "^1.0.0",
"@walletconnect/types": "^1.7.6", "@walletconnect/types": "^1.7.7",
"bn.js": "4.11.8", "bn.js": "4.11.8",
"js-sha3": "0.8.0", "js-sha3": "0.8.0",
"query-string": "6.13.5" "query-string": "6.13.5"
@ -10635,15 +10649,15 @@
} }
}, },
"node_modules/@walletconnect/web3-provider": { "node_modules/@walletconnect/web3-provider": {
"version": "1.7.6", "version": "1.7.7",
"resolved": "https://registry.npmjs.org/@walletconnect/web3-provider/-/web3-provider-1.7.6.tgz", "resolved": "https://registry.npmjs.org/@walletconnect/web3-provider/-/web3-provider-1.7.7.tgz",
"integrity": "sha512-INjHVTuuISm9rk9QGr8v0IvcmjygEyt+rDB6Iw6G5hK+qwEB+UlrRbXyu0bAmEe4wREpiJmegz7KjiHIxmCTNA==", "integrity": "sha512-hUhDyaMu93e7e82OVCu3KnYOn6m6wQO9YObbhi3PexppCANe/Y9eDrw/37S+7jbjLIx5nS1et2JU+taKR7OSOw==",
"dependencies": { "dependencies": {
"@walletconnect/client": "^1.7.6", "@walletconnect/client": "^1.7.7",
"@walletconnect/http-connection": "^1.7.6", "@walletconnect/http-connection": "^1.7.7",
"@walletconnect/qrcode-modal": "^1.7.6", "@walletconnect/qrcode-modal": "^1.7.7",
"@walletconnect/types": "^1.7.6", "@walletconnect/types": "^1.7.7",
"@walletconnect/utils": "^1.7.6", "@walletconnect/utils": "^1.7.7",
"web3-provider-engine": "16.0.1" "web3-provider-engine": "16.0.1"
} }
}, },
@ -28179,15 +28193,14 @@
"integrity": "sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==" "integrity": "sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw=="
}, },
"node_modules/next": { "node_modules/next": {
"version": "12.1.0", "version": "12.1.5",
"resolved": "https://registry.npmjs.org/next/-/next-12.1.0.tgz", "resolved": "https://registry.npmjs.org/next/-/next-12.1.5.tgz",
"integrity": "sha512-s885kWvnIlxsUFHq9UGyIyLiuD0G3BUC/xrH0CEnH5lHEWkwQcHOORgbDF0hbrW9vr/7am4ETfX4A7M6DjrE7Q==", "integrity": "sha512-YGHDpyfgCfnT5GZObsKepmRnne7Kzp7nGrac07dikhutWQug7hHg85/+sPJ4ZW5Q2pDkb+n0FnmLkmd44htIJQ==",
"dependencies": { "dependencies": {
"@next/env": "12.1.0", "@next/env": "12.1.5",
"caniuse-lite": "^1.0.30001283", "caniuse-lite": "^1.0.30001283",
"postcss": "8.4.5", "postcss": "8.4.5",
"styled-jsx": "5.0.0", "styled-jsx": "5.0.1"
"use-subscription": "1.5.1"
}, },
"bin": { "bin": {
"next": "dist/bin/next" "next": "dist/bin/next"
@ -28196,17 +28209,18 @@
"node": ">=12.22.0" "node": ">=12.22.0"
}, },
"optionalDependencies": { "optionalDependencies": {
"@next/swc-android-arm64": "12.1.0", "@next/swc-android-arm-eabi": "12.1.5",
"@next/swc-darwin-arm64": "12.1.0", "@next/swc-android-arm64": "12.1.5",
"@next/swc-darwin-x64": "12.1.0", "@next/swc-darwin-arm64": "12.1.5",
"@next/swc-linux-arm-gnueabihf": "12.1.0", "@next/swc-darwin-x64": "12.1.5",
"@next/swc-linux-arm64-gnu": "12.1.0", "@next/swc-linux-arm-gnueabihf": "12.1.5",
"@next/swc-linux-arm64-musl": "12.1.0", "@next/swc-linux-arm64-gnu": "12.1.5",
"@next/swc-linux-x64-gnu": "12.1.0", "@next/swc-linux-arm64-musl": "12.1.5",
"@next/swc-linux-x64-musl": "12.1.0", "@next/swc-linux-x64-gnu": "12.1.5",
"@next/swc-win32-arm64-msvc": "12.1.0", "@next/swc-linux-x64-musl": "12.1.5",
"@next/swc-win32-ia32-msvc": "12.1.0", "@next/swc-win32-arm64-msvc": "12.1.5",
"@next/swc-win32-x64-msvc": "12.1.0" "@next/swc-win32-ia32-msvc": "12.1.5",
"@next/swc-win32-x64-msvc": "12.1.5"
}, },
"peerDependencies": { "peerDependencies": {
"fibers": ">= 3.1.0", "fibers": ">= 3.1.0",
@ -30540,12 +30554,12 @@
} }
}, },
"node_modules/react-chartjs-2": { "node_modules/react-chartjs-2": {
"version": "4.0.1", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-4.0.1.tgz", "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-4.1.0.tgz",
"integrity": "sha512-q8bgWzKoFvBvD7YcjT/hXG8jt55TaMAuJ1dmI3tKFJ7CijUWYz4pIfOhkTI6PBTwqu/pmeWsClBRd/7HiWzN1g==", "integrity": "sha512-AsUihxEp8Jm1oBhbEovE+w50m9PVNhz1sfwEIT4hZduRC0m14gHWHd0cUaxkFDb8HNkdMIGzsNlmVqKiOpU74g==",
"peerDependencies": { "peerDependencies": {
"chart.js": "^3.5.0", "chart.js": "^3.5.0",
"react": "^16.8.0 || ^17.0.0" "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
} }
}, },
"node_modules/react-clipboard.js": { "node_modules/react-clipboard.js": {
@ -30772,14 +30786,14 @@
} }
}, },
"node_modules/react-paginate": { "node_modules/react-paginate": {
"version": "8.1.2", "version": "8.1.3",
"resolved": "https://registry.npmjs.org/react-paginate/-/react-paginate-8.1.2.tgz", "resolved": "https://registry.npmjs.org/react-paginate/-/react-paginate-8.1.3.tgz",
"integrity": "sha512-buBkBiN9J8gvZYwYNixlTGRmWOC5C6+tH2XHTN8B5qGkRPOSYFkAqxhWUnxSVAeLKxpVZGPya/gOL2eJQNZGvg==", "integrity": "sha512-zBp80DBRcaeBnAeHUfbGKD0XHfbGNUolQ+S60Ymfs8o7rusYaJYZMAt1j93ADDNLlzRmJ0tMF/NeTlcdKf7dlQ==",
"dependencies": { "dependencies": {
"prop-types": "^15.6.1" "prop-types": "^15.6.1"
}, },
"peerDependencies": { "peerDependencies": {
"react": "^16 || ^17" "react": "^16 || ^17 || ^18"
} }
}, },
"node_modules/react-popper": { "node_modules/react-popper": {
@ -34135,14 +34149,14 @@
} }
}, },
"node_modules/styled-jsx": { "node_modules/styled-jsx": {
"version": "5.0.0", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.0.0.tgz", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.0.1.tgz",
"integrity": "sha512-qUqsWoBquEdERe10EW8vLp3jT25s/ssG1/qX5gZ4wu15OZpmSMFI2v+fWlRhLfykA5rFtlJ1ME8A8pm/peV4WA==", "integrity": "sha512-+PIZ/6Uk40mphiQJJI1202b+/dYeTVd9ZnMPR80pgiWbjIwvN2zIp4r9et0BgqBuShh48I0gttPlAXA7WVvBxw==",
"engines": { "engines": {
"node": ">= 12.0.0" "node": ">= 12.0.0"
}, },
"peerDependencies": { "peerDependencies": {
"react": ">= 16.8.0 || 17.x.x || 18.x.x" "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0"
}, },
"peerDependenciesMeta": { "peerDependenciesMeta": {
"@babel/core": { "@babel/core": {
@ -34337,9 +34351,9 @@
} }
}, },
"node_modules/swr": { "node_modules/swr": {
"version": "1.2.2", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/swr/-/swr-1.2.2.tgz", "resolved": "https://registry.npmjs.org/swr/-/swr-1.3.0.tgz",
"integrity": "sha512-ky0BskS/V47GpW8d6RU7CPsr6J8cr7mQD6+do5eky3bM0IyJaoi3vO8UhvrzJaObuTlGhPl2szodeB2dUd76Xw==", "integrity": "sha512-dkghQrOl2ORX9HYrMDtPa7LTVHJjCTeZoB1dqTbnnEDlSvN8JEKpYIYurDfvbQFUUS8Cg8PceFVZNkW0KNNYPw==",
"peerDependencies": { "peerDependencies": {
"react": "^16.11.0 || ^17.0.0 || ^18.0.0" "react": "^16.11.0 || ^17.0.0 || ^18.0.0"
} }
@ -36015,17 +36029,6 @@
"react": "^16.8.0 || ^17.0.0" "react": "^16.8.0 || ^17.0.0"
} }
}, },
"node_modules/use-subscription": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.5.1.tgz",
"integrity": "sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA==",
"dependencies": {
"object-assign": "^4.1.1"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0"
}
},
"node_modules/utf-8-validate": { "node_modules/utf-8-validate": {
"version": "5.0.8", "version": "5.0.8",
"resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.8.tgz", "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.8.tgz",
@ -37111,9 +37114,9 @@
} }
}, },
"node_modules/web3modal": { "node_modules/web3modal": {
"version": "1.9.5", "version": "1.9.7",
"resolved": "https://registry.npmjs.org/web3modal/-/web3modal-1.9.5.tgz", "resolved": "https://registry.npmjs.org/web3modal/-/web3modal-1.9.7.tgz",
"integrity": "sha512-L5ME6zgoaCDa+T66skW9WpxGOJX6vU9v+7aLacoQJhU3AMTk784ionpX+Pg4UdhdM+UQW+odge32GkwEX11czQ==", "integrity": "sha512-z3XfY7cV8GwGvHP3WvrSxPU6/7ocwVyiU77U/Lxoa53AUSsOKl01V8ErZ8CkJSH41C3YgzwBaOETj0rC9uFBKg==",
"dependencies": { "dependencies": {
"detect-browser": "^5.1.0", "detect-browser": "^5.1.0",
"prop-types": "^15.7.2", "prop-types": "^15.7.2",
@ -41785,74 +41788,80 @@
} }
}, },
"@next/env": { "@next/env": {
"version": "12.1.0", "version": "12.1.5",
"resolved": "https://registry.npmjs.org/@next/env/-/env-12.1.0.tgz", "resolved": "https://registry.npmjs.org/@next/env/-/env-12.1.5.tgz",
"integrity": "sha512-nrIgY6t17FQ9xxwH3jj0a6EOiQ/WDHUos35Hghtr+SWN/ntHIQ7UpuvSi0vaLzZVHQWaDupKI+liO5vANcDeTQ==" "integrity": "sha512-+34yUJslfJi7Lyx6ELuN8nWcOzi27izfYnZIC1Dqv7kmmfiBVxgzR3BXhlvEMTKC2IRJhXVs2FkMY+buQe3k7Q=="
},
"@next/swc-android-arm-eabi": {
"version": "12.1.5",
"resolved": "https://registry.npmjs.org/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-12.1.5.tgz",
"integrity": "sha512-SKnGTdYcoN04Y2DvE0/Y7/MjkA+ltsmbuH/y/hR7Ob7tsj+8ZdOYuk+YvW1B8dY20nDPHP58XgDTSm2nA8BzzA==",
"optional": true
}, },
"@next/swc-android-arm64": { "@next/swc-android-arm64": {
"version": "12.1.0", "version": "12.1.5",
"resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-12.1.0.tgz", "resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-12.1.5.tgz",
"integrity": "sha512-/280MLdZe0W03stA69iL+v6I+J1ascrQ6FrXBlXGCsGzrfMaGr7fskMa0T5AhQIVQD4nA/46QQWxG//DYuFBcA==", "integrity": "sha512-YXiqgQ/9Rxg1dXp6brXbeQM1JDx9SwUY/36JiE+36FXqYEmDYbxld9qkX6GEzkc5rbwJ+RCitargnzEtwGW0mw==",
"optional": true "optional": true
}, },
"@next/swc-darwin-arm64": { "@next/swc-darwin-arm64": {
"version": "12.1.0", "version": "12.1.5",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.1.0.tgz", "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.1.5.tgz",
"integrity": "sha512-R8vcXE2/iONJ1Unf5Ptqjk6LRW3bggH+8drNkkzH4FLEQkHtELhvcmJwkXcuipyQCsIakldAXhRbZmm3YN1vXg==", "integrity": "sha512-y8mhldb/WFZ6lFeowkGfi0cO/lBdiBqDk4T4LZLvCpoQp4Or/NzUN6P5NzBQZ5/b4oUHM/wQICEM+1wKA4qIVw==",
"optional": true "optional": true
}, },
"@next/swc-darwin-x64": { "@next/swc-darwin-x64": {
"version": "12.1.0", "version": "12.1.5",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-12.1.0.tgz", "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-12.1.5.tgz",
"integrity": "sha512-ieAz0/J0PhmbZBB8+EA/JGdhRHBogF8BWaeqR7hwveb6SYEIJaDNQy0I+ZN8gF8hLj63bEDxJAs/cEhdnTq+ug==", "integrity": "sha512-wqJ3X7WQdTwSGi0kIDEmzw34QHISRIQ5uvC+VXmsIlCPFcMA+zM5723uh8NfuKGquDMiEMS31a83QgkuHMYbwQ==",
"optional": true "optional": true
}, },
"@next/swc-linux-arm-gnueabihf": { "@next/swc-linux-arm-gnueabihf": {
"version": "12.1.0", "version": "12.1.5",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.1.0.tgz", "resolved": "https://registry.npmjs.org/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.1.5.tgz",
"integrity": "sha512-njUd9hpl6o6A5d08dC0cKAgXKCzm5fFtgGe6i0eko8IAdtAPbtHxtpre3VeSxdZvuGFh+hb0REySQP9T1ttkog==", "integrity": "sha512-WnhdM5duONMvt2CncAl+9pim0wBxDS2lHoo7ub/o/i1bRbs11UTzosKzEXVaTDCUkCX2c32lIDi1WcN2ZPkcdw==",
"optional": true "optional": true
}, },
"@next/swc-linux-arm64-gnu": { "@next/swc-linux-arm64-gnu": {
"version": "12.1.0", "version": "12.1.5",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.1.0.tgz", "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.1.5.tgz",
"integrity": "sha512-OqangJLkRxVxMhDtcb7Qn1xjzFA3s50EIxY7mljbSCLybU+sByPaWAHY4px97ieOlr2y4S0xdPKkQ3BCAwyo6Q==", "integrity": "sha512-Jq2H68yQ4bLUhR/XQnbw3LDW0GMQn355qx6rU36BthDLeGue7YV7MqNPa8GKvrpPocEMW77nWx/1yI6w6J07gw==",
"optional": true "optional": true
}, },
"@next/swc-linux-arm64-musl": { "@next/swc-linux-arm64-musl": {
"version": "12.1.0", "version": "12.1.5",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.1.0.tgz", "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.1.5.tgz",
"integrity": "sha512-hB8cLSt4GdmOpcwRe2UzI5UWn6HHO/vLkr5OTuNvCJ5xGDwpPXelVkYW/0+C3g5axbDW2Tym4S+MQCkkH9QfWA==", "integrity": "sha512-KgPjwdbhDqXI7ghNN8V/WAiLquc9Ebe8KBrNNEL0NQr+yd9CyKJ6KqjayVkmX+hbHzbyvbui/5wh/p3CZQ9xcQ==",
"optional": true "optional": true
}, },
"@next/swc-linux-x64-gnu": { "@next/swc-linux-x64-gnu": {
"version": "12.1.0", "version": "12.1.5",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.1.0.tgz", "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.1.5.tgz",
"integrity": "sha512-OKO4R/digvrVuweSw/uBM4nSdyzsBV5EwkUeeG4KVpkIZEe64ZwRpnFB65bC6hGwxIBnTv5NMSnJ+0K/WmG78A==", "integrity": "sha512-O2ErUTvCJ6DkNTSr9pbu1n3tcqykqE/ebty1rwClzIYdOgpB3T2MfEPP+K7GhUR87wmN/hlihO9ch7qpVFDGKw==",
"optional": true "optional": true
}, },
"@next/swc-linux-x64-musl": { "@next/swc-linux-x64-musl": {
"version": "12.1.0", "version": "12.1.5",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.1.0.tgz", "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.1.5.tgz",
"integrity": "sha512-JohhgAHZvOD3rQY7tlp7NlmvtvYHBYgY0x5ZCecUT6eCCcl9lv6iV3nfu82ErkxNk1H893fqH0FUpznZ/H3pSw==", "integrity": "sha512-1eIlZmlO/VRjxxzUBcVosf54AFU3ltAzHi+BJA+9U/lPxCYIsT+R4uO3QksRzRjKWhVQMRjEnlXyyq5SKJm7BA==",
"optional": true "optional": true
}, },
"@next/swc-win32-arm64-msvc": { "@next/swc-win32-arm64-msvc": {
"version": "12.1.0", "version": "12.1.5",
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.1.0.tgz", "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.1.5.tgz",
"integrity": "sha512-T/3gIE6QEfKIJ4dmJk75v9hhNiYZhQYAoYm4iVo1TgcsuaKLFa+zMPh4056AHiG6n9tn2UQ1CFE8EoybEsqsSw==", "integrity": "sha512-oromsfokbEuVb0CBLLE7R9qX3KGXucZpsojLpzUh1QJjuy1QkrPJncwr8xmWQnwgtQ6ecMWXgXPB+qtvizT9Tw==",
"optional": true "optional": true
}, },
"@next/swc-win32-ia32-msvc": { "@next/swc-win32-ia32-msvc": {
"version": "12.1.0", "version": "12.1.5",
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.1.0.tgz", "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.1.5.tgz",
"integrity": "sha512-iwnKgHJdqhIW19H9PRPM9j55V6RdcOo6rX+5imx832BCWzkDbyomWnlzBfr6ByUYfhohb8QuH4hSGEikpPqI0Q==", "integrity": "sha512-a/51L5KzBpeZSW9LbekMo3I3Cwul+V+QKwbEIMA+Qwb2qrlcn1L9h3lt8cHqNTFt2y72ce6aTwDTw1lyi5oIRA==",
"optional": true "optional": true
}, },
"@next/swc-win32-x64-msvc": { "@next/swc-win32-x64-msvc": {
"version": "12.1.0", "version": "12.1.5",
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.1.0.tgz", "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.1.5.tgz",
"integrity": "sha512-aBvcbMwuanDH4EMrL2TthNJy+4nP59Bimn8egqv6GHMVj0a44cU6Au4PjOhLNqEh9l+IpRGBqMTzec94UdC5xg==", "integrity": "sha512-/SoXW1Ntpmpw3AXAzfDRaQidnd8kbZ2oSni8u5z0yw6t4RwJvmdZy1eOaAADRThWKV+2oU90++LSnXJIwBRWYQ==",
"optional": true "optional": true
}, },
"@nodelib/fs.scandir": { "@nodelib/fs.scandir": {
@ -41917,9 +41926,9 @@
"integrity": "sha512-M/yyKfpWmMRHWPTjvKlrRWUcIbfkRWyHhjHUI1kPggJPPX6ADxApTwtzwVXJ/+WyegcaYc7bqwuclqvg9XPqBQ==" "integrity": "sha512-M/yyKfpWmMRHWPTjvKlrRWUcIbfkRWyHhjHUI1kPggJPPX6ADxApTwtzwVXJ/+WyegcaYc7bqwuclqvg9XPqBQ=="
}, },
"@oceanprotocol/lib": { "@oceanprotocol/lib": {
"version": "1.0.0-next.35", "version": "1.0.0-next.37",
"resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-1.0.0-next.35.tgz", "resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-1.0.0-next.37.tgz",
"integrity": "sha512-HLfg0W/GiPRHyevcKq9tZ+v0rZBaEIpZmIj7cJBNM+x82GxWKsTGqAkLjtWboMvO8/KdxW9nEs6RGuqTC6Lxvw==", "integrity": "sha512-3d3JSSZbBjPnlqzx8LJw6g+Ti4LL96FH/TTOqFCP9D4kbux2gN0KaUdHzI66G6S6vhsxBKOmUyACJcOuH3eBDQ==",
"requires": { "requires": {
"@oceanprotocol/contracts": "1.0.0-alpha.28", "@oceanprotocol/contracts": "1.0.0-alpha.28",
"bignumber.js": "^9.0.2", "bignumber.js": "^9.0.2",
@ -45055,9 +45064,9 @@
} }
}, },
"@types/chart.js": { "@types/chart.js": {
"version": "2.9.35", "version": "2.9.37",
"resolved": "https://registry.npmjs.org/@types/chart.js/-/chart.js-2.9.35.tgz", "resolved": "https://registry.npmjs.org/@types/chart.js/-/chart.js-2.9.37.tgz",
"integrity": "sha512-MWx/zZlh4wHBbM4Tm4YsZyYGb1/LkTiFLFwX/FXb0EJCvXX2xWTRHwlJ2RAAEXWxLrOdaAWP8vFtJXny+4CpEw==", "integrity": "sha512-9bosRfHhkXxKYfrw94EmyDQcdjMaQPkU1fH2tDxu8DWXxf1mjzWQAV4laJF51ZbC2ycYwNDvIm1rGez8Bug0vg==",
"dev": true, "dev": true,
"requires": { "requires": {
"moment": "^2.10.2" "moment": "^2.10.2"
@ -45995,36 +46004,36 @@
"requires": {} "requires": {}
}, },
"@walletconnect/browser-utils": { "@walletconnect/browser-utils": {
"version": "1.7.6", "version": "1.7.7",
"resolved": "https://registry.npmjs.org/@walletconnect/browser-utils/-/browser-utils-1.7.6.tgz", "resolved": "https://registry.npmjs.org/@walletconnect/browser-utils/-/browser-utils-1.7.7.tgz",
"integrity": "sha512-7dZkvybjxIt59YdGqMCft8ydghlR7axSzZVW3Oy6NOYdq0ztZGCV/hpUcQ3pgC3uhpn93XqVPrBAyKLqt+/u5A==", "integrity": "sha512-6Mt7DSPaG0FKnHhuVzkU1hgtsCpGvl2nfbfRytLpyDY05iWMzMg5uK1DzV+0k4hCt9pVli0JVNt6dh9a6Xm94w==",
"requires": { "requires": {
"@walletconnect/safe-json": "1.0.0", "@walletconnect/safe-json": "1.0.0",
"@walletconnect/types": "^1.7.6", "@walletconnect/types": "^1.7.7",
"@walletconnect/window-getters": "1.0.0", "@walletconnect/window-getters": "1.0.0",
"@walletconnect/window-metadata": "1.0.0", "@walletconnect/window-metadata": "1.0.0",
"detect-browser": "5.2.0" "detect-browser": "5.2.0"
} }
}, },
"@walletconnect/client": { "@walletconnect/client": {
"version": "1.7.6", "version": "1.7.7",
"resolved": "https://registry.npmjs.org/@walletconnect/client/-/client-1.7.6.tgz", "resolved": "https://registry.npmjs.org/@walletconnect/client/-/client-1.7.7.tgz",
"integrity": "sha512-ZAcH9aL+p3psXwcsts51liKiqS/Kez05bYM193QC7mfcGwlFhQWMCRWHb38y8yHrWQMUmtOZ+jKotKjrOitDUw==", "integrity": "sha512-UuDkpXDc1Emx09aGXKz2Fg8omNp5J8ZRgNblnQTb8xnoQ8rgOJSyhbFR37PFIFwVpriZZDAgmy8HlqoGwLQ2ug==",
"requires": { "requires": {
"@walletconnect/core": "^1.7.6", "@walletconnect/core": "^1.7.7",
"@walletconnect/iso-crypto": "^1.7.6", "@walletconnect/iso-crypto": "^1.7.7",
"@walletconnect/types": "^1.7.6", "@walletconnect/types": "^1.7.7",
"@walletconnect/utils": "^1.7.6" "@walletconnect/utils": "^1.7.7"
} }
}, },
"@walletconnect/core": { "@walletconnect/core": {
"version": "1.7.6", "version": "1.7.7",
"resolved": "https://registry.npmjs.org/@walletconnect/core/-/core-1.7.6.tgz", "resolved": "https://registry.npmjs.org/@walletconnect/core/-/core-1.7.7.tgz",
"integrity": "sha512-gWD80GTgJ/xpYbJ/R5sbto1daDcDqeHl3ODzdtaVbDR2whS16spsEsXxgsM6BXFKqbGJ0r90SkHsNHa8xiekLQ==", "integrity": "sha512-XsF2x4JcBS1V2Nk/Uh38dU7ZlLmW/R5oxHp4+tVgCwTID6nZlo3vUSHBOqM7jgDRblKOHixANollm0r94bM8Cg==",
"requires": { "requires": {
"@walletconnect/socket-transport": "^1.7.6", "@walletconnect/socket-transport": "^1.7.7",
"@walletconnect/types": "^1.7.6", "@walletconnect/types": "^1.7.7",
"@walletconnect/utils": "^1.7.6" "@walletconnect/utils": "^1.7.7"
} }
}, },
"@walletconnect/crypto": { "@walletconnect/crypto": {
@ -46054,24 +46063,24 @@
"integrity": "sha512-4BwqyWy6KpSvkocSaV7WR3BlZfrxLbJSLkg+j7Gl6pTDE+U55lLhJvQaMuDVazXYxcjBsG09k7UlH7cGiUI5vQ==" "integrity": "sha512-4BwqyWy6KpSvkocSaV7WR3BlZfrxLbJSLkg+j7Gl6pTDE+U55lLhJvQaMuDVazXYxcjBsG09k7UlH7cGiUI5vQ=="
}, },
"@walletconnect/http-connection": { "@walletconnect/http-connection": {
"version": "1.7.6", "version": "1.7.7",
"resolved": "https://registry.npmjs.org/@walletconnect/http-connection/-/http-connection-1.7.6.tgz", "resolved": "https://registry.npmjs.org/@walletconnect/http-connection/-/http-connection-1.7.7.tgz",
"integrity": "sha512-G2xgqALcy2naHeiFS1N3VEwsgqIbFrbBv9gYaHE3R6RuEb4VVSIVGy6brpN+CoLmI680Kj2EmiJG7yvpNsHKdg==", "integrity": "sha512-MmhVJfBjvjYcZnrJYnDx4VBwpYM6yh7eX4/8szo6sGwzG4E+8V4YBKU2NF6fA6YXpdAyEYayElqXhB0YBEZFJA==",
"requires": { "requires": {
"@walletconnect/types": "^1.7.6", "@walletconnect/types": "^1.7.7",
"@walletconnect/utils": "^1.7.6", "@walletconnect/utils": "^1.7.7",
"eventemitter3": "4.0.7", "eventemitter3": "4.0.7",
"xhr2-cookies": "1.1.0" "xhr2-cookies": "1.1.0"
} }
}, },
"@walletconnect/iso-crypto": { "@walletconnect/iso-crypto": {
"version": "1.7.6", "version": "1.7.7",
"resolved": "https://registry.npmjs.org/@walletconnect/iso-crypto/-/iso-crypto-1.7.6.tgz", "resolved": "https://registry.npmjs.org/@walletconnect/iso-crypto/-/iso-crypto-1.7.7.tgz",
"integrity": "sha512-x80OVfarjPzD02kJgnpmLCxlsFRaymGjlGWzLmtwO8/hp1mrtT/ukFOsl1Fs6Tunp7BdCoJT+9FYFarcvbsG8Q==", "integrity": "sha512-t8RKJZkFtFyWMFrl0jPz/3RAGhM5yext+MLFq3L/KTPxLgMZuT1yFHRUiV7cAN3+LcCmk6Sy/rV1yQPTiB158Q==",
"requires": { "requires": {
"@walletconnect/crypto": "^1.0.2", "@walletconnect/crypto": "^1.0.2",
"@walletconnect/types": "^1.7.6", "@walletconnect/types": "^1.7.7",
"@walletconnect/utils": "^1.7.6" "@walletconnect/utils": "^1.7.7"
} }
}, },
"@walletconnect/jsonrpc-types": { "@walletconnect/jsonrpc-types": {
@ -46097,13 +46106,13 @@
"integrity": "sha512-ZtKRio4uCZ1JUF7LIdecmZt7FOLnX72RPSY7aUVu7mj7CSfxDwUn6gBuK6WGtH+NZCldBqDl5DenI5fFSvkKYw==" "integrity": "sha512-ZtKRio4uCZ1JUF7LIdecmZt7FOLnX72RPSY7aUVu7mj7CSfxDwUn6gBuK6WGtH+NZCldBqDl5DenI5fFSvkKYw=="
}, },
"@walletconnect/qrcode-modal": { "@walletconnect/qrcode-modal": {
"version": "1.7.6", "version": "1.7.7",
"resolved": "https://registry.npmjs.org/@walletconnect/qrcode-modal/-/qrcode-modal-1.7.6.tgz", "resolved": "https://registry.npmjs.org/@walletconnect/qrcode-modal/-/qrcode-modal-1.7.7.tgz",
"integrity": "sha512-SXx8eTllgyGpArwdB8v1WsmAKbxiizqebJLn32C6KRzWVW5FP4FizzgEi+r6xINWSEpWLX72GbeWAoiQDwFVFw==", "integrity": "sha512-HRzw6g4P8/C4ClJYJShaGfdvjfrTfkXv+eb+IylWGWvC8IQhuiSXCq5+F3t0CXxuZs3ir26abgviEMRFQxGKdA==",
"requires": { "requires": {
"@walletconnect/browser-utils": "^1.7.6", "@walletconnect/browser-utils": "^1.7.7",
"@walletconnect/mobile-registry": "^1.4.0", "@walletconnect/mobile-registry": "^1.4.0",
"@walletconnect/types": "^1.7.6", "@walletconnect/types": "^1.7.7",
"copy-to-clipboard": "^3.3.1", "copy-to-clipboard": "^3.3.1",
"preact": "10.4.1", "preact": "10.4.1",
"qrcode": "1.4.4" "qrcode": "1.4.4"
@ -46132,29 +46141,29 @@
"integrity": "sha512-QJzp/S/86sUAgWY6eh5MKYmSfZaRpIlmCJdi5uG4DJlKkZrHEF7ye7gA+VtbVzvTtpM/gRwO2plQuiooIeXjfg==" "integrity": "sha512-QJzp/S/86sUAgWY6eh5MKYmSfZaRpIlmCJdi5uG4DJlKkZrHEF7ye7gA+VtbVzvTtpM/gRwO2plQuiooIeXjfg=="
}, },
"@walletconnect/socket-transport": { "@walletconnect/socket-transport": {
"version": "1.7.6", "version": "1.7.7",
"resolved": "https://registry.npmjs.org/@walletconnect/socket-transport/-/socket-transport-1.7.6.tgz", "resolved": "https://registry.npmjs.org/@walletconnect/socket-transport/-/socket-transport-1.7.7.tgz",
"integrity": "sha512-yH2eKD9P34gnOxOfCarERROl5SkiwBR9UcASjcnp2L7r02ZaXHbhheXHUWzcU5HpEXrvz8DGciE7GBQn+aNgQg==", "integrity": "sha512-RxeFkT+5BqdaZzPtPYIw6+KSVh6Q1NaYqTiAzWWh9RPuvuTajIEsi+fUXizfkpmyi9UTYBvdFXnKcB+eSImpDg==",
"requires": { "requires": {
"@walletconnect/types": "^1.7.6", "@walletconnect/types": "^1.7.7",
"@walletconnect/utils": "^1.7.6", "@walletconnect/utils": "^1.7.7",
"ws": "7.5.3" "ws": "7.5.3"
} }
}, },
"@walletconnect/types": { "@walletconnect/types": {
"version": "1.7.6", "version": "1.7.7",
"resolved": "https://registry.npmjs.org/@walletconnect/types/-/types-1.7.6.tgz", "resolved": "https://registry.npmjs.org/@walletconnect/types/-/types-1.7.7.tgz",
"integrity": "sha512-3JVjEzvJgDc5DzaXNxhg4JcdG4U8Qk6HVBELOu+TwiWG31TZRt82uL9CcVZKieFPP/nTWQnj+QkiKSpO7T1KTQ==" "integrity": "sha512-yXJrLxwLLCXtWgd/e8FjfY9v5DKds12Z7EEPzUrPSq6v7WtXpqate577KwlFQ6UYzioQzIEDE8+98j+0aiZbsw=="
}, },
"@walletconnect/utils": { "@walletconnect/utils": {
"version": "1.7.6", "version": "1.7.7",
"resolved": "https://registry.npmjs.org/@walletconnect/utils/-/utils-1.7.6.tgz", "resolved": "https://registry.npmjs.org/@walletconnect/utils/-/utils-1.7.7.tgz",
"integrity": "sha512-GLneac0Hx52pNHAOkTt/07K+Ht8LmWFaK0nQlHqrLmOJm8WZPnUvMZGMTpSOzgKw47u0cjhE38ipbXOaq8qReA==", "integrity": "sha512-slNlnROS4DEusGFx53hshIBylYhzd5JtGF+AJpza+Tc616+u8ozjQ9aKKUaV85bucnv5Q42bTwLYrYrXiydmuw==",
"requires": { "requires": {
"@walletconnect/browser-utils": "^1.7.6", "@walletconnect/browser-utils": "^1.7.7",
"@walletconnect/encoding": "^1.0.1", "@walletconnect/encoding": "^1.0.1",
"@walletconnect/jsonrpc-utils": "^1.0.0", "@walletconnect/jsonrpc-utils": "^1.0.0",
"@walletconnect/types": "^1.7.6", "@walletconnect/types": "^1.7.7",
"bn.js": "4.11.8", "bn.js": "4.11.8",
"js-sha3": "0.8.0", "js-sha3": "0.8.0",
"query-string": "6.13.5" "query-string": "6.13.5"
@ -46178,15 +46187,15 @@
} }
}, },
"@walletconnect/web3-provider": { "@walletconnect/web3-provider": {
"version": "1.7.6", "version": "1.7.7",
"resolved": "https://registry.npmjs.org/@walletconnect/web3-provider/-/web3-provider-1.7.6.tgz", "resolved": "https://registry.npmjs.org/@walletconnect/web3-provider/-/web3-provider-1.7.7.tgz",
"integrity": "sha512-INjHVTuuISm9rk9QGr8v0IvcmjygEyt+rDB6Iw6G5hK+qwEB+UlrRbXyu0bAmEe4wREpiJmegz7KjiHIxmCTNA==", "integrity": "sha512-hUhDyaMu93e7e82OVCu3KnYOn6m6wQO9YObbhi3PexppCANe/Y9eDrw/37S+7jbjLIx5nS1et2JU+taKR7OSOw==",
"requires": { "requires": {
"@walletconnect/client": "^1.7.6", "@walletconnect/client": "^1.7.7",
"@walletconnect/http-connection": "^1.7.6", "@walletconnect/http-connection": "^1.7.7",
"@walletconnect/qrcode-modal": "^1.7.6", "@walletconnect/qrcode-modal": "^1.7.7",
"@walletconnect/types": "^1.7.6", "@walletconnect/types": "^1.7.7",
"@walletconnect/utils": "^1.7.6", "@walletconnect/utils": "^1.7.7",
"web3-provider-engine": "16.0.1" "web3-provider-engine": "16.0.1"
} }
}, },
@ -60037,26 +60046,26 @@
"integrity": "sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==" "integrity": "sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw=="
}, },
"next": { "next": {
"version": "12.1.0", "version": "12.1.5",
"resolved": "https://registry.npmjs.org/next/-/next-12.1.0.tgz", "resolved": "https://registry.npmjs.org/next/-/next-12.1.5.tgz",
"integrity": "sha512-s885kWvnIlxsUFHq9UGyIyLiuD0G3BUC/xrH0CEnH5lHEWkwQcHOORgbDF0hbrW9vr/7am4ETfX4A7M6DjrE7Q==", "integrity": "sha512-YGHDpyfgCfnT5GZObsKepmRnne7Kzp7nGrac07dikhutWQug7hHg85/+sPJ4ZW5Q2pDkb+n0FnmLkmd44htIJQ==",
"requires": { "requires": {
"@next/env": "12.1.0", "@next/env": "12.1.5",
"@next/swc-android-arm64": "12.1.0", "@next/swc-android-arm-eabi": "12.1.5",
"@next/swc-darwin-arm64": "12.1.0", "@next/swc-android-arm64": "12.1.5",
"@next/swc-darwin-x64": "12.1.0", "@next/swc-darwin-arm64": "12.1.5",
"@next/swc-linux-arm-gnueabihf": "12.1.0", "@next/swc-darwin-x64": "12.1.5",
"@next/swc-linux-arm64-gnu": "12.1.0", "@next/swc-linux-arm-gnueabihf": "12.1.5",
"@next/swc-linux-arm64-musl": "12.1.0", "@next/swc-linux-arm64-gnu": "12.1.5",
"@next/swc-linux-x64-gnu": "12.1.0", "@next/swc-linux-arm64-musl": "12.1.5",
"@next/swc-linux-x64-musl": "12.1.0", "@next/swc-linux-x64-gnu": "12.1.5",
"@next/swc-win32-arm64-msvc": "12.1.0", "@next/swc-linux-x64-musl": "12.1.5",
"@next/swc-win32-ia32-msvc": "12.1.0", "@next/swc-win32-arm64-msvc": "12.1.5",
"@next/swc-win32-x64-msvc": "12.1.0", "@next/swc-win32-ia32-msvc": "12.1.5",
"@next/swc-win32-x64-msvc": "12.1.5",
"caniuse-lite": "^1.0.30001283", "caniuse-lite": "^1.0.30001283",
"postcss": "8.4.5", "postcss": "8.4.5",
"styled-jsx": "5.0.0", "styled-jsx": "5.0.1"
"use-subscription": "1.5.1"
}, },
"dependencies": { "dependencies": {
"postcss": { "postcss": {
@ -61828,9 +61837,9 @@
} }
}, },
"react-chartjs-2": { "react-chartjs-2": {
"version": "4.0.1", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-4.0.1.tgz", "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-4.1.0.tgz",
"integrity": "sha512-q8bgWzKoFvBvD7YcjT/hXG8jt55TaMAuJ1dmI3tKFJ7CijUWYz4pIfOhkTI6PBTwqu/pmeWsClBRd/7HiWzN1g==", "integrity": "sha512-AsUihxEp8Jm1oBhbEovE+w50m9PVNhz1sfwEIT4hZduRC0m14gHWHd0cUaxkFDb8HNkdMIGzsNlmVqKiOpU74g==",
"requires": {} "requires": {}
}, },
"react-clipboard.js": { "react-clipboard.js": {
@ -62007,9 +62016,9 @@
} }
}, },
"react-paginate": { "react-paginate": {
"version": "8.1.2", "version": "8.1.3",
"resolved": "https://registry.npmjs.org/react-paginate/-/react-paginate-8.1.2.tgz", "resolved": "https://registry.npmjs.org/react-paginate/-/react-paginate-8.1.3.tgz",
"integrity": "sha512-buBkBiN9J8gvZYwYNixlTGRmWOC5C6+tH2XHTN8B5qGkRPOSYFkAqxhWUnxSVAeLKxpVZGPya/gOL2eJQNZGvg==", "integrity": "sha512-zBp80DBRcaeBnAeHUfbGKD0XHfbGNUolQ+S60Ymfs8o7rusYaJYZMAt1j93ADDNLlzRmJ0tMF/NeTlcdKf7dlQ==",
"requires": { "requires": {
"prop-types": "^15.6.1" "prop-types": "^15.6.1"
} }
@ -64692,9 +64701,9 @@
} }
}, },
"styled-jsx": { "styled-jsx": {
"version": "5.0.0", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.0.0.tgz", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.0.1.tgz",
"integrity": "sha512-qUqsWoBquEdERe10EW8vLp3jT25s/ssG1/qX5gZ4wu15OZpmSMFI2v+fWlRhLfykA5rFtlJ1ME8A8pm/peV4WA==", "integrity": "sha512-+PIZ/6Uk40mphiQJJI1202b+/dYeTVd9ZnMPR80pgiWbjIwvN2zIp4r9et0BgqBuShh48I0gttPlAXA7WVvBxw==",
"requires": {} "requires": {}
}, },
"supports-color": { "supports-color": {
@ -64840,9 +64849,9 @@
} }
}, },
"swr": { "swr": {
"version": "1.2.2", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/swr/-/swr-1.2.2.tgz", "resolved": "https://registry.npmjs.org/swr/-/swr-1.3.0.tgz",
"integrity": "sha512-ky0BskS/V47GpW8d6RU7CPsr6J8cr7mQD6+do5eky3bM0IyJaoi3vO8UhvrzJaObuTlGhPl2szodeB2dUd76Xw==", "integrity": "sha512-dkghQrOl2ORX9HYrMDtPa7LTVHJjCTeZoB1dqTbnnEDlSvN8JEKpYIYurDfvbQFUUS8Cg8PceFVZNkW0KNNYPw==",
"requires": {} "requires": {}
}, },
"symbol-observable": { "symbol-observable": {
@ -66092,14 +66101,6 @@
"@use-it/event-listener": "^0.1.2" "@use-it/event-listener": "^0.1.2"
} }
}, },
"use-subscription": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.5.1.tgz",
"integrity": "sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA==",
"requires": {
"object-assign": "^4.1.1"
}
},
"utf-8-validate": { "utf-8-validate": {
"version": "5.0.8", "version": "5.0.8",
"resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.8.tgz", "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.8.tgz",
@ -67038,9 +67039,9 @@
} }
}, },
"web3modal": { "web3modal": {
"version": "1.9.5", "version": "1.9.7",
"resolved": "https://registry.npmjs.org/web3modal/-/web3modal-1.9.5.tgz", "resolved": "https://registry.npmjs.org/web3modal/-/web3modal-1.9.7.tgz",
"integrity": "sha512-L5ME6zgoaCDa+T66skW9WpxGOJX6vU9v+7aLacoQJhU3AMTk784ionpX+Pg4UdhdM+UQW+odge32GkwEX11czQ==", "integrity": "sha512-z3XfY7cV8GwGvHP3WvrSxPU6/7ocwVyiU77U/Lxoa53AUSsOKl01V8ErZ8CkJSH41C3YgzwBaOETj0rC9uFBKg==",
"requires": { "requires": {
"detect-browser": "^5.1.0", "detect-browser": "^5.1.0",
"prop-types": "^15.7.2", "prop-types": "^15.7.2",

View File

@ -24,15 +24,14 @@
"@coingecko/cryptoformat": "^0.4.4", "@coingecko/cryptoformat": "^0.4.4",
"@loadable/component": "^5.15.2", "@loadable/component": "^5.15.2",
"@oceanprotocol/art": "^3.2.0", "@oceanprotocol/art": "^3.2.0",
"@oceanprotocol/lib": "^1.0.0-next.35", "@oceanprotocol/lib": "^1.0.0-next.37",
"@oceanprotocol/typographies": "^0.1.0", "@oceanprotocol/typographies": "^0.1.0",
"@portis/web3": "^4.0.7", "@portis/web3": "^4.0.7",
"@storybook/addon-storyshots": "^6.4.22", "@storybook/addon-storyshots": "^6.4.22",
"@tippyjs/react": "^4.2.6", "@tippyjs/react": "^4.2.6",
"@urql/exchange-refocus": "^0.2.5", "@urql/exchange-refocus": "^0.2.5",
"@walletconnect/web3-provider": "^1.7.6", "@walletconnect/web3-provider": "^1.7.7",
"axios": "^0.26.1", "axios": "^0.26.1",
"bignumber.js": "^9.0.2",
"chart.js": "^3.7.1", "chart.js": "^3.7.1",
"classnames": "^2.3.1", "classnames": "^2.3.1",
"date-fns": "^2.28.0", "date-fns": "^2.28.0",
@ -48,29 +47,29 @@
"lodash.debounce": "^4.0.8", "lodash.debounce": "^4.0.8",
"lodash.omit": "^4.5.0", "lodash.omit": "^4.5.0",
"myetherwallet-blockies": "^0.1.1", "myetherwallet-blockies": "^0.1.1",
"next": "^12.1.0", "next": "^12.1.5",
"query-string": "^7.1.1", "query-string": "^7.1.1",
"react": "^17.0.2", "react": "^17.0.2",
"react-chartjs-2": "^4.0.1", "react-chartjs-2": "^4.1.0",
"react-clipboard.js": "^2.0.16", "react-clipboard.js": "^2.0.16",
"react-data-table-component": "^6.11.7", "react-data-table-component": "^6.11.7",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-dotdotdot": "^1.3.1", "react-dotdotdot": "^1.3.1",
"react-modal": "^3.14.4", "react-modal": "^3.14.4",
"react-paginate": "^8.1.2", "react-paginate": "^8.1.3",
"react-spring": "^9.4.4", "react-spring": "^9.4.4",
"react-tabs": "^3.2.3", "react-tabs": "^3.2.3",
"react-toastify": "^8.1.0", "react-toastify": "^8.2.0",
"remark": "^13.0.0", "remark": "^13.0.0",
"remark-gfm": "^1.0.0", "remark-gfm": "^1.0.0",
"remark-html": "^13.0.1", "remark-html": "^13.0.1",
"remove-markdown": "^0.3.0", "remove-markdown": "^0.3.0",
"slugify": "^1.6.5", "slugify": "^1.6.5",
"swr": "^1.2.2", "swr": "^1.3.0",
"urql": "^2.2.0", "urql": "^2.2.0",
"use-dark-mode": "^2.3.1", "use-dark-mode": "^2.3.1",
"web3": "^1.7.1", "web3": "^1.7.3",
"web3modal": "^1.9.5", "web3modal": "^1.9.7",
"yup": "^0.32.11" "yup": "^0.32.11"
}, },
"devDependencies": { "devDependencies": {
@ -85,7 +84,7 @@
"@testing-library/jest-dom": "^5.16.4", "@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^12.1.5", "@testing-library/react": "^12.1.5",
"@testing-library/user-event": "^14.1.1", "@testing-library/user-event": "^14.1.1",
"@types/chart.js": "^2.9.35", "@types/chart.js": "^2.9.37",
"@types/d3": "^7.1.0", "@types/d3": "^7.1.0",
"@types/js-cookie": "^3.0.1", "@types/js-cookie": "^3.0.1",
"@types/loadable__component": "^5.13.1", "@types/loadable__component": "^5.13.1",

View File

@ -11,12 +11,12 @@ import { Config, LoggerInstance, Purgatory } from '@oceanprotocol/lib'
import { CancelToken } from 'axios' import { CancelToken } from 'axios'
import { retrieveAsset } from '@utils/aquarius' import { retrieveAsset } from '@utils/aquarius'
import { useWeb3 } from './Web3' import { useWeb3 } from './Web3'
import { useSiteMetadata } from '@hooks/useSiteMetadata'
import { useCancelToken } from '@hooks/useCancelToken' import { useCancelToken } from '@hooks/useCancelToken'
import { getOceanConfig, getDevelopmentConfig } from '@utils/ocean' import { getOceanConfig, getDevelopmentConfig } from '@utils/ocean'
import { AssetExtended } from 'src/@types/AssetExtended' import { AssetExtended } from 'src/@types/AssetExtended'
import { getAccessDetails } from '@utils/accessDetailsAndPricing' import { getAccessDetails } from '@utils/accessDetailsAndPricing'
import { useIsMounted } from '@hooks/useIsMounted' import { useIsMounted } from '@hooks/useIsMounted'
import { useMarketMetadata } from './MarketMetadata'
interface AssetProviderValue { interface AssetProviderValue {
isInPurgatory: boolean isInPurgatory: boolean
@ -40,7 +40,7 @@ function AssetProvider({
did: string did: string
children: ReactNode children: ReactNode
}): ReactElement { }): ReactElement {
const { appConfig } = useSiteMetadata() const { appConfig } = useMarketMetadata()
const { chainId, accountId } = useWeb3() const { chainId, accountId } = useWeb3()
const [isInPurgatory, setIsInPurgatory] = useState(false) const [isInPurgatory, setIsInPurgatory] = useState(false)

View File

@ -8,7 +8,7 @@ import React, {
} from 'react' } from 'react'
import { deleteCookie, getCookieValue, setCookie } from '@utils/cookies' import { deleteCookie, getCookieValue, setCookie } from '@utils/cookies'
import { UseGdprMetadata, useGdprMetadata } from '@hooks/useGdprMetadata' import { UseGdprMetadata, useGdprMetadata } from '@hooks/useGdprMetadata'
import { useSiteMetadata } from '@hooks/useSiteMetadata' import { useMarketMetadata } from './MarketMetadata'
export enum CookieConsentStatus { export enum CookieConsentStatus {
NOT_AVAILABLE = -1, NOT_AVAILABLE = -1,
@ -32,7 +32,7 @@ const ConsentContext = createContext({} as ConsentProviderValue)
function ConsentProvider({ children }: { children: ReactNode }): ReactElement { function ConsentProvider({ children }: { children: ReactNode }): ReactElement {
const cookies = useGdprMetadata() const cookies = useGdprMetadata()
const { privacyPreferenceCenter } = useSiteMetadata().appConfig const { appConfig } = useMarketMetadata()
const [consentStatus, setConsentStatus] = useState({} as ConsentStatus) const [consentStatus, setConsentStatus] = useState({} as ConsentStatus)
@ -80,7 +80,7 @@ function ConsentProvider({ children }: { children: ReactNode }): ReactElement {
} }
useEffect(() => { useEffect(() => {
if (privacyPreferenceCenter !== 'true') return if (appConfig?.privacyPreferenceCenter !== 'true') return
const initialValues = {} as ConsentStatus const initialValues = {} as ConsentStatus
cookies.optionalCookies?.map((cookie) => { cookies.optionalCookies?.map((cookie) => {
@ -100,8 +100,7 @@ function ConsentProvider({ children }: { children: ReactNode }): ReactElement {
}) })
setConsentStatus(initialValues) setConsentStatus(initialValues)
// eslint-disable-next-line react-hooks/exhaustive-deps }, [cookies.optionalCookies, appConfig])
}, [])
useEffect(() => { useEffect(() => {
Object.keys(consentStatus).map((cookieName) => { Object.keys(consentStatus).map((cookieName) => {

View File

@ -0,0 +1,12 @@
import { gql } from 'urql'
export const opcQuery = gql`
query OpcQuery {
opc(id: 1) {
swapOceanFee
swapNonOceanFee
approvedTokens
id
}
}
`

View File

@ -0,0 +1,58 @@
export interface OpcFee {
chainId: number
swapNotApprovedFee: string
swapApprovedFee: string
approvedTokens: string[]
}
export interface AppConfig {
metadataCacheUri: string
infuraProjectId: string
chainIds: number[]
chainIdsSupported: number[]
marketFeeAddress: string
publisherMarketOrderFee: string
publisherMarketPoolSwapFee: string
publisherMarketFixedSwapFee: string
consumeMarketOrderFee: string
consumeMarketPoolSwapFee: string
consumeMarketFixedSwapFee: string
currencies: string[]
portisId: string
allowFixedPricing: string
allowDynamicPricing: string
allowFreePricing: string
defaultPrivacyPolicySlug: string
privacyPreferenceCenter: string
darkModeConfig: {
classNameDark: string
classNameLight: string
storageKey: string
}
}
export interface SiteContent {
siteTitle: string
siteTagline: string
siteUrl: string
siteImage: string
copyright: string
menu: {
name: string
link: string
}[]
warning: {
main: string
polygonPublish: string
}
announcement: {
main: string
polygon: string
}
}
export interface MarketMetadataProviderValue {
opcFees: OpcFee[]
siteContent: SiteContent
appConfig: AppConfig
getOpcFeeForToken: (tokenAddress: string, chainId: number) => string
}

View File

@ -0,0 +1,80 @@
import React, {
createContext,
ReactElement,
ReactNode,
useCallback,
useContext,
useEffect,
useState
} from 'react'
import { OpcQuery } from 'src/@types/subgraph/OpcQuery'
import { OperationResult } from 'urql'
import { opcQuery } from './_queries'
import { MarketMetadataProviderValue, OpcFee } from './_types'
import siteContent from '../../../content/site.json'
import appConfig from '../../../app.config'
import { fetchData, getQueryContext } from '@utils/subgraph'
const MarketMetadataContext = createContext({} as MarketMetadataProviderValue)
function MarketMetadataProvider({
children
}: {
children: ReactNode
}): ReactElement {
const [opcFees, setOpcFees] = useState<OpcFee[]>()
useEffect(() => {
async function getOpcData() {
const opcData = []
for (let i = 0; i < appConfig.chainIdsSupported.length; i++) {
const response: OperationResult<OpcQuery> = await fetchData(
opcQuery,
null,
getQueryContext(appConfig.chainIdsSupported[i])
)
opcData.push({
chainId: appConfig.chainIdsSupported[i],
approvedTokens: response.data?.opc.approvedTokens,
swapApprovedFee: response.data?.opc.swapOceanFee,
swapNotApprovedFee: response.data.opc.swapNonOceanFee
} as OpcFee)
}
setOpcFees(opcData)
}
getOpcData()
}, [])
const getOpcFeeForToken = useCallback(
(tokenAddress: string, chainId: number): string => {
if (!opcFees) return '0'
const opc = opcFees.filter((x) => x.chainId === chainId)[0]
const isTokenApproved = opc.approvedTokens.includes(tokenAddress)
return isTokenApproved ? opc.swapApprovedFee : opc.swapNotApprovedFee
},
[opcFees]
)
return (
<MarketMetadataContext.Provider
value={
{
opcFees,
siteContent,
appConfig,
getOpcFeeForToken
} as MarketMetadataProviderValue
}
>
{children}
</MarketMetadataContext.Provider>
)
}
// Helper hook to access the provider values
const useMarketMetadata = (): MarketMetadataProviderValue =>
useContext(MarketMetadataContext)
export { MarketMetadataProvider, useMarketMetadata, MarketMetadataContext }
export default MarketMetadataProvider

View File

@ -1,4 +1,3 @@
import Decimal from 'decimal.js'
import { import {
PoolData_poolSnapshots as PoolDataPoolSnapshots, PoolData_poolSnapshots as PoolDataPoolSnapshots,
PoolData_poolData as PoolDataPoolData PoolData_poolData as PoolDataPoolData
@ -15,13 +14,12 @@ export interface PoolInfo {
baseTokenSymbol: string baseTokenSymbol: string
baseTokenAddress: string baseTokenAddress: string
totalPoolTokens: string totalPoolTokens: string
totalLiquidityInOcean: Decimal
} }
export interface PoolInfoUser { export interface PoolInfoUser {
liquidity: Decimal // liquidity in base token liquidity: string
poolShares: string // pool share tokens poolShares: string
poolShare: string // in % poolSharePercentage: string
} }
export interface PoolProviderValue { export interface PoolProviderValue {
@ -31,7 +29,6 @@ export interface PoolProviderValue {
poolInfoUser: PoolInfoUser poolInfoUser: PoolInfoUser
poolSnapshots: PoolDataPoolSnapshots[] poolSnapshots: PoolDataPoolSnapshots[]
hasUserAddedLiquidity: boolean hasUserAddedLiquidity: boolean
isRemoveDisabled: boolean
refreshInterval: number refreshInterval: number
fetchAllData: () => void fetchAllData: () => void
} }

View File

@ -1,5 +1,4 @@
import { LoggerInstance, Pool } from '@oceanprotocol/lib' import { LoggerInstance } from '@oceanprotocol/lib'
import { isValidNumber } from '@utils/numbers'
import Decimal from 'decimal.js' import Decimal from 'decimal.js'
import React, { import React, {
useContext, useContext,
@ -16,22 +15,17 @@ import {
} from 'src/@types/subgraph/PoolData' } from 'src/@types/subgraph/PoolData'
import { useAsset } from '../Asset' import { useAsset } from '../Asset'
import { useWeb3 } from '../Web3' import { useWeb3 } from '../Web3'
import { calculateSharesVL } from '@utils/pool' import { calcSingleOutGivenPoolIn } from '@utils/pool'
import { PoolProviderValue, PoolInfo, PoolInfoUser } from './_types' import { PoolProviderValue, PoolInfo, PoolInfoUser } from './_types'
import { getFee, getPoolData, getWeight } from './_utils' import { getFee, getPoolData, getWeight } from './_utils'
import { useMarketMetadata } from '@context/MarketMetadata'
Decimal.set({ toExpNeg: -18, precision: 18, rounding: 1 })
const PoolContext = createContext({} as PoolProviderValue) const PoolContext = createContext({} as PoolProviderValue)
const refreshInterval = 10000 // 10 sec. const refreshInterval = 10000 // 10 sec.
const initialPoolInfo: Partial<PoolInfo> = {
totalLiquidityInOcean: new Decimal(0)
}
const initialPoolInfoUser: Partial<PoolInfoUser> = { const initialPoolInfoUser: Partial<PoolInfoUser> = {
liquidity: new Decimal(0), liquidity: '0',
poolShares: '0' poolShares: '0'
} }
@ -39,12 +33,10 @@ const initialPoolInfoCreator: Partial<PoolInfoUser> = initialPoolInfoUser
function PoolProvider({ children }: { children: ReactNode }): ReactElement { function PoolProvider({ children }: { children: ReactNode }): ReactElement {
const { accountId, web3, chainId } = useWeb3() const { accountId, web3, chainId } = useWeb3()
const { isInPurgatory, asset, owner } = useAsset() const { asset, owner } = useAsset()
const { getOpcFeeForToken } = useMarketMetadata()
const [poolData, setPoolData] = useState<PoolDataPoolData>() const [poolData, setPoolData] = useState<PoolDataPoolData>()
const [poolInfo, setPoolInfo] = useState<PoolInfo>( const [poolInfo, setPoolInfo] = useState<PoolInfo>()
initialPoolInfo as PoolInfo
)
const [poolInfoOwner, setPoolInfoOwner] = useState<PoolInfoUser>( const [poolInfoOwner, setPoolInfoOwner] = useState<PoolInfoUser>(
initialPoolInfoCreator as PoolInfoUser initialPoolInfoCreator as PoolInfoUser
) )
@ -53,10 +45,7 @@ function PoolProvider({ children }: { children: ReactNode }): ReactElement {
) )
const [poolSnapshots, setPoolSnapshots] = useState<PoolDataPoolSnapshots[]>() const [poolSnapshots, setPoolSnapshots] = useState<PoolDataPoolSnapshots[]>()
const [hasUserAddedLiquidity, setUserHasAddedLiquidity] = useState(false) const [hasUserAddedLiquidity, setUserHasAddedLiquidity] = useState(false)
const [isRemoveDisabled, setIsRemoveDisabled] = useState(false)
// const [fetchInterval, setFetchInterval] = useState<NodeJS.Timeout>() // const [fetchInterval, setFetchInterval] = useState<NodeJS.Timeout>()
const [ownerPoolShares, setOwnerPoolShares] = useState('0')
const [userPoolShares, setUserPoolShares] = useState('0')
const fetchAllData = useCallback(async () => { const fetchAllData = useCallback(async () => {
if (!asset?.chainId || !asset?.accessDetails?.addressOrId || !owner) return if (!asset?.chainId || !asset?.accessDetails?.addressOrId || !owner) return
@ -87,8 +76,11 @@ function PoolProvider({ children }: { children: ReactNode }): ReactElement {
// //
useEffect(() => { useEffect(() => {
if (asset?.accessDetails?.type !== 'dynamic') return if (asset?.accessDetails?.type !== 'dynamic') return
fetchAllData() fetchAllData()
const interval = setInterval(() => {
fetchAllData()
}, refreshInterval)
return () => clearInterval(interval)
}, [fetchAllData, asset?.accessDetails?.type]) }, [fetchAllData, asset?.accessDetails?.type])
// //
@ -97,37 +89,24 @@ function PoolProvider({ children }: { children: ReactNode }): ReactElement {
useEffect(() => { useEffect(() => {
if (!poolData) return if (!poolData) return
// once we have poolData, we need to get owner's pool shares (OVL)
calculateSharesVL(
poolData.id,
poolData.baseToken.address,
poolData.shares[0].shares,
asset.chainId
).then((shares) => {
setOwnerPoolShares(shares)
})
// Total Liquidity
const totalLiquidityInOcean = new Decimal(
poolData.baseTokenLiquidity * 2 || 0
)
const newPoolInfo = { const newPoolInfo = {
liquidityProviderSwapFee: getFee(poolData.liquidityProviderSwapFee), liquidityProviderSwapFee: getFee(poolData.liquidityProviderSwapFee),
publishMarketSwapFee: getFee(poolData.publishMarketSwapFee), publishMarketSwapFee: getFee(poolData.publishMarketSwapFee),
opcFee: getFee(poolData.opcFee), opcFee: getFee(
getOpcFeeForToken(poolData.baseToken.address, asset?.chainId)
),
weightBaseToken: getWeight(poolData.baseTokenWeight), weightBaseToken: getWeight(poolData.baseTokenWeight),
weightDt: getWeight(poolData.datatokenWeight), weightDt: getWeight(poolData.datatokenWeight),
datatokenSymbol: poolData.datatoken.symbol, datatokenSymbol: poolData.datatoken.symbol,
datatokenAddress: poolData.datatoken.address, datatokenAddress: poolData.datatoken.address,
baseTokenSymbol: poolData.baseToken.symbol, baseTokenSymbol: poolData.baseToken.symbol,
baseTokenAddress: poolData.baseToken.address, baseTokenAddress: poolData.baseToken.address,
totalPoolTokens: poolData.totalShares, totalPoolTokens: poolData.totalShares
totalLiquidityInOcean
} }
setPoolInfo(newPoolInfo) setPoolInfo(newPoolInfo)
LoggerInstance.log('[pool] Created new pool info:', newPoolInfo) LoggerInstance.log('[pool] Created new pool info:', newPoolInfo)
}, [asset?.chainId, chainId, poolData, web3]) }, [asset?.chainId, chainId, getOpcFeeForToken, poolData, web3])
// //
// 2 Pool Creator Info // 2 Pool Creator Info
@ -136,29 +115,34 @@ function PoolProvider({ children }: { children: ReactNode }): ReactElement {
if ( if (
!poolData || !poolData ||
!poolInfo?.totalPoolTokens || !poolInfo?.totalPoolTokens ||
!poolInfo.totalLiquidityInOcean || poolData.shares[0]?.shares === '0'
ownerPoolShares === '0'
) )
return return
// Pool share tokens. // Pool share tokens.
const poolShare = new Decimal(ownerPoolShares) const poolSharePercentage = new Decimal(poolData.shares[0]?.shares)
.dividedBy(poolInfo.totalLiquidityInOcean) .dividedBy(poolInfo.totalPoolTokens)
.mul(100) .mul(100)
.toFixed(2) .toFixed(2)
const ownerLiquidity = calcSingleOutGivenPoolIn(
poolData.baseTokenLiquidity,
poolData.totalShares,
poolData?.shares[0]?.shares
)
const newPoolOwnerInfo = { const newPoolOwnerInfo = {
liquidity: new Decimal(ownerPoolShares), // liquidity in base token, values from from `calcSingleOutGivenPoolIn` method liquidity: ownerLiquidity,
poolShares: ownerPoolShares, poolShares: poolData.shares[0]?.shares,
poolShare poolSharePercentage
} }
setPoolInfoOwner(newPoolOwnerInfo) setPoolInfoOwner(newPoolOwnerInfo)
LoggerInstance.log('[pool] Created new owner pool info:', newPoolOwnerInfo) LoggerInstance.log('[pool] Created new pool creatorinfo:', newPoolOwnerInfo)
}, [ }, [
ownerPoolShares, asset?.chainId,
poolData, poolData,
poolInfo.totalLiquidityInOcean, poolInfo?.baseTokenAddress,
poolInfo.totalPoolTokens poolInfo?.totalPoolTokens
]) ])
// //
@ -169,35 +153,29 @@ function PoolProvider({ children }: { children: ReactNode }): ReactElement {
!poolData || !poolData ||
!poolInfo?.totalPoolTokens || !poolInfo?.totalPoolTokens ||
!poolInfoUser?.poolShares || !poolInfoUser?.poolShares ||
!poolInfo?.totalLiquidityInOcean ||
!poolData?.baseTokenLiquidity || !poolData?.baseTokenLiquidity ||
!asset?.chainId || !asset?.chainId
!accountId ||
!poolInfoUser
) )
return return
// once we have poolData, we need to get user's pool shares (VL) const userLiquidity = calcSingleOutGivenPoolIn(
calculateSharesVL( poolData.baseTokenLiquidity,
poolData.id, poolData.totalShares,
poolData.baseToken.address, poolInfoUser.poolShares
poolInfoUser.poolShares, )
asset.chainId
).then((shares) => {
setUserPoolShares(shares)
})
// Pool share in %. // Pool share in %.
const poolShare = new Decimal(userPoolShares) const poolSharePercentage = new Decimal(poolInfoUser.poolShares)
.dividedBy(new Decimal(poolInfo.totalLiquidityInOcean)) .dividedBy(new Decimal(poolInfo.totalPoolTokens))
.mul(100) .mul(100)
.toFixed(2) .toFixed(2)
setUserHasAddedLiquidity(Number(poolShare) > 0) setUserHasAddedLiquidity(Number(poolSharePercentage) > 0)
const newPoolInfoUser = { const newPoolInfoUser: PoolInfoUser = {
liquidity: new Decimal(userPoolShares), // liquidity in base token, values from from `calcSingleOutGivenPoolIn` method liquidity: userLiquidity,
poolShare poolShares: poolInfoUser.poolShares,
poolSharePercentage
} }
setPoolInfoUser((prevState: PoolInfoUser) => ({ setPoolInfoUser((prevState: PoolInfoUser) => ({
...prevState, ...prevState,
@ -205,29 +183,16 @@ function PoolProvider({ children }: { children: ReactNode }): ReactElement {
})) }))
LoggerInstance.log('[pool] Created new user pool info:', { LoggerInstance.log('[pool] Created new user pool info:', {
poolShares: userPoolShares,
...newPoolInfoUser ...newPoolInfoUser
}) })
// poolInfoUser was not added on purpose, we use setPoolInfoUser so it will just loop
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [ }, [
poolData, poolData,
poolInfoUser?.poolShares, poolInfoUser?.poolShares,
accountId,
userPoolShares,
asset?.chainId, asset?.chainId,
owner, owner,
poolInfo?.totalPoolTokens poolInfo?.totalPoolTokens
]) ])
//
// Check if removing liquidity should be disabled.
//
useEffect(() => {
if (!owner || !accountId) return
setIsRemoveDisabled(isInPurgatory && owner === accountId)
}, [isInPurgatory, owner, accountId])
return ( return (
<PoolContext.Provider <PoolContext.Provider
value={ value={
@ -238,7 +203,6 @@ function PoolProvider({ children }: { children: ReactNode }): ReactElement {
poolInfoUser, poolInfoUser,
poolSnapshots, poolSnapshots,
hasUserAddedLiquidity, hasUserAddedLiquidity,
isRemoveDisabled,
refreshInterval, refreshInterval,
fetchAllData fetchAllData
} as PoolProviderValue } as PoolProviderValue

View File

@ -3,12 +3,13 @@ import React, {
ReactElement, ReactElement,
createContext, createContext,
useContext, useContext,
ReactNode ReactNode,
useEffect
} from 'react' } from 'react'
import { fetchData } from '@utils/fetch' import { fetchData } from '@utils/fetch'
import useSWR from 'swr' import useSWR from 'swr'
import { useSiteMetadata } from '@hooks/useSiteMetadata'
import { LoggerInstance } from '@oceanprotocol/lib' import { LoggerInstance } from '@oceanprotocol/lib'
import { useMarketMetadata } from './MarketMetadata'
interface Prices { interface Prices {
[key: string]: number [key: string]: number
@ -34,12 +35,19 @@ export default function PricesProvider({
}: { }: {
children: ReactNode children: ReactNode
}): ReactElement { }): ReactElement {
const { appConfig } = useSiteMetadata() const { appConfig } = useMarketMetadata()
const tokenId = 'ocean-protocol' const tokenId = 'ocean-protocol'
const currencies = appConfig.currencies.join(',') // comma-separated list
const url = `https://api.coingecko.com/api/v3/simple/price?ids=${tokenId}&vs_currencies=${currencies}`
const [prices, setPrices] = useState(initialData) const [prices, setPrices] = useState(initialData)
const [url, setUrl] = useState('')
useEffect(() => {
if (!appConfig) return
// comma-separated list
const currencies = appConfig.currencies.join(',')
const url = `https://api.coingecko.com/api/v3/simple/price?ids=${tokenId}&vs_currencies=${currencies}`
setUrl(url)
}, [appConfig])
const onSuccess = async (data: { [tokenId]: Prices }) => { const onSuccess = async (data: { [tokenId]: Prices }) => {
if (!data) return if (!data) return

View File

@ -16,11 +16,11 @@ import { useUserPreferences } from './UserPreferences'
import { PoolShares_poolShares as PoolShare } from '../@types/subgraph/PoolShares' import { PoolShares_poolShares as PoolShare } from '../@types/subgraph/PoolShares'
import { Asset, LoggerInstance } from '@oceanprotocol/lib' import { Asset, LoggerInstance } from '@oceanprotocol/lib'
import { getDownloadAssets, getPublishedAssets } from '@utils/aquarius' import { getDownloadAssets, getPublishedAssets } from '@utils/aquarius'
import { useSiteMetadata } from '@hooks/useSiteMetadata'
import { accountTruncate } from '@utils/web3' import { accountTruncate } from '@utils/web3'
import axios, { CancelToken } from 'axios' import axios, { CancelToken } from 'axios'
import get3BoxProfile from '@utils/profile' import get3BoxProfile from '@utils/profile'
import web3 from 'web3' import web3 from 'web3'
import { useMarketMetadata } from './MarketMetadata'
interface ProfileProviderValue { interface ProfileProviderValue {
profile: Profile profile: Profile
@ -49,7 +49,7 @@ function ProfileProvider({
children: ReactNode children: ReactNode
}): ReactElement { }): ReactElement {
const { chainIds } = useUserPreferences() const { chainIds } = useUserPreferences()
const { appConfig } = useSiteMetadata() const { appConfig } = useMarketMetadata()
const [isEthAddress, setIsEthAddress] = useState<boolean>() const [isEthAddress, setIsEthAddress] = useState<boolean>()

View File

@ -8,7 +8,7 @@ import React, {
} from 'react' } from 'react'
import { LoggerInstance, LogLevel } from '@oceanprotocol/lib' import { LoggerInstance, LogLevel } from '@oceanprotocol/lib'
import { isBrowser } from '@utils/index' import { isBrowser } from '@utils/index'
import { useSiteMetadata } from '@hooks/useSiteMetadata' import { useMarketMetadata } from './MarketMetadata'
interface UserPreferencesValue { interface UserPreferencesValue {
debug: boolean debug: boolean
@ -51,9 +51,8 @@ function UserPreferencesProvider({
}: { }: {
children: ReactNode children: ReactNode
}): ReactElement { }): ReactElement {
const { appConfig } = useSiteMetadata() const { appConfig } = useMarketMetadata()
const localStorage = getLocalStorage() const localStorage = getLocalStorage()
// Set default values from localStorage // Set default values from localStorage
const [debug, setDebug] = useState<boolean>(localStorage?.debug || false) const [debug, setDebug] = useState<boolean>(localStorage?.debug || false)
const [currency, setCurrency] = useState<string>( const [currency, setCurrency] = useState<string>(
@ -64,7 +63,7 @@ function UserPreferencesProvider({
const [chainIds, setChainIds] = useState( const [chainIds, setChainIds] = useState(
localStorage?.chainIds || appConfig.chainIds localStorage?.chainIds || appConfig.chainIds
) )
const { defaultPrivacyPolicySlug } = useSiteMetadata().appConfig const { defaultPrivacyPolicySlug } = appConfig
const [privacyPolicySlug, setPrivacyPolicySlug] = useState<string>( const [privacyPolicySlug, setPrivacyPolicySlug] = useState<string>(
localStorage?.privacyPolicySlug || defaultPrivacyPolicySlug localStorage?.privacyPolicySlug || defaultPrivacyPolicySlug

View File

@ -21,6 +21,7 @@ import useNetworkMetadata, {
getNetworkType, getNetworkType,
NetworkType NetworkType
} from '../@hooks/useNetworkMetadata' } from '../@hooks/useNetworkMetadata'
import { useMarketMetadata } from './MarketMetadata'
interface Web3ProviderValue { interface Web3ProviderValue {
web3: Web3 web3: Web3
@ -37,6 +38,7 @@ interface Web3ProviderValue {
block: number block: number
isTestnet: boolean isTestnet: boolean
web3Loading: boolean web3Loading: boolean
isSupportedOceanNetwork: boolean
connect: () => Promise<void> connect: () => Promise<void>
logout: () => Promise<void> logout: () => Promise<void>
} }
@ -88,6 +90,7 @@ const Web3Context = createContext({} as Web3ProviderValue)
function Web3Provider({ children }: { children: ReactNode }): ReactElement { function Web3Provider({ children }: { children: ReactNode }): ReactElement {
const { networksList } = useNetworkMetadata() const { networksList } = useNetworkMetadata()
const { appConfig } = useMarketMetadata()
const [web3, setWeb3] = useState<Web3>() const [web3, setWeb3] = useState<Web3>()
const [web3Provider, setWeb3Provider] = useState<any>() const [web3Provider, setWeb3Provider] = useState<any>()
@ -106,6 +109,7 @@ function Web3Provider({ children }: { children: ReactNode }): ReactElement {
eth: '0', eth: '0',
ocean: '0' ocean: '0'
}) })
const [isSupportedOceanNetwork, setIsSupportedOceanNetwork] = useState(true)
// ----------------------------------- // -----------------------------------
// Helper: connect to web3 // Helper: connect to web3
@ -304,6 +308,17 @@ function Web3Provider({ children }: { children: ReactNode }): ReactElement {
} }
await web3Modal.clearCachedProvider() await web3Modal.clearCachedProvider()
} }
// -----------------------------------
// Get valid Networks and set isSupportedOceanNetwork
// -----------------------------------
useEffect(() => {
if (appConfig.chainIdsSupported.includes(networkId)) {
setIsSupportedOceanNetwork(true)
} else {
setIsSupportedOceanNetwork(false)
}
}, [networkId, appConfig.chainIdsSupported])
// ----------------------------------- // -----------------------------------
// Handle change events // Handle change events
@ -358,6 +373,7 @@ function Web3Provider({ children }: { children: ReactNode }): ReactElement {
block, block,
isTestnet, isTestnet,
web3Loading, web3Loading,
isSupportedOceanNetwork,
connect, connect,
logout logout
}} }}

View File

@ -1,6 +0,0 @@
import { UseSiteMetadata } from './types'
import { getSiteMetadata } from '@utils/siteConfig'
export function useSiteMetadata(): UseSiteMetadata {
return getSiteMetadata()
}

View File

@ -1,44 +0,0 @@
export interface UseSiteMetadata {
siteTitle: string
siteTagline: string
siteUrl: string
siteImage: string
copyright: string
menu: {
name: string
link: string
}[]
warning: {
main: string
polygonPublish: string
}
announcement: {
main: string
polygon: string
}
appConfig: {
metadataCacheUri: string
infuraProjectId: string
chainIds: number[]
chainIdsSupported: number[]
marketFeeAddress: string
publisherMarketOrderFee: string
publisherMarketPoolSwapFee: string
publisherMarketFixedSwapFee: string
consumeMarketOrderFee: string
consumeMarketPoolSwapFee: string
consumeMarketFixedSwapFee: string
currencies: string[]
portisId: string
allowFixedPricing: string
allowDynamicPricing: string
allowFreePricing: string
defaultPrivacyPolicySlug: string
privacyPreferenceCenter: string
darkModeConfig: {
classNameDark: string
classNameLight: string
storageKey: string
}
}
}

9
src/@types/Utils.d.ts vendored Normal file
View File

@ -0,0 +1,9 @@
interface CalcInGivenOutParams {
tokenInLiquidity: string
tokenOutLiquidity: string
tokenOutAmount: string
opcFee: string
lpSwapFee: string
publishMarketSwapFee: string
consumeMarketSwapFee: string
}

View File

@ -10,11 +10,11 @@ import {
} from '../@types/subgraph/TokensPriceQuery' } from '../@types/subgraph/TokensPriceQuery'
import { Asset, LoggerInstance, ProviderInstance } from '@oceanprotocol/lib' import { Asset, LoggerInstance, ProviderInstance } from '@oceanprotocol/lib'
import { AssetExtended } from 'src/@types/AssetExtended' import { AssetExtended } from 'src/@types/AssetExtended'
import { calculateBuyPrice } from './pool' import { calcInGivenOut } from './pool'
import { getFixedBuyPrice } from './fixedRateExchange' import { getFixedBuyPrice } from './fixedRateExchange'
import { getSiteMetadata } from './siteConfig'
import { AccessDetails, OrderPriceAndFees } from 'src/@types/Price' import { AccessDetails, OrderPriceAndFees } from 'src/@types/Price'
import Decimal from 'decimal.js' import Decimal from 'decimal.js'
import { consumeMarketOrderFee } from '../../app.config'
const TokensPriceQuery = gql` const TokensPriceQuery = gql`
query TokensPriceQuery($datatokenIds: [ID!], $account: String) { query TokensPriceQuery($datatokenIds: [ID!], $account: String) {
@ -229,17 +229,16 @@ function getAccessDetailsFromTokenPrice(
*/ */
export async function getOrderPriceAndFees( export async function getOrderPriceAndFees(
asset: AssetExtended, asset: AssetExtended,
accountId: string accountId: string,
paramsForPool: CalcInGivenOutParams
): Promise<OrderPriceAndFees> { ): Promise<OrderPriceAndFees> {
const { appConfig } = getSiteMetadata()
const orderPriceAndFee = { const orderPriceAndFee = {
price: '0', price: '0',
publisherMarketOrderFee: publisherMarketOrderFee:
asset?.accessDetails?.publisherMarketOrderFee || '0', asset?.accessDetails?.publisherMarketOrderFee || '0',
publisherMarketPoolSwapFee: '0', publisherMarketPoolSwapFee: '0',
publisherMarketFixedSwapFee: '0', publisherMarketFixedSwapFee: '0',
consumeMarketOrderFee: appConfig.consumeMarketOrderFee || '0', consumeMarketOrderFee: consumeMarketOrderFee || '0',
consumeMarketPoolSwapFee: '0', consumeMarketPoolSwapFee: '0',
consumeMarketFixedSwapFee: '0', consumeMarketFixedSwapFee: '0',
providerFee: { providerFee: {
@ -261,10 +260,7 @@ export async function getOrderPriceAndFees(
// fetch price and swap fees // fetch price and swap fees
switch (asset?.accessDetails?.type) { switch (asset?.accessDetails?.type) {
case 'dynamic': { case 'dynamic': {
const poolPrice = await calculateBuyPrice( const poolPrice = calcInGivenOut(paramsForPool)
asset?.accessDetails,
asset?.chainId
)
orderPriceAndFee.price = poolPrice.tokenAmount orderPriceAndFee.price = poolPrice.tokenAmount
orderPriceAndFee.liquidityProviderSwapFee = orderPriceAndFee.liquidityProviderSwapFee =
poolPrice.liquidityProviderSwapFeeAmount poolPrice.liquidityProviderSwapFeeAmount
@ -279,7 +275,6 @@ export async function getOrderPriceAndFees(
orderPriceAndFee.price = fixed.baseTokenAmount orderPriceAndFee.price = fixed.baseTokenAmount
orderPriceAndFee.opcFee = fixed.oceanFeeAmount orderPriceAndFee.opcFee = fixed.oceanFeeAmount
orderPriceAndFee.publisherMarketFixedSwapFee = fixed.marketFeeAmount orderPriceAndFee.publisherMarketFixedSwapFee = fixed.marketFeeAmount
// hack because we don't have it in contracts
orderPriceAndFee.consumeMarketFixedSwapFee = fixed.consumeMarketFeeAmount orderPriceAndFee.consumeMarketFixedSwapFee = fixed.consumeMarketFeeAmount
break break

View File

@ -30,3 +30,9 @@ export function randomIntFromInterval(min: number, max: number): number {
// min and max are included // min and max are included
return Math.floor(Math.random() * (max - min + 1) + min) return Math.floor(Math.random() * (max - min + 1) + min)
} }
export function getMaxDecimalsValidation(max: number): RegExp {
// eslint-disable-next-line security/detect-non-literal-regexp
const maxDecimalsValidation = new RegExp('^\\d+(\\.\\d{1,' + max + '})?$')
return maxDecimalsValidation
}

View File

@ -9,8 +9,12 @@ import { AssetExtended } from 'src/@types/AssetExtended'
import Web3 from 'web3' import Web3 from 'web3'
import { getOceanConfig } from './ocean' import { getOceanConfig } from './ocean'
import { TransactionReceipt } from 'web3-eth' import { TransactionReceipt } from 'web3-eth'
import { getSiteMetadata } from './siteConfig'
import { OrderPriceAndFees } from 'src/@types/Price' import { OrderPriceAndFees } from 'src/@types/Price'
import {
marketFeeAddress,
consumeMarketOrderFee,
consumeMarketFixedSwapFee
} from '../../app.config'
/** /**
* For pool you need to buy the datatoken beforehand, this always assumes you want to order the first service * For pool you need to buy the datatoken beforehand, this always assumes you want to order the first service
@ -27,7 +31,6 @@ export async function order(
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
const datatoken = new Datatoken(web3) const datatoken = new Datatoken(web3)
const config = getOceanConfig(asset.chainId) const config = getOceanConfig(asset.chainId)
const { appConfig } = getSiteMetadata()
const initializeData = await ProviderInstance.initialize( const initializeData = await ProviderInstance.initialize(
asset.id, asset.id,
@ -42,8 +45,8 @@ export async function order(
serviceIndex: 0, serviceIndex: 0,
_providerFee: initializeData.providerFee, _providerFee: initializeData.providerFee,
_consumeMarketFee: { _consumeMarketFee: {
consumeMarketFeeAddress: appConfig.marketFeeAddress, consumeMarketFeeAddress: marketFeeAddress,
consumeMarketFeeAmount: appConfig.consumeMarketOrderFee, consumeMarketFeeAmount: consumeMarketOrderFee,
consumeMarketFeeToken: config.oceanTokenAddress consumeMarketFeeToken: config.oceanTokenAddress
} }
} as OrderParams } as OrderParams
@ -68,8 +71,8 @@ export async function order(
exchangeContract: config.fixedRateExchangeAddress, exchangeContract: config.fixedRateExchangeAddress,
exchangeId: asset.accessDetails.addressOrId, exchangeId: asset.accessDetails.addressOrId,
maxBaseTokenAmount: orderPriceAndFees.price, maxBaseTokenAmount: orderPriceAndFees.price,
swapMarketFee: appConfig.consumeMarketFixedSwapFee, swapMarketFee: consumeMarketFixedSwapFee,
marketFeeAddress: appConfig.marketFeeAddress marketFeeAddress
} as FreOrderParams } as FreOrderParams
const tx = await datatoken.buyFromFreAndOrder( const tx = await datatoken.buyFromFreAndOrder(
asset.accessDetails.datatoken.address, asset.accessDetails.datatoken.address,

View File

@ -1,12 +1,11 @@
import { approve, Pool, PoolPriceAndFees } from '@oceanprotocol/lib' import { approve, Pool, PoolPriceAndFees } from '@oceanprotocol/lib'
import Web3 from 'web3' import Web3 from 'web3'
import { getSiteMetadata } from './siteConfig'
import { getDummyWeb3 } from './web3' import { getDummyWeb3 } from './web3'
import { TransactionReceipt } from 'web3-eth' import { TransactionReceipt } from 'web3-eth'
import Decimal from 'decimal.js' import Decimal from 'decimal.js'
import { AccessDetails } from 'src/@types/Price' import { AccessDetails } from 'src/@types/Price'
import { isValidNumber } from './numbers' import { consumeMarketPoolSwapFee, marketFeeAddress } from '../../app.config'
import { MAX_DECIMALS } from './constants'
/** /**
* This is used to calculate the price to buy one datatoken from a pool, that is different from spot price. You need to pass either a web3 object or a chainId. If you pass a chainId a dummy web3 object will be created * This is used to calculate the price to buy one datatoken from a pool, that is different from spot price. You need to pass either a web3 object or a chainId. If you pass a chainId a dummy web3 object will be created
* @param {AccessDetails} accessDetails * @param {AccessDetails} accessDetails
@ -27,13 +26,13 @@ export async function calculateBuyPrice(
} }
const pool = new Pool(web3) const pool = new Pool(web3)
const { appConfig } = getSiteMetadata()
const estimatedPrice = await pool.getAmountInExactOut( const estimatedPrice = await pool.getAmountInExactOut(
accessDetails.addressOrId, accessDetails.addressOrId,
accessDetails.baseToken.address, accessDetails.baseToken.address,
accessDetails.datatoken.address, accessDetails.datatoken.address,
'1', '1',
appConfig.consumeMarketPoolSwapFee consumeMarketPoolSwapFee
) )
return estimatedPrice return estimatedPrice
@ -45,7 +44,6 @@ export async function buyDtFromPool(
web3: Web3 web3: Web3
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
const pool = new Pool(web3) const pool = new Pool(web3)
const { appConfig } = getSiteMetadata()
// we need to calculate the actual price to buy one datatoken // we need to calculate the actual price to buy one datatoken
const dtPrice = await calculateBuyPrice(accessDetails, null, web3) const dtPrice = await calculateBuyPrice(accessDetails, null, web3)
const approveTx = await approve( const approveTx = await approve(
@ -63,14 +61,14 @@ export async function buyDtFromPool(
accountId, accountId,
accessDetails.addressOrId, accessDetails.addressOrId,
{ {
marketFeeAddress: appConfig.marketFeeAddress, marketFeeAddress,
tokenIn: accessDetails.baseToken.address, tokenIn: accessDetails.baseToken.address,
tokenOut: accessDetails.datatoken.address tokenOut: accessDetails.datatoken.address
}, },
{ {
// this is just to be safe // this is just to be safe
maxAmountIn: new Decimal(dtPrice.tokenAmount).mul(10).toString(), maxAmountIn: new Decimal(dtPrice.tokenAmount).mul(10).toString(),
swapMarketFee: appConfig.consumeMarketPoolSwapFee, swapMarketFee: consumeMarketPoolSwapFee,
tokenAmountOut: '1' tokenAmountOut: '1'
} }
) )
@ -79,61 +77,105 @@ export async function buyDtFromPool(
} }
/** /**
* Calculate the base token liquidity based on shares info * This is used to calculate the actual price of buying a datatoken, it's a copy of the math in the contracts.
* @param {string} shares * @param params
* @param {string} totalShares
* @param {string} baseTokenLiquidity
* @returns * @returns
*/ */
export function calculateUserLiquidity( export function calcInGivenOut(params: CalcInGivenOutParams): PoolPriceAndFees {
shares: string, const result = {
totalShares: string, tokenAmount: '0',
baseTokenLiquidity: string liquidityProviderSwapFeeAmount: '0',
): string { oceanFeeAmount: '0',
const totalLiquidity = publishMarketSwapFeeAmount: '0',
isValidNumber(shares) && consumeMarketSwapFeeAmount: '0'
isValidNumber(totalShares) && } as PoolPriceAndFees
isValidNumber(baseTokenLiquidity) const one = new Decimal(1)
? new Decimal(shares) const tokenOutLiqudity = new Decimal(params.tokenOutLiquidity)
.dividedBy(new Decimal(totalShares)) const tokenInLiquidity = new Decimal(params.tokenInLiquidity)
.mul(baseTokenLiquidity) const tokenOutAmount = new Decimal(params.tokenOutAmount)
: new Decimal(0) const opcFee = new Decimal(params.opcFee)
return totalLiquidity.toDecimalPlaces(MAX_DECIMALS).toString() const lpFee = new Decimal(params.lpSwapFee)
const publishMarketSwapFee = new Decimal(params.publishMarketSwapFee)
const consumeMarketSwapFee = new Decimal(params.consumeMarketSwapFee)
const diff = tokenOutLiqudity.minus(tokenOutAmount)
const y = tokenOutLiqudity.div(diff)
let foo = y.pow(one)
foo = foo.minus(one)
const totalFee = lpFee
.plus(opcFee)
.plus(publishMarketSwapFee)
.plus(consumeMarketSwapFee)
const tokenAmountIn = tokenInLiquidity.mul(foo).div(one.sub(totalFee))
result.tokenAmount = tokenAmountIn.toString()
result.oceanFeeAmount = tokenAmountIn
.sub(tokenAmountIn.mul(one.sub(opcFee)))
.toString()
result.publishMarketSwapFeeAmount = tokenAmountIn
.sub(tokenAmountIn.mul(one.sub(publishMarketSwapFee)))
.toString()
result.consumeMarketSwapFeeAmount = tokenAmountIn
.sub(tokenAmountIn.mul(one.sub(consumeMarketSwapFee)))
.toString()
result.liquidityProviderSwapFeeAmount = tokenAmountIn
.sub(tokenAmountIn.mul(one.sub(lpFee)))
.toString()
return result
} }
export function calculateUserTVL( /**
shares: string, * Used to calculate swap values, it's a copy of the math in the contracts.
totalShares: string, * @param tokenLiquidity
baseTokenLiquidity: string * @param poolSupply
* @param poolShareAmount
* @returns
*/
export function calcSingleOutGivenPoolIn(
tokenLiquidity: string,
poolSupply: string,
poolShareAmount: string
): string { ): string {
const liquidity = calculateUserLiquidity( const tokenLiquidityD = new Decimal(tokenLiquidity)
shares, const poolSupplyD = new Decimal(poolSupply)
totalShares, const poolShareAmountD = new Decimal(poolShareAmount)
baseTokenLiquidity
) const newPoolSupply = poolSupplyD.sub(poolShareAmountD)
const tvl = new Decimal(liquidity).mul(2) // we multiply by 2 because of 50/50 weight const poolRatio = newPoolSupply.div(poolSupplyD)
return tvl.toDecimalPlaces(MAX_DECIMALS).toString()
const tokenOutRatio = poolRatio.pow(2)
const newTokenBalanceOut = tokenLiquidityD.mul(tokenOutRatio)
const tokensOut = tokenLiquidityD.sub(newTokenBalanceOut)
return tokensOut.toString()
} }
export async function calculateSharesVL( /**
* Returns the amount of tokens (based on tokenAddress) that can be withdrawn from the pool
* @param {string} poolAddress
* @param {string} tokenAddress
* @param {string} shares
* @param {number} chainId
* @returns
*/
export async function getLiquidityByShares(
pool: string, pool: string,
tokenAddress: string, tokenAddress: string,
shares: string, shares: string,
chainId?: number chainId: number
): Promise<string> { ): Promise<string> {
if (!chainId) throw new Error("chainId can't be undefined at the same time!")
// we only use the dummyWeb3 connection here // we only use the dummyWeb3 connection here
const web3 = await getDummyWeb3(chainId) const web3 = await getDummyWeb3(chainId)
const poolInstance = new Pool(web3) const poolInstance = new Pool(web3)
// get shares VL in ocean // get shares VL in ocean
const amountOcean = await poolInstance.calcSingleOutGivenPoolIn( const amountBaseToken = await poolInstance.calcSingleOutGivenPoolIn(
pool, pool,
tokenAddress, tokenAddress,
shares shares
) )
const tvl = new Decimal(amountOcean || 0).mul(2) // we multiply by 2 because of 50/50 weight return amountBaseToken
return tvl.toDecimalPlaces(MAX_DECIMALS).toString()
} }

View File

@ -1,12 +0,0 @@
import { UseSiteMetadata } from '@hooks/useSiteMetadata/types'
import siteContent from '../../content/site.json'
import appConfig from '../../app.config'
export function getSiteMetadata(): UseSiteMetadata {
const siteMeta: UseSiteMetadata = {
...siteContent,
appConfig
}
return siteMeta
}

View File

@ -15,7 +15,7 @@ import {
import { OrdersData_orders as OrdersData } from '../@types/subgraph/OrdersData' import { OrdersData_orders as OrdersData } from '../@types/subgraph/OrdersData'
import { UserSalesQuery as UsersSalesList } from '../@types/subgraph/UserSalesQuery' import { UserSalesQuery as UsersSalesList } from '../@types/subgraph/UserSalesQuery'
import { OpcFeesQuery as OpcFeesData } from '../@types/subgraph/OpcFeesQuery' import { OpcFeesQuery as OpcFeesData } from '../@types/subgraph/OpcFeesQuery'
import { calculateUserTVL } from './pool' import { calcSingleOutGivenPoolIn, getLiquidityByShares } from './pool'
import Decimal from 'decimal.js' import Decimal from 'decimal.js'
import { MAX_DECIMALS } from './constants' import { MAX_DECIMALS } from './constants'
@ -243,13 +243,10 @@ export async function fetchDataForMultipleChains(
let datas: any[] = [] let datas: any[] = []
try { try {
for (const chainId of chainIds) { for (const chainId of chainIds) {
// console.log('fetch chainID', chainId)
const context: OperationContext = getQueryContext(chainId) const context: OperationContext = getQueryContext(chainId)
const response = await fetchData(query, variables, context) const response = await fetchData(query, variables, context)
// console.log('fetch response', response)
if (!response || response.error) continue if (!response || response.error) continue
datas = datas.concat(response?.data) datas = datas.concat(response?.data)
// console.log('fetch datas', datas)
} }
return datas return datas
} catch (error) { } catch (error) {
@ -343,7 +340,7 @@ export async function getHighestLiquidityDatatokens(
return dtList return dtList
} }
export async function getAccountTVLInOwnAssets( export async function getAccountLiquidityInOwnAssets(
accountId: string, accountId: string,
chainIds: number[], chainIds: number[],
pools: string[] pools: string[]
@ -357,22 +354,20 @@ export async function getAccountTVLInOwnAssets(
queryVariables, queryVariables,
chainIds chainIds
) )
let tvl = new Decimal(0) let totalLiquidity = new Decimal(0)
// console.log('resss', results)
for (const result of results) { for (const result of results) {
// console.log('result.poolShares', result.poolShares)
for (const poolShare of result.poolShares) { for (const poolShare of result.poolShares) {
const poolUserTvl = calculateUserTVL( const poolUserLiquidity = calcSingleOutGivenPoolIn(
poolShare.shares, poolShare.pool.baseTokenLiquidity,
poolShare.pool.totalShares, poolShare.pool.totalShares,
poolShare.pool.baseTokenLiquidity poolShare.shares
) )
tvl = tvl.add(new Decimal(poolUserTvl))
// console.log('result.poolShares', tvl.toString()) totalLiquidity = totalLiquidity.add(new Decimal(poolUserLiquidity))
} }
} }
return tvl.toDecimalPlaces(MAX_DECIMALS).toString() return totalLiquidity.toDecimalPlaces(MAX_DECIMALS).toString()
} }
export async function getPoolSharesData( export async function getPoolSharesData(

View File

@ -3,8 +3,8 @@ import React, { ReactElement, useEffect, useState } from 'react'
import { getAssetsNames } from '@utils/aquarius' import { getAssetsNames } from '@utils/aquarius'
import styles from './AssetListTitle.module.css' import styles from './AssetListTitle.module.css'
import axios from 'axios' import axios from 'axios'
import { useSiteMetadata } from '@hooks/useSiteMetadata'
import { Asset } from '@oceanprotocol/lib' import { Asset } from '@oceanprotocol/lib'
import { useMarketMetadata } from '@context/MarketMetadata'
export default function AssetListTitle({ export default function AssetListTitle({
asset, asset,
@ -15,7 +15,7 @@ export default function AssetListTitle({
did?: string did?: string
title?: string title?: string
}): ReactElement { }): ReactElement {
const { appConfig } = useSiteMetadata() const { appConfig } = useMarketMetadata()
const [assetTitle, setAssetTitle] = useState<string>(title) const [assetTitle, setAssetTitle] = useState<string>(title)
useEffect(() => { useEffect(() => {

View File

@ -6,18 +6,22 @@ import { InputProps } from '@shared/FormInput'
import { getFileUrlInfo } from '@utils/provider' import { getFileUrlInfo } from '@utils/provider'
import { FormPublishData } from 'src/components/Publish/_types' import { FormPublishData } from 'src/components/Publish/_types'
import { LoggerInstance } from '@oceanprotocol/lib' import { LoggerInstance } from '@oceanprotocol/lib'
import { useAsset } from '@context/Asset'
export default function FilesInput(props: InputProps): ReactElement { export default function FilesInput(props: InputProps): ReactElement {
const [field, meta, helpers] = useField(props.name) const [field, meta, helpers] = useField(props.name)
const [isLoading, setIsLoading] = useState(false) const [isLoading, setIsLoading] = useState(false)
const { values, setFieldError } = useFormikContext<FormPublishData>() const { values, setFieldError } = useFormikContext<FormPublishData>()
const { asset } = useAsset()
async function handleValidation(e: React.SyntheticEvent, url: string) { async function handleValidation(e: React.SyntheticEvent, url: string) {
// File example 'https://oceanprotocol.com/tech-whitepaper.pdf' // File example 'https://oceanprotocol.com/tech-whitepaper.pdf'
e.preventDefault() e.preventDefault()
try { try {
const providerUrl = values?.services[0].providerUrl.url const providerUrl = values?.services
? values?.services[0].providerUrl.url
: asset.services[0].serviceEndpoint
setIsLoading(true) setIsLoading(true)
const checkedFile = await getFileUrlInfo(url, providerUrl) const checkedFile = await getFileUrlInfo(url, providerUrl)

View File

@ -1,7 +1,8 @@
import React, { ReactElement } from 'react' import React, { ReactElement } from 'react'
import Head from 'next/head' import Head from 'next/head'
import { useSiteMetadata } from '@hooks/useSiteMetadata'
import { isBrowser } from '@utils/index' import { isBrowser } from '@utils/index'
import { useMarketMetadata } from '@context/MarketMetadata'
export default function Seo({ export default function Seo({
title, title,
@ -12,14 +13,14 @@ export default function Seo({
description?: string description?: string
uri: string uri: string
}): ReactElement { }): ReactElement {
const { siteTitle, siteTagline, siteUrl, siteImage } = useSiteMetadata() const { siteContent } = useMarketMetadata()
// Remove trailing slash from all URLs // Remove trailing slash from all URLs
const canonical = `${siteUrl}${uri}`.replace(/\/$/, '') const canonical = `${siteContent?.siteUrl}${uri}`.replace(/\/$/, '')
const pageTitle = title const pageTitle = title
? `${title} - ${siteTitle}` ? `${title} - ${siteContent?.siteTitle}`
: `${siteTitle}${siteTagline}` : `${siteContent?.siteTitle}${siteContent?.siteTagline}`
return ( return (
<Head> <Head>
@ -47,10 +48,16 @@ export default function Seo({
<meta property="og:description" content={description} /> <meta property="og:description" content={description} />
<meta property="og:url" content={canonical} /> <meta property="og:url" content={canonical} />
<meta name="image" content={`${siteUrl}${siteImage}`} /> <meta
<meta property="og:image" content={`${siteUrl}${siteImage}`} /> name="image"
content={`${siteContent?.siteUrl}${siteContent?.siteImage}`}
/>
<meta
property="og:image"
content={`${siteContent?.siteUrl}${siteContent?.siteImage}`}
/>
<meta property="og:site_name" content={siteTitle} /> <meta property="og:site_name" content={siteContent?.siteTitle} />
<meta name="twitter:creator" content="@oceanprotocol" /> <meta name="twitter:creator" content="@oceanprotocol" />
<meta name="twitter:card" content="summary_large_image" /> <meta name="twitter:card" content="summary_large_image" />
</Head> </Head>

View File

@ -6,7 +6,6 @@ import { useUserPreferences } from '@context/UserPreferences'
import { gql } from 'urql' import { gql } from 'urql'
import { TransactionHistory_poolTransactions as TransactionHistoryPoolTransactions } from '../../../@types/subgraph/TransactionHistory' import { TransactionHistory_poolTransactions as TransactionHistoryPoolTransactions } from '../../../@types/subgraph/TransactionHistory'
import { fetchDataForMultipleChains } from '@utils/subgraph' import { fetchDataForMultipleChains } from '@utils/subgraph'
import { useSiteMetadata } from '@hooks/useSiteMetadata'
import NetworkName from '@shared/NetworkName' import NetworkName from '@shared/NetworkName'
import { getAssetsFromDtList } from '@utils/aquarius' import { getAssetsFromDtList } from '@utils/aquarius'
import { getAsset } from '../../Profile/History/PoolShares/_utils' import { getAsset } from '../../Profile/History/PoolShares/_utils'
@ -15,6 +14,7 @@ import Title from './Title'
import styles from './index.module.css' import styles from './index.module.css'
import { Asset, LoggerInstance } from '@oceanprotocol/lib' import { Asset, LoggerInstance } from '@oceanprotocol/lib'
import { useCancelToken } from '@hooks/useCancelToken' import { useCancelToken } from '@hooks/useCancelToken'
import { useMarketMetadata } from '@context/MarketMetadata'
const REFETCH_INTERVAL = 20000 const REFETCH_INTERVAL = 20000
@ -135,7 +135,7 @@ export default function PoolTransactions({
accountId: string accountId: string
}): ReactElement { }): ReactElement {
const { chainIds } = useUserPreferences() const { chainIds } = useUserPreferences()
const { appConfig } = useSiteMetadata() const { appConfig } = useMarketMetadata()
const cancelToken = useCancelToken() const cancelToken = useCancelToken()
const [transactions, setTransactions] = useState<PoolTransaction[]>() const [transactions, setTransactions] = useState<PoolTransaction[]>()
@ -199,7 +199,7 @@ export default function PoolTransactions({
setTransactions(sortedTransactions) setTransactions(sortedTransactions)
setIsLoading(false) setIsLoading(false)
}, },
[data, chainIds, setIsLoading] [data, minimal, chainIds, poolChainId]
) )
// //

View File

@ -2,9 +2,7 @@ import React, { ReactElement } from 'react'
import styles from './index.module.css' import styles from './index.module.css'
import PriceUnit from '@shared/Price/PriceUnit' import PriceUnit from '@shared/Price/PriceUnit'
import Logo from '@shared/atoms/Logo' import Logo from '@shared/atoms/Logo'
import Decimal from 'decimal.js'
import Conversion from '@shared/Price/Conversion' import Conversion from '@shared/Price/Conversion'
import { MAX_DECIMALS } from '@utils/constants'
export default function Token({ export default function Token({
symbol, symbol,
@ -15,7 +13,7 @@ export default function Token({
}: { }: {
symbol: string symbol: string
balance: string balance: string
conversion?: Decimal conversion?: boolean
noIcon?: boolean noIcon?: boolean
size?: 'small' | 'mini' size?: 'small' | 'mini'
}): ReactElement { }): ReactElement {
@ -29,11 +27,8 @@ export default function Token({
</figure> </figure>
<PriceUnit price={balance} symbol={symbol} size={size} /> <PriceUnit price={balance} symbol={symbol} size={size} />
</div> </div>
{conversion?.greaterThan(0) && ( {conversion && (
<Conversion <Conversion price={balance} className={`${styles.conversion}`} />
price={conversion.toDecimalPlaces(MAX_DECIMALS).toString()}
className={styles.conversion}
/>
)} )}
</> </>
) )

View File

@ -3,7 +3,6 @@ import Alert from '@shared/atoms/Alert'
import Footer from '../Footer/Footer' import Footer from '../Footer/Footer'
import Header from '../Header' import Header from '../Header'
import { useWeb3 } from '@context/Web3' import { useWeb3 } from '@context/Web3'
import { useSiteMetadata } from '@hooks/useSiteMetadata'
import { useAccountPurgatory } from '@hooks/useAccountPurgatory' import { useAccountPurgatory } from '@hooks/useAccountPurgatory'
import AnnouncementBanner from '@shared/AnnouncementBanner' import AnnouncementBanner from '@shared/AnnouncementBanner'
import PrivacyPreferenceCenter from '../Privacy/PrivacyPreferenceCenter' import PrivacyPreferenceCenter from '../Privacy/PrivacyPreferenceCenter'
@ -11,6 +10,7 @@ import styles from './index.module.css'
import { ToastContainer } from 'react-toastify' import { ToastContainer } from 'react-toastify'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import content from '../../../content/purgatory.json' import content from '../../../content/purgatory.json'
import { useMarketMetadata } from '@context/MarketMetadata'
export default function App({ export default function App({
children children
@ -19,14 +19,14 @@ export default function App({
}): ReactElement { }): ReactElement {
const router = useRouter() const router = useRouter()
const { warning, appConfig } = useSiteMetadata() const { siteContent, appConfig } = useMarketMetadata()
const { accountId } = useWeb3() const { accountId } = useWeb3()
const { isInPurgatory, purgatoryData } = useAccountPurgatory(accountId) const { isInPurgatory, purgatoryData } = useAccountPurgatory(accountId)
return ( return (
<div className={styles.app}> <div className={styles.app}>
{router.pathname === '/' && warning.main !== '' && ( {router.pathname === '/' && siteContent?.warning.main !== '' && (
<AnnouncementBanner text={warning.main} /> <AnnouncementBanner text={siteContent?.warning.main} />
)} )}
<Header /> <Header />
@ -41,7 +41,7 @@ export default function App({
<main className={styles.main}>{children}</main> <main className={styles.main}>{children}</main>
<Footer /> <Footer />
{appConfig.privacyPreferenceCenter === 'true' && ( {appConfig?.privacyPreferenceCenter === 'true' && (
<PrivacyPreferenceCenter style="small" /> <PrivacyPreferenceCenter style="small" />
)} )}

View File

@ -1,8 +1,5 @@
import React, { useState, ReactElement, useEffect, useCallback } from 'react' import React, { useState, ReactElement, useEffect, useCallback } from 'react'
import { import {
LoggerInstance,
ComputeAlgorithm,
ComputeOutput,
Asset, Asset,
DDO, DDO,
PublisherTrustedAlgorithm, PublisherTrustedAlgorithm,
@ -12,7 +9,6 @@ import { toast } from 'react-toastify'
import Price from '@shared/Price' import Price from '@shared/Price'
import FileIcon from '@shared/FileIcon' import FileIcon from '@shared/FileIcon'
import Alert from '@shared/atoms/Alert' import Alert from '@shared/atoms/Alert'
import { useSiteMetadata } from '@hooks/useSiteMetadata'
import { useWeb3 } from '@context/Web3' import { useWeb3 } from '@context/Web3'
import { import {
generateBaseQuery, generateBaseQuery,
@ -25,7 +21,7 @@ import axios from 'axios'
import FormStartComputeDataset from './FormComputeDataset' import FormStartComputeDataset from './FormComputeDataset'
import styles from './index.module.css' import styles from './index.module.css'
import SuccessConfetti from '@shared/SuccessConfetti' import SuccessConfetti from '@shared/SuccessConfetti'
import { getServiceByName, secondsToString } from '@utils/ddo' import { getServiceByName } from '@utils/ddo'
import { AssetSelectionAsset } from '@shared/FormFields/AssetSelection' import { AssetSelectionAsset } from '@shared/FormFields/AssetSelection'
import AlgorithmDatasetsListForCompute from './AlgorithmDatasetsListForCompute' import AlgorithmDatasetsListForCompute from './AlgorithmDatasetsListForCompute'
import { getPreviousOrders } from '@utils/subgraph' import { getPreviousOrders } from '@utils/subgraph'
@ -37,6 +33,7 @@ import { SortTermOptions } from '../../../../@types/aquarius/SearchQuery'
import { getAccessDetails } from '@utils/accessDetailsAndPricing' import { getAccessDetails } from '@utils/accessDetailsAndPricing'
import { AccessDetails } from 'src/@types/Price' import { AccessDetails } from 'src/@types/Price'
import { transformAssetToAssetSelection } from '@utils/assetConvertor' import { transformAssetToAssetSelection } from '@utils/assetConvertor'
import { useMarketMetadata } from '@context/MarketMetadata'
export default function Compute({ export default function Compute({
ddo, ddo,
@ -55,7 +52,7 @@ export default function Compute({
isConsumable?: boolean isConsumable?: boolean
consumableFeedback?: string consumableFeedback?: string
}): ReactElement { }): ReactElement {
const { appConfig } = useSiteMetadata() const { appConfig } = useMarketMetadata()
const { accountId } = useWeb3() const { accountId } = useWeb3()
const [isJobStarting, setIsJobStarting] = useState(false) const [isJobStarting, setIsJobStarting] = useState(false)
const [error, setError] = useState<string>() const [error, setError] = useState<string>()

View File

@ -17,6 +17,8 @@ import { getOrderPriceAndFees } from '@utils/accessDetailsAndPricing'
import { OrderPriceAndFees } from 'src/@types/Price' import { OrderPriceAndFees } from 'src/@types/Price'
import { toast } from 'react-toastify' import { toast } from 'react-toastify'
import { useIsMounted } from '@hooks/useIsMounted' import { useIsMounted } from '@hooks/useIsMounted'
import { usePool } from '@context/Pool'
import { useMarketMetadata } from '@context/MarketMetadata'
export default function Download({ export default function Download({
asset, asset,
@ -34,6 +36,7 @@ export default function Download({
consumableFeedback?: string consumableFeedback?: string
}): ReactElement { }): ReactElement {
const { accountId, web3 } = useWeb3() const { accountId, web3 } = useWeb3()
const { getOpcFeeForToken } = useMarketMetadata()
const { isInPurgatory, isAssetNetwork } = useAsset() const { isInPurgatory, isAssetNetwork } = useAsset()
const isMounted = useIsMounted() const isMounted = useIsMounted()
@ -44,6 +47,7 @@ export default function Download({
const [isOwned, setIsOwned] = useState(false) const [isOwned, setIsOwned] = useState(false)
const [validOrderTx, setValidOrderTx] = useState('') const [validOrderTx, setValidOrderTx] = useState('')
const { poolData } = usePool()
const [orderPriceAndFees, setOrderPriceAndFees] = const [orderPriceAndFees, setOrderPriceAndFees] =
useState<OrderPriceAndFees>() useState<OrderPriceAndFees>()
useEffect(() => { useEffect(() => {
@ -55,19 +59,35 @@ export default function Download({
async function init() { async function init() {
if ( if (
asset?.accessDetails?.addressOrId === ZERO_ADDRESS || asset?.accessDetails?.addressOrId === ZERO_ADDRESS ||
asset?.accessDetails?.type === 'free' asset?.accessDetails?.type === 'free' ||
(!poolData && asset?.accessDetails?.type === 'dynamic')
) )
return return
setIsLoading(true) setIsLoading(true)
setStatusText('Calculating price including fees.') setStatusText('Calculating price including fees.')
const orderPriceAndFees = await getOrderPriceAndFees(asset, ZERO_ADDRESS)
const params: CalcInGivenOutParams = {
tokenInLiquidity: poolData?.baseTokenLiquidity,
tokenOutLiquidity: poolData?.datatokenLiquidity,
tokenOutAmount: '1',
opcFee: getOpcFeeForToken(poolData.baseToken.address, asset?.chainId),
lpSwapFee: poolData?.liquidityProviderSwapFee,
publishMarketSwapFee: poolData?.publishMarketSwapFee,
consumeMarketSwapFee: '0'
}
const orderPriceAndFees = await getOrderPriceAndFees(
asset,
ZERO_ADDRESS,
params
)
setOrderPriceAndFees(orderPriceAndFees) setOrderPriceAndFees(orderPriceAndFees)
setIsLoading(false) setIsLoading(false)
} }
init() init()
}, [asset, accountId]) }, [asset, accountId, poolData, getOpcFeeForToken])
useEffect(() => { useEffect(() => {
setHasDatatoken(Number(dtBalance) >= 1) setHasDatatoken(Number(dtBalance) >= 1)

View File

@ -4,13 +4,18 @@
margin-bottom: var(--spacer); margin-bottom: var(--spacer);
padding-bottom: calc(var(--spacer) / 2); padding-bottom: calc(var(--spacer) / 2);
border-bottom: 1px solid var(--border-color); border-bottom: 1px solid var(--border-color);
margin-top: -1rem;
margin-left: -2rem; margin-left: -2rem;
margin-right: -2rem; margin-right: -2rem;
padding-left: var(--spacer); padding-left: var(--spacer);
padding-right: var(--spacer); padding-right: var(--spacer);
} }
@media (min-width: 40rem) {
.header {
margin-top: -1rem;
}
}
.headerTitle { .headerTitle {
font-size: var(--font-size-large); font-size: var(--font-size-large);
margin: 0; margin: 0;

View File

@ -1,6 +1,6 @@
.buttonMax { .buttonMax {
position: absolute; position: absolute;
font-size: var(--font-size-mini); font-size: var(--font-size-mini);
bottom: calc(var(--spacer) / 2); bottom: calc(var(--spacer) / 2.6);
right: calc(var(--spacer) * 2.5); right: calc(var(--spacer) * 2.5);
} }

View File

@ -1,12 +1,8 @@
import React, { ReactElement, useEffect } from 'react' import React, { ReactElement, useEffect } from 'react'
import styles from './FormAdd.module.css' import styles from './FormAdd.module.css'
import Input from '@shared/FormInput' import Input from '@shared/FormInput'
import { import Error from '@shared/FormInput/Error'
Field, import { FormikContextType, useField, useFormikContext } from 'formik'
FieldInputProps,
FormikContextType,
useFormikContext
} from 'formik'
import Button from '@shared/atoms/Button' import Button from '@shared/atoms/Button'
import { FormAddLiquidity } from '.' import { FormAddLiquidity } from '.'
import UserLiquidity from '../../UserLiquidity' import UserLiquidity from '../../UserLiquidity'
@ -36,7 +32,7 @@ export default function FormAdd({
values, values,
isSubmitting isSubmitting
}: FormikContextType<FormAddLiquidity> = useFormikContext() }: FormikContextType<FormAddLiquidity> = useFormikContext()
const [field, meta] = useField('amount')
useEffect(() => { useEffect(() => {
async function calculatePoolShares() { async function calculatePoolShares() {
if (!web3 || !poolData?.id || !poolInfo?.totalPoolTokens) return if (!web3 || !poolData?.id || !poolInfo?.totalPoolTokens) return
@ -53,7 +49,7 @@ export default function FormAdd({
const poolTokens = await poolInstance.calcPoolOutGivenSingleIn( const poolTokens = await poolInstance.calcPoolOutGivenSingleIn(
poolData.id, poolData.id,
poolInfo.baseTokenAddress, poolInfo.baseTokenAddress,
values.amount values.amount.toString()
) )
setNewPoolTokens(poolTokens) setNewPoolTokens(poolTokens)
const newPoolShareDecimal = const newPoolShareDecimal =
@ -89,29 +85,15 @@ export default function FormAdd({
symbol={poolInfo?.baseTokenSymbol} symbol={poolInfo?.baseTokenSymbol}
/> />
<Field name="amount"> <Input
{({ type="number"
field, min="0"
form prefix={poolInfo?.baseTokenSymbol}
}: { placeholder="0"
field: FieldInputProps<FormAddLiquidity> disabled={!isAssetNetwork || isSubmitting}
form: any {...field}
}) => ( additionalComponent={<Error meta={meta} />}
<Input />
type="number"
name="amount"
max={amountMax}
min="0"
value={values.amount}
step="any"
prefix={poolInfo?.baseTokenSymbol}
placeholder="0"
field={field}
form={form}
disabled={!isAssetNetwork || isSubmitting}
/>
)}
</Field>
{Number(balance.ocean) > 0 && ( {Number(balance.ocean) > 0 && (
<Button <Button

View File

@ -15,13 +15,15 @@ import { useAsset } from '@context/Asset'
import content from '../../../../../../content/price.json' import content from '../../../../../../content/price.json'
import { calcMaxExactIn, LoggerInstance, Pool } from '@oceanprotocol/lib' import { calcMaxExactIn, LoggerInstance, Pool } from '@oceanprotocol/lib'
import { usePool } from '@context/Pool' import { usePool } from '@context/Pool'
import { MAX_DECIMALS } from '@utils/constants'
import { getMaxDecimalsValidation } from '@utils/numbers'
export interface FormAddLiquidity { export interface FormAddLiquidity {
amount: string amount: number
} }
const initialValues: FormAddLiquidity = { const initialValues: FormAddLiquidity = {
amount: '' amount: 0
} }
export default function Add({ export default function Add({
@ -43,12 +45,18 @@ export default function Add({
// Live validation rules // Live validation rules
// https://github.com/jquense/yup#number // https://github.com/jquense/yup#number
const validationSchema: Yup.SchemaOf<FormAddLiquidity> = Yup.object().shape({ const validationSchema: Yup.SchemaOf<FormAddLiquidity> = Yup.object().shape({
amount: Yup.string() amount: Yup.number()
.min(0.00001, (param) => `Must be more or equal to ${param.min}`) .min(0.00001, (param) => `Must be more or equal to ${param.min}`)
.max( .max(
Number(amountMax), Number(amountMax),
`Maximum you can add is ${Number(amountMax).toFixed(2)} OCEAN` `Maximum you can add is ${Number(amountMax).toFixed(2)} OCEAN`
) )
.test(
'maxDigitsAfterDecimal',
`Must have maximum ${MAX_DECIMALS} decimal digits`,
(param) =>
getMaxDecimalsValidation(MAX_DECIMALS).test(param?.toString())
)
.required('Required') .required('Required')
}) })
@ -126,7 +134,7 @@ export default function Add({
initialValues={initialValues} initialValues={initialValues}
validationSchema={validationSchema} validationSchema={validationSchema}
onSubmit={async (values, { setSubmitting, resetForm }) => { onSubmit={async (values, { setSubmitting, resetForm }) => {
await handleAddLiquidity(values.amount, resetForm) await handleAddLiquidity(values.amount.toString(), resetForm)
setSubmitting(false) setSubmitting(false)
}} }}
> >
@ -162,15 +170,14 @@ export default function Add({
!isValid || !isValid ||
!isWarningAccepted || !isWarningAccepted ||
!values.amount || !values.amount ||
values.amount === '' || values.amount === 0
values.amount === '0'
} }
isLoading={isSubmitting} isLoading={isSubmitting}
loaderMessage="Adding Liquidity..." loaderMessage="Adding Liquidity..."
successMessage="Successfully added liquidity." successMessage="Successfully added liquidity."
actionName={content.pool.add.action} actionName={content.pool.add.action}
action={submitForm} action={submitForm}
amount={values.amount} amount={values.amount.toString()}
tokenAddress={poolInfo?.baseTokenAddress} tokenAddress={poolInfo?.baseTokenAddress}
tokenSymbol={poolInfo?.baseTokenSymbol} tokenSymbol={poolInfo?.baseTokenSymbol}
txId={txId} txId={txId}

View File

@ -53,7 +53,6 @@ export default function Graph(): ReactElement {
const conversionSpotPrice = prices[currency.toLowerCase()] const conversionSpotPrice = prices[currency.toLowerCase()]
const tvl = new Decimal(item.baseTokenLiquidity) const tvl = new Decimal(item.baseTokenLiquidity)
.mul(2)
.mul(conversionSpotPrice) // convert to user currency .mul(conversionSpotPrice) // convert to user currency
.toString() .toString()
return tvl return tvl

View File

@ -1,19 +1,38 @@
import { calcMaxExactOut } from '@oceanprotocol/lib' import { PoolInfo, PoolInfoUser } from '@context/Pool/_types'
import { calcMaxExactOut, Pool } from '@oceanprotocol/lib'
import Decimal from 'decimal.js' import Decimal from 'decimal.js'
import { PoolData_poolData as PoolData } from 'src/@types/subgraph/PoolData'
export async function getMax(poolTokens: string, totalPoolTokens: string) { export async function getMax(
const poolTokensAmount = !poolTokens || poolTokens === '0' ? '1' : poolTokens poolInstance: Pool,
const maxTokensToRemoveFromPool = calcMaxExactOut(totalPoolTokens) poolInfo: PoolInfo,
const poolTokensDecimal = new Decimal(poolTokensAmount) poolInfoUser: PoolInfoUser,
const maxTokensToRemoveForUser = maxTokensToRemoveFromPool.greaterThan( poolData: PoolData
poolTokensDecimal ) {
const maxBaseTokensRemovable = calcMaxExactOut(poolData.baseTokenLiquidity)
const maxPoolSharesRemovable = await poolInstance.calcPoolInGivenSingleOut(
poolData.id,
poolInfo.baseTokenAddress,
maxBaseTokensRemovable.toString()
) )
? poolTokensDecimal
: maxTokensToRemoveFromPool
const maxPercent = new Decimal(100) const userPoolShares = poolInfoUser.poolShares
.mul(maxTokensToRemoveForUser)
.div(poolTokensDecimal) const maxPoolSharesRemovableDecimal = new Decimal(maxPoolSharesRemovable)
const userPoolSharesDecimal = new Decimal(userPoolShares)
const maxPoolSharesRemovableByUser =
maxPoolSharesRemovableDecimal.greaterThan(userPoolSharesDecimal)
? userPoolSharesDecimal
: maxPoolSharesRemovableDecimal
// small hack because if the values are equal the decimal.js result is 99.(9)
const maxPercent = maxPoolSharesRemovableByUser.equals(userPoolSharesDecimal)
? new Decimal(100)
: new Decimal(100)
.mul(maxPoolSharesRemovableByUser)
.div(userPoolSharesDecimal)
return maxPercent.toDecimalPlaces(0, Decimal.ROUND_DOWN).toString() return maxPercent.toDecimalPlaces(0, Decimal.ROUND_DOWN).toString()
} }

View File

@ -3,6 +3,7 @@
padding-left: calc(var(--spacer) * 2); padding-left: calc(var(--spacer) * 2);
padding-right: calc(var(--spacer) * 2); padding-right: calc(var(--spacer) * 2);
padding-bottom: calc(var(--spacer) / 2); padding-bottom: calc(var(--spacer) / 2);
margin-bottom: 0;
} }
.range { .range {
@ -50,25 +51,22 @@
} }
.output { .output {
composes: output from '../Add/Output.module.css'; composes: container from '../Section/index.module.css';
} display: grid;
gap: var(--spacer);
.output [class*='token'] { grid-template-columns: 1fr 1fr;
white-space: nowrap;
}
.output [class*='token'] > figure {
display: inline-block;
}
.output figure[class*='pool shares'] {
display: none;
} }
.output p { .output p {
font-weight: var(--font-weight-bold);
margin-bottom: calc(var(--spacer) / 8);
font-size: var(--font-size-small); font-size: var(--font-size-small);
} }
.output [class*='token'] > figure {
display: none;
}
.slippage { .slippage {
composes: slippage from '../../Trade/Slippage.module.css'; composes: slippage from '../../Trade/Slippage.module.css';
} }

View File

@ -43,8 +43,6 @@ export default function Remove({
const [slippage, setSlippage] = useState<string>('5') const [slippage, setSlippage] = useState<string>('5')
const [minOceanAmount, setMinOceanAmount] = useState<string>('0') const [minOceanAmount, setMinOceanAmount] = useState<string>('0')
// TODO: precision needs to be set based on baseToken decimals
Decimal.set({ toExpNeg: -18, precision: 18, rounding: 1 })
const poolInstance = new Pool(web3) const poolInstance = new Pool(web3)
async function handleRemoveLiquidity() { async function handleRemoveLiquidity() {
@ -79,10 +77,18 @@ export default function Remove({
if (!accountId || !poolInfoUser?.poolShares || !poolInfo?.totalPoolTokens) if (!accountId || !poolInfoUser?.poolShares || !poolInfo?.totalPoolTokens)
return return
getMax(poolInfoUser.poolShares, poolInfo.totalPoolTokens).then((max) => getMax(poolInstance, poolInfo, poolInfoUser, poolData).then((max) =>
setAmountMaxPercent(max) setAmountMaxPercent(max)
) )
}, [accountId, poolInfoUser?.poolShares, poolInfo?.totalPoolTokens]) }, [
accountId,
poolInfoUser?.poolShares,
poolInfo?.totalPoolTokens,
poolInfoUser,
poolInfo,
poolInstance,
poolData
])
const getValues = useRef( const getValues = useRef(
debounce(async (newAmountPoolShares) => { debounce(async (newAmountPoolShares) => {
@ -91,7 +97,6 @@ export default function Remove({
poolInfo?.baseTokenAddress, poolInfo?.baseTokenAddress,
newAmountPoolShares newAmountPoolShares
) )
setAmountOcean(newAmountOcean) setAmountOcean(newAmountOcean)
}, 150) }, 150)
) )
@ -137,20 +142,18 @@ export default function Remove({
.dividedBy(100) .dividedBy(100)
.mul(new Decimal(poolInfoUser.poolShares)) .mul(new Decimal(poolInfoUser.poolShares))
.toString() .toString()
setAmountPoolShares(amountPoolShares)
setAmountPoolShares(`${amountPoolShares.slice(0, 18)}`)
} }
function handleMaxButton(e: ChangeEvent<HTMLInputElement>) { function handleMaxButton(e: ChangeEvent<HTMLInputElement>) {
e.preventDefault() e.preventDefault()
setAmountPercent(amountMaxPercent) setAmountPercent(amountMaxPercent)
const amountPoolShares = new Decimal(amountMaxPercent) const amountPoolShares = new Decimal(amountMaxPercent)
.dividedBy(100) .dividedBy(100)
.mul(new Decimal(poolInfoUser?.poolShares)) .mul(new Decimal(poolInfoUser?.poolShares))
.toString() .toString()
setAmountPoolShares(`${amountPoolShares.slice(0, 18)}`) setAmountPoolShares(amountPoolShares)
} }
function handleSlippageChange(e: ChangeEvent<HTMLSelectElement>) { function handleSlippageChange(e: ChangeEvent<HTMLSelectElement>) {
@ -196,13 +199,17 @@ export default function Remove({
</form> </form>
<div className={styles.output}> <div className={styles.output}>
<div> <div>
<p>{content.pool.remove.output.titleOut} minimum</p> <p>{content.pool.remove.output.titleOutExpected}</p>
<Token
symbol={poolInfo?.baseTokenSymbol}
balance={amountOcean}
noIcon
/>
</div>
<div>
<p>{content.pool.remove.output.titleOutMinimum}</p>
<Token symbol={poolInfo?.baseTokenSymbol} balance={minOceanAmount} /> <Token symbol={poolInfo?.baseTokenSymbol} balance={minOceanAmount} />
</div> </div>
{/* <div>
<p>{content.pool.remove.output.titleIn}</p>
<Token symbol="pool shares" balance={amountPoolShares} noIcon />
</div> */}
</div> </div>
<div className={styles.slippage}> <div className={styles.slippage}>
<strong>Slippage Tolerance</strong> <strong>Slippage Tolerance</strong>

View File

@ -1,4 +1,6 @@
.update { .update {
display: block;
margin: 0;
font-size: var(--font-size-mini); font-size: var(--font-size-mini);
color: var(--color-secondary); color: var(--color-secondary);
text-align: center; text-align: center;
@ -6,27 +8,31 @@
padding-bottom: calc(var(--spacer) / 3); padding-bottom: calc(var(--spacer) / 3);
} }
/* .update:before { .update:before {
content: ''; content: '';
width: 6px; width: 6px;
height: 6px; height: 6px;
border-radius: 50%; border-radius: 50%;
display: inline-block; display: inline-block;
border: 1px solid var(--brand-alert-green); border: 1px solid var(--brand-alert-green);
margin-right: 0.2rem; margin-right: 0.2rem;
margin-top: -0.1rem; margin-top: -0.1rem;
vertical-align: middle; vertical-align: middle;
animation: pulse 2s ease-in-out infinite; animation: pulse 2s ease-in-out infinite;
}
.button {
font-size: var(--font-size-mini);
}
@keyframes pulse {
0% {
background: transparent;
} }
50% {
@keyframes pulse { background: var(--brand-alert-green);
0% { }
background: transparent; 100% {
} background: transparent;
50% { }
background: var(--brand-alert-green); }
}
100% {
background: transparent;
}
} */

View File

@ -1,17 +1,26 @@
import { usePool } from '@context/Pool' import { usePool } from '@context/Pool'
import { useUserPreferences } from '@context/UserPreferences'
import Button from '@shared/atoms/Button' import Button from '@shared/atoms/Button'
import React from 'react' import React from 'react'
import styles from './Update.module.css' import styles from './Update.module.css'
export default function Update() { export default function Update() {
const { fetchAllData } = usePool() const { debug } = useUserPreferences()
const { fetchAllData, refreshInterval } = usePool()
return ( return (
<div className={styles.update}> <p className={styles.update}>
<Button style="text" size="small" onClick={() => fetchAllData()}> Fetching every {refreshInterval / 1000} sec.{' '}
Refresh Data {debug && (
</Button> <Button
{/* Fetching every {refreshInterval / 1000} sec. */} style="text"
</div> size="small"
onClick={() => fetchAllData()}
className={styles.button}
>
Refresh Data
</Button>
)}
</p>
) )
} }

View File

@ -47,9 +47,10 @@ export default function PoolSections() {
</PoolSection> </PoolSection>
<PoolSection <PoolSection
title="Your Value Locked" title="Your liquidity"
titlePostfix={ titlePostfix={
poolInfoUser?.poolShare && `${poolInfoUser?.poolShare}% of pool` poolInfoUser?.poolSharePercentage &&
`${poolInfoUser?.poolSharePercentage}% of pool`
} }
tooltip={content.pool.tooltips.liquidity.replace( tooltip={content.pool.tooltips.liquidity.replace(
'SWAPFEE', 'SWAPFEE',
@ -59,27 +60,27 @@ export default function PoolSections() {
> >
<Token <Token
symbol={poolInfo?.baseTokenSymbol} symbol={poolInfo?.baseTokenSymbol}
balance={poolInfoUser?.liquidity.toString()} balance={poolInfoUser?.liquidity}
conversion={poolInfoUser?.liquidity} conversion
/> />
</PoolSection> </PoolSection>
<PoolSection <PoolSection
title="Owner Value Locked" title="Owner liquidity"
titlePostfix={`${poolInfoOwner?.poolShare}% of pool`} titlePostfix={`${poolInfoOwner?.poolSharePercentage}% of pool`}
> >
<Token <Token
symbol={poolInfo?.baseTokenSymbol} symbol={poolInfo?.baseTokenSymbol}
balance={poolInfoOwner?.liquidity.toString()} balance={poolInfoOwner?.liquidity}
conversion={poolInfoOwner?.liquidity} conversion
/> />
</PoolSection> </PoolSection>
<PoolSection title="Total Value Locked"> <PoolSection title="Total Value Locked">
<Token <Token
symbol={poolInfo?.baseTokenSymbol} symbol={poolInfo?.baseTokenSymbol}
balance={poolInfo?.totalLiquidityInOcean.toString()} balance={poolData?.baseTokenLiquidity.toString()}
conversion={poolInfo?.totalLiquidityInOcean} conversion
/> />
</PoolSection> </PoolSection>
@ -92,7 +93,6 @@ export default function PoolSections() {
titlePostfixTitle={`Weight of ${poolInfo?.weightBaseToken}% ${poolInfo?.baseTokenSymbol} & ${poolInfo?.weightDt}% ${poolInfo?.datatokenSymbol}`} titlePostfixTitle={`Weight of ${poolInfo?.weightBaseToken}% ${poolInfo?.baseTokenSymbol} & ${poolInfo?.weightDt}% ${poolInfo?.datatokenSymbol}`}
> >
<Graph /> <Graph />
<Token <Token
symbol={poolInfo?.baseTokenSymbol} symbol={poolInfo?.baseTokenSymbol}
balance={`${poolData?.baseTokenLiquidity}`} balance={`${poolData?.baseTokenLiquidity}`}
@ -105,7 +105,7 @@ export default function PoolSections() {
/> />
<Token <Token
symbol="% pool fee" symbol="% swap fee"
balance={poolInfo?.liquidityProviderSwapFee} balance={poolInfo?.liquidityProviderSwapFee}
noIcon noIcon
size="mini" size="mini"
@ -117,7 +117,7 @@ export default function PoolSections() {
size="mini" size="mini"
/> />
<Token <Token
symbol="% OPF fee" symbol="% OPC fee"
balance={poolInfo?.opcFee} balance={poolInfo?.opcFee}
noIcon noIcon
size="mini" size="mini"

View File

@ -13,7 +13,7 @@ import PoolSections from './Sections'
export default function Pool(): ReactElement { export default function Pool(): ReactElement {
const { isInPurgatory, asset, isAssetNetwork } = useAsset() const { isInPurgatory, asset, isAssetNetwork } = useAsset()
const { hasUserAddedLiquidity, isRemoveDisabled } = usePool() const { hasUserAddedLiquidity } = usePool()
const { accountId } = useWeb3() const { accountId } = useWeb3()
const [showAdd, setShowAdd] = useState(false) const [showAdd, setShowAdd] = useState(false)
@ -34,12 +34,12 @@ export default function Pool(): ReactElement {
style="primary" style="primary"
size="small" size="small"
onClick={() => setShowAdd(true)} onClick={() => setShowAdd(true)}
disabled={isInPurgatory} disabled={isInPurgatory || !isAssetNetwork}
> >
Add Liquidity Add Liquidity
</Button> </Button>
{hasUserAddedLiquidity && !isRemoveDisabled && ( {hasUserAddedLiquidity && (
<Button <Button
size="small" size="small"
onClick={() => setShowRemove(true)} onClick={() => setShowRemove(true)}

View File

@ -22,7 +22,7 @@ import { initialValues } from './_constants'
import content from '../../../../../content/price.json' import content from '../../../../../content/price.json'
import { AssetExtended } from 'src/@types/AssetExtended' import { AssetExtended } from 'src/@types/AssetExtended'
import { usePool } from '@context/Pool' import { usePool } from '@context/Pool'
import { useSiteMetadata } from '@hooks/useSiteMetadata' import { useMarketMetadata } from '@context/MarketMetadata'
export default function FormTrade({ export default function FormTrade({
asset, asset,
@ -34,7 +34,7 @@ export default function FormTrade({
const { web3, accountId } = useWeb3() const { web3, accountId } = useWeb3()
const { isAssetNetwork } = useAsset() const { isAssetNetwork } = useAsset()
const { debug } = useUserPreferences() const { debug } = useUserPreferences()
const { appConfig } = useSiteMetadata() const { appConfig } = useMarketMetadata()
const { poolInfo } = usePool() const { poolInfo } = usePool()
const [txId, setTxId] = useState<string>() const [txId, setTxId] = useState<string>()
const [coinFrom, setCoinFrom] = useState<string>('OCEAN') const [coinFrom, setCoinFrom] = useState<string>('OCEAN')
@ -67,7 +67,7 @@ export default function FormTrade({
.defined() .defined()
async function handleTrade(values: FormTradeData) { async function handleTrade(values: FormTradeData) {
if (!web3 || !asset || !poolInfo || !values) return if (!web3 || !asset || !poolInfo || !values || !appConfig) return
try { try {
const poolInstance = new Pool(web3) const poolInstance = new Pool(web3)

View File

@ -20,8 +20,8 @@ import {
} from '@oceanprotocol/lib' } from '@oceanprotocol/lib'
import { AssetExtended } from 'src/@types/AssetExtended' import { AssetExtended } from 'src/@types/AssetExtended'
import { usePool } from '@context/Pool' import { usePool } from '@context/Pool'
import { useSiteMetadata } from '@hooks/useSiteMetadata'
import { MAX_DECIMALS } from '@utils/constants' import { MAX_DECIMALS } from '@utils/constants'
import { useMarketMetadata } from '@context/MarketMetadata'
// Decimal.set({ toExpNeg: -15, precision: 5, rounding: Decimal.ROUND_DOWN }) // Decimal.set({ toExpNeg: -15, precision: 5, rounding: Decimal.ROUND_DOWN })
@ -41,7 +41,7 @@ export default function Swap({
const { isAssetNetwork } = useAsset() const { isAssetNetwork } = useAsset()
const { web3 } = useWeb3() const { web3 } = useWeb3()
const { poolInfo, poolData } = usePool() const { poolInfo, poolData } = usePool()
const { appConfig } = useSiteMetadata() const { appConfig } = useMarketMetadata()
const [baseTokenItem, setBaseTokenItem] = useState<TradeItem>({ const [baseTokenItem, setBaseTokenItem] = useState<TradeItem>({
amount: '0', amount: '0',
@ -69,7 +69,7 @@ export default function Swap({
const [lpSwapFee, setLpSwapFee] = useState<string>() const [lpSwapFee, setLpSwapFee] = useState<string>()
useEffect(() => { useEffect(() => {
if (!asset || !balance || !values?.type || !web3) return if (!asset || !balance || !values?.type || !web3 || !appConfig) return
const poolInstance = new Pool(web3) const poolInstance = new Pool(web3)
async function calculateMaximum() { async function calculateMaximum() {
@ -171,6 +171,7 @@ export default function Swap({
poolInfo.liquidityProviderSwapFee, poolInfo.liquidityProviderSwapFee,
poolInfo.datatokenAddress, poolInfo.datatokenAddress,
poolInfo.baseTokenAddress, poolInfo.baseTokenAddress,
appConfig,
appConfig.consumeMarketPoolSwapFee appConfig.consumeMarketPoolSwapFee
]) ])

View File

@ -11,12 +11,12 @@ import {
} from '@utils/aquarius' } from '@utils/aquarius'
import { useAsset } from '@context/Asset' import { useAsset } from '@context/Asset'
import { PublisherTrustedAlgorithm } from '@oceanprotocol/lib' import { PublisherTrustedAlgorithm } from '@oceanprotocol/lib'
import { useSiteMetadata } from '@hooks/useSiteMetadata'
import FormActions from './FormActions' import FormActions from './FormActions'
import { useCancelToken } from '@hooks/useCancelToken' import { useCancelToken } from '@hooks/useCancelToken'
import { SortTermOptions } from '../../../@types/aquarius/SearchQuery' import { SortTermOptions } from '../../../@types/aquarius/SearchQuery'
import { getServiceByName } from '@utils/ddo' import { getServiceByName } from '@utils/ddo'
import { transformAssetToAssetSelection } from '@utils/assetConvertor' import { transformAssetToAssetSelection } from '@utils/assetConvertor'
import { useMarketMetadata } from '@context/MarketMetadata'
export default function FormEditComputeDataset({ export default function FormEditComputeDataset({
data, data,
@ -25,7 +25,7 @@ export default function FormEditComputeDataset({
data: InputProps[] data: InputProps[]
title: string title: string
}): ReactElement { }): ReactElement {
const { appConfig } = useSiteMetadata() const { appConfig } = useMarketMetadata()
const { asset } = useAsset() const { asset } = useAsset()
const { values }: FormikContextType<ComputePrivacyForm> = useFormikContext() const { values }: FormikContextType<ComputePrivacyForm> = useFormikContext()
const [allAlgorithms, setAllAlgorithms] = useState<AssetSelectionAsset[]>() const [allAlgorithms, setAllAlgorithms] = useState<AssetSelectionAsset[]>()
@ -59,7 +59,7 @@ export default function FormEditComputeDataset({
getAlgorithmList(publisherTrustedAlgorithms).then((algorithms) => { getAlgorithmList(publisherTrustedAlgorithms).then((algorithms) => {
setAllAlgorithms(algorithms) setAllAlgorithms(algorithms)
}) })
}, [appConfig.metadataCacheUri, publisherTrustedAlgorithms]) }, [appConfig, appConfig.metadataCacheUri, publisherTrustedAlgorithms])
return ( return (
<Form className={styles.form}> <Form className={styles.form}>

View File

@ -1,15 +1,15 @@
import React, { ReactElement } from 'react' import React, { ReactElement } from 'react'
import styles from './Footer.module.css' import styles from './Footer.module.css'
import Markdown from '@shared/Markdown' import Markdown from '@shared/Markdown'
import { useSiteMetadata } from '@hooks/useSiteMetadata'
import MarketStats from './MarketStats' import MarketStats from './MarketStats'
import BuildId from './BuildId' import BuildId from './BuildId'
import Links from './Links' import Links from './Links'
import Button from '@shared/atoms/Button' import Button from '@shared/atoms/Button'
import External from '@images/external.svg' import External from '@images/external.svg'
import { useMarketMetadata } from '@context/MarketMetadata'
export default function Footer(): ReactElement { export default function Footer(): ReactElement {
const { copyright } = useSiteMetadata() const { siteContent } = useMarketMetadata()
const year = new Date().getFullYear() const year = new Date().getFullYear()
return ( return (
@ -20,7 +20,7 @@ export default function Footer(): ReactElement {
<div className={styles.grid}> <div className={styles.grid}>
<Links /> <Links />
<div className={styles.copyright}> <div className={styles.copyright}>
© {year} <Markdown text={copyright} /> © {year} <Markdown text={siteContent?.copyright} />
<Button <Button
style="text" style="text"
size="small" size="small"

View File

@ -1,15 +1,15 @@
import { useUserPreferences } from '@context/UserPreferences' import { useUserPreferences } from '@context/UserPreferences'
import { useGdprMetadata } from '@hooks/useGdprMetadata' import { useGdprMetadata } from '@hooks/useGdprMetadata'
import { useSiteMetadata } from '@hooks/useSiteMetadata'
import Button from '@shared/atoms/Button' import Button from '@shared/atoms/Button'
import Link from 'next/link' import Link from 'next/link'
import React, { Fragment } from 'react' import React, { Fragment } from 'react'
import content from '../../../content/footer.json' import content from '../../../content/footer.json'
import External from '@images/external.svg' import External from '@images/external.svg'
import styles from './Links.module.css' import styles from './Links.module.css'
import { useMarketMetadata } from '@context/MarketMetadata'
export default function Links() { export default function Links() {
const { appConfig } = useSiteMetadata() const { appConfig } = useMarketMetadata()
const { setShowPPC, privacyPolicySlug } = useUserPreferences() const { setShowPPC, privacyPolicySlug } = useUserPreferences()
const cookies = useGdprMetadata() const cookies = useGdprMetadata()
@ -35,7 +35,7 @@ export default function Links() {
<Link href={privacyPolicySlug}> <Link href={privacyPolicySlug}>
<a>Privacy</a> <a>Privacy</a>
</Link> </Link>
{appConfig.privacyPreferenceCenter === 'true' && ( {appConfig?.privacyPreferenceCenter === 'true' && (
<> <>
{' — '} {' — '}
<Button <Button

View File

@ -2,7 +2,6 @@ import React, { ReactElement, useCallback, useEffect, useState } from 'react'
import { OperationContext } from 'urql' import { OperationContext } from 'urql'
import Tooltip from '@shared/atoms/Tooltip' import Tooltip from '@shared/atoms/Tooltip'
import { fetchData, getSubgraphUri } from '@utils/subgraph' import { fetchData, getSubgraphUri } from '@utils/subgraph'
import { useSiteMetadata } from '@hooks/useSiteMetadata'
import useNetworkMetadata, { import useNetworkMetadata, {
filterNetworksByType filterNetworksByType
} from '@hooks/useNetworkMetadata' } from '@hooks/useNetworkMetadata'
@ -16,6 +15,7 @@ import { usePrices } from '@context/Prices'
import { useUserPreferences } from '@context/UserPreferences' import { useUserPreferences } from '@context/UserPreferences'
import Decimal from 'decimal.js' import Decimal from 'decimal.js'
import { StatsTotal, StatsValue } from './_types' import { StatsTotal, StatsValue } from './_types'
import { useMarketMetadata } from '@context/MarketMetadata'
const initialTotal: StatsTotal = { const initialTotal: StatsTotal = {
totalValueLockedInOcean: 0, totalValueLockedInOcean: 0,
@ -27,14 +27,15 @@ const initialTotal: StatsTotal = {
} }
export default function MarketStats(): ReactElement { export default function MarketStats(): ReactElement {
const { appConfig } = useSiteMetadata() const { appConfig } = useMarketMetadata()
const { networksList } = useNetworkMetadata() const { networksList } = useNetworkMetadata()
const { currency } = useUserPreferences() const { currency } = useUserPreferences()
const { prices } = usePrices() const { prices } = usePrices()
const [mainChainIds, setMainChainIds] = useState<number[]>() const [mainChainIds, setMainChainIds] = useState<number[]>()
const [data, setData] = const [data, setData] = useState<{
useState<{ [chainId: number]: FooterStatsValuesGlobalStatistics }>() [chainId: number]: FooterStatsValuesGlobalStatistics
}>()
const [totalValueLockedInOcean, setTotalValueLockedInOcean] = const [totalValueLockedInOcean, setTotalValueLockedInOcean] =
useState<StatsValue>() useState<StatsValue>()
const [totalOceanLiquidity, setTotalOceanLiquidity] = useState<StatsValue>() const [totalOceanLiquidity, setTotalOceanLiquidity] = useState<StatsValue>()
@ -45,7 +46,7 @@ export default function MarketStats(): ReactElement {
// Set the main chain ids we want to display stats for // Set the main chain ids we want to display stats for
// //
useEffect(() => { useEffect(() => {
if (!networksList) return if (!networksList || !appConfig || !appConfig?.chainIdsSupported) return
const mainChainIdsList = filterNetworksByType( const mainChainIdsList = filterNetworksByType(
'mainnet', 'mainnet',
@ -53,7 +54,7 @@ export default function MarketStats(): ReactElement {
networksList networksList
) )
setMainChainIds(mainChainIdsList) setMainChainIds(mainChainIdsList)
}, [appConfig.chainIdsSupported, networksList]) }, [appConfig, appConfig?.chainIdsSupported, networksList])
// //
// Helper: fetch data from subgraph // Helper: fetch data from subgraph

View File

@ -1,7 +1,6 @@
import React, { ReactElement } from 'react' import React, { ReactElement } from 'react'
import Link from 'next/link' import Link from 'next/link'
import loadable from '@loadable/component' import loadable from '@loadable/component'
import { useSiteMetadata } from '@hooks/useSiteMetadata'
import Badge from '@shared/atoms/Badge' import Badge from '@shared/atoms/Badge'
import Logo from '@shared/atoms/Logo' import Logo from '@shared/atoms/Logo'
import UserPreferences from './UserPreferences' import UserPreferences from './UserPreferences'
@ -9,6 +8,7 @@ import Networks from './UserPreferences/Networks'
import SearchBar from './SearchBar' import SearchBar from './SearchBar'
import styles from './Menu.module.css' import styles from './Menu.module.css'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import { useMarketMetadata } from '@context/MarketMetadata'
const Wallet = loadable(() => import('./Wallet')) const Wallet = loadable(() => import('./Wallet'))
@ -33,7 +33,7 @@ function MenuLink({ item }: { item: MenuItem }) {
} }
export default function Menu(): ReactElement { export default function Menu(): ReactElement {
const { menu, siteTitle } = useSiteMetadata() const { siteContent } = useMarketMetadata()
return ( return (
<nav className={styles.menu}> <nav className={styles.menu}>
@ -41,13 +41,13 @@ export default function Menu(): ReactElement {
<a className={styles.logo}> <a className={styles.logo}>
<Logo noWordmark /> <Logo noWordmark />
<h1 className={styles.title}> <h1 className={styles.title}>
{siteTitle} <Badge label="v4" /> {siteContent?.siteTitle} <Badge label="v4" />
</h1> </h1>
</a> </a>
</Link> </Link>
<ul className={styles.navigation}> <ul className={styles.navigation}>
{menu.map((item: MenuItem) => ( {siteContent?.menu.map((item: MenuItem) => (
<li key={item.name}> <li key={item.name}>
<MenuLink item={item} /> <MenuLink item={item} />
</li> </li>

View File

@ -1,11 +1,11 @@
import React, { ReactElement, ChangeEvent } from 'react' import React, { ReactElement, ChangeEvent } from 'react'
import { useSiteMetadata } from '@hooks/useSiteMetadata'
import { useUserPreferences } from '@context/UserPreferences' import { useUserPreferences } from '@context/UserPreferences'
import Input from '@shared/FormInput' import Input from '@shared/FormInput'
import { useMarketMetadata } from '@context/MarketMetadata'
export default function Currency(): ReactElement { export default function Currency(): ReactElement {
const { currency, setCurrency } = useUserPreferences() const { currency, setCurrency } = useUserPreferences()
const { appConfig } = useSiteMetadata() const { appConfig } = useMarketMetadata()
return ( return (
<li> <li>
@ -14,7 +14,7 @@ export default function Currency(): ReactElement {
label="Currency" label="Currency"
help="Your conversion display currency." help="Your conversion display currency."
type="select" type="select"
options={appConfig.currencies} options={appConfig?.currencies}
value={currency} value={currency}
onChange={(e: ChangeEvent<HTMLSelectElement>) => onChange={(e: ChangeEvent<HTMLSelectElement>) =>
setCurrency(e.target.value) setCurrency(e.target.value)

View File

@ -1,6 +1,5 @@
import React, { ReactElement } from 'react' import React, { ReactElement } from 'react'
import Label from '@shared/FormInput/Label' import Label from '@shared/FormInput/Label'
import { useSiteMetadata } from '@hooks/useSiteMetadata'
import FormHelp from '@shared/FormInput/Help' import FormHelp from '@shared/FormInput/Help'
import Tooltip from '@shared/atoms/Tooltip' import Tooltip from '@shared/atoms/Tooltip'
import Caret from '@images/caret.svg' import Caret from '@images/caret.svg'
@ -12,10 +11,11 @@ import useNetworkMetadata, {
filterNetworksByType filterNetworksByType
} from '@hooks/useNetworkMetadata' } from '@hooks/useNetworkMetadata'
import { useUserPreferences } from '@context/UserPreferences' import { useUserPreferences } from '@context/UserPreferences'
import { useMarketMetadata } from '@context/MarketMetadata'
export default function Networks(): ReactElement { export default function Networks(): ReactElement {
const { appConfig } = useMarketMetadata()
const { networksList } = useNetworkMetadata() const { networksList } = useNetworkMetadata()
const { appConfig } = useSiteMetadata()
const { chainIds } = useUserPreferences() const { chainIds } = useUserPreferences()
const networksMain = filterNetworksByType( const networksMain = filterNetworksByType(

View File

@ -8,12 +8,12 @@ import Caret from '@images/caret.svg'
import useDarkMode from 'use-dark-mode' import useDarkMode from 'use-dark-mode'
import Appearance from './Appearance' import Appearance from './Appearance'
import TokenApproval from './TokenApproval' import TokenApproval from './TokenApproval'
import { useSiteMetadata } from '@hooks/useSiteMetadata' import { useMarketMetadata } from '@context/MarketMetadata'
export default function UserPreferences(): ReactElement { export default function UserPreferences(): ReactElement {
const { appConfig } = useSiteMetadata() const { appConfig } = useMarketMetadata()
// Calling this here because <Style /> is not mounted on first load // Calling this here because <Style /> is not mounted on first load
const darkMode = useDarkMode(false, appConfig.darkModeConfig) const darkMode = useDarkMode(false, appConfig?.darkModeConfig)
return ( return (
<Tooltip <Tooltip

View File

@ -1,4 +1,4 @@
import React, { ReactElement, useEffect, useState } from 'react' import React, { ChangeEvent, ReactElement, useEffect, useState } from 'react'
import { formatCurrency } from '@coingecko/cryptoformat' import { formatCurrency } from '@coingecko/cryptoformat'
import { useUserPreferences } from '@context/UserPreferences' import { useUserPreferences } from '@context/UserPreferences'
import Button from '@shared/atoms/Button' import Button from '@shared/atoms/Button'
@ -7,6 +7,7 @@ import Conversion from '@shared/Price/Conversion'
import { useWeb3 } from '@context/Web3' import { useWeb3 } from '@context/Web3'
import { getOceanConfig } from '@utils/ocean' import { getOceanConfig } from '@utils/ocean'
import styles from './Details.module.css' import styles from './Details.module.css'
import InputElement from '@shared/FormInput/InputElement'
export default function Details(): ReactElement { export default function Details(): ReactElement {
const { const {
@ -26,7 +27,7 @@ export default function Details(): ReactElement {
address: string address: string
symbol: string symbol: string
}>() }>()
// const [portisNetwork, setPortisNetwork] = useState<string>() const [portisNetwork, setPortisNetwork] = useState<string>()
useEffect(() => { useEffect(() => {
if (!networkId) return if (!networkId) return
@ -45,14 +46,14 @@ export default function Details(): ReactElement {
}, [networkData, networkId]) }, [networkData, networkId])
// Handle network change for Portis // Handle network change for Portis
// async function handlePortisNetworkChange(e: ChangeEvent<HTMLSelectElement>) { async function handlePortisNetworkChange(e: ChangeEvent<HTMLSelectElement>) {
// setPortisNetwork(e.target.value) setPortisNetwork(e.target.value)
// const portisNetworkName = e.target.value.toLowerCase() const portisNetworkName = e.target.value.toLowerCase()
// await web3Provider._portis.changeNetwork(portisNetworkName) await web3Provider._portis.changeNetwork(portisNetworkName)
// // TODO: using our connect initializes a new Portis instance, // TODO: using our connect initializes a new Portis instance,
// // which then defaults back to initial network (Mainnet). // which then defaults back to initial network (Mainnet).
// // await connect() // await connect()
// } }
return ( return (
<div className={styles.details}> <div className={styles.details}>
@ -75,7 +76,7 @@ export default function Details(): ReactElement {
<img className={styles.walletLogo} src={web3ProviderInfo?.logo} /> <img className={styles.walletLogo} src={web3ProviderInfo?.logo} />
{web3ProviderInfo?.name} {web3ProviderInfo?.name}
</span> </span>
{/* {web3ProviderInfo?.name === 'Portis' && ( {web3ProviderInfo?.name === 'Portis' && (
<InputElement <InputElement
name="network" name="network"
type="select" type="select"
@ -84,7 +85,7 @@ export default function Details(): ReactElement {
value={portisNetwork} value={portisNetwork}
onChange={handlePortisNetworkChange} onChange={handlePortisNetworkChange}
/> />
)} */} )}
{web3ProviderInfo?.name === 'MetaMask' && ( {web3ProviderInfo?.name === 'MetaMask' && (
<AddToken <AddToken
address={oceanTokenMetadata?.address} address={oceanTokenMetadata?.address}

View File

@ -1,27 +1,13 @@
import React, { useState, useEffect, ReactElement } from 'react' import React, { ReactElement } from 'react'
import Status from '@shared/atoms/Status' import Status from '@shared/atoms/Status'
import Badge from '@shared/atoms/Badge' import Badge from '@shared/atoms/Badge'
import Tooltip from '@shared/atoms/Tooltip' import Tooltip from '@shared/atoms/Tooltip'
import { useWeb3 } from '@context/Web3' import { useWeb3 } from '@context/Web3'
import NetworkName from '@shared/NetworkName' import NetworkName from '@shared/NetworkName'
import styles from './Network.module.css' import styles from './Network.module.css'
import { getOceanConfig } from '@utils/ocean'
export default function Network(): ReactElement { export default function Network(): ReactElement {
const { networkId, isTestnet } = useWeb3() const { networkId, isTestnet, isSupportedOceanNetwork } = useWeb3()
const [isSupportedOceanNetwork, setIsSupportedOceanNetwork] =
useState<boolean>()
useEffect(() => {
// take network from user when present
const network = networkId || 1
// Check networkId against ocean.js ConfigHelper configs
// to figure out if network is supported.
const isSupportedOceanNetwork = Boolean(getOceanConfig(network))
setIsSupportedOceanNetwork(isSupportedOceanNetwork)
}, [networkId])
return networkId ? ( return networkId ? (
<div className={styles.network}> <div className={styles.network}>

View File

@ -6,11 +6,11 @@ import Price from '@shared/Price'
import Tooltip from '@shared/atoms/Tooltip' import Tooltip from '@shared/atoms/Tooltip'
import AssetTitle from '@shared/AssetList/AssetListTitle' import AssetTitle from '@shared/AssetList/AssetListTitle'
import { retrieveDDOListByDIDs } from '@utils/aquarius' import { retrieveDDOListByDIDs } from '@utils/aquarius'
import { useSiteMetadata } from '@hooks/useSiteMetadata'
import { useCancelToken } from '@hooks/useCancelToken' import { useCancelToken } from '@hooks/useCancelToken'
import { AssetExtended } from 'src/@types/AssetExtended' import { AssetExtended } from 'src/@types/AssetExtended'
import { getAccessDetailsForAssets } from '@utils/accessDetailsAndPricing' import { getAccessDetailsForAssets } from '@utils/accessDetailsAndPricing'
import { useWeb3 } from '@context/Web3' import { useWeb3 } from '@context/Web3'
import { useMarketMetadata } from '@context/MarketMetadata'
const columns = [ const columns = [
{ {
@ -43,7 +43,7 @@ const columns = [
] ]
export default function Bookmarks(): ReactElement { export default function Bookmarks(): ReactElement {
const { appConfig } = useSiteMetadata() const { appConfig } = useMarketMetadata()
const { accountId } = useWeb3() const { accountId } = useWeb3()
const { bookmarks } = useUserPreferences() const { bookmarks } = useUserPreferences()

View File

@ -1,32 +1,30 @@
import { LoggerInstance } from '@oceanprotocol/lib' import { LoggerInstance } from '@oceanprotocol/lib'
import React, { useEffect, useState, ReactElement } from 'react' import React, { useEffect, useState, ReactElement } from 'react'
import { useUserPreferences } from '@context/UserPreferences' import { useUserPreferences } from '@context/UserPreferences'
import { getAccountTVLInOwnAssets, UserLiquidity } from '@utils/subgraph' import { getAccountLiquidityInOwnAssets } from '@utils/subgraph'
import Conversion from '@shared/Price/Conversion' import Conversion from '@shared/Price/Conversion'
import NumberUnit from './NumberUnit' import NumberUnit from './NumberUnit'
import styles from './Stats.module.css' import styles from './Stats.module.css'
import { useProfile } from '@context/Profile' import { useProfile } from '@context/Profile'
import { PoolShares_poolShares as PoolShare } from '../../../@types/subgraph/PoolShares' import { PoolShares_poolShares as PoolShare } from '../../../@types/subgraph/PoolShares'
import { getAccessDetailsForAssets } from '@utils/accessDetailsAndPricing' import { getAccessDetailsForAssets } from '@utils/accessDetailsAndPricing'
import { calculateUserTVL } from '@utils/pool' import { calcSingleOutGivenPoolIn } from '@utils/pool'
import Decimal from 'decimal.js' import Decimal from 'decimal.js'
import { MAX_DECIMALS } from '@utils/constants' import { MAX_DECIMALS } from '@utils/constants'
async function getPoolSharesLiquidity( function getPoolSharesLiquidity(poolShares: PoolShare[]): string {
poolShares: PoolShare[] let liquidity = new Decimal(0)
): Promise<string> {
let tvl = new Decimal(0)
for (const poolShare of poolShares) { for (const poolShare of poolShares) {
const poolUserTvl = calculateUserTVL( const poolUserLiquidity = calcSingleOutGivenPoolIn(
poolShare.shares, poolShare.pool.baseTokenLiquidity,
poolShare.pool.totalShares, poolShare.pool.totalShares,
poolShare.pool.baseTokenLiquidity poolShare.shares
) )
tvl = tvl.add(new Decimal(poolUserTvl)) liquidity = liquidity.add(new Decimal(poolUserLiquidity))
} }
return tvl.toDecimalPlaces(MAX_DECIMALS).toString() return liquidity.toDecimalPlaces(MAX_DECIMALS).toString()
} }
export default function Stats({ export default function Stats({
@ -61,7 +59,7 @@ export default function Stats({
) )
} }
} }
const userTvl = await getAccountTVLInOwnAssets( const userTvl = await getAccountLiquidityInOwnAssets(
accountId, accountId,
chainIds, chainIds,
accountPoolAdresses accountPoolAdresses
@ -91,11 +89,11 @@ export default function Stats({
return ( return (
<div className={styles.stats}> <div className={styles.stats}>
<NumberUnit <NumberUnit
label="TVL in Own Assets" label="Liquidity in Own Assets"
value={<Conversion price={publisherTvl} hideApproximateSymbol />} value={<Conversion price={publisherTvl} hideApproximateSymbol />}
/> />
<NumberUnit <NumberUnit
label="TVL" label="Liquidity"
value={<Conversion price={totalTvl} hideApproximateSymbol />} value={<Conversion price={totalTvl} hideApproximateSymbol />}
/> />
<NumberUnit label={`Sale${sales === 1 ? '' : 's'}`} value={sales} /> <NumberUnit label={`Sale${sales === 1 ? '' : 's'}`} value={sales} />

View File

@ -7,8 +7,8 @@ import { retrieveAsset } from '@utils/aquarius'
import Results from './Results' import Results from './Results'
import styles from './Details.module.css' import styles from './Details.module.css'
import { useCancelToken } from '@hooks/useCancelToken' import { useCancelToken } from '@hooks/useCancelToken'
import { useSiteMetadata } from '@hooks/useSiteMetadata'
import MetaItem from '../../../Asset/AssetContent/MetaItem' import MetaItem from '../../../Asset/AssetContent/MetaItem'
import { useMarketMetadata } from '@context/MarketMetadata'
function Asset({ function Asset({
title, title,
@ -40,7 +40,7 @@ function Asset({
} }
function DetailsAssets({ job }: { job: ComputeJobMetaData }) { function DetailsAssets({ job }: { job: ComputeJobMetaData }) {
const { appConfig } = useSiteMetadata() const { appConfig } = useMarketMetadata()
const [algoName, setAlgoName] = useState<string>() const [algoName, setAlgoName] = useState<string>()
const [algoDtSymbol, setAlgoDtSymbol] = useState<string>() const [algoDtSymbol, setAlgoDtSymbol] = useState<string>()
const newCancelToken = useCancelToken() const newCancelToken = useCancelToken()

View File

@ -1,11 +1,10 @@
import React from 'react' import React, { useEffect, useState } from 'react'
import Conversion from '@shared/Price/Conversion' import Conversion from '@shared/Price/Conversion'
import styles from './Liquidity.module.css' import styles from './Liquidity.module.css'
import Token from '../../../@shared/Token' import Token from '../../../@shared/Token'
import { isValidNumber } from '@utils/numbers'
import Decimal from 'decimal.js' import Decimal from 'decimal.js'
import { AssetPoolShare } from './index' import { AssetPoolShare } from './index'
import { calculateUserTVL } from '@utils/pool' import { calcSingleOutGivenPoolIn } from '@utils/pool'
export function Liquidity({ export function Liquidity({
row, row,
@ -14,38 +13,34 @@ export function Liquidity({
row: AssetPoolShare row: AssetPoolShare
type: string type: string
}) { }) {
let price = '0' const [liquidity, setLiquidity] = useState('0')
let liquidity = '0'
if (type === 'user') { useEffect(() => {
price = new Decimal(row.userLiquidity).mul(2).toString() let calculatedLiquidity = '0'
if (type === 'user') {
calculatedLiquidity = calcSingleOutGivenPoolIn(
row.poolShare.pool.baseTokenLiquidity,
row.poolShare.pool.totalShares,
row.poolShare.shares
)
}
if (type === 'pool') {
calculatedLiquidity = new Decimal(
row.poolShare.pool.baseTokenLiquidity
).toString()
}
setLiquidity(calculatedLiquidity)
}, [
row.poolShare.pool.baseTokenLiquidity,
row.poolShare.pool.totalShares,
row.poolShare.shares,
type
])
// Liquidity in base token, calculated from pool share tokens.
liquidity = calculateUserTVL(
row.poolShare.shares,
row.poolShare.pool.totalShares,
row.poolShare.pool.baseTokenLiquidity
)
}
if (type === 'pool') {
price =
isValidNumber(row.poolShare.pool.baseTokenLiquidity) &&
isValidNumber(row.poolShare.pool.datatokenLiquidity) &&
isValidNumber(row.poolShare.pool.spotPrice)
? new Decimal(row.poolShare.pool.datatokenLiquidity)
.mul(new Decimal(row.poolShare.pool.spotPrice))
.plus(row.poolShare.pool.baseTokenLiquidity)
.toString()
: '0'
liquidity = new Decimal(row.poolShare.pool.baseTokenLiquidity)
.mul(2)
.toString()
}
return ( return (
<div className={styles.userLiquidity}> <div className={styles.userLiquidity}>
<Conversion <Conversion
price={price} price={liquidity}
className={styles.totalLiquidity} className={styles.totalLiquidity}
hideApproximateSymbol hideApproximateSymbol
/> />

View File

@ -1,5 +1,5 @@
import { getAssetsFromDtList } from '@utils/aquarius' import { getAssetsFromDtList } from '@utils/aquarius'
import { calculateUserLiquidity } from '@utils/pool' import { calcSingleOutGivenPoolIn, getLiquidityByShares } from '@utils/pool'
import { CancelToken } from 'axios' import { CancelToken } from 'axios'
import { PoolShares_poolShares as PoolShare } from '../../../../@types/subgraph/PoolShares' import { PoolShares_poolShares as PoolShare } from '../../../../@types/subgraph/PoolShares'
import { AssetPoolShare } from '.' import { AssetPoolShare } from '.'
@ -31,10 +31,10 @@ export async function getAssetsFromPoolShares(
const ddoList = await getAssetsFromDtList(dtList, chainIds, cancelToken) const ddoList = await getAssetsFromDtList(dtList, chainIds, cancelToken)
for (let i = 0; i < data.length; i++) { for (let i = 0; i < data.length; i++) {
const userLiquidity = calculateUserLiquidity( const userLiquidity = calcSingleOutGivenPoolIn(
data[i].shares, data[i].pool.baseTokenLiquidity,
data[i].pool.totalShares, data[i].pool.totalShares,
data[i].pool.baseTokenLiquidity data[i].shares
) )
assetList.push({ assetList.push({
poolShare: data[i], poolShare: data[i],

View File

@ -38,7 +38,7 @@ const columns = [
} }
}, },
{ {
name: 'Your Value Locked', name: 'Your liquidity',
selector: function getAssetRow(row: AssetPoolShare) { selector: function getAssetRow(row: AssetPoolShare) {
return <Liquidity row={row} type="user" /> return <Liquidity row={row} type="user" />
}, },

View File

@ -2,18 +2,18 @@ import { LoggerInstance } from '@oceanprotocol/lib'
import React, { ReactElement, useEffect, useState, useCallback } from 'react' import React, { ReactElement, useEffect, useState, useCallback } from 'react'
import AssetList from '@shared/AssetList' import AssetList from '@shared/AssetList'
import { getPublishedAssets } from '@utils/aquarius' import { getPublishedAssets } from '@utils/aquarius'
import { useSiteMetadata } from '@hooks/useSiteMetadata'
import { useUserPreferences } from '@context/UserPreferences' import { useUserPreferences } from '@context/UserPreferences'
import styles from './PublishedList.module.css' import styles from './PublishedList.module.css'
import { useCancelToken } from '@hooks/useCancelToken' import { useCancelToken } from '@hooks/useCancelToken'
import Filters from '../../Search/Filters' import Filters from '../../Search/Filters'
import { useMarketMetadata } from '@context/MarketMetadata'
export default function PublishedList({ export default function PublishedList({
accountId accountId
}: { }: {
accountId: string accountId: string
}): ReactElement { }): ReactElement {
const { appConfig } = useSiteMetadata() const { appConfig } = useMarketMetadata()
const { chainIds } = useUserPreferences() const { chainIds } = useUserPreferences()
const [queryResult, setQueryResult] = useState<PagedAssets>() const [queryResult, setQueryResult] = useState<PagedAssets>()
@ -56,7 +56,7 @@ export default function PublishedList({
}, [ }, [
accountId, accountId,
page, page,
appConfig.metadataCacheUri, appConfig?.metadataCacheUri,
chainIds, chainIds,
newCancelToken, newCancelToken,
getPublished, getPublished,

View File

@ -8,3 +8,16 @@
.actions button { .actions button {
margin: 0 calc(var(--spacer) / 2); margin: 0 calc(var(--spacer) / 2);
} }
.infoIcon {
width: 0.85em;
height: 0.85em;
display: inline-block;
margin-bottom: -0.1em;
margin-left: calc(var(--spacer) / 6);
fill: currentColor;
}
.infoButton {
cursor: help !important;
pointer-events: all !important;
}

View File

@ -5,7 +5,10 @@ import { FormikContextType, useFormikContext } from 'formik'
import { FormPublishData } from '../_types' import { FormPublishData } from '../_types'
import { wizardSteps } from '../_constants' import { wizardSteps } from '../_constants'
import SuccessConfetti from '@shared/SuccessConfetti' import SuccessConfetti from '@shared/SuccessConfetti'
import { useWeb3 } from '../../../@context/Web3' import { useWeb3 } from '@context/Web3'
import Tooltip from '@shared/atoms/Tooltip'
import AvailableNetworks from 'src/components/Publish/AvailableNetworks'
import Info from '@images/info.svg'
export default function Actions({ export default function Actions({
scrollToRef, scrollToRef,
@ -14,6 +17,7 @@ export default function Actions({
scrollToRef: RefObject<any> scrollToRef: RefObject<any>
did: string did: string
}): ReactElement { }): ReactElement {
const { isSupportedOceanNetwork } = useWeb3()
const { const {
values, values,
errors, errors,
@ -78,6 +82,17 @@ export default function Actions({
<Button type="submit" style="primary" onClick={handleActivation}> <Button type="submit" style="primary" onClick={handleActivation}>
Connect Wallet Connect Wallet
</Button> </Button>
) : !isSupportedOceanNetwork ? (
<Tooltip content={<AvailableNetworks />}>
<Button
type="submit"
style="primary"
disabled
className={styles.infoButton}
>
Unsupported Network <Info className={styles.infoIcon} />
</Button>
</Tooltip>
) : ( ) : (
<Button <Button
type="submit" type="submit"

View File

@ -0,0 +1,8 @@
.button {
font-family: var(--font-family-base);
font-weight: var(--font-weight-base);
line-height: var(--line-height);
color: var(--color-secondary);
font-weight: var(--font-weight-base);
font-size: var(--font-size-small);
}

View File

@ -0,0 +1,31 @@
import React, { ReactElement } from 'react'
import NetworkName from '@shared/NetworkName'
import styles from './Network.module.css'
import Button from '@shared/atoms/Button'
import useNetworkMetadata from '@hooks/useNetworkMetadata'
import { addCustomNetwork } from '@utils/web3'
import { useWeb3 } from '@context/Web3'
export default function Network({
chainId
}: {
chainId: number
}): ReactElement {
const { networksList } = useNetworkMetadata()
const { web3Provider } = useWeb3()
function changeNetwork(chainId: number) {
const networkNode = networksList.find((data) => data.chainId === chainId)
addCustomNetwork(web3Provider, networkNode)
}
return (
<Button
style="text"
className={styles.button}
onClick={() => changeNetwork(chainId)}
>
<NetworkName key={chainId} networkId={chainId} />
</Button>
)
}

View File

@ -0,0 +1,12 @@
.networks {
column-count: 2;
}
.title {
font-size: var(--font-size-small);
margin-bottom: calc(var(--spacer) / 6);
margin-top: calc(var(--spacer) / 2);
color: var(--color-secondary);
}
.content {
padding: calc(var(--spacer) / 2);
}

View File

@ -0,0 +1,53 @@
import React, { Fragment, ReactElement } from 'react'
import styles from './index.module.css'
import Network from './Network'
import useNetworkMetadata, {
filterNetworksByType
} from '@hooks/useNetworkMetadata'
import content from '../../../../content/publish/index.json'
import { useMarketMetadata } from '@context/MarketMetadata'
export default function AvailableNetworks(): ReactElement {
const { networksList } = useNetworkMetadata()
const { appConfig } = useMarketMetadata()
const networksMain = filterNetworksByType(
'mainnet',
appConfig.chainIdsSupported,
networksList
)
const networksTest = filterNetworksByType(
'testnet',
appConfig.chainIdsSupported,
networksList
)
const networkCategories = [
{ title: 'Main', data: networksMain },
{ title: 'Test', data: networksTest }
]
const networkList = (networks: number[]) =>
networks.map((chainId) => (
<li key={chainId}>
<Network chainId={chainId} />
</li>
))
return (
<div className={styles.content}>
{content.tooltipAvailableNetworks}
{networkCategories.map(
(networkCategory) =>
networkCategory.data.length > 0 && (
<Fragment key={networkCategory.title}>
<h4 className={styles.title}>{networkCategory.title}</h4>
<ul className={styles.networks}>
{networkList(networkCategory.data)}
</ul>
</Fragment>
)
)}
</div>
)
}

View File

@ -7,7 +7,7 @@ import Error from '@shared/FormInput/Error'
import { getOpcFees } from '../../../@utils/subgraph' import { getOpcFees } from '../../../@utils/subgraph'
import { OpcFeesQuery_opc as OpcFeesData } from '../../../@types/subgraph/OpcFeesQuery' import { OpcFeesQuery_opc as OpcFeesData } from '../../../@types/subgraph/OpcFeesQuery'
import { useWeb3 } from '@context/Web3' import { useWeb3 } from '@context/Web3'
import { useSiteMetadata } from '@hooks/useSiteMetadata' import { useMarketMetadata } from '@context/MarketMetadata'
const Default = ({ const Default = ({
title, title,
@ -45,7 +45,7 @@ export default function Fees({
const [field, meta] = useField('pricing.swapFee') const [field, meta] = useField('pricing.swapFee')
const [opcFees, setOpcFees] = useState<OpcFeesData>(undefined) const [opcFees, setOpcFees] = useState<OpcFeesData>(undefined)
const { chainId } = useWeb3() const { chainId } = useWeb3()
const { appConfig } = useSiteMetadata() const { appConfig } = useMarketMetadata()
useEffect(() => { useEffect(() => {
getOpcFees(chainId || 1).then((response: OpcFeesData) => { getOpcFees(chainId || 1).then((response: OpcFeesData) => {
@ -88,8 +88,8 @@ export default function Fees({
tooltip={tooltips.marketplaceFee} tooltip={tooltips.marketplaceFee}
value={ value={
pricingType === 'dynamic' pricingType === 'dynamic'
? appConfig.publisherMarketPoolSwapFee ? appConfig?.publisherMarketPoolSwapFee
: appConfig.publisherMarketFixedSwapFee : appConfig?.publisherMarketFixedSwapFee
} }
/> />
</div> </div>

View File

@ -1,6 +1,6 @@
import Conversion from '@shared/Price/Conversion' import Conversion from '@shared/Price/Conversion'
import { Field, useField, useFormikContext } from 'formik' import { Field, useField, useFormikContext } from 'formik'
import React, { ReactElement } from 'react' import React, { ReactElement, useEffect } from 'react'
import Input from '@shared/FormInput' import Input from '@shared/FormInput'
import Error from '@shared/FormInput/Error' import Error from '@shared/FormInput/Error'
import PriceUnit from '@shared/Price/PriceUnit' import PriceUnit from '@shared/Price/PriceUnit'

View File

@ -1,6 +1,5 @@
import React, { ReactElement, useEffect } from 'react' import React, { ReactElement, useEffect } from 'react'
import { useFormikContext } from 'formik' import { useFormikContext } from 'formik'
import { useSiteMetadata } from '@hooks/useSiteMetadata'
import Tabs from '@shared/atoms/Tabs' import Tabs from '@shared/atoms/Tabs'
import { isValidNumber } from '@utils/numbers' import { isValidNumber } from '@utils/numbers'
import Decimal from 'decimal.js' import Decimal from 'decimal.js'
@ -11,9 +10,10 @@ import Fixed from './Fixed'
import Free from './Free' import Free from './Free'
import content from '../../../../content/price.json' import content from '../../../../content/price.json'
import styles from './index.module.css' import styles from './index.module.css'
import { useMarketMetadata } from '@context/MarketMetadata'
export default function PricingFields(): ReactElement { export default function PricingFields(): ReactElement {
const { appConfig } = useSiteMetadata() const { appConfig } = useMarketMetadata()
// Connect with main publish form // Connect with main publish form
const { values, setFieldValue } = useFormikContext<FormPublishData>() const { values, setFieldValue } = useFormikContext<FormPublishData>()

View File

@ -2,15 +2,21 @@
color: var(--font-color-heading); color: var(--font-color-heading);
margin-left: calc(var(--spacer) / 3); margin-left: calc(var(--spacer) / 3);
} }
.network svg { .network svg {
width: 1em; width: 1em;
height: 1em; height: 1em;
margin-top: -0.25em; margin-top: -0.25em;
fill: currentColor; fill: currentColor;
} }
.tooltip { .tooltip {
width: 0.5em; width: 0.5em;
height: 0.5em; height: 0.5em;
fill: var(--color-secondary);
}
.error {
fill: var(--brand-alert-red);
color: var(--brand-alert-red);
}
.infoIcon {
composes: infoIcon from '../Actions/index.module.css';
} }

View File

@ -3,22 +3,40 @@ import NetworkName from '@shared/NetworkName'
import Tooltip from '@shared/atoms/Tooltip' import Tooltip from '@shared/atoms/Tooltip'
import styles from './index.module.css' import styles from './index.module.css'
import content from '../../../../content/publish/index.json' import content from '../../../../content/publish/index.json'
import { useWeb3 } from '@context/Web3'
import Info from '@images/info.svg'
import AvailableNetworks from 'src/components/Publish/AvailableNetworks'
export default function Title({ export default function Title({
networkId networkId
}: { }: {
networkId: number networkId: number
}): ReactElement { }): ReactElement {
const { isSupportedOceanNetwork, accountId } = useWeb3()
return ( return (
<> <>
{content.title}{' '} {content.title}{' '}
{networkId && ( {networkId && (
<> <>
into <NetworkName networkId={networkId} className={styles.network} /> into
<Tooltip <NetworkName
content={content.tooltipNetwork} networkId={networkId}
className={styles.tooltip} className={
isSupportedOceanNetwork || !accountId
? styles.network
: `${styles.network} ${styles.error}`
}
/> />
<Tooltip
content={<AvailableNetworks />}
className={
isSupportedOceanNetwork || !accountId
? styles.tooltip
: `${styles.tooltip} ${styles.error}`
}
>
<Info className={styles.infoIcon} />
</Tooltip>
</> </>
)} )}
</> </>

View File

@ -17,7 +17,6 @@ import {
import { mapTimeoutStringToSeconds } from '@utils/ddo' import { mapTimeoutStringToSeconds } from '@utils/ddo'
import { generateNftCreateData } from '@utils/nft' import { generateNftCreateData } from '@utils/nft'
import { getEncryptedFiles } from '@utils/provider' import { getEncryptedFiles } from '@utils/provider'
import { getSiteMetadata } from '@utils/siteConfig'
import Decimal from 'decimal.js' import Decimal from 'decimal.js'
import slugify from 'slugify' import slugify from 'slugify'
import Web3 from 'web3' import Web3 from 'web3'
@ -26,6 +25,12 @@ import {
MetadataAlgorithmContainer MetadataAlgorithmContainer
} from './_constants' } from './_constants'
import { FormPublishData } from './_types' import { FormPublishData } from './_types'
import {
marketFeeAddress,
publisherMarketOrderFee,
publisherMarketPoolSwapFee,
publisherMarketFixedSwapFee
} from '../../../app.config'
export function getFieldContent( export function getFieldContent(
fieldName: string, fieldName: string,
@ -201,7 +206,6 @@ export async function createTokensAndPricing(
accountId, accountId,
values.metadata.transferable values.metadata.transferable
) )
const { appConfig } = getSiteMetadata()
LoggerInstance.log('[publish] Creating NFT with metadata', nftCreateData) LoggerInstance.log('[publish] Creating NFT with metadata', nftCreateData)
// TODO: cap is hardcoded for now to 1000, this needs to be discussed at some point // TODO: cap is hardcoded for now to 1000, this needs to be discussed at some point
@ -209,9 +213,9 @@ export async function createTokensAndPricing(
templateIndex: values.pricing.type === 'dynamic' ? 1 : 2, templateIndex: values.pricing.type === 'dynamic' ? 1 : 2,
minter: accountId, minter: accountId,
paymentCollector: accountId, paymentCollector: accountId,
mpFeeAddress: appConfig.marketFeeAddress, mpFeeAddress: marketFeeAddress,
feeToken: config.oceanTokenAddress, feeToken: config.oceanTokenAddress,
feeAmount: appConfig.publisherMarketOrderFee, feeAmount: publisherMarketOrderFee,
// max number // max number
cap: '115792089237316195423570985008687907853269984665640564039457', cap: '115792089237316195423570985008687907853269984665640564039457',
name: values.services[0].dataTokenOptions.name, name: values.services[0].dataTokenOptions.name,
@ -234,7 +238,7 @@ export async function createTokensAndPricing(
baseTokenAddress: config.oceanTokenAddress, baseTokenAddress: config.oceanTokenAddress,
baseTokenSender: config.erc721FactoryAddress, baseTokenSender: config.erc721FactoryAddress,
publisherAddress: accountId, publisherAddress: accountId,
marketFeeCollector: appConfig.marketFeeAddress, marketFeeCollector: marketFeeAddress,
poolTemplateAddress: config.poolTemplateAddress, poolTemplateAddress: config.poolTemplateAddress,
rate: new Decimal(1).div(values.pricing.price).toString(), rate: new Decimal(1).div(values.pricing.price).toString(),
baseTokenDecimals: 18, baseTokenDecimals: 18,
@ -242,7 +246,7 @@ export async function createTokensAndPricing(
vestedBlocks: 2726000, vestedBlocks: 2726000,
initialBaseTokenLiquidity: values.pricing.amountOcean.toString(), initialBaseTokenLiquidity: values.pricing.amountOcean.toString(),
swapFeeLiquidityProvider: (values.pricing.swapFee / 100).toString(), swapFeeLiquidityProvider: (values.pricing.swapFee / 100).toString(),
swapFeeMarketRunner: appConfig.publisherMarketPoolSwapFee swapFeeMarketRunner: publisherMarketPoolSwapFee
} }
LoggerInstance.log( LoggerInstance.log(
@ -286,11 +290,11 @@ export async function createTokensAndPricing(
fixedRateAddress: config.fixedRateExchangeAddress, fixedRateAddress: config.fixedRateExchangeAddress,
baseTokenAddress: config.oceanTokenAddress, baseTokenAddress: config.oceanTokenAddress,
owner: accountId, owner: accountId,
marketFeeCollector: appConfig.marketFeeAddress, marketFeeCollector: marketFeeAddress,
baseTokenDecimals: 18, baseTokenDecimals: 18,
datatokenDecimals: 18, datatokenDecimals: 18,
fixedRate: values.pricing.price.toString(), fixedRate: values.pricing.price.toString(),
marketFee: appConfig.publisherMarketFixedSwapFee, marketFee: publisherMarketFixedSwapFee,
withMint: true withMint: true
} }

View File

@ -2,6 +2,7 @@ import { MAX_DECIMALS } from '@utils/constants'
import { initialValues } from './_constants' import { initialValues } from './_constants'
import * as Yup from 'yup' import * as Yup from 'yup'
import Decimal from 'decimal.js' import Decimal from 'decimal.js'
import { getMaxDecimalsValidation } from '@utils/numbers'
// TODO: conditional validation // TODO: conditional validation
// e.g. when algo is selected, Docker image is required // e.g. when algo is selected, Docker image is required
@ -63,10 +64,6 @@ const validationService = {
}) })
} }
const maxDecimalsValidation = new RegExp(
'^\\d+(\\.\\d{1,' + MAX_DECIMALS + '})?$'
)
const validationPricing = { const validationPricing = {
type: Yup.string() type: Yup.string()
.matches(/fixed|dynamic|free/g, { excludeEmptyString: true }) .matches(/fixed|dynamic|free/g, { excludeEmptyString: true })
@ -82,7 +79,7 @@ const validationPricing = {
.test( .test(
'maxDigitsAfterDecimal', 'maxDigitsAfterDecimal',
`Must have maximum ${MAX_DECIMALS} decimal digits`, `Must have maximum ${MAX_DECIMALS} decimal digits`,
(param) => maxDecimalsValidation.test(param?.toString()) (param) => getMaxDecimalsValidation(MAX_DECIMALS).test(param?.toString())
) )
.required('Required'), .required('Required'),
amountDataToken: Yup.number().required('Required'), amountDataToken: Yup.number().required('Required'),
@ -110,7 +107,7 @@ const validationPricing = {
.test( .test(
'maxDigitsAfterDecimal', 'maxDigitsAfterDecimal',
`Must have maximum ${MAX_DECIMALS} decimal digits`, `Must have maximum ${MAX_DECIMALS} decimal digits`,
(param) => maxDecimalsValidation.test(param?.toString()) (param) => getMaxDecimalsValidation(MAX_DECIMALS).test(param?.toString())
) )
.required('Required'), .required('Required'),
weightOnDataToken: Yup.string().required('Required'), weightOnDataToken: Yup.string().required('Required'),
@ -121,7 +118,7 @@ const validationPricing = {
.test( .test(
'maxDigitsAfterDecimal', 'maxDigitsAfterDecimal',
`Must have maximum ${MAX_DECIMALS} decimal digits`, `Must have maximum ${MAX_DECIMALS} decimal digits`,
(param) => maxDecimalsValidation.test(param?.toString()) (param) => getMaxDecimalsValidation(MAX_DECIMALS).test(param?.toString())
) )
.required('Required') .required('Required')
} }

View File

@ -10,22 +10,27 @@ import App from 'src/components/App'
import '@oceanprotocol/typographies/css/ocean-typo.css' import '@oceanprotocol/typographies/css/ocean-typo.css'
import '../stylesGlobal/styles.css' import '../stylesGlobal/styles.css'
import Decimal from 'decimal.js'
import MarketMetadataProvider from '@context/MarketMetadata'
function MyApp({ Component, pageProps }: AppProps): ReactElement { function MyApp({ Component, pageProps }: AppProps): ReactElement {
Decimal.set({ rounding: 1 })
return ( return (
<Web3Provider> <MarketMetadataProvider>
<UrqlProvider> <Web3Provider>
<UserPreferencesProvider> <UrqlProvider>
<PricesProvider> <UserPreferencesProvider>
<ConsentProvider> <PricesProvider>
<App> <ConsentProvider>
<Component {...pageProps} /> <App>
</App> <Component {...pageProps} />
</ConsentProvider> </App>
</PricesProvider> </ConsentProvider>
</UserPreferencesProvider> </PricesProvider>
</UrqlProvider> </UserPreferencesProvider>
</Web3Provider> </UrqlProvider>
</Web3Provider>
</MarketMetadataProvider>
) )
} }

View File

@ -1,17 +1,17 @@
import React, { ReactElement } from 'react' import React, { ReactElement } from 'react'
import Home from '../components/Home' import Home from '../components/Home'
import { useSiteMetadata } from '@hooks/useSiteMetadata'
import Page from '@shared/Page' import Page from '@shared/Page'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import { useMarketMetadata } from '@context/MarketMetadata'
export default function PageHome(): ReactElement { export default function PageHome(): ReactElement {
const { siteTitle, siteTagline } = useSiteMetadata() const { siteContent } = useMarketMetadata()
const router = useRouter() const router = useRouter()
return ( return (
<Page <Page
title={siteTitle} title={siteContent?.siteTitle}
description={siteTagline} description={siteContent?.siteTagline}
uri={router.route} uri={router.route}
headerCenter headerCenter
> >