From d26247ab350f72dc49df299efd63fb0e699039d1 Mon Sep 17 00:00:00 2001 From: Juliano Lazzarotto <30806844+stackchain@users.noreply.github.com> Date: Mon, 9 Oct 2023 19:38:57 +0100 Subject: [PATCH] chore: state and behaviors --- .../SelectPoolFromList/SelectPoolFromList.tsx | 38 ++++++++-------- .../CreateOrder/CreateOrder.tsx | 2 +- .../EditBuyAmount/EditBuyAmount.tsx | 14 ++---- .../SelectBuyTokenFromListScreen.tsx | 15 +++++-- .../SelectSellTokenFromListScreen.tsx | 12 +++-- .../orders/factories/makeOrderCalculations.ts | 45 +++++++++++-------- 6 files changed, 69 insertions(+), 57 deletions(-) diff --git a/apps/wallet-mobile/src/features/Swap/common/SelectPool/SelectPoolFromList/SelectPoolFromList.tsx b/apps/wallet-mobile/src/features/Swap/common/SelectPool/SelectPoolFromList/SelectPoolFromList.tsx index 761f768943..47221c5c15 100644 --- a/apps/wallet-mobile/src/features/Swap/common/SelectPool/SelectPoolFromList/SelectPoolFromList.tsx +++ b/apps/wallet-mobile/src/features/Swap/common/SelectPool/SelectPoolFromList/SelectPoolFromList.tsx @@ -1,6 +1,5 @@ -import {useSwap} from '@yoroi/swap' +import {getPairPriceInPtTerms, useSwap} from '@yoroi/swap' import {Balance, Swap} from '@yoroi/types' -import BigNumber from 'bignumber.js' import React, {useState} from 'react' import {StyleSheet, Text, TouchableOpacity, View} from 'react-native' import LinearGradient from 'react-native-linear-gradient' @@ -29,7 +28,7 @@ export const SelectPoolFromList = ({pools = []}: Props) => { const navigate = useNavigateTo() const {track} = useMetrics() - const handleCardSelect = (pool: Swap.Pool) => { + const handleOnPoolSelection = (pool: Swap.Pool) => { track.swapPoolChanged() selectedPoolChanged(pool.poolId) setSelectedCardIndex(pool.poolId) @@ -57,7 +56,7 @@ export const SelectPoolFromList = ({pools = []}: Props) => { colors={pool.poolId === selectedCardIndex ? ['#E4E8F7', '#C6F7F7'] : [COLORS.WHITE, COLORS.WHITE]} style={styles.linearGradient} > - handleCardSelect(pool)} style={[styles.card]}> + handleOnPoolSelection(pool)} style={[styles.card]}> @@ -120,26 +119,25 @@ export const SelectPoolFromList = ({pools = []}: Props) => { type PriceInAdaProps = {pool: Swap.Pool; wallet: YoroiWallet; sell: Balance.Amount} const PriceInAda = ({pool, wallet, sell}: PriceInAdaProps) => { const strings = useStrings() - - const {decimals: decimalsA = 0}= useTokenInfo({wallet, tokenId: pool.tokenA.tokenId}) - const {decimals: decimalsB = 0}= useTokenInfo({wallet, tokenId: pool.tokenB.tokenId}) - - const scaleA = new BigNumber(10).pow(decimalsA) - const scaleB = new BigNumber(10).pow(decimalsB) - - const isSellTokenA = pool.tokenA.tokenId === sell.tokenId - const [dividend, divisor] = isSellTokenA - ? [new BigNumber(pool.ptPriceTokenB).multipliedBy(scaleB), new BigNumber(pool.ptPriceTokenA).multipliedBy(scaleA)] - : [new BigNumber(pool.ptPriceTokenA).multipliedBy(scaleA), new BigNumber(pool.ptPriceTokenB).multipliedBy(scaleB)] - // limit decimals - const ptPrice = divisor.isZero() ? '0' : dividend.dividedBy(divisor).toFixed(Math.max(decimalsA, decimalsB), BigNumber.ROUND_DOWN) - // const price = parsedPrice != null ? asQuantity(parsedPrice) : Quantities.zero - // const formattedPriceInPt = `${Quantities.format(price, 0, decimals)} ${ticker}` + const {ptPriceTokenA, ptPriceTokenB, tokenA, tokenB} = pool + + const {decimals: decimalsA = 0} = useTokenInfo({wallet, tokenId: tokenA.tokenId}) + const {decimals: decimalsB = 0} = useTokenInfo({wallet, tokenId: tokenB.tokenId}) + + const {ptPriceAB} = getPairPriceInPtTerms({ + amountA: tokenA, + decimalsA, + decimalsB, + ptPriceTokenA, + ptPriceTokenB, + sell, + }) + return ( {strings.price} - {ptPrice} + {ptPriceAB} ) } diff --git a/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/CreateOrder/CreateOrder.tsx b/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/CreateOrder/CreateOrder.tsx index 7b460e6e0b..18e4c710db 100644 --- a/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/CreateOrder/CreateOrder.tsx +++ b/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/CreateOrder/CreateOrder.tsx @@ -42,7 +42,7 @@ export const CreateOrder = () => { tokenB: orderData.amounts.buy.tokenId, }, { - enabled: isBuyTouched, + enabled: isBuyTouched && isSellTouched, onSuccess: (pools) => { poolPairsChanged(pools) }, diff --git a/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/CreateOrder/EditBuyAmount/EditBuyAmount.tsx b/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/CreateOrder/EditBuyAmount/EditBuyAmount.tsx index c4fb2b03dd..ffc6414794 100644 --- a/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/CreateOrder/EditBuyAmount/EditBuyAmount.tsx +++ b/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/CreateOrder/EditBuyAmount/EditBuyAmount.tsx @@ -20,7 +20,7 @@ export const EditBuyAmount = () => { const inputRef = React.useRef(null) const {orderData, buyQuantityChanged} = useSwap() - const {isBuyTouched} = useSwapTouched() + const {isBuyTouched, isSellTouched} = useSwapTouched() const pool = orderData.selectedPoolCalculation?.pool const {tokenId, quantity} = orderData.amounts.buy const tokenInfo = useTokenInfo({wallet, tokenId}) @@ -30,15 +30,6 @@ export const EditBuyAmount = () => { const [inputValue, setInputValue] = React.useState(Quantities.format(quantity, tokenInfo.decimals ?? 0)) React.useEffect(() => { - console.log('EditBuyAmount::useEffect') - console.log( - 'isBuyTouched', - isBuyTouched, - 'inputRef?.current?.isFocused()', - inputRef?.current?.isFocused(), - 'quantity', - quantity, - ) if (isBuyTouched && !inputRef?.current?.isFocused()) { setInputValue(Quantities.format(quantity, tokenInfo.decimals ?? 0)) } @@ -46,7 +37,8 @@ export const EditBuyAmount = () => { const poolSupply = tokenId === pool?.tokenA.tokenId ? pool?.tokenA.quantity : pool?.tokenB.quantity const hasSupply = !Quantities.isGreaterThan(quantity, poolSupply ?? Quantities.zero) - const showError = (!Quantities.isZero(quantity) && !hasSupply) || (isBuyTouched && pool === undefined) + const showError = + (!Quantities.isZero(quantity) && !hasSupply) || (isSellTouched && isBuyTouched && pool === undefined) const onChangeQuantity = (text: string) => { try { diff --git a/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/CreateOrder/EditBuyAmount/SelectBuyTokenFromListScreen/SelectBuyTokenFromListScreen.tsx b/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/CreateOrder/EditBuyAmount/SelectBuyTokenFromListScreen/SelectBuyTokenFromListScreen.tsx index 8588dcc76e..6ba130870f 100644 --- a/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/CreateOrder/EditBuyAmount/SelectBuyTokenFromListScreen/SelectBuyTokenFromListScreen.tsx +++ b/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/CreateOrder/EditBuyAmount/SelectBuyTokenFromListScreen/SelectBuyTokenFromListScreen.tsx @@ -178,13 +178,15 @@ const TokenList = () => { type SelectableTokenProps = {disabled?: boolean; tokenForList: TokenForList; wallet: YoroiWallet} const SelectableToken = ({tokenForList, wallet}: SelectableTokenProps) => { const {closeSearch} = useSearch() - const {buyTokenIdChanged} = useSwap() - const {buyTouched} = useSwapTouched() + const {buyTokenIdChanged, orderData} = useSwap() + const {buyTouched, isSellTouched} = useSwapTouched() const navigateTo = useNavigateTo() const balanceAvailable = useBalance({wallet, tokenId: tokenForList.id}) const {track} = useMetrics() - const onSelect = () => { + const isDisabled = tokenForList.id === orderData.amounts.sell.tokenId && isSellTouched + + const handleOnTokenSelection = () => { track.swapAssetToChanged({ to_asset: [{asset_name: tokenForList.name, asset_ticker: tokenForList.ticker, policy_id: tokenForList.group}], }) @@ -195,7 +197,12 @@ const SelectableToken = ({tokenForList, wallet}: SelectableTokenProps) => { } return ( - + { type SelectableTokenProps = {disabled?: boolean; tokenInfo: Balance.TokenInfo; wallet: YoroiWallet} const SelectableToken = ({tokenInfo, wallet}: SelectableTokenProps) => { const {closeSearch} = useSearch() - const {sellTokenIdChanged} = useSwap() + const {sellTokenIdChanged, orderData} = useSwap() const {sellTouched} = useSwapTouched() const navigateTo = useNavigateTo() const {track} = useMetrics() const balanceAvailable = useBalance({wallet, tokenId: tokenInfo.id}) + const isDisabled = tokenInfo.id === orderData.amounts.buy.tokenId - const onSelect = () => { + const handleOnTokenSelection = () => { track.swapAssetFromChanged({ from_asset: [{asset_name: tokenInfo.name, asset_ticker: tokenInfo.ticker, policy_id: tokenInfo.group}], }) @@ -101,7 +102,12 @@ const SelectableToken = ({tokenInfo, wallet}: SelectableTokenProps) => { } return ( - + ) diff --git a/packages/swap/src/helpers/orders/factories/makeOrderCalculations.ts b/packages/swap/src/helpers/orders/factories/makeOrderCalculations.ts index 1e38b5d8a2..204c17e2b8 100644 --- a/packages/swap/src/helpers/orders/factories/makeOrderCalculations.ts +++ b/packages/swap/src/helpers/orders/factories/makeOrderCalculations.ts @@ -67,10 +67,11 @@ export const makeOrderCalculations = ({ const liquidityFee: Balance.Amount = getLiquidityProviderFee(pool.fee, sell) const [ptPriceBuy, ptPriceSell] = isBuyTokenA - ? [pool.ptPriceTokenA, pool.ptPriceTokenB] - : [pool.ptPriceTokenB, pool.ptPriceTokenA] + ? [new BigNumber(pool.ptPriceTokenA), new BigNumber(pool.ptPriceTokenB)] + : [new BigNumber(pool.ptPriceTokenB), new BigNumber(pool.ptPriceTokenA)] // ffee is based on PT value range + LP holding range (sides may need conversion, when none is PT) + // TODO: it needs update, prices by muesli are provided in ADA, quantities in atomic units const frontendFeeInfo = getFrontendFee({ sell, buy, @@ -78,31 +79,39 @@ export const makeOrderCalculations = ({ primaryTokenId, sellInPrimaryTokenValue: { tokenId: primaryTokenId, - quantity: asQuantity( - new BigNumber(amounts.sell.quantity) - .dividedBy(ptPriceSell) - .integerValue(BigNumber.ROUND_CEIL), - ), + quantity: ptPriceSell.isZero() + ? Quantities.zero + : asQuantity( + new BigNumber(amounts.sell.quantity) + .dividedBy(ptPriceSell) + .integerValue(BigNumber.ROUND_CEIL), + ), }, buyInPrimaryTokenValue: { tokenId: primaryTokenId, - quantity: asQuantity( - new BigNumber(amounts.buy.quantity) - .dividedBy(ptPriceBuy) - .integerValue(BigNumber.ROUND_CEIL), - ), + quantity: ptPriceBuy.isZero() + ? Quantities.zero + : asQuantity( + new BigNumber(amounts.buy.quantity) + .dividedBy(ptPriceBuy) + .integerValue(BigNumber.ROUND_CEIL), + ), }, }) // transform fees in terms of sell side quantity * pt price (unit of fees) // it applies market price always const feeInSellSideQuantities = { - batcherFee: new BigNumber(pool.batcherFee.quantity) - .dividedBy(ptPriceSell) - .integerValue(BigNumber.ROUND_CEIL), - frontendFee: new BigNumber(frontendFeeInfo.fee.quantity) - .dividedBy(ptPriceSell) - .integerValue(BigNumber.ROUND_CEIL), + batcherFee: ptPriceSell.isZero() + ? Quantities.zero + : new BigNumber(pool.batcherFee.quantity) + .dividedBy(ptPriceSell) + .integerValue(BigNumber.ROUND_CEIL), + frontendFee: ptPriceSell.isZero() + ? Quantities.zero + : new BigNumber(frontendFeeInfo.fee.quantity) + .dividedBy(ptPriceSell) + .integerValue(BigNumber.ROUND_CEIL), } const priceWithSlippage = Quantities.isZero(buyAmountWithSlippage.quantity)