Skip to content

Commit

Permalink
Merge pull request #192 from EmmanuelAR/feat/191
Browse files Browse the repository at this point in the history
Feat/191
  • Loading branch information
EmmanuelAR authored Nov 6, 2024
2 parents a031629 + cf6fe23 commit 77367e3
Show file tree
Hide file tree
Showing 11 changed files with 683 additions and 448 deletions.
5 changes: 3 additions & 2 deletions contracts/src/fund.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,13 @@ pub mod Fund {
name: ByteArray,
goal: u256,
evidence_link: ByteArray,
contact_handle: ByteArray
contact_handle: ByteArray,
reason: ByteArray
) {
self.id.write(id);
self.owner.write(owner);
self.name.write(name);
self.reason.write(" ");
self.reason.write(reason);
self.up_votes.write(FundConstants::INITIAL_UP_VOTES);
self.goal.write(goal);
self.state.write(FundStates::RECOLLECTING_VOTES);
Expand Down
7 changes: 5 additions & 2 deletions contracts/src/fundManager.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ pub trait IFundManager<TContractState> {
name: ByteArray,
goal: u256,
evidence_link: ByteArray,
contact_handle: ByteArray
contact_handle: ByteArray,
reason: ByteArray
);
fn getCurrentId(self: @TContractState) -> u128;
fn getFund(self: @TContractState, id: u128) -> ContractAddress;
Expand Down Expand Up @@ -82,7 +83,8 @@ pub mod FundManager {
name: ByteArray,
goal: u256,
evidence_link: ByteArray,
contact_handle: ByteArray
contact_handle: ByteArray,
reason: ByteArray,
) {
assert(goal >= FundConstants::MINIMUM_GOAL, 'Goal must be at least 500');
let mut call_data: Array<felt252> = array![];
Expand All @@ -92,6 +94,7 @@ pub mod FundManager {
Serde::serialize(@goal, ref call_data);
Serde::serialize(@evidence_link, ref call_data);
Serde::serialize(@contact_handle, ref call_data);
Serde::serialize(@reason, ref call_data);
let (new_fund_address, _) = deploy_syscall(
self.fund_class_hash.read(), 12345, call_data.span(), false
)
Expand Down
14 changes: 9 additions & 5 deletions contracts/tests/test_fund.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ fn FUND_MANAGER() -> ContractAddress {
fn NAME() -> ByteArray {
"Lorem impsum, Lorem impsum, Lorem impsum, Lorem impsum, Lorem impsum, Lorem impsum, Lorem impsum, Lorem impsum"
}
fn REASON() -> ByteArray {
fn REASON_1() -> ByteArray {
"Lorem impsum, Lorem impsum, Lorem impsum, Lorem impsum, Lorem impsum, Lorem impsum, Lorem impsum, Lorem impsum"
}
fn REASON_2() -> ByteArray {
"Lorem impsum, Lorem impsum, Lorem impsum, Lorem impsum, Lorem impsum, Lorem impsum, Lorem impsum, Lorem impsum"
}
fn GOAL() -> u256 {
Expand All @@ -63,6 +66,7 @@ fn _setup_() -> ContractAddress {
calldata.append_serde(GOAL());
calldata.append_serde(EVIDENCE_LINK_1());
calldata.append_serde(CONTACT_HANDLE_1());
calldata.append_serde(REASON_1());
let (contract_address, _) = contract.deploy(@calldata).unwrap();
contract_address
}
Expand All @@ -85,7 +89,7 @@ fn test_constructor() {
assert(id == ID(), 'Invalid id');
assert(owner == OWNER(), 'Invalid owner');
assert(name == NAME(), 'Invalid name');
assert(reason == " ", 'Invalid reason');
assert(reason == REASON_1(), 'Invalid reason');
assert(up_votes == 0, 'Invalid up votes');
assert(goal == GOAL(), 'Invalid goal');
assert(current_goal_state == 0, 'Invalid current goal state');
Expand All @@ -109,11 +113,11 @@ fn test_set_reason() {
let contract_address = _setup_();
let dispatcher = IFundDispatcher { contract_address };
let reason = dispatcher.getReason();
assert(reason == " ", 'Invalid reason');
assert(reason == REASON_1(), 'Invalid reason');
start_cheat_caller_address_global(OWNER());
dispatcher.setReason(REASON());
dispatcher.setReason(REASON_2());
let new_reason = dispatcher.getReason();
assert(new_reason == REASON(), 'Set reason method not working')
assert(new_reason == REASON_2(), 'Set reason method not working')
}

#[test]
Expand Down
8 changes: 4 additions & 4 deletions contracts/tests/test_fund_manager.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ fn EVIDENCE_LINK() -> ByteArray {
fn CONTACT_HANDLE() -> ByteArray {
"Lorem impsum, Lorem impsum, Lorem impsum, Lorem impsum, Lorem impsum, Lorem impsum, Lorem impsum, Lorem impsum"
}

fn _setup_() -> (ContractAddress, ClassHash) {
// Fund
let fund = declare("Fund").unwrap();
Expand All @@ -54,6 +53,7 @@ fn _setup_() -> (ContractAddress, ClassHash) {
fund_calldata.append_serde(GOAL());
fund_calldata.append_serde(EVIDENCE_LINK());
fund_calldata.append_serde(CONTACT_HANDLE());
fund_calldata.append_serde(REASON());

let (fund_contract_address, _) = fund.deploy(@fund_calldata).unwrap();
let fund_class_hash = get_class_hash(fund_contract_address);
Expand Down Expand Up @@ -87,7 +87,7 @@ fn test_new_fund() {
start_cheat_caller_address_global(OWNER());
let (contract_address, fund_class_hash) = _setup_();
let fund_manager_contract = IFundManagerDispatcher { contract_address };
fund_manager_contract.newFund(NAME(), GOAL(), EVIDENCE_LINK(), CONTACT_HANDLE());
fund_manager_contract.newFund(NAME(), GOAL(), EVIDENCE_LINK(), CONTACT_HANDLE(), REASON());
let expected_fund_class_hash = get_class_hash(fund_manager_contract.getFund(1));
let current_id = fund_manager_contract.getCurrentId();
assert(expected_fund_class_hash == fund_class_hash, 'Invalid fund address');
Expand All @@ -100,7 +100,7 @@ fn test_new_fund_bad_goal() {
start_cheat_caller_address_global(OWNER());
let (contract_address, _) = _setup_();
let fund_manager_contract = IFundManagerDispatcher { contract_address };
fund_manager_contract.newFund(NAME(), BAD_GOAL(), EVIDENCE_LINK(), CONTACT_HANDLE());
fund_manager_contract.newFund(NAME(), BAD_GOAL(), EVIDENCE_LINK(), CONTACT_HANDLE(), REASON());
}

#[test]
Expand All @@ -113,7 +113,7 @@ fn test_fund_deployed_event() {
let mut spy = spy_events();

let current_id = fund_manager_contract.getCurrentId();
fund_manager_contract.newFund(NAME(), GOAL(), EVIDENCE_LINK(), CONTACT_HANDLE());
fund_manager_contract.newFund(NAME(), GOAL(), EVIDENCE_LINK(), CONTACT_HANDLE(), REASON());

let expected_fund_class_hash = fund_manager_contract.getFund(1);

Expand Down
1 change: 0 additions & 1 deletion frontend/gostarkme-web/app/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ const Dashboard = () => {
const fundContract = new Contract(fundAbi, fundaddr, wallet?.account);
// GET FUND NAME
let name = await fundContract.getName();
name = hex2ascii(name.toString(16));
// GET FUND DESCRIPTION
let desc = await fundContract.getReason();
// GET FUND ID
Expand Down
4 changes: 2 additions & 2 deletions frontend/gostarkme-web/components/modules/Fund/Fund.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ const Fund = () => {

// GET FUND NAME
let name = await fundContract.getName();
name = hex2ascii(name.toString(16));
// GET FUND DESCRIPTION

let desc = await fundContract.getReason();
if (desc == " ") {
desc = "No description provided";
}
let state = await fundContract.getState();

let currentBalance = await fundContract.getCurrentGoalState();
let currentBalance = await fundContract.get_current_goal_state();

let goal = await fundContract.getGoal();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,25 @@ import React from 'react';
interface FundingStepProps {
fundingName: string;
setFundingName: (name: string) => void;
name: string;
setName: (name: string) => void;
errors: { fundingName: string; name: string }; // Expecting errors as props
setErrors: React.Dispatch<React.SetStateAction<{ fundingName: string; name: string }>>; // Specify the type for setErrors
goal: string;
setGoal: (name: string) => void;
evidenceLink: string;
setEvidenceLink: (name: string) => void;
contactHandle: string;
setContactHandle: (name: string) => void;
errors: { fundingName: string; goal: string ;evidenceLink: string; contactHandle: string }; // Expecting errors as props
setErrors: React.Dispatch<React.SetStateAction<{ fundingName: string; goal: string ;evidenceLink: string; contactHandle: string }>>; // Specify the type for setErrors
}

const FundingStep: React.FC<FundingStepProps> = ({
fundingName,
setFundingName,
name,
setName,
goal,
setGoal,
evidenceLink,
setEvidenceLink,
contactHandle,
setContactHandle,
errors,
setErrors,
}) => {
Expand All @@ -22,10 +30,10 @@ const FundingStep: React.FC<FundingStepProps> = ({

// Check if the input is empty or a valid non-negative number
if (newValue === '' || (Number(newValue) >= 0 && !isNaN(Number(newValue)))) {
setName(newValue);
setErrors((prev) => ({ ...prev, name: '' }));
setGoal(newValue);
setErrors((prev) => ({ ...prev, goal : '' }));
} else {
setErrors((prev) => ({ ...prev, name: 'The goal must be a non-negative number.' }));
setErrors((prev) => ({ ...prev, goal: 'The goal must be a non-negative number.' }));
}
};

Expand All @@ -45,6 +53,26 @@ const FundingStep: React.FC<FundingStepProps> = ({
}
};

const handleEvidenceLink = (e: React.ChangeEvent<HTMLInputElement>) => {
const newValue = e.target.value;
setEvidenceLink(newValue);
if (!newValue) {
setErrors((prev) => ({ ...prev, evidenceLink: 'Evidence link is required.' }));
} else {
setErrors((prev) => ({ ...prev, evidenceLink: '' }));
}
};

const handleContactHandle = (e: React.ChangeEvent<HTMLInputElement>) => {
const newValue = e.target.value;
setContactHandle(newValue);
if (!newValue) {
setErrors((prev) => ({ ...prev, evidenceLink: 'Contact handle is required.' }));
} else {
setErrors((prev) => ({ ...prev, evidenceLink: '' }));
}
};

return (
<div className="text-center w-11/12 md:w-3/3 lg:w-1/1">
<input
Expand All @@ -58,19 +86,41 @@ const FundingStep: React.FC<FundingStepProps> = ({
<input
type="number"
placeholder="Set your goal in STRKs"
value={name}
value={goal}
onChange={handleGoal}
className={`mt-4 p-2 pl-4 border rounded w-full placeholder:text-base ${errors.name ? 'border-red-500' : 'border-black'}`}
className={`mt-4 p-2 pl-4 border rounded w-full placeholder:text-base ${errors.goal ? 'border-red-500' : 'border-black'}`}
required
min={0}
/>
<input
type="text"
placeholder="Set a link to the repo or evidence"
value={evidenceLink}
onChange={handleEvidenceLink}
className={`mt-4 p-2 pl-4 border rounded w-full placeholder:text-base ${errors.evidenceLink ? 'border-red-500' : 'border-black'}`}
required
/>
<input
type="text"
placeholder="Set a contact handle"
value={contactHandle}
onChange={handleContactHandle}
className={`mt-4 p-2 pl-4 border rounded w-full placeholder:text-base ${errors.contactHandle ? 'border-red-500' : 'border-black'}`}
required
/>

{/* Error Messages */}
{errors.fundingName && (
<p className="mt-5 text-red-500 text-center mb-4">{errors.fundingName}</p>
)}
{errors.name && (
<p className="mt-5 text-red-500 text-center mb-4">{errors.name}</p>
{errors.goal && (
<p className="mt-5 text-red-500 text-center mb-4">{errors.goal}</p>
)}
{errors.evidenceLink && (
<p className="mt-5 text-red-500 text-center mb-4">{errors.evidenceLink}</p>
)}
{errors.contactHandle && (
<p className="mt-5 text-red-500 text-center mb-4">{errors.contactHandle}</p>
)}
</div>
);
Expand Down
52 changes: 41 additions & 11 deletions frontend/gostarkme-web/components/modules/newfunding/Stages.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,26 @@ import { Button } from "@/components/ui/Button";
import { useState } from "react";
import FundingStep from "./FundingStep";
import DescriptionStep from "./DescriptionStep";
import { Contract, wallet, InvokeFunctionResponse, shortString } from "starknet";
import { fundManager } from "@/contracts/abis/fundManager";
import { FUND_MANAGER_ADDR } from "@/constants";
import { useAtomValue } from "jotai";
import { walletStarknetkitLatestAtom } from "@/state/connectedWallet";


const Stages = () => {
const [currentStep, setCurrentStep] = useState(0);
const [fundingName, setFundingName] = useState("");
const [name, setName] = useState("");
const [goal, setGoal] = useState("");
const [fundingDescription, setFundingDescription] = useState("");
const [errors, setErrors] = useState({ fundingName: "", name: "" });
const [errors, setErrors] = useState({ fundingName: "", goal: "",evidenceLink: "",contactHandle: "" });
const [evidenceLink, setEvidenceLink] = useState("");
const [contactHandle, setContactHandle] = useState("");
const wallet = useAtomValue(walletStarknetkitLatestAtom);

const handleNextStep = () => {
// Reset errors
setErrors({ fundingName: "", name: "" });
setErrors({ fundingName: "", goal: "", evidenceLink: "", contactHandle: ""});

// Validate fields
let hasErrors = false;
Expand All @@ -21,8 +30,16 @@ const Stages = () => {
setErrors((prev) => ({ ...prev, fundingName: "Funding name is required." }));
hasErrors = true;
}
if (!name) {
setErrors((prev) => ({ ...prev, name: "The goal is required." }));
if (!goal) {
setErrors((prev) => ({ ...prev, goal: "The goal is required." }));
hasErrors = true;
}
if (!evidenceLink) {
setErrors((prev) => ({ ...prev, evidenceLink: "The evidence link is required." }));
hasErrors = true;
}
if (!contactHandle) {
setErrors((prev) => ({ ...prev, contactHandle: "The contact handle is required." }));
hasErrors = true;
}
}
Expand All @@ -38,22 +55,35 @@ const Stages = () => {
alert("Please enter a description.");
return;
}
console.log("Funding Name:", fundingName);
console.log("Name:", name);
console.log("Description:", fundingDescription);
newFund();
};

function newFund() {
const fundNameSplited = shortString.splitLongString(fundingName);
const fundManagerContract = new Contract(fundManager, FUND_MANAGER_ADDR, wallet?.account);
const myCall = fundManagerContract.newFund(fundingName,goal,evidenceLink,contactHandle,fundingDescription);
wallet?.account?.execute(myCall)
.then(async (resp: InvokeFunctionResponse) => {
console.log("increaseBalance txH =", resp.transaction_hash);
})
.catch((e: any) => { console.log("error increase balance =", e) });
}

return (
<div className="flex flex-col items-center justify-center space-y-6">
{/* Step Content */}
{currentStep === 0 ? (
<FundingStep
fundingName={fundingName}
setFundingName={setFundingName}
name={name}
setName={setName}
goal={goal}
setGoal={setGoal}
evidenceLink={evidenceLink}
setEvidenceLink={setEvidenceLink}
contactHandle={contactHandle}
setContactHandle={setContactHandle}
errors={errors} // Pass errors down
setErrors={setErrors} // Pass setErrors down
setErrors={setErrors} // Pass setErrors down,
/>
) : (
<DescriptionStep
Expand Down
2 changes: 1 addition & 1 deletion frontend/gostarkme-web/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export const ARGENT_WEBWALLET_URL =
process.env.NEXT_PUBLIC_ARGENT_WEBWALLET_URL || "https://web.argent.xyz"

export const FUND_MANAGER_ADDR =
"0x0263457e0646dc4312c4a583fcae334d98f9b4ff1cf7a9c091649c2bec02543a"
"0x029875ea72f9b0ad21be7fe8defcfc5f2355a748015aefdd8b0477857a236d96"

export const navItems = [
{ label: 'My Profile', href: '/app/myprofile' },
Expand Down
Loading

0 comments on commit 77367e3

Please sign in to comment.