diff --git a/react-wordle/config/webpack.config.js b/react-wordle/config/webpack.config.js index eee221e..5acf05d 100644 --- a/react-wordle/config/webpack.config.js +++ b/react-wordle/config/webpack.config.js @@ -303,6 +303,8 @@ module.exports = function (webpackEnv) { fallback: { 'tfhe_bg.wasm': require.resolve('tfhe/tfhe_bg.wasm'), "buffer": require.resolve('buffer'), + "crypto": require.resolve("crypto-browserify"), + "stream": require.resolve("stream-browserify"), }, // These are the reasonable defaults supported by the Node ecosystem. // We also include JSX as a common component filename extension to support diff --git a/react-wordle/package.json b/react-wordle/package.json index f2ec4ac..ff5cbf1 100644 --- a/react-wordle/package.json +++ b/react-wordle/package.json @@ -37,6 +37,7 @@ "camelcase": "^6.2.1", "case-sensitive-paths-webpack-plugin": "^2.4.0", "classnames": "^2.3.1", + "crypto-browserify": "^3.12.0", "css-loader": "^6.5.1", "css-minimizer-webpack-plugin": "^3.2.0", "date-fns": "^2.29.1", @@ -78,6 +79,7 @@ "sass-loader": "^12.3.0", "semver": "^7.3.5", "source-map-loader": "^3.0.0", + "stream-browserify": "^3.0.0", "style-loader": "^3.3.1", "tailwindcss": "^3.0.2", "terser-webpack-plugin": "^5.2.5", @@ -113,6 +115,7 @@ "@trivago/prettier-plugin-sort-imports": "^4.2.0", "@types/react-datepicker": "^4.4.2", "autoprefixer": "^10.4.15", + "gh-pages": "^6.1.0", "lint-staged": "^13.2.2", "postcss": "^8.4.5", "prettier": "^3.0.3", @@ -179,5 +182,6 @@ "presets": [ "react-app" ] - } + }, + "homepage": "https://kroist.github.io/encryptedWords" } diff --git a/react-wordle/src/App.tsx b/react-wordle/src/App.tsx index de9818d..20287d9 100644 --- a/react-wordle/src/App.tsx +++ b/react-wordle/src/App.tsx @@ -1,123 +1,73 @@ import './App.css' import { ClockIcon } from '@heroicons/react/outline' +import { useSDK } from '@metamask/sdk-react-ui' import { format } from 'date-fns' import { default as GraphemeSplitter } from 'grapheme-splitter' import { useEffect, useState } from 'react' import Div100vh from 'react-div-100vh' -import { useSDK } from '@metamask/sdk-react-ui'; import { AlertContainer } from './components/alerts/AlertContainer' import { Grid } from './components/grid/Grid' import { Keyboard } from './components/keyboard/Keyboard' -import { DatePickerModal } from './components/modals/DatePickerModal' import { InfoModal } from './components/modals/InfoModal' -import { MigrateStatsModal } from './components/modals/MigrateStatsModal' -import { SettingsModal } from './components/modals/SettingsModal' -import { StatsModal } from './components/modals/StatsModal' import { Navbar } from './components/navbar/Navbar' import { DATE_LOCALE, DISCOURAGE_INAPP_BROWSERS, - LONG_ALERT_TIME_MS, MAX_CHALLENGES, REVEAL_TIME_MS, - WELCOME_INFO_MODAL_MS, } from './constants/settings' import { - CORRECT_WORD_MESSAGE, DISCOURAGE_INAPP_BROWSER_TEXT, - GAME_COPIED_MESSAGE, - HARD_MODE_ALERT_MESSAGE, NOT_ENOUGH_LETTERS_MESSAGE, - SHARE_FAILURE_TEXT, WIN_MESSAGES, WORD_NOT_FOUND_MESSAGE, } from './constants/strings' import { useAlert } from './context/AlertContext' -import { isInAppBrowser } from './lib/browser' import { - getStoredIsHighContrastMode, - loadGameStateFromLocalStorage, - saveGameStateToLocalStorage, - setStoredIsHighContrastMode, -} from './lib/localStorage' -import { addStatsForCompletedGame, loadStats } from './lib/stats' + getGuesses, + getIsGameStarted, + guessWord, + initFHE, +} from './lib/blockchain' +import { isInAppBrowser } from './lib/browser' +import { getGuessStatuses } from './lib/statuses' import { - findFirstUnusedReveal, getGameDate, getIsLatestGame, - isWinningWord, isWordInWordList, - setGameDate, solution, - solutionGameDate, unicodeLength, } from './lib/words' -import { - initFHE, - getIsGameFinished, - getIsGameStarted, - guessWord, - getGuesses -} from './lib/blockchain' -import { getGuessStatuses } from './lib/statuses' - function App() { const isLatestGame = getIsLatestGame() const gameDate = getGameDate() - const prefersDarkMode = window.matchMedia( - '(prefers-color-scheme: dark)' - ).matches - const { showError: showErrorAlert, showSuccess: showSuccessAlert } = useAlert() - const [isFhevmInitialized, setFhevmInitialized] = useState(false); + const [isFhevmInitialized, setFhevmInitialized] = useState(false) const [currentGuess, setCurrentGuess] = useState('') const [isGameWon, setIsGameWon] = useState(false) const [isGameStarted, setIsGameStarted] = useState(false) - const [isGameFinished, setIsGameFinished] = useState(false) const [isInfoModalOpen, setIsInfoModalOpen] = useState(false) - const [isStatsModalOpen, setIsStatsModalOpen] = useState(false) - const [isDatePickerModalOpen, setIsDatePickerModalOpen] = useState(false) - const [isMigrateStatsModalOpen, setIsMigrateStatsModalOpen] = useState(false) - const [isSettingsModalOpen, setIsSettingsModalOpen] = useState(false) const [currentRowClass, setCurrentRowClass] = useState('') - const [isGameLost, setIsGameLost] = useState(false) - const [isDarkMode, setIsDarkMode] = useState( - localStorage.getItem('theme') - ? localStorage.getItem('theme') === 'dark' - : prefersDarkMode - ? true - : false - ) - const [isHighContrastMode, setIsHighContrastMode] = useState( - getStoredIsHighContrastMode() - ) - const [isRevealing, setIsRevealing] = useState(false) - const [guesses, setGuesses] = useState<[string,number,number][]>(() => { - const arr: [string, number, number][] = []; - return arr; - }); - - const [stats, setStats] = useState(() => loadStats()) + const isRevealing = false + const [guesses, setGuesses] = useState<[string, number, number][]>(() => { + const arr: [string, number, number][] = [] + return arr + }) - const [isHardMode, setIsHardMode] = useState( - localStorage.getItem('gameMode') - ? localStorage.getItem('gameMode') === 'hard' - : false - ) - const { sdk, connected, connecting, provider, chainId } = useSDK(); + const { provider } = useSDK() useEffect(() => { - const changeChain = async() => { + const changeChain = async () => { try { await provider?.request({ method: 'wallet_switchEthereumChain', params: [{ chainId: '0x1F49' }], - }); + }) } catch (switchError: any) { // This error code indicates that the chain has not been added to MetaMask. if (switchError.code === 4902) { @@ -134,10 +84,10 @@ function App() { decimals: 18, name: 'ZAMA', symbol: 'ZAMA', - } + }, }, ], - }); + }) } catch (addError) { // handle "add" error } @@ -145,57 +95,40 @@ function App() { // handle other "switch" errors } } - changeChain(); + changeChain() }) useEffect(() => { - console.log("HERE"); - initFHE(provider!).then(() => { - console.log("INITED"); - setFhevmInitialized(true); - }) - .catch(() => setFhevmInitialized(false)); - }, [provider]); - - useEffect(() => { - getIsGameFinished().then(res => { - setIsGameFinished(res); - }) - }, [isFhevmInitialized]) + console.log('HERE') + initFHE(provider!) + .then(() => { + console.log('INITED') + setFhevmInitialized(true) + }) + .catch(() => setFhevmInitialized(false)) + }, [provider]) useEffect(() => { - console.log("IS GAME STARTED"); - getIsGameStarted().then(res => { - console.log(res); - setIsGameStarted(res); + console.log('IS GAME STARTED') + getIsGameStarted().then((res) => { + console.log(res) + setIsGameStarted(res) }) }, [isFhevmInitialized]) useEffect(() => { if (isFhevmInitialized) { - getGuesses([]) - .then(curGuesses => { - setGuesses(curGuesses); + getGuesses([]).then((curGuesses) => { + setGuesses(curGuesses) if (curGuesses.length > 0) { - let statuses = getGuessStatuses(curGuesses.at(curGuesses.length-1)!); - if (statuses.filter(val => val === "correct").length === 5) { - setIsGameWon(true); + let statuses = getGuessStatuses(curGuesses.at(curGuesses.length - 1)!) + if (statuses.filter((val) => val === 'correct').length === 5) { + setIsGameWon(true) } } }) } - }, [isFhevmInitialized]); - - - useEffect(() => { - // if no game state on load, - // show the user the how-to info modal - if (!loadGameStateFromLocalStorage(true)) { - setTimeout(() => { - setIsInfoModalOpen(true) - }, WELCOME_INFO_MODAL_MS) - } - }) + }, [isFhevmInitialized]) useEffect(() => { DISCOURAGE_INAPP_BROWSERS && @@ -207,28 +140,9 @@ function App() { }, [showErrorAlert]) useEffect(() => { - if (isDarkMode) { - document.documentElement.classList.add('dark') - } else { - document.documentElement.classList.remove('dark') - } - - if (isHighContrastMode) { - document.documentElement.classList.add('high-contrast') - } else { - document.documentElement.classList.remove('high-contrast') - } - }, [isDarkMode, isHighContrastMode]) - - const handleDarkMode = (isDark: boolean) => { - setIsDarkMode(isDark) - localStorage.setItem('theme', isDark ? 'dark' : 'light') - } - - const handleHighContrastMode = (isHighContrast: boolean) => { - setIsHighContrastMode(isHighContrast) - setStoredIsHighContrastMode(isHighContrast) - } + document.documentElement.classList.remove('dark') + document.documentElement.classList.remove('high-contrast') + }) const clearCurrentRowClass = () => { setCurrentRowClass('') @@ -241,20 +155,11 @@ function App() { const delayMs = REVEAL_TIME_MS * solution.length showSuccessAlert(winMessage, { - delayMs, - onClose: () => setIsStatsModalOpen(true), + delayMs }) } - if (isGameLost) { - setTimeout( - () => { - setIsStatsModalOpen(true) - }, - (solution.length + 1) * REVEAL_TIME_MS - ) - } - }, [isGameWon, isGameLost, showSuccessAlert]) + }, [isGameWon, showSuccessAlert]) const onChar = (value: string) => { if ( @@ -273,7 +178,7 @@ function App() { } const onEnter = async () => { - if (isGameWon || isGameLost) { + if (isGameWon) { return } @@ -291,55 +196,18 @@ function App() { }) } - // setIsRevealing(true) - // // turn this back off after all - // // chars have been revealed - // setTimeout(() => { - // setIsRevealing(false) - // }, REVEAL_TIME_MS * solution.length) - - await guessWord(currentGuess); - const curGuesses = await getGuesses(guesses); - console.log("kek ", curGuesses); - setGuesses(curGuesses); - setCurrentGuess(''); - let isFinished = await getIsGameFinished(); - setIsGameFinished(isFinished); - let statuses = getGuessStatuses(curGuesses.at(curGuesses.length-1)!); - if (statuses.filter(val => val === "correct").length === 5) { - setIsGameWon(true); + await guessWord(currentGuess) + const curGuesses = await getGuesses(guesses) + console.log('kek ', curGuesses) + setGuesses(curGuesses) + setCurrentGuess('') + let statuses = getGuessStatuses(curGuesses.at(curGuesses.length - 1)!) + if (statuses.filter((val) => val === 'correct').length === 5) { + setIsGameWon(true) } - - // if ( - // unicodeLength(currentGuess) === solution.length && - // guesses.length < MAX_CHALLENGES && - // !isGameWon - // ) { - // setGuesses([...guesses, currentGuess]) - // setCurrentGuess('') - - // if (winningWord) { - // if (isLatestGame) { - // setStats(addStatsForCompletedGame(stats, guesses.length)) - // } - // return setIsGameWon(true) - // } - - // if (guesses.length === MAX_CHALLENGES - 1) { - // if (isLatestGame) { - // setStats(addStatsForCompletedGame(stats, guesses.length + 1)) - // } - // setIsGameLost(true) - // showErrorAlert(CORRECT_WORD_MESSAGE(solution), { - // persist: true, - // delayMs: REVEAL_TIME_MS * solution.length + 1, - // }) - // } - // } } - if (!isFhevmInitialized) - return null; + if (!isFhevmInitialized) return null return ( @@ -363,11 +231,8 @@ function App() { )}
- - { - isGameStarted && - ( -
+ {isGameStarted && ( +
-
- ) - } -

If you are not seeing some updates, refresh the page! The state is fully saved on blockchain

+
+ )} +

+ If you are not seeing some updates, refresh the page! The state is + fully saved on blockchain +

setIsInfoModalOpen(false)} diff --git a/react-wordle/src/components/grid/Grid.tsx b/react-wordle/src/components/grid/Grid.tsx index cb54eeb..92dcb33 100644 --- a/react-wordle/src/components/grid/Grid.tsx +++ b/react-wordle/src/components/grid/Grid.tsx @@ -4,7 +4,7 @@ import { CurrentRow } from './CurrentRow' import { EmptyRow } from './EmptyRow' type Props = { - guesses: [string,number,number][] + guesses: [string, number, number][] currentGuess: string isRevealing?: boolean currentRowClassName: string diff --git a/react-wordle/src/components/keyboard/Keyboard.tsx b/react-wordle/src/components/keyboard/Keyboard.tsx index 7563687..c6f075b 100644 --- a/react-wordle/src/components/keyboard/Keyboard.tsx +++ b/react-wordle/src/components/keyboard/Keyboard.tsx @@ -1,7 +1,6 @@ import { useEffect } from 'react' import { DELETE_TEXT, ENTER_TEXT } from '../../constants/strings' -import { getStatuses } from '../../lib/statuses' import { localeAwareUpperCase } from '../../lib/words' import { Key } from './Key' @@ -12,13 +11,8 @@ type Props = { isRevealing?: boolean } -export const Keyboard = ({ - onChar, - onDelete, - onEnter, - isRevealing, -}: Props) => { - const charStatuses: {[key: string]: string} = {}; +export const Keyboard = ({ onChar, onDelete, onEnter, isRevealing }: Props) => { + const charStatuses: { [key: string]: string } = {} const onClick = (value: string) => { if (value === 'ENTER') { diff --git a/react-wordle/src/components/modals/InfoModal.tsx b/react-wordle/src/components/modals/InfoModal.tsx index 1261732..275d678 100644 --- a/react-wordle/src/components/modals/InfoModal.tsx +++ b/react-wordle/src/components/modals/InfoModal.tsx @@ -56,72 +56,68 @@ export const InfoModal = ({ isOpen, handleClose }: Props) => {

The letter U is not in the word in any spot.

-

Controls:

+

+ Controls: +

to start/restart game (2 transactions)

to set the secret word (call to relayer)

to check if you won

update your score

- ) } diff --git a/react-wordle/src/components/navbar/Navbar.tsx b/react-wordle/src/components/navbar/Navbar.tsx index 7295960..558fc0d 100644 --- a/react-wordle/src/components/navbar/Navbar.tsx +++ b/react-wordle/src/components/navbar/Navbar.tsx @@ -1,28 +1,23 @@ import { - CalendarIcon, - ChartBarIcon, - CogIcon, InformationCircleIcon, } from '@heroicons/react/outline' - +import { SDKProvider } from '@metamask/sdk' import { useEffect, useState } from 'react' -import { ENABLE_ARCHIVED_GAMES } from '../../constants/settings' + import { GAME_TITLE } from '../../constants/strings' -import { MetaMaskButton } from "@metamask/sdk-react-ui"; -import { SDKProvider } from '@metamask/sdk'; -import { - startNewGame, +import { useAlert } from '../../context/AlertContext' +import { callRelayerForWord, - getIsGameCreated, - getIsWordIdSet, - setId, claimWin, getIsGameClaimed, - mintWinToken, + getIsGameCreated, + getIsWordIdSet, getWinTokens, - revealWord -} from '../../lib/blockchain'; -import { useAlert } from '../../context/AlertContext'; + mintWinToken, + revealWord, + setId, + startNewGame, +} from '../../lib/blockchain' type Props = { setIsInfoModalOpen: (value: boolean) => void @@ -41,39 +36,39 @@ export const Navbar = ({ isGameWon, guesses, }: Props) => { - const [isFirstTxGameCreate, setIsFirstTxGameCreate] = useState(false); - const [isSecondTxGameCreate, setIsSecondTxGameCreate] = useState(false); - const [isGameCreated, setIsGameCreated] = useState(false); - const [isWordIdSet, setIsWordIdSet] = useState(false); - const [isGameClaimed, setIsGameClaimed] = useState(false); - const [winTokens, setWinTokens] = useState(0); + const [isFirstTxGameCreate, setIsFirstTxGameCreate] = useState(false) + const [isSecondTxGameCreate, setIsSecondTxGameCreate] = useState(false) + const [isGameCreated, setIsGameCreated] = useState(false) + const [isWordIdSet, setIsWordIdSet] = useState(false) + const [isGameClaimed, setIsGameClaimed] = useState(false) + const [winTokens, setWinTokens] = useState(0) const { showError: showErrorAlert, showSuccess: showSuccessAlert } = useAlert() useEffect(() => { - getIsGameCreated().then(res => { - setIsGameCreated(res); + getIsGameCreated().then((res) => { + setIsGameCreated(res) }) }) useEffect(() => { - getIsWordIdSet().then(res => { - setIsWordIdSet(res); + getIsWordIdSet().then((res) => { + setIsWordIdSet(res) }) }) useEffect(() => { - getIsGameClaimed().then(res => { - setIsGameClaimed(res); + getIsGameClaimed().then((res) => { + setIsGameClaimed(res) }) }) useEffect(() => { - getWinTokens().then(res => { - setWinTokens(res); + getWinTokens().then((res) => { + setWinTokens(res) }) }) - + return (
@@ -84,156 +79,145 @@ export const Navbar = ({ /> - { - (isGameCreated && isWordIdSet && !isGameStarted) && + {isGameCreated && isWordIdSet && !isGameStarted && ( - } - { - (isGameWon && !isGameClaimed) && + )} + {isGameWon && !isGameClaimed && ( - } - { - (isGameClaimed) && + )} + {isGameClaimed && ( - } - { - (guesses.length === 5 && !isGameWon) && + )} + {guesses.length === 5 && !isGameWon && ( - } + )}

{GAME_TITLE}

-

Games won: {winTokens}

+

+ Games won: {winTokens} +

{/*
diff --git a/react-wordle/src/index.tsx b/react-wordle/src/index.tsx index 362ccc9..78d0936 100644 --- a/react-wordle/src/index.tsx +++ b/react-wordle/src/index.tsx @@ -1,23 +1,27 @@ import './index.css' +import { MetaMaskUIProvider } from '@metamask/sdk-react-ui' import React from 'react' import ReactDOM from 'react-dom' import App from './App' import { AlertProvider } from './context/AlertContext' import reportWebVitals from './reportWebVitals' -import { MetaMaskUIProvider } from '@metamask/sdk-react-ui'; ReactDOM.render( - + diff --git a/react-wordle/src/lib/blockchain.ts b/react-wordle/src/lib/blockchain.ts index 25350ab..5d146f1 100644 --- a/react-wordle/src/lib/blockchain.ts +++ b/react-wordle/src/lib/blockchain.ts @@ -1,1088 +1,1133 @@ -import { AbiCoder, BrowserProvider, Contract } from "ethers"; -import { providers, utils } from "ethers"; -import { initFhevm, createInstance, FhevmInstance } from "fhevmjs/web"; -import { SDKProvider } from '@metamask/sdk'; -import { wordAtIdToNumber, numberToWord } from "./words"; - +import { SDKProvider } from '@metamask/sdk' +import { Contract } from 'ethers' +import { providers, utils } from 'ethers' +import { FhevmInstance, createInstance, initFhevm } from 'fhevmjs/web' + +import { numberToWord, wordAtIdToNumber } from './words' + const factoryContractAbi = [ { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" + inputs: [], + stateMutability: 'nonpayable', + type: 'constructor', }, { - "inputs": [], - "name": "InvalidShortString", - "type": "error" + inputs: [], + name: 'InvalidShortString', + type: 'error', }, { - "inputs": [ + inputs: [ { - "internalType": "string", - "name": "str", - "type": "string" - } + internalType: 'string', + name: 'str', + type: 'string', + }, ], - "name": "StringTooLong", - "type": "error" + name: 'StringTooLong', + type: 'error', }, { - "anonymous": false, - "inputs": [], - "name": "EIP712DomainChanged", - "type": "event" + anonymous: false, + inputs: [], + name: 'EIP712DomainChanged', + type: 'event', }, { - "inputs": [ + inputs: [ { - "internalType": "address", - "name": "", - "type": "address" - } + internalType: 'address', + name: '', + type: 'address', + }, ], - "name": "claimedWin", - "outputs": [ + name: 'claimedWin', + outputs: [ { - "internalType": "bool", - "name": "", - "type": "bool" - } + internalType: 'bool', + name: '', + type: 'bool', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "address", - "name": "_relayerAddr", - "type": "address" - } + internalType: 'address', + name: '_relayerAddr', + type: 'address', + }, ], - "name": "createGame", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + name: 'createGame', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "address", - "name": "_relayerAddr", - "type": "address" - } + internalType: 'address', + name: '_relayerAddr', + type: 'address', + }, ], - "name": "createTest", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + name: 'createTest', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', }, { - "inputs": [], - "name": "creator", - "outputs": [ + inputs: [], + name: 'creator', + outputs: [ { - "internalType": "address", - "name": "", - "type": "address" - } + internalType: 'address', + name: '', + type: 'address', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [], - "name": "eip712Domain", - "outputs": [ + inputs: [], + name: 'eip712Domain', + outputs: [ { - "internalType": "bytes1", - "name": "fields", - "type": "bytes1" + internalType: 'bytes1', + name: 'fields', + type: 'bytes1', }, { - "internalType": "string", - "name": "name", - "type": "string" + internalType: 'string', + name: 'name', + type: 'string', }, { - "internalType": "string", - "name": "version", - "type": "string" + internalType: 'string', + name: 'version', + type: 'string', }, { - "internalType": "uint256", - "name": "chainId", - "type": "uint256" + internalType: 'uint256', + name: 'chainId', + type: 'uint256', }, { - "internalType": "address", - "name": "verifyingContract", - "type": "address" + internalType: 'address', + name: 'verifyingContract', + type: 'address', }, { - "internalType": "bytes32", - "name": "salt", - "type": "bytes32" + internalType: 'bytes32', + name: 'salt', + type: 'bytes32', }, { - "internalType": "uint256[]", - "name": "extensions", - "type": "uint256[]" - } + internalType: 'uint256[]', + name: 'extensions', + type: 'uint256[]', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [], - "name": "gameNotStarted", - "outputs": [ + inputs: [], + name: 'gameNotStarted', + outputs: [ { - "internalType": "bool", - "name": "", - "type": "bool" - } + internalType: 'bool', + name: '', + type: 'bool', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "address", - "name": "", - "type": "address" - } + internalType: 'address', + name: '', + type: 'address', + }, ], - "name": "gamesWon", - "outputs": [ + name: 'gamesWon', + outputs: [ { - "internalType": "uint32", - "name": "", - "type": "uint32" - } + internalType: 'uint32', + name: '', + type: 'uint32', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [], - "name": "mint", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + inputs: [], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "address", - "name": "", - "type": "address" - } + internalType: 'address', + name: '', + type: 'address', + }, ], - "name": "userLastContract", - "outputs": [ + name: 'userLastContract', + outputs: [ { - "internalType": "address", - "name": "", - "type": "address" - } + internalType: 'address', + name: '', + type: 'address', + }, ], - "stateMutability": "view", - "type": "function" - } -]; -const contractAbi = -[ + stateMutability: 'view', + type: 'function', + }, +] +const contractAbi = [ { - "inputs": [ + inputs: [ { - "internalType": "address", - "name": "_playerAddr", - "type": "address" + internalType: 'address', + name: '_playerAddr', + type: 'address', }, { - "internalType": "address", - "name": "_relayerAddr", - "type": "address" + internalType: 'address', + name: '_relayerAddr', + type: 'address', }, { - "internalType": "uint16", - "name": "_word1Id", - "type": "uint16" + internalType: 'uint16', + name: '_word1Id', + type: 'uint16', }, { - "internalType": "bytes32", - "name": "_root", - "type": "bytes32" + internalType: 'bytes32', + name: '_root', + type: 'bytes32', }, { - "internalType": "uint16", - "name": "_wordSetSz", - "type": "uint16" - } + internalType: 'uint16', + name: '_wordSetSz', + type: 'uint16', + }, ], - "stateMutability": "nonpayable", - "type": "constructor" + stateMutability: 'nonpayable', + type: 'constructor', }, { - "inputs": [], - "name": "InvalidShortString", - "type": "error" + inputs: [], + name: 'InvalidShortString', + type: 'error', }, { - "inputs": [ + inputs: [ { - "internalType": "string", - "name": "str", - "type": "string" - } + internalType: 'string', + name: 'str', + type: 'string', + }, ], - "name": "StringTooLong", - "type": "error" + name: 'StringTooLong', + type: 'error', }, { - "anonymous": false, - "inputs": [], - "name": "EIP712DomainChanged", - "type": "event" + anonymous: false, + inputs: [], + name: 'EIP712DomainChanged', + type: 'event', }, { - "inputs": [], - "name": "checkProof", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + inputs: [], + name: 'checkProof', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "uint8", - "name": "guessN", - "type": "uint8" - } + internalType: 'uint8', + name: 'guessN', + type: 'uint8', + }, ], - "name": "claimWin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + name: 'claimWin', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', }, { - "inputs": [], - "name": "eip712Domain", - "outputs": [ + inputs: [], + name: 'eip712Domain', + outputs: [ { - "internalType": "bytes1", - "name": "fields", - "type": "bytes1" + internalType: 'bytes1', + name: 'fields', + type: 'bytes1', }, { - "internalType": "string", - "name": "name", - "type": "string" + internalType: 'string', + name: 'name', + type: 'string', }, { - "internalType": "string", - "name": "version", - "type": "string" + internalType: 'string', + name: 'version', + type: 'string', }, { - "internalType": "uint256", - "name": "chainId", - "type": "uint256" + internalType: 'uint256', + name: 'chainId', + type: 'uint256', }, { - "internalType": "address", - "name": "verifyingContract", - "type": "address" + internalType: 'address', + name: 'verifyingContract', + type: 'address', }, { - "internalType": "bytes32", - "name": "salt", - "type": "bytes32" + internalType: 'bytes32', + name: 'salt', + type: 'bytes32', }, { - "internalType": "uint256[]", - "name": "extensions", - "type": "uint256[]" - } + internalType: 'uint256[]', + name: 'extensions', + type: 'uint256[]', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "uint256", - "name": "", - "type": "uint256" - } + internalType: 'uint256', + name: '', + type: 'uint256', + }, ], - "name": "eqMaskGuess", - "outputs": [ + name: 'eqMaskGuess', + outputs: [ { - "internalType": "euint8", - "name": "", - "type": "uint256" - } + internalType: 'euint8', + name: '', + type: 'uint256', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [], - "name": "gameStarted", - "outputs": [ + inputs: [], + name: 'gameStarted', + outputs: [ { - "internalType": "bool", - "name": "", - "type": "bool" - } + internalType: 'bool', + name: '', + type: 'bool', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "uint8", - "name": "guessN", - "type": "uint8" + internalType: 'uint8', + name: 'guessN', + type: 'uint8', }, { - "internalType": "bytes32", - "name": "publicKey", - "type": "bytes32" + internalType: 'bytes32', + name: 'publicKey', + type: 'bytes32', }, { - "internalType": "bytes", - "name": "signature", - "type": "bytes" - } + internalType: 'bytes', + name: 'signature', + type: 'bytes', + }, ], - "name": "getGuess", - "outputs": [ + name: 'getGuess', + outputs: [ { - "internalType": "bytes", - "name": "", - "type": "bytes" + internalType: 'bytes', + name: '', + type: 'bytes', }, { - "internalType": "bytes", - "name": "", - "type": "bytes" - } + internalType: 'bytes', + name: '', + type: 'bytes', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "uint8", - "name": "guessN", - "type": "uint8" + internalType: 'uint8', + name: 'guessN', + type: 'uint8', }, { - "internalType": "uint8", - "name": "letterN", - "type": "uint8" + internalType: 'uint8', + name: 'letterN', + type: 'uint8', }, { - "internalType": "bytes32", - "name": "publicKey", - "type": "bytes32" + internalType: 'bytes32', + name: 'publicKey', + type: 'bytes32', }, { - "internalType": "bytes", - "name": "signature", - "type": "bytes" - } + internalType: 'bytes', + name: 'signature', + type: 'bytes', + }, ], - "name": "getLetterGuess", - "outputs": [ + name: 'getLetterGuess', + outputs: [ { - "internalType": "bytes", - "name": "", - "type": "bytes" - } + internalType: 'bytes', + name: '', + type: 'bytes', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "bytes32", - "name": "publicKey", - "type": "bytes32" + internalType: 'bytes32', + name: 'publicKey', + type: 'bytes32', }, { - "internalType": "bytes", - "name": "signature", - "type": "bytes" - } + internalType: 'bytes', + name: 'signature', + type: 'bytes', + }, ], - "name": "getWord1Id", - "outputs": [ + name: 'getWord1Id', + outputs: [ { - "internalType": "bytes", - "name": "", - "type": "bytes" - } + internalType: 'bytes', + name: '', + type: 'bytes', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "bytes", - "name": "el0", - "type": "bytes" + internalType: 'bytes', + name: 'el0', + type: 'bytes', }, { - "internalType": "bytes", - "name": "el1", - "type": "bytes" + internalType: 'bytes', + name: 'el1', + type: 'bytes', }, { - "internalType": "bytes", - "name": "el2", - "type": "bytes" + internalType: 'bytes', + name: 'el2', + type: 'bytes', }, { - "internalType": "bytes", - "name": "el3", - "type": "bytes" + internalType: 'bytes', + name: 'el3', + type: 'bytes', }, { - "internalType": "bytes", - "name": "el4", - "type": "bytes" + internalType: 'bytes', + name: 'el4', + type: 'bytes', }, { - "internalType": "bytes", - "name": "eMask", - "type": "bytes" - } + internalType: 'bytes', + name: 'eMask', + type: 'bytes', + }, ], - "name": "guessWord1", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + name: 'guessWord1', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "euint16", - "name": "l0", - "type": "uint256" + internalType: 'euint16', + name: 'l0', + type: 'uint256', }, { - "internalType": "euint16", - "name": "l1", - "type": "uint256" + internalType: 'euint16', + name: 'l1', + type: 'uint256', }, { - "internalType": "euint16", - "name": "l2", - "type": "uint256" + internalType: 'euint16', + name: 'l2', + type: 'uint256', }, { - "internalType": "euint16", - "name": "l3", - "type": "uint256" + internalType: 'euint16', + name: 'l3', + type: 'uint256', }, { - "internalType": "euint16", - "name": "l4", - "type": "uint256" + internalType: 'euint16', + name: 'l4', + type: 'uint256', }, { - "internalType": "euint32", - "name": "letterMask", - "type": "uint256" - } + internalType: 'euint32', + name: 'letterMask', + type: 'uint256', + }, ], - "name": "guessWord1", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + name: 'guessWord1', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "uint256", - "name": "", - "type": "uint256" - } + internalType: 'uint256', + name: '', + type: 'uint256', + }, ], - "name": "letterMaskGuess", - "outputs": [ + name: 'letterMaskGuess', + outputs: [ { - "internalType": "euint32", - "name": "", - "type": "uint256" - } + internalType: 'euint32', + name: '', + type: 'uint256', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "uint256", - "name": "", - "type": "uint256" + internalType: 'uint256', + name: '', + type: 'uint256', }, { - "internalType": "uint256", - "name": "", - "type": "uint256" - } + internalType: 'uint256', + name: '', + type: 'uint256', + }, ], - "name": "letterMaskGuessHist", - "outputs": [ + name: 'letterMaskGuessHist', + outputs: [ { - "internalType": "euint16", - "name": "", - "type": "uint256" - } + internalType: 'euint16', + name: '', + type: 'uint256', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [], - "name": "nGuesses", - "outputs": [ + inputs: [], + name: 'nGuesses', + outputs: [ { - "internalType": "uint8", - "name": "", - "type": "uint8" - } + internalType: 'uint8', + name: '', + type: 'uint8', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [], - "name": "playerAddr", - "outputs": [ + inputs: [], + name: 'playerAddr', + outputs: [ { - "internalType": "address", - "name": "", - "type": "address" - } + internalType: 'address', + name: '', + type: 'address', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [], - "name": "playerWon", - "outputs": [ + inputs: [], + name: 'playerWon', + outputs: [ { - "internalType": "bool", - "name": "", - "type": "bool" - } + internalType: 'bool', + name: '', + type: 'bool', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [], - "name": "proofChecked", - "outputs": [ + inputs: [], + name: 'proofChecked', + outputs: [ { - "internalType": "bool", - "name": "", - "type": "bool" - } + internalType: 'bool', + name: '', + type: 'bool', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [], - "name": "relayerAddr", - "outputs": [ + inputs: [], + name: 'relayerAddr', + outputs: [ { - "internalType": "address", - "name": "", - "type": "address" - } + internalType: 'address', + name: '', + type: 'address', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [], - "name": "revealWord", - "outputs": [ + inputs: [], + name: 'revealWord', + outputs: [ { - "internalType": "uint16", - "name": "", - "type": "uint16" + internalType: 'uint16', + name: '', + type: 'uint16', }, { - "internalType": "uint16", - "name": "", - "type": "uint16" + internalType: 'uint16', + name: '', + type: 'uint16', }, { - "internalType": "uint16", - "name": "", - "type": "uint16" + internalType: 'uint16', + name: '', + type: 'uint16', }, { - "internalType": "uint16", - "name": "", - "type": "uint16" + internalType: 'uint16', + name: '', + type: 'uint16', }, { - "internalType": "uint16", - "name": "", - "type": "uint16" - } + internalType: 'uint16', + name: '', + type: 'uint16', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [], - "name": "revealWordAndStore", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + inputs: [], + name: 'revealWordAndStore', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', }, { - "inputs": [], - "name": "setWord1Id", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + inputs: [], + name: 'setWord1Id', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "bytes32[]", - "name": "_proof", - "type": "bytes32[]" - } + internalType: 'bytes32[]', + name: '_proof', + type: 'bytes32[]', + }, ], - "name": "submitProof", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + name: 'submitProof', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "bytes", - "name": "el0", - "type": "bytes" + internalType: 'bytes', + name: 'el0', + type: 'bytes', }, { - "internalType": "bytes", - "name": "el1", - "type": "bytes" + internalType: 'bytes', + name: 'el1', + type: 'bytes', }, { - "internalType": "bytes", - "name": "el2", - "type": "bytes" + internalType: 'bytes', + name: 'el2', + type: 'bytes', }, { - "internalType": "bytes", - "name": "el3", - "type": "bytes" + internalType: 'bytes', + name: 'el3', + type: 'bytes', }, { - "internalType": "bytes", - "name": "el4", - "type": "bytes" + internalType: 'bytes', + name: 'el4', + type: 'bytes', }, { - "internalType": "bytes", - "name": "eMask", - "type": "bytes" - } + internalType: 'bytes', + name: 'eMask', + type: 'bytes', + }, ], - "name": "submitWord1", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + name: 'submitWord1', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "euint16", - "name": "l0", - "type": "uint256" + internalType: 'euint16', + name: 'l0', + type: 'uint256', }, { - "internalType": "euint16", - "name": "l1", - "type": "uint256" + internalType: 'euint16', + name: 'l1', + type: 'uint256', }, { - "internalType": "euint16", - "name": "l2", - "type": "uint256" + internalType: 'euint16', + name: 'l2', + type: 'uint256', }, { - "internalType": "euint16", - "name": "l3", - "type": "uint256" + internalType: 'euint16', + name: 'l3', + type: 'uint256', }, { - "internalType": "euint16", - "name": "l4", - "type": "uint256" + internalType: 'euint16', + name: 'l4', + type: 'uint256', }, { - "internalType": "euint32", - "name": "mask", - "type": "uint256" - } + internalType: 'euint32', + name: 'mask', + type: 'uint256', + }, ], - "name": "submitWord1", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + name: 'submitWord1', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', }, { - "inputs": [], - "name": "word1", - "outputs": [ + inputs: [], + name: 'word1', + outputs: [ { - "internalType": "uint32", - "name": "", - "type": "uint32" - } + internalType: 'uint32', + name: '', + type: 'uint32', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [], - "name": "word1Id", - "outputs": [ + inputs: [], + name: 'word1Id', + outputs: [ { - "internalType": "euint16", - "name": "", - "type": "uint256" - } + internalType: 'euint16', + name: '', + type: 'uint256', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [], - "name": "word1IdSet", - "outputs": [ + inputs: [], + name: 'word1IdSet', + outputs: [ { - "internalType": "bool", - "name": "", - "type": "bool" - } + internalType: 'bool', + name: '', + type: 'bool', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [ + inputs: [ { - "internalType": "uint256", - "name": "", - "type": "uint256" - } + internalType: 'uint256', + name: '', + type: 'uint256', + }, ], - "name": "word1Letters", - "outputs": [ + name: 'word1Letters', + outputs: [ { - "internalType": "euint16", - "name": "", - "type": "uint256" - } + internalType: 'euint16', + name: '', + type: 'uint256', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [], - "name": "word1LettersMask", - "outputs": [ + inputs: [], + name: 'word1LettersMask', + outputs: [ { - "internalType": "euint32", - "name": "", - "type": "uint256" - } + internalType: 'euint32', + name: '', + type: 'uint256', + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: 'view', + type: 'function', }, { - "inputs": [], - "name": "wordSubmitted", - "outputs": [ + inputs: [], + name: 'wordSubmitted', + outputs: [ { - "internalType": "bool", - "name": "", - "type": "bool" - } + internalType: 'bool', + name: '', + type: 'bool', + }, ], - "stateMutability": "view", - "type": "function" - } -]; - -const relayerAddr = "0x95D095295182679a0187Ed1715BF636E770A3f3E"; -const factoryContractAddr = "0x67aF4754ae255Cc5A6653BBd1d602F4cD4E7668B"; + stateMutability: 'view', + type: 'function', + }, +] +// const relayerAddr = '0x95D095295182679a0187Ed1715BF636E770A3f3E' +const factoryContractAddr = '0x67aF4754ae255Cc5A6653BBd1d602F4cD4E7668B' -let fhevmInstance: FhevmInstance; -let provider: BrowserProvider; +let fhevmInstance: FhevmInstance +let provider: providers.Web3Provider const createFhevmInstance = async () => { - - const network = await provider.getNetwork(); - const chainId = +network.chainId.toString(); - const ret = await provider.call({ - // fhe lib address, may need to be changed depending on network - to: "0x000000000000000000000000000000000000005d", - // first four bytes of keccak256('fhePubKey(bytes1)') + 1 byte for library - data: "0xd9d47bb001", - }); - const decoded = utils.defaultAbiCoder.decode(["bytes"], ret); - const publicKey = decoded[0]; - return createInstance({ chainId: chainId, publicKey }); -}; + const network = await provider.getNetwork() + const chainId = +network.chainId.toString() + const ret = await provider.call({ + // fhe lib address, may need to be changed depending on network + to: '0x000000000000000000000000000000000000005d', + // first four bytes of keccak256('fhePubKey(bytes1)') + 1 byte for library + data: '0xd9d47bb001', + }) + const decoded = utils.defaultAbiCoder.decode(['bytes'], ret) + const publicKey = decoded[0] + return createInstance({ chainId: chainId, publicKey }) +} export const initFHE = async (metamaskProvider: SDKProvider) => { - provider = new providers.Web3Provider(metamaskProvider as any); - // provider = new BrowserProvider((metamaskProvider as any)); - await initFhevm(); // Load TFHE - fhevmInstance = await createFhevmInstance(); + provider = new providers.Web3Provider(metamaskProvider as any) + // provider = new BrowserProvider((metamaskProvider as any)); + await initFhevm() // Load TFHE + fhevmInstance = await createFhevmInstance() } export const getIsGameFinished = async () => { - const signer = await provider.getSigner(); - let contract = new Contract(factoryContractAddr, factoryContractAbi, signer); - let res: boolean = await contract.gameNotStarted(); - return res; + const signer = await provider.getSigner() + let contract = new Contract(factoryContractAddr, factoryContractAbi, signer) + let res: boolean = await contract.gameNotStarted() + return res } const getGameAddr = async () => { - const signer = await provider.getSigner(); - const factoryContract = new Contract(factoryContractAddr, factoryContractAbi, signer); - const contractAddr = await factoryContract.userLastContract(await signer.getAddress()); - return contractAddr; + const signer = await provider.getSigner() + const factoryContract = new Contract( + factoryContractAddr, + factoryContractAbi, + signer + ) + const contractAddr = await factoryContract.userLastContract( + await signer.getAddress() + ) + return contractAddr } const getGameContract = async () => { - const signer = await provider.getSigner(); - const contractAddr = await getGameAddr(); - const contract = new Contract(contractAddr, contractAbi, signer); - return contract; + const signer = await provider.getSigner() + const contractAddr = await getGameAddr() + const contract = new Contract(contractAddr, contractAbi, signer) + return contract } export const getIsGameCreated = async () => { - const contract = await getGameContract(); - await contract.playerAddr(); - return true; + const contract = await getGameContract() + await contract.playerAddr() + return true } export const getIsWordIdSet = async () => { - let contract = await getGameContract(); - let word1IdSet: boolean = await contract.word1IdSet(); - return word1IdSet; + let contract = await getGameContract() + let word1IdSet: boolean = await contract.word1IdSet() + return word1IdSet } export const getIsGameStarted = async () => { - let contract = await getGameContract(); - let gameStarted: boolean = await contract.gameStarted(); - return gameStarted; + let contract = await getGameContract() + let gameStarted: boolean = await contract.gameStarted() + return gameStarted } export const startNewGame = async () => { - const signer = await provider.getSigner(); - let factoryContract = new Contract(factoryContractAddr, factoryContractAbi, signer); - return factoryContract.createGame(await signer.getAddress(), { - gasLimit: 4000000, + const signer = await provider.getSigner() + let factoryContract = new Contract( + factoryContractAddr, + factoryContractAbi, + signer + ) + return factoryContract + .createGame(await signer.getAddress(), { + gasLimit: 4000000, + }) + .then((tx: any) => { + return tx.wait() + }) + .then(() => { + console.log('game created') }) - .then((tx:any) => { - return tx.wait(); - }).then(() => { - console.log("game created"); - }); - } export const setId = async () => { - - let contract = await getGameContract(); - return contract.setWord1Id({ - gasLimit: 4000000, - }).then((tx:any) => { - return tx.wait(); - }).then(() => { - console.log("word1 id set"); - }); + let contract = await getGameContract() + return contract + .setWord1Id({ + gasLimit: 4000000, + }) + .then((tx: any) => { + return tx.wait() + }) + .then(() => { + console.log('word1 id set') + }) } export const callRelayerForWord = async (metamaskProvider: SDKProvider) => { - const signer = await provider.getSigner(); - let contract = await getGameContract(); - const contractAddress = await getGameAddr(); - const encryptedParam = fhevmInstance.generateToken({ - verifyingContract: contractAddress, - }); - const signature = await signer._signTypedData( - encryptedParam.token.domain, - { Reencrypt: encryptedParam.token.types.Reencrypt }, // Need to remove EIP712Domain from types - encryptedParam.token.message, - ); - // fhevmInstance.setTokenSignature(contractAddress, signature); + const signer = await provider.getSigner() + let contract = await getGameContract() + const contractAddress = await getGameAddr() + const encryptedParam = fhevmInstance.generateToken({ + verifyingContract: contractAddress, + }) + const signature = await signer._signTypedData( + encryptedParam.token.domain, + { Reencrypt: encryptedParam.token.types.Reencrypt }, // Need to remove EIP712Domain from types + encryptedParam.token.message + ) + // fhevmInstance.setTokenSignature(contractAddress, signature); - const response = await contract.getWord1Id(encryptedParam.publicKey, signature); - const word1Id: number = fhevmInstance.decrypt(contractAddress, response); - console.log("word1Id: ", word1Id); + const response = await contract.getWord1Id( + encryptedParam.publicKey, + signature + ) + const word1Id: number = fhevmInstance.decrypt(contractAddress, response) + console.log('word1Id: ', word1Id) - let word1Number: number = wordAtIdToNumber(word1Id); - const l0 = word1Number%26; - const l1 = (word1Number/26)%26; - const l2 = (word1Number/26/26)%26; - const l3 = (word1Number/26/26/26)%26; - const l4 = (word1Number/26/26/26/26)%26; - const mask = (1< { - word = word.toLowerCase(); - let contract = await getGameContract(); - const l0 = (word.charCodeAt(0)-97); - const l1 = (word.charCodeAt(1)-97); - const l2 = (word.charCodeAt(2)-97); - const l3 = (word.charCodeAt(3)-97); - const l4 = (word.charCodeAt(4)-97); - const wordNumber = l0 + 26 * (l1 + 26 * (l2 + 26 * (l3 + 26 * l4))); - const mask = (1< { - return tx.wait(); - }); - + return tx.wait() + }) } let mySignature: { - publicKey: Uint8Array; - signature: string; -}; + publicKey: Uint8Array + signature: string +} -export const getGuesses = async (prevGuesses:[string,number,number][]) => { - const signer = await provider.getSigner(); - let contract = await getGameContract(); - let contractAddress = await getGameAddr(); +export const getGuesses = async (prevGuesses: [string, number, number][]) => { + const signer = await provider.getSigner() + let contract = await getGameContract() + let contractAddress = await getGameAddr() if (!fhevmInstance.hasKeypair(contractAddress)) { - const encryptedParam = fhevmInstance.generateToken({ verifyingContract: contractAddress, - }); + }) const signature = await signer._signTypedData( - encryptedParam.token.domain, - { Reencrypt: encryptedParam.token.types.Reencrypt }, // Need to remove EIP712Domain from types - encryptedParam.token.message, - ); - mySignature = {publicKey: encryptedParam.publicKey, signature}; - fhevmInstance.setTokenSignature(contractAddress, signature); + encryptedParam.token.domain, + { Reencrypt: encryptedParam.token.types.Reencrypt }, // Need to remove EIP712Domain from types + encryptedParam.token.message + ) + mySignature = { publicKey: encryptedParam.publicKey, signature } + fhevmInstance.setTokenSignature(contractAddress, signature) // mySignature = fhevmInstance.getTokenSignature(contractAddress)!; } - const params = mySignature; - - let guessesNumber: number = await contract.nGuesses(); + const params = mySignature + + let guessesNumber: number = await contract.nGuesses() - let res: [string, number, number][] = prevGuesses; + let res: [string, number, number][] = prevGuesses for (let i = prevGuesses.length; i < guessesNumber; i++) { - const [eqMaskGuessBytes, letterMaskGuessBytes] = await contract.getGuess(i, params.publicKey, params.signature); - const eqMaskGuess: number = fhevmInstance.decrypt(contractAddress, eqMaskGuessBytes); - const letterMaskGuess: number = fhevmInstance.decrypt(contractAddress, letterMaskGuessBytes); - let word = 0; + const [eqMaskGuessBytes, letterMaskGuessBytes] = await contract.getGuess( + i, + params.publicKey, + params.signature + ) + const eqMaskGuess: number = fhevmInstance.decrypt( + contractAddress, + eqMaskGuessBytes + ) + const letterMaskGuess: number = fhevmInstance.decrypt( + contractAddress, + letterMaskGuessBytes + ) + let word = 0 for (let j = 4; j >= 0; j--) { - const letterIEnc = await contract.getLetterGuess(i, j, params.publicKey, params.signature); - const letterI = fhevmInstance.decrypt(contractAddress, letterIEnc); - word = word * 26 + letterI; + const letterIEnc = await contract.getLetterGuess( + i, + j, + params.publicKey, + params.signature + ) + const letterI = fhevmInstance.decrypt(contractAddress, letterIEnc) + word = word * 26 + letterI } - res.push([numberToWord(word), eqMaskGuess, letterMaskGuess]); + res.push([numberToWord(word), eqMaskGuess, letterMaskGuess]) } - return res; + return res } export const claimWin = async (guessN: number) => { - let contract = await getGameContract(); - return contract.claimWin(guessN, { + let contract = await getGameContract() + return contract + .claimWin(guessN, { gasLimit: 4000000, - }).then((tx:any) => { - return tx.wait(); - }).then(() => { - }); + }) + .then((tx: any) => { + return tx.wait() + }) + .then(() => {}) } export const getIsGameClaimed = async () => { - const contract = await getGameContract(); - return await contract.playerWon(); + const contract = await getGameContract() + return await contract.playerWon() } export const mintWinToken = async () => { - const signer = await provider.getSigner(); - const factoryContract = new Contract(factoryContractAddr, factoryContractAbi, signer); - const tx = await factoryContract.mint(); - await tx.wait(); + const signer = await provider.getSigner() + const factoryContract = new Contract( + factoryContractAddr, + factoryContractAbi, + signer + ) + const tx = await factoryContract.mint() + await tx.wait() } -export const getWinTokens = async() => { - const signer = await provider.getSigner(); - const factoryContract = new Contract(factoryContractAddr, factoryContractAbi, signer); - return await factoryContract.gamesWon(await signer.getAddress()); +export const getWinTokens = async () => { + const signer = await provider.getSigner() + const factoryContract = new Contract( + factoryContractAddr, + factoryContractAbi, + signer + ) + return await factoryContract.gamesWon(await signer.getAddress()) } -export const revealWord = async() => { - const contract = await getGameContract(); - const [l0, l1, l2, l3, l4] = await contract.revealWord(); - const wordNumber = l0 + 26 * (l1 + 26 * (l2 + 26 * (l3 + 26 * l4))); - const word = numberToWord(wordNumber); - return word; +export const revealWord = async () => { + const contract = await getGameContract() + const [l0, l1, l2, l3, l4] = await contract.revealWord() + const wordNumber = l0 + 26 * (l1 + 26 * (l2 + 26 * (l3 + 26 * l4))) + const word = numberToWord(wordNumber) + return word } diff --git a/react-wordle/src/lib/statuses.ts b/react-wordle/src/lib/statuses.ts index 7a50686..e359387 100644 --- a/react-wordle/src/lib/statuses.ts +++ b/react-wordle/src/lib/statuses.ts @@ -3,22 +3,20 @@ import { unicodeSplit } from './words' export type CharStatus = 'absent' | 'present' | 'correct' export const getStatuses = ( - guesses: [string,number,number][] + guesses: [string, number, number][] ): { [key: string]: CharStatus } => { const charObj: { [key: string]: CharStatus } = {} guesses.forEach((word) => { unicodeSplit(word[0]).forEach((letter, i) => { // if (!splitSolution.includes(letter)) { - // make status absent - // return (charObj[letter] = 'absent') + // make status absent + // return (charObj[letter] = 'absent') // } - // if (letter === splitSolution[i]) { // //make status correct // return (charObj[letter] = 'correct') // } - // if (charObj[letter] !== 'correct') { // //make status present // return (charObj[letter] = 'present') @@ -37,18 +35,14 @@ export const getGuessStatuses = ( const statuses: CharStatus[] = Array.from(Array(5)) for (let i = 0; i < 5; i++) { - if ((guess[1]>>i) & 1) { - statuses[i] = 'correct'; - } - else { - let charNo = splitGuess[i].charCodeAt(0)-97; - if ((guess[2]>>charNo) & 1) - statuses[i] = 'present'; - else - statuses[i] = 'absent'; + if ((guess[1] >> i) & 1) { + statuses[i] = 'correct' + } else { + let charNo = splitGuess[i].charCodeAt(0) - 97 + if ((guess[2] >> charNo) & 1) statuses[i] = 'present' + else statuses[i] = 'absent' } } - return statuses } diff --git a/react-wordle/src/lib/words.ts b/react-wordle/src/lib/words.ts index f8f6440..cf67366 100644 --- a/react-wordle/src/lib/words.ts +++ b/react-wordle/src/lib/words.ts @@ -1,3 +1,4 @@ +import { StandardMerkleTree } from '@openzeppelin/merkle-tree' import { addDays, differenceInDays, @@ -7,7 +8,6 @@ import { } from 'date-fns' import { default as GraphemeSplitter } from 'grapheme-splitter' import queryString from 'query-string' -import { StandardMerkleTree } from "@openzeppelin/merkle-tree"; import { ENABLE_ARCHIVED_GAMES } from '../constants/settings' import { NOT_CONTAINED_MESSAGE, WRONG_SPOT_MESSAGE } from '../constants/strings' @@ -28,8 +28,8 @@ export const isWordInWordList = (word: string) => { } export const isWinningWord = (word: string) => { - console.log(word); - console.log(solution); + console.log(word) + console.log(solution) return solution === word } @@ -180,44 +180,46 @@ export const getIsLatestGame = () => { } export const wordAtId = (id: number) => { - return WORDS[id]; + return WORDS[id] } export const wordAtIdToNumber = (id: number) => { - const word = WORDS[id]; - return (word.charCodeAt(0)-97) - + (word.charCodeAt(1)-97) * 26 - + (word.charCodeAt(2)-97) * 26 * 26 - + (word.charCodeAt(3)-97) * 26 * 26 * 26 - + (word.charCodeAt(4)-97) * 26 * 26 * 26 * 26; + const word = WORDS[id] + return ( + word.charCodeAt(0) - + 97 + + (word.charCodeAt(1) - 97) * 26 + + (word.charCodeAt(2) - 97) * 26 * 26 + + (word.charCodeAt(3) - 97) * 26 * 26 * 26 + + (word.charCodeAt(4) - 97) * 26 * 26 * 26 * 26 + ) } export const numberToWord = (number: number) => { return String.fromCharCode( - number%26+97, - (number/26)%26+97, - (number/26/26)%26+97, - (number/26/26/26)%26+97, - (number/26/26/26/26)%26+97, + (number % 26) + 97, + ((number / 26) % 26) + 97, + ((number / 26 / 26) % 26) + 97, + ((number / 26 / 26 / 26) % 26) + 97, + ((number / 26 / 26 / 26 / 26) % 26) + 97 ) } export const getProof = (id: number) => { - const wordsList = []; - const wordsSz = WORDS.length; + const wordsList = [] + const wordsSz = WORDS.length for (let i = 0; i < wordsSz; i++) { - wordsList.push([i, wordAtIdToNumber(i)]); + wordsList.push([i, wordAtIdToNumber(i)]) } - const tree = StandardMerkleTree.of(wordsList, ["uint16", "uint32"]); - const root = tree.root; + const tree = StandardMerkleTree.of(wordsList, ['uint16', 'uint32']) + const root = tree.root for (const [i, v] of tree.entries()) { - if (v[0] == id) { - const proof = tree.getProof(i); - return [root, proof]; + if (v[0] === id) { + const proof = tree.getProof(i) + return [root, proof] } } - return ["", []]; - + return ['', []] } export const { solution, solutionGameDate, solutionIndex, tomorrow } = diff --git a/react-wordle/src/react-app-env.d.ts b/react-wordle/src/react-app-env.d.ts index 624c875..a6f59fb 100644 --- a/react-wordle/src/react-app-env.d.ts +++ b/react-wordle/src/react-app-env.d.ts @@ -4,68 +4,68 @@ declare namespace NodeJS { interface ProcessEnv { - readonly NODE_ENV: 'development' | 'production' | 'test'; - readonly PUBLIC_URL: string; + readonly NODE_ENV: 'development' | 'production' | 'test' + readonly PUBLIC_URL: string } } declare module '*.avif' { - const src: string; - export default src; + const src: string + export default src } declare module '*.bmp' { - const src: string; - export default src; + const src: string + export default src } declare module '*.gif' { - const src: string; - export default src; + const src: string + export default src } declare module '*.jpg' { - const src: string; - export default src; + const src: string + export default src } declare module '*.jpeg' { - const src: string; - export default src; + const src: string + export default src } declare module '*.png' { - const src: string; - export default src; + const src: string + export default src } declare module '*.webp' { - const src: string; - export default src; + const src: string + export default src } declare module '*.svg' { - import * as React from 'react'; + import * as React from 'react' - export const ReactComponent: React.FunctionComponent & { title?: string }>; + export const ReactComponent: React.FunctionComponent< + React.SVGProps & { title?: string } + > - const src: string; - export default src; + const src: string + export default src } declare module '*.module.css' { - const classes: { readonly [key: string]: string }; - export default classes; + const classes: { readonly [key: string]: string } + export default classes } declare module '*.module.scss' { - const classes: { readonly [key: string]: string }; - export default classes; + const classes: { readonly [key: string]: string } + export default classes } declare module '*.module.sass' { - const classes: { readonly [key: string]: string }; - export default classes; + const classes: { readonly [key: string]: string } + export default classes }