Skip to content

Commit

Permalink
Refactor Wordle hooks (#18)
Browse files Browse the repository at this point in the history
## 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.
  • Loading branch information
rccsousa authored Nov 7, 2024
1 parent 059c8ab commit 751f332
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 44 deletions.
58 changes: 26 additions & 32 deletions frontend/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,31 @@
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'

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
Expand All @@ -46,29 +44,35 @@ 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)

getAlphabet(currentAcc).then(res => {
if (res.length === 0) setIsPlaying(false)
else setIsPlaying(true)
setAlphabet(res)
})
getPlayerGuesses(currentAcc).then(setPlayerGuesses)

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) {
getParams(currentAddress)
}
}, [currentAcc, playerGuesses])

}, [currentAddress])

// handle the guess input
const handleGuessChange = (e) => setGuess(e.target.value)

// handle new guess
const handleNewGuess = (account, guess) => {
tryGuess(account, guess)
setTimeout(() => getPlayerGuesses(account).then(setPlayerGuesses), 500)
}

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")) {
Expand All @@ -94,31 +98,21 @@ function App() {
<header>
<ConnectWallet onAddressChange={setCurrentAddress} />
</header>

{/* Modals for approving transactions and messages */}
{approvalModal && <ApprovalModal account={currentAcc} close={() => setApprovalModal(false)}/>}
{lowFundsWarn && <LowFunds account={currentAcc} close={() => setLowFundsWarn(false)}/>}
{approvalModal && <ApprovalModal account={currentAddress} close={() => setApprovalModal(false)}/>}
{lowFundsWarn && <LowFunds account={currentAddress} close={() => setLowFundsWarn(false)}/>}
{playedToday && <AlreadyPlayed close={() => setPlayedToday(false)}/>}


{/* Playground: list accounts to experiment */}
<h4>Here are some addresses:</h4>
<select onChange={(e) => setCurrentAcc(local_accounts.find(a => a.address === e.target.value))}>
<option value="">Select an address</option>
{local_accounts.map((address) => (
<option key={address.address} value={address.address}>{address.address}</option>
))}
</select>
<p>WDT Balance: {wdtBalance ? `${wdtBalance.toString()} WDT` : '???'}</p>

{/* Game space */}
{!isPlaying ?
(<div className={"game-buttons"}>
<button onClick={() => handleInitAttempts(currentAcc)}>Play</button>
<button onClick={() => handleInitAttempts(currentAddress)}>Play</button>
</div>) : (
<div>
<input placeholder='Enter guess' onChange={handleGuessChange}/>
<button onClick={() => handleNewGuess(currentAcc, guess)}>Submit</button>
<button onClick={() => handleNewGuess(currentAddress, guess)}>Submit</button>
<GameSpace playerGuesses={playerGuesses}/>
<Alphabet playerAlphabet={alphabet}/>
</div>)}
Expand Down
24 changes: 12 additions & 12 deletions frontend/src/hooks/WordleHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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])
return attempts.toString()
const attempts = await wordle.read.getPlayerAttempts([account])
return formatEther(attempts)
}

// 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
Expand All @@ -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)
}
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand Down

0 comments on commit 751f332

Please sign in to comment.