mirror of
https://github.com/kremalicious/asi-calculator.git
synced 2024-12-22 17:33:18 +01:00
refactor
This commit is contained in:
parent
5d2a805995
commit
70398b26c4
@ -4,7 +4,7 @@
|
||||
|
||||
--foreground-rgb: 20, 20, 20;
|
||||
--foreground-rgb-highlight: 0, 0, 0;
|
||||
--background-start-rgb: 214, 219, 220;
|
||||
--background-start-rgb: 225, 230, 230;
|
||||
--background-end-rgb: 255, 255, 255;
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
:root {
|
||||
--foreground-rgb: 220, 220, 220;
|
||||
--foreground-rgb-highlight: 255, 255, 255;
|
||||
--background-start-rgb: 0, 0, 0;
|
||||
--background-start-rgb: 25, 25, 25;
|
||||
--background-end-rgb: 0, 0, 0;
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,14 @@
|
||||
font-size: clamp(1.1rem, 10vw, 1.5rem);
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
gap: 2rem;
|
||||
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
|
||||
max-width: calc(var(--max-width) * 1.5);
|
||||
margin: 3rem auto;
|
||||
}
|
||||
|
||||
.footer {
|
||||
flex-shrink: 0;
|
||||
font-size: 0.8rem;
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { Prices } from '@/components/Prices'
|
||||
import styles from './page.module.css'
|
||||
import { metadata } from './layout'
|
||||
import { Swap, Buy } from '@/components/Strategies'
|
||||
import { Content } from '@/components/Content'
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
@ -10,7 +11,11 @@ export default function Home() {
|
||||
<p className={styles.description}>{`${metadata.description}`}</p>
|
||||
</header>
|
||||
<main className={styles.main}>
|
||||
<Prices />
|
||||
<div className={styles.grid}>
|
||||
<Swap />
|
||||
<Buy />
|
||||
</div>
|
||||
<Content />
|
||||
</main>
|
||||
<footer className={styles.footer}>
|
||||
Send ❤️ and memecoins to krema.eth
|
||||
|
@ -1,23 +1,23 @@
|
||||
'use client'
|
||||
|
||||
import { ratioOceanToAsi, ratioAgixToAsi, ratioFetToAsi } from '@/constants'
|
||||
import styles from './Content.module.css'
|
||||
import { usePrices } from '@/hooks'
|
||||
|
||||
type Props = {
|
||||
prices: {
|
||||
[key: string]: number
|
||||
}
|
||||
}
|
||||
export function Content() {
|
||||
const prices = usePrices()
|
||||
|
||||
export function Content({ prices }: Props) {
|
||||
return (
|
||||
<div className={styles.content}>
|
||||
<p>
|
||||
The displayed values should be seen as estimates. Except for the{' '}
|
||||
All displayed values should be seen as estimates. Except for the{' '}
|
||||
<a href="https://blog.oceanprotocol.com/ocean-protocol-is-joining-the-superintelligence-alliance-767c82693f24#3c8e">
|
||||
fixed ASI exchange rate
|
||||
</a>
|
||||
, the fiat values fetched from <a href="">Coingecko</a> and the token
|
||||
swap quotes from <a href="https://uniswap.org">Uniswap</a> v3 routes are
|
||||
constantly changing.
|
||||
, the fiat values fetched from{' '}
|
||||
<a href="https://coingecko.com">Coingecko</a> and the token swap quotes
|
||||
from <a href="https://uniswap.org">Uniswap</a> v3 routes are constantly
|
||||
changing.
|
||||
</p>
|
||||
<p>
|
||||
There is no guarantee they reflect the value of your investment once the
|
||||
|
1
components/FormAmount/index.tsx
Normal file
1
components/FormAmount/index.tsx
Normal file
@ -0,0 +1 @@
|
||||
export * from './FormAmount'
|
@ -1,161 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import useSWR from 'swr'
|
||||
import { useDebounce } from 'use-debounce'
|
||||
import styles from './Prices.module.css'
|
||||
import { Result } from './Result'
|
||||
import {
|
||||
tokens,
|
||||
ratioOceanToAsi,
|
||||
ratioAgixToAsi,
|
||||
ratioFetToAsi
|
||||
} from '@/constants'
|
||||
import { useState } from 'react'
|
||||
import { FormAmount } from './FormAmount'
|
||||
import { fetcher, formatNumber } from '@/utils'
|
||||
import { Content } from '@/components/Content'
|
||||
|
||||
export function Prices() {
|
||||
const [amountSwap, setAmountSwap] = useState(100)
|
||||
const [debouncedAmountSwap] = useDebounce(amountSwap, 500)
|
||||
const [amountBuy, setAmountBuy] = useState(100)
|
||||
const [debouncedAmountBuy] = useDebounce(amountBuy, 500)
|
||||
|
||||
const { data: dataPrices } = useSWR(
|
||||
`/api/prices/?tokens=${tokens.toString()}`,
|
||||
fetcher
|
||||
)
|
||||
|
||||
const { data: dataSwapOceanToAgix } = useSWR(
|
||||
`/api/quote/?tokenIn=${tokens[0]}&tokenOut=${tokens[2]}&amountIn=${debouncedAmountSwap}`,
|
||||
fetcher
|
||||
)
|
||||
|
||||
const { data: dataSwapOceanToFet } = useSWR(
|
||||
`/api/quote/?tokenIn=${tokens[0]}&tokenOut=${tokens[1]}&amountIn=${debouncedAmountSwap}`,
|
||||
fetcher
|
||||
)
|
||||
|
||||
const priceOcean = dataPrices?.[tokens[0]]?.usd || 0
|
||||
const priceFet = dataPrices?.[tokens[1]]?.usd || 0
|
||||
const priceAgix = dataPrices?.[tokens[2]]?.usd || 0
|
||||
const priceAsi = priceFet
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={styles.grid}>
|
||||
<div className={styles.results}>
|
||||
<h3>
|
||||
Swapping{' '}
|
||||
<FormAmount amount={amountSwap} setAmount={setAmountSwap} /> OCEAN (
|
||||
{formatNumber(debouncedAmountSwap * priceOcean, 'USD')}) right now
|
||||
gets you:
|
||||
</h3>
|
||||
|
||||
<Result
|
||||
tokenSymbol="OCEAN"
|
||||
tokenAddress="0x967da4048cd07ab37855c090aaf366e4ce1b9f48"
|
||||
amount={debouncedAmountSwap}
|
||||
amountAsi={debouncedAmountSwap * ratioOceanToAsi}
|
||||
amountFiat={debouncedAmountSwap * ratioOceanToAsi * priceAsi}
|
||||
/>
|
||||
|
||||
<Result
|
||||
tokenSymbol="AGIX"
|
||||
tokenAddress="0x5b7533812759b45c2b44c19e320ba2cd2681b542"
|
||||
amount={
|
||||
dataSwapOceanToAgix?.amountOut /
|
||||
Number(`1e${dataSwapOceanToAgix?.decimals}`) || 0
|
||||
}
|
||||
amountAsi={
|
||||
(dataSwapOceanToAgix?.amountOut /
|
||||
Number(`1e${dataSwapOceanToAgix?.decimals}`) || 0) *
|
||||
ratioAgixToAsi
|
||||
}
|
||||
amountFiat={
|
||||
(dataSwapOceanToAgix?.amountOut /
|
||||
Number(`1e${dataSwapOceanToAgix?.decimals}`) || 0) *
|
||||
ratioAgixToAsi *
|
||||
priceAsi
|
||||
}
|
||||
/>
|
||||
|
||||
<Result
|
||||
tokenSymbol="FET"
|
||||
tokenAddress="0xaea46a60368a7bd060eec7df8cba43b7ef41ad85"
|
||||
amount={
|
||||
dataSwapOceanToFet?.amountOut /
|
||||
Number(`1e${dataSwapOceanToFet?.decimals}`) || 0
|
||||
}
|
||||
amountAsi={
|
||||
(dataSwapOceanToFet?.amountOut /
|
||||
Number(`1e${dataSwapOceanToFet?.decimals}`) || 0) *
|
||||
ratioFetToAsi
|
||||
}
|
||||
amountFiat={
|
||||
(dataSwapOceanToFet?.amountOut /
|
||||
Number(`1e${dataSwapOceanToFet?.decimals}`) || 0) * priceAsi
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={styles.results}>
|
||||
<h3>
|
||||
Buying with $
|
||||
<FormAmount amount={amountBuy} setAmount={setAmountBuy} /> right now
|
||||
gets you:
|
||||
</h3>
|
||||
<Result
|
||||
tokenSymbol="OCEAN"
|
||||
tokenAddress="0x967da4048cd07ab37855c090aaf366e4ce1b9f48"
|
||||
amount={priceOcean ? debouncedAmountBuy / priceOcean : 0}
|
||||
amountAsi={
|
||||
priceOcean
|
||||
? (debouncedAmountBuy / priceOcean) * ratioOceanToAsi
|
||||
: 0
|
||||
}
|
||||
amountFiat={
|
||||
priceOcean
|
||||
? (debouncedAmountBuy / priceOcean) * ratioOceanToAsi * priceAsi
|
||||
: 0
|
||||
}
|
||||
/>
|
||||
<Result
|
||||
tokenSymbol="AGIX"
|
||||
tokenAddress="0x5b7533812759b45c2b44c19e320ba2cd2681b542"
|
||||
amount={priceAgix ? debouncedAmountBuy / priceAgix : 0}
|
||||
amountAsi={
|
||||
priceAgix ? (debouncedAmountBuy / priceAgix) * ratioAgixToAsi : 0
|
||||
}
|
||||
amountFiat={
|
||||
priceAgix
|
||||
? (debouncedAmountBuy / priceAgix) * ratioAgixToAsi * priceAsi
|
||||
: 0
|
||||
}
|
||||
/>
|
||||
<Result
|
||||
tokenSymbol="FET"
|
||||
tokenAddress="0xaea46a60368a7bd060eec7df8cba43b7ef41ad85"
|
||||
amount={priceFet ? debouncedAmountBuy / priceFet : 0}
|
||||
amountAsi={
|
||||
priceFet ? (debouncedAmountBuy / priceFet) * ratioFetToAsi : 0
|
||||
}
|
||||
amountFiat={
|
||||
priceFet
|
||||
? (debouncedAmountBuy / priceFet) * ratioFetToAsi * priceAsi
|
||||
: 0
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<Content
|
||||
prices={{
|
||||
ocean: priceOcean,
|
||||
agix: priceAgix,
|
||||
asi: priceAsi,
|
||||
fet: priceFet
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import styles from './Result.module.css'
|
||||
import { formatNumber } from '../utils'
|
||||
import styles from './ResultRow.module.css'
|
||||
import { formatNumber } from '@/utils'
|
||||
import Image from 'next/image'
|
||||
|
||||
type Props = {
|
1
components/ResultRow/index.tsx
Normal file
1
components/ResultRow/index.tsx
Normal file
@ -0,0 +1 @@
|
||||
export * from './ResultRow'
|
66
components/Strategies/Buy.tsx
Normal file
66
components/Strategies/Buy.tsx
Normal file
@ -0,0 +1,66 @@
|
||||
'use client'
|
||||
|
||||
import { ratioOceanToAsi, ratioAgixToAsi, ratioFetToAsi } from '@/constants'
|
||||
import { FormAmount } from '../FormAmount'
|
||||
import { Result } from '../ResultRow'
|
||||
import { useState } from 'react'
|
||||
import { useDebounce } from 'use-debounce'
|
||||
import styles from './styles.module.css'
|
||||
import { usePrices } from '@/hooks'
|
||||
|
||||
export function Buy() {
|
||||
const prices = usePrices()
|
||||
const [amountBuy, setAmountBuy] = useState(100)
|
||||
const [debouncedAmountBuy] = useDebounce(amountBuy, 500)
|
||||
|
||||
return (
|
||||
<div className={styles.results}>
|
||||
<h3>
|
||||
Buying with $
|
||||
<FormAmount amount={amountBuy} setAmount={setAmountBuy} /> right now
|
||||
gets you:
|
||||
</h3>
|
||||
<Result
|
||||
tokenSymbol="OCEAN"
|
||||
tokenAddress="0x967da4048cd07ab37855c090aaf366e4ce1b9f48"
|
||||
amount={prices.ocean ? debouncedAmountBuy / prices.ocean : 0}
|
||||
amountAsi={
|
||||
prices.ocean
|
||||
? (debouncedAmountBuy / prices.ocean) * ratioOceanToAsi
|
||||
: 0
|
||||
}
|
||||
amountFiat={
|
||||
prices.ocean
|
||||
? (debouncedAmountBuy / prices.ocean) * ratioOceanToAsi * prices.asi
|
||||
: 0
|
||||
}
|
||||
/>
|
||||
<Result
|
||||
tokenSymbol="AGIX"
|
||||
tokenAddress="0x5b7533812759b45c2b44c19e320ba2cd2681b542"
|
||||
amount={prices.agix ? debouncedAmountBuy / prices.agix : 0}
|
||||
amountAsi={
|
||||
prices.agix ? (debouncedAmountBuy / prices.agix) * ratioAgixToAsi : 0
|
||||
}
|
||||
amountFiat={
|
||||
prices.agix
|
||||
? (debouncedAmountBuy / prices.agix) * ratioAgixToAsi * prices.asi
|
||||
: 0
|
||||
}
|
||||
/>
|
||||
<Result
|
||||
tokenSymbol="FET"
|
||||
tokenAddress="0xaea46a60368a7bd060eec7df8cba43b7ef41ad85"
|
||||
amount={prices.fet ? debouncedAmountBuy / prices.fet : 0}
|
||||
amountAsi={
|
||||
prices.fet ? (debouncedAmountBuy / prices.fet) * ratioFetToAsi : 0
|
||||
}
|
||||
amountFiat={
|
||||
prices.fet
|
||||
? (debouncedAmountBuy / prices.fet) * ratioFetToAsi * prices.asi
|
||||
: 0
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
86
components/Strategies/Swap.tsx
Normal file
86
components/Strategies/Swap.tsx
Normal file
@ -0,0 +1,86 @@
|
||||
'use client'
|
||||
|
||||
import {
|
||||
ratioOceanToAsi,
|
||||
ratioAgixToAsi,
|
||||
ratioFetToAsi,
|
||||
tokens
|
||||
} from '@/constants'
|
||||
import { fetcher, formatNumber } from '@/utils'
|
||||
import { FormAmount } from '../FormAmount'
|
||||
import { Result } from '../ResultRow'
|
||||
import styles from './styles.module.css'
|
||||
import { useState } from 'react'
|
||||
import useSWR from 'swr'
|
||||
import { useDebounce } from 'use-debounce'
|
||||
import { usePrices } from '@/hooks'
|
||||
|
||||
export function Swap() {
|
||||
const prices = usePrices()
|
||||
const [amountSwap, setAmountSwap] = useState(100)
|
||||
const [debouncedAmountSwap] = useDebounce(amountSwap, 500)
|
||||
|
||||
const { data: dataSwapOceanToAgix } = useSWR(
|
||||
`/api/quote/?tokenIn=${tokens[0]}&tokenOut=${tokens[2]}&amountIn=${debouncedAmountSwap}`,
|
||||
fetcher
|
||||
)
|
||||
|
||||
const { data: dataSwapOceanToFet } = useSWR(
|
||||
`/api/quote/?tokenIn=${tokens[0]}&tokenOut=${tokens[1]}&amountIn=${debouncedAmountSwap}`,
|
||||
fetcher
|
||||
)
|
||||
|
||||
return (
|
||||
<div className={styles.results}>
|
||||
<h3>
|
||||
Swapping <FormAmount amount={amountSwap} setAmount={setAmountSwap} />{' '}
|
||||
OCEAN ({formatNumber(debouncedAmountSwap * prices.ocean, 'USD')}) right
|
||||
now gets you:
|
||||
</h3>
|
||||
|
||||
<Result
|
||||
tokenSymbol="OCEAN"
|
||||
tokenAddress="0x967da4048cd07ab37855c090aaf366e4ce1b9f48"
|
||||
amount={debouncedAmountSwap}
|
||||
amountAsi={debouncedAmountSwap * ratioOceanToAsi}
|
||||
amountFiat={debouncedAmountSwap * ratioOceanToAsi * prices.asi}
|
||||
/>
|
||||
|
||||
<Result
|
||||
tokenSymbol="AGIX"
|
||||
tokenAddress="0x5b7533812759b45c2b44c19e320ba2cd2681b542"
|
||||
amount={
|
||||
dataSwapOceanToAgix?.amountOut /
|
||||
Number(`1e${dataSwapOceanToAgix?.decimals}`) || 0
|
||||
}
|
||||
amountAsi={
|
||||
(dataSwapOceanToAgix?.amountOut /
|
||||
Number(`1e${dataSwapOceanToAgix?.decimals}`) || 0) * ratioAgixToAsi
|
||||
}
|
||||
amountFiat={
|
||||
(dataSwapOceanToAgix?.amountOut /
|
||||
Number(`1e${dataSwapOceanToAgix?.decimals}`) || 0) *
|
||||
ratioAgixToAsi *
|
||||
prices.asi
|
||||
}
|
||||
/>
|
||||
|
||||
<Result
|
||||
tokenSymbol="FET"
|
||||
tokenAddress="0xaea46a60368a7bd060eec7df8cba43b7ef41ad85"
|
||||
amount={
|
||||
dataSwapOceanToFet?.amountOut /
|
||||
Number(`1e${dataSwapOceanToFet?.decimals}`) || 0
|
||||
}
|
||||
amountAsi={
|
||||
(dataSwapOceanToFet?.amountOut /
|
||||
Number(`1e${dataSwapOceanToFet?.decimals}`) || 0) * ratioFetToAsi
|
||||
}
|
||||
amountFiat={
|
||||
(dataSwapOceanToFet?.amountOut /
|
||||
Number(`1e${dataSwapOceanToFet?.decimals}`) || 0) * prices.asi
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
2
components/Strategies/index.tsx
Normal file
2
components/Strategies/index.tsx
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './Buy'
|
||||
export * from './Swap'
|
@ -1,11 +1,3 @@
|
||||
.grid {
|
||||
display: grid;
|
||||
gap: 2rem;
|
||||
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
|
||||
max-width: calc(var(--max-width) * 1.5);
|
||||
margin: 3rem auto;
|
||||
}
|
||||
|
||||
.results {
|
||||
border: 1px solid rgba(var(--foreground-rgb), 0.2);
|
||||
border-radius: var(--border-radius);
|
1
hooks/index.ts
Normal file
1
hooks/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './use-prices'
|
19
hooks/use-prices.tsx
Normal file
19
hooks/use-prices.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
'use client'
|
||||
|
||||
import { tokens } from '@/constants'
|
||||
import { fetcher } from '@/utils'
|
||||
import useSWR from 'swr'
|
||||
|
||||
export function usePrices() {
|
||||
const { data: dataPrices } = useSWR(
|
||||
`/api/prices/?tokens=${tokens.toString()}`,
|
||||
fetcher
|
||||
)
|
||||
|
||||
const ocean = dataPrices?.[tokens[0]]?.usd || 0
|
||||
const fet = dataPrices?.[tokens[1]]?.usd || 0
|
||||
const agix = dataPrices?.[tokens[2]]?.usd || 0
|
||||
const asi = fet
|
||||
|
||||
return { ocean, fet, agix, asi }
|
||||
}
|
Loading…
Reference in New Issue
Block a user