From 8f93d9bc2fb536e7a0a521b4600754b0d3b1ce26 Mon Sep 17 00:00:00 2001 From: Bogdan Fazakas Date: Wed, 30 Mar 2022 16:06:40 +0300 Subject: [PATCH 1/8] bump oceanlib to 1.0.0-next.32 (#1282) --- package-lock.json | 16 +++++++--------- package.json | 2 +- src/components/Publish/_utils.ts | 2 +- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 038ba2c99..1feff6753 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@coingecko/cryptoformat": "^0.4.4", "@loadable/component": "^5.15.2", "@oceanprotocol/art": "^3.2.0", - "@oceanprotocol/lib": "^1.0.0-next.29", + "@oceanprotocol/lib": "^1.0.0-next.32", "@oceanprotocol/typographies": "^0.1.0", "@portis/web3": "^4.0.7", "@tippyjs/react": "^4.2.6", @@ -3404,9 +3404,9 @@ } }, "node_modules/@oceanprotocol/lib": { - "version": "1.0.0-next.29", - "resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-1.0.0-next.29.tgz", - "integrity": "sha512-/QualMxcT8XvnhZ/ixtShI7MVQn6Arkg0R9f8lMeQw4Dyykh7ZuIlfJxvIjzsMeSavdAgt2BIy1slzr6Z5VtyA==", + "version": "1.0.0-next.32", + "resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-1.0.0-next.32.tgz", + "integrity": "sha512-J+4A2rIE8IAXLCGBhyXuWM+0gwJxXf3JG/3XBZEhjMvWUNFEGeJLD26fr7evQY13Oy9mXHyUpp6rQxxHvE2/zA==", "dependencies": { "@oceanprotocol/contracts": "1.0.0-alpha.26", "bignumber.js": "^9.0.2", @@ -26719,16 +26719,15 @@ } }, "@oceanprotocol/lib": { - "version": "1.0.0-next.29", - "resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-1.0.0-next.29.tgz", - "integrity": "sha512-/QualMxcT8XvnhZ/ixtShI7MVQn6Arkg0R9f8lMeQw4Dyykh7ZuIlfJxvIjzsMeSavdAgt2BIy1slzr6Z5VtyA==", + "version": "1.0.0-next.32", + "resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-1.0.0-next.32.tgz", + "integrity": "sha512-J+4A2rIE8IAXLCGBhyXuWM+0gwJxXf3JG/3XBZEhjMvWUNFEGeJLD26fr7evQY13Oy9mXHyUpp6rQxxHvE2/zA==", "requires": { "@oceanprotocol/contracts": "1.0.0-alpha.26", "bignumber.js": "^9.0.2", "cross-fetch": "^3.1.5", "crypto-js": "^4.1.1", "decimal.js": "^10.3.1", - "web3": "^1.7.1", "web3-core": "^1.7.1", "web3-eth-contract": "^1.7.1" } @@ -26831,7 +26830,6 @@ "integrity": "sha512-5vwpq6kbvwkQwKqAoOU3L72GZ3Ta8RRrewKj9OJRolx28KLJJ8Dg9Rf7obRwt5jQA9bkYd8gqzMTrI7H3xLfaw==", "dev": true, "requires": { - "@oclif/config": "^1.15.1", "@oclif/errors": "^1.3.3", "@oclif/parser": "^3.8.3", "@oclif/plugin-help": "^3", diff --git a/package.json b/package.json index 1f8eb39c5..c8d9bf488 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "@coingecko/cryptoformat": "^0.4.4", "@loadable/component": "^5.15.2", "@oceanprotocol/art": "^3.2.0", - "@oceanprotocol/lib": "^1.0.0-next.29", + "@oceanprotocol/lib": "^1.0.0-next.32", "@oceanprotocol/typographies": "^0.1.0", "@portis/web3": "^4.0.7", "@tippyjs/react": "^4.2.6", diff --git a/src/components/Publish/_utils.ts b/src/components/Publish/_utils.ts index 05efb3dbd..ab31a0ac6 100644 --- a/src/components/Publish/_utils.ts +++ b/src/components/Publish/_utils.ts @@ -207,7 +207,7 @@ export async function createTokensAndPricing( const ercParams: Erc20CreateParams = { templateIndex: values.pricing.type === 'dynamic' ? 1 : 2, minter: accountId, - feeManager: accountId, + paymentCollector: accountId, mpFeeAddress: appConfig.marketFeeAddress, feeToken: config.oceanTokenAddress, feeAmount: appConfig.publisherMarketOrderFee, From 795ba0c01b17a60ef5502feb875b47aa5f82afc9 Mon Sep 17 00:00:00 2001 From: Soon Huat Date: Wed, 30 Mar 2022 22:44:10 +0800 Subject: [PATCH 2/8] c2d show price with fee, exclude provider fee --- .../Compute/FormComputeDataset.tsx | 21 +++++++-- .../Asset/AssetActions/Compute/index.tsx | 46 +++++++++++++++++-- 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/src/components/Asset/AssetActions/Compute/FormComputeDataset.tsx b/src/components/Asset/AssetActions/Compute/FormComputeDataset.tsx index d11fd09de..4919e633f 100644 --- a/src/components/Asset/AssetActions/Compute/FormComputeDataset.tsx +++ b/src/components/Asset/AssetActions/Compute/FormComputeDataset.tsx @@ -10,7 +10,7 @@ import { useAsset } from '@context/Asset' import { useWeb3 } from '@context/Web3' import content from '../../../../../content/pages/startComputeDataset.json' import { Asset } from '@oceanprotocol/lib' -import { AccessDetails } from 'src/@types/Price' +import { AccessDetails, OrderPriceAndFees } from 'src/@types/Price' import { getAccessDetailsForAssets, getAccessDetails @@ -40,7 +40,9 @@ export default function FormStartCompute({ selectedComputeAssetTimeout, stepText, isConsumable, - consumableFeedback + consumableFeedback, + datasetOrderPriceAndFees, + algoOrderPriceAndFees }: { algorithms: AssetSelectionAsset[] ddoListAlgorithms: Asset[] @@ -65,6 +67,8 @@ export default function FormStartCompute({ stepText: string isConsumable: boolean consumableFeedback: string + datasetOrderPriceAndFees?: OrderPriceAndFees + algoOrderPriceAndFees?: OrderPriceAndFees }): ReactElement { const { isValid, values }: FormikContextType<{ algorithm: string }> = useFormikContext() @@ -107,11 +111,16 @@ export default function FormStartCompute({ if (!asset?.accessDetails || !selectedAlgorithmAsset?.accessDetails) return const priceDataset = - hasPreviousOrder || hasDatatoken ? 0 : Number(asset.accessDetails.price) + hasPreviousOrder || hasDatatoken + ? 0 + : Number(datasetOrderPriceAndFees?.price || asset.accessDetails.price) const priceAlgo = hasPreviousOrderSelectedComputeAsset || hasDatatokenSelectedComputeAsset ? 0 - : Number(selectedAlgorithmAsset?.accessDetails.price) + : Number( + algoOrderPriceAndFees?.price || + selectedAlgorithmAsset?.accessDetails.price + ) setTotalPrice((priceDataset + priceAlgo).toString()) }, [ @@ -120,7 +129,9 @@ export default function FormStartCompute({ hasPreviousOrder, hasDatatoken, hasPreviousOrderSelectedComputeAsset, - hasDatatokenSelectedComputeAsset + hasDatatokenSelectedComputeAsset, + datasetOrderPriceAndFees, + algoOrderPriceAndFees ]) useEffect(() => { diff --git a/src/components/Asset/AssetActions/Compute/index.tsx b/src/components/Asset/AssetActions/Compute/index.tsx index f8b0a77a8..210ec0df5 100644 --- a/src/components/Asset/AssetActions/Compute/index.tsx +++ b/src/components/Asset/AssetActions/Compute/index.tsx @@ -83,13 +83,17 @@ export default function Compute({ const [isConsumablePrice, setIsConsumablePrice] = useState(true) const [isAlgoConsumablePrice, setIsAlgoConsumablePrice] = useState(true) const [computeStatusText, setComputeStatusText] = useState('') + const [datasetOrderPriceAndFees, setDatasetOrderPriceAndFees] = + useState() + const [algoOrderPriceAndFees, setAlgoOrderPriceAndFees] = + useState() const isComputeButtonDisabled = isJobStarting === true || file === null || (!validOrderTx && !hasDatatoken && !isConsumablePrice) || (!validAlgorithmOrderTx && !hasAlgoAssetDatatoken && !isAlgoConsumablePrice) - async function checkAssetDTBalance(asset: DDO) { + async function checkAssetDTBalance(asset: DDO): Promise { if (!asset?.services[0].datatokenAddress) return const datatokenInstance = new Datatoken(web3) const dtBalance = await datatokenInstance.balance( @@ -97,7 +101,9 @@ export default function Compute({ accountId ) setAlgorithmDTBalance(new Decimal(dtBalance).toString()) - setHasAlgoAssetDatatoken(Number(dtBalance) >= 1) + const hasAlgoDt = Number(dtBalance) >= 1 + setHasAlgoAssetDatatoken(hasAlgoDt) + return hasAlgoDt } useEffect(() => { @@ -106,16 +112,48 @@ export default function Compute({ setIsConsumablePrice(asset?.accessDetails?.isPurchasable) setIsOwned(asset?.accessDetails?.isOwned) setValidOrderTx(asset?.accessDetails?.validOrderTx) + + async function initDatasetPriceAndFees() { + if ( + asset?.accessDetails?.addressOrId === ZERO_ADDRESS || + asset?.accessDetails?.type === 'free' + ) + return + const orderPriceAndFees = await getOrderPriceAndFees(asset, accountId) + setDatasetOrderPriceAndFees(orderPriceAndFees) + } + + initDatasetPriceAndFees() }, [asset?.accessDetails]) useEffect(() => { if (!selectedAlgorithmAsset?.accessDetails || !accountId) return - checkAssetDTBalance(selectedAlgorithmAsset) + setIsConsumablePrice(selectedAlgorithmAsset?.accessDetails?.isPurchasable) setIsAlgorithmOwned(selectedAlgorithmAsset?.accessDetails?.isOwned) setValidAlgorithmOrderTx( selectedAlgorithmAsset?.accessDetails?.validOrderTx ) + + async function initAlgoPriceAndFees() { + if ( + selectedAlgorithmAsset?.accessDetails?.addressOrId === ZERO_ADDRESS || + selectedAlgorithmAsset?.accessDetails?.type === 'free' + ) + return + const orderPriceAndFees = await getOrderPriceAndFees( + selectedAlgorithmAsset, + accountId + ) + setAlgoOrderPriceAndFees(orderPriceAndFees) + } + + async function initSelectedAlgo() { + const hasAlgoDt = await checkAssetDTBalance(selectedAlgorithmAsset) + !hasAlgoDt && (await initAlgoPriceAndFees()) + } + + initSelectedAlgo() }, [selectedAlgorithmAsset]) useEffect(() => { @@ -436,6 +474,8 @@ export default function Compute({ stepText={computeStatusText} isConsumable={isConsumable} consumableFeedback={consumableFeedback} + datasetOrderPriceAndFees={datasetOrderPriceAndFees} + algoOrderPriceAndFees={algoOrderPriceAndFees} /> )} From cd2565d5e7f792d7e2e1c67a1f59c3dce24ec47f Mon Sep 17 00:00:00 2001 From: Bogdan Fazakas Date: Thu, 31 Mar 2022 11:51:21 +0300 Subject: [PATCH 3/8] fix error when sample on edit is empty --- src/components/@shared/FormFields/FilesInput/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/@shared/FormFields/FilesInput/index.tsx b/src/components/@shared/FormFields/FilesInput/index.tsx index 73d5057c4..6f0c97c56 100644 --- a/src/components/@shared/FormFields/FilesInput/index.tsx +++ b/src/components/@shared/FormFields/FilesInput/index.tsx @@ -65,7 +65,7 @@ export default function FilesInput(props: InputProps): ReactElement { return ( <> - {field.value[0].valid !== undefined ? ( + {field?.value && field?.value[0]?.valid !== undefined ? ( ) : ( Date: Thu, 31 Mar 2022 14:49:15 +0300 Subject: [PATCH 4/8] Undefined graph labels fix (#1283) * get format price * added price format fix, removed logs * remove all commas from the price string * space fixes * fix * fix locale in graph, undo price fix Co-authored-by: ClaudiaHolhos Co-authored-by: mihaisc --- src/components/Asset/AssetActions/Pool/Graph/_utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Asset/AssetActions/Pool/Graph/_utils.ts b/src/components/Asset/AssetActions/Pool/Graph/_utils.ts index eb36b1e77..6d5ec2451 100644 --- a/src/components/Asset/AssetActions/Pool/Graph/_utils.ts +++ b/src/components/Asset/AssetActions/Pool/Graph/_utils.ts @@ -25,7 +25,7 @@ export function getOptions( borderColor: isDarkMode ? `#41474e` : `#e2e2e2`, callbacks: { label: (tooltipItem: TooltipItem) => - `${formatPrice(`${tooltipItem.formattedValue}`, locale)} ${symbol}` + `${tooltipItem.formattedValue} ${symbol}` } } }, From 45dad876e288b833f1cb6b328f9eca434bd4d978 Mon Sep 17 00:00:00 2001 From: mihaisc Date: Thu, 31 Mar 2022 04:50:32 -0700 Subject: [PATCH 5/8] fix pool tx (#1288) Signed-off-by: mihaisc --- .../@shared/PoolTransactions/index.tsx | 30 +++++++++++-------- .../Asset/AssetActions/Pool/index.tsx | 2 +- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/components/@shared/PoolTransactions/index.tsx b/src/components/@shared/PoolTransactions/index.tsx index 8569263cd..3318a5303 100644 --- a/src/components/@shared/PoolTransactions/index.tsx +++ b/src/components/@shared/PoolTransactions/index.tsx @@ -23,7 +23,7 @@ const txHistoryQueryByPool = gql` poolTransactions( orderBy: timestamp orderDirection: desc - where: { pool: $pool } + where: { pool: $pool, user: $user } first: 1000 ) { baseToken { @@ -40,6 +40,9 @@ const txHistoryQueryByPool = gql` tx timestamp pool { + datatoken { + id + } id } } @@ -67,6 +70,9 @@ const txHistoryQuery = gql` tx timestamp pool { + datatoken { + id + } id } } @@ -124,7 +130,7 @@ export default function PoolTransactions({ accountId }: { poolAddress?: string - poolChainId?: number[] + poolChainId?: number minimal?: boolean accountId: string }): ReactElement { @@ -146,7 +152,7 @@ export default function PoolTransactions({ const result = await fetchDataForMultipleChains( poolAddress ? txHistoryQueryByPool : txHistoryQuery, variables, - poolAddress ? poolChainId : chainIds + poolAddress ? [poolChainId] : chainIds ) for (let i = 0; i < result.length; i++) { @@ -166,24 +172,24 @@ export default function PoolTransactions({ return } const poolTransactions: PoolTransaction[] = [] - const dtList: string[] = [] - - for (let i = 0; i < data.length; i++) { - dtList.push(data[i]?.datatoken?.address) - } + let dtList: string[] = [] + dtList = [...new Set(data.map((item) => item.pool.datatoken.id))] if (dtList.length === 0) { setTransactions([]) setIsLoading(false) return } - const ddoList = await getAssetsFromDtList(dtList, chainIds, cancelToken) - + const ddoList = !minimal + ? await getAssetsFromDtList(dtList, chainIds, cancelToken) + : [] for (let i = 0; i < data.length; i++) { poolTransactions.push({ ...data[i], - networkId: getAsset(ddoList, data[i].datatoken.address).chainId, - asset: getAsset(ddoList, data[i].datatoken.address) + networkId: !minimal + ? getAsset(ddoList, data[i].pool.datatoken.id).chainId + : poolChainId, + asset: !minimal ? getAsset(ddoList, data[i].pool.datatoken.id) : null }) } const sortedTransactions = poolTransactions.sort( diff --git a/src/components/Asset/AssetActions/Pool/index.tsx b/src/components/Asset/AssetActions/Pool/index.tsx index 26eebff59..2b9a94bfe 100644 --- a/src/components/Asset/AssetActions/Pool/index.tsx +++ b/src/components/Asset/AssetActions/Pool/index.tsx @@ -208,7 +208,7 @@ export default function Pool(): ReactElement { From 31167856fc2b16caede4ca1ccf221d9babd3fb79 Mon Sep 17 00:00:00 2001 From: Soon Huat Date: Thu, 31 Mar 2022 23:55:22 +0800 Subject: [PATCH 6/8] include loading when calculating data + algo price, tooltip show order price --- .../Compute/FormComputeDataset.tsx | 15 +++++++++++++++ .../Asset/AssetActions/Compute/PriceOutput.tsx | 16 +++++++++++++--- .../Asset/AssetActions/Compute/index.tsx | 18 +++++++++++++++++- 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/components/Asset/AssetActions/Compute/FormComputeDataset.tsx b/src/components/Asset/AssetActions/Compute/FormComputeDataset.tsx index 4919e633f..e991f02bb 100644 --- a/src/components/Asset/AssetActions/Compute/FormComputeDataset.tsx +++ b/src/components/Asset/AssetActions/Compute/FormComputeDataset.tsx @@ -74,6 +74,12 @@ export default function FormStartCompute({ useFormikContext() const { asset, isAssetNetwork } = useAsset() const [totalPrice, setTotalPrice] = useState(asset?.accessDetails?.price) + const [datasetOrderPrice, setDatasetOrderPrice] = useState( + asset?.accessDetails?.price + ) + const [algoOrderPrice, setAlgoOrderPrice] = useState( + selectedAlgorithmAsset?.accessDetails?.price + ) const [isBalanceSufficient, setIsBalanceSufficient] = useState(false) const { accountId, balance } = useWeb3() @@ -110,6 +116,13 @@ export default function FormStartCompute({ useEffect(() => { if (!asset?.accessDetails || !selectedAlgorithmAsset?.accessDetails) return + setDatasetOrderPrice( + datasetOrderPriceAndFees?.price || asset.accessDetails.price + ) + setAlgoOrderPrice( + algoOrderPriceAndFees?.price || + selectedAlgorithmAsset?.accessDetails.price + ) const priceDataset = hasPreviousOrder || hasDatatoken ? 0 @@ -164,6 +177,8 @@ export default function FormStartCompute({ algorithmConsumeDetails={selectedAlgorithmAsset?.accessDetails} symbol={oceanSymbol} totalPrice={Number.parseFloat(totalPrice)} + datasetOrderPrice={datasetOrderPrice} + algoOrderPrice={algoOrderPrice} /> () + const [isRequestingDataseOrderPrice, setIsRequestingDataseOrderPrice] = + useState(false) const [algoOrderPriceAndFees, setAlgoOrderPriceAndFees] = useState() + const [isRequestingAlgoOrderPrice, setIsRequestingAlgoOrderPrice] = + useState(false) const isComputeButtonDisabled = isJobStarting === true || file === null || @@ -119,8 +123,12 @@ export default function Compute({ asset?.accessDetails?.type === 'free' ) return + + setIsRequestingDataseOrderPrice(true) + setComputeStatusText('Calculating price including fees.') const orderPriceAndFees = await getOrderPriceAndFees(asset, accountId) setDatasetOrderPriceAndFees(orderPriceAndFees) + setIsRequestingDataseOrderPrice(false) } initDatasetPriceAndFees() @@ -141,11 +149,15 @@ export default function Compute({ selectedAlgorithmAsset?.accessDetails?.type === 'free' ) return + + setIsRequestingAlgoOrderPrice(true) + setComputeStatusText('Calculating price including fees.') const orderPriceAndFees = await getOrderPriceAndFees( selectedAlgorithmAsset, accountId ) setAlgoOrderPriceAndFees(orderPriceAndFees) + setIsRequestingAlgoOrderPrice(false) } async function initSelectedAlgo() { @@ -444,7 +456,11 @@ export default function Compute({ ddoListAlgorithms={ddoAlgorithmList} selectedAlgorithmAsset={selectedAlgorithmAsset} setSelectedAlgorithm={setSelectedAlgorithmAsset} - isLoading={isJobStarting} + isLoading={ + isJobStarting || + isRequestingDataseOrderPrice || + isRequestingAlgoOrderPrice + } isComputeButtonDisabled={isComputeButtonDisabled} hasPreviousOrder={validOrderTx !== undefined} hasDatatoken={hasDatatoken} From 47144d80b59bfce062bf0c5f617e811fc535fd0e Mon Sep 17 00:00:00 2001 From: EnzoVezzaro Date: Fri, 1 Apr 2022 04:22:38 -0400 Subject: [PATCH 7/8] fix remove liquidity issues (#1258) * reset slider after transaction * fix issue on remove button hover * restore transform on Button.module.css * added check on accountId to avoid failing calls * disable remove button on amountPercent = 0 --- src/@context/Pool/index.tsx | 9 +++++++- .../@shared/atoms/Button.module.css | 3 ++- .../AssetActions/Pool/Remove/index.module.css | 8 +++++-- .../Asset/AssetActions/Pool/Remove/index.tsx | 22 +++++++++++++++++-- 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/@context/Pool/index.tsx b/src/@context/Pool/index.tsx index 34f28e5bb..de6ff8b68 100644 --- a/src/@context/Pool/index.tsx +++ b/src/@context/Pool/index.tsx @@ -56,7 +56,13 @@ function PoolProvider({ children }: { children: ReactNode }): ReactElement { // const [fetchInterval, setFetchInterval] = useState() const fetchAllData = useCallback(async () => { - if (!asset?.chainId || !asset?.accessDetails?.addressOrId || !owner) return + if ( + !accountId || + !asset?.chainId || + !asset?.accessDetails?.addressOrId || + !owner + ) + return const response = await getPoolData( asset.chainId, @@ -64,6 +70,7 @@ function PoolProvider({ children }: { children: ReactNode }): ReactElement { owner, accountId || '' ) + if (!response) return setPoolData(response.poolData) diff --git a/src/components/@shared/atoms/Button.module.css b/src/components/@shared/atoms/Button.module.css index d63783b26..e187b43cf 100644 --- a/src/components/@shared/atoms/Button.module.css +++ b/src/components/@shared/atoms/Button.module.css @@ -26,6 +26,7 @@ .button:last-child { margin-right: 0; + min-width: auto; } .button:hover, @@ -33,8 +34,8 @@ color: var(--brand-white); background: var(--brand-grey-light); text-decoration: none; - transform: translate3d(0, -0.05rem, 0); box-shadow: 0 12px 30px 0 rgba(0, 0, 0, 0.1); + transform: translate3d(0, -0.05rem, 0); } .button:active { diff --git a/src/components/Asset/AssetActions/Pool/Remove/index.module.css b/src/components/Asset/AssetActions/Pool/Remove/index.module.css index 0bdc13d89..f34cd2dbb 100644 --- a/src/components/Asset/AssetActions/Pool/Remove/index.module.css +++ b/src/components/Asset/AssetActions/Pool/Remove/index.module.css @@ -31,13 +31,17 @@ .maximum { position: absolute; - right: -2rem; - bottom: 2rem; + right: 0; + bottom: 2.5rem; font-size: var(--font-size-mini); min-width: 5rem; text-align: center; } +.maximum:hover { + transform: none; +} + .toggle { margin-top: calc(var(--spacer) / 2); margin-bottom: 0; diff --git a/src/components/Asset/AssetActions/Pool/Remove/index.tsx b/src/components/Asset/AssetActions/Pool/Remove/index.tsx index 07691f391..538c1c858 100644 --- a/src/components/Asset/AssetActions/Pool/Remove/index.tsx +++ b/src/components/Asset/AssetActions/Pool/Remove/index.tsx @@ -67,11 +67,16 @@ export default function Remove({ minOceanAmount ) setTxId(result?.transactionHash) + // fetch new data fetchAllData() } catch (error) { LoggerInstance.error(error.message) toast.error(error.message) } finally { + // reset slider after transaction + setAmountPercent('0') + setAmountOcean('0') + setMinOceanAmount('0') setIsLoading(false) } } @@ -80,8 +85,10 @@ export default function Remove({ if (!accountId || !poolTokens) return async function getMax() { + const poolTokensAmount = + !poolTokens || poolTokens === '0' ? '1' : poolTokens const maxTokensToRemoveFromPool = calcMaxExactOut(totalPoolTokens) - const poolTokensDecimal = new Decimal(poolTokens) + const poolTokensDecimal = new Decimal(poolTokensAmount) const maxTokensToRemoveForUser = maxTokensToRemoveFromPool.greaterThan( poolTokensDecimal ) @@ -105,6 +112,7 @@ export default function Remove({ tokenOutAddress, newAmountPoolShares ) + setAmountOcean(newAmountOcean) }, 150) ) @@ -116,6 +124,11 @@ export default function Remove({ }, [amountPoolShares, accountId, poolTokens, poolAddress, totalPoolTokens]) useEffect(() => { + if (!amountOcean || amountPercent === '0') { + setMinOceanAmount('0') + return + } + const minOceanAmount = new Decimal(amountOcean) .mul(new Decimal(100).minus(new Decimal(slippage))) .dividedBy(100) @@ -220,7 +233,12 @@ export default function Remove({ actionName={content.pool.remove.action} action={handleRemoveLiquidity} successMessage="Successfully removed liquidity." - isDisabled={!isAssetNetwork || amountOcean === '0'} + isDisabled={ + !isAssetNetwork || + amountPercent === '0' || + amountOcean === '0' || + poolTokens === '0' + } txId={txId} tokenAddress={tokenOutAddress} tokenSymbol={tokenOutSymbol} From 65f0c5c675dc54adcba8dbfa65c089fae5039988 Mon Sep 17 00:00:00 2001 From: claudiaHash <49017601+claudiaHash@users.noreply.github.com> Date: Fri, 1 Apr 2022 11:38:32 +0300 Subject: [PATCH 8/8] Price length and decimals number validation (#1225) * price length and decimals number validation * undefined parameter fix * fixes * use the decimals constant in regex * validation added for moire fields * cleanup * swap fee decimals fixes * constant fix * use max 6 decimals for swap fee * remove unused code Co-authored-by: ClaudiaHolhos --- src/@utils/constants.ts | 2 +- src/components/Publish/Pricing/Price.tsx | 8 ++++++- src/components/Publish/_validation.ts | 30 ++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/@utils/constants.ts b/src/@utils/constants.ts index cf39b726d..ef3558975 100644 --- a/src/@utils/constants.ts +++ b/src/@utils/constants.ts @@ -1 +1 @@ -export const MAX_DECIMALS = 5 +export const MAX_DECIMALS = 6 diff --git a/src/components/Publish/Pricing/Price.tsx b/src/components/Publish/Pricing/Price.tsx index b18b80292..c55b92544 100644 --- a/src/components/Publish/Pricing/Price.tsx +++ b/src/components/Publish/Pricing/Price.tsx @@ -34,7 +34,13 @@ export default function Price({ <>
- +
diff --git a/src/components/Publish/_validation.ts b/src/components/Publish/_validation.ts index 7e4e50195..bbae3841f 100644 --- a/src/components/Publish/_validation.ts +++ b/src/components/Publish/_validation.ts @@ -1,8 +1,10 @@ +import { MAX_DECIMALS } from '@utils/constants' import * as Yup from 'yup' // TODO: conditional validation // e.g. when algo is selected, Docker image is required // hint, hint: https://github.com/jquense/yup#mixedwhenkeys-string--arraystring-builder-object--value-schema-schema-schema + const validationMetadata = { type: Yup.string() .matches(/dataset|algorithm/g, { excludeEmptyString: true }) @@ -54,25 +56,53 @@ const validationService = { }) } +const maxDecimalsValidation = new RegExp( + '^\\d+(\\.\\d{1,' + MAX_DECIMALS + '})?$' +) + const validationPricing = { type: Yup.string() .matches(/fixed|dynamic|free/g, { excludeEmptyString: true }) .required('Required'), // https://github.com/jquense/yup#mixedwhenkeys-string--arraystring-builder-object--value-schema-schema-schema + price: Yup.number() .min(1, (param: { min: number }) => `Must be more or equal to ${param.min}`) + .max( + 1000000, + (param: { max: number }) => `Must be less than or equal to ${param.max}` + ) + .test( + 'maxDigitsAfterDecimal', + `Must have maximum ${MAX_DECIMALS} decimal digits`, + (param) => maxDecimalsValidation.test(param?.toString()) + ) .required('Required'), amountDataToken: Yup.number() .min(50, (param) => `Must be more or equal to ${param.min}`) .required('Required'), amountOcean: Yup.number() .min(50, (param) => `Must be more or equal to ${param.min}`) + .max( + 1000000, + (param: { max: number }) => `Must be less than or equal to ${param.max}` + ) + .test( + 'maxDigitsAfterDecimal', + `Must have maximum ${MAX_DECIMALS} decimal digits`, + (param) => maxDecimalsValidation.test(param?.toString()) + ) .required('Required'), weightOnDataToken: Yup.string().required('Required'), weightOnOcean: Yup.string().required('Required'), swapFee: Yup.number() .min(0.1, (param) => `Must be more or equal to ${param.min}`) .max(10, 'Maximum is 10%') + .test( + 'maxDigitsAfterDecimal', + `Must have maximum ${MAX_DECIMALS} decimal digits`, + (param) => maxDecimalsValidation.test(param?.toString()) + ) .required('Required') }