From 37b0f4f0473c1efcf708a64e5c908213a74af204 Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Fri, 9 Oct 2020 19:44:50 +0200 Subject: [PATCH 01/17] prototype --- .../AssetActions/Pool/Remove.module.css | 11 ++ .../organisms/AssetActions/Pool/Remove.tsx | 112 +++++++++++++----- .../organisms/AssetActions/Pool/index.tsx | 1 + 3 files changed, 93 insertions(+), 31 deletions(-) diff --git a/src/components/organisms/AssetActions/Pool/Remove.module.css b/src/components/organisms/AssetActions/Pool/Remove.module.css index fe0697c94..f565b05a7 100644 --- a/src/components/organisms/AssetActions/Pool/Remove.module.css +++ b/src/components/organisms/AssetActions/Pool/Remove.module.css @@ -4,8 +4,19 @@ .buttonMax { composes: buttonMax from './Add.module.css'; + bottom: -1rem; + right: 0; } .userLiquidity { composes: userLiquidity from './Add.module.css'; } + +.removeRow { + position: relative; + margin-bottom: var(--spacer); +} + +.removeRow:last-child { + margin-bottom: 0; +} diff --git a/src/components/organisms/AssetActions/Pool/Remove.tsx b/src/components/organisms/AssetActions/Pool/Remove.tsx index 245f1e2a1..7eae14de3 100644 --- a/src/components/organisms/AssetActions/Pool/Remove.tsx +++ b/src/components/organisms/AssetActions/Pool/Remove.tsx @@ -14,26 +14,33 @@ export default function Remove({ setShowRemove, poolAddress, totalPoolTokens, - userLiquidity + userLiquidity, + dtSymbol }: { setShowRemove: (show: boolean) => void poolAddress: string totalPoolTokens: string userLiquidity: Balance + dtSymbol: string }): ReactElement { const { ocean, accountId } = useOcean() - const [amount, setAmount] = useState('') + const [amountOcean, setAmountOcean] = useState('') + const [amountDatatoken, setAmountDatatoken] = useState('') const [isLoading, setIsLoading] = useState() const [txId, setTxId] = useState('') async function handleRemoveLiquidity() { setIsLoading(true) + // TODO: can remove OCEAN & DT in one transaction? + // exitswapExternAmountOut? exitswapPoolAmountIn? + // TODO: when user hits 'use max', use pool.exitPool() + try { const result = await ocean.pool.removeOceanLiquidity( accountId, poolAddress, - amount, + amountOcean, totalPoolTokens ) setTxId(result.transactionHash) @@ -45,12 +52,25 @@ export default function Remove({ } } - function handleAmountChange(e: ChangeEvent) { - setAmount(e.target.value) + // TODO: enforce correct weight rules + function handleOceanAmountChange(e: ChangeEvent) { + setAmountOcean(e.target.value) + setAmountDatatoken(`${Number(e.target.value) * 9}`) } - function handleMax() { - setAmount(`${userLiquidity.ocean}`) + function handleMaxOcean() { + setAmountOcean(`${userLiquidity.ocean}`) + setAmountDatatoken(`${userLiquidity.ocean * 9}`) + } + + function handleMaxDatatoken() { + setAmountDatatoken(`${userLiquidity.datatoken}`) + setAmountOcean(`${userLiquidity.ocean / 9}`) + } + + function handleDatatokenAmountChange(e: ChangeEvent) { + setAmountDatatoken(e.target.value) + setAmountOcean(`${Number(e.target.value) / 9}`) } return ( @@ -61,33 +81,63 @@ export default function Remove({ />
-
- Your pool liquidity: - -
- +
+
+ Your pool liquidity: + +
+ - {userLiquidity.ocean > Number(amount) && ( - - )} + {userLiquidity.ocean > Number(amountOcean) && ( + + )} +
+ +
+
+ Your pool liquidity: + +
+ + + {userLiquidity.datatoken > Number(amountDatatoken) && ( + + )} +
- {/* */} -

You will receive

) : ( <> From c0689585139f604d1dd1d599df713b27b199cbb7 Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Tue, 13 Oct 2020 14:02:06 +0200 Subject: [PATCH 02/17] use slider prototype --- .../AssetActions/Pool/Remove.module.css | 13 +- .../organisms/AssetActions/Pool/Remove.tsx | 128 ++++++------------ .../organisms/AssetActions/Pool/index.tsx | 1 + 3 files changed, 54 insertions(+), 88 deletions(-) diff --git a/src/components/organisms/AssetActions/Pool/Remove.module.css b/src/components/organisms/AssetActions/Pool/Remove.module.css index f565b05a7..3c7e54727 100644 --- a/src/components/organisms/AssetActions/Pool/Remove.module.css +++ b/src/components/organisms/AssetActions/Pool/Remove.module.css @@ -12,11 +12,14 @@ composes: userLiquidity from './Add.module.css'; } -.removeRow { - position: relative; - margin-bottom: var(--spacer); +.range { + text-align: center; } -.removeRow:last-child { - margin-bottom: 0; +.range h3 { + margin-bottom: calc(var(--spacer) / 4); +} + +.range input { + width: 100%; } diff --git a/src/components/organisms/AssetActions/Pool/Remove.tsx b/src/components/organisms/AssetActions/Pool/Remove.tsx index 7eae14de3..d1b017d7e 100644 --- a/src/components/organisms/AssetActions/Pool/Remove.tsx +++ b/src/components/organisms/AssetActions/Pool/Remove.tsx @@ -1,47 +1,44 @@ -import React, { ReactElement, useState, ChangeEvent } from 'react' +import React, { ReactElement, useState, ChangeEvent, useEffect } from 'react' import styles from './Remove.module.css' import { useOcean } from '@oceanprotocol/react' import Header from './Header' import { toast } from 'react-toastify' -import InputElement from '../../../atoms/Input/InputElement' import Actions from './Actions' import { Logger } from '@oceanprotocol/lib' -import Button from '../../../atoms/Button' -import PriceUnit from '../../../atoms/Price/PriceUnit' import { Balance } from '.' +import Token from './Token' export default function Remove({ setShowRemove, poolAddress, + poolTokens, totalPoolTokens, userLiquidity, dtSymbol }: { setShowRemove: (show: boolean) => void poolAddress: string + poolTokens: string totalPoolTokens: string userLiquidity: Balance dtSymbol: string }): ReactElement { const { ocean, accountId } = useOcean() - const [amountOcean, setAmountOcean] = useState('') - const [amountDatatoken, setAmountDatatoken] = useState('') + const [amountPercent, setAmountPercent] = useState('0') + const [amountPoolShares, setAmountPoolShares] = useState('0') + const [amountOcean, setAmountOcean] = useState('0') + const [amountDatatoken, setAmountDatatoken] = useState('0') const [isLoading, setIsLoading] = useState() const [txId, setTxId] = useState('') async function handleRemoveLiquidity() { setIsLoading(true) - // TODO: can remove OCEAN & DT in one transaction? - // exitswapExternAmountOut? exitswapPoolAmountIn? - // TODO: when user hits 'use max', use pool.exitPool() - try { - const result = await ocean.pool.removeOceanLiquidity( + const result = await ocean.pool.removePoolLiquidity( accountId, poolAddress, - amountOcean, - totalPoolTokens + amountPoolShares ) setTxId(result.transactionHash) } catch (error) { @@ -52,26 +49,32 @@ export default function Remove({ } } - // TODO: enforce correct weight rules - function handleOceanAmountChange(e: ChangeEvent) { - setAmountOcean(e.target.value) - setAmountDatatoken(`${Number(e.target.value) * 9}`) + function handleAmountPercentChange(e: ChangeEvent) { + setAmountPercent(e.target.value) } - function handleMaxOcean() { - setAmountOcean(`${userLiquidity.ocean}`) - setAmountDatatoken(`${userLiquidity.ocean * 9}`) - } + useEffect(() => { + if (!ocean) return - function handleMaxDatatoken() { - setAmountDatatoken(`${userLiquidity.datatoken}`) - setAmountOcean(`${userLiquidity.ocean / 9}`) - } + async function getValues() { + const amountPoolShares = + (Number(poolTokens) / Number(amountPercent)) * 100 + setAmountPoolShares(`${amountPoolShares}`) - function handleDatatokenAmountChange(e: ChangeEvent) { - setAmountDatatoken(e.target.value) - setAmountOcean(`${Number(e.target.value) / 9}`) - } + const amountOcean = await ocean.pool.getPoolSharesForRemoveOcean( + poolAddress, + `${amountPoolShares}` + ) + setAmountOcean(amountOcean) + + const amountDatatoken = await ocean.pool.getPoolSharesForRemoveDT( + poolAddress, + `${amountPoolShares}` + ) + setAmountDatatoken(amountDatatoken) + } + getValues() + }, [amountPercent, ocean, poolTokens, poolAddress]) return (
@@ -81,65 +84,24 @@ export default function Remove({ />
-
-
- Your pool liquidity: - -
- +

{amountPercent}%

+ - - {userLiquidity.ocean > Number(amountOcean) && ( - - )} -
- -
-
- Your pool liquidity: - -
- - - {userLiquidity.datatoken > Number(amountDatatoken) && ( - - )} -
+

You will receive

+ + + Date: Tue, 13 Oct 2020 14:16:50 +0200 Subject: [PATCH 03/17] make slider/output work --- .../organisms/AssetActions/Pool/Remove.tsx | 20 +++++++++---------- .../organisms/AssetActions/Pool/index.tsx | 2 -- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/components/organisms/AssetActions/Pool/Remove.tsx b/src/components/organisms/AssetActions/Pool/Remove.tsx index d1b017d7e..34dd54c57 100644 --- a/src/components/organisms/AssetActions/Pool/Remove.tsx +++ b/src/components/organisms/AssetActions/Pool/Remove.tsx @@ -5,31 +5,26 @@ import Header from './Header' import { toast } from 'react-toastify' import Actions from './Actions' import { Logger } from '@oceanprotocol/lib' -import { Balance } from '.' import Token from './Token' export default function Remove({ setShowRemove, poolAddress, poolTokens, - totalPoolTokens, - userLiquidity, dtSymbol }: { setShowRemove: (show: boolean) => void poolAddress: string poolTokens: string - totalPoolTokens: string - userLiquidity: Balance dtSymbol: string }): ReactElement { const { ocean, accountId } = useOcean() const [amountPercent, setAmountPercent] = useState('0') const [amountPoolShares, setAmountPoolShares] = useState('0') - const [amountOcean, setAmountOcean] = useState('0') - const [amountDatatoken, setAmountDatatoken] = useState('0') + const [amountOcean, setAmountOcean] = useState() + const [amountDatatoken, setAmountDatatoken] = useState() const [isLoading, setIsLoading] = useState() - const [txId, setTxId] = useState('') + const [txId, setTxId] = useState() async function handleRemoveLiquidity() { setIsLoading(true) @@ -53,12 +48,13 @@ export default function Remove({ setAmountPercent(e.target.value) } + // Check and set outputs when percentage changes useEffect(() => { - if (!ocean) return + if (!ocean || !poolTokens) return async function getValues() { const amountPoolShares = - (Number(poolTokens) / Number(amountPercent)) * 100 + (Number(amountPercent) / Number(poolTokens)) * 100 setAmountPoolShares(`${amountPoolShares}`) const amountOcean = await ocean.pool.getPoolSharesForRemoveOcean( @@ -97,6 +93,10 @@ export default function Remove({ +

You will spend

+ + +

You will receive

diff --git a/src/components/organisms/AssetActions/Pool/index.tsx b/src/components/organisms/AssetActions/Pool/index.tsx index 48d15eb46..f2a1990e1 100644 --- a/src/components/organisms/AssetActions/Pool/index.tsx +++ b/src/components/organisms/AssetActions/Pool/index.tsx @@ -129,8 +129,6 @@ export default function Pool({ ddo }: { ddo: DDO }): ReactElement { setShowRemove={setShowRemove} poolAddress={price.address} poolTokens={poolTokens} - totalPoolTokens={totalPoolTokens} - userLiquidity={userLiquidity} dtSymbol={dtSymbol} /> ) : ( From 89f4bf5aea14eacee244154f6398f218ad8ad706 Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Tue, 13 Oct 2020 18:01:17 +0200 Subject: [PATCH 04/17] method changes --- src/components/organisms/AssetActions/Pool/Remove.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/organisms/AssetActions/Pool/Remove.tsx b/src/components/organisms/AssetActions/Pool/Remove.tsx index 34dd54c57..ce5e77077 100644 --- a/src/components/organisms/AssetActions/Pool/Remove.tsx +++ b/src/components/organisms/AssetActions/Pool/Remove.tsx @@ -57,13 +57,13 @@ export default function Remove({ (Number(amountPercent) / Number(poolTokens)) * 100 setAmountPoolShares(`${amountPoolShares}`) - const amountOcean = await ocean.pool.getPoolSharesForRemoveOcean( + const amountOcean = await ocean.pool.getOceanRemovedforPoolShares( poolAddress, `${amountPoolShares}` ) setAmountOcean(amountOcean) - const amountDatatoken = await ocean.pool.getPoolSharesForRemoveDT( + const amountDatatoken = await ocean.pool.getDTRemovedforPoolShares( poolAddress, `${amountPoolShares}` ) From 36d1289a8e17cfc44a68136463ef84a83fbe965b Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Tue, 13 Oct 2020 18:13:34 +0200 Subject: [PATCH 05/17] percentage is hard --- src/components/organisms/AssetActions/Pool/Remove.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/organisms/AssetActions/Pool/Remove.tsx b/src/components/organisms/AssetActions/Pool/Remove.tsx index ce5e77077..e7fa9e355 100644 --- a/src/components/organisms/AssetActions/Pool/Remove.tsx +++ b/src/components/organisms/AssetActions/Pool/Remove.tsx @@ -54,7 +54,7 @@ export default function Remove({ async function getValues() { const amountPoolShares = - (Number(amountPercent) / Number(poolTokens)) * 100 + (Number(amountPercent) / 100) * Number(poolTokens) setAmountPoolShares(`${amountPoolShares}`) const amountOcean = await ocean.pool.getOceanRemovedforPoolShares( From 1a71f0f66f1df72c4071edf2cd5c4f2a105b1692 Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Wed, 14 Oct 2020 10:26:00 +0200 Subject: [PATCH 06/17] remove liquidity in OCEAN only --- .../organisms/AssetActions/Pool/Remove.tsx | 15 ++++----------- .../organisms/AssetActions/Pool/index.tsx | 1 - 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/components/organisms/AssetActions/Pool/Remove.tsx b/src/components/organisms/AssetActions/Pool/Remove.tsx index e7fa9e355..12f6b095f 100644 --- a/src/components/organisms/AssetActions/Pool/Remove.tsx +++ b/src/components/organisms/AssetActions/Pool/Remove.tsx @@ -10,19 +10,16 @@ import Token from './Token' export default function Remove({ setShowRemove, poolAddress, - poolTokens, - dtSymbol + poolTokens }: { setShowRemove: (show: boolean) => void poolAddress: string poolTokens: string - dtSymbol: string }): ReactElement { const { ocean, accountId } = useOcean() const [amountPercent, setAmountPercent] = useState('0') const [amountPoolShares, setAmountPoolShares] = useState('0') const [amountOcean, setAmountOcean] = useState() - const [amountDatatoken, setAmountDatatoken] = useState() const [isLoading, setIsLoading] = useState() const [txId, setTxId] = useState() @@ -52,6 +49,9 @@ export default function Remove({ useEffect(() => { if (!ocean || !poolTokens) return + // TODO: check max amount to be able to remove + // getOceanMaxRemoveLiquidity() + async function getValues() { const amountPoolShares = (Number(amountPercent) / 100) * Number(poolTokens) @@ -62,12 +62,6 @@ export default function Remove({ `${amountPoolShares}` ) setAmountOcean(amountOcean) - - const amountDatatoken = await ocean.pool.getDTRemovedforPoolShares( - poolAddress, - `${amountPoolShares}` - ) - setAmountDatatoken(amountDatatoken) } getValues() }, [amountPercent, ocean, poolTokens, poolAddress]) @@ -100,7 +94,6 @@ export default function Remove({

You will receive

- ) : ( <> From 96ce7b518b59f9b63120d4383436a2556823d43d Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Wed, 14 Oct 2020 10:32:25 +0200 Subject: [PATCH 07/17] add help copy --- .../organisms/AssetActions/Pool/Remove.module.css | 12 ++++++------ .../organisms/AssetActions/Pool/Remove.tsx | 5 +++++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/components/organisms/AssetActions/Pool/Remove.module.css b/src/components/organisms/AssetActions/Pool/Remove.module.css index 3c7e54727..360910e0a 100644 --- a/src/components/organisms/AssetActions/Pool/Remove.module.css +++ b/src/components/organisms/AssetActions/Pool/Remove.module.css @@ -1,11 +1,7 @@ .removeInput { composes: addInput from './Add.module.css'; -} - -.buttonMax { - composes: buttonMax from './Add.module.css'; - bottom: -1rem; - right: 0; + padding-left: calc(var(--spacer) * 2); + padding-right: calc(var(--spacer) * 2); } .userLiquidity { @@ -23,3 +19,7 @@ .range input { width: 100%; } + +.range p { + margin-bottom: 0; +} diff --git a/src/components/organisms/AssetActions/Pool/Remove.tsx b/src/components/organisms/AssetActions/Pool/Remove.tsx index 12f6b095f..c16279bd1 100644 --- a/src/components/organisms/AssetActions/Pool/Remove.tsx +++ b/src/components/organisms/AssetActions/Pool/Remove.tsx @@ -6,6 +6,7 @@ import { toast } from 'react-toastify' import Actions from './Actions' import { Logger } from '@oceanprotocol/lib' import Token from './Token' +import FormHelp from '../../../atoms/Input/Help' export default function Remove({ setShowRemove, @@ -84,6 +85,10 @@ export default function Remove({ value={amountPercent} onChange={handleAmountPercentChange} /> + + Set the amount of your pool shares to spend. You will get the + equivalent value in OCEAN. + From 207b61933a711b76647271ae354b4cc6e63f6821 Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Wed, 14 Oct 2020 12:04:55 +0200 Subject: [PATCH 08/17] combine both flows --- .../AssetActions/Pool/Remove.module.css | 8 +++ .../organisms/AssetActions/Pool/Remove.tsx | 69 +++++++++++++++---- .../organisms/AssetActions/Pool/index.tsx | 1 + 3 files changed, 66 insertions(+), 12 deletions(-) diff --git a/src/components/organisms/AssetActions/Pool/Remove.module.css b/src/components/organisms/AssetActions/Pool/Remove.module.css index 360910e0a..9451a224b 100644 --- a/src/components/organisms/AssetActions/Pool/Remove.module.css +++ b/src/components/organisms/AssetActions/Pool/Remove.module.css @@ -2,6 +2,7 @@ composes: addInput from './Add.module.css'; padding-left: calc(var(--spacer) * 2); padding-right: calc(var(--spacer) * 2); + padding-bottom: calc(var(--spacer) / 2); } .userLiquidity { @@ -22,4 +23,11 @@ .range p { margin-bottom: 0; + margin-left: -2rem; + margin-right: -2rem; +} + +.range button { + margin-top: calc(var(--spacer) / 4); + margin-bottom: 0; } diff --git a/src/components/organisms/AssetActions/Pool/Remove.tsx b/src/components/organisms/AssetActions/Pool/Remove.tsx index c16279bd1..881edd301 100644 --- a/src/components/organisms/AssetActions/Pool/Remove.tsx +++ b/src/components/organisms/AssetActions/Pool/Remove.tsx @@ -1,4 +1,10 @@ -import React, { ReactElement, useState, ChangeEvent, useEffect } from 'react' +import React, { + ReactElement, + useState, + ChangeEvent, + useEffect, + FormEvent +} from 'react' import styles from './Remove.module.css' import { useOcean } from '@oceanprotocol/react' import Header from './Header' @@ -7,20 +13,32 @@ import Actions from './Actions' import { Logger } from '@oceanprotocol/lib' import Token from './Token' import FormHelp from '../../../atoms/Input/Help' +import Button from '../../../atoms/Button' + +const help = { + simple: + 'You will get the equivalent value in OCEAN, limited to xxx% of the total liquidity.', + advanced: + 'You will get OCEAN and Datatokens equivalent to your pool share, without any limit.' +} export default function Remove({ setShowRemove, poolAddress, - poolTokens + poolTokens, + dtSymbol }: { setShowRemove: (show: boolean) => void poolAddress: string poolTokens: string + dtSymbol: string }): ReactElement { const { ocean, accountId } = useOcean() const [amountPercent, setAmountPercent] = useState('0') const [amountPoolShares, setAmountPoolShares] = useState('0') const [amountOcean, setAmountOcean] = useState() + const [amountDatatoken, setAmountDatatoken] = useState() + const [isAdvanced, setIsAdvanced] = useState(false) const [isLoading, setIsLoading] = useState() const [txId, setTxId] = useState() @@ -28,12 +46,21 @@ export default function Remove({ setIsLoading(true) try { - const result = await ocean.pool.removePoolLiquidity( - accountId, - poolAddress, - amountPoolShares - ) - setTxId(result.transactionHash) + const result = + isAdvanced === true + ? await ocean.pool.removePoolLiquidity( + accountId, + poolAddress, + amountPoolShares + ) + : await ocean.pool.removeOceanLiquidity( + accountId, + poolAddress, + amountDatatoken, + amountPoolShares + ) + + setTxId(result?.transactionHash) } catch (error) { Logger.error(error.message) toast.error(error.message) @@ -46,6 +73,11 @@ export default function Remove({ setAmountPercent(e.target.value) } + function handleAdvancedButton(e: FormEvent) { + e.preventDefault() + setIsAdvanced(!isAdvanced) + } + // Check and set outputs when percentage changes useEffect(() => { if (!ocean || !poolTokens) return @@ -63,9 +95,17 @@ export default function Remove({ `${amountPoolShares}` ) setAmountOcean(amountOcean) + + if (!isAdvanced) return + + const amountDatatoken = await ocean.pool.getDTRemovedforPoolShares( + poolAddress, + `${amountPoolShares}` + ) + setAmountDatatoken(amountDatatoken) } getValues() - }, [amountPercent, ocean, poolTokens, poolAddress]) + }, [amountPercent, ocean, poolTokens, poolAddress, isAdvanced]) return (
@@ -81,14 +121,18 @@ export default function Remove({ type="range" min="0" max="100" - step="25" + step="10" value={amountPercent} onChange={handleAmountPercentChange} /> - Set the amount of your pool shares to spend. You will get the - equivalent value in OCEAN. + {`Set the amount of your pool shares to spend. ${ + isAdvanced === true ? help.advanced : help.simple + }`} +
@@ -99,6 +143,7 @@ export default function Remove({

You will receive

+ {isAdvanced && } ) : ( <> From 0a248b36a1832c0cd315c5983e48f579a96236b8 Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Wed, 14 Oct 2020 12:58:10 +0200 Subject: [PATCH 09/17] refactor token checks * requires https://github.com/oceanprotocol/ocean.js/pull/361 --- .../AssetActions/Pool/Remove.module.css | 16 ++++++ .../organisms/AssetActions/Pool/Remove.tsx | 55 +++++++++++-------- 2 files changed, 47 insertions(+), 24 deletions(-) diff --git a/src/components/organisms/AssetActions/Pool/Remove.module.css b/src/components/organisms/AssetActions/Pool/Remove.module.css index 9451a224b..9549df334 100644 --- a/src/components/organisms/AssetActions/Pool/Remove.module.css +++ b/src/components/organisms/AssetActions/Pool/Remove.module.css @@ -31,3 +31,19 @@ margin-top: calc(var(--spacer) / 4); margin-bottom: 0; } + +.output { + composes: output from './Add.module.css'; +} + +.output [class*='token'] { + white-space: nowrap; +} + +.output [class*='token'] > figure { + display: inline-block; +} + +.output figure[class*='pool shares'] { + display: none; +} diff --git a/src/components/organisms/AssetActions/Pool/Remove.tsx b/src/components/organisms/AssetActions/Pool/Remove.tsx index 881edd301..a1215b344 100644 --- a/src/components/organisms/AssetActions/Pool/Remove.tsx +++ b/src/components/organisms/AssetActions/Pool/Remove.tsx @@ -82,30 +82,34 @@ export default function Remove({ useEffect(() => { if (!ocean || !poolTokens) return - // TODO: check max amount to be able to remove - // getOceanMaxRemoveLiquidity() - async function getValues() { const amountPoolShares = (Number(amountPercent) / 100) * Number(poolTokens) setAmountPoolShares(`${amountPoolShares}`) - const amountOcean = await ocean.pool.getOceanRemovedforPoolShares( - poolAddress, - `${amountPoolShares}` - ) - setAmountOcean(amountOcean) + if (isAdvanced === true) { + const tokens = await ocean.pool.getTokensRemovedforPoolShares( + poolAddress, + `${amountPoolShares}` + ) + setAmountOcean(tokens?.oceanAmount) + setAmountDatatoken(tokens?.dtAmount) + } else { + // TODO: check max amount to be able to remove + const maxOcean = await ocean.pool.getOceanMaxRemoveLiquidity( + poolAddress + ) + console.log(maxOcean) - if (!isAdvanced) return - - const amountDatatoken = await ocean.pool.getDTRemovedforPoolShares( - poolAddress, - `${amountPoolShares}` - ) - setAmountDatatoken(amountDatatoken) + const amountOcean = await ocean.pool.getOceanRemovedforPoolShares( + poolAddress, + `${amountPoolShares}` + ) + setAmountOcean(amountOcean) + } } getValues() - }, [amountPercent, ocean, poolTokens, poolAddress, isAdvanced]) + }, [amountPercent, isAdvanced, ocean, poolTokens, poolAddress]) return (
@@ -136,14 +140,17 @@ export default function Remove({
-

You will spend

- - - -

You will receive

- - - {isAdvanced && } +
+
+

You will spend

+ +
+
+

You will receive

+ + {isAdvanced && } +
+
Date: Wed, 14 Oct 2020 15:11:03 +0200 Subject: [PATCH 10/17] prepare max checks --- .../organisms/AssetActions/Pool/Remove.tsx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/components/organisms/AssetActions/Pool/Remove.tsx b/src/components/organisms/AssetActions/Pool/Remove.tsx index a1215b344..4bbc8ac15 100644 --- a/src/components/organisms/AssetActions/Pool/Remove.tsx +++ b/src/components/organisms/AssetActions/Pool/Remove.tsx @@ -35,6 +35,7 @@ export default function Remove({ }): ReactElement { const { ocean, accountId } = useOcean() const [amountPercent, setAmountPercent] = useState('0') + const [amountMaxPercent, setAmountMaxPercent] = useState('100') const [amountPoolShares, setAmountPoolShares] = useState('0') const [amountOcean, setAmountOcean] = useState() const [amountDatatoken, setAmountDatatoken] = useState() @@ -95,11 +96,15 @@ export default function Remove({ setAmountOcean(tokens?.oceanAmount) setAmountDatatoken(tokens?.dtAmount) } else { - // TODO: check max amount to be able to remove - const maxOcean = await ocean.pool.getOceanMaxRemoveLiquidity( + const amountMaxOcean = await ocean.pool.getOceanMaxRemoveLiquidity( poolAddress ) - console.log(maxOcean) + console.log(amountMaxOcean) + + // TODO: Calculate maximum percentage a user can remove based on maximum OCEAN + // to limit the range slider + // const maxPercent = ?? + // setAmountMaxPercent(maxPercent) const amountOcean = await ocean.pool.getOceanRemovedforPoolShares( poolAddress, @@ -124,7 +129,7 @@ export default function Remove({ Date: Wed, 14 Oct 2020 15:57:30 +0200 Subject: [PATCH 11/17] max checks --- .../AssetActions/Pool/Remove.module.css | 14 ++++ .../organisms/AssetActions/Pool/Remove.tsx | 68 +++++++++++++------ 2 files changed, 61 insertions(+), 21 deletions(-) diff --git a/src/components/organisms/AssetActions/Pool/Remove.module.css b/src/components/organisms/AssetActions/Pool/Remove.module.css index 9549df334..9c279b9a5 100644 --- a/src/components/organisms/AssetActions/Pool/Remove.module.css +++ b/src/components/organisms/AssetActions/Pool/Remove.module.css @@ -32,6 +32,20 @@ margin-bottom: 0; } +.slider { + position: relative; + z-index: 1; +} + +.maximum { + position: absolute; + right: -1.5rem; + bottom: 1.5rem; + font-size: var(--font-size-small); + z-index: 0; + pointer-events: none; +} + .output { composes: output from './Add.module.css'; } diff --git a/src/components/organisms/AssetActions/Pool/Remove.tsx b/src/components/organisms/AssetActions/Pool/Remove.tsx index 4bbc8ac15..c9130e969 100644 --- a/src/components/organisms/AssetActions/Pool/Remove.tsx +++ b/src/components/organisms/AssetActions/Pool/Remove.tsx @@ -10,18 +10,45 @@ import { useOcean } from '@oceanprotocol/react' import Header from './Header' import { toast } from 'react-toastify' import Actions from './Actions' -import { Logger } from '@oceanprotocol/lib' +import { Logger, Ocean } from '@oceanprotocol/lib' import Token from './Token' import FormHelp from '../../../atoms/Input/Help' import Button from '../../../atoms/Button' const help = { simple: - 'You will get the equivalent value in OCEAN, limited to xxx% of the total liquidity.', + 'You will get the equivalent value in OCEAN, limited to 60% of the total liquidity.', advanced: 'You will get OCEAN and Datatokens equivalent to your pool share, without any limit.' } +async function getMaxValues( + ocean: Ocean, + poolAddress: string, + poolTokens: string, + amountPoolShares: string +) { + const amountMaxOcean = await ocean.pool.getOceanMaxRemoveLiquidity( + poolAddress + ) + + const amountMaxPoolShares = await ocean.pool.getPoolSharesRequiredToRemoveOcean( + poolAddress, + amountMaxOcean + ) + + const amountMaxPercent = `${Math.floor( + (Number(amountMaxPoolShares) / Number(poolTokens)) * 100 + )}` + + const amountOcean = await ocean.pool.getOceanRemovedforPoolShares( + poolAddress, + amountPoolShares + ) + + return { amountMaxPercent, amountOcean } +} + export default function Remove({ setShowRemove, poolAddress, @@ -96,20 +123,13 @@ export default function Remove({ setAmountOcean(tokens?.oceanAmount) setAmountDatatoken(tokens?.dtAmount) } else { - const amountMaxOcean = await ocean.pool.getOceanMaxRemoveLiquidity( - poolAddress - ) - console.log(amountMaxOcean) - - // TODO: Calculate maximum percentage a user can remove based on maximum OCEAN - // to limit the range slider - // const maxPercent = ?? - // setAmountMaxPercent(maxPercent) - - const amountOcean = await ocean.pool.getOceanRemovedforPoolShares( + const { amountMaxPercent, amountOcean } = await getMaxValues( + ocean, poolAddress, + poolTokens, `${amountPoolShares}` ) + setAmountMaxPercent(amountMaxPercent) setAmountOcean(amountOcean) } } @@ -126,14 +146,20 @@ export default function Remove({

{amountPercent}%

- +
+ + {`${amountMaxPercent}% max.`} +
+ {`Set the amount of your pool shares to spend. ${ isAdvanced === true ? help.advanced : help.simple From 2646e181cf89cbac7fe8617cbd994a9526fb2c6f Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Wed, 14 Oct 2020 16:02:26 +0200 Subject: [PATCH 12/17] reset range slider on view switch --- .../organisms/AssetActions/Pool/Remove.tsx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/components/organisms/AssetActions/Pool/Remove.tsx b/src/components/organisms/AssetActions/Pool/Remove.tsx index c9130e969..fa1b1d3c8 100644 --- a/src/components/organisms/AssetActions/Pool/Remove.tsx +++ b/src/components/organisms/AssetActions/Pool/Remove.tsx @@ -64,8 +64,8 @@ export default function Remove({ const [amountPercent, setAmountPercent] = useState('0') const [amountMaxPercent, setAmountMaxPercent] = useState('100') const [amountPoolShares, setAmountPoolShares] = useState('0') - const [amountOcean, setAmountOcean] = useState() - const [amountDatatoken, setAmountDatatoken] = useState() + const [amountOcean, setAmountOcean] = useState('0') + const [amountDatatoken, setAmountDatatoken] = useState('0') const [isAdvanced, setIsAdvanced] = useState(false) const [isLoading, setIsLoading] = useState() const [txId, setTxId] = useState() @@ -116,6 +116,8 @@ export default function Remove({ setAmountPoolShares(`${amountPoolShares}`) if (isAdvanced === true) { + setAmountMaxPercent('100') + const tokens = await ocean.pool.getTokensRemovedforPoolShares( poolAddress, `${amountPoolShares}` @@ -155,9 +157,11 @@ export default function Remove({ value={amountPercent} onChange={handleAmountPercentChange} /> - {`${amountMaxPercent}% max.`} + {isAdvanced === false && ( + {`${amountMaxPercent}% max.`} + )}
From 959158d82a4faabec6db273018c0bc4a2851264a Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Wed, 14 Oct 2020 16:08:49 +0200 Subject: [PATCH 13/17] refactor --- .../organisms/AssetActions/Pool/Remove.tsx | 36 ++++--------------- .../organisms/AssetActions/Pool/utils.ts | 28 +++++++++++++++ 2 files changed, 34 insertions(+), 30 deletions(-) create mode 100644 src/components/organisms/AssetActions/Pool/utils.ts diff --git a/src/components/organisms/AssetActions/Pool/Remove.tsx b/src/components/organisms/AssetActions/Pool/Remove.tsx index fa1b1d3c8..9f50ba387 100644 --- a/src/components/organisms/AssetActions/Pool/Remove.tsx +++ b/src/components/organisms/AssetActions/Pool/Remove.tsx @@ -10,10 +10,11 @@ import { useOcean } from '@oceanprotocol/react' import Header from './Header' import { toast } from 'react-toastify' import Actions from './Actions' -import { Logger, Ocean } from '@oceanprotocol/lib' +import { Logger } from '@oceanprotocol/lib' import Token from './Token' import FormHelp from '../../../atoms/Input/Help' import Button from '../../../atoms/Button' +import { getMaxValuesRemove } from './utils' const help = { simple: @@ -22,33 +23,6 @@ const help = { 'You will get OCEAN and Datatokens equivalent to your pool share, without any limit.' } -async function getMaxValues( - ocean: Ocean, - poolAddress: string, - poolTokens: string, - amountPoolShares: string -) { - const amountMaxOcean = await ocean.pool.getOceanMaxRemoveLiquidity( - poolAddress - ) - - const amountMaxPoolShares = await ocean.pool.getPoolSharesRequiredToRemoveOcean( - poolAddress, - amountMaxOcean - ) - - const amountMaxPercent = `${Math.floor( - (Number(amountMaxPoolShares) / Number(poolTokens)) * 100 - )}` - - const amountOcean = await ocean.pool.getOceanRemovedforPoolShares( - poolAddress, - amountPoolShares - ) - - return { amountMaxPercent, amountOcean } -} - export default function Remove({ setShowRemove, poolAddress, @@ -125,7 +99,7 @@ export default function Remove({ setAmountOcean(tokens?.oceanAmount) setAmountDatatoken(tokens?.dtAmount) } else { - const { amountMaxPercent, amountOcean } = await getMaxValues( + const { amountMaxPercent, amountOcean } = await getMaxValuesRemove( ocean, poolAddress, poolTokens, @@ -183,7 +157,9 @@ export default function Remove({

You will receive

- {isAdvanced && } + {isAdvanced === true && ( + + )}
diff --git a/src/components/organisms/AssetActions/Pool/utils.ts b/src/components/organisms/AssetActions/Pool/utils.ts new file mode 100644 index 000000000..31dc46622 --- /dev/null +++ b/src/components/organisms/AssetActions/Pool/utils.ts @@ -0,0 +1,28 @@ +import { Ocean } from '@oceanprotocol/lib' + +export async function getMaxValuesRemove( + ocean: Ocean, + poolAddress: string, + poolTokens: string, + amountPoolShares: string +): Promise<{ amountMaxPercent: string; amountOcean: string }> { + const amountMaxOcean = await ocean.pool.getOceanMaxRemoveLiquidity( + poolAddress + ) + + const amountMaxPoolShares = await ocean.pool.getPoolSharesRequiredToRemoveOcean( + poolAddress, + amountMaxOcean + ) + + const amountMaxPercent = `${Math.floor( + (Number(amountMaxPoolShares) / Number(poolTokens)) * 100 + )}` + + const amountOcean = await ocean.pool.getOceanRemovedforPoolShares( + poolAddress, + amountPoolShares + ) + + return { amountMaxPercent, amountOcean } +} From abc70b9caecda42870eb4d71a50e1c8a869f58a5 Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Wed, 14 Oct 2020 18:21:47 +0200 Subject: [PATCH 14/17] bump ocean.js --- package-lock.json | 6 +++--- package.json | 2 +- .../organisms/AssetActions/Pool/Remove.module.css | 5 ++++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0d240d135..2e11bde5a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4029,9 +4029,9 @@ "integrity": "sha512-LING+GvW37I0L40rZdPCZ1SvcZurDSGGhT0WOVPNO8oyh2C3bXModDBNE4+gCFa8pTbQBOc4ot1/Zoj9PfT/zA==" }, "@oceanprotocol/lib": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-0.6.1.tgz", - "integrity": "sha512-nU+sBTpGdoCaZkzOBkZxwEtjSsxFQ9YDK3C3a8iuxoY60Cd1OfoiG4toBWF3yLgXaXkaiYPufZ6rL4sJKakHKg==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-0.6.2.tgz", + "integrity": "sha512-hqZCzJXU+P8lnal+H329UHXfoLHAgjYw+foWxG466KcrQ66TtcdpGIMKMNev+A990P8KzueC8mC62BLGj6//Gg==", "requires": { "@ethereum-navigator/navigator": "^0.5.0", "@oceanprotocol/contracts": "^0.5.5", diff --git a/package.json b/package.json index c5b8acc92..9f36f426f 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "@coingecko/cryptoformat": "^0.4.2", "@loadable/component": "5.13.1", "@oceanprotocol/art": "^3.0.0", - "@oceanprotocol/lib": "^0.6.1", + "@oceanprotocol/lib": "^0.6.2", "@oceanprotocol/react": "^0.2.0", "@oceanprotocol/typographies": "^0.1.0", "@sindresorhus/slugify": "^1.0.0", diff --git a/src/components/organisms/AssetActions/Pool/Remove.module.css b/src/components/organisms/AssetActions/Pool/Remove.module.css index 9c279b9a5..ff4201a04 100644 --- a/src/components/organisms/AssetActions/Pool/Remove.module.css +++ b/src/components/organisms/AssetActions/Pool/Remove.module.css @@ -2,7 +2,6 @@ composes: addInput from './Add.module.css'; padding-left: calc(var(--spacer) * 2); padding-right: calc(var(--spacer) * 2); - padding-bottom: calc(var(--spacer) / 2); } .userLiquidity { @@ -30,6 +29,10 @@ .range button { margin-top: calc(var(--spacer) / 4); margin-bottom: 0; + position: absolute; + bottom: 1rem; + right: 2rem; + font-size: var(--font-size-mini); } .slider { From 287eea3c947df1f6a6989f5fad887f4bd7cd6d9b Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Wed, 14 Oct 2020 19:08:46 +0200 Subject: [PATCH 15/17] move all pool copy into content data file --- content/price.json | 26 ++++++++++ .../organisms/AssetActions/Pool/Add.tsx | 34 +++++++++++-- .../organisms/AssetActions/Pool/Remove.tsx | 48 ++++++++++++------- .../organisms/AssetActions/Pool/index.tsx | 29 +++++++++-- 4 files changed, 112 insertions(+), 25 deletions(-) create mode 100644 content/price.json diff --git a/content/price.json b/content/price.json new file mode 100644 index 000000000..dddfa663d --- /dev/null +++ b/content/price.json @@ -0,0 +1,26 @@ +{ + "pool": { + "tooltips": { + "price": "Explain how this price is determined...", + "liquidity": "Explain what this represents, advantage of providing liquidity..." + }, + "add": { + "title": "Add Liquidity", + "output": { + "titleIn": "You will receive", + "titleOut": "You will earn" + }, + "action": "Supply" + }, + "remove": { + "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.", + "advanced": "Set the amount of your pool shares to spend. You will get OCEAN and Datatokens equivalent to your pool share, without any limit.", + "output": { + "titleIn": "You will spend", + "titleOut": "You will receive" + }, + "action": "Remove" + } + } +} diff --git a/src/components/organisms/AssetActions/Pool/Add.tsx b/src/components/organisms/AssetActions/Pool/Add.tsx index c8b3fdbc7..0aa9f2033 100644 --- a/src/components/organisms/AssetActions/Pool/Add.tsx +++ b/src/components/organisms/AssetActions/Pool/Add.tsx @@ -11,6 +11,29 @@ import PriceUnit from '../../../atoms/Price/PriceUnit' import Actions from './Actions' import Tooltip from '../../../atoms/Tooltip' import { ReactComponent as Caret } from '../../../../images/caret.svg' +import { graphql, useStaticQuery } from 'gatsby' + +const contentQuery = graphql` + query PoolAddQuery { + content: allFile(filter: { relativePath: { eq: "price.json" } }) { + edges { + node { + childContentJson { + pool { + add { + output { + titleIn + titleOut + } + action + } + } + } + } + } + } + } +` export default function Add({ setShowAdd, @@ -29,6 +52,9 @@ export default function Add({ dtSymbol: string dtAddress: string }): ReactElement { + const data = useStaticQuery(contentQuery) + const content = data.content.edges[0].node.childContentJson.pool.add + const { ocean, accountId, balance } = useOcean() const [amount, setAmount] = useState('') const [txId, setTxId] = useState('') @@ -93,7 +119,7 @@ export default function Add({ return ( <> -
setShowAdd(false)} /> +
setShowAdd(false)} />
@@ -138,12 +164,12 @@ export default function Add({
-

You will receive

+

{content.output.titleIn}

-

You will earn

+

{content.output.titleOut}

@@ -151,7 +177,7 @@ export default function Add({ diff --git a/src/components/organisms/AssetActions/Pool/Remove.tsx b/src/components/organisms/AssetActions/Pool/Remove.tsx index 9f50ba387..16c911330 100644 --- a/src/components/organisms/AssetActions/Pool/Remove.tsx +++ b/src/components/organisms/AssetActions/Pool/Remove.tsx @@ -15,13 +15,31 @@ import Token from './Token' import FormHelp from '../../../atoms/Input/Help' import Button from '../../../atoms/Button' import { getMaxValuesRemove } from './utils' +import { graphql, useStaticQuery } from 'gatsby' -const help = { - simple: - 'You will get the equivalent value in OCEAN, limited to 60% of the total liquidity.', - advanced: - 'You will get OCEAN and Datatokens equivalent to your pool share, without any limit.' -} +const contentQuery = graphql` + query PoolRemoveQuery { + content: allFile(filter: { relativePath: { eq: "price.json" } }) { + edges { + node { + childContentJson { + pool { + remove { + simple + advanced + output { + titleIn + titleOut + } + action + } + } + } + } + } + } + } +` export default function Remove({ setShowRemove, @@ -34,6 +52,9 @@ export default function Remove({ poolTokens: string dtSymbol: string }): ReactElement { + const data = useStaticQuery(contentQuery) + const content = data.content.edges[0].node.childContentJson.pool.remove + const { ocean, accountId } = useOcean() const [amountPercent, setAmountPercent] = useState('0') const [amountMaxPercent, setAmountMaxPercent] = useState('100') @@ -114,10 +135,7 @@ export default function Remove({ return (
-
setShowRemove(false)} - /> +
setShowRemove(false)} />
@@ -139,9 +157,7 @@ export default function Remove({
- {`Set the amount of your pool shares to spend. ${ - isAdvanced === true ? help.advanced : help.simple - }`} + {isAdvanced === true ? content.advanced : content.simple}