Skip to content

Commit

Permalink
Almost finish treasury FE
Browse files Browse the repository at this point in the history
  • Loading branch information
tensojka committed Aug 19, 2024
1 parent 4bbf105 commit 8e11486
Show file tree
Hide file tree
Showing 10 changed files with 1,294 additions and 75 deletions.
Binary file added frontend/bun.lockb
Binary file not shown.
5 changes: 4 additions & 1 deletion frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Proposal from "./components/Proposal";
import { CONTRACT_ADDR } from "./lib/config";
// import { useAccount } from "@starknet-react/core";
import SubmitProposalModal from "./components/SubmitProposalModal";
import TreasuryStatus from "./components/TreasuryStatus";

function App() {
const [isModalOpen, setIsModalOpen] = React.useState(false);
Expand All @@ -34,7 +35,7 @@ function App() {
<SubmitProposalModal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)} />

{/* List of proposals */}
<div className="flex max-w-[50rem] flex-col items-center w-full gap-2 p-6">
<div className="flex max-w-[50rem] flex-col items-center w-full pt-6 gap-2">
<div className="flex flex-row items-start w-full">
<div className="flex-grow text-2xl font-bold">
Proposals
Expand Down Expand Up @@ -65,6 +66,8 @@ function App() {
})
)}
</div>

<TreasuryStatus />
</main>
);
}
Expand Down
51 changes: 25 additions & 26 deletions frontend/src/components/NewProposalForm.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React, { useState } from "react";
import React, { useState, useMemo } from "react";
import toast from "react-hot-toast";
import { CONTRACT_ADDR } from "../lib/config";
import { useAccount, useContractWrite } from "@starknet-react/core";
import CustomProposal from "./CustomProposal";
//import CustomProposal from "./CustomProposal";
import Treasury from "./proposal-form/Treasury";

const proposalTypes = ["airdrop", "signal vote", "AMM", "governance", "treasury"];

Expand All @@ -15,7 +16,7 @@ export default function NewProposalForm({
const [selectedType, setSelectedType] = useState<string | null>(null);
const [payload, setPayload] = useState<string>("");

const calls = React.useMemo(() => {
const calls = useMemo(() => {
if (!selectedType) return [];
const typeIndex = proposalTypes.indexOf(selectedType);
return [{
Expand Down Expand Up @@ -47,7 +48,8 @@ export default function NewProposalForm({
}

return (
<form onSubmit={submitProposal} className="space-y-4">
//<!---->
<>
<div className="flex justify-between space-x-2">
{proposalTypes.map((type) => (
<button
Expand All @@ -64,29 +66,26 @@ export default function NewProposalForm({
</div>

{selectedType && selectedType !== "treasury" && (
<div>
<label htmlFor="payload" className="block mb-2">Payload</label>
<input
id="payload"
type="text"
placeholder="(integer or hex, e.g.: 1 or 0x1)"
className="w-full p-2 border rounded-lg border-slate-300"
value={payload}
onChange={(e) => setPayload(e.target.value)}
/>
</div>
<form onSubmit={submitProposal} className="w-full space-y-2">
<label htmlFor="payload" className="block">Payload</label>
<input
id="payload"
type="text"
placeholder="(integer or hex, e.g.: 1 or 0x1)"
className="w-full p-2 border rounded-lg border-slate-300"
value={payload}
onChange={(e) => setPayload(e.target.value)}
/>
<button
type="submit"
className="w-full p-2 bg-blue-500 text-white rounded-lg"
>
Submit
</button>
</form>
)}

{selectedType === "treasury" && <CustomProposal setIsModalOpen={setIsModalOpen}/>}

{selectedType !== "treasury" && (
<button
type="submit"
className="w-full p-2 bg-blue-500 text-white rounded-lg"
>
Submit
</button>
)}
</form>
{selectedType === "treasury" && <Treasury setIsModalOpen={setIsModalOpen}/>}
</>
);
}
56 changes: 56 additions & 0 deletions frontend/src/components/TreasuryStatus.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { TREASURY_ADDRESS, ETH_ADDRESS, STRK_ADDRESS } from '../constants/config.json';
import React, { useMemo } from "react";
import { useContractRead } from "@starknet-react/core";
import { abi, formatBalance } from "../lib/erc20";

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

const balanceReads = tokens.map(token =>
useContractRead({
functionName: "balanceOf",
args: [TREASURY_ADDRESS],
abi,
address: token.address,
watch: true,
})
);

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

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

return (
<div className="p-6 mb-6">
<div className="flex w-full flex-grow pb-4 text-2xl font-bold">Treasury status</div>
{isLoading ? (
<div>Loading...</div>
) : (
<div className="w-[50rem] max-w-[50rem] grid grid-cols-2 items-center p-2 pl-0 rounded-lg bg-slate-200">
{balances.map((token, index) => (
<div key={index} className="flex items-center">
<div className="self-stretch pl-5 pr-4 mr-4 font-mono border-r grid text-slate-400 place-content-center border-slate-400">
{token.name}
</div>
<div className="flex justify-between items-center gap-20">
<div className="flex-grow font-bold">
{formatBalance(BigInt(token.balance.toString()))}
</div>
</div>
</div>
))}
</div>
)}
</div>
);
}
73 changes: 73 additions & 0 deletions frontend/src/components/proposal-form/Distribution.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import React, { useState } from "react";
import { ETH_ADDRESS, STRK_ADDRESS } from '../../constants/config.json';
import { toast } from 'react-hot-toast';

interface DistributionProps {
onSubmit: (calldata: string[]) => void;
}

export const Distribution: React.FC<DistributionProps> = ({ onSubmit }) => {
const [recipient, setRecipient] = useState("");
const [token, setToken] = useState("ETH");
const [amount, setAmount] = useState("");

const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
let tok;
if(token == "ETH") {
tok = ETH_ADDRESS;
} else if (token == "STRK") {
tok = STRK_ADDRESS;
}

if(!recipient.startsWith("0x")) {
toast.error('Address must start with 0x');
return;
}
const amountWei = parseFloat(amount).toString();
const calldata = [recipient, tok, amountWei];
onSubmit(calldata);
};

return (
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<label htmlFor="recipient" className="block mb-2">Recipient</label>
<input
id="recipient"
className='border border-gray-300 rounded-lg p-2 w-full'
type="text"
value={recipient}
onChange={(e) => setRecipient(e.target.value)}
/>
</div>
<div>
<label htmlFor="token" className="block mb-2">Token to distribute</label>
<select
id="token"
className='border border-gray-300 rounded-lg p-2 w-full'
value={token}
onChange={(e) => setToken(e.target.value)}
>
<option value="ETH">ETH</option>
</select>
</div>
<div>
<label htmlFor="amount" className="block mb-2">Amount</label>
<input
id="amount"
type="number"
className='border border-gray-300 rounded-lg p-2 w-full'
value={amount}
onChange={(e) => setAmount(e.target.value)}
/>
</div>
<button
type="submit"
className="w-full p-2 mt-4 text-white bg-blue-500 rounded-lg"
>
Submit
</button>
</form>
);
};
74 changes: 74 additions & 0 deletions frontend/src/components/proposal-form/Treasury.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React, { useState } from "react";
import { Distribution } from "./Distribution";
import { useAccount, useContractWrite } from '@starknet-react/core';
import { toast } from 'react-hot-toast';
import { CONTRACT_ADDR } from "../../lib/config";

const treasuryProposalTypes = ["distribution", "zklend", "nostra", "carmine"];


export default function Treasury({
setIsModalOpen,
}: {
setIsModalOpen: React.Dispatch<React.SetStateAction<boolean>>;
}) {
const [selectedType, setSelectedType] = useState<string | null>(null);
const { isConnected } = useAccount();
const [calldata, setCalldata] = useState<string[]>([]);

const { writeAsync } = useContractWrite({ calls: [] });

const handleSubmit = async (newCalldata: string[]) => {
if (!isConnected) {
toast.error('Please connect your wallet');
return;
}

if (!selectedType || newCalldata.length === 0) {
toast.error('Please fill out all fields');
return;
}

setCalldata(newCalldata);
if (!selectedType || calldata.length === 0) return [];
const calls = [{
contractAddress: CONTRACT_ADDR,
entrypoint: 'submit_custom_proposal',
calldata: [
selectedType,
...calldata.map(data => data.toString()),
],
}];
try {
await writeAsync({ calls: calls });
toast.success('Custom proposal submitted');
} catch (e) {
toast.error('Something went wrong');
console.error(e);
} finally {
setIsModalOpen(false);
}
};

return (
<>
<div className="flex justify-between space-x-2">
{treasuryProposalTypes.map((type) => (
<button
key={type}
type="button"
onClick={() => setSelectedType(type)}
className={`px-4 py-2 rounded flex-1 ${
selectedType === type ? "bg-blue-500 text-white" : "bg-gray-200"
}`}
>
{type}
</button>
))}
</div>
{selectedType === "distribution" && (
<Distribution onSubmit={handleSubmit} />
)}
</>
);
}
1 change: 1 addition & 0 deletions frontend/src/constants/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"API_URL": "https://api.carmine.finance",
"AMM_ADDRESS": "0x047472e6755afc57ada9550b6a3ac93129cc4b5f98f51c73e0644d129fd208d9",
"GOVERNANCE_ADDRESS": "0x057dfabb5a506bfd1937062562a1adf45c7c4c62d0377ccfc59a0b42d7ab3212",
"TREASURY_ADDRESS": "0x4c990da03da72bdfb10db5c04e8aaa9d5404a07fe454037facb7744c132d42c",
"ETH_ADDRESS": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7",
"USDC_ADDRESS": "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8",
"BTC_ADDRESS": "0x03fe2b97c1fd336e750087d68b9b867997fd64a2661ff3ca5a7c771641e8e7ac",
Expand Down
47 changes: 0 additions & 47 deletions frontend/src/helpers/tokens.tsx

This file was deleted.

3 changes: 2 additions & 1 deletion frontend/src/lib/config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export const CONTRACT_ADDR =
"0x057dfabb5a506bfd1937062562a1adf45c7c4c62d0377ccfc59a0b42d7ab3212";
// mainnet: "0x001405ab78ab6ec90fba09e6116f373cda53b0ba557789a4578d8c1ec374ba0f";
"0x057dfabb5a506bfd1937062562a1adf45c7c4c62d0377ccfc59a0b42d7ab3212"; // sepolia with treasury
export const TOKEN_CONTRACT =
"0x2b91dd683bc4bcae7a9c5d0cbeba0e8d62fa657742e4640f1e8163dc10e9bd7";

Expand Down
Loading

0 comments on commit 8e11486

Please sign in to comment.