Skip to content

Commit

Permalink
Add ability to add new stake
Browse files Browse the repository at this point in the history
  • Loading branch information
tensojka committed Aug 29, 2024
1 parent 9383126 commit bea21a7
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 37 deletions.
38 changes: 8 additions & 30 deletions frontend/src/components/TokenBalance.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,18 @@
import React, { useMemo } from "react";
import { useContractRead } from "@starknet-react/core";
import { abi, formatBalance } from "../lib/erc20";
import React from "react";
import { formatBalance } from "../lib/erc20";

interface Token {
interface TokenBalanceItem {
name: string;
address: string;
balance: bigint;
}

interface TokenBalanceProps {
tokens: Token[];
accountAddress: string;
balances: TokenBalanceItem[];
title: string;
isLoading: boolean;
}

export default function TokenBalance({ tokens, accountAddress, title }: TokenBalanceProps) {
const balanceReads = tokens.map(token =>
useContractRead({
functionName: "balanceOf",
args: [accountAddress],
abi,
address: token.address,
watch: true,
})
);

const balances = useMemo(() =>
tokens.map((token, index) => ({
name: token.name,
balance: balanceReads[index].data,
isLoading: balanceReads[index].isLoading,
})),
[tokens, balanceReads]
);

const isLoading = balances.some(b => b.isLoading);

export default function TokenBalance({ balances, title, isLoading }: TokenBalanceProps) {
return (
<div>
<div className="flex w-full flex-grow pb-4 text-2xl font-bold">{title}</div>
Expand All @@ -49,7 +27,7 @@ export default function TokenBalance({ tokens, accountAddress, title }: TokenBal
</div>
<div className="flex justify-between items-center gap-20">
<div className="flex-grow font-bold">
{formatBalance(BigInt(token.balance.toString()))}
{formatBalance(token.balance)}
</div>
</div>
</div>
Expand Down
6 changes: 4 additions & 2 deletions frontend/src/components/TreasuryStatus.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import { TREASURY_ADDRESS, ETH_ADDRESS, STRK_ADDRESS } from '../lib/config';
import React from "react";
import TokenBalance from './TokenBalance';
import { useTokenBalances } from "../lib/useTokenBalances";

export default function TreasuryStatus() {
const tokens = [
{ name: "ETH", address: ETH_ADDRESS },
{ name: "STRK", address: STRK_ADDRESS },
];
const { balances, isLoading } = useTokenBalances(tokens, TREASURY_ADDRESS);

return (
<TokenBalance
tokens={tokens}
accountAddress={TREASURY_ADDRESS}
balances={balances}
isLoading={isLoading}
title="Treasury status"
/>
);
Expand Down
89 changes: 89 additions & 0 deletions frontend/src/components/staking/NewStake.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import React, { useState, useMemo } from "react";
import { useContractWrite } from "@starknet-react/core";
import { CONTRACT_ADDR, FLOATING_TOKEN_CONTRACT } from '../../lib/config'; //
import toast from "react-hot-toast";

const stakingPeriods = [
{ label: "1 month", value: "2629743" }
];

interface NewStakeProps {
floatingBalance: string;
}

export default function NewStake({ floatingBalance }: NewStakeProps) {
const [amount, setAmount] = useState<string>("");
const [period, setPeriod] = useState<string>(stakingPeriods[0].value);

const calls = useMemo(() => {
if (!amount) return [];
return [
{
contractAddress: FLOATING_TOKEN_CONTRACT,
entrypoint: "approve",
calldata: [CONTRACT_ADDR, 0, amount]
},
{
contractAddress: CONTRACT_ADDR,
entrypoint: "stake",
calldata: [period, amount],
}
];
}, [amount, period]);

const { writeAsync } = useContractWrite({ calls });

const handleStake = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
if (!amount) {
toast.error("Please enter an amount to stake");
return;
}
writeAsync()
.then(() => toast.success("Stake successful"))
.catch((e) => {
toast.error("Staking failed");
console.error(e);
});
};

if (BigInt(floatingBalance) === 0n) return null;

return (
<form onSubmit={handleStake} className="mt-4 space-y-4">
<div className="flex w-full flex-grow pb-4 text-xl font-bold">Stake your floating token</div>
<div>
<label htmlFor="stakePeriod" className="block mb-1">Staking Period</label>
<select
id="stakePeriod"
className="w-full p-2 border rounded-lg border-slate-300"
value={period}
onChange={(e) => setPeriod(e.target.value)}
>
{stakingPeriods.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>
</div>
<div>
<label htmlFor="stakeAmount" className="block mb-1">Stake Amount</label>
<input
id="stakeAmount"
type="text"
placeholder="Amount in wei"
className="w-full p-2 border rounded-lg border-slate-300"
value={amount}
onChange={(e) => setAmount(e.target.value)}
/>
</div>
<button
type="submit"
className="w-full p-2 bg-blue-500 text-white rounded-lg"
>
Stake
</button>
</form>
);
}
18 changes: 13 additions & 5 deletions frontend/src/components/staking/VotingPower.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,27 @@ import { VOTING_TOKEN_CONTRACT, FLOATING_TOKEN_CONTRACT } from '../../lib/config
import React from "react";
import { useAccount } from "@starknet-react/core";
import TokenBalance from '../TokenBalance';
import { useTokenBalances } from "../../lib/useTokenBalances";
import NewStake from './NewStake';

export default function VotingPower() {
const { address } = useAccount();
const tokens = [
{ name: "VOTING", address: VOTING_TOKEN_CONTRACT },
{ name: "FLOATING", address: FLOATING_TOKEN_CONTRACT },
];
const { balances, isLoading } = useTokenBalances(tokens, address);

const floatingBalance = balances.find(b => b.name === "FLOATING")?.balance || "0";

return (
<TokenBalance
tokens={tokens}
accountAddress={address}
title="Voting Power"
/>
<div className="w-full max-w-[50rem]">
<TokenBalance
balances={balances}
isLoading={isLoading}
title="Voting Power"
/>
<NewStake floatingBalance={floatingBalance.toString()} />
</div>
);
}
32 changes: 32 additions & 0 deletions frontend/src/lib/useTokenBalances.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { useMemo } from "react";
import { useContractRead } from "@starknet-react/core";
import { abi } from "./erc20";

interface Token {
name: string;
address: string;
}

export function useTokenBalances(tokens: Token[], accountAddress: string) {
const balanceReads = tokens.map(token =>
useContractRead({
functionName: "balanceOf",
args: [accountAddress],
abi,
address: token.address,
watch: true,
})
);

const balances = useMemo(() =>
tokens.map((token, index) => ({
name: token.name,
balance: BigInt(balanceReads[index].data?.toString() || "0"),
})),
[tokens, balanceReads]
);

const isLoading = balanceReads.some(read => read.isLoading);

return { balances, isLoading };
}

0 comments on commit bea21a7

Please sign in to comment.