Skip to content

Commit

Permalink
Merge pull request #394 from kleros/refactor(web)/token-symbol-logic-…
Browse files Browse the repository at this point in the history
…and-xdai-decimals-to-2

Refactor(web)/token symbol logic and xdai decimals to 2
  • Loading branch information
alcercu authored Dec 5, 2023
2 parents 374b34e + 2a83c5d commit 6a7f939
Show file tree
Hide file tree
Showing 17 changed files with 118 additions and 143 deletions.
12 changes: 5 additions & 7 deletions src/components/account-details-popup.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from "react";
import React, { useMemo } from "react";
import t from "prop-types";
import styled from "styled-components/macro";
import { List, Popover, Spin, Divider } from "antd";
Expand All @@ -7,12 +7,14 @@ import { VIEW_ONLY_ADDRESS } from "../bootstrap/dataloader";
import ETHAddress from "./eth-address";
import ETHAmount from "./eth-amount";
import Identicon from "./identicon";
import { AutoDetectedTokenSymbol } from "./token-symbol";
import { getTokenSymbol } from "../helpers/get-token-symbol";

const { useDrizzle, useDrizzleState } = drizzleReactHooks;

export default function AccountDetailsPopup({ trigger, pinakion, className }) {
const { useCacheCall } = useDrizzle();
const chainId = useDrizzleState((ds) => ds.web3.networkId);
const pnkTokenSymbol = useMemo(() => getTokenSymbol(chainId, "PNK"), [chainId]);

const drizzleState = useDrizzleState((drizzleState) => ({
account: drizzleState.accounts[0] || VIEW_ONLY_ADDRESS,
Expand Down Expand Up @@ -51,11 +53,7 @@ export default function AccountDetailsPopup({ trigger, pinakion, className }) {
<List.Item>
<List.Item.Meta
description={<ETHAmount amount={PNK} tokenSymbol="PNK" />}
title={
<>
<AutoDetectedTokenSymbol token="PNK" /> Balance
</>
}
title={<>{pnkTokenSymbol} Balance</>}
/>
</List.Item>
</Spin>
Expand Down
17 changes: 4 additions & 13 deletions src/components/claim-modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { ReactComponent as Kleros } from "../assets/images/kleros.svg";
import { ReactComponent as RightArrow } from "../assets/images/right-arrow.svg";
import useChainId from "../hooks/use-chain-id";
import ETHAmount from "./eth-amount";
import TokenSymbol from "./token-symbol";

const chainIdToParams = {
1: {
Expand Down Expand Up @@ -265,11 +264,7 @@ const ClaimModal = ({ visible, onOk, onCancel, displayButton, apyCallback }) =>
}}
centered
keyboard
okText={
<>
Claim Your <TokenSymbol token="PNK" /> Tokens
</>
}
okText={<>Claim Your PNK Tokens</>}
onOk={onOk}
onCancel={handleCancel}
visible={visible}
Expand Down Expand Up @@ -309,7 +304,7 @@ const ClaimModal = ({ visible, onOk, onCancel, displayButton, apyCallback }) =>
</span>
</div>
<div style={{ fontSize: "24px", fontWeight: "500", marginTop: "8px" }}>
As a Kleros Juror, you will earn <TokenSymbol token="PNK" /> for staking in Court.
As a Kleros Juror, you will earn PNK for staking in Court.
</div>

<div
Expand All @@ -325,9 +320,7 @@ const ClaimModal = ({ visible, onOk, onCancel, displayButton, apyCallback }) =>
}}
>
<div style={{ display: "flex", justifyContent: "space-between" }}>
<div>
Total Rewarded <TokenSymbol token="PNK" />:
</div>
<div>Total Rewarded PNK:</div>
<div style={{ fontWeight: "500", textAlign: "right" }}>
<ETHAmount amount={claims && getTotalRewarded(claims)} decimals={0} tokenSymbol="PNK" />
</div>
Expand Down Expand Up @@ -413,9 +406,7 @@ const ClaimModal = ({ visible, onOk, onCancel, displayButton, apyCallback }) =>
}
disabled={!claims || Number(drizzle.web3.utils.fromWei(getTotalClaimable(claims))).toFixed(0) < 1}
>
<span>
Claim Your <TokenSymbol token="PNK" /> Tokens
</span>
<span>Claim Your PNK Tokens</span>
</Button>
)}
</Modal>
Expand Down
25 changes: 20 additions & 5 deletions src/components/eth-amount.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,40 @@
import React from "react";
import React, { useMemo } from "react";
import t from "prop-types";
import { Skeleton } from "antd";
import styled from "styled-components/macro";
import Web3 from "web3";
import { AutoDetectedTokenSymbol } from "./token-symbol";
import { getTokenSymbol } from "../helpers/get-token-symbol";
import { drizzleReactHooks } from "@drizzle/react-plugin";

const { useDrizzleState } = drizzleReactHooks;
const { fromWei } = Web3.utils;

export default function ETHAmount({ amount, decimals, tokenSymbol }) {
const chainId = useDrizzleState((ds) => ds.web3.networkId);

let finalDecimals = decimals;
const chainTokenSymbol = useMemo(() => getTokenSymbol(chainId), [chainId]);
const calculatedTokenSymbol = useMemo(() => getTokenSymbol(chainId, tokenSymbol), [chainId, tokenSymbol]);

if (chainTokenSymbol === "xDAI" && tokenSymbol === true) {
finalDecimals = 2;
}

if (amount === null) {
return <StyledSkeleton active paragraph={false} title={SkeletonTitleProps} />;
}

const numericValue = Number(
fromWei(typeof amount === "number" ? formatNumber(amount, { decimals: 0 }) : String(amount))
);
const value = formatNumber(decimals === 0 ? Math.trunc(numericValue) : numericValue, { decimals, useGrouping: true });
const value = formatNumber(finalDecimals === 0 ? Math.trunc(numericValue) : numericValue, {
decimals: finalDecimals,
useGrouping: true,
});

return tokenSymbol === true ? (
<>
{value} <AutoDetectedTokenSymbol />
{value} {chainTokenSymbol}
</>
) : tokenSymbol === false ? (
value
Expand All @@ -29,7 +44,7 @@ export default function ETHAmount({ amount, decimals, tokenSymbol }) {
</>
) : (
<>
{value} <AutoDetectedTokenSymbol token={tokenSymbol} />
{value} {calculatedTokenSymbol}
</>
);
}
Expand Down
12 changes: 6 additions & 6 deletions src/components/multi-balance.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import React from "react";
import React, { useMemo } from "react";
import t from "prop-types";
import clsx from "clsx";
import { Typography } from "antd";
import Web3 from "web3";
import styled from "styled-components/macro";
import EthAmount from "./eth-amount";
import TokenSymbol, { AutoDetectedTokenSymbol } from "./token-symbol";
import { getTokenSymbol } from "../helpers/get-token-symbol";

const { BN } = Web3.utils;

export default function MultiBalance({ title, chainId, errors, balance, rawBalance, rowClassNames }) {
const TokenSymbolComponent = chainId ? TokenSymbol : AutoDetectedTokenSymbol;
const tokenSymbolProps = chainId ? { chainId } : {};
const balanceTokenSymbol = <TokenSymbolComponent {...tokenSymbolProps} token="PNK" />;
const rawBalanceTokenSymbol = <TokenSymbolComponent {...tokenSymbolProps} token="xPNK" />;
const [balanceTokenSymbol, rawBalanceTokenSymbol] = useMemo(
() => (chainId ? [getTokenSymbol(chainId, "PNK"), getTokenSymbol(chainId, "xPNK")] : ["PNK", "xPNK"]),
[chainId]
);

return (
<StyledMultiBalance>
Expand Down
7 changes: 1 addition & 6 deletions src/components/pnk-balance-card.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { ReactComponent as PurpleArrowBackground } from "../assets/images/purple
import { VIEW_ONLY_ADDRESS } from "../bootstrap/dataloader";
import ETHAmount from "./eth-amount";
import Hint from "./hint";
import TokenSymbol from "./token-symbol";

const { useDrizzle, useDrizzleState } = drizzleReactHooks;

Expand Down Expand Up @@ -174,11 +173,7 @@ const PNKBalanceCard = () => {
<StyledBottomDiv>
Locked{" "}
<Hint
description={
<>
These <TokenSymbol token="PNK" /> are locked in active disputes for potential redistribution.
</>
}
description={<>These PNK are locked in active disputes for potential redistribution.</>}
title={
<>
<ETHAmount amount={juror && juror.lockedTokens} tokenSymbol="PNK" />
Expand Down
33 changes: 13 additions & 20 deletions src/components/side-chain/pnk-actions.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from "react";
import React, { useMemo } from "react";
import t from "prop-types";
import styled from "styled-components/macro";
import { Link } from "react-router-dom";
Expand All @@ -17,7 +17,7 @@ import useAccount from "../../hooks/use-account";
import usePromise from "../../hooks/use-promise";
import useForceUpdate from "../../hooks/use-force-update";
import { useAsyncGenerator } from "../../hooks/use-generators";
import TokenSymbol from "../token-symbol";
import { getTokenSymbol } from "../../helpers/get-token-symbol";
import MultiBalance from "../multi-balance";
import MultiTransactionStatus from "../multi-transaction-status";

Expand Down Expand Up @@ -117,6 +117,9 @@ function UnwrappedSideChainPnkModal({ triggerCondition, account, balance, rawBal
const showTriggerButton = ["click", "both"].includes(triggerCondition);
const showAutomatically = ["auto", "both"].includes(triggerCondition);

const xPnkTokenSymbol = useMemo(() => getTokenSymbol(chainId, "xPNK"), [chainId]);
const pnkTokenSymbol = useMemo(() => getTokenSymbol(chainId, "PNK"), [chainId]);

const [visible, setVisible] = React.useState(false);
React.useEffect(() => {
setVisible(showAutomatically);
Expand Down Expand Up @@ -150,21 +153,15 @@ function UnwrappedSideChainPnkModal({ triggerCondition, account, balance, rawBal
{showTriggerButton ? (
<Affix style={{ position: "fixed", bottom: 24, left: 24 }}>
<StyledPulseButton type="primary" shape="round" size="large" onClick={() => setVisible(true)}>
<span>
Deposit <TokenSymbol chainId={chainId} token="xPNK" />
</span>
<span>Deposit {xPnkTokenSymbol}</span>
</StyledPulseButton>
</Affix>
) : null}
<StyledModal
visible={visible}
centered
width={586}
title={
<>
Deposit your <TokenSymbol chainId={chainId} token="xPNK" />
</>
}
title={<>Deposit your {xPnkTokenSymbol}</>}
cancelText="Ignore"
onCancel={handleCancel}
cancelButtonProps={{
Expand All @@ -178,11 +175,10 @@ function UnwrappedSideChainPnkModal({ triggerCondition, account, balance, rawBal
onOk={handleOk}
>
<StyledExplainer>
To be able to stake on Kleros Court, you need to deposit your <TokenSymbol chainId={chainId} token="xPNK" />{" "}
to convert it to <TokenSymbol chainId={chainId} token="PNK" /> (Staking PNK).{" "}
To be able to stake on Kleros Court, you need to deposit your {xPnkTokenSymbol} to convert it to{" "}
{pnkTokenSymbol}(Staking PNK).{" "}
<strong>
You will receive 1 <TokenSymbol chainId={chainId} token="PNK" /> for every 1{" "}
<TokenSymbol chainId={chainId} token="xPNK" /> you deposit.
You will receive 1 {pnkTokenSymbol} for every 1 {xPnkTokenSymbol} you deposit.
</strong>
</StyledExplainer>
<MultiBalance errors={errors} balance={balance} rawBalance={rawBalance} />
Expand Down Expand Up @@ -216,6 +212,7 @@ UnwrappedSideChainPnkModal.defaultProps = {

function GetSideChainPnkModal({ defaultVisible }) {
const chainId = useChainId();
const xPnkTokenSymbol = useMemo(() => getTokenSymbol(chainId, "xPNK"), [chainId]);

const [visible, setVisible] = React.useState(defaultVisible);
const handleCancel = () => setVisible(false);
Expand All @@ -225,16 +222,12 @@ function GetSideChainPnkModal({ defaultVisible }) {
visible={visible}
centered
width={586}
title={
<>
You have no <TokenSymbol chainId={chainId} token="xPNK" />
</>
}
title={<>You have no {xPnkTokenSymbol}</>}
onCancel={handleCancel}
footer={null}
>
<StyledExplainer>
To be able to stake on Kleros Court, first you need to get some <TokenSymbol chainId={chainId} token="xPNK" />.
To be able to stake on Kleros Court, first you need to get some {xPnkTokenSymbol}.
</StyledExplainer>
<div
css={`
Expand Down
15 changes: 10 additions & 5 deletions src/components/side-chain/switch-court-chain.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from "react";
import React, { useMemo } from "react";
import t from "prop-types";
import styled from "styled-components/macro";
import { Button, Icon, Modal, Typography } from "antd";
Expand All @@ -25,7 +25,7 @@ import { chainIdToNetworkName, chainIdToNetworkShortName } from "../../helpers/n
import { useSetRequiredChainId } from "../required-chain-id-gateway";
import AnnouncementBanner from "./announcement-banner";
import MultiBalance from "../multi-balance";
import TokenSymbol from "../token-symbol";
import { getTokenSymbol } from "../../helpers/get-token-symbol";

const { useDrizzle } = drizzleReactHooks;

Expand All @@ -36,6 +36,8 @@ export default function SwitchCourtChain() {
const account = useAccount();
const hasAccount = !!account;

const pnkTokenSymbol = useMemo(() => getTokenSymbol(chainId, "PNK"), [chainId]);

const destinationChainId = React.useMemo(() => {
try {
return getCounterPartyChainId(chainId);
Expand Down Expand Up @@ -64,7 +66,7 @@ export default function SwitchCourtChain() {
<StyledButtonWrapper>
<Link component={StyledButtonLink} to="/convert-pnk" icon="swap">
<span>
Send <TokenSymbol chainId={chainId} token="PNK" /> to {chainIdToNetworkShortName[destinationChainId]}
Send {pnkTokenSymbol} to {chainIdToNetworkShortName[destinationChainId]}
</span>
</Link>
<CustomButton
Expand Down Expand Up @@ -260,11 +262,12 @@ function GetSideChainPnkLink({ icon, as, ...additionalProps }) {
const Component = as;
const destinationChainId = useDestinationChainId();
const { bridgeAppUrl } = getSideChainParams(destinationChainId);
const xPnkDestinationTokenSymbol = useMemo(() => getTokenSymbol(destinationChainId, "xPNK"), [destinationChainId]);

return (
<Component href={bridgeAppUrl} target="_blank" rel="noreferrer noopener" {...additionalProps}>
<span>
Get <TokenSymbol chainId={destinationChainId} token="xPNK" /> for {chainIdToNetworkName[destinationChainId]}
Get {xPnkDestinationTokenSymbol} for {chainIdToNetworkName[destinationChainId]}
</span>
{icon}
</Component>
Expand Down Expand Up @@ -320,6 +323,8 @@ function SideChainCourtModal({ balance, rawBalance, errors, trigger }) {
const [visible, setVisible] = React.useState(false);
const destinationChainId = useDestinationChainId();

const xPnkDestinationTokenSymbol = useMemo(() => getTokenSymbol(destinationChainId, "xPNK"), [destinationChainId]);

const switchChain = useSwitchChain(destinationChainId);

const [autoSwitchEnabled, setAutoSwitchEnabled] = React.useState(false);
Expand Down Expand Up @@ -380,7 +385,7 @@ function SideChainCourtModal({ balance, rawBalance, errors, trigger }) {
<StyledSpacer style={{ "--size": "2rem" }} />
<StyledExplainer>
To be able to stake on Kleros Court on {chainIdToNetworkName[destinationChainId]}, first you need to get some{" "}
<TokenSymbol chainId={destinationChainId} token="xPNK" /> for that chain.
{xPnkDestinationTokenSymbol} for that chain.
</StyledExplainer>
</StyledModal>
</>
Expand Down
11 changes: 6 additions & 5 deletions src/components/stake-modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import infoImg from "../assets/images/info.png";
import { useDataloader, VIEW_ONLY_ADDRESS } from "../bootstrap/dataloader";
import useAccount from "../hooks/use-account";
import useChainId from "../hooks/use-chain-id";
import { AutoDetectedTokenSymbol } from "./token-symbol";
import { getTokenSymbol } from "../helpers/get-token-symbol";
import ETHAmount from "./eth-amount";
import { isSupportedSideChain } from "../api/side-chain";
import SideChainPnkActions from "./side-chain/pnk-actions";
Expand Down Expand Up @@ -47,6 +47,7 @@ StakeModal.propTypes = {
const RECOMMENDED_UNSTAKED_BUFFER = toBN("2000000000000000000000");

const StakeModalForm = Form.create()(({ ID, form, onCancel, stakedTokens, max }) => {
const chainId = useDrizzleState((ds) => ds.web3.networkId);
const { useCacheCall, useCacheSend } = useDrizzle();
const drizzleState = useDrizzleState((drizzleState) => ({
account: drizzleState.accounts[0] || VIEW_ONLY_ADDRESS,
Expand All @@ -68,6 +69,7 @@ const StakeModalForm = Form.create()(({ ID, form, onCancel, stakedTokens, max })
const selectedStakeValue = Number.parseInt(String(form.getFieldValue("PNK")));
const selectedStake = toBN(toWei(String(Number.isNaN(selectedStakeValue) ? 0 : selectedStakeValue)));
const shouldShowMaxStakeAlert = selectedStake.gt(maxRecommendedStake) && selectedStake.lte(max);
const pnkTokenSymbol = useMemo(() => getTokenSymbol(chainId, "PNK"), [chainId]);

const loading = !min || !max;
const { send, status } = useCacheSend("KlerosLiquid", "setStake");
Expand Down Expand Up @@ -102,7 +104,7 @@ const StakeModalForm = Form.create()(({ ID, form, onCancel, stakedTokens, max })
)}
title={
<>
Stake <AutoDetectedTokenSymbol token="PNK" /> in {name || "-"}
Stake {pnkTokenSymbol} in {name || "-"}
</>
}
visible
Expand All @@ -115,8 +117,7 @@ const StakeModalForm = Form.create()(({ ID, form, onCancel, stakedTokens, max })
<ETHAmount amount={max} tokenSymbol="PNK" />
</StyledAmountDiv>
<div>
(<AutoDetectedTokenSymbol token="PNK" /> in your wallet - <AutoDetectedTokenSymbol token="PNK" /> already
staked)
({pnkTokenSymbol} in your wallet - {pnkTokenSymbol} already staked)
</div>
</AvailableStake>
</StyledRow>
Expand Down Expand Up @@ -151,7 +152,7 @@ const StakeModalForm = Form.create()(({ ID, form, onCancel, stakedTokens, max })
</div>
}
hasFeedback
label={<AutoDetectedTokenSymbol token="PNK" />}
label={pnkTokenSymbol}
>
{form.getFieldDecorator("PNK", {
initialValue: fromWei(String(maxRecommendedStake)),
Expand Down
Loading

0 comments on commit 6a7f939

Please sign in to comment.