Compare commits

..

No commits in common. "main" and "extension-integration" have entirely different histories.

29 changed files with 285 additions and 1002 deletions

View File

@ -1,7 +1,7 @@
{
"name": "ghost-dao-interface",
"private": true,
"version": "0.3.11",
"version": "0.2.15",
"type": "module",
"scripts": {
"dev": "vite",

View File

@ -14,7 +14,7 @@ import Sidebar from "./components/Sidebar/Sidebar";
import TopBar from "./components/TopBar/TopBar";
import { shouldTriggerSafetyCheck } from "./helpers";
import { isNetworkAvailable, isNetworkLegacy } from "./constants";
import { isNetworkAvailable } from "./constants";
import useTheme from "./hooks/useTheme";
import { useUnstableProvider } from "./hooks/ghost";
import { dark as darkTheme } from "./themes/dark.js";
@ -27,7 +27,6 @@ const BondModalContainer = lazy(() => import("./containers/Bond/BondModal"));
const StakeContainer = lazy(() => import("./containers/Stake/StakeContainer"));
const TreasuryDashboard = lazy(() => import("./containers/TreasuryDashboard/TreasuryDashboard"));
const Faucet = lazy(() => import("./containers/Faucet/Faucet"));
const Wrapper = lazy(() => import("./containers/WethWrapper/WethWrapper"));
const Dex = lazy(() => import("./containers/Dex/Dex"));
const Bridge = lazy(() => import("./containers/Bridge/Bridge"));
const NotFound = lazy(() => import("./containers/NotFound/NotFound"));
@ -207,10 +206,7 @@ function App() {
<Route path="/bonds" element={<Bonds connect={tryConnectInjected} address={address} chainId={addressChainId ? addressChainId : chainId} />} />
<Route path="/bonds/:id" element={<BondModalContainer connect={tryConnectInjected} address={address} chainId={addressChainId ? addressChainId : chainId} />} />
<Route path="/stake" element={<StakeContainer connect={tryConnectInjected} address={address} chainId={addressChainId ? addressChainId : chainId}/>} />
{isNetworkLegacy(chainId)
? <Route path="/faucet" element={<Faucet config={config} connect={tryConnectInjected} address={address} chainId={addressChainId ? addressChainId : chainId} />} />
: <Route path="/wrapper" element={<Wrapper config={config} connect={tryConnectInjected} address={address} chainId={addressChainId ? addressChainId : chainId} />} />
}
<Route path="/faucet" element={<Faucet config={config} connect={tryConnectInjected} address={address} chainId={addressChainId ? addressChainId : chainId} />} />
<Route path="/bridge" element={<Bridge config={config} connect={tryConnectInjected} address={address} chainId={addressChainId ? addressChainId : chainId} />} />
<Route path="/dex/:name" element={<Dex connect={tryConnectInjected} address={address} chainId={addressChainId ? addressChainId : chainId} />} />
</>

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
{"abi":[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"src","type":"address"},{"indexed":true,"internalType":"address","name":"guy","type":"address"},{"indexed":false,"internalType":"uint256","name":"wad","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"dst","type":"address"},{"indexed":false,"internalType":"uint256","name":"wad","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"src","type":"address"},{"indexed":true,"internalType":"address","name":"dst","type":"address"},{"indexed":false,"internalType":"uint256","name":"wad","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"src","type":"address"},{"indexed":false,"internalType":"uint256","name":"wad","type":"uint256"}],"name":"Withdrawal","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"guy","type":"address"},{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]}

View File

@ -1,36 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="uuid-61b3c585-44d6-4fd8-a0e7-6a5e76478eb1" data-name="uuid-70ba15fb-c44e-4945-a02a-8d07f94a9abb" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 505 505">
<defs>
<style>
.uuid-6437a6f0-42e0-4c9c-b0ef-b632253e989a {
fill: #fff;
}
.uuid-f6980b42-338a-476b-b4b3-c6f8474bfe6a {
fill: #0b8311;
}
.uuid-cee5d69f-ecfa-41d4-b22b-62a3555cf216 {
fill: #3ab83a;
}
.uuid-8c3bab1c-21e8-4834-aebc-42a28aaec68e {
fill: #146714;
}
</style>
</defs>
<g fill="#222" data-name="uuid-3af91251-9afa-43cd-b331-1e6ceef8228b">
<g id="uuid-38146a20-6896-4919-8709-3b8aa9b9b9de" data-name="uuid-bca144dc-fff0-427e-b9b1-33b0d4491804">
<g id="uuid-01777163-9cb4-4f63-8018-462f63cda4ae" data-name="uuid-d1a1e453-da74-40e2-920d-7662cd9352f5">
<path d="m245.2,485.4c-64.14,0-124.44-24.99-169.8-70.36C30.05,369.68,5.05,309.36,5,245.2c0-64.15,24.99-124.46,70.36-169.84C120.73,29.98,181.05,5,245.2,5s124.47,24.99,169.84,70.36c45.37,45.37,70.36,105.69,70.36,169.84s-24.99,124.47-70.36,169.84-105.69,70.36-169.84,70.36h0Z"/>
<path class="uuid-6437a6f0-42e0-4c9c-b0ef-b632253e989a" d="m245.2,10c31.75,0,62.55,6.22,91.54,18.48,28.01,11.85,53.16,28.81,74.77,50.41,21.61,21.61,38.57,46.76,50.41,74.77,12.26,28.99,18.48,59.79,18.48,91.54s-6.22,62.55-18.48,91.54c-11.85,28.01-28.81,53.16-50.41,74.77-21.61,21.61-46.76,38.57-74.77,50.41-28.99,12.26-59.79,18.48-91.54,18.48s-62.54-6.22-91.52-18.48c-28-11.85-53.14-28.81-74.74-50.41s-38.56-46.76-50.41-74.77c-12.27-28.99-18.5-59.79-18.52-91.54,0-31.75,6.22-62.55,18.48-91.54,11.85-28.01,28.81-53.16,50.41-74.77,21.61-21.61,46.76-38.57,74.77-50.41,28.99-12.26,59.79-18.48,91.54-18.48M245.21,0C109.8,0,0,109.8,0,245.2c.1,135.4,109.8,245.2,245.2,245.2s245.2-109.8,245.2-245.2S380.6,0,245.2,0h0Z"/>
</g>
<g id="uuid-91c9d373-1cb9-4018-9a6a-66437f262f1c" data-name="uuid-863b3aee-71cf-488d-8b5a-a2d97fac93c4">
<path id="uuid-538e9787-13a3-4271-8587-11f8527f9a71" data-name="uuid-10bd56be-0db7-4e24-bb20-a24d1c3cbcb7" class="uuid-cee5d69f-ecfa-41d4-b22b-62a3555cf216" d="m144.29,259.73c35.56,18.89,72.67,38.65,101.33,53.95l100.5-53.95c-36.39,54.06-66.71,99.06-100.5,148.87-33.85-49.7-71.23-104.54-101.33-148.87Zm3.87-14.91l97.57-52.07,96.3,51.69-96.25,52.12-97.63-51.74h.01Zm97.46-68.75l-101.33,53.34,100.89-147.71,100.94,148.04-100.5-53.67h0Z"/>
<path id="uuid-4aa91baa-53f1-4f63-abbe-cf753f8525a0" data-name="uuid-4c5fd78b-71fb-4d56-83d4-a2022fef9f50" class="uuid-f6980b42-338a-476b-b4b3-c6f8474bfe6a" d="m245.61,313.68l100.5-53.95c-36.39,54.06-100.5,148.87-100.5,148.87v-94.92h0Zm.11-120.93l96.3,51.69-96.25,52.12-.05-103.81h0Zm-.11-16.68l-.44-94.37,100.94,148.04-100.5-53.67h0Z"/>
<path id="uuid-3febb173-485e-4b4e-92b6-b05cc7b0412b" data-name="uuid-3f7cae2c-d7bb-44d6-a6e9-cd80adc2aeac" class="uuid-f6980b42-338a-476b-b4b3-c6f8474bfe6a" d="m148.15,244.82l97.58,8.01,96.3-8.34-96.25,52.13-97.63-51.8h0Z"/>
<path id="uuid-df565d0e-a3cf-452f-80f6-2e6ea5ca4f56" data-name="uuid-e69b7837-4cf3-4793-a865-a26ad4121390" class="uuid-8c3bab1c-21e8-4834-aebc-42a28aaec68e" d="m245.72,252.83l96.3-8.34-96.25,52.13-.05-43.79h0Z"/>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -1,36 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="uuid-39ebc51d-db02-45d2-ad4b-e7ae31bb915b" data-name="Ethereum" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 250 250">
<defs>
<style>
.uuid-e080659c-91a4-4965-9905-603394020b2c {
fill: #fff;
}
.uuid-ca9afedd-40fd-4006-99f9-d2c3cf46bc21 {
fill: #627eea;
}
.uuid-bb37a35d-b2ce-440e-86f6-0142a60ec718 {
fill: rgba(255, 255, 255, .2);
}
.uuid-933ff958-c1b5-4023-94a9-0cca9b4aab50 {
fill: rgba(255, 255, 255, .6);
}
</style>
</defs>
<g id="uuid-c49657cc-831e-4816-83c0-b3ceca5eead0" data-name="Ethereum">
<g id="uuid-559a2235-ac8a-4942-be49-ac3193ebd3cd" data-name="EthereumBackground">
<circle class="uuid-ca9afedd-40fd-4006-99f9-d2c3cf46bc21" cx="125" cy="125" r="122.5"/>
<path class="uuid-e080659c-91a4-4965-9905-603394020b2c" d="m125,5c32.05,0,62.19,12.48,84.85,35.15,22.67,22.66,35.15,52.8,35.15,84.85s-12.48,62.19-35.15,84.85-52.8,35.15-84.85,35.15-62.19-12.48-84.85-35.15C17.48,187.19,5,157.05,5,125s12.48-62.19,35.15-84.85C62.81,17.48,92.95,5,125,5m0-5C55.96,0,0,55.96,0,125s55.96,125,125,125,125-55.96,125-125S194.04,0,125,0h0Z"/>
</g>
<g id="uuid-0bd28738-f2c4-4934-8365-8668de7b64ac" data-name="EthereumIcon">
<path class="uuid-933ff958-c1b5-4023-94a9-0cca9b4aab50" d="m128.89,31.25v69.3l58.57,26.17-58.57-95.47Z"/>
<path class="uuid-e080659c-91a4-4965-9905-603394020b2c" d="m128.89,31.25l-58.58,95.47,58.58-26.17V31.25Z"/>
<path class="uuid-933ff958-c1b5-4023-94a9-0cca9b4aab50" d="m128.89,171.62v47.09l58.61-81.09-58.61,34Z"/>
<path class="uuid-e080659c-91a4-4965-9905-603394020b2c" d="m128.89,218.71v-47.09l-58.58-33.99,58.58,81.09Z"/>
<path class="uuid-bb37a35d-b2ce-440e-86f6-0142a60ec718" d="m128.89,160.73l58.57-34.01-58.57-26.16v60.16Z"/>
<path class="uuid-933ff958-c1b5-4023-94a9-0cca9b4aab50" d="m70.31,126.72l58.58,34.01v-60.16l-58.58,26.16Z"/>
</g>
<svg xmlns="http://www.w3.org/2000/svg" width="2500" height="2500" viewBox="0 0 32 32">
<g fill="none" fill-rule="evenodd">
<circle cx="16" cy="16" r="16" fill="#627EEA"/>
<g fill="#FFF" fill-rule="nonzero">
<path fill-opacity=".602" d="M16.498 4v8.87l7.497 3.35z"/>
<path d="M16.498 4L9 16.22l7.498-3.35z"/>
<path fill-opacity=".602" d="M16.498 21.968v6.027L24 17.616z"/>
<path d="M16.498 27.995v-6.028L9 17.616z"/>
<path fill-opacity=".2" d="M16.498 20.573l7.497-4.353-7.497-3.348z"/>
<path fill-opacity=".602" d="M9 16.22l7.498 4.353v-7.701z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 617 B

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="uuid-39ebc51d-db02-45d2-ad4b-e7ae31bb915b" data-name="Ethereum" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 250 250">
<defs>
<style>
.uuid-e080659c-91a4-4965-9905-603394020b2c {
fill: #fff;
}
.uuid-ca9afedd-40fd-4006-99f9-d2c3cf46bc21 {
fill: #627eea;
}
.uuid-bb37a35d-b2ce-440e-86f6-0142a60ec718 {
fill: rgba(255, 255, 255, .2);
}
.uuid-933ff958-c1b5-4023-94a9-0cca9b4aab50 {
fill: rgba(255, 255, 255, .6);
}
</style>
</defs>
<g id="uuid-c49657cc-831e-4816-83c0-b3ceca5eead0" data-name="Ethereum">
<g id="uuid-559a2235-ac8a-4942-be49-ac3193ebd3cd" data-name="EthereumBackground">
<circle class="uuid-ca9afedd-40fd-4006-99f9-d2c3cf46bc21" cx="125" cy="125" r="122.5"/>
<path class="uuid-e080659c-91a4-4965-9905-603394020b2c" d="m125,5c32.05,0,62.19,12.48,84.85,35.15,22.67,22.66,35.15,52.8,35.15,84.85s-12.48,62.19-35.15,84.85-52.8,35.15-84.85,35.15-62.19-12.48-84.85-35.15C17.48,187.19,5,157.05,5,125s12.48-62.19,35.15-84.85C62.81,17.48,92.95,5,125,5m0-5C55.96,0,0,55.96,0,125s55.96,125,125,125,125-55.96,125-125S194.04,0,125,0h0Z"/>
</g>
<g id="uuid-0bd28738-f2c4-4934-8365-8668de7b64ac" data-name="EthereumIcon">
<path class="uuid-933ff958-c1b5-4023-94a9-0cca9b4aab50" d="m128.89,31.25v69.3l58.57,26.17-58.57-95.47Z"/>
<path class="uuid-e080659c-91a4-4965-9905-603394020b2c" d="m128.89,31.25l-58.58,95.47,58.58-26.17V31.25Z"/>
<path class="uuid-933ff958-c1b5-4023-94a9-0cca9b4aab50" d="m128.89,171.62v47.09l58.61-81.09-58.61,34Z"/>
<path class="uuid-e080659c-91a4-4965-9905-603394020b2c" d="m128.89,218.71v-47.09l-58.58-33.99,58.58,81.09Z"/>
<path class="uuid-bb37a35d-b2ce-440e-86f6-0142a60ec718" d="m128.89,160.73l58.57-34.01-58.57-26.16v60.16Z"/>
<path class="uuid-933ff958-c1b5-4023-94a9-0cca9b4aab50" d="m70.31,126.72l58.58,34.01v-60.16l-58.58,26.16Z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -37,7 +37,7 @@ import BondIcon from "../Icon/BondIcon";
import StakeIcon from "../Icon/StakeIcon";
import WrapIcon from "../Icon/WrapIcon";
import { isNetworkAvailable, isNetworkLegacy } from "../../constants";
import { isNetworkAvailable } from "../../constants";
import { AVAILABLE_DEXES } from "../../constants/dexes";
import { ECOSYSTEM } from "../../constants/ecosystem";
import { DecimalBigNumber } from "../../helpers/DecimalBigNumber";
@ -46,7 +46,6 @@ import BondDiscount from "../../containers/Bond/components/BondDiscount";
import DashboardIcon from '@mui/icons-material/Dashboard';
import ShowerIcon from '@mui/icons-material/Shower';
import WifiProtectedSetupIcon from '@mui/icons-material/WifiProtectedSetup';
import { useTokenSymbol } from "../../hooks/tokens";
import { useFtsoPrice, useGhstPrice, useGhostedSupplyPrice } from "../../hooks/prices";
@ -149,10 +148,7 @@ const NavContent = ({ chainId, addressChainId }) => {
}
/>
<NavItem icon={StakeIcon} label={`Stake`} to="/stake" />
{isNetworkLegacy(chainId)
? <NavItem icon={ShowerIcon} label={`Faucet`} to="/faucet" />
: <NavItem icon={WifiProtectedSetupIcon} label={`Wrapper`} to="/wrapper" />
}
<NavItem icon={ShowerIcon} label={`Faucet`} to="/faucet" />
<NavItem icon={PublicIcon} label={`Bridge`} to="/bridge" />
<NavItem
icon={CurrencyExchangeIcon}

View File

@ -5,8 +5,7 @@ import FtsoIcon from "../../assets/tokens/FTSO.svg?react";
import StnkIcon from "../../assets/tokens/STNK.svg?react";
import GhstIcon from "../../assets/tokens/GHST.svg?react";
import DaiIcon from "../../assets/tokens/DAI.svg?react";
import EthIcon from "../../assets/tokens/ETH.svg?react";
import EtcIcon from "../../assets/tokens/ETC.svg?react";
import WethIcon from "../../assets/tokens/wETH.svg?react";
import UnknownIcon from "../../assets/tokens/Unknown.svg?react";
const PREFIX = "Token";
@ -24,55 +23,49 @@ const StyledSvgIcon = styled(SvgIcon)(() => ({
},
}));
export const parseKnownToken = (name) => {
let icon;
switch (name?.toUpperCase()) {
case "FTSO":
icon = FtsoIcon;
break;
case "ECSPR":
icon = FtsoIcon;
break;
case "STNK":
icon = StnkIcon;
break;
case "SCSPR":
icon = StnkIcon;
break;
case "GHST":
icon = GhstIcon;
break;
case "CSPR":
icon = GhstIcon;
break;
case "GDAI":
icon = DaiIcon;
break;
case "DAI":
icon = DaiIcon;
break;
case "ETH":
icon = EthIcon;
break;
case "WETH":
icon = EthIcon;
break;
case "METC":
icon = EtcIcon;
break;
case "WMETC":
icon = EtcIcon;
break;
default:
icon = UnknownIcon;
}
return icon;
}
const Token = ({ name, viewBox = "0 0 260 260", fontSize = "large", ...props }) => {
const parseKnownToken = (name) => {
let icon;
switch (name?.toUpperCase()) {
case "FTSO":
icon = FtsoIcon;
break;
case "ECSPR":
icon = FtsoIcon;
break;
case "STNK":
icon = StnkIcon;
break;
case "SCSPR":
icon = StnkIcon;
break;
case "GHST":
icon = GhstIcon;
break;
case "CSPR":
icon = GhstIcon;
break;
case "GDAI":
icon = DaiIcon;
break;
case "DAI":
icon = DaiIcon;
break;
case "ETH":
icon = WethIcon;
break;
case "WETH":
icon = WethIcon;
break;
default:
icon = UnknownIcon;
}
return icon;
}
return (
<StyledSvgIcon
inheritViewBox
viewBox={viewBox}
fontSize={fontSize}
component={parseKnownToken(name)}
{...props}

View File

@ -9,7 +9,7 @@ import FormControl from '@mui/material/FormControl';
import Select from '@mui/material/Select';
import { isNetworkAvailable } from "../../constants";
import { parseKnownToken } from "../../components/Token/Token";
import EthIcon from "../../assets/tokens/ETH.svg?react";
import { useSwitchChain } from 'wagmi';
import toast from "react-hot-toast";
@ -53,11 +53,11 @@ function SelectNetwork({ chainId, wrongNetworkToastId, setWrongNetworkToastId, s
}
}}
>
{chains.map((chain, i) => {
{chains.map(chain => {
return (
<MenuItem key={chain.name} value={chain.id}>
<Box gap="10px" display="flex" flexDirection="row" alignItems="center">
<SvgIcon component={parseKnownToken(chain?.nativeCurrency?.symbol)} inheritViewBox />
<SvgIcon component={EthIcon} viewBox="0 0 32 32" />
{!small && <Typography>{chain.name}</Typography>}
</Box>
</MenuItem>

View File

@ -22,7 +22,7 @@ import { PrimaryButton, SecondaryButton } from "../../Button";
import ArrowUpIcon from "../../../assets/icons/arrow-up.svg?react";
import { formatCurrency, shorten } from "../../../helpers";
import { DecimalBigNumber } from "../../../helpers/DecimalBigNumber";
import { RESERVE_ADDRESSES, FTSO_ADDRESSES } from "../../../constants/addresses";
import { DAI_ADDRESSES, FTSO_ADDRESSES } from "../../../constants/addresses";
import { useAccount, useDisconnect } from "wagmi";
@ -156,9 +156,9 @@ function InitialWalletView({ isWalletOpen, address, chainId, onClose }) {
>
<SecondaryButton
fullWidth
onClick={() => onBtnClick("uniswap", RESERVE_ADDRESSES[chainId], FTSO_ADDRESSES[chainId])}
onClick={() => onBtnClick("uniswap", DAI_ADDRESSES[chainId], FTSO_ADDRESSES[chainId])}
>
<Typography>{`${tokens?.ftso?.symbol}-${tokens?.reserve?.symbol} on Uniswap`}</Typography>
<Typography>{`${tokens?.ftso?.symbol}-${tokens?.dai?.symbol} on Uniswap`}</Typography>
</SecondaryButton>
</Box>

View File

@ -13,24 +13,15 @@ import { ChangeEvent, useState, useEffect } from "react";
import { useNavigate, createSearchParams } from "react-router-dom";
import { useQuery } from "react-query";
import { formatCurrency, formatNumber } from "../../../helpers";
import { DecimalBigNumber } from "../../../helpers/DecimalBigNumber"
import { tokenNameConverter } from "../../../helpers/tokenConverter";
import { isNetworkLegacy } from "../../../constants";
import GhostStyledIcon from "../../Icon/GhostIcon";
import TokenStack from "../../TokenStack/TokenStack";
import { PrimaryButton, SecondaryButton } from "../../Button";
import { useBalance, useTokenSymbol } from "../../../hooks/tokens";
import {
useNativePrice,
useReservePrice,
useFtsoPrice,
useStnkPrice,
useGhstPrice
} from "../../../hooks/prices";
import { useDaiPrice, useFtsoPrice, useStnkPrice, useGhstPrice } from "../../../hooks/prices";
import { useLpValuation } from "../../../hooks/treasury";
import { useAccount, useBalance as useNativeBalance, useConfig } from "wagmi";
import { useAccount } from "wagmi";
const addTokenToWallet = async (token, userAddress) => {
if (!window.ethereum) return;
@ -69,7 +60,6 @@ const BalanceValue = ({
export const Token = (props) => {
const {
isNative,
symbol,
icons,
address,
@ -78,7 +68,7 @@ export const Token = (props) => {
onAddTokenToWallet,
expanded,
onChangeExpanded,
reserveAddress,
daiAddress,
onClose,
isPool
} = props;
@ -86,7 +76,7 @@ export const Token = (props) => {
const navigate = useNavigate();
const useLink = (symbol, fromAddress, toAddress, isPool) => {
if (symbol.toUpperCase() === "RESERVE") {
if (symbol.toUpperCase() === "GDAI") {
navigate({ pathname: "/faucet" })
} else {
navigate({
@ -108,11 +98,8 @@ export const Token = (props) => {
}
return (
<Accordion expanded={isNative ? false : expanded} onChange={onChangeExpanded}>
<AccordionSummary
sx={{ paddingRight: isNative ? "37.43px" : "" }}
expandIcon={isNative ? null : <GhostStyledIcon component={ExpandMoreIcon} color="disabled" />}
>
<Accordion expanded={expanded} onChange={onChangeExpanded}>
<AccordionSummary expandIcon={<GhostStyledIcon component={ExpandMoreIcon} color="disabled" />}>
<Box sx={{ display: "flex", justifyContent: "space-between", width: "100%", marginRight: "10px" }}>
<Box sx={{ display: "flex", alignItems: "center", gap: "15px" }}>
<TokenStack
@ -130,7 +117,7 @@ export const Token = (props) => {
/>
</Box>
</AccordionSummary>
{!isNative && <AccordionDetails style={{ margin: "auto", padding: theme.spacing(1, 0) }}>
<AccordionDetails style={{ margin: "auto", padding: theme.spacing(1, 0) }}>
<Box
sx={{ display: "flex", flexDirection: "column", flex: 1, mx: "32px", justifyContent: "center" }}
style={{ gap: theme.spacing(1) }}
@ -143,14 +130,14 @@ export const Token = (props) => {
<Typography>Add to Wallet</Typography>
</PrimaryButton>
<SecondaryButton
onClick={() => useLink(symbol, reserveAddress, address, isPool)}
onClick={() => useLink(symbol, daiAddress, address, isPool)}
fullWidth
>
<Typography>Get on {symbol?.toUpperCase() === "RESERVE" ? "Faucet" : "Uniswap"}</Typography>
<Typography>Get on {symbol.toUpperCase() === "GDAI" ? "Faucet" : "Uniswap"}</Typography>
</SecondaryButton>
</Box>
</Box>
</AccordionDetails>}
</AccordionDetails>
</Accordion>
);
};
@ -160,15 +147,10 @@ const sumObjValues = (obj: Record<string, string> = {}) =>
export const useWallet = (chainId, userAddress) => {
const {
data: nativeBalanceRaw,
refetch: nativeBalanceRefetch
} = useNativeBalance({ address: userAddress });
const nativeBalance = new DecimalBigNumber(nativeBalanceRaw?.value ?? 0n, 18);
const {
balance: reserveBalance,
refetch: reserveRefetch,
contractAddress: reserveAddress,
} = useBalance(chainId, "RESERVE", userAddress);
balance: daiBalance,
refetch: daiRefetch,
contractAddress: daiAddress,
} = useBalance(chainId, "GDAI", userAddress);
const {
balance: ftsoBalance,
refetch: ftsoRefetch,
@ -185,45 +167,32 @@ export const useWallet = (chainId, userAddress) => {
contractAddress: ghstAddress,
} = useBalance(chainId, "GHST", userAddress);
const {
balance: lpReserveFtsoBalance,
refetch: lpReserveFtsoRefetch,
contractAddress: lpReserveFtsoBalanceAddress,
} = useBalance(chainId, "RESERVE_FTSO", userAddress);
balance: lpDaiFtsoBalance,
refetch: lpDaiFtsoRefetch,
contractAddress: lpDaiFtsoBalanceAddress,
} = useBalance(chainId, "GDAI_FTSO", userAddress);
const nativePrice = useNativePrice(chainId);
const reservePrice = useReservePrice(chainId);
const daiPrice = useDaiPrice(chainId);
const ftsoPrice = useFtsoPrice(chainId);
const stnkPrice = useStnkPrice(chainId);
const ghstPrice = useGhstPrice(chainId);
const lpReserveFtsoPrice = useLpValuation(chainId, "RESERVE_FTSO", 1000000000000000000n);
const lpDaiFtsoPrice = useLpValuation(chainId, "GDAI_FTSO", 1000000000000000000n);
const config = useConfig();
const nativeSymbol = config?.getClient()?.chain?.nativeCurrency?.symbol;
const { symbol: reserveSymbol } = useTokenSymbol(chainId, "RESERVE");
const { symbol: daiSymbol } = useTokenSymbol(chainId, "GDAI");
const { symbol: ftsoSymbol } = useTokenSymbol(chainId, "FTSO");
const { symbol: stnkSymbol } = useTokenSymbol(chainId, "STNK");
const { symbol: ghstSymbol } = useTokenSymbol(chainId, "GHST");
const { symbol: lpReserveFtsoSymbol } = useTokenSymbol(chainId, "RESERVE_FTSO");
const { symbol: lpDaiFtsoSymbol } = useTokenSymbol(chainId, "GDAI_FTSO");
const tokens = {
native: {
symbol: nativeSymbol,
icons: [nativeSymbol],
balance: nativeBalance,
price: nativePrice,
refetch: nativeBalanceRefetch
},
reserve: {
symbol: reserveSymbol,
address: reserveAddress,
balance: reserveBalance,
price: reservePrice,
icons: isNetworkLegacy(chainId) ? ["GDAI"] : [tokenNameConverter(chainId, reserveSymbol)],
externalUrl: isNetworkLegacy(chainId)
? "https://ghostchain.io/wp-content/uploads/2025/03/gDAI.svg"
: "https://ghostchain.io/wp-content/uploads/2025/11/6A-Classic-ETC-Token.svg",
refetch: reserveRefetch,
dai: {
symbol: daiSymbol,
address: daiAddress,
balance: daiBalance,
price: daiPrice,
icons: ["GDAI"],
externalUrl: "https://ghostchain.io/wp-content/uploads/2025/03/gDAI.svg",
refetch: daiRefetch,
},
ftso: {
symbol: ftsoSymbol,
@ -252,15 +221,15 @@ export const useWallet = (chainId, userAddress) => {
externalUrl: "https://ghostchain.io/wp-content/uploads/2025/03/GHST.svg",
refetch: ghstRefetch,
},
reserveFtso: {
daiFtso: {
isPool: true,
symbol: lpReserveFtsoSymbol,
address: lpReserveFtsoBalanceAddress,
balance: lpReserveFtsoBalance,
price: lpReserveFtsoPrice,
icons: ["FTSO", isNetworkLegacy(chainId) ? "GDAI" : tokenNameConverter(chainId, reserveSymbol)],
symbol: lpDaiFtsoSymbol,
address: lpDaiFtsoBalanceAddress,
balance: lpDaiFtsoBalance,
price: lpDaiFtsoPrice,
icons: ["GDAI", "FTSO"],
externalUrl: "https://ghostchain.io/wp-content/uploads/2025/03/uni-v2.svg",
refetch: lpReserveFtsoRefetch,
refetch: lpDaiFtsoRefetch,
}
};
@ -277,12 +246,12 @@ export const useWallet = (chainId, userAddress) => {
export const Tokens = ({ address, tokens, onClose }) => {
const [expanded, setExpanded] = useState(null);
const alwaysShowTokens = [tokens.native, tokens.reserve, tokens.ftso, tokens.stnk, tokens.ghst, tokens.reserveFtso];
const alwaysShowTokens = [tokens.dai, tokens.ftso, tokens.stnk, tokens.ghst, tokens.daiFtso];
const tokenProps = (token) => ({
...token,
expanded: expanded === token.symbol,
reserveAddress: tokens.reserve.address,
daiAddress: tokens.dai.address,
onChangeExpanded: (e, isExpanded) => setExpanded(isExpanded ? token.symbol : null),
onAddTokenToWallet: () => addTokenToWallet(token, address),
onClose: () => onClose(),
@ -291,7 +260,7 @@ export const Tokens = ({ address, tokens, onClose }) => {
return (
<>
{alwaysShowTokens.map((token, i) => (
<Token key={i} isNative={i === 0} {...tokenProps(token)} />
<Token key={i} {...tokenProps(token)} />
))}
</>
);

View File

@ -1,28 +1,8 @@
import { defineChain } from 'viem'
import { http, fallback, createConfig } from 'wagmi'
import { sepolia, hoodi } from 'wagmi/chains'
const mordor = defineChain({
id: 63,
name: 'Mordor',
nativeCurrency: {
decimals: 18,
name: 'METC',
symbol: 'mETC',
},
rpcUrls: {
default: { http: ['https://rpc.mordor.etccooperative.org'] },
},
blockExplorers: {
default: {
name: 'Blockscout',
url: 'https://etc-mordor.blockscout.com/'
},
},
})
export const config = createConfig({
chains: [sepolia, hoodi, mordor],
chains: [sepolia, hoodi],
transports: {
[sepolia.id]: fallback([
http('https://ethereum-sepolia-rpc.publicnode.com'),
@ -36,10 +16,6 @@ export const config = createConfig({
[hoodi.id]: fallback([
http('https://rpc.hoodi.ethpandaops.io'),
http('https://0xrpc.io/hoodi'),
]),
[mordor.id]: fallback([
http('https://rpc.mordor.etccooperative.org'),
http('https://geth-mordor.etc-network.info'),
])
},
})

View File

@ -1,29 +1,10 @@
export enum NetworkId {
TESTNET_SEPOLIA = 11155111,
TESTNET_HOODI = 560048,
TESTNET_MORDOR = 63,
}
export const isNetworkAvailable = (chainId, addressChainId) => {
chainId = addressChainId ? addressChainId : chainId;
let exists = false;
switch (chainId) {
case 11155111:
exists = true
break;
case 560048:
exists = true
break;
case 63:
exists = true
break;
default:
break;
}
return exists;
}
export const isNetworkLegacy = (chainId) => {
let exists = false;
switch (chainId) {
case 11155111:

View File

@ -3,116 +3,78 @@ import { NetworkId } from "../constants";
export const STAKING_ADDRESSES = {
[NetworkId.TESTNET_SEPOLIA]: "0xd90E63E88282596E1ea33765b41Ba3d650f4aD52",
[NetworkId.TESTNET_HOODI]: "0x25F62eDc6C89FF84E957C22336A35d2dfc861a86",
[NetworkId.TESTNET_MORDOR]: "0xC25C9C56a89ebd6ef291b415d00ACfa7913c55e7",
};
export const BOND_DEPOSITORY_ADDRESSES = {
[NetworkId.TESTNET_SEPOLIA]: "0xdcE486113280e49ca2fB200258E5Ee1B2D21D495",
[NetworkId.TESTNET_HOODI]: "0x6Ad50B1E293E68B2fC230c576220a93A9D311571",
[NetworkId.TESTNET_MORDOR]: "0x7C85cDEddBAd0f50453d373F7332BEa11ECa7BAf",
};
export const DAO_TREASURY_ADDRESSES = {
[NetworkId.TESTNET_SEPOLIA]: "0x93dd30f819403710de7933B79A74C4A42438458D",
[NetworkId.TESTNET_HOODI]: "0x1a1b29b18f714fac9dDabEf530dFc4f85b56A6e8",
[NetworkId.TESTNET_MORDOR]: "0x5883C8e2259556B534036c7fDF4555E09dE9f243",
};
export const FTSO_DAI_LP_ADDRESSES = {
[NetworkId.TESTNET_SEPOLIA]: "0x1394dC3f7bABaa2F0CA80353648087DAB1BF3fd6",
[NetworkId.TESTNET_HOODI]: "0xf7B2d44209E70782d93A70F7D8eC50010dF7ae50",
[NetworkId.TESTNET_MORDOR]: "0xE6546D12665dB5B22Cb92FB9e0221aE51A57aeaa",
};
export const FTSO_STNK_LP_ADDRESSES = {
[NetworkId.TESTNET_SEPOLIA]: "0x0000000000000000000000000000000000000000", // TBD
[NetworkId.TESTNET_SEPOLIA]: "0x0000000000000000000000000000000000000000",
[NetworkId.TESTNET_MORDOR]: "0x0000000000000000000000000000000000000000",
}
export const RESERVE_ADDRESSES = {
export const DAI_ADDRESSES = {
[NetworkId.TESTNET_SEPOLIA]: "0x5f63a27a9214a0352F2EF8dAF1eD4974d713192B",
[NetworkId.TESTNET_HOODI]: "0x80c6676c334BCcE60b3CC852085B72143379CE58",
[NetworkId.TESTNET_MORDOR]: "0x6af91B3763b5d020E0985f85555EB50e5852d7AC",
};
export const WETH_ADDRESSES = {
[NetworkId.TESTNET_SEPOLIA]: "0xfff9976782d46cc05630d1f6ebab18b2324d6b14",
[NetworkId.TESTNET_HOODI]: "0xE69a5c6dd88cA798b93c3C92fc50c51Fd5305eB4",
[NetworkId.TESTNET_MORDOR]: "0x6af91B3763b5d020E0985f85555EB50e5852d7AC",
};
export const GHST_ADDRESSES = {
[NetworkId.TESTNET_SEPOLIA]: "0xdf2e5306A3dCcfA4e21bbF4226C17Ff5B008dDC4",
[NetworkId.TESTNET_HOODI]: "0xE98f7426457E6533B206e91B7EcA97aa8A258B46",
[NetworkId.TESTNET_MORDOR]: "0x14b5787F8a1E62786F50A7998A9b14aa24298423",
};
export const STNK_ADDRESSES = {
[NetworkId.TESTNET_SEPOLIA]: "0x02C296A27eA779d5a16F934337c12062C5E3c0D9",
[NetworkId.TESTNET_HOODI]: "0xF07e9303A9f16Afd82f4f57Fd6fca68Aa0AB6D7F",
[NetworkId.TESTNET_MORDOR]: "0x137bA9403885D8ECEa95AaFBb8734F5a16121bAC",
};
export const FTSO_ADDRESSES = {
[NetworkId.TESTNET_SEPOLIA]: "0xcFedFFEB3FdeCd2196820Ba3b71f3F84A1255f93",
[NetworkId.TESTNET_HOODI]: "0xb184e423811b644A1924334E63985c259F5D0033",
[NetworkId.TESTNET_MORDOR]: "0xeA170CC0faceC531a6a9e93a28C4330Ac50343a1",
};
export const DISTRIBUTOR_ADDRESSES = {
[NetworkId.TESTNET_SEPOLIA]: "0x8fbF8eB4Fcd451EF62Aee33508D46FE120963194",
[NetworkId.TESTNET_HOODI]: "0xdF49dC81c457c6f92e26cf6d686C7a8715255842",
[NetworkId.TESTNET_MORDOR]: "0xaf5e76706520db7fb01096E322940206bf3fce57",
};
export const GHOST_GOVERNANCE_ADDRESSES = {
[NetworkId.TESTNET_SEPOLIA]: "0xDab0c51918E6990d8763FAC8a04AE159e44e0c4f",
[NetworkId.TESTNET_HOODI]: "0x1B96B792840d4d19d5097ee007392Ed4d851e64F",
[NetworkId.TESTNET_MORDOR]: "0x3dD438416D9593A58193fC52850E588efAa3D57E",
};
export const BONDING_CALCULATOR_ADDRESSES = {
[NetworkId.TESTNET_SEPOLIA]: "0x4896bFc6256A57Df826d7144E48c9633d51d6319",
[NetworkId.TESTNET_HOODI]: "0x2635d526Ad24b98082563937f7b996075052c6Fd",
[NetworkId.TESTNET_MORDOR]: "0x0c4C7C49a173E2a3f9Eed93125F3F146D8e17bCb",
}
export const GATEKEEPER_ADDRESSES = {
[NetworkId.TESTNET_SEPOLIA]: "0xc85129A097773B7F8970a7364c928C05f265E6A1",
[NetworkId.TESTNET_MORDOR]: "0xA59cB4ff90bE2206121aE61eEB68d0AeC7BA095f",
}
export const UNISWAP_V2_ROUTER = {
[NetworkId.TESTNET_SEPOLIA]: "0xee567fe1712faf6149d80da1e6934e354124cfe3",
[NetworkId.TESTNET_HOODI]: "0xD41daF947c6FFEf344754B99ad09466FBCBb7583",
[NetworkId.TESTNET_MORDOR]: "0x90ecf6a29798E3cf31EB7DCE64a372AC40d83F83",
};
export const UNISWAP_V2_FACTORY = {
[NetworkId.TESTNET_SEPOLIA]: "0xF62c03E08ada871A0bEb309762E260a7a6a880E6",
[NetworkId.TESTNET_HOODI]: "0xF140342cB5C29C1468d91Aee408d7b7271C48b5A",
[NetworkId.TESTNET_MORDOR]: "0x909f96C1a436B3386E9962e30f3Ce753070ff524",
};
export const NATIVE_TICKERS = {
[NetworkId.TESTNET_SEPOLIA]: [
"https://api.binance.com/api/v3/ticker/price?symbol=ETHUSDT",
"https://api.coinbase.com/v2/prices/ETH-USDT/spot",
],
[NetworkId.TESTNET_HOODI]: [
"https://api.binance.com/api/v3/ticker/price?symbol=ETHUSDT",
"https://api.coinbase.com/v2/prices/ETH-USDT/spot",
],
[NetworkId.TESTNET_MORDOR]: [
"https://api.binance.com/api/v3/ticker/price?symbol=ETCUSDT",
"https://api.coinbase.com/v2/prices/ETC-USDT/spot",
],
}
export const CEX_TICKERS = {
[NetworkId.TESTNET_MORDOR]: [
"https://api.binance.com/api/v3/ticker/price?symbol=ETCUSDT",
"https://api.coinbase.com/v2/prices/ETC-USDT/spot",
],
}

View File

@ -18,11 +18,4 @@ export const AVAILABLE_DEXES = {
viewBox: "0 0 195 230",
},
],
[NetworkId.TESTNET_MORDOR]: [
{
name: "Uniswap",
icon: UniswapIcon,
viewBox: "0 0 195 230",
},
],
};

View File

@ -1,5 +1,4 @@
import { useEffect, useState, useMemo, useCallback } from "react";
import ReactGA from "react-ga4";
import {
Box,
@ -18,8 +17,7 @@ import {
import { ss58Decode, ss58Address } from "@polkadot-labs/hdkd-helpers";
import { toHex } from "@polkadot-api/utils";
import { decodeAddress } from "@polkadot/util-crypto";
import { useTransactionConfirmations } from "wagmi";
import { getBlockNumber } from "@wagmi/core";
import { useBlockNumber, useTransactionConfirmations } from "wagmi";
import { keccak256 } from "viem";
import { u64, u128 } from "scale-ts";
@ -68,7 +66,7 @@ const STORAGE_PREFIX = "storedTransactions"
const Bridge = ({ chainId, address, config, connect }) => {
const theme = useTheme();
const isSmallScreen = useMediaQuery("(max-width: 650px)");
const isSemiSmallScreen = useMediaQuery("(max-width: 540px)");
const isSemiSmallScreen = useMediaQuery("(max-width: 480px)");
const isVerySmallScreen = useMediaQuery("(max-width: 379px)");
const [copiedIndex, setCopiedIndex] = useState(null);
@ -78,15 +76,23 @@ const Bridge = ({ chainId, address, config, connect }) => {
const [receiver, setReceiver] = useState("");
const [convertedReceiver, setConvertedReceiver] = useState(undefined);
const [amount, setAmount] = useState("");
const [rotation, setRotation] = useState(0);
const [blockNumber, setBlockNumber] = useState(0);
const sliceString = (string, first, second) => {
if (!string) return "";
return string.slice(0, first) + "..." + string.slice(second);
}
const initialStoredTransactions = localStorage.getItem(STORAGE_PREFIX);
// const initialStoredTransactions = JSON.stringify([
// {
// sessionIndex: 124,
// transactionHash: "0x637276eccfa0787de396877a1a259964334fb52cb5111ea84bb28f0006f06276",
// receiverAddress: "sfK147dy2NapxEKwrTLLxTkmhw15kkoJeEKrg77oLFRmUQZDb",
// amount: "10000000000000000000",
// chainId: 11155111,
// blockNumber: 9033063,
// timestamp: Date.now()
// }
// ]);
const [storedTransactions, setStoredTransactions] = useState(
initialStoredTransactions ? JSON.parse(initialStoredTransactions) : []
);
@ -139,8 +145,7 @@ const Bridge = ({ chainId, address, config, connect }) => {
const finalityDelay = Number(evmNetwork?.finality_delay ?? 0n);
const incomingFee = Number(evmNetwork?.incoming_fee ?? 0n) / 10000000;
getBlockNumber(config).then(block => setBlockNumber(block));
const { data: blockNumber } = useBlockNumber({ watch: true });
const { gatekeeperAddress } = useGatekeeperAddress(chainId);
const { symbol: ghstSymbol } = useTokenSymbol(chainId, "GHST");
const {
@ -148,17 +153,6 @@ const Bridge = ({ chainId, address, config, connect }) => {
refetch: ghstBalanceRefetch
} = useBalance(chainId, "GHST", address);
useEffect(() => {
ReactGA.send({ hitType: "pageview", page: "/bridge" });
}, []);
useEffect(() => {
const interval = setInterval(() => {
setRotation((prevRotation) => prevRotation > 0 ? 0 : 180)
}, 2000);
return () => clearInterval(interval);
}, [setRotation])
useEffect(() => {
try {
const [publicKey, prefix] = ss58Decode(receiver);
@ -194,7 +188,7 @@ const Bridge = ({ chainId, address, config, connect }) => {
const clapsNeeded = Math.floor(clapsInSessionLength * appluseThreshold / 100);
const step = finalization > 0
? 0
: receivedClapsLength < clapsNeeded && !transactionApplaused
: receivedClapsLength < clapsNeeded
? 1
: !transactionApplaused
? 2
@ -238,20 +232,6 @@ const Bridge = ({ chainId, address, config, connect }) => {
return storedTransactions.filter(obj => obj.chainId === chainId);
}, [storedTransactions, chainId]);
const selfApplauseUrl = useMemo(() => {
if (!currentRecord) return '';
const amount = new DecimalBigNumber(BigInt(currentRecord.amount), 18).toString();
let url = "https://lite.ghostchain.io/#/applause?";
url += `networkId=${currentRecord.chainId}&`;
url += `sessionIndex=${currentRecord.sessionIndex}&`;
url += `amount=${amount}&`;
url += `receiver=${currentRecord.receiverAddress}&`;
url += `transactionHash=${currentRecord.transactionHash}`;
return url;
}, [currentRecord]);
const removeStoredRecord = useCallback(() => {
const newStoredTransactions = storedTransactions.filter((_, index) => index !== activeTxIndex)
setStoredTransactions(newStoredTransactions);
@ -272,31 +252,29 @@ const Bridge = ({ chainId, address, config, connect }) => {
} else {
setIsPending(true);
try {
const txHash = await ghost(chainId, address, convertedReceiver, preparedAmount);
const txHash = await ghost(chainId, address, convertedReceiver, preparedAmount);
await ghstBalanceRefetch();
const transaction = {
sessionIndex: currentSession ?? 0,
transactionHash: txHash,
receiverAddress: receiver,
amount: preparedAmount.toString(),
chainId: chainId,
blockNumber: Number(blockNumber),
timestamp: Date.now()
}
setReceiver("");
setAmount("");
setIsPending(false);
const newStoredTransactions = [...storedTransactions, transaction];
setStoredTransactions(newStoredTransactions);
localStorage.setItem(STORAGE_PREFIX, JSON.stringify(newStoredTransactions));
const transaction = {
sessionIndex: currentSession ?? 0,
transactionHash: txHash,
receiverAddress: receiver,
amount: preparedAmount.toString(),
chainId: chainId,
blockNumber: Number(blockNumber),
timestamp: Date.now()
}
if (providerDetail) {
setActiveTxIndex(newStoredTransactions.length - 1)
}
} finally {
await ghstBalanceRefetch();
setReceiver("");
setAmount("");
setIsPending(false);
const newStoredTransactions = [...storedTransactions, transaction];
setStoredTransactions(newStoredTransactions);
localStorage.setItem(STORAGE_PREFIX, JSON.stringify(newStoredTransactions));
if (providerDetail) {
setActiveTxIndex(newStoredTransactions.length - 1)
}
}
}
@ -369,10 +347,8 @@ const Bridge = ({ chainId, address, config, connect }) => {
sx={{
width: "35px",
height: "35px",
transition: "transform 0.7s ease-in-out",
transform: (currentRecord?.finalization ?? 0) > 0
? `rotate(${rotation}deg)`
: "rotate(0deg)"
transition: "transform 0.5s ease-in-out",
transform: (currentRecord?.finalization ?? 0) % 2 === 0 ? "rotate(0deg)" : "rotate(180deg)"
}}
viewBox="0 0 25 25"
component={HourglassBottomIcon}
@ -409,8 +385,10 @@ const Bridge = ({ chainId, address, config, connect }) => {
sx={{
width: "35px",
height: "35px",
transition: "transform 0.7s ease-in-out",
transform: `rotateX(${currentRecord.step == 1 ? rotation : 0}deg)`
transition: "transform 0.5s ease-in-out",
transform: currentRecord?.step === 1 && Number(blockNumber) % 2 === 0
? "rotateX(0deg)"
: "rotateX(180deg)"
}}
viewBox="0 0 25 25"
component={ThumbUpIcon}
@ -419,8 +397,10 @@ const Bridge = ({ chainId, address, config, connect }) => {
sx={{
width: "35px",
height: "35px",
transition: "transform 0.7s ease-in-out",
transform: `rotateX(${currentRecord.step == 1 ? rotation : 0}deg)`
transition: "transform 0.5s ease-in-out",
transform: currentRecord?.step === 1 && Number(blockNumber) % 2 === 0
? "rotateX(0deg)"
: "rotateX(180deg)"
}}
viewBox="0 0 25 25"
component={ThumbDownAltIcon}
@ -478,25 +458,6 @@ const Bridge = ({ chainId, address, config, connect }) => {
</Box>
</Box>
{(currentRecord?.step ?? 3) < 3 && (currentSession && currentRecord && currentSession > (currentRecord.sessionIndex ?? 0) + 2) &&
<Box display="flex" flexDirection="column" gap="5px">
<PrimaryButton
fullWidth
onClick={() => window.open(
selfApplauseUrl,
'_blank',
'noopener,noreferrer'
)}
>
Self Applause
</PrimaryButton>
<Typography variant="body2" sx={{ fontStyle: "italic" }}>
Your transaction seems to be stuck, possibly because of a problem with some inactive validators on the network.
</Typography>
</Box>
}
<Box display="flex" flexDirection="column" gap="5px" padding="0.6rem 0">
<Box display="flex" flexDirection="row" justifyContent="space-between">
<Box display="flex" flexDirection="row">
@ -515,7 +476,7 @@ const Bridge = ({ chainId, address, config, connect }) => {
>
{authorities?.map((authority, idx) => {
const authorityAddress = ss58Address(authority.asHex(), 1996);
const disabled = clapsInSession?.find((info => info.at(0) === idx))?.at(1)?.disabled;
const disabled = clapsInSession?.at(idx)?.at(1)?.disabled;
const clapped = receivedClaps?.some(authId => authId === idx);
return (
@ -535,7 +496,7 @@ const Bridge = ({ chainId, address, config, connect }) => {
textOverflow: "ellipsis",
color: clapped
? theme.colors.primary[300]
: disabled
: clapped
? theme.colors.feedback.error
: theme.colors.gray[10]
}}
@ -640,7 +601,7 @@ const Bridge = ({ chainId, address, config, connect }) => {
</Box>
</Box>
</Modal>
<Box width="100%" maxWidth="506px" display="flex" alignItems="center" justifyContent="center" flexDirection="column">
<Box width="100%" maxWidth="476px" display="flex" alignItems="center" justifyContent="center" flexDirection="column">
<Paper
headerContent={
<Box alignItems="center" justifyContent="start" display="flex" width="100%">
@ -671,24 +632,22 @@ const Bridge = ({ chainId, address, config, connect }) => {
iconNotNeeded
UpperSwapCard={<SwapCard
id={`bridge-token-receiver`}
inputWidth={isVerySmallScreen ? "180px" : isSemiSmallScreen ? "280px" : "516px"}
inputWidth={isVerySmallScreen ? "100px" : isSemiSmallScreen ? "180px" : "250px"}
value={receiver}
onChange={event => setReceiver(event.currentTarget.value)}
inputProps={{ "data-testid": "fromInput" }}
placeholder="Ghost address (sf prefixed)"
type="text"
maxWidth="446px"
/>}
LowerSwapCard={<SwapCard
id={`bridge-token-amount`}
inputWidth={isVerySmallScreen ? "100px" : isSemiSmallScreen ? "180px" : "280px"}
inputWidth={isVerySmallScreen ? "100px" : isSemiSmallScreen ? "180px" : "250px"}
info={`${formatCurrency(ghstBalance.toString(), 4, ghstSymbol)}`}
value={amount}
onChange={event => setAmount(event.currentTarget.value)}
inputProps={{ "data-testid": "fromInput" }}
endString={"Max"}
endStringOnClick={() => setAmount(ghstBalance.toString())}
maxWidth="446px"
/>}
/>
<Box
@ -724,7 +683,7 @@ const Bridge = ({ chainId, address, config, connect }) => {
</>
)}
</Box>
<Box maxWidth="506px" display="flex" justifyContent={isVerySmallScreen ? "end" : "space-between"}>
<Box maxWidth="416px" display="flex" justifyContent={isVerySmallScreen ? "end" : "space-between"}>
{!providerDetail
? (
<Typography mr="10px" variant="body2" color="textSecondary">
@ -744,25 +703,25 @@ const Bridge = ({ chainId, address, config, connect }) => {
: metadata
? (
<Box width="100%" display="flex" flexDirection="column" gap="0px">
<Box maxWidth="506px" display="flex" justifyContent={isVerySmallScreen ? "end" : "space-between"}>
<Box maxWidth="416px" display="flex" justifyContent={isVerySmallScreen ? "end" : "space-between"}>
{!isVerySmallScreen && <Typography fontSize="12px" lineHeight="15px">Estimated Fee:</Typography>}
<Typography fontSize="12px" lineHeight="15px">{incomingFee.toFixed(4)}%</Typography>
</Box>
<Box maxWidth="506px" display="flex" justifyContent={isVerySmallScreen ? "end" : "space-between"}>
<Box maxWidth="416px" display="flex" justifyContent={isVerySmallScreen ? "end" : "space-between"}>
{!isVerySmallScreen && <Box display="flex" flexDirection="row">
<Typography fontSize="12px" lineHeight="15px">Finality Delay:</Typography>
<InfoTooltip message="The finality delay period guarantees that a bridging transaction becomes permanent and immutable on the GHOST Chain ledger." />
<InfoTooltip message="This period ensures that the transaction is securely added to the ledger and cannot be altered or canceled." />
</Box>}
<Typography fontSize="12px" lineHeight="15px">{finalityDelay} blocks</Typography>
</Box>
<hr width="100%" />
<Box maxWidth="506px" display="flex" justifyContent={isVerySmallScreen ? "end" : "space-between"}>
{!isVerySmallScreen && <Typography fontSize="12px" lineHeight="15px">Current GHOST Epoch:</Typography>}
<Box maxWidth="416px" display="flex" justifyContent={isVerySmallScreen ? "end" : "space-between"}>
{!isVerySmallScreen && <Typography fontSize="12px" lineHeight="15px">Current Epoch:</Typography>}
<Typography fontSize="12px" lineHeight="15px">{currentSession ?? 0}</Typography>
</Box>
<Box maxWidth="506px" display="flex" justifyContent={isVerySmallScreen ? "end" : "space-between"}>
<Box maxWidth="416px" display="flex" justifyContent={isVerySmallScreen ? "end" : "space-between"}>
{!isVerySmallScreen && <Box display="flex" flexDirection="row">
<Typography fontSize="12px" lineHeight="15px">Current Validators:</Typography>
<Typography fontSize="12px" lineHeight="15px">Number of validators:</Typography>
<InfoTooltip message={<>
<Typography variant="subtitle1">Validators</Typography>
<Box
@ -777,7 +736,7 @@ const Bridge = ({ chainId, address, config, connect }) => {
>
{authorities?.map((authority, idx) => {
const authorityAddress = ss58Address(authority.asHex(), 1996);
const clapInfo = clapsInSession?.find((info => info.at(0) === idx))?.at(1);
const clapInfo = clapsInSession?.at(idx)?.at(1);
return (
<Box
@ -810,7 +769,7 @@ const Bridge = ({ chainId, address, config, connect }) => {
</Box>
</>} />
</Box>}
<Typography fontSize="12px" lineHeight="15px">{clapsInSessionLength} / {authorities?.length ?? 0}</Typography>
<Typography fontSize="12px" lineHeight="15px">{clapsInSessionLength}</Typography>
</Box>
</Box>
)

View File

@ -26,7 +26,7 @@ import { Tab, Tabs } from "../../components/Tabs/Tabs";
import {
UNISWAP_V2_ROUTER,
UNISWAP_V2_FACTORY,
RESERVE_ADDRESSES,
DAI_ADDRESSES,
FTSO_ADDRESSES,
} from "../../constants/addresses";
import { useTokenSymbol } from "../../hooks/tokens";
@ -56,7 +56,7 @@ const Dex = ({ chainId, address, connect }) => {
const [slippage, setSlippage] = useState(localStorage.getItem("dex-slippage") || "5");
const [formatDecimals, setFormatDecimals] = useState(localStorage.getItem("dex-decimals") || "5");
const [tokenAddressTop, setTokenAddressTop] = useState(RESERVE_ADDRESSES[chainId]);
const [tokenAddressTop, setTokenAddressTop] = useState(DAI_ADDRESSES[chainId]);
const [tokenAddressBottom, setTokenAddressBottom] = useState(FTSO_ADDRESSES[chainId]);
const { symbol: tokenNameTop } = useTokenSymbol(chainId, tokenAddressTop);
@ -75,8 +75,8 @@ const Dex = ({ chainId, address, connect }) => {
setTokenAddressTop(currentQueryParameters.get("from"));
newQueryParameters.set("from", currentQueryParameters.get("from"));
} else {
setTokenAddressTop(RESERVE_ADDRESSES[chainId]);
newQueryParameters.set("from", RESERVE_ADDRESSES[chainId]);
setTokenAddressTop(DAI_ADDRESSES[chainId]);
newQueryParameters.set("from", DAI_ADDRESSES[chainId]);
}
if (currentQueryParameters.has("to")) {

View File

@ -187,11 +187,11 @@ const SwapContainer = ({
>
<Box width="100%" display="flex" justifyContent="space-between">
<Typography fontSize="12px" lineHeight="15px">Current price:</Typography>
<Typography fontSize="12px" lineHeight="15px">{formatCurrency(currentPrice, formatDecimals, tokenNameTop)}</Typography>
<Typography fontSize="12px" lineHeight="15px">{formatCurrency(currentPrice, formatDecimals)}</Typography>
</Box>
<Box width="100%" display="flex" justifyContent="space-between">
<Typography fontSize="12px" lineHeight="15px">Next price:</Typography>
<Typography fontSize="12px" lineHeight="15px">{formatCurrency(nextPrice === "" ? currentPrice : nextPrice, formatDecimals, tokenNameTop)}</Typography>
<Typography fontSize="12px" lineHeight="15px">{formatCurrency(nextPrice === "" ? currentPrice : nextPrice, formatDecimals)}</Typography>
</Box>
<Box width="100%" display="flex" justifyContent="space-between">
<Typography fontSize="12px" lineHeight="15px">Transaction deadline:</Typography>

View File

@ -1,5 +1,4 @@
import { useState, useEffect, useMemo } from "react";
import { useConfig } from "wagmi";
import {
Divider,
Typography,
@ -20,8 +19,7 @@ import TokenStack from "../../components/TokenStack/TokenStack";
import { DecimalBigNumber } from "../../helpers/DecimalBigNumber";
import { formatNumber } from "../../helpers/";
import { useBalance, useTokenSymbol } from "../../hooks/tokens";
import { isNetworkLegacy } from "../../constants";
import { RESERVE_ADDRESSES, FTSO_ADDRESSES, STNK_ADDRESSES, GHST_ADDRESSES } from "../../constants/addresses";
import { DAI_ADDRESSES, FTSO_ADDRESSES, STNK_ADDRESSES, GHST_ADDRESSES } from "../../constants/addresses";
const TokenModal = ({ chainId, account, listOpen, setListOpen, setTokenAddress }) => {
const isSmallScreen = useMediaQuery("(max-width: 599px)");
@ -39,19 +37,16 @@ const TokenModal = ({ chainId, account, listOpen, setListOpen, setTokenAddress }
const { symbol: searchSymbol } = useTokenSymbol(chainId, address);
const { balance: searchBalance } = useBalance(chainId, address, account);
const { balance: reserveBalance } = useBalance(chainId, "RESERVE", account);
const { balance: daiBalance } = useBalance(chainId, "GDAI", account);
const { balance: ftsoBalance } = useBalance(chainId, "FTSO", account);
const { balance: stnkBalance } = useBalance(chainId, "STNK", account);
const { balance: ghstBalance } = useBalance(chainId, "GHST", account);
const { symbol: reserveSymbol } = useTokenSymbol(chainId, "RESERVE");
const { symbol: daiSymbol } = useTokenSymbol(chainId, "GDAI");
const { symbol: ftsoSymbol } = useTokenSymbol(chainId, "FTSO");
const { symbol: stnkSymbol } = useTokenSymbol(chainId, "STNK");
const { symbol: ghstSymbol } = useTokenSymbol(chainId, "GHST");
const config = useConfig();
const nativeSymbol = config?.getClient()?.chain?.nativeCurrency?.symbol;
const searchToken = useMemo(() => {
return [{
name: searchSymbol,
@ -64,10 +59,10 @@ const TokenModal = ({ chainId, account, listOpen, setListOpen, setTokenAddress }
const knownTokens = useMemo(() => {
return [
{
name: reserveSymbol,
icons: isNetworkLegacy(chainId) ? ["GDAI"] : [nativeSymbol],
balance: reserveBalance,
address: RESERVE_ADDRESSES[chainId]
name: daiSymbol,
icons: ["GDAI"],
balance: daiBalance,
address: DAI_ADDRESSES[chainId]
},
{
name: ftsoSymbol,
@ -88,7 +83,7 @@ const TokenModal = ({ chainId, account, listOpen, setListOpen, setTokenAddress }
address: GHST_ADDRESSES[chainId]
}
]
}, [reserveSymbol, ftsoSymbol, stnkSymbol, ghstSymbol, reserveBalance, ftsoBalance, stnkBalance, ghstBalance]);
}, [daiSymbol, ftsoSymbol, stnkSymbol, ghstSymbol, daiBalance, ftsoBalance, stnkBalance, ghstBalance]);
useEffect(() => {
if (isAddress(userInput)) {

View File

@ -11,7 +11,7 @@ import TokenStack from "../../components/TokenStack/TokenStack";
import { PrimaryButton } from "../../components/Button";
import { Tab, Tabs } from "../../components/Tabs/Tabs";
import { RESERVE_ADDRESSES } from "../../constants/addresses";
import { DAI_ADDRESSES } from "../../constants/addresses";
import { DecimalBigNumber } from "../../helpers/DecimalBigNumber";
import { formatCurrency, formatNumber } from "../../helpers";
@ -44,14 +44,14 @@ const Faucet = ({ chainId, address, config, connect }) => {
symbol: "",
})
const reserveConversionRate = useConversionRate(chainId, "RESERVE");
const accumulatedDonation = useAccumulatedDonation(chainId, "RESERVE");
const daiConversionRate = useConversionRate(chainId, "GDAI");
const accumulatedDonation = useAccumulatedDonation(chainId, "GDAI");
const { balance: reserveBalance, refetch: reserveBalanceRefetch } = useTokenBalance(chainId, "RESERVE", address);
const { balance: daiBalance, refetch: daiBalanceRefetch } = useTokenBalance(chainId, "GDAI", address);
const { data: nativeBalance, refetch: balanceRefetch } = useBalance({ address });
const { data: contractBalance, refetch: contractBalanceRefetch } = useBalance({ address: RESERVE_ADDRESSES[chainId] });
const { totalSupply: reserveTotalSupply, refetch: refetchReserveTotalSupply } = useTotalSupply(chainId, "RESERVE");
const { symbol: reserveSymbol } = useTokenSymbol(chainId, "RESERVE");
const { data: contractBalance, refetch: contractBalanceRefetch } = useBalance({ address: DAI_ADDRESSES[chainId] });
const { totalSupply: reserveTotalSupply, refetch: refetchReserveTotalSupply } = useTotalSupply(chainId, "GDAI");
const { symbol: faucetSymbol } = useTokenSymbol(chainId, "GDAI");
useEffect(() => {
ReactGA.send({ hitType: "pageview", page: "/faucet" });
@ -93,10 +93,10 @@ const Faucet = ({ chainId, address, config, connect }) => {
}, [amount, balance, nativeInfo])
const estimatedAmountIn = useMemo(() => {
const rate = new DecimalBigNumber(reserveConversionRate.toString(), 0);
const rate = new DecimalBigNumber(daiConversionRate.toString(), 0);
const value = new DecimalBigNumber(amount, nativeInfo.decimals);
return value.mul(rate);
}, [amount, reserveConversionRate, nativeInfo]);
}, [amount, daiConversionRate, nativeInfo]);
const contractBalanceFree = useMemo(() => {
const realContractBalance = contractBalance ? contractBalance.value : 0n;
@ -129,7 +129,7 @@ const Faucet = ({ chainId, address, config, connect }) => {
}
await balanceRefetch();
await reserveBalanceRefetch();
await daiBalanceRefetch();
await contractBalanceRefetch();
await refetchReserveTotalSupply();
setAmount("");
@ -159,7 +159,7 @@ const Faucet = ({ chainId, address, config, connect }) => {
<meta name="twitter:image" content="https://ghostchain.io/wp-content/uploads/2025/03/ghostFaucet-Featured_Image.png" />
</Helmet>
<PageTitle name={`${reserveSymbol} Faucet`} subtitle={`Swap Sepolia ${nativeInfo.symbol} for ${reserveSymbol}.`} />
<PageTitle name={`${faucetSymbol} Faucet`} subtitle={`Swap Sepolia ${nativeInfo.symbol} for ${faucetSymbol}.`} />
<Container
style={{
paddingLeft: isSmallScreen || isVerySmallScreen ? "0" : "3.3rem",
@ -188,7 +188,7 @@ const Faucet = ({ chainId, address, config, connect }) => {
</Tabs>
{!isSemiSmallScreen && <PrimaryButton
variant="text"
href={`${scanInfo.url}/token/${RESERVE_ADDRESSES[chainId]}`}
href={`${scanInfo.url}/token/${DAI_ADDRESSES[chainId]}`}
>
Check on {scanInfo.name}
</PrimaryButton>}
@ -211,14 +211,14 @@ const Faucet = ({ chainId, address, config, connect }) => {
{!isMint && <SwapCard
id={`faucet-sepolia-eth`}
inputWidth={isVerySmallScreen ? "100px" : isSemiSmallScreen ? "180px" : "250px"}
tokenName={reserveSymbol}
token={<TokenStack tokens={[reserveSymbol]} sx={{ fontSize: "21px" }} />}
info={`${formatCurrency(reserveBalance.toString(), 4, reserveSymbol)}`}
tokenName={faucetSymbol}
token={<TokenStack tokens={[faucetSymbol]} sx={{ fontSize: "21px" }} />}
info={`${formatCurrency(daiBalance.toString(), 4, faucetSymbol)}`}
value={amount}
onChange={event => setAmount(event.currentTarget.value)}
inputProps={{ "data-testid": "fromInput" }}
endString={"Max"}
endStringOnClick={() => setAmount(reserveBalance.toString())}
endStringOnClick={() => setAmount(daiBalance.toString())}
/>}
<Box
mb="20px"
@ -231,15 +231,15 @@ const Faucet = ({ chainId, address, config, connect }) => {
<>
<Box maxWidth="416px" display="flex" justifyContent={isVerySmallScreen ? "end" : "space-between"}>
{!isVerySmallScreen && <Typography fontSize="12px" lineHeight="15px">{nativeInfo.symbol} multiplier:</Typography>}
<Typography fontSize="12px" lineHeight="15px">{formatNumber(reserveConversionRate, 2)}</Typography>
<Typography fontSize="12px" lineHeight="15px">{formatNumber(daiConversionRate, 2)}</Typography>
</Box>
<Box maxWidth="416px" display="flex" justifyContent={isVerySmallScreen ? "end" : "space-between"}>
{!isVerySmallScreen && <Typography fontSize="12px" lineHeight="15px">You will get:</Typography>}
<Typography fontSize="12px" lineHeight="15px">{formatCurrency(estimatedAmountIn, 5, reserveSymbol)}</Typography>
<Typography fontSize="12px" lineHeight="15px">{formatCurrency(estimatedAmountIn, 5, faucetSymbol)}</Typography>
</Box>
<Box display="flex" justifyContent={isVerySmallScreen ? "end" : "space-between"}>
{!isVerySmallScreen && <Typography fontSize="12px" lineHeight="15px">Your {reserveSymbol} balance:</Typography>}
<Typography fontSize="12px" lineHeight="15px">{formatCurrency(reserveBalance, 5, reserveSymbol)}</Typography>
{!isVerySmallScreen && <Typography fontSize="12px" lineHeight="15px">Your {faucetSymbol} balance:</Typography>}
<Typography fontSize="12px" lineHeight="15px">{formatCurrency(daiBalance, 5, faucetSymbol)}</Typography>
</Box>
</>
)}
@ -267,7 +267,7 @@ const Faucet = ({ chainId, address, config, connect }) => {
preparedAmount?._value === 0n ||
isPending ||
(isMint && balance?.lt(preparedAmount)) ||
(!isMint && reserveBalance?.lt(preparedAmount))
(!isMint && daiBalance?.lt(preparedAmount))
)
}
loading={isPending}

View File

@ -16,33 +16,34 @@ import { SecondaryButton } from "../../../components/Button";
import TokenStack from "../../../components/TokenStack/TokenStack";
import { DecimalBigNumber } from "../../../helpers/DecimalBigNumber";
import { formatCurrency } from "../../../helpers";
import { tokenNameConverter } from "../../../helpers/tokenConverter";
import { isNetworkLegacy } from "../../../constants";
import { useLpValuation } from "../../../hooks/treasury";
import { useTotalSupply, useTokenSymbol } from "../../../hooks/tokens";
import { RESERVE_ADDRESSES, FTSO_ADDRESSES } from "../../../constants/addresses";
import {
DAI_ADDRESSES,
FTSO_ADDRESSES,
} from "../../../constants/addresses";
const FarmPools = ({ chainId }) => {
const isSmallScreen = useMediaQuery("(max-width: 775px)");
const { totalSupply: reserveFtsoUniTotalSupply } = useTotalSupply(chainId, "RESERVE_FTSO");
const reserveFtsoUniValuation = useLpValuation(chainId, "RESERVE_FTSO", reserveFtsoUniTotalSupply._value);
const { totalSupply: daiFtsoUniTotalSupply } = useTotalSupply(chainId, "GDAI_FTSO");
const daiFtsoUniValuation = useLpValuation(chainId, "GDAI_FTSO", daiFtsoUniTotalSupply._value);
const { symbol: reserveSymbol } = useTokenSymbol(chainId, "RESERVE");
const { symbol: daiSymbol } = useTokenSymbol(chainId, "GDAI");
const { symbol: ftsoSymbol } = useTokenSymbol(chainId, "FTSO");
const pools = [
{
icons: ["FTSO", isNetworkLegacy(chainId) ? "GDAI" : tokenNameConverter(chainId, reserveSymbol)],
name: `${ftsoSymbol}-${reserveSymbol}`,
icons: ["FTSO", "GDAI"],
name: `${ftsoSymbol}-${daiSymbol}`,
dex: "Uniswap V2",
url: "/dex/uniswap",
tvl: reserveFtsoUniValuation,
tvl: daiFtsoUniValuation,
params: createSearchParams({
pool: "true",
from: `${RESERVE_ADDRESSES[chainId]}`,
from: `${DAI_ADDRESSES[chainId]}`,
to: `${FTSO_ADDRESSES[chainId]}`,
})
},

View File

@ -1,22 +1,19 @@
import { Grid, Box, Typography, useTheme } from "@mui/material";
import { useAccount, useConfig, useBalance as useBalanceNative } from "wagmi";
import { useAccount } from "wagmi";
import { useNavigate, createSearchParams } from "react-router-dom";
import Token from "../../../components/Token/Token";
import { SecondaryButton } from "../../../components/Button";
import { formatNumber, formatCurrency } from "../../../helpers";
import { DecimalBigNumber } from "../../../helpers/DecimalBigNumber";
import { isNetworkLegacy } from "../../../constants"
import { useBalance, useTokenSymbol } from "../../../hooks/tokens";
import {
useFtsoPrice,
useStnkPrice,
useGhstPrice,
useReservePrice,
useNativePrice,
useDaiPrice,
} from "../../../hooks/prices";
import { tokenNameConverter } from "../../../helpers/tokenConverter";
const TokenTab = ({ isMobileScreen, theme, tokenName, tokenUrl, tokenUrlParams, balance, price, description }) => {
const navigate = useNavigate();
@ -77,26 +74,20 @@ const TokenInfo = ({ chainId, isMobileScreen }) => {
const theme = useTheme();
const { address } = useAccount();
const config = useConfig();
const nativeSymbol = config?.getClient()?.chain?.nativeCurrency?.symbol;
const networkName = config?.getClient()?.chain?.name;
const nativePrice = useNativePrice(chainId);
const ftsoPrice = useFtsoPrice(chainId);
const stnkPrice = useStnkPrice(chainId);
const ghstPrice = useGhstPrice(chainId);
const reservePrice = useReservePrice(chainId);
const daiPrice = useDaiPrice(chainId);
const { symbol: reserveSymbol } = useTokenSymbol(chainId, "RESERVE");
const { symbol: daiSymbol } = useTokenSymbol(chainId, "GDAI");
const { symbol: ftsoSymbol } = useTokenSymbol(chainId, "FTSO");
const { symbol: stnkSymbol } = useTokenSymbol(chainId, "STNK");
const { symbol: ghstSymbol } = useTokenSymbol(chainId, "GHST");
const { data: nativeBalance } = useBalanceNative({ address });
const { balance: ftsoBalance, contractAddress: ftsoAddress } = useBalance(chainId, "FTSO", address);
const { balance: stnkBalance, contractAddress: stnkAddress } = useBalance(chainId, "STNK", address);
const { balance: ghstBalance, contractAddress: ghstAddress } = useBalance(chainId, "GHST", address);
const { balance: reserveBalance, contractAddress: reserveAddress } = useBalance(chainId, "RESERVE", address);
const { balance: daiBalance, contractAddress: daiAddress } = useBalance(chainId, "GDAI", address);
return (
<Grid container spacing={0} justifyContent={"center"}>
@ -105,7 +96,7 @@ const TokenInfo = ({ chainId, isMobileScreen }) => {
isMobileScreen={isMobileScreen}
tokenUrl="/dex/uniswap"
tokenUrlParams={createSearchParams({
from: `${reserveAddress}`,
from: `${daiAddress}`,
to: `${ftsoAddress}`,
})}
theme={theme}
@ -118,7 +109,7 @@ const TokenInfo = ({ chainId, isMobileScreen }) => {
isMobileScreen={isMobileScreen}
tokenUrl="/dex/uniswap"
tokenUrlParams={createSearchParams({
from: `${reserveAddress}`,
from: `${daiAddress}`,
to: `${stnkAddress}`,
})}
theme={theme}
@ -131,7 +122,7 @@ const TokenInfo = ({ chainId, isMobileScreen }) => {
isMobileScreen={isMobileScreen}
tokenUrl="/dex/uniswap"
tokenUrlParams={createSearchParams({
from: `${reserveAddress}`,
from: `${daiAddress}`,
to: `${ghstAddress}`,
})}
theme={theme}
@ -142,32 +133,15 @@ const TokenInfo = ({ chainId, isMobileScreen }) => {
/>
<TokenTab
isMobileScreen={isMobileScreen}
tokenUrl={isNetworkLegacy(chainId) ? "/faucet" : "/wrapper"}
tokenUrl="/faucet"
tokenUrlParams=""
theme={theme}
tokenName={reserveSymbol}
balance={reserveBalance}
price={reservePrice}
description={isNetworkLegacy(chainId)
? `${ftsoSymbol} is backed by a treasury reserve of crypto assets, with ${reserveSymbol} being the primary and most liquid asset.`
: `${reserveSymbol} (Wrapped ${nativeSymbol}) is an ERC-20 token that represents ${nativeSymbol} and is pegged 1:1 to the value of ${nativeSymbol}.`
}
tokenName={daiSymbol}
balance={daiBalance}
price={daiPrice}
description={`${ftsoSymbol} is backed by a treasury reserve of crypto assets, with ${daiSymbol} being the primary and most liquid asset.`}
/>
</Box>
{!isNetworkLegacy(chainId) && (
<Box width="100%" mt="25px">
<TokenTab
isMobileScreen={true}
tokenUrl={isNetworkLegacy(chainId) ? "/faucet" : "/wrapper"}
tokenUrlParams=""
theme={theme}
tokenName={nativeSymbol}
balance={new DecimalBigNumber(nativeBalance?.value ?? 0n, 18)}
price={reservePrice}
description={`${nativeSymbol} is the native currency of the ${networkName} Network, functioning as the backing asset for the ghostDAO.`}
/>
</Box>
)}
</Grid>
)
}

View File

@ -1,260 +0,0 @@
import { useState, useEffect, useMemo } from "react";
import { Box, Container, Typography, useMediaQuery } from "@mui/material";
import { useConfig, useBalance } from "wagmi";
import { Helmet } from "react-helmet";
import ReactGA from "react-ga4";
import PageTitle from "../../components/PageTitle/PageTitle";
import Paper from "../../components/Paper/Paper";
import SwapCard from "../../components/Swap/SwapCard";
import TokenStack from "../../components/TokenStack/TokenStack";
import { PrimaryButton } from "../../components/Button";
import { Tab, Tabs } from "../../components/Tabs/Tabs";
import { RESERVE_ADDRESSES } from "../../constants/addresses";
import { DecimalBigNumber } from "../../helpers/DecimalBigNumber";
import { formatCurrency, formatNumber } from "../../helpers";
import {
useBalance as useTokenBalance,
useTokenSymbol,
useTotalSupply,
useConversionRate,
useAccumulatedDonation,
depositNative,
withdrawWeth
} from "../../hooks/tokens";
const WethWrapper = ({ chainId, address, config, connect }) => {
const isSmallScreen = useMediaQuery("(max-width: 650px)");
const isSemiSmallScreen = useMediaQuery("(max-width: 480px)");
const isVerySmallScreen = useMediaQuery("(max-width: 379px)");
const [chainName, setChainName] = useState("");
const [isMint, setIsMint] = useState(true);
const [isPending, setIsPending] = useState(false);
const [balance, setBalance] = useState(new DecimalBigNumber(0, 0));
const [amount, setAmount] = useState("");
const [scanInfo, setScanInfo] = useState({
name: "",
url: "",
});
const [nativeInfo, setNativeInfo] = useState({
decimals: 18,
name: "",
symbol: "",
})
const { balance: reserveBalance, refetch: reserveBalanceRefetch } = useTokenBalance(chainId, "RESERVE", address);
const { data: nativeBalance, refetch: balanceRefetch } = useBalance({ address });
const { symbol: reserveSymbol } = useTokenSymbol(chainId, "RESERVE");
useEffect(() => {
ReactGA.send({ hitType: "pageview", page: "/wrapper" });
}, [])
useEffect(() => {
const value = nativeBalance ? nativeBalance.value : 0n;
const decimals = nativeBalance ? nativeBalance.decimals : 18;
setBalance(new DecimalBigNumber(value, decimals));
}, [nativeBalance]);
useEffect(() => {
let scanName = "";
let scanUrl = "";
const client = config?.getClient();
scanName = client?.chain?.blockExplorers?.default?.name;
scanUrl = client?.chain?.blockExplorers?.default?.url;
setScanInfo({
name: scanName,
url: scanUrl,
})
setChainName(client?.chain?.name);
setNativeInfo(client?.chain?.nativeCurrency)
}, [chainId]);
const changeIsMinted = (value) => {
setAmount("");
setIsMint(value);
}
const preparedAmount = useMemo(() => {
if (address === "") new DecimalBigNumber("0", 0);
const decimals = isMint ? nativeInfo.decimals : 18;
return new DecimalBigNumber(amount, decimals);
}, [amount, balance, nativeInfo])
const estimatedAmountIn = useMemo(() => {
return new DecimalBigNumber(amount, nativeInfo.decimals);
}, [amount, nativeInfo]);
const estimatedAmountOut = useMemo(() => {
return new DecimalBigNumber(amount, nativeInfo.decimals);
}, [amount, nativeInfo]);
const actionOrConnect = async () => {
if (address === "") {
connect();
} else {
setIsPending(true);
if (isMint) {
await depositNative(chainId, address, preparedAmount._value.toString());
} else {
await withdrawWeth(chainId, address, preparedAmount._value.toString());
}
await balanceRefetch();
await reserveBalanceRefetch();
setAmount("");
setIsPending(false);
}
}
return (
<Box height="calc(100vh - 43px)">
<Helmet>
<title>ghostWrapper | WETH9</title>
<meta name="description" content="Standard WETH9 wrapper. Convert native coin to WETH9 representation directly to your wallet." />
<meta name="keywords" content="weth, weth9, ghostFaucet, web3 faucet, ethereum, sepolia, polygon, bnb, bsc, AVAX" />
<meta property="og:image" content="https://ghostchain.io/wp-content/uploads/2025/03/ghostFaucet-Featured_Image.png" />
<meta property="og:title" content="ghostDAO | The DeFi 2.0 cross-chain reserve currency" />
<meta property="og:image:type" content="image/png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:type" content="website" />
<meta property="og:description" content="Standard WETH9 wrapper. Convert native coin to WETH9 representation directly to your wallet." />
<meta name="twitter:card" content="summary" />
<meta name="twitter:site" content="@realGhostChain" />
<meta name="twitter:title" content="ghostDAO | The DeFi 2.0 cross-chain reserve currency" />
<meta name="twitter:description" content="Standard WETH9 wrapper. Convert native coin to WETH9 representation directly to your wallet." />
<meta name="twitter:image" content="https://ghostchain.io/wp-content/uploads/2025/03/ghostFaucet-Featured_Image.png" />
</Helmet>
<PageTitle name={`${reserveSymbol} Wrapper`} subtitle={`Wrap ${nativeInfo.symbol} into ${reserveSymbol}.`} />
<Container
style={{
paddingLeft: isSmallScreen || isVerySmallScreen ? "0" : "3.3rem",
paddingRight: isSmallScreen || isVerySmallScreen ? "0" : "3.3rem",
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "calc(100vh - 153px)"
}}
>
<Box width="100%" maxWidth="476px" display="flex" alignItems="center" justifyContent="center" flexDirection="column">
<Paper
headerContent={
<Box alignItems="center" justifyContent="space-between" display="flex" width="100%">
<Tabs
centered
textColor="primary"
indicatorColor="primary"
value={isMint ? 0 : 1}
aria-label="Faucet menu"
onChange={(_, view) => changeIsMinted(view === 0)}
TabIndicatorProps={{ style: { display: "none" } }}
>
<Tab aria-label="faucet-mint-button" label="Wrap" style={{ fontSize: "1.5rem" }} />
<Tab aria-label="faucet-burn-button" label="Unwrap" style={{ fontSize: "1.5rem" }} />
</Tabs>
{!isSemiSmallScreen && <PrimaryButton
variant="text"
href={`${scanInfo.url}/token/${RESERVE_ADDRESSES[chainId]}`}
>
Check on {scanInfo.name}
</PrimaryButton>}
</Box>
}
enableBackground
fullWidth
>
<Box>
{isMint && <SwapCard
id={`faucet-sepolia-eth`}
inputWidth={isVerySmallScreen ? "100px" : isSemiSmallScreen ? "180px" : "250px"}
tokenName={nativeInfo.symbol}
token={<TokenStack tokens={[nativeInfo.symbol]} sx={{ fontSize: "21px" }} />}
info={`${isSemiSmallScreen ? "" : "Balance: "}${formatCurrency(balance.toString(), 4, nativeInfo.symbol)}`}
value={amount}
onChange={event => setAmount(event.currentTarget.value)}
inputProps={{ "data-testid": "fromInput" }}
/>}
{!isMint && <SwapCard
id={`faucet-sepolia-eth`}
inputWidth={isVerySmallScreen ? "100px" : isSemiSmallScreen ? "180px" : "250px"}
tokenName={reserveSymbol}
token={<TokenStack tokens={[reserveSymbol]} sx={{ fontSize: "21px" }} />}
info={`${formatCurrency(reserveBalance.toString(), 4, reserveSymbol)}`}
value={amount}
onChange={event => setAmount(event.currentTarget.value)}
inputProps={{ "data-testid": "fromInput" }}
endString={"Max"}
endStringOnClick={() => setAmount(reserveBalance.toString())}
/>}
<Box
mb="20px"
mt="20px"
flexDirection="column"
display="flex"
justifyContent="space-between"
>
{isMint && (
<>
<Box maxWidth="416px" display="flex" justifyContent={isVerySmallScreen ? "end" : "space-between"}>
{!isVerySmallScreen && <Typography fontSize="12px" lineHeight="15px">You will get:</Typography>}
<Typography fontSize="12px" lineHeight="15px">{formatCurrency(estimatedAmountIn, 5, reserveSymbol)}</Typography>
</Box>
<Box display="flex" justifyContent={isVerySmallScreen ? "end" : "space-between"}>
{!isVerySmallScreen && <Typography fontSize="12px" lineHeight="15px">Your {reserveSymbol} balance:</Typography>}
<Typography fontSize="12px" lineHeight="15px">{formatCurrency(reserveBalance, 5, reserveSymbol)}</Typography>
</Box>
</>
)}
{!isMint && (
<>
<Box maxWidth="416px" display="flex" justifyContent={isVerySmallScreen ? "end" : "space-between"}>
{!isVerySmallScreen && <Typography fontSize="12px" lineHeight="15px">You will get:</Typography>}
<Typography fontSize="12px" lineHeight="15px">{formatCurrency(estimatedAmountOut, 5, nativeInfo.symbol)}</Typography>
</Box>
<Box display="flex" justifyContent={isVerySmallScreen ? "end" : "space-between"}>
{!isVerySmallScreen && <Typography fontSize="12px" lineHeight="15px">Your {nativeInfo.symbol} balance:</Typography>}
<Typography fontSize="12px" lineHeight="15px">{formatCurrency(balance, 5, nativeInfo.symbol)}</Typography>
</Box>
</>
)}
</Box>
<PrimaryButton
fullWidth
disabled={
address !== "" && (
preparedAmount?._value === 0n ||
isPending ||
(isMint && balance?.lt(preparedAmount)) ||
(!isMint && reserveBalance?.lt(preparedAmount))
)
}
loading={isPending}
onClick={() => actionOrConnect()}
>
{address === "" ?
"Connect"
:
isMint ? "Wrap" : "Unwrap"
}
</PrimaryButton>
</Box>
</Paper>
</Box>
</Container>
</Box>
)
}
export default WethWrapper;

View File

@ -1,10 +0,0 @@
export const tokenNameConverter = (chainId, name) => {
if (name?.toUpperCase() === "WETH") {
switch (chainId) {
case 63:
name = "wmETC"
break;
}
}
return name;
}

View File

@ -1,10 +1,9 @@
import {
RESERVE_ADDRESSES,
DAI_ADDRESSES,
FTSO_ADDRESSES,
STNK_ADDRESSES,
GHST_ADDRESSES,
FTSO_DAI_LP_ADDRESSES,
WETH_ADDRESSES,
} from "../constants/addresses";
import { abi as DaiAbi } from "../abi/Reserve.json";
@ -12,7 +11,6 @@ import { abi as FatsoAbi } from "../abi/Fatso.json";
import { abi as StinkyAbi } from "../abi/Stinky.json";
import { abi as GhostAbi } from "../abi/Ghost.json";
import { abi as Erc20Abi } from "../abi/ERC20.json";
import { abi as WethAbi } from "../abi/WETH9.json";
// TBD: should be extended on new tokens
export const getTokenAbi = (name) => {
@ -24,9 +22,6 @@ export const getTokenAbi = (name) => {
case "GDAI":
abi = DaiAbi;
break;
case "RESERVE":
abi = DaiAbi;
break;
case "FTSO":
abi = FatsoAbi;
break;
@ -45,9 +40,6 @@ export const getTokenAbi = (name) => {
case "CSPR":
abi = GhostAbi;
break;
case "WETH":
abi = WethAbi;
break;
}
return abi;
}
@ -62,9 +54,6 @@ export const getTokenDecimals = (name) => {
case "GDAI":
decimals = 18;
break;
case "RESERVE":
decimals = 18;
break;
case "FTSO":
decimals = 9;
break;
@ -83,9 +72,6 @@ export const getTokenDecimals = (name) => {
case "CSPR":
decimals = 18;
break;
case "WETH":
decimals = 18;
break;
}
return decimals;
}
@ -95,13 +81,10 @@ export const getTokenAddress = (chainId, name) => {
let address = name;
switch (name?.toUpperCase()) {
case "DAI":
address = RESERVE_ADDRESSES[chainId];
address = DAI_ADDRESSES[chainId];
break;
case "GDAI":
address = RESERVE_ADDRESSES[chainId];
break;
case "RESERVE":
address = RESERVE_ADDRESSES[chainId];
address = DAI_ADDRESSES[chainId];
break;
case "FTSO":
address = FTSO_ADDRESSES[chainId];
@ -124,15 +107,6 @@ export const getTokenAddress = (chainId, name) => {
case "GDAI_FTSO":
address = FTSO_DAI_LP_ADDRESSES[chainId];
break;
case "RESERVE_FTSO":
address = FTSO_DAI_LP_ADDRESSES[chainId];
break;
case "WETH":
address = WETH_ADDRESSES[chainId];
break;
case "WETC":
address = WETH_ADDRESSES[chainId];
break;
}
return address;
}
@ -141,8 +115,8 @@ export const getTokenAddress = (chainId, name) => {
export const getTokenIcons = (chainId, address) => {
let icons = [""];
switch (address) {
case RESERVE_ADDRESSES[chainId]:
icons = ["RESERVE"];
case DAI_ADDRESSES[chainId]:
icons = ["GDAI"];
break;
case FTSO_ADDRESSES[chainId]:
icons = ["FTSO"];
@ -154,7 +128,7 @@ export const getTokenIcons = (chainId, address) => {
icons = ["GHST"];
break;
case FTSO_DAI_LP_ADDRESSES[chainId]:
icons = ["FTSO", "RESERVE"];
icons = ["FTSO", "GDAI"];
break;
}
return icons;
@ -170,14 +144,11 @@ export const getBondNameDisplayName = (chainId, stringValue, tokenAddress) => {
export const getTokenPurchaseLink = (chainId, tokenAddress) => {
let purchaseUrl = "https://app.dao.ghostchain.io/#/dex/uniswap";
switch (tokenAddress) {
case RESERVE_ADDRESSES[chainId]:
case DAI_ADDRESSES[chainId]:
purchaseUrl = "https://app.dao.ghostchain.io/#/faucet";
if (chainId == 63) {
purchaseUrl = "https://app.dao.ghostchain.io/#/wrapper";
}
break;
case FTSO_DAI_LP_ADDRESSES[chainId]:
purchaseUrl += `?pool=true&from=${RESERVE_ADDRESSES[chainId]}&to=${FTSO_ADDRESSES[chainId]}`;
purchaseUrl += `?pool=true&from=${DAI_ADDRESSES[chainId]}&to=${FTSO_ADDRESSES[chainId]}`;
break;
}
return purchaseUrl;

View File

@ -1,144 +1,26 @@
import { useState, useEffect } from "react";
import { useReadContract } from "wagmi";
import { useCurrentIndex, useGhostedSupply } from "../staking";
import { useUniswapV2PairReserves } from "../uniswapv2";
import { DecimalBigNumber } from "../../helpers/DecimalBigNumber";
import {
FTSO_DAI_LP_ADDRESSES,
RESERVE_ADDRESSES,
FTSO_ADDRESSES,
CEX_TICKERS,
NATIVE_TICKERS,
} from "../../constants/addresses";
import { FTSO_DAI_LP_ADDRESSES, DAI_ADDRESSES, FTSO_ADDRESSES } from "../../constants/addresses";
const cexPriceGetters = new Map();
function callWithCacheTTL(fn, ttlMs = 10000) {
let lastFetchTime = 0;
let cachedValue;
let inFlight = null;
return function(...args) {
const now = Date.now();
if ((now - lastFetchTime) < ttlMs) {
return inFlight ? inFlight : Promise.resolve(cachedValue);
}
lastFetchTime = now;
inFlight = Promise.resolve(fn(...args))
.then(res => {
cachedValue = res;
inFlight = null;
return res;
})
.catch(err => {
inFlight = null;
throw err;
});
return inFlight;
}
}
export const useNativePrice = (chainId) => {
const [nativePrice, setNativePrice] = useState(new DecimalBigNumber(1000000000000000000n, 18));
const cexApis = NATIVE_TICKERS[chainId];
useEffect(() => {
if (!cexApis) {
setNativePrice(new DecimalBigNumber(1000000000000000000n, 18));
return;
}
let getCexPriceCached = cexPriceGetters.get(chainId);
if (!getCexPriceCached) {
getCexPriceCached = callWithCacheTTL(() => {
const fetchPromises = cexApis.map(url => fetch(url)
.then(res => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
})
)
return Promise.any(fetchPromises);
}, 5000);
cexPriceGetters.set(chainId, getCexPriceCached);
}
getCexPriceCached()
.then(response => {
if ('data' in response) {
const coinPrice = Number(response?.data?.amount ?? 0.0);
const priceInWei = Math.floor(coinPrice * 1e18 / 0.99);
setNativePrice(new DecimalBigNumber(BigInt(priceInWei), 18));
} else if ('price' in response) {
const coinPrice = Number(response?.price ?? 0.0);
const priceInWei = Math.floor(coinPrice * 1e18)
setNativePrice(new DecimalBigNumber(BigInt(priceInWei), 18));
} else {
throw Error("Unexpected json in response.");
}
})
.catch(error => {
setNativePrice(new DecimalBigNumber(0n, 18));
});
}, [chainId, cexApis])
return nativePrice;
}
export const useReservePrice = (chainId) => {
const [reservePrice, setReservePrice] = useState(new DecimalBigNumber(1000000000000000000n, 18));
const cexApis = CEX_TICKERS[chainId];
useEffect(() => {
if (!cexApis) {
setReservePrice(new DecimalBigNumber(1000000000000000000n, 18));
return;
}
let getCexPriceCached = cexPriceGetters.get(chainId);
if (!getCexPriceCached) {
getCexPriceCached = callWithCacheTTL(() => {
const fetchPromises = cexApis.map(url => fetch(url)
.then(res => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
})
)
return Promise.any(fetchPromises);
}, 5000);
cexPriceGetters.set(chainId, getCexPriceCached);
}
getCexPriceCached()
.then(response => {
if ('data' in response) {
const coinPrice = Number(response?.data?.amount ?? 0.0);
const priceInWei = Math.floor(coinPrice * 1e18 / 0.99);
setReservePrice(new DecimalBigNumber(BigInt(priceInWei), 18));
} else if ('price' in response) {
const coinPrice = Number(response?.price ?? 0.0);
const priceInWei = Math.floor(coinPrice * 1e18)
setReservePrice(new DecimalBigNumber(BigInt(priceInWei), 18));
} else {
throw Error("Unexpected json in response.");
}
})
.catch(error => {
setReservePrice(new DecimalBigNumber(0n, 18));
});
}, [chainId, cexApis])
return reservePrice;
export const useDaiPrice = (chainId) => {
const daiPrice = new DecimalBigNumber(1000000000000000000n, 18);
return daiPrice;
};
export const useFtsoPrice = (chainId) => {
const { reserves, tokens, refetch } = useUniswapV2PairReserves(chainId, FTSO_DAI_LP_ADDRESSES[chainId]);
const { reserves, tokens, refetch } = useUniswapV2PairReserves(
chainId,
FTSO_DAI_LP_ADDRESSES[chainId],
9,
18,
"FTSO",
"GDAI",
);
const reservePrice = useReservePrice(chainId);
const reserveAddress = RESERVE_ADDRESSES[chainId];
const reserveAddress = DAI_ADDRESSES[chainId];
const ftsoAddress = FTSO_ADDRESSES[chainId];
if (!reserveAddress || !ftsoAddress) {
return new DecimalBigNumber(0n, 9);
@ -155,9 +37,8 @@ export const useFtsoPrice = (chainId) => {
let price = 0n
if (ftsoReserves > 0n)
price = stableReserves / ftsoReserves;
price = price * reservePrice._value;
return new DecimalBigNumber(price, 27);
return new DecimalBigNumber(price, 9);
};
export const useStnkPrice = (chainId) => {

View File

@ -6,7 +6,6 @@ import { getTokenAbi, getTokenAddress, getTokenDecimals } from "../helpers";
import { DecimalBigNumber } from "../../helpers/DecimalBigNumber";
import { shorten } from "../../helpers";
import { tokenNameConverter } from "../../helpers/tokenConverter";
import { config } from "../../config";
export const useTotalSupply = (chainId, name) => {
@ -69,9 +68,7 @@ export const useTokenSymbol = (chainId, name) => {
chainId: chainId,
});
let symbol = data ? data : "";
symbol = tokenNameConverter(chainId, symbol);
const symbol = data ? data : "";
return { symbol, refetch };
}
@ -232,53 +229,3 @@ export const burnDai = async (chainId, account, value) => {
toast.error("Burning gDAI from the faucet failed. Check logs for error detalization.")
}
}
export const depositNative = async (chainId, account, value) => {
try {
const { request } = await simulateContract(config, {
abi: getTokenAbi("WETH"),
address: getTokenAddress(chainId, "WETH"),
functionName: 'deposit',
account: account,
chainId: chainId,
value: value
});
const txHash = await writeContract(config, request);
await waitForTransactionReceipt(config, {
hash: txHash,
onReplaced: () => toast("WETH9 deposit transaction was replaced. Wait for inclusion please."),
chainId
});
toast.success("WETH9 successfully minted to your wallet! Check your wallet balance.");
} catch (err) {
console.error(err);
toast.error("WETH9 wrapping failed. Check logs for error detalization.")
}
}
export const withdrawWeth = async (chainId, account, value) => {
try {
const { request } = await simulateContract(config, {
abi: getTokenAbi("WETH"),
address: getTokenAddress(chainId, "WETH"),
functionName: 'withdraw',
args: [value],
account: account,
chainId: chainId
});
const txHash = await writeContract(config, request);
await waitForTransactionReceipt(config, {
hash: txHash,
onReplaced: () => toast("WETH9 withdraw transaction was replaced. Wait for inclusion please."),
chainId
});
toast.success("WETH9 successfully burned for native coins! Check your wallet balance.");
} catch (err) {
console.error(err);
toast.error("WETH9 unwrapping failed. Check logs for error detalization.")
}
}

View File

@ -3,23 +3,9 @@ import { useReadContract } from "wagmi";
import { DAO_TREASURY_ADDRESSES } from "../../constants/addresses";
import { abi as TreasuryAbi } from "../../abi/GhostTreasury.json";
import { useReservePrice } from "../prices/index";
import { DecimalBigNumber } from "../../helpers/DecimalBigNumber";
import { getTokenAddress } from "../helpers";
export const useOrinalCoefficient = (chainId) => {
const { data: original } = useReadContract({
abi: TreasuryAbi,
address: DAO_TREASURY_ADDRESSES[chainId],
functionName: "originalCoefficient",
scopeKey: `originalCoefficient-${chainId}`,
chainId: chainId
});
return new DecimalBigNumber(original ? original : 1000000000000000000n, 18);
}
export const useTotalReserves = (chainId) => {
const { data: totalReservesRaw } = useReadContract({
abi: TreasuryAbi,
@ -29,13 +15,10 @@ export const useTotalReserves = (chainId) => {
chainId: chainId,
});
const original = useOrinalCoefficient(chainId);
const price = useReservePrice(chainId);
const totalReservesPrepared = totalReservesRaw ? totalReservesRaw : 0n;
const totalReserves = new DecimalBigNumber(totalReservesPrepared, 9);
return totalReserves.mul(price).div(original);
return totalReserves;
};
export const useLpValuation = (chainId, pairAddress, pairSupply) => {