Skip to content

Commit

Permalink
chore: state and behaviors
Browse files Browse the repository at this point in the history
  • Loading branch information
stackchain committed Oct 9, 2023
1 parent b3fee39 commit d26247a
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 57 deletions.
Original file line number Diff line number Diff line change
@@ -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'
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -57,7 +56,7 @@ export const SelectPoolFromList = ({pools = []}: Props) => {
colors={pool.poolId === selectedCardIndex ? ['#E4E8F7', '#C6F7F7'] : [COLORS.WHITE, COLORS.WHITE]}
style={styles.linearGradient}
>
<TouchableOpacity key={pool.poolId} onPress={() => handleCardSelect(pool)} style={[styles.card]}>
<TouchableOpacity key={pool.poolId} onPress={() => handleOnPoolSelection(pool)} style={[styles.card]}>
<View style={styles.cardHeader}>
<View style={styles.icon}>
<PoolIcon size={40} providerId={pool.provider} />
Expand Down Expand Up @@ -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 (
<View style={styles.info}>
<Text style={styles.infoLabel}>{strings.price}</Text>

<Text style={styles.infoValue}>{ptPrice}</Text>
<Text style={styles.infoValue}>{ptPriceAB}</Text>
</View>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const CreateOrder = () => {
tokenB: orderData.amounts.buy.tokenId,
},
{
enabled: isBuyTouched,
enabled: isBuyTouched && isSellTouched,
onSuccess: (pools) => {
poolPairsChanged(pools)
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const EditBuyAmount = () => {
const inputRef = React.useRef<TextInput>(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})
Expand All @@ -30,23 +30,15 @@ export const EditBuyAmount = () => {
const [inputValue, setInputValue] = React.useState<string>(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))
}
}, [isBuyTouched, quantity, tokenInfo.decimals])

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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}],
})
Expand All @@ -195,7 +197,12 @@ const SelectableToken = ({tokenForList, wallet}: SelectableTokenProps) => {
}

return (
<TouchableOpacity style={styles.item} onPress={onSelect} testID="selectTokenButton">
<TouchableOpacity
style={styles.item}
onPress={handleOnTokenSelection}
testID="selectTokenButton"
disabled={isDisabled}
>
<AmountItem
amount={{tokenId: tokenForList.id, quantity: balanceAvailable}}
wallet={wallet}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,15 @@ const TokenList = () => {
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}],
})
Expand All @@ -101,7 +102,12 @@ const SelectableToken = ({tokenInfo, wallet}: SelectableTokenProps) => {
}

return (
<TouchableOpacity style={[styles.item]} onPress={onSelect} testID="selectTokenButton">
<TouchableOpacity
style={[styles.item]}
onPress={handleOnTokenSelection}
testID="selectTokenButton"
disabled={isDisabled}
>
<AmountItem amount={{tokenId: tokenInfo.id, quantity: balanceAvailable}} wallet={wallet} />
</TouchableOpacity>
)
Expand Down
45 changes: 27 additions & 18 deletions packages/swap/src/helpers/orders/factories/makeOrderCalculations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,42 +67,51 @@ 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,
lpTokenHeld,
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)
Expand Down

0 comments on commit d26247a

Please sign in to comment.