Skip to content
Merged

Mat #20

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/contexts/RatesContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { createContext } from "react"
export type Rates = {
data: {
rates: {
BUSDNGN: { rate: number; key: string }
BUSDUSD: { rate: number; key: string }
USDTNGN: number
USDTUSD: number
}
time: number
}
Expand Down
153 changes: 126 additions & 27 deletions src/hooks/interfaces/useConverterInferface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
TradeType,
} from "@pancakeswap/sdk"
import { useChainId, useNetwork } from "wagmi"
import { useCallback, useEffect, useMemo, useState } from "react"
import { useCallback, useEffect, useMemo, useRef, useState } from "react"
import { useAtom } from "jotai"
import { parseUnits } from "ethers/lib/utils"
import useTokens from "../../state/tokens/hooks"
Expand Down Expand Up @@ -100,6 +100,83 @@ const useConverterInterface = (): ReturnTypes => {
const [sellAmount, setSellAmount] = useState<
CurrencyAmount<Currency> | undefined
>()
const buyAmountRef = useRef<FiatAmount | undefined>(buyAmount)
const sellAmountRef = useRef<CurrencyAmount<Currency> | undefined>(sellAmount)
const buyAmountDebounceRef = useRef<ReturnType<typeof setTimeout> | null>(
null
)
const sellAmountDebounceRef = useRef<ReturnType<typeof setTimeout> | null>(
null
)
const DEBOUNCE_MS = 200

useEffect(() => {
buyAmountRef.current = buyAmount
}, [buyAmount])

useEffect(() => {
sellAmountRef.current = sellAmount
}, [sellAmount])

useEffect(
() => () => {
if (buyAmountDebounceRef.current) {
clearTimeout(buyAmountDebounceRef.current)
}
if (sellAmountDebounceRef.current) {
clearTimeout(sellAmountDebounceRef.current)
}
},
[]
)

const scheduleBuyAmountUpdate = useCallback(
(nextAmount: FiatAmount | undefined) => {
if (
nextAmount?.toExact() === buyAmountRef.current?.toExact() ||
(!nextAmount && !buyAmountRef.current)
) {
return
}
if (buyAmountDebounceRef.current) {
clearTimeout(buyAmountDebounceRef.current)
}
buyAmountDebounceRef.current = setTimeout(() => {
if (
nextAmount?.toExact() === buyAmountRef.current?.toExact() ||
(!nextAmount && !buyAmountRef.current)
) {
return
}
setBuyAmount(nextAmount)
}, DEBOUNCE_MS)
},
[]
)

const scheduleSellAmountUpdate = useCallback(
(nextAmount: CurrencyAmount<Currency> | undefined) => {
if (
nextAmount?.toExact() === sellAmountRef.current?.toExact() ||
(!nextAmount && !sellAmountRef.current)
) {
return
}
if (sellAmountDebounceRef.current) {
clearTimeout(sellAmountDebounceRef.current)
}
sellAmountDebounceRef.current = setTimeout(() => {
if (
nextAmount?.toExact() === sellAmountRef.current?.toExact() ||
(!nextAmount && !sellAmountRef.current)
) {
return
}
setSellAmount(nextAmount)
}, DEBOUNCE_MS)
},
[]
)

const amountToFetchPrice = useMemo(
() => (sellAmount ? [sellAmount] : undefined),
Expand Down Expand Up @@ -164,10 +241,10 @@ const useConverterInterface = (): ReturnTypes => {
parseUnits(amount, buyToken.decimals).toString()
)

setBuyAmount(newAmount)
scheduleBuyAmountUpdate(newAmount)
}
},
[buyToken]
[buyToken, scheduleBuyAmountUpdate]
)

// validate and format inputted sellAmount before updating state
Expand All @@ -185,10 +262,10 @@ const useConverterInterface = (): ReturnTypes => {
parseUnits(amount, sellToken.decimals).toString()
)

setSellAmount(newAmount)
scheduleSellAmountUpdate(newAmount)
}
},
[sellToken]
[sellToken, scheduleSellAmountUpdate]
)

// get the fiat equivalent of the sellAmount
Expand Down Expand Up @@ -227,21 +304,24 @@ const useConverterInterface = (): ReturnTypes => {
exchangeRate = useMemo(() => {
if (buyAmount && sellAmount) {
if (sellAmount.equalTo(0)) return undefined
const numerator = buyAmount
.toDollarAmount(
dollarRates[
preferredFiat.fiat.symbol.toLowerCase() === "usd" ? "ngn" : "usd"
] * 100
)
.multiply(sellAmount.decimalScale)
.multiply(100)
.divide(buyAmount.decimalScale)
.toFixed(0)
const denominator = sellAmount
.multiply(sellAmount.decimalScale)
.divide(buyAmount.decimalScale)
.toFixed(0)

return new Fraction(
buyAmount
.toDollarAmount(
dollarRates[
preferredFiat.fiat.symbol.toLowerCase() === "usd" ? "ngn" : "usd"
] * 100
)
.multiply(sellAmount.decimalScale)
.multiply(100)
.divide(buyAmount.decimalScale)
.toFixed(0),
sellAmount
.multiply(sellAmount.decimalScale)
.divide(buyAmount.decimalScale)
.toFixed(0)
numerator === "0" ? 1 : numerator,
denominator === "0" ? 1 : denominator
)
}

Expand Down Expand Up @@ -281,19 +361,32 @@ const useConverterInterface = (): ReturnTypes => {
const NGNAmount = amountOut
? stableCoinAmountToFiat(amountOut, dollarRates.ngn, NGN)
: undefined
setBuyAmount(NGNAmount)
if (
NGNAmount?.toExact() === buyAmount?.toExact() ||
(!NGNAmount && !buyAmount)
) {
return
}
scheduleBuyAmountUpdate(NGNAmount)
})()
} else if (
(!sellAmount || sellAmount.toExact() === "0") &&
independentField === "sell"
) {
setBuyAmount(undefined)
scheduleBuyAmountUpdate(undefined)
} else if (independentField !== "sell" && typedValue === "") {
setSellAmount(undefined)
scheduleSellAmountUpdate(undefined)
}

// eslint-disable-next-line react-hooks/exhaustive-deps
}, [sellAmount, tradeIn?.outputAmount, dollarRates.ngn])
}, [
sellAmount,
tradeIn?.outputAmount,
dollarRates.ngn,
scheduleBuyAmountUpdate,
scheduleSellAmountUpdate,
typedValue,
])

// update sellAmount when buyAmount changes
useEffect(() => {
Expand All @@ -313,19 +406,25 @@ const useConverterInterface = (): ReturnTypes => {
dollarRates.ngn
)
: tradeOut?.inputAmount ?? undefined
setSellAmount(amountIn)
scheduleSellAmountUpdate(amountIn)
})()
} else if (
(!buyAmount || buyAmount.toExact() === "0") &&
independentField === "buy"
) {
setSellAmount(undefined)
scheduleSellAmountUpdate(undefined)
} else if (independentField !== "buy" && typedValue === "") {
setBuyAmount(undefined)
scheduleBuyAmountUpdate(undefined)
}

// eslint-disable-next-line react-hooks/exhaustive-deps
}, [buyAmount, tradeOut?.inputAmount])
}, [
buyAmount,
tradeOut?.inputAmount,
scheduleBuyAmountUpdate,
scheduleSellAmountUpdate,
typedValue,
])

return {
sellAmount,
Expand Down
33 changes: 13 additions & 20 deletions src/hooks/useRates.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,29 @@
import {
Dispatch,
useContext,
SetStateAction,
useCallback,
useEffect,
useState,
} from "react"
import { useContext, useCallback, useEffect, useState } from "react"
import { rateSocket } from "../services/socket.setup"
import RateContext, { RateValues, Rates } from "../contexts/RatesContext"

export function useGetRates(): RateValues {
const [data, setRates] = useState<undefined | Rates>()
const listener = useCallback(
(cb: Dispatch<SetStateAction<Rates | undefined>>, _rates?: Rates) =>
_rates && cb(_rates),
[]
)
const handleRates = useCallback((rates?: Rates) => {
if (rates) {
setRates(rates)
}
}, [])

// eslint-disable-next-line arrow-body-style
useEffect(() => {
rateSocket.on("rates", (__rates) => {
listener(setRates, __rates)
})
rateSocket.on("rates", handleRates)
if (!rateSocket.connected) {
rateSocket.connect()
}

return () => {
rateSocket.off("rates", listener)
rateSocket.off("rates", handleRates)
}
}, [listener])
}, [handleRates])

return {
data,
ngn: data?.data.rates.BUSDNGN.rate,
ngn: data?.data.rates.USDTNGN,
usd: 1,
}
}
Expand Down
11 changes: 9 additions & 2 deletions src/services/socket.setup.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { io } from "socket.io-client"

export const rateSocket = io(`${process.env.REACT_APP_BACKEND_URL}/rates`)
export const txSocket = io(`${process.env.REACT_APP_BACKEND_URL}/transactions`)
export const rateSocket = io(`${process.env.REACT_APP_BACKEND_URL}/rates`, {
autoConnect: false,
})
export const txSocket = io(
`${process.env.REACT_APP_BACKEND_URL}/transactions`,
{
autoConnect: true,
}
)
2 changes: 1 addition & 1 deletion src/state/exchange/atoms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const exchangeAtom = atom<Exchange>({
dollarRate: 1,
preferredFiat: supportedFiat.usd,

dollarRates: { usd: 1, ngn: 745 },
dollarRates: { usd: 1, ngn: 1470 },

bankAccount: undefined,
txHash: "0x",
Expand Down
4 changes: 2 additions & 2 deletions src/utils/constants/exchange.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ export const pinnedTokens: { [key in ChainId]: [ERC20Token, string][] } = {
export const BIG_INT_TEN = JSBI.BigInt(10)
export const BIG_INT_ZERO = JSBI.BigInt(0)

// used to ensure the user doesn't send so much BNB so they end up with <.01
export const MIN_BNB: JSBI = JSBI.exponentiate(BIG_INT_TEN, JSBI.BigInt(16)) // .01 BNB
// used to ensure the user doesn't send so much BNB so they end up with <.0000000000001
export const MIN_BNB: JSBI = JSBI.exponentiate(BIG_INT_TEN, JSBI.BigInt(5)) // .0000000000001 BNB

export const BIPS_BASE = JSBI.BigInt(10000)
export const BETTER_TRADE_LESS_HOPS_THRESHOLD = new Percent(
Expand Down
4 changes: 2 additions & 2 deletions src/utils/constants/tokens/97.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ export const bscTestnetTokens = {
),
usdc: new ERC20Token(
ChainId.BSC_TESTNET,
"0xCA8eB2dec4Fe3a5abbFDc017dE48E461A936623D",
"0x64544969ed7EBf5f083679233325356EbE738930",
18,
"USDC",
"Binance-Peg USD Coin"
),
usdt: new ERC20Token(
ChainId.BSC_TESTNET,
"0x0fB5D7c73FA349A90392f873a4FA1eCf6a3d0a96",
"0x337610d27c682E347C9cD60BD4b3b107C9d34dDd",
18,
"USDT",
"Tether USD"
Expand Down
Loading