diff --git a/frontend/src/components/TokenBalance.tsx b/frontend/src/components/TokenBalance.tsx
index 30ff2dbe..916e13da 100644
--- a/frontend/src/components/TokenBalance.tsx
+++ b/frontend/src/components/TokenBalance.tsx
@@ -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 (
{title}
@@ -49,7 +27,7 @@ export default function TokenBalance({ tokens, accountAddress, title }: TokenBal
- {formatBalance(BigInt(token.balance.toString()))}
+ {formatBalance(token.balance)}
diff --git a/frontend/src/components/TreasuryStatus.tsx b/frontend/src/components/TreasuryStatus.tsx
index 768e37c7..ca292a0b 100644
--- a/frontend/src/components/TreasuryStatus.tsx
+++ b/frontend/src/components/TreasuryStatus.tsx
@@ -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 (
);
diff --git a/frontend/src/components/staking/NewStake.tsx b/frontend/src/components/staking/NewStake.tsx
new file mode 100644
index 00000000..8ae01e4a
--- /dev/null
+++ b/frontend/src/components/staking/NewStake.tsx
@@ -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("");
+ const [period, setPeriod] = useState(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) => {
+ 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 (
+
+ );
+}
\ No newline at end of file
diff --git a/frontend/src/components/staking/VotingPower.tsx b/frontend/src/components/staking/VotingPower.tsx
index d8ce242c..0b358bbc 100644
--- a/frontend/src/components/staking/VotingPower.tsx
+++ b/frontend/src/components/staking/VotingPower.tsx
@@ -2,6 +2,8 @@ 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();
@@ -9,12 +11,18 @@ export default function VotingPower() {
{ 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 (
-
+
+
+
+
);
}
\ No newline at end of file
diff --git a/frontend/src/lib/useTokenBalances.ts b/frontend/src/lib/useTokenBalances.ts
new file mode 100644
index 00000000..6972a751
--- /dev/null
+++ b/frontend/src/lib/useTokenBalances.ts
@@ -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 };
+}
\ No newline at end of file