mirror of
https://github.com/kremalicious/asi-calculator.git
synced 2024-12-22 09:23:16 +01:00
refactor
This commit is contained in:
parent
1ffaab23f5
commit
6123e5d182
@ -3,7 +3,7 @@
|
||||
import { ratioOceanToAsi, ratioAgixToAsi, ratioFetToAsi } from '@/constants'
|
||||
import styles from './CalculationBase.module.css'
|
||||
import { usePrices } from '@/hooks'
|
||||
import { Label } from '../Label'
|
||||
import { Label } from '@/components/Label'
|
||||
|
||||
export function CalculationBase() {
|
||||
const { prices, isValidating } = usePrices()
|
||||
|
@ -2,7 +2,7 @@ import { InputAmount } from '@/components/FormAmount/Inputs/InputAmount'
|
||||
import { InputToken } from './Inputs/InputToken'
|
||||
import styles from './FormAmount.module.css'
|
||||
import { Dispatch, SetStateAction } from 'react'
|
||||
import { Token } from './types'
|
||||
import { TokenSymbol } from '@/types'
|
||||
|
||||
export function FormAmount({
|
||||
amount,
|
||||
@ -13,8 +13,8 @@ export function FormAmount({
|
||||
}: {
|
||||
amount: number
|
||||
setAmount: Dispatch<SetStateAction<number>>
|
||||
token: Token | string
|
||||
setToken?: Dispatch<SetStateAction<Token>>
|
||||
token: TokenSymbol | string
|
||||
setToken?: Dispatch<SetStateAction<TokenSymbol>>
|
||||
isFiat?: boolean
|
||||
}) {
|
||||
return (
|
||||
|
@ -1,33 +1,35 @@
|
||||
import { Dispatch, SetStateAction } from 'react'
|
||||
import styles from './InputToken.module.css'
|
||||
import { CaretDownIcon } from '@radix-ui/react-icons'
|
||||
import { Token } from '../types'
|
||||
import { TokenSymbol } from '@/types'
|
||||
|
||||
export function InputToken({
|
||||
token,
|
||||
setToken,
|
||||
isFiat
|
||||
}: {
|
||||
token: Token | string
|
||||
token: TokenSymbol | string
|
||||
isFiat?: boolean
|
||||
setToken?: Dispatch<SetStateAction<Token>>
|
||||
setToken?: Dispatch<SetStateAction<TokenSymbol>>
|
||||
}) {
|
||||
return (
|
||||
<span className={styles.selectWrapper}>
|
||||
<select
|
||||
className={styles.select}
|
||||
onChange={(e) => (setToken ? setToken(e.target.value as Token) : null)}
|
||||
onChange={(e) =>
|
||||
setToken ? setToken(e.target.value as TokenSymbol) : null
|
||||
}
|
||||
value={token}
|
||||
disabled={!setToken}
|
||||
style={setToken ? { paddingRight: '1.25rem' } : {}}
|
||||
>
|
||||
{isFiat ? (
|
||||
<option value="usd">USD</option>
|
||||
<option value="USD">USD</option>
|
||||
) : (
|
||||
<>
|
||||
<option value="ocean">OCEAN</option>
|
||||
<option value="fet">FET</option>
|
||||
<option value="agix">AGIX</option>
|
||||
<option value="OCEAN">OCEAN</option>
|
||||
<option value="FET">FET</option>
|
||||
<option value="AGIX">AGIX</option>
|
||||
</>
|
||||
)}
|
||||
</select>
|
||||
|
@ -1,2 +1 @@
|
||||
export * from './FormAmount'
|
||||
export * from './types'
|
||||
|
@ -1 +0,0 @@
|
||||
export type Token = 'ocean' | 'fet' | 'agix' | undefined
|
@ -1,58 +1,49 @@
|
||||
'use client'
|
||||
|
||||
import { Result } from '@/components/ResultRow'
|
||||
import {
|
||||
ratioOceanToAsi,
|
||||
ratioAgixToAsi,
|
||||
ratioFetToAsi,
|
||||
tokens
|
||||
} from '@/constants'
|
||||
import { fetcher } from '@/utils'
|
||||
import { Result } from '@/components/ResultRow'
|
||||
import stylesShared from './styles.module.css'
|
||||
import { useState } from 'react'
|
||||
import useSWR from 'swr'
|
||||
import { useDebounce } from 'use-debounce'
|
||||
import { usePrices } from '@/hooks'
|
||||
import { FormAmount, type Token } from '@/components/FormAmount'
|
||||
import { fetcher } from '@/utils'
|
||||
import useSWR from 'swr'
|
||||
import { TokenSymbol } from '@/types'
|
||||
|
||||
export function Swap() {
|
||||
export function SwapResults({
|
||||
token,
|
||||
amount
|
||||
}: {
|
||||
token: TokenSymbol
|
||||
amount: number
|
||||
}) {
|
||||
const { prices, isValidating: isValidatingPrices } = usePrices()
|
||||
const [amount, setAmount] = useState(100)
|
||||
const [debouncedAmount] = useDebounce(amount, 500)
|
||||
const [token, setToken] = useState<Token>('ocean')
|
||||
|
||||
const { data: dataSwapOceanToAgix, isValidating: isValidatingOceanToAgix } =
|
||||
useSWR(
|
||||
`/api/quote/?tokenIn=${tokens[0]}&tokenOut=${tokens[2]}&amountIn=${debouncedAmount}`,
|
||||
`/api/quote/?tokenIn=${tokens[0].address}&tokenOut=${tokens[2].address}&amountIn=${amount}`,
|
||||
fetcher
|
||||
)
|
||||
|
||||
const { data: dataSwapOceanToFet, isValidating: isValidatingOceanToFet } =
|
||||
useSWR(
|
||||
`/api/quote/?tokenIn=${tokens[0]}&tokenOut=${tokens[1]}&amountIn=${debouncedAmount}`,
|
||||
`/api/quote/?tokenIn=${tokens[0].address}&tokenOut=${tokens[1].address}&amountIn=${amount}`,
|
||||
fetcher
|
||||
)
|
||||
|
||||
return (
|
||||
<div className={stylesShared.results}>
|
||||
<h3 className={stylesShared.title}>
|
||||
Holding or swapping{' '}
|
||||
<FormAmount
|
||||
amount={amount}
|
||||
token={token}
|
||||
setAmount={setAmount}
|
||||
// setToken={setToken}
|
||||
/>{' '}
|
||||
right now gets you:
|
||||
</h3>
|
||||
|
||||
<>
|
||||
<Result
|
||||
tokenSymbol="OCEAN"
|
||||
tokenAddress="0x967da4048cd07ab37855c090aaf366e4ce1b9f48"
|
||||
amount={debouncedAmount}
|
||||
amountAsi={debouncedAmount * ratioOceanToAsi}
|
||||
amountFiat={debouncedAmount * ratioOceanToAsi * prices.asi}
|
||||
amountOriginalFiat={token ? debouncedAmount * prices[token] : undefined}
|
||||
amount={amount}
|
||||
amountAsi={amount * ratioOceanToAsi}
|
||||
amountFiat={amount * ratioOceanToAsi * prices.asi}
|
||||
amountOriginalFiat={
|
||||
token
|
||||
? amount *
|
||||
prices[token.toLowerCase() as 'ocean' | 'agix' | 'fet' | 'asi']
|
||||
: undefined
|
||||
}
|
||||
isValidating={
|
||||
isValidatingOceanToAgix ||
|
||||
isValidatingOceanToFet ||
|
||||
@ -105,6 +96,6 @@ export function Swap() {
|
||||
}
|
||||
isValidating={isValidatingOceanToFet || isValidatingPrices}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
31
components/Strategies/Swap/Swap.tsx
Normal file
31
components/Strategies/Swap/Swap.tsx
Normal file
@ -0,0 +1,31 @@
|
||||
'use client'
|
||||
|
||||
import stylesShared from '../styles.module.css'
|
||||
import { useState } from 'react'
|
||||
import { useDebounce } from 'use-debounce'
|
||||
import { FormAmount } from '@/components/FormAmount'
|
||||
import { SwapResults } from './Results'
|
||||
import { TokenSymbol } from '@/types'
|
||||
|
||||
export function Swap() {
|
||||
const [amount, setAmount] = useState(100)
|
||||
const [debouncedAmount] = useDebounce(amount, 500)
|
||||
const [token, setToken] = useState<TokenSymbol>('OCEAN')
|
||||
|
||||
return (
|
||||
<div className={stylesShared.results}>
|
||||
<h3 className={stylesShared.title}>
|
||||
Holding or swapping{' '}
|
||||
<FormAmount
|
||||
amount={amount}
|
||||
token={token}
|
||||
setAmount={setAmount}
|
||||
// setToken={setToken}
|
||||
/>{' '}
|
||||
right now gets you:
|
||||
</h3>
|
||||
|
||||
<SwapResults token={token} amount={debouncedAmount} />
|
||||
</div>
|
||||
)
|
||||
}
|
@ -1,2 +1,2 @@
|
||||
export * from './Buy'
|
||||
export * from './Swap'
|
||||
export * from './Swap/Swap'
|
||||
|
10
constants.ts
10
constants.ts
@ -1,9 +1,11 @@
|
||||
import { Token } from '@/types'
|
||||
|
||||
export const ratioOceanToAsi = 0.433226
|
||||
export const ratioAgixToAsi = 0.43335
|
||||
export const ratioFetToAsi = 1
|
||||
|
||||
export const tokens: `0x${string}`[] = [
|
||||
'0x967da4048cd07ab37855c090aaf366e4ce1b9f48', // OCEAN
|
||||
'0xaea46a60368a7bd060eec7df8cba43b7ef41ad85', // FET
|
||||
'0x5b7533812759b45c2b44c19e320ba2cd2681b542' // AGIX
|
||||
export const tokens: Token[] = [
|
||||
{ symbol: 'OCEAN', address: '0x967da4048cd07ab37855c090aaf366e4ce1b9f48' },
|
||||
{ symbol: 'FET', address: '0xaea46a60368a7bd060eec7df8cba43b7ef41ad85' },
|
||||
{ symbol: 'AGIX', address: '0x5b7533812759b45c2b44c19e320ba2cd2681b542' }
|
||||
]
|
||||
|
@ -1,22 +1,33 @@
|
||||
'use client'
|
||||
|
||||
import { tokens } from '@/constants'
|
||||
import { fetcher } from '@/utils'
|
||||
import { fetcher, getTokenAddressBySymbol } from '@/utils'
|
||||
import useSWR from 'swr'
|
||||
|
||||
const tokenAddresses = tokens.map((token) => token.address).toString()
|
||||
|
||||
export function usePrices(): {
|
||||
prices: { ocean: number; fet: number; agix: number; asi: number }
|
||||
isValidating: boolean
|
||||
isLoading: boolean
|
||||
} {
|
||||
const { data, isValidating, isLoading } = useSWR(
|
||||
`/api/prices/?tokens=${tokens.toString()}`,
|
||||
`/api/prices/?tokens=${tokenAddresses}`,
|
||||
fetcher
|
||||
)
|
||||
|
||||
const ocean = data?.[tokens[0]]?.usd || 0
|
||||
const fet = data?.[tokens[1]]?.usd || 0
|
||||
const agix = data?.[tokens[2]]?.usd || 0
|
||||
const oceanAddress = getTokenAddressBySymbol('OCEAN')
|
||||
const fetAddress = getTokenAddressBySymbol('FET')
|
||||
const agixAddress = getTokenAddressBySymbol('AGIX')
|
||||
|
||||
if (!oceanAddress || !fetAddress || !agixAddress)
|
||||
return {
|
||||
prices: { ocean: 0, fet: 0, agix: 0, asi: 0 },
|
||||
isValidating,
|
||||
isLoading
|
||||
}
|
||||
|
||||
const ocean = data?.[oceanAddress]?.usd || 0
|
||||
const fet = data?.[fetAddress]?.usd || 0
|
||||
const agix = data?.[agixAddress]?.usd || 0
|
||||
const asi = fet
|
||||
|
||||
return { prices: { ocean, fet, agix, asi }, isValidating, isLoading }
|
||||
|
7
types/Token.ts
Normal file
7
types/Token.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export type TokenSymbol = 'OCEAN' | 'FET' | 'AGIX' | 'ASI'
|
||||
export type TokenAddress = `0x${string}`
|
||||
|
||||
export type Token = {
|
||||
symbol: TokenSymbol
|
||||
address: `0x${string}`
|
||||
}
|
1
types/index.ts
Normal file
1
types/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './Token'
|
@ -1,3 +1,5 @@
|
||||
import { tokens } from '@/constants'
|
||||
import type { TokenAddress, Token } from '@/types'
|
||||
import { formatCurrency } from '@coingecko/cryptoformat'
|
||||
|
||||
export function formatNumber(price: number, currency: string) {
|
||||
@ -12,3 +14,15 @@ export async function fetcher(url: string) {
|
||||
if (!res.ok) throw new Error('Failed to fetch')
|
||||
return await res.json()
|
||||
}
|
||||
|
||||
export function getTokenBySymbol(symbol: string): Token | undefined {
|
||||
const token = tokens.find((t) => t.symbol === symbol)
|
||||
return token
|
||||
}
|
||||
|
||||
export function getTokenAddressBySymbol(
|
||||
symbol: string
|
||||
): TokenAddress | undefined {
|
||||
const token = getTokenBySymbol(symbol)
|
||||
return token?.address
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user