From 73cda93f1e9169674e139a9b034e7b5a4c3fcb01 Mon Sep 17 00:00:00 2001 From: Avelous Ujiri <86206128+Avelous@users.noreply.github.com> Date: Sat, 2 Mar 2024 15:09:28 +0100 Subject: [PATCH 1/4] Merge from main (#31) From 9d9883a42c0d78b048d361e113cae330e770661e Mon Sep 17 00:00:00 2001 From: Avelous Ujiri <86206128+Avelous@users.noreply.github.com> Date: Thu, 14 Mar 2024 22:40:26 +0100 Subject: [PATCH 2/4] Fixed sweeping gas handling following EIP-4844 upgrades on optimism (#35) * Fixed gas issues following EIP-4844 upgrade on optimism --- packages/nextjs/hooks/useSweepWallet.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/nextjs/hooks/useSweepWallet.tsx b/packages/nextjs/hooks/useSweepWallet.tsx index 5aad943..fedefe4 100644 --- a/packages/nextjs/hooks/useSweepWallet.tsx +++ b/packages/nextjs/hooks/useSweepWallet.tsx @@ -43,8 +43,8 @@ const useSweepWallet = ({ game, token }: { game?: Game; token?: string }) => { const gasPrice = await provider.getGasPrice(); - const gasLimit = 21000000; - let gasCost = gasPrice.mul(42000000); // gasLimit * 2 + const gasLimit = 21000; + let gasCost = gasPrice.mul(42000); // gasLimit * 2 let totalToSend = balance.sub(gasCost); @@ -90,7 +90,7 @@ const useSweepWallet = ({ game, token }: { game?: Game; token?: string }) => { setIsSweeping(false); } catch (error: any) { try { - gasCost = gasPrice.mul(84000000); // gasLimit * 4 + gasCost = gasPrice.mul(84000); // gasLimit * 4 totalToSend = balance.sub(gasCost); @@ -124,7 +124,7 @@ const useSweepWallet = ({ game, token }: { game?: Game; token?: string }) => { setIsSweeping(false); } catch (error: any) { try { - gasCost = gasPrice.mul(168000000); // gasLimit * 8 + gasCost = gasPrice.mul(168000); // gasLimit * 8 totalToSend = balance.sub(gasCost); From 57bc9431edad2f84fa510751c154b2a9776ff4eb Mon Sep 17 00:00:00 2001 From: Avelous Ujiri <86206128+Avelous@users.noreply.github.com> Date: Tue, 19 Mar 2024 19:51:17 +0100 Subject: [PATCH 3/4] Pk dice updates (#36) * Added a welcome roll section to home screen, set theme to light mode only, removed ai background & responsive UI updates --- packages/nextjs/components/Footer.tsx | 21 +-- packages/nextjs/components/Header.tsx | 8 +- packages/nextjs/components/SwitchTheme.tsx | 2 +- packages/nextjs/components/Wallet.tsx | 4 +- .../components/dicedemo/GameCreateForm.tsx | 6 +- .../components/dicedemo/GameJoinForm.tsx | 17 +-- .../{Congrats.tsx => PlayerAnnoucement.tsx} | 4 +- .../components/dicedemo/WelcomeRoll.tsx | 143 ++++++++++++++++++ .../RainbowKitCustomConnectButton.tsx | 4 +- packages/nextjs/pages/_app.tsx | 12 +- packages/nextjs/pages/game/[id].tsx | 86 ++++------- packages/nextjs/pages/index.tsx | 77 +++++----- packages/nextjs/tailwind.config.js | 20 ++- packages/nextjs/utils/diceDemo/gameUtils.ts | 15 ++ 14 files changed, 270 insertions(+), 149 deletions(-) rename packages/nextjs/components/dicedemo/{Congrats.tsx => PlayerAnnoucement.tsx} (97%) create mode 100644 packages/nextjs/components/dicedemo/WelcomeRoll.tsx create mode 100644 packages/nextjs/utils/diceDemo/gameUtils.ts diff --git a/packages/nextjs/components/Footer.tsx b/packages/nextjs/components/Footer.tsx index f15f646..7b8cf2d 100644 --- a/packages/nextjs/components/Footer.tsx +++ b/packages/nextjs/components/Footer.tsx @@ -1,21 +1,22 @@ -import { hardhat } from "wagmi/chains"; -import { CurrencyDollarIcon } from "@heroicons/react/24/outline"; +// import { hardhat } from "wagmi/chains"; +// import { CurrencyDollarIcon } from "@heroicons/react/24/outline"; import { HeartIcon } from "@heroicons/react/24/outline"; -import { SwitchTheme } from "~~/components/SwitchTheme"; -import { Faucet } from "~~/components/scaffold-eth"; -import { useGlobalState } from "~~/services/store/store"; -import { getTargetNetwork } from "~~/utils/scaffold-eth"; + +// import { SwitchTheme } from "~~/components/SwitchTheme"; +// import { Faucet } from "~~/components/scaffold-eth"; +// import { useGlobalState } from "~~/services/store/store"; +// import { getTargetNetwork } from "~~/utils/scaffold-eth"; /** * Site footer */ export const Footer = () => { - const nativeCurrencyPrice = useGlobalState(state => state.nativeCurrencyPrice); + // const nativeCurrencyPrice = useGlobalState(state => state.nativeCurrencyPrice); const codeLink = "https://github.com/BuidlGuidl/private-key-dice"; return ( -
-
+
+ {/*
{nativeCurrencyPrice > 0 && ( @@ -28,7 +29,7 @@ export const Footer = () => {
-
+
*/}
    diff --git a/packages/nextjs/components/Header.tsx b/packages/nextjs/components/Header.tsx index 765db53..c6a5c53 100644 --- a/packages/nextjs/components/Header.tsx +++ b/packages/nextjs/components/Header.tsx @@ -59,7 +59,7 @@ export const Header = () => { ); return ( -
    +
    - DICE + DICE
    Private Key Dice
    -
      + {/*
        -
      +
    */}
    diff --git a/packages/nextjs/components/SwitchTheme.tsx b/packages/nextjs/components/SwitchTheme.tsx index 4752e35..993378a 100644 --- a/packages/nextjs/components/SwitchTheme.tsx +++ b/packages/nextjs/components/SwitchTheme.tsx @@ -8,7 +8,7 @@ export const SwitchTheme = ({ className }: { className?: string }) => { useEffect(() => { const body = document.body; - body.setAttribute("data-theme", isDarkMode ? "scaffoldEthDark" : "scaffoldEth"); + body.setAttribute("data-theme", "scaffoldEth"); }, [isDarkMode]); return ( diff --git a/packages/nextjs/components/Wallet.tsx b/packages/nextjs/components/Wallet.tsx index 2f3153c..d9abc8e 100644 --- a/packages/nextjs/components/Wallet.tsx +++ b/packages/nextjs/components/Wallet.tsx @@ -186,8 +186,8 @@ export default function Wallet() {
    - Point your camera phone at qr code to open in   - + Point your phone camera at qr code to open in   + Punk Wallet : diff --git a/packages/nextjs/components/dicedemo/GameCreateForm.tsx b/packages/nextjs/components/dicedemo/GameCreateForm.tsx index d03539c..5112182 100644 --- a/packages/nextjs/components/dicedemo/GameCreateForm.tsx +++ b/packages/nextjs/components/dicedemo/GameCreateForm.tsx @@ -109,10 +109,10 @@ const GameCreationForm = () => { }; return ( -
    +

    - diff --git a/packages/nextjs/components/dicedemo/GameJoinForm.tsx b/packages/nextjs/components/dicedemo/GameJoinForm.tsx index 66cd7be..ac5d2b9 100644 --- a/packages/nextjs/components/dicedemo/GameJoinForm.tsx +++ b/packages/nextjs/components/dicedemo/GameJoinForm.tsx @@ -1,4 +1,4 @@ -import React, { Dispatch, SetStateAction, useEffect, useRef, useState } from "react"; +import React, { Dispatch, SetStateAction, useEffect, useState } from "react"; import { useRouter } from "next/router"; import { InputBase } from "../scaffold-eth"; import QrReader from "react-qr-reader-es6"; @@ -15,7 +15,6 @@ const GameJoinForm = ({ setInviteCode: Dispatch>; }) => { const router = useRouter(); - const labelRef = useRef(null); const [scanning, setScanning] = useState(false); const [loading, setLoading] = useState(false); @@ -73,12 +72,6 @@ const GameJoinForm = ({ // setScanning(true); // }; - useEffect(() => { - if (labelRef.current) { - labelRef.current.focus(); - } - }, []); - useEffect(() => { if (invite) { handleJoinGame(invite as string); @@ -93,10 +86,10 @@ const GameJoinForm = ({ }, [invite]); return ( -
    +
    -
      { setIsDarkTheme(isDarkMode); }, [isDarkMode]); - const nowish = new Date(); - return ( @@ -42,15 +40,7 @@ const ScaffoldEthApp = ({ Component, pageProps }: AppProps) => { avatar={BlockieAvatar} theme={isDarkTheme ? darkTheme() : lightTheme()} > -
      +
      diff --git a/packages/nextjs/pages/game/[id].tsx b/packages/nextjs/pages/game/[id].tsx index bd077b1..998cc07 100644 --- a/packages/nextjs/pages/game/[id].tsx +++ b/packages/nextjs/pages/game/[id].tsx @@ -6,8 +6,8 @@ import QRCode from "qrcode.react"; import CopyToClipboard from "react-copy-to-clipboard"; import { useAccount, useBalance } from "wagmi"; import { CheckCircleIcon, DocumentDuplicateIcon } from "@heroicons/react/24/outline"; -import Congrats from "~~/components/dicedemo/Congrats"; import HostAnnouncement from "~~/components/dicedemo/HostAnnouncement"; +import PlayerAnnouncement from "~~/components/dicedemo/PlayerAnnoucement"; import RestartWithNewPk from "~~/components/dicedemo/RestartWithNewPk"; import { Address } from "~~/components/scaffold-eth"; import { Price } from "~~/components/scaffold-eth/Price"; @@ -15,6 +15,7 @@ import useGameData from "~~/hooks/useGameData"; import useSweepWallet from "~~/hooks/useSweepWallet"; import { Game } from "~~/types/game/game"; import { kickPlayer, pauseResumeGame, toggleMode } from "~~/utils/diceDemo/apiUtils"; +import { calculateLength, compareResult, generateRandomHex } from "~~/utils/diceDemo/gameUtils"; function GamePage() { const router = useRouter(); @@ -46,20 +47,7 @@ function GamePage() { const prize = useBalance({ address: game?.adminAddress }); const { sweepWallet, isSweeping, sweepMessage } = useSweepWallet({ game, token }); - const calculateLength = () => { - const maxLength = 150; - const diceCount = game?.diceCount ?? 0; - const calculatedLength = Math.max(maxLength - (diceCount - 1) * 3, 10); - return calculatedLength; - }; - - const length = calculateLength(); - - const generateRandomHex = () => { - const hexDigits = "0123456789ABCDEF"; - const randomIndex = Math.floor(Math.random() * hexDigits.length); - return hexDigits[randomIndex]; - }; + const length = calculateLength(game?.diceCount as number); const isAdmin = address == game?.adminAddress; const isPlayer = game?.players?.includes(address as string); @@ -117,16 +105,8 @@ function GamePage() { } }; - const compareResult = () => { - if (rolled && rolledResult.length > 0 && game?.hiddenChars) - return rolledResult.every( - (value, index) => value.toLowerCase() === Object.values(game?.hiddenChars)[index].toLowerCase(), - ); - }; - useEffect(() => { const { token, game: gameState } = loadGameState(); - setGame(gameState); setToken(token); setIsUnitRolling(Array.from({ length: gameState?.diceCount }, () => false)); @@ -140,7 +120,11 @@ function GamePage() { }, []); useEffect(() => { - const isHiiddenChars = compareResult(); + let isHiiddenChars; + + if (rolled && rolledResult.length > 0 && game?.hiddenChars) { + isHiiddenChars = compareResult(rolledResult, game?.hiddenChars); + } if (isHiiddenChars) { setAutoRolling(false); @@ -246,15 +230,15 @@ function GamePage() { if (game) { return (
      -
      +
      -
      -
      -
      +
      +
      +
      {isAdmin && (
      -
      +
      Copy Invite Url {inviteUrlCopied ? ( @@ -311,26 +295,8 @@ function GamePage() { )}
      - {/*
      - {inviteUrlCopied ? ( - Copied invite Url - ) : ( - { - setInviteUrlCopied(true); - setTimeout(() => { - setInviteUrlCopied(false); - }, 800); - }} - > - Copy invite Url - - )} -
      */}
      - ) -
      +
      Status: {game.status} @@ -343,7 +309,7 @@ function GamePage() { checked={game?.status == "ongoing"} />
      -
      +
      Mode: {game.mode}
      @@ -388,7 +354,7 @@ function GamePage() {
      {screenwidth <= 768 && (
      -
      +

      PRIVATE KEY

      @@ -400,7 +366,7 @@ function GamePage() { )} {game.winner && (

      - Winner
      + Winner
      )} {/* {isAdmin && game.winner && ( @@ -418,7 +384,7 @@ function GamePage() {
      {isAdmin && (
      -
      +

      PRIVATE KEY

      @@ -428,7 +394,7 @@ function GamePage() { )}

      -
      +

      PLAYERS: {game?.players.length}

      @@ -486,7 +452,7 @@ function GamePage() {
      )} -
      +
      {Object.entries(game.hiddenChars).map(([key], index) => rolled ? ( isUnitRolling[index] || (isRolling && game.mode == "brute") ? ( @@ -494,7 +460,7 @@ function GamePage() { className="transition duration-500 opacity-100 rounded-lg" key={key} src="/rolls-gif/Spin.gif" - alt="spinning dice" + alt="spinning" width={length} height={length} /> @@ -503,7 +469,7 @@ function GamePage() { className="transition duration-500 ease-in rounded-lg" key={key} src={`/rolls-jpg/${rolls[index]}.jpg`} - alt="rolled dice" + alt="rolled" width={length} height={length} /> @@ -513,7 +479,7 @@ function GamePage() { className="rounded-lg" key={key} src={`/rolls-jpg/0.jpg`} - alt="rolled dice" + alt="zero roll" width={length} height={length} /> @@ -522,7 +488,7 @@ function GamePage() {
      {" "} {(isHacked || game.winner) && ( - )} {screenwidth <= 768 && game.players.length > 0 && ( -
      +
      -
      +

      PLAYERS

      diff --git a/packages/nextjs/pages/index.tsx b/packages/nextjs/pages/index.tsx index 359b22b..f678422 100644 --- a/packages/nextjs/pages/index.tsx +++ b/packages/nextjs/pages/index.tsx @@ -4,6 +4,7 @@ import type { NextPage } from "next"; import { MetaHeader } from "~~/components/MetaHeader"; import GameCreationForm from "~~/components/dicedemo/GameCreateForm"; import GameJoinForm from "~~/components/dicedemo/GameJoinForm"; +import WelcomeRoll from "~~/components/dicedemo/WelcomeRoll"; const Home: NextPage = () => { const router = useRouter(); @@ -11,58 +12,62 @@ const Home: NextPage = () => { const { invite } = router.query; const [gameState, setGameState] = useState<"createGame" | "joinGame">("joinGame"); const [inviteCode, setInviteCode] = useState(""); + const [showWelcomeRoll, setShowWelcomRoll] = useState(true); useEffect(() => { if (invite) { setGameState("joinGame"); setInviteCode(invite as string); + setShowWelcomRoll(false); } }, [invite]); - const quote = - "Every key is a boundless whisper from the unknown and each guess a brushstroke on the infinite canvas of possibility, our journey weaves through the lattice of chance and destiny, illuminating paths in the cosmic dance of uncharted realms, where the thrill of discovery echoes in the heartbeats of the bold, crafting a universe with every daring leap into the silence of the never-before-seen."; + // const quote = "Every key is a boundless whisper from the unknown and each guess a brushstroke on the infinite canvas of possibility, our journey weaves through the lattice of chance and destiny, illuminating paths in the cosmic dance of uncharted realms, where the thrill of discovery echoes in the heartbeats of the bold, crafting a universe with every daring leap into the silence of the never-before-seen." return ( <> -
      -
      +
      + {/*

      {quote}

      -
      -
      -
      -
      -
      +
      */} + +
      +
      + {showWelcomeRoll && } +
      + +
      -
      - - {gameState == "createGame" && } - {gameState == "joinGame" && } +
      + {gameState == "createGame" && } + {gameState == "joinGame" && } +
      diff --git a/packages/nextjs/tailwind.config.js b/packages/nextjs/tailwind.config.js index b3a3b61..f0aecae 100644 --- a/packages/nextjs/tailwind.config.js +++ b/packages/nextjs/tailwind.config.js @@ -8,17 +8,17 @@ module.exports = { themes: [ { scaffoldEth: { - primary: "#d6fcf8", + primary: "#93BBFB", "primary-content": "#212638", - secondary: "#dceeee", + secondary: "#DAE8FF", "secondary-content": "#212638", - accent: "#90fbfb", + accent: "#93BBFB", "accent-content": "#212638", neutral: "#212638", "neutral-content": "#ffffff", "base-100": "#ffffff", - "base-200": "#f3fafa", - "base-300": "#dcfefe", + "base-200": "#f4f8ff", + "base-300": "#DAE8FF", "base-content": "#212638", info: "#93BBFB", success: "#34EEB6", @@ -45,7 +45,7 @@ module.exports = { "base-100": "#385183", "base-200": "#2A3655", "base-300": "#212638", - "base-content": "#048e8e", + "base-content": "#F9FBFF", info: "#385183", success: "#34EEB6", warning: "#FFCF72", @@ -90,6 +90,14 @@ module.exports = { theme: { // Extend Tailwind classes (e.g. font-bai-jamjuree, animate-grow) extend: { + colors: { + new_primary: "#293853", + new_secondary: "#3f5174", + new_tertiary: "#93bbfb", + }, + backgroundColor: { + gradient: "linear-gradient(225deg, #293853 0%, #521f93 100%)", + }, fontFamily: { "bai-jamjuree": ["Bai Jamjuree", "sans-serif"], }, diff --git a/packages/nextjs/utils/diceDemo/gameUtils.ts b/packages/nextjs/utils/diceDemo/gameUtils.ts new file mode 100644 index 0000000..7e15d46 --- /dev/null +++ b/packages/nextjs/utils/diceDemo/gameUtils.ts @@ -0,0 +1,15 @@ +export const calculateLength = (count: number) => { + const maxLength = 150; + const calculatedLength = Math.max(maxLength - (count - 1) * 3, 10); + return calculatedLength; +}; + +export const generateRandomHex = () => { + const hexDigits = "0123456789ABCDEF"; + const randomIndex = Math.floor(Math.random() * hexDigits.length); + return hexDigits[randomIndex]; +}; + +export const compareResult = (rolledResult: string[], pkChars: Record) => { + return rolledResult.every((value, index) => value.toLowerCase() === Object.values(pkChars)[index].toLowerCase()); +}; From eec2a7b46ba241a21bad11c78fe2f55a46f1b486 Mon Sep 17 00:00:00 2001 From: Avelous Ujiri <86206128+Avelous@users.noreply.github.com> Date: Thu, 18 Apr 2024 13:49:46 +0100 Subject: [PATCH 4/4] Added admin feature to increase and decrease hidden characters (#38) * Added admin feature to increase and decrease hidden characters --- packages/backend/controllers/Admin.ts | 27 +++++++++ packages/backend/models/Game.ts | 2 +- packages/backend/routes/admin.ts | 3 +- packages/nextjs/pages/game/[id].tsx | 65 +++++++++++++++++++--- packages/nextjs/server.config.ts | 2 +- packages/nextjs/utils/diceDemo/apiUtils.ts | 41 ++++++++++++++ 6 files changed, 129 insertions(+), 11 deletions(-) diff --git a/packages/backend/controllers/Admin.ts b/packages/backend/controllers/Admin.ts index 7516113..221bd27 100644 --- a/packages/backend/controllers/Admin.ts +++ b/packages/backend/controllers/Admin.ts @@ -243,3 +243,30 @@ export const kickPlayer = async (req: Request, res: Response) => { res.status(500).json({ error: (err as Error).message }); } }; + +export const varyHiddenPrivatekey = async (req: Request, res: Response) => { + try { + const { id } = req.params; + const { hiddenChars, hiddenPrivateKey, diceCount } = req.body; + const game = await Game.findById(id); + + if (!game) { + return res.status(404).json({ error: "Game not found." }); + } + + if (diceCount < 1 || diceCount > 64) { + return res.status(400).json({ error: "Invalid dice count." }); + } + + game.hiddenChars = hiddenChars; + game.hiddenPrivateKey = hiddenPrivateKey; + game.diceCount = diceCount; + const updatedGame = await game.save(); + const channel = ably.channels.get(`gameUpdate`); + channel.publish(`gameUpdate`, updatedGame); + + res.status(200).json(updatedGame); + } catch (err) { + res.status(500).json({ error: (err as Error).message }); + } +}; diff --git a/packages/backend/models/Game.ts b/packages/backend/models/Game.ts index c012dd0..7d47211 100644 --- a/packages/backend/models/Game.ts +++ b/packages/backend/models/Game.ts @@ -32,7 +32,7 @@ const gameSchema = new mongoose.Schema( }, hiddenPrivateKey: { type: String, - required: false, + required: true, }, hiddenChars: { type: Object, diff --git a/packages/backend/routes/admin.ts b/packages/backend/routes/admin.ts index bb0279d..1a23a17 100644 --- a/packages/backend/routes/admin.ts +++ b/packages/backend/routes/admin.ts @@ -1,5 +1,5 @@ import express from "express"; -import { createGame, changeGameMode, pauseGame, resumeGame, kickPlayer, restartWithNewPk } from "../controllers/Admin"; +import { createGame, changeGameMode, pauseGame, resumeGame, kickPlayer, restartWithNewPk, varyHiddenPrivatekey } from "../controllers/Admin"; import { verifyToken } from "../middleware/auth"; const router = express.Router(); @@ -10,5 +10,6 @@ router.patch("/pause/:id", verifyToken, pauseGame); router.patch("/resume/:id", verifyToken, resumeGame); router.patch("/kickplayer/:id", verifyToken, kickPlayer); router.patch("/restartwithnewpk/:id", verifyToken, restartWithNewPk); +router.patch("/varyhiddenprivatekey/:id", verifyToken, varyHiddenPrivatekey); export default router; diff --git a/packages/nextjs/pages/game/[id].tsx b/packages/nextjs/pages/game/[id].tsx index 998cc07..813dcd2 100644 --- a/packages/nextjs/pages/game/[id].tsx +++ b/packages/nextjs/pages/game/[id].tsx @@ -5,7 +5,12 @@ import Ably from "ably"; import QRCode from "qrcode.react"; import CopyToClipboard from "react-copy-to-clipboard"; import { useAccount, useBalance } from "wagmi"; -import { CheckCircleIcon, DocumentDuplicateIcon } from "@heroicons/react/24/outline"; +import { + CheckCircleIcon, + ChevronDoubleDownIcon, + ChevronDoubleUpIcon, + DocumentDuplicateIcon, +} from "@heroicons/react/24/outline"; import HostAnnouncement from "~~/components/dicedemo/HostAnnouncement"; import PlayerAnnouncement from "~~/components/dicedemo/PlayerAnnoucement"; import RestartWithNewPk from "~~/components/dicedemo/RestartWithNewPk"; @@ -14,7 +19,7 @@ import { Price } from "~~/components/scaffold-eth/Price"; import useGameData from "~~/hooks/useGameData"; import useSweepWallet from "~~/hooks/useSweepWallet"; import { Game } from "~~/types/game/game"; -import { kickPlayer, pauseResumeGame, toggleMode } from "~~/utils/diceDemo/apiUtils"; +import { kickPlayer, pauseResumeGame, toggleMode, varyHiddenPrivatekey } from "~~/utils/diceDemo/apiUtils"; import { calculateLength, compareResult, generateRandomHex } from "~~/utils/diceDemo/gameUtils"; function GamePage() { @@ -357,9 +362,31 @@ function GamePage() {

      PRIVATE KEY

      -

      - {Object.values(game?.hiddenPrivateKey)} -

      +
      +

      + {Object.values(game?.hiddenPrivateKey)} +

      +
      + + +
      +
      )}
      @@ -387,9 +414,31 @@ function GamePage() {

      PRIVATE KEY

      -

      - {Object.values(game?.hiddenPrivateKey)} -

      +
      +

      + {Object.values(game?.hiddenPrivateKey)} +

      +
      + + +
      +
      )} diff --git a/packages/nextjs/server.config.ts b/packages/nextjs/server.config.ts index 9121921..1ff75de 100644 --- a/packages/nextjs/server.config.ts +++ b/packages/nextjs/server.config.ts @@ -1,5 +1,5 @@ const serverConfig = { - isLocal: false, + isLocal: true, localUrl: "http://localhost:6001", liveUrl: "https://rich-ruby-cygnet-tie.cyclic.app/", }; diff --git a/packages/nextjs/utils/diceDemo/apiUtils.ts b/packages/nextjs/utils/diceDemo/apiUtils.ts index 1cd33e6..9fffe0a 100644 --- a/packages/nextjs/utils/diceDemo/apiUtils.ts +++ b/packages/nextjs/utils/diceDemo/apiUtils.ts @@ -59,8 +59,49 @@ export const kickPlayer = async (game: Game, token: string, playerAddress: strin }); const responseData = await response.json(); + notification.success("Kicked " + playerAddress); if (responseData.error) { notification.error(responseData.error); return; } }; + +export const varyHiddenPrivatekey = async (game: Game, token: string, vary: "increase" | "decrease") => { + let hiddenPrivateKey = game?.hiddenPrivateKey; + const hiddenChars = game?.hiddenChars; + const privateKey = game?.privateKey; + let diceCount = game?.diceCount; + + const hiddCharsCopy = { ...hiddenChars }; + + if (vary === "increase") { + hiddenPrivateKey = "*".repeat(diceCount + 1) + privateKey.slice(diceCount + 1); + hiddCharsCopy[diceCount] = privateKey[diceCount]; + diceCount++; + } else { + hiddenPrivateKey = "*".repeat(diceCount - 1) + privateKey.slice(diceCount - 1); + delete hiddCharsCopy[diceCount - 1]; + diceCount--; + } + + if (diceCount < 1 || diceCount > 64) { + notification.error("Invalid dice count."); + return; + } + + try { + await fetch(`${serverUrl}/admin/varyhiddenprivatekey/${game?._id}`, { + method: "PATCH", + headers: { + Authorization: `Bearer ${token}`, + "Content-Type": "application/json", + }, + body: JSON.stringify({ hiddenChars: hiddCharsCopy, hiddenPrivateKey: hiddenPrivateKey, diceCount: diceCount }), + }); + + notification.success("Updated hidden characters"); + } catch (error) { + notification.error((error as Error).message); + return; + } +};