Skip to content

Commit db029a8

Browse files
committed
Feat: Add ch-2
1 parent b83a327 commit db029a8

39 files changed

+1645
-179
lines changed

packages/nextjs/.env

Whitespace-only changes.

packages/nextjs/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,5 @@ yarn-error.log*
3434
# typescript
3535
*.tsbuildinfo
3636
next-env.d.ts
37+
38+
yarn.lock

packages/nextjs/app/debug/_components/DebugContracts.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export function DebugContracts() {
2424
}, [selectedContract, setSelectedContract]);
2525

2626
return (
27-
<div className="flex flex-col gap-y-6 lg:gap-y-8 py-8 lg:py-12 justify-center items-center">
27+
<div className="flex flex-col gap-y-6 lg:gap-y-8 py-8 lg:py-12 justify-center items-center text-primary">
2828
{contractNames.length === 0 ? (
2929
<p className="text-3xl mt-14">No contracts found!</p>
3030
) : (

packages/nextjs/app/debug/_components/contract/ContractInput.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,11 @@ export const ContractInput = ({
5858
<div className="flex flex-col gap-1.5 w-full">
5959
<div className="flex items-center ml-2">
6060
{paramType.name && (
61-
<span className="text-xs font-medium mr-2 leading-none">
61+
<span className="text-xs font-medium mr-2 leading-none text-neutral">
6262
{paramType.name}
6363
</span>
6464
)}
65-
<span className="block text-xs font-extralight leading-none">
65+
<span className="block text-xs font-extralight leading-none text-neutral">
6666
{displayType(paramType.type)}
6767
</span>
6868
</div>

packages/nextjs/app/debug/_components/contract/ContractReadMethods.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export const ContractReadMethods = ({
2929
};
3030
});
3131
if (!functionsToDisplay.length) {
32-
return <>No read methods</>;
32+
return <span className="text-neutral">No read methods</span>;
3333
}
3434
return (
3535
<>

packages/nextjs/app/debug/_components/contract/ContractUI.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export const ContractUI = ({
4141

4242
if (!deployedContractData) {
4343
return (
44-
<p className="text-3xl mt-14">
44+
<p className="text-3xl mt-14 text-neutral">
4545
{`No contract found by the name of "${contractName}" on chain "${targetNetwork.name}"!`}
4646
</p>
4747
);
@@ -59,7 +59,9 @@ export const ContractUI = ({
5959
<span className="font-bold text-neutral">{contractName}</span>
6060
<Address address={deployedContractData.address} />
6161
<div className="flex gap-1 items-center">
62-
<span className="font-bold text-sm">Balance:</span>
62+
<span className="font-bold text-sm text-neutral">
63+
Balance:
64+
</span>
6365
<Balance
6466
address={deployedContractData.address}
6567
className="px-0 h-1.5 min-h-[0.375rem] text-network"
@@ -69,7 +71,7 @@ export const ContractUI = ({
6971
</div>
7072
{targetNetwork && (
7173
<p className="my-0 text-sm">
72-
<span className="font-bold">Network</span>:{" "}
74+
<span className="font-bold text-neutral">Network</span>:{" "}
7375
<span className="text-network">{targetNetwork.name}</span>
7476
</p>
7577
)}
@@ -86,7 +88,7 @@ export const ContractUI = ({
8688
<div className="rounded-[5px] border border-[#8A45FC] flex flex-col mt-10 relative bg-component">
8789
<div className="bg-function w-[140px] h-[32.5px] absolute self-start -top-[43px] -left-[1px] -z-10 py-[0.55rem] clip-corner">
8890
<div className="flex items-center justify-center space-x-2">
89-
<p className="my-0 text-sm text-center">Read</p>
91+
<p className="my-0 text-sm text-center text-neutral">Read</p>
9092
</div>
9193
</div>
9294
<div className="p-5 divide-y divide-secondary">
@@ -100,7 +102,7 @@ export const ContractUI = ({
100102
<div className="rounded-[5px] border border-[#8A45FC] flex flex-col mt-10 relative bg-component">
101103
<div className="w-[140px] h-[32.5px] absolute self-start -top-[43px] -left-[1px] -z-10 py-[0.55rem] bg-function clip-corner">
102104
<div className="flex items-center justify-center space-x-2">
103-
<p className="my-0 text-sm">Write</p>
105+
<p className="my-0 text-sm text-neutral">Write</p>
104106
</div>
105107
</div>
106108
<div className="p-5 divide-y divide-secondary">

packages/nextjs/app/debug/_components/contract/ContractVariables.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export const ContractVariables = ({
3131
};
3232
});
3333
if (!functionsToDisplay.length) {
34-
return <>No contract variables</>;
34+
return <span className="text-neutral">No contract variables</span>;
3535
}
3636

3737
return (

packages/nextjs/app/debug/_components/contract/DisplayVariable.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export const DisplayVariable = ({
5555
{abiFunction.name}
5656
</h3>
5757
<button
58-
className="btn btn-ghost btn-xs"
58+
className="btn btn-ghost btn-xs text-neutral"
5959
onClick={async () => await refetch()}
6060
>
6161
{!isLoading && isFetching ? (

packages/nextjs/app/debug/_components/contract/WriteOnlyFunctionForm.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ export const WriteOnlyFunctionForm = ({
116116
{inputs}
117117
<div className="flex justify-between gap-2">
118118
{!zeroInputs && (
119-
<div className="flex-grow basis-0">
119+
<div className="flex-grow basis-0 text-neutral-content">
120120
{displayedTxResult ? (
121121
<TxReceipt txResult={displayedTxResult} />
122122
) : null}

packages/nextjs/app/exampleView1/page.tsx

Lines changed: 0 additions & 15 deletions
This file was deleted.

packages/nextjs/app/page.tsx

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,55 @@
11
"use client";
2-
2+
import Image from "next/image";
33
import type { NextPage } from "next";
44
import { useAccount } from "@starknet-react/core";
55

66
const Home: NextPage = () => {
77
const connectedAddress = useAccount();
88
return (
9-
<>
10-
<div className="flex items-center flex-col flex-grow pt-10">
11-
<div className="px-5 w-[90%] md:w-[75%]"></div>
9+
<div className="flex items-center flex-col flex-grow pt-10 bg-">
10+
<div className="px-5 w-[90%] md:w-[75%]">
11+
<h1 className="text-center mb-6 text-neutral">
12+
<span className="block text-2xl mb-2 text-neutral">
13+
SpeedRunStark
14+
</span>
15+
<span className="block text-4xl font-bold text-neutral">
16+
Challenge #1: 🔏 Decentralized Staking App
17+
</span>
18+
</h1>
19+
<div className="flex flex-col items-center justify-center">
20+
<Image
21+
src="/banner-home.svg"
22+
width="727"
23+
height="231"
24+
alt="challenge banner"
25+
className="rounded-xl border-4 border-primary"
26+
/>
27+
<div className="max-w-3xl ">
28+
<p className="text-center text-lg mt-8 text-neutral">
29+
🦸 A superpower of Starknet is allowing you, the builder, to
30+
create a simple set of rules that an adversarial group of players
31+
can use to work together. In this challenge, you create a
32+
decentralized application where users can coordinate a group
33+
funding effort. The users only have to trust the code.
34+
</p>
35+
<p className="text-center text-lg text-neutral">
36+
🌟 The final deliverable is deploying a Dapp that lets users send
37+
ether to a contract and stake if the conditions are met, then
38+
deploy your app to a public webserver. Submit the url on{" "}
39+
<a
40+
href="https://speedrunstark.com/"
41+
target="_blank"
42+
rel="noreferrer"
43+
className="underline text-neutral font-bold"
44+
>
45+
SpeedRunStark.com
46+
</a>
47+
!
48+
</p>
49+
</div>
50+
</div>
1251
</div>
13-
</>
52+
</div>
1453
);
1554
};
1655

packages/nextjs/app/stake-ui/page.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
"use client";
2+
3+
import type { NextPage } from "next";
4+
import { StakeContractInteraction } from "~~/components/stake/StakeContractInteraction";
5+
import { useDeployedContractInfo } from "~~/hooks/scaffold-stark";
6+
7+
const StakerUI: NextPage = () => {
8+
const { data: StakerContract } = useDeployedContractInfo("Staker");
9+
10+
return (
11+
<StakeContractInteraction
12+
key={StakerContract?.address}
13+
address={StakerContract?.address}
14+
/>
15+
);
16+
};
17+
18+
export default StakerUI;

packages/nextjs/app/stakings/page.tsx

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
"use client";
2+
import React from "react";
3+
import { NextPage } from "next";
4+
import { useScaffoldEventHistory } from "~~/hooks/scaffold-stark/useScaffoldEventHistory";
5+
import { Address } from "~~/components/scaffold-stark";
6+
import { formatEther } from "ethers";
7+
8+
interface StakeEvent {
9+
args: {
10+
sender: string;
11+
amount: bigint;
12+
};
13+
}
14+
const Staking: NextPage = () => {
15+
// @ts-ignore
16+
const { data: stakeEvents, isLoading } = useScaffoldEventHistory<StakeEvent>({
17+
contractName: "Staker",
18+
eventName: "contracts::Staker::Staker::Stake",
19+
watch: true,
20+
fromBlock: 0n,
21+
});
22+
console.log(stakeEvents);
23+
24+
if (isLoading)
25+
return (
26+
<div className="flex justify-center items-center mt-10">
27+
<span className="loading loading-spinner loading-lg"></span>
28+
</div>
29+
);
30+
31+
return (
32+
<div className="flex items-center flex-col flex-grow pt-10 text-neutral">
33+
<div className="px-5">
34+
<h1 className="text-center mb-3">
35+
<span className="block text-2xl font-bold">All Staking Events</span>
36+
</h1>
37+
</div>
38+
<div className="overflow-x-auto border border-secondary">
39+
<table className="table table-zebra w-full">
40+
<thead>
41+
<tr>
42+
<th className="bg-secondary text-white">From</th>
43+
<th className="bg-secondary text-white">Value</th>
44+
</tr>
45+
</thead>
46+
<tbody>
47+
{!stakeEvents || stakeEvents.length === 0 ? (
48+
<tr>
49+
<td colSpan={3} className="text-center">
50+
No events found
51+
</td>
52+
</tr>
53+
) : (
54+
stakeEvents?.map((event: StakeEvent, index) => {
55+
return (
56+
<tr key={index}>
57+
<td>
58+
<Address address={`0x${event.args.sender}`} />
59+
</td>
60+
<td>
61+
{event.args.amount &&
62+
formatEther(BigInt(event.args.amount))}{" "}
63+
ETH
64+
</td>
65+
</tr>
66+
);
67+
})
68+
)}
69+
</tbody>
70+
</table>
71+
</div>
72+
</div>
73+
);
74+
};
75+
76+
export default Staking;

packages/nextjs/components/Button/Button.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const Button: React.FC<ButtonProps> = ({
1313
}) => {
1414
return (
1515
<button
16-
className={`py-[10px] px-[20px] sm:px-[10px] sm:py-[5px] bg-base-300 text-base-100 rounded-[8px] sm:text-[12px] ${isDisable ? "cursor-not-allowed opacity-50" : "cursor-pointer"}`}
16+
className={`py-[5px] px-[10px] sm:px-[20px] sm:py-[10px] bg-base-300 text-base-100 rounded-[8px] sm:text-[14px] text-[12px] ${isDisable ? "cursor-not-allowed opacity-50" : "cursor-pointer"}`}
1717
onClick={onClick}
1818
type="button"
1919
disabled={isDisable || children === "Coming Soon"}

packages/nextjs/components/Header.tsx

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,19 @@ import React, { useCallback, useRef, useState, useEffect } from "react";
44
import Image from "next/image";
55
import Link from "next/link";
66
import { usePathname } from "next/navigation";
7-
import { Bars3Icon, BugAntIcon, PhotoIcon } from "@heroicons/react/24/outline";
7+
import {
8+
Bars3Icon,
9+
BugAntIcon,
10+
CircleStackIcon,
11+
InboxStackIcon,
12+
} from "@heroicons/react/24/outline";
813
import { useOutsideClick } from "~~/hooks/scaffold-stark";
914
import { CustomConnectButton } from "~~/components/scaffold-stark/CustomConnectButton";
1015
import { useTheme } from "next-themes";
1116
import { useTargetNetwork } from "~~/hooks/scaffold-stark/useTargetNetwork";
1217
import { devnet } from "@starknet-react/chains";
1318
import { SwitchTheme } from "./SwitchTheme";
19+
import { useAccount, useProvider } from "@starknet-react/core";
1420

1521
export type HeaderMenuLink = {
1622
label: string;
@@ -20,9 +26,18 @@ export type HeaderMenuLink = {
2026

2127
export const menuLinks: HeaderMenuLink[] = [
2228
{
23-
label: "Example View 1",
24-
href: "/exampleView1",
25-
icon: <PhotoIcon className="h-4 w-4" />,
29+
label: "Home",
30+
href: "/",
31+
},
32+
{
33+
label: "Staker UI",
34+
href: "/stake-ui",
35+
icon: <CircleStackIcon className="h-4 w-4" />,
36+
},
37+
{
38+
label: "Stake Events",
39+
href: "/stakings",
40+
icon: <InboxStackIcon className="h-4 w-4" />,
2641
},
2742
{
2843
label: "Debug Contracts",
@@ -39,6 +54,7 @@ export const HeaderMenuLinks = () => {
3954
useEffect(() => {
4055
setIsDark(theme === "dark");
4156
}, [theme]);
57+
4258
return (
4359
<>
4460
{menuLinks.map(({ label, href, icon }) => {
@@ -77,6 +93,23 @@ export const Header = () => {
7793
);
7894
const { targetNetwork } = useTargetNetwork();
7995
const isLocalNetwork = targetNetwork.id === devnet.id;
96+
const { provider } = useProvider();
97+
const { address, status } = useAccount();
98+
const [isDeployed, setIsDeployed] = useState(true);
99+
100+
useEffect(() => {
101+
if (status === "connected" && address) {
102+
provider
103+
.getContractVersion(address)
104+
.then((v) => {
105+
if (v) setIsDeployed(true);
106+
})
107+
.catch((e) => {
108+
console.log(e);
109+
setIsDeployed(false);
110+
});
111+
}
112+
}, [status, address, provider]);
80113

81114
return (
82115
<div className="sticky lg:static top-0 navbar min-h-0 flex-shrink-0 justify-between z-20 px-0 sm:px-2">
@@ -128,8 +161,12 @@ export const Header = () => {
128161
</ul>
129162
</div>
130163
<div className="navbar-end flex-grow mr-4 gap-4">
164+
{status === "connected" && !isDeployed ? (
165+
<span className="bg-[#8a45fc] text-[9px] p-1 text-white">
166+
Wallet Not Deployed
167+
</span>
168+
) : null}
131169
<CustomConnectButton />
132-
{/* <FaucetButton /> */}
133170
<SwitchTheme
134171
className={`pointer-events-auto ${
135172
isLocalNetwork ? "self-end md:self-auto" : ""

0 commit comments

Comments
 (0)