From e6c342aefe9bce945af567381e6f176cacc9642c Mon Sep 17 00:00:00 2001 From: Rui Sousa Date: Thu, 7 Nov 2024 11:30:23 +0000 Subject: [PATCH 1/2] Refactor Wordle hooks ## Why Wordle3 hooks were using a local account strucutre that had to destructure the account into `account.address` in order to separate address and private key which is not what will happen in production. ## How By refactoring the hooks' argument to stop destructuring the account as `WagmiProvider` passes the correct data structure to work as intended. --- frontend/src/App.jsx | 42 +++++++++++-------------------- frontend/src/hooks/WordleHooks.ts | 22 ++++++++-------- 2 files changed, 26 insertions(+), 38 deletions(-) diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 0d87e8f..9399c13 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -1,25 +1,24 @@ import {useEffect, useState} from 'react' import './App.css' -import {local_accounts} from './clients/testClient' +// import wordle hooks import { getAlphabet, getWDTBalance, getPlayerGuesses, - getHitmap, - canPlay, - useFaucet, initAttempts, - tryGuess + tryGuess, } from './hooks/WordleHooks' + +// import components import {Alphabet} from './components/Alphabet/Alphabet' import { GameSpace } from './components/GameSpace/GameSpace' import { ApprovalModal } from './components/ApprovalModal/ApprovalModal' import { LowFunds } from './components/LowFunds/LowFunds' import { AlreadyPlayed } from './components/AlreadyPlayed/AlreadyPlayed' -import { ConnectWallet } from './clients/walletClient/ConnectWallet' // wagmi connection +import { ConnectWallet } from './clients/walletClient/ConnectWallet' import { wagmiConfig } from '../wagmi.config' import { WagmiProvider } from 'wagmi' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' @@ -27,7 +26,6 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query' function App() { // Current account and respetive variables const [currentAddress, setCurrentAddress] = useState(undefined) - const [currentAcc, setCurrentAcc] = useState(local_accounts[0]) const [alphabet, setAlphabet] = useState(undefined) // TODO: remove after testing and prototyping @@ -46,17 +44,17 @@ function App() { // Gets the current account's WDT balance, eligibility to play, player attempts, guesses and alphabet. // this is constantly pinging the network, so i'm unsure if this is the right way to go useEffect(() => { - if (currentAcc) { - getWDTBalance(currentAcc).then(setWdtBalance) + if (currentAddress) { + getWDTBalance(currentAddress).then(setWdtBalance) - getAlphabet(currentAcc).then(res => { + getAlphabet(currentAddress).then(res => { if (res.length === 0) setIsPlaying(false) else setIsPlaying(true) setAlphabet(res) }) - getPlayerGuesses(currentAcc).then(setPlayerGuesses) + getPlayerGuesses(currentAddress).then(setPlayerGuesses) } - }, [currentAcc, playerGuesses]) + }, [currentAddress, playerGuesses]) // handle the guess input const handleGuessChange = (e) => setGuess(e.target.value) @@ -68,7 +66,7 @@ function App() { const handleInitAttempts = async (account) => { try { - const res = await initAttempts(account) + await initAttempts(account) } catch (err) { // placeholder for token faucet user flow if (err.message.includes("You don't have enough tokens to play")) { @@ -94,31 +92,21 @@ function App() {
- {/* Modals for approving transactions and messages */} - {approvalModal && setApprovalModal(false)}/>} - {lowFundsWarn && setLowFundsWarn(false)}/>} + {approvalModal && setApprovalModal(false)}/>} + {lowFundsWarn && setLowFundsWarn(false)}/>} {playedToday && setPlayedToday(false)}/>} - - {/* Playground: list accounts to experiment */} -

Here are some addresses:

-

WDT Balance: {wdtBalance ? `${wdtBalance.toString()} WDT` : '???'}

{/* Game space */} {!isPlaying ? (
- +
) : (
- +
)} diff --git a/frontend/src/hooks/WordleHooks.ts b/frontend/src/hooks/WordleHooks.ts index d3ddf88..a0a66af 100644 --- a/frontend/src/hooks/WordleHooks.ts +++ b/frontend/src/hooks/WordleHooks.ts @@ -5,36 +5,36 @@ import ERC20ABI from '../abis/ERC20ABI.json' // Get number of remaining attempts a player still has export async function getAttempts(account) { - const attempts = await wordle.read.getPlayerAttempts([account.address]) + const attempts = await wordle.read.getPlayerAttempts([account]) return attempts.toString() } // Get the current state of the player's alphabet hitmap export async function getAlphabet(account) { - return await wordle.read.getAlphabet([account.address]) + return await wordle.read.getAlphabet([account]) } // Get the current player hitmap state export async function getHitmap(account) { - return await wordle.read.getHiddenWord([account.address]) + return await wordle.read.getHiddenWord([account]) } // Gets the WDT balance of a player export async function getWDTBalance(account) { - const res = await wdt.read.balanceOf([account.address]) + const res = await wdt.read.balanceOf([account]) return formatEther(res) } // Gets player used guesses array export async function getPlayerGuesses(account) { - const res = await wordle.read.getPlayerGuesses([account.address]) + const res = await wordle.read.getPlayerGuesses([account]) return res } // Checks if a player is eligible to play export async function canPlay(account) { - return await wordle.read.canPlay([account.address]) + return await wordle.read.canPlay([account]) } // Give a player some WDT @@ -44,7 +44,7 @@ export async function useFaucet(account) { address: wordle.address, abi: WordleABI, functionName: 'tokenFaucet', - args: [account.address], + args: [account], }) await client.writeContract(request) } @@ -60,12 +60,12 @@ export async function approveGame(account) { args: [wordle.address, 200 * decimals], }) await client.writeContract(request) - const allowance = await wdt.read.allowance([account.address, wordle.address]) + const allowance = await wdt.read.allowance([account, wordle.address]) } // Initialize the player's attempts export async function initAttempts(account) { - const allowance = await wdt.read.allowance([account.address, wordle.address]) + const allowance = await wdt.read.allowance([account, wordle.address]) // simulate/validate the contract to ensure contract exists // and is valid (+info: https://viem.sh/docs/contract/writeContract) @@ -74,7 +74,7 @@ export async function initAttempts(account) { address: wordle.address, abi: WordleABI, functionName: 'initAttempts', - args: [account.address], + args: [account], }) if (request) await client.writeContract(request) @@ -92,7 +92,7 @@ export async function tryGuess(account, guess) { address: wordle.address, abi: WordleABI, functionName: 'tryGuess', - args: [guess, account.address], + args: [guess, account], }) if (request) await client.writeContract(request) From dccfcd7d4981242c290d550b700f1afaef4320e0 Mon Sep 17 00:00:00 2001 From: Rui Sousa <149320958+rccsousa@users.noreply.github.com> Date: Thu, 7 Nov 2024 12:15:42 +0000 Subject: [PATCH 2/2] fix constant network pinging (#19) ## Why The `useEffect` hook was constantly pinging the network while looking for changes in `playerGuesses` which lead excessive network requests. ## How By changing the `useEffect` to watch only for address changes and shifting the `playerGuess` update to `handleTryGuess`, which makes more sense. --- frontend/src/App.jsx | 24 +++++++++++++++--------- frontend/src/hooks/WordleHooks.ts | 2 +- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 9399c13..e8a5270 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -44,17 +44,22 @@ function App() { // Gets the current account's WDT balance, eligibility to play, player attempts, guesses and alphabet. // this is constantly pinging the network, so i'm unsure if this is the right way to go useEffect(() => { + + const getParams = async (address) => { + const balance = await getWDTBalance(address) + const alphabet = await getAlphabet(address) + const playerGuesses = await getPlayerGuesses(address) + if (alphabet.length > 0) {setIsPlaying(true)} + if (balance) setWdtBalance(balance) + if (alphabet) setAlphabet(alphabet) + if (playerGuesses) setPlayerGuesses(playerGuesses) + } + if (currentAddress) { - getWDTBalance(currentAddress).then(setWdtBalance) - - getAlphabet(currentAddress).then(res => { - if (res.length === 0) setIsPlaying(false) - else setIsPlaying(true) - setAlphabet(res) - }) - getPlayerGuesses(currentAddress).then(setPlayerGuesses) + getParams(currentAddress) } - }, [currentAddress, playerGuesses]) + + }, [currentAddress]) // handle the guess input const handleGuessChange = (e) => setGuess(e.target.value) @@ -62,6 +67,7 @@ function App() { // handle new guess const handleNewGuess = (account, guess) => { tryGuess(account, guess) + setTimeout(() => getPlayerGuesses(account).then(setPlayerGuesses), 500) } const handleInitAttempts = async (account) => { diff --git a/frontend/src/hooks/WordleHooks.ts b/frontend/src/hooks/WordleHooks.ts index a0a66af..77593fd 100644 --- a/frontend/src/hooks/WordleHooks.ts +++ b/frontend/src/hooks/WordleHooks.ts @@ -6,7 +6,7 @@ import ERC20ABI from '../abis/ERC20ABI.json' // Get number of remaining attempts a player still has export async function getAttempts(account) { const attempts = await wordle.read.getPlayerAttempts([account]) - return attempts.toString() + return formatEther(attempts) } // Get the current state of the player's alphabet hitmap