Skip to content

Commit dbfd7ea

Browse files
authored
Merge pull request #44 from kleros/chore/sell-existing-position
feat: account-for-existing-position
2 parents c0664ec + 7962b65 commit dbfd7ea

File tree

6 files changed

+192
-78
lines changed

6 files changed

+192
-78
lines changed

src/app/(homepage)/components/ProjectFunding/PositionValue.tsx

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ import React, { useMemo } from "react";
22

33
import clsx from "clsx";
44
import { formatUnits, Address, formatEther } from "viem";
5-
import { useAccount } from "wagmi";
65

7-
import { sDaiAddress, useReadErc20BalanceOf } from "@/generated";
6+
import { sDaiAddress } from "@/generated";
87

8+
import { useBalance } from "@/hooks/useBalance";
99
import { useMarketPrice } from "@/hooks/useMarketPrice";
1010

1111
import { formatValue, isUndefined } from "@/utils";
@@ -16,17 +16,17 @@ interface IPositionValue {
1616
}
1717

1818
const PositionValue: React.FC<IPositionValue> = ({ upToken, downToken }) => {
19-
const { address } = useAccount();
2019
const {
2120
value: upValue,
2221
balance: upBalance,
2322
price: upPrice,
24-
} = useTokenPositionValue(upToken, address ?? "0x");
23+
} = useTokenPositionValue(upToken);
2524
const {
2625
value: downValue,
2726
balance: downBalance,
2827
price: downPrice,
29-
} = useTokenPositionValue(downToken, address ?? "0x");
28+
} = useTokenPositionValue(downToken);
29+
3030
const totalValue = upValue + downValue;
3131

3232
if (totalValue > 0) {
@@ -87,15 +87,8 @@ const PositionValue: React.FC<IPositionValue> = ({ upToken, downToken }) => {
8787
}
8888
};
8989

90-
const useTokenPositionValue = (token: Address, address: Address) => {
91-
const { data: balance } = useReadErc20BalanceOf({
92-
address: token,
93-
args: [address ?? "0x"],
94-
query: {
95-
staleTime: 5000,
96-
enabled: typeof address !== "undefined",
97-
},
98-
});
90+
const useTokenPositionValue = (token: Address) => {
91+
const { data: balance } = useBalance(token);
9992

10093
const { data: priceRaw } = useMarketPrice(
10194
token,
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import React from "react";
2+
import { useMemo } from "react";
3+
4+
import { Button, Modal } from "@kleros/ui-components-library";
5+
import { useToggle } from "react-use";
6+
import { formatUnits } from "viem";
7+
8+
import { useCardInteraction } from "@/context/CardInteractionContext";
9+
import { useMarketContext } from "@/context/MarketContext";
10+
import { useBalance } from "@/hooks/useBalance";
11+
import { useMarketQuote } from "@/hooks/useMarketQuote";
12+
13+
import LightButton from "@/components/LightButton";
14+
15+
import CloseIcon from "@/assets/svg/close-icon.svg";
16+
17+
import { isUndefined } from "@/utils";
18+
19+
import DefaultPredictButton from "./PredictPopup/ActionButtons/DefaultPredictButton";
20+
import TradeButton from "./PredictPopup/ActionButtons/TradeButton";
21+
22+
import PredictPopup from "./PredictPopup";
23+
24+
const PredictButton: React.FC = () => {
25+
const [isOpen, toggleIsOpen] = useToggle(false);
26+
const [isPopUpOpen, toggleIsPopUpOpen] = useToggle(false);
27+
28+
const { setActiveCardId } = useCardInteraction();
29+
30+
const {
31+
market,
32+
isUpPredict,
33+
differenceBetweenRoutes,
34+
isLoading: isLoadingComplexRoute,
35+
refetchQuotes,
36+
} = useMarketContext();
37+
38+
const { upToken, downToken, underlyingToken, marketId } = market;
39+
40+
const { data: underlyingBalance } = useBalance(underlyingToken);
41+
const { data: upBalance } = useBalance(upToken);
42+
const { data: downBalance } = useBalance(downToken);
43+
44+
const needsSelling = useMemo(
45+
() =>
46+
isUpPredict
47+
? !isUndefined(downBalance) && downBalance > 0
48+
: !isUndefined(upBalance) && upBalance > 0,
49+
[isUpPredict, downBalance, upBalance],
50+
);
51+
52+
const sellToken = isUpPredict ? downToken : upToken;
53+
const sellTokenBalance = isUpPredict ? downBalance : upBalance;
54+
const { data: sellQuote } = useMarketQuote(
55+
underlyingToken,
56+
sellToken,
57+
sellTokenBalance ? formatUnits(sellTokenBalance, 18) : "1",
58+
);
59+
60+
// if no previous position, carry with the default behaviour
61+
if (!needsSelling)
62+
return (
63+
<>
64+
{differenceBetweenRoutes > 0 ? (
65+
<Button
66+
text={"Predict"}
67+
aria-label="Predict Button"
68+
isDisabled={
69+
isUndefined(underlyingBalance) ||
70+
underlyingBalance === 0n ||
71+
isLoadingComplexRoute
72+
}
73+
isLoading={isLoadingComplexRoute}
74+
onPress={async () => {
75+
setActiveCardId(marketId);
76+
toggleIsPopUpOpen();
77+
}}
78+
/>
79+
) : (
80+
<DefaultPredictButton />
81+
)}
82+
<PredictPopup isOpen={isPopUpOpen} toggleIsOpen={toggleIsPopUpOpen} />
83+
</>
84+
);
85+
86+
// if previous prediction present, liquidate that to set a new prediction
87+
return (
88+
<>
89+
<Button text="Predict" onPress={toggleIsOpen} />
90+
<Modal
91+
className="relative h-fit w-max overflow-x-hidden p-6 py-8"
92+
onOpenChange={toggleIsOpen}
93+
{...{ isOpen }}
94+
>
95+
<LightButton
96+
className="absolute top-4 right-4 p-1"
97+
text=""
98+
icon={
99+
<CloseIcon className="[&_path]:stroke-klerosUIComponentsSecondaryText size-4" />
100+
}
101+
onPress={toggleIsOpen}
102+
/>
103+
<div className="flex size-full flex-col items-center justify-center gap-4 pt-2">
104+
<p className="text-klerosUIComponentsPrimaryText text-center">
105+
You have a previous prediction with {isUpPredict ? "DOWN" : "UP"}{" "}
106+
tokens, <br />
107+
Sell those tokens to make a new prediction.
108+
</p>
109+
<TradeButton
110+
quote={sellQuote}
111+
sellToken={sellToken}
112+
setNextStep={() => {
113+
toggleIsOpen();
114+
refetchQuotes();
115+
}}
116+
/>
117+
</div>
118+
</Modal>
119+
</>
120+
);
121+
};
122+
export default PredictButton;

src/app/(homepage)/components/ProjectFunding/index.tsx

Lines changed: 5 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,17 @@
11
import React from "react";
22

3-
import {
4-
Card,
5-
Accordion,
6-
NumberField,
7-
Button,
8-
} from "@kleros/ui-components-library";
3+
import { Card, Accordion, NumberField } from "@kleros/ui-components-library";
94
import clsx from "clsx";
10-
import { useToggle } from "react-use";
115

126
import { useCardInteraction } from "@/context/CardInteractionContext";
137
import { useMarketContext } from "@/context/MarketContext";
14-
import { useBalance } from "@/hooks/useBalance";
158

169
import { isUndefined } from "@/utils";
1710

18-
import DefaultPredictButton from "./PredictPopup/ActionButtons/DefaultPredictButton";
19-
2011
import Details from "./Details";
2112
import PositionValue from "./PositionValue";
13+
import PredictButton from "./PredictButton";
2214
import PredictionSlider from "./PredictionSlider";
23-
import PredictPopup from "./PredictPopup";
2415

2516
const ProjectFunding: React.FC = ({}) => {
2617
const { setActiveCardId } = useCardInteraction();
@@ -30,22 +21,9 @@ const ProjectFunding: React.FC = ({}) => {
3021
prediction,
3122
setPrediction,
3223
showEstimateVariant,
33-
differenceBetweenRoutes,
34-
isLoading: isLoadingComplexRoute,
3524
} = useMarketContext();
36-
const {
37-
name,
38-
color,
39-
upToken,
40-
downToken,
41-
precision,
42-
details,
43-
marketId,
44-
underlyingToken,
45-
} = market;
46-
const { data: underlyingBalance } = useBalance(underlyingToken);
47-
48-
const [isPopUpOpen, toggleIsPopUpOpen] = useToggle(false);
25+
const { name, color, upToken, downToken, precision, details, marketId } =
26+
market;
4927

5028
return (
5129
<Card
@@ -85,24 +63,7 @@ const ProjectFunding: React.FC = ({}) => {
8563
}
8664
onChange={(e) => setPrediction(e * precision)}
8765
/>
88-
{differenceBetweenRoutes > 0 ? (
89-
<Button
90-
text={"Predict"}
91-
aria-label="Predict Button"
92-
isDisabled={
93-
isUndefined(underlyingBalance) ||
94-
underlyingBalance === 0n ||
95-
isLoadingComplexRoute
96-
}
97-
isLoading={isLoadingComplexRoute}
98-
onPress={async () => {
99-
setActiveCardId(marketId);
100-
toggleIsPopUpOpen();
101-
}}
102-
/>
103-
) : (
104-
<DefaultPredictButton />
105-
)}
66+
<PredictButton />
10667
</div>
10768
<label
10869
className={clsx(
@@ -128,7 +89,6 @@ const ProjectFunding: React.FC = ({}) => {
12889
items={[{ title: "Details", body: <Details {...details} /> }]}
12990
/>
13091
</div>
131-
<PredictPopup isOpen={isPopUpOpen} toggleIsOpen={toggleIsPopUpOpen} />
13292
</Card>
13393
);
13494
};

0 commit comments

Comments
 (0)