diff --git a/frontend/.env.example b/frontend/.env.example
index 8355651..cb4b21f 100644
--- a/frontend/.env.example
+++ b/frontend/.env.example
@@ -1,3 +1,4 @@
NEXT_PUBLIC_GRAPHQL_URL=http://127.0.0.1:8080/graphql
+NEXT_PUBLIC_INSPECT_URL=http://127.0.0.1:8080/inspect
NEXT_PUBLIC_TOKEN_ADDRESS=0xae7f61eCf06C65405560166b259C54031428A9C4
NEXT_PUBLIC_DAPP_ADDRESS=0x70ac08179605AF2D9e75782b8DEcDD3c22aA4D0C
diff --git a/frontend/package.json b/frontend/package.json
index 7037fcf..c1d0432 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -29,6 +29,7 @@
"react-icons": "^4",
"react-jazzicon": "^1",
"react-use-downloader": "^1.2.4",
+ "swr": "^2",
"urql": "^4",
"viem": "^1",
"wagmi": "^1"
diff --git a/frontend/src/app/create/page.tsx b/frontend/src/app/create/page.tsx
index dc35488..a8f1815 100644
--- a/frontend/src/app/create/page.tsx
+++ b/frontend/src/app/create/page.tsx
@@ -22,7 +22,7 @@ import {
useErc20PortalDepositErc20Tokens,
usePrepareErc20PortalDepositErc20Tokens,
} from "../../hooks/contracts";
-import { DifficultyLevel } from "../../components/DifficultyLevel";
+import { DifficultyLevelPicker } from "../../components/DifficultyLevelPicker";
import { GameLevel } from "../../components/GameLevel";
const parseIfNeeded = (setter: (v: number) => void) => {
@@ -159,7 +159,7 @@ const CreateGame: FC = () => {
onChange={parseIfNeeded(setSubmissionTime)}
description="Amount of time players will have to submit their gameplay"
/>
-
diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx
index 0c60c35..60c3704 100644
--- a/frontend/src/app/page.tsx
+++ b/frontend/src/app/page.tsx
@@ -1,26 +1,70 @@
"use client";
-
import React, { FC } from "react";
-import { Button, Center, Stack } from "@mantine/core";
+import { Button, Center, Stack, Text, Title } from "@mantine/core";
import Image from "next/image";
import Link from "next/link";
+import { useInspect } from "../hooks/inspect";
+import { Contest } from "../model";
+import { DifficultyLevel } from "../components/DifficultyLevel";
+import { formatUnits, Hex, hexToBigInt } from "viem";
+
const Home: FC = () => {
+ const {
+ report: contest,
+ error,
+ data,
+ } = useInspect(`/active_contest`);
+ const c = {
+ contest_id: 1,
+ name: "Contest",
+ host: "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92261",
+ ticket_price: "0x8ac7230489e80000",
+ level: 1,
+ difficulty: 3,
+ play_time: 3600,
+ submission_time: 3600,
+ creation_timestamp: 1695505002,
+ state: "finalized",
+ players: [
+ {
+ wallet: "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
+ score: 123,
+ reward: null,
+ },
+ {
+ wallet: "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92267",
+ score: null,
+ reward: null,
+ },
+ ],
+ prize_pool: "0x32d26d12e980b600000",
+ };
+
return (
-
-
-
-
-
-
-
+ {!c && (
+ <>
+
+
+
+
+ >
+ )}
+ {c.name}
+ Hosted by {c.host}
+
+
+ {formatUnits(hexToBigInt(c.ticket_price as Hex), 18)} APE to
+ signup
+
+
);
diff --git a/frontend/src/components/DifficultyLevel.tsx b/frontend/src/components/DifficultyLevel.tsx
index 0c8194d..c57537b 100644
--- a/frontend/src/components/DifficultyLevel.tsx
+++ b/frontend/src/components/DifficultyLevel.tsx
@@ -1,4 +1,4 @@
-import { Image, SegmentedControl, Stack, Text } from "@mantine/core";
+import { Image, Overlay, SegmentedControl, Stack, Text } from "@mantine/core";
import { FC } from "react";
export const difficultyLevels = [
@@ -9,30 +9,25 @@ export const difficultyLevels = [
];
export type DifficultyLevelProps = {
- onChange(value: number): void;
value: number;
};
-export const DifficultyLevel: FC = ({
- onChange,
- value,
-}) => {
+export const DifficultyLevel: FC = ({ value }) => {
return (
onChange(parseInt(value))}
value={value.toString()}
data={difficultyLevels.map((level, index) => ({
value: index.toString(),
label: (
{level.label}
+ {index != value && }
event.target}
/>
),
diff --git a/frontend/src/components/DifficultyLevelPicker.tsx b/frontend/src/components/DifficultyLevelPicker.tsx
new file mode 100644
index 0000000..8ea157e
--- /dev/null
+++ b/frontend/src/components/DifficultyLevelPicker.tsx
@@ -0,0 +1,41 @@
+import { Image, Overlay, SegmentedControl, Stack, Text } from "@mantine/core";
+import { FC } from "react";
+
+export const difficultyLevels = [
+ { label: "I'm Too Young to Die", image: "/img/difficulty1.png" },
+ { label: "Hurt Me Plenty", image: "/img/difficulty2.png" },
+ { label: "Ultra Violence", image: "/img/difficulty3.png" },
+ { label: "Nightmare", image: "/img/difficulty4.png" },
+];
+
+export type DifficultyLevelPickerProps = {
+ onChange(value: number): void;
+ value: number;
+};
+
+export const DifficultyLevelPicker: FC = ({
+ onChange,
+ value,
+}) => {
+ return (
+ onChange(parseInt(value))}
+ value={value.toString()}
+ data={difficultyLevels.map((level, index) => ({
+ value: index.toString(),
+ label: (
+
+ {level.label}
+
+
+ ),
+ }))}
+ />
+ );
+};
diff --git a/frontend/src/hooks/inspect.ts b/frontend/src/hooks/inspect.ts
new file mode 100644
index 0000000..26978fd
--- /dev/null
+++ b/frontend/src/hooks/inspect.ts
@@ -0,0 +1,56 @@
+import useSWR, { Key, SWRResponse } from "swr";
+import { bytesToString, toBytes } from "viem";
+
+const baseURL = process.env.NEXT_PUBLIC_INSPECT_URL;
+
+export enum InspectStatus {
+ Accepted = "Accepted",
+ Rejected = "Rejected",
+ Exception = "Exception",
+ MachineHalted = "MachineHalted",
+ CycleLimitExceeded = "CycleLimitExceeded",
+ TimeLimitExceeded = "TimeLimitExceeded",
+}
+
+export interface InspectReport {
+ payload: string;
+}
+
+export interface InspectMetadata {
+ active_epoch_index: number;
+ current_input_index: number;
+}
+
+export interface InspectResponse {
+ status: InspectStatus;
+ exception_payload: string;
+ reports: InspectReport[];
+ metadata: InspectMetadata;
+}
+
+type ReportResponse = {
+ report?: TReport;
+};
+
+export type UseInspect = SWRResponse &
+ ReportResponse;
+
+export const useInspect = (key: Key): UseInspect => {
+ const swr = useSWR(() =>
+ key ? `${baseURL}${key}` : false
+ );
+
+ const response = swr.data;
+ let report = undefined;
+ if (
+ response &&
+ response.status == InspectStatus.Accepted &&
+ response.reports.length > 0
+ ) {
+ const r = response.reports[0];
+ const data = bytesToString(toBytes(r.payload));
+ report = JSON.parse(data) as TReport;
+ }
+
+ return { ...swr, report };
+};
diff --git a/frontend/src/model/index.ts b/frontend/src/model/index.ts
new file mode 100644
index 0000000..6bf7527
--- /dev/null
+++ b/frontend/src/model/index.ts
@@ -0,0 +1,20 @@
+export interface Player {
+ wallet: string;
+ score: number;
+ reward: string;
+}
+
+export interface Contest {
+ contest_id: number;
+ name: string;
+ host: string;
+ ticket_price: string;
+ prize_pool: string;
+ level: number;
+ difficulty: number;
+ creation_timestamp: number;
+ play_time: number;
+ submission_time: number;
+ state: "ready_to_play" | "gameplay_submission" | "finalized";
+ players: Player[];
+}