diff --git a/deployed-addresses.json b/deployed-addresses.json index c7fdce9..274b519 100644 --- a/deployed-addresses.json +++ b/deployed-addresses.json @@ -67,25 +67,48 @@ "80001": { "contracts": { "WegaERC20Escrow": { - "address": "0x0000000000000000000000000000000000000000" + "address": "0xCEBc6b24362cA2F4fA625d340BeF8Af4F91DB5bB", + "legacyAddresses": [], + "deploymentBlock": "263113a", + "implementation": "0x0993a07880aD59E02e72E745dC5b623409Ad24af" }, "WegaERC20Dummy": { - "address": "0x0000000000000000000000000000000000000000" + "address": "0x802361100a4772847DBc29BC59F76FD1F186E002", + "legacyAddresses": [], + "deploymentBlock": "263112e" }, "WegaGameController": { - "address": "0x0000000000000000000000000000000000000000" + "address": "0xe4da6EE02D91b7C03DB000B9295A815D6BEeC4ca", + "legacyAddresses": [ + "0x760D87Ce891F301d19F608044D42356De2D50D14", + "0x740e1416aE865E2bff8f95aa5776F5Fa0a3706e7", + "0x02D7EF0f678BCd9323f2FA88e7197528D113f24a", + "0x0000000000000000000000000000000000000000" + ], + "deploymentBlock": "272c37b", + "implementation": "0x21A8Eda1B590268410e520B70635467720B41418" }, "WegaRandomizerController": { - "address": "0x0000000000000000000000000000000000000000" + "address": "0xcd44090c1BC8DC05298540488ca6FA058d27Ac70", + "legacyAddresses": [], + "implementation": "0x24F9E5E74976661E3784E258986Ee9ee6AAe8132" }, "WegaDiceGame": { - "address": "0x0000000000000000000000000000000000000000" + "address": "0x5581147651B29D44d4eD95099F1a53aAE052f797", + "legacyAddresses": [], + "deploymentBlock": "263116f", + "implementation": "0x4f2Fe30D48961581d65C0a486AE5e83A9b8356b0" }, "WegaCoinFlipGame": { - "address": "0x0000000000000000000000000000000000000000" + "address": "0x24133b29067AC3858B4F58112bCAC243941538c8", + "legacyAddresses": [], + "deploymentBlock": "2631158", + "implementation": "0x0C438E3C3B7b629044573e7cc3B0FBe55DB1b8b6" }, "FeeManager": { - "address": "0x0000000000000000000000000000000000000000" + "address": "0xe2cDC641b8AF26a208402a3e218EE022E954Afd0", + "legacyAddresses": [], + "implementation": "0x30D1C9b043014820cC878ea023bd9Ae53238B395" }, "WegaRandomizer": { "address": "0x0000000000000000000000000000000000000000" diff --git a/package-lock.json b/package-lock.json index 3f4ebe7..e7870bc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -70,7 +70,8 @@ "tailwindcss-cli": "^0.1.2", "twin.macro": "^3.4.0", "typescript": "^5.1.6", - "vite": "^4.4.5" + "vite": "^4.4.5", + "vite-plugin-mkcert": "^1.17.1" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -5306,6 +5307,161 @@ "node": ">= 10" } }, + "node_modules/@octokit/auth-token": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", + "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", + "dev": true, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/core": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.0.2.tgz", + "integrity": "sha512-cZUy1gUvd4vttMic7C0lwPed8IYXWYp8kHIMatyhY8t8n3Cpw2ILczkV5pGMPqef7v0bLo0pOHrEHarsau2Ydg==", + "dev": true, + "dependencies": { + "@octokit/auth-token": "^4.0.0", + "@octokit/graphql": "^7.0.0", + "@octokit/request": "^8.0.2", + "@octokit/request-error": "^5.0.0", + "@octokit/types": "^12.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/endpoint": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.3.tgz", + "integrity": "sha512-TXVX57fJV7SA6LvRkeXPIOBr8AKvKDlhwNVBP/26O9DjIFi+CkYZGFLP9WtPdVOicRIhqGHxBCC6Fdj5AWWGgQ==", + "dev": true, + "dependencies": { + "@octokit/types": "^12.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/graphql": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.0.2.tgz", + "integrity": "sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q==", + "dev": true, + "dependencies": { + "@octokit/request": "^8.0.1", + "@octokit/types": "^12.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "19.0.2", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.0.2.tgz", + "integrity": "sha512-8li32fUDUeml/ACRp/njCWTsk5t17cfTM1jp9n08pBrqs5cDFJubtjsSnuz56r5Tad6jdEPJld7LxNp9dNcyjQ==", + "dev": true + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.1.4.tgz", + "integrity": "sha512-MvZx4WvfhBnt7PtH5XE7HORsO7bBk4er1FgRIUr1qJ89NR2I6bWjGyKsxk8z42FPQ34hFQm0Baanh4gzdZR4gQ==", + "dev": true, + "dependencies": { + "@octokit/types": "^12.3.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": ">=5" + } + }, + "node_modules/@octokit/plugin-request-log": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.0.tgz", + "integrity": "sha512-2uJI1COtYCq8Z4yNSnM231TgH50bRkheQ9+aH8TnZanB6QilOnx8RMD2qsnamSOXtDj0ilxvevf5fGsBhBBzKA==", + "dev": true, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": ">=5" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "10.1.5", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.1.5.tgz", + "integrity": "sha512-LMEdsMV8TTMjMTqVoqMzV95XTbv0ZsWxCxQtjAunQOCdwoDH4BVF/Ke5JMSZEVCWGI2kzxnUNbFnK/MxwV7NjA==", + "dev": true, + "dependencies": { + "@octokit/types": "^12.3.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": ">=5" + } + }, + "node_modules/@octokit/request": { + "version": "8.1.6", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.6.tgz", + "integrity": "sha512-YhPaGml3ncZC1NfXpP3WZ7iliL1ap6tLkAp6MvbK2fTTPytzVUyUesBBogcdMm86uRYO5rHaM1xIWxigWZ17MQ==", + "dev": true, + "dependencies": { + "@octokit/endpoint": "^9.0.0", + "@octokit/request-error": "^5.0.0", + "@octokit/types": "^12.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/request-error": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.0.1.tgz", + "integrity": "sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ==", + "dev": true, + "dependencies": { + "@octokit/types": "^12.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/rest": { + "version": "20.0.2", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.0.2.tgz", + "integrity": "sha512-Ux8NDgEraQ/DMAU1PlAohyfBBXDwhnX2j33Z1nJNziqAfHi70PuxkFYIcIt8aIAxtRE7KVuKp8lSR8pA0J5iOQ==", + "dev": true, + "dependencies": { + "@octokit/core": "^5.0.0", + "@octokit/plugin-paginate-rest": "^9.0.0", + "@octokit/plugin-request-log": "^4.0.0", + "@octokit/plugin-rest-endpoint-methods": "^10.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/types": { + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.3.0.tgz", + "integrity": "sha512-nJ8X2HRr234q3w/FcovDlA+ttUU4m1eJAourvfUUtwAWeqL8AsyRqfnLvVnYn3NFbUnsmzQCzLNdFerPwdmcDQ==", + "dev": true, + "dependencies": { + "@octokit/openapi-types": "^19.0.2" + } + }, "node_modules/@pkgr/utils": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.2.tgz", @@ -8057,6 +8213,12 @@ "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", "dev": true }, + "node_modules/before-after-hook": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", + "dev": true + }, "node_modules/big-integer": { "version": "1.6.51", "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", @@ -9146,6 +9308,12 @@ "node": ">= 0.8" } }, + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "dev": true + }, "node_modules/dequal": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", @@ -17134,6 +17302,12 @@ "node": ">=4" } }, + "node_modules/universal-user-agent": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", + "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==", + "dev": true + }, "node_modules/universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -17540,6 +17714,24 @@ } } }, + "node_modules/vite-plugin-mkcert": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/vite-plugin-mkcert/-/vite-plugin-mkcert-1.17.1.tgz", + "integrity": "sha512-/OxFqPXF3yTuikjn5Lbgt0WWm6Yq0KBWkFj68MZTV/icv3tO+7Y/HS+8+4v9vyx0TDzkSTVyaC/4J7Qtnh/PIw==", + "dev": true, + "dependencies": { + "@octokit/rest": "^20.0.2", + "axios": "^1.6.2", + "debug": "^4.3.4", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=v16.7.0" + }, + "peerDependencies": { + "vite": ">=3" + } + }, "node_modules/vite/node_modules/@esbuild/android-arm": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", diff --git a/package.json b/package.json index 6f69e96..f398066 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ } }, "scripts": { - "dev": "export GSAP_TOKEN=$(grep 'GSAP_TOKEN=' .env | cut -d'=' -f2) && vite --mode", + "app": "export GSAP_TOKEN=$(grep 'GSAP_TOKEN=' .env | cut -d'=' -f2) && vite --mode", "build": "tsc && vite build", "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "lint:fix": "eslint \"src/**/*.{ts,tsx}\" --fix", @@ -81,7 +81,8 @@ "tailwindcss-cli": "^0.1.2", "twin.macro": "^3.4.0", "typescript": "^5.1.6", - "vite": "^4.4.5" + "vite": "^4.4.5", + "vite-plugin-mkcert": "^1.17.1" }, "browserslist": { "production": [ diff --git a/src/common/modals/BounceFromTop.tsx b/src/common/modals/BounceFromTop.tsx new file mode 100644 index 0000000..8d1660e --- /dev/null +++ b/src/common/modals/BounceFromTop.tsx @@ -0,0 +1,23 @@ +import React, { useRef, useLayoutEffect } from "react" +import { gsap } from "gsap" +import "twin.macro" + +interface IBounceFromTop { + children: React.ReactNode | React.ReactNode[] +} +const BounceFromTop: React.FC = ({ children }) => { + const wrapperRef = useRef(null) + useLayoutEffect(() => { + const context = gsap.context(() => { + gsap.from(wrapperRef.current, { y: "100%", ease: "elastic.out(1.2, 0.4)" }) + }, wrapperRef) + + return () => context.revert(); + }, []) + return ( +
+ {children} +
+ ) +} +export default BounceFromTop diff --git a/src/common/modals/GlobalModal.tsx b/src/common/modals/GlobalModal.tsx index 0498187..c088498 100644 --- a/src/common/modals/GlobalModal.tsx +++ b/src/common/modals/GlobalModal.tsx @@ -3,6 +3,7 @@ import { ModalContainer } from './types'; import { GameWinnerDeclarationModal } from './GameWinnerDeclarationModal'; import { GameLoserDeclarationModal } from './GameLoserDeclarationModal'; import { ClaimModal } from './ClaimModal'; +import BounceFromTop from './BounceFromTop'; export const MODAL_TYPES = { WINNER_DECLARATION_WINNER_MODAL: 'WINNER_DECLARATION_WINNER_MODAL', @@ -44,8 +45,7 @@ type GlobalModalProps = { } // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars -const GlobalModal: React.FC = () => { - +const GlobalModal: React.FC = ({ children }) => { const [store, setStore] = useState({ modalType: undefined, modalProps: undefined, @@ -114,7 +114,7 @@ const GlobalModal: React.FC = () => { if (!modalType || !ModalComponent) { return null } - return + return } return ( = () => { } } - {/* { - typeof (responseModalStore.responseType) === 'number' && // FOUND THE GODDAMN BUG - null : - hideResponseModal - } - > - { - renderResponseModalComponent(rType as ResponseTypes) - } - - } */} + {children} ) } diff --git a/src/common/modals/types.ts b/src/common/modals/types.ts index d426292..a109b08 100644 --- a/src/common/modals/types.ts +++ b/src/common/modals/types.ts @@ -6,7 +6,6 @@ export const ModalContainer = styled.div` right: 0; width: 100vw; height: 100vh; - background-color: rgba(45, 45, 45, 0.5); z-index: 10000; display: flex; align-items: center; diff --git a/src/components/CreateGameCard/CreateDiceGameCard.tsx b/src/components/CreateGameCard/CreateDiceGameCard.tsx index d573cba..f724bd3 100644 --- a/src/components/CreateGameCard/CreateDiceGameCard.tsx +++ b/src/components/CreateGameCard/CreateDiceGameCard.tsx @@ -33,15 +33,21 @@ import { ArrowDownIcon, StarLoaderIcon } from '../../assets/icons'; import tw from 'twin.macro'; import { useForm } from 'react-hook-form'; import { useBalance } from 'wagmi'; -import { useNavigateTo, useWegaStore, useCreateGameParams, useTokenUSDValue } from '../../hooks'; -import { useCreateGameMutation } from '../../containers/App/api'; +import { useNavigateTo, useWegaStore, useCreateGameParams, useTokenUSDValue} from '../../hooks'; +import { useCreateGameMutation, useGetRandomNumberQuery } from './apiSlice'; import { useCreateWagerAndDepositMutation, useAllowanceQuery, useApproveERC20Mutation, } from './blockchainApiSlice'; import toast from 'react-hot-toast'; -import { toastSettings, toBigIntInWei, escrowConfig, parseTopicDataFromEventLog } from '../../utils'; +import { + toastSettings, + toBigIntInWei, + escrowConfig, + parseTopicDataFromEventLog, + convertBytesToNumber +} from '../../utils'; import Button from '../../common/Button'; import { ToggleWagerBadge } from '../../common/ToggleWagerBadge'; import { useFormReveal } from './animations'; @@ -63,6 +69,7 @@ export const CreateDiceGameCard = ({ }: CreateGameCardInterface & React.Attributes & React.AllHTMLAttributes ) => { const { openConnectModal } = useConnectModal(); const { wallet, user, network } = useWegaStore(); + const randomnessQuery = useGetRandomNumberQuery(undefined); const {tokenAddress, playerAddress, playerUuid } = useCreateGameParams({ wallet, user, network}); const formRef = useRef(null); const detailsBlock = useRef(null) @@ -90,11 +97,7 @@ export const CreateDiceGameCard = ({ // get token balance of user const { data: userWagerBalance, isLoading: isWagerbalanceLoading } = useBalance({ address: wallet?.address as HexishString, - token: tokenAddress, - cacheTime: 60_000, - onError(error) { - console.log('Error', error) - }, + token: tokenAddress }) // create game @@ -112,8 +115,15 @@ export const CreateDiceGameCard = ({ if(!isWagerApproved(allowanceQuery.data, wager)) { await approveERC20({ spender: escrowConfig.address[network?.id as keyof typeof escrowConfig.address], wagerAsBigint: toBigIntInWei(wager), tokenAddress }).unwrap(); } - const receipt = await createWagerAndDeposit({ tokenAddress, wagerAsBigint: toBigIntInWei(wager), gameType }).unwrap(); - const parsedTopicData = parseTopicDataFromEventLog(receipt.logs[3], ['event GameCreation(bytes32 indexed escrowHash, uint256 indexed nonce, address creator, string name)']); + const receipt = await createWagerAndDeposit({ + tokenAddress, + wagerAsBigint: toBigIntInWei(wager), + gameType, + randomness: [convertBytesToNumber(randomnessQuery.data?.randomness)] + }).unwrap(); + + const parsedTopicData = parseTopicDataFromEventLog(receipt.logs[2], ['event GameCreation(bytes32 indexed escrowHash, uint256 indexed nonce, address creator, string name)']); + await createGame({ gameType, players: [ { uuid: playerUuid } ], @@ -121,10 +131,10 @@ export const CreateDiceGameCard = ({ wager: { wagerType: currentWagerType.toUpperCase() as AllPossibleWagerTypes, wagerHash: parsedTopicData?.escrowHash, - tokenAddress, + tokenAddress, wagerAmount: parseEther(String(wager)).toString(), wagerCurrency: currentCurrencyType, - nonce: parsedTopicData?.nonce.toNumber(), + nonce: Number(parsedTopicData?.nonce), } }).unwrap(); toast.success('Create game success', { ...toastSettings('success', 'top-center') as any }); @@ -151,13 +161,11 @@ export const CreateDiceGameCard = ({ } } }, [ - watch('wager'), + watch('wager'), tokenAddress, - isWagerApproved, createGameStatus, createGameResponse ]); - return (
({ + url: '/randomness', + method: 'GET', + }), }), }), }) @@ -29,4 +35,4 @@ appApiSlice.enhanceEndpoints({ addTagTypes: ['Games'], endpoints: { createGame: { invalidatesTags: [ { type: 'Games', id: 'LIST' } ]} } }); -export const { useCreateGameMutation } = createGameApiSlice; +export const { useCreateGameMutation, useGetRandomNumberQuery } = createGameApiSlice; diff --git a/src/components/CreateGameCard/blockchainApiSlice.ts b/src/components/CreateGameCard/blockchainApiSlice.ts index 6161d8a..6088dc3 100644 --- a/src/components/CreateGameCard/blockchainApiSlice.ts +++ b/src/components/CreateGameCard/blockchainApiSlice.ts @@ -10,12 +10,12 @@ import { formatEther } from 'ethers'; // write function names with type safety export const createGameBlockchainApiSlice = blockchainApiSlice.injectEndpoints({ endpoints: (builder) => ({ - createWagerAndDeposit: builder.mutation({ - query: ({ tokenAddress, wagerAsBigint, gameType }) => ({ + createWagerAndDeposit: builder.mutation({ + query: ({ tokenAddress, wagerAsBigint, gameType, randomness }) => ({ functionName: 'createGame', contract: ContractTypes.GAMECONTROLLER, method: 'WRITE', - args: [gameType, tokenAddress, wagerAsBigint] + args: [gameType, tokenAddress, wagerAsBigint, randomness] }) }), approveERC20: builder.mutation({ diff --git a/src/components/Dice/animations.ts b/src/components/Dice/animations.ts index 9e7e4aa..365091b 100644 --- a/src/components/Dice/animations.ts +++ b/src/components/Dice/animations.ts @@ -3,6 +3,8 @@ import { gsap } from 'gsap'; // eslint-disable-next-line no-unused-vars type Callback = (...args: any[]) => void | null; +// eslint-disable-next-line no-unused-vars +// type AsyncCallback = (...args: any[]) => Promise; export function useRoll(diceRef: any, onBegin?: Callback, onEnd?: Callback) { const [trigger, setStrigger] = useState(false); diff --git a/src/components/Dice/types.ts b/src/components/Dice/types.ts index ad20cdf..a116e5f 100644 --- a/src/components/Dice/types.ts +++ b/src/components/Dice/types.ts @@ -12,15 +12,16 @@ export const DiceContainer = styled.div` box-shadow: 0px 6.939759254455566px 17.34939956665039px 0px rgba(0, 0, 0, 0.25); background: rgba(75, 75, 75, 0.30 ); backdrop-filter: blur(15px); - ${tw`border border-blanc border-[1.5px]`} - border-radius: 5px; + border-radius: 13.964px; + ${tw`border border-blanc border-[1.461px]`} + ` export const DiceWrapper = styled.div` position: relative; z-index: 10; width: 70px; height: 70px; - border-radius: 5.205px; + border-radius: 13.964px; border-left: 5px solid #FF9C27; border-right: 5px solid #F26D21; background-image: linear-gradient(to left, #F26D21, #FF9C27), linear-gradient(to left, #F26D21, #FF9C27); diff --git a/src/components/JoinGameCard/JoinDiceGamecard.tsx b/src/components/JoinGameCard/JoinDiceGamecard.tsx index 172deea..0659758 100644 --- a/src/components/JoinGameCard/JoinDiceGamecard.tsx +++ b/src/components/JoinGameCard/JoinDiceGamecard.tsx @@ -28,14 +28,15 @@ import { ArrowDownIcon, StarLoaderIcon } from '../../assets/icons'; import tw from 'twin.macro'; import { useForm } from 'react-hook-form'; import { useBalance } from 'wagmi'; -import { useNavigateTo } from '../../hooks'; +import { useNavigateTo, useTokenUSDValue } from '../../hooks'; import { useDepositAndJoinDiceMutation } from './blockchainApiSlice'; import { useAllowanceQuery, useApproveERC20Mutation } from '../CreateGameCard/blockchainApiSlice'; import toast from 'react-hot-toast'; -import { toastSettings, escrowConfig, toBigIntInWei } from '../../utils'; +import { toastSettings, escrowConfig, toBigIntInWei, convertBytesToNumber } from '../../utils'; import Button from '../../common/Button'; import { useFormReveal } from '../CreateGameCard/animations'; -import { useJoinGameMutation, useUpdateGameMutation } from '../../containers/App/api'; +import { useJoinGameMutation, useUpdateGameMutation } from './apiSlice'; +import { useGetRandomNumberQuery } from '../CreateGameCard/apiSlice'; import { JoinGameCardProps } from './' export interface JoinDiceGameCardProps extends JoinGameCardProps, React.Attributes, React.AllHTMLAttributes {}; @@ -62,9 +63,10 @@ const JoinGameDiceCard: React.FC = ({ const [currentWagerType] = useState(wagerType); const [currentCurrencyType] = useState(currencyType); const {revealed, triggerRevealAnimation} = useFormReveal(false, formRef, detailsBlock); + const randomnessQuery = useGetRandomNumberQuery(undefined); // should go into blockchain api slice - const { register, formState: { errors }, handleSubmit } = useForm({ + const { register, formState: { errors }, handleSubmit, watch } = useForm({ mode: 'onChange', resolver: joiResolver(createGameSchema('wager', wagerAmount)) , reValidateMode: 'onChange', @@ -73,6 +75,8 @@ const JoinGameDiceCard: React.FC = ({ } }); + const wagerUSDValue = useTokenUSDValue(currentCurrencyType, watch('wager')); + // approval for allowance const isWagerApproved = (allowance: number, wagerAmount: number) => allowance >= wagerAmount; const allowanceQuery = useAllowanceQuery({ @@ -97,7 +101,10 @@ const JoinGameDiceCard: React.FC = ({ if(!isWagerApproved(allowanceQuery.data, wagerAmount)) { await approveERC20({ spender: escrowConfig.address[network.id as keyof typeof escrowConfig.address], wagerAsBigint: toBigIntInWei(wagerAmount), tokenAddress }).unwrap(); } - await depositAndJoinDice({ escrowHash: escrowId }).unwrap(); + await depositAndJoinDice({ + escrowHash: escrowId, + randomness: [convertBytesToNumber(randomnessQuery.data?.randomness)] + }).unwrap(); await joinGame({ newPlayerUuid: playerUuid, gameUuid }).unwrap(); await updateGame({ uuid: gameUuid, state: WegaState.PLAYING }).unwrap(); navigateToGameUi(`/${gameType.toLowerCase()}/play/${gameUuid}`, 1500, { replace: true, state: { gameId: gameId, gameUuid } }); @@ -114,7 +121,7 @@ const JoinGameDiceCard: React.FC = ({ const navigateToGameUi = useNavigateTo() useEffect(() => { allowanceQuery.refetch(); - }, [tokenAddress, wagerAmount, isWagerApproved]); + }, [tokenAddress, wagerAmount]); return ( = ({ name="wager" render={({ message }) => {message} } /> - 00,00 USD + {wagerUSDValue.loading ? 'loading...' : wagerUSDValue.value} USD Balance: { isWagerbalanceLoading ? "Retrieving balance..." : userWagerBalance?.formatted + ' ' + userWagerBalance?.symbol } diff --git a/src/components/JoinGameCard/apiSlice.ts b/src/components/JoinGameCard/apiSlice.ts new file mode 100644 index 0000000..2ef0475 --- /dev/null +++ b/src/components/JoinGameCard/apiSlice.ts @@ -0,0 +1,35 @@ +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +import { appApiSlice } from '../../app/apiSlice'; +import { + type Wega, + type WegaAttributes +} from '../../models' + +export const joinGameApiSlice = appApiSlice.injectEndpoints({ + endpoints: (builder) => ({ + joinGame: builder.mutation({ + query: ({ gameUuid , newPlayerUuid, gameAttributes }) => ({ + url: `/games/${gameUuid}/join`, + method: 'PATCH', + body: { newPlayerUuid, uuid: gameUuid, gameAttributes } + }), + }), + updateGame: builder.mutation>({ + query: ({ uuid, ...updates }) => { + return ({ + url: `/games/${uuid}`, + method: 'PATCH', + body: { uuid, ...updates } + }) + }, + }), + }), +}); +appApiSlice.enhanceEndpoints({ + addTagTypes: ['Games'], + endpoints: { + createGame: { invalidatesTags: [ { type: 'Games', id: 'LIST' } ] }, + updateGame: { invalidatesTags: [ { type: 'Games', id: 'LIST' } ] } + } +}); +export const { useJoinGameMutation, useUpdateGameMutation } = joinGameApiSlice; diff --git a/src/components/JoinGameCard/blockchainApiSlice.ts b/src/components/JoinGameCard/blockchainApiSlice.ts index 3564a17..8ee1ed3 100644 --- a/src/components/JoinGameCard/blockchainApiSlice.ts +++ b/src/components/JoinGameCard/blockchainApiSlice.ts @@ -3,23 +3,23 @@ import { HexishString } from '../../models'; import { ContractTypes } from '../../libs/wagmi'; // Todo - // write function names with type safety +// write function names with type safety export const joinGameBlockchainApiSlice = blockchainApiSlice.injectEndpoints({ endpoints: (builder) => ({ - depositAndJoinDice: builder.mutation({ - query: ({escrowHash}) => ({ + depositAndJoinDice: builder.mutation({ + query: ({escrowHash, randomness }) => ({ functionName: 'depositOrPlay', contract: ContractTypes.GAMECONTROLLER, method: 'WRITE', - args: [escrowHash] + args: [escrowHash, randomness] }) }), - depositAndJoinCoinflip: builder.mutation({ - query: ({ escrowHash, playerChoices}) => ({ + depositAndJoinCoinflip: builder.mutation({ + query: ({ escrowHash, playerChoices, randomness }) => ({ functionName: 'depositOrPlay', contract: ContractTypes.GAMECONTROLLER, method: 'WRITE', - args: [escrowHash, playerChoices] + args: [escrowHash, playerChoices, randomness] }) }), }) diff --git a/src/components/PlayGamePlayerCard/index.tsx b/src/components/PlayGamePlayerCard/index.tsx index 356e4c0..d83f8c6 100644 --- a/src/components/PlayGamePlayerCard/index.tsx +++ b/src/components/PlayGamePlayerCard/index.tsx @@ -17,24 +17,22 @@ export interface PlayGamePlayerCardProps { opponent?: Player; shouldRoll: boolean; isGameOver: boolean; - isRolling: boolean; - isGamePlayable: boolean; - coinFlipChoice?: AllPossibleCoinSides; + isRolling?: boolean; + coinFlipChoice?: AllPossibleCoinSides; + hasAnyOneRolled: boolean; } export const PlayGamePlayerCard = ({ status, wager, player, opponent, - shouldRoll, - isRolling, isGameOver, coinFlipChoice, - isGamePlayable, + hasAnyOneRolled }: PlayGamePlayerCardProps) => { - console.log(coinFlipChoice) + return status !== 'connecting' ? ( - + { (player || opponent) && @@ -65,24 +63,15 @@ export const PlayGamePlayerCard = ({ { - !isGameOver && isGamePlayable && (shouldRoll ? ( -
+ !isGameOver && (status == 'idle' ? ( - Press roll to start... + Awaiting opponent -
) : ( - - Awaiting opponent - - )) - } - { - !isGameOver && (isRolling && -
+ ) : status == 'rolling' && hasAnyOneRolled ? ( Rolling... -
) + ) : Press roll to start ) }
) : diff --git a/src/components/PlayGameSection/PlayDiceGameSection.tsx b/src/components/PlayGameSection/PlayDiceGameSection.tsx index 9b855b7..ce82b5f 100644 --- a/src/components/PlayGameSection/PlayDiceGameSection.tsx +++ b/src/components/PlayGameSection/PlayDiceGameSection.tsx @@ -9,6 +9,7 @@ import { useRoll } from '../Dice/animations'; import { useUpdateGameMutation } from "./apiSlice"; import { useGlobalModalContext, MODAL_TYPES } from "../../common/modals"; import Button from "../../common/Button"; +import { getGameStatus, isCurrentUserGameCreator } from './utils'; import 'twin.macro'; interface PlayGameSectionProps { @@ -35,7 +36,6 @@ const PlayDiceGameSection: React.FC= ({ const [updateGame, ] = useUpdateGameMutation(); const maxTurns = MinimumGameRounds[game.gameType] * game.requiredPlayerNum; const { showModal, hideModal } = useGlobalModalContext(); - const [isRolling, setIsRolling] = useState(false); const [hasRolled, setHasRolled] = useState(false); const [shouldCurrentPlayerRoll, setShouldCurrentPlayerRoll] = useState(false); @@ -49,22 +49,29 @@ const PlayDiceGameSection: React.FC= ({ } const handleOnRollClick = async (gameUuid: string, turn: number) => { - // should trigger the animation here - try { - return await updateGame({ uuid: gameUuid, currentTurn: turn, state: WegaState.COMPLETED }).unwrap(); - } catch (e) { - console.log(e) + if(turn < maxTurns) { + try { + return await updateGame({ uuid: gameUuid, currentTurn: turn }).unwrap(); + } catch (e) { + console.log(e) + } + } else { + const gameWinners = winners.map(w => ({ winner: w })); + try { + return await updateGame({ uuid: game.uuid, currentTurn: turn, state: WegaState.COMPLETED, gameWinners }).unwrap(); + } catch(e) { + console.log(e) + } } } + // setup animation const diceRef = useRef(null); const { rolled, triggerRoll } = useRoll(diceRef, () => { - setIsRolling(true); setHasRolled(false) }, // on animation begin () => { - setIsRolling(false); setHasRolled(true); } // on animation end ); @@ -123,24 +130,30 @@ const PlayDiceGameSection: React.FC= ({
{/* player card */} 0 ? hasRolled && shouldCurrentPlayerRoll : shouldCurrentPlayerRoll} - isGamePlayable={isGamePlayable} + hasAnyOneRolled={gameInfo.currentTurn > 0} /> {/* searching for opponent box */} player.uuid !== user.uuid)[0]} wager={game.wager} - isGameOver={gameInfo.currentTurn === maxTurns} - isRolling={isRolling && shouldCurrentPlayerRoll} + isGameOver={rolled} shouldRoll={gameInfo.currentTurn > 0 ? hasRolled && !shouldCurrentPlayerRoll : !shouldCurrentPlayerRoll} - isGamePlayable={isGamePlayable} + hasAnyOneRolled={gameInfo.currentTurn > 0} />
{ diff --git a/src/components/PlayGameSection/apiSlice.ts b/src/components/PlayGameSection/apiSlice.ts index 58b15b6..1823591 100644 --- a/src/components/PlayGameSection/apiSlice.ts +++ b/src/components/PlayGameSection/apiSlice.ts @@ -6,11 +6,11 @@ export const playGameApiSlice = appApiSlice.injectEndpoints({ endpoints: (builder) => ({ updateGame: builder.mutation>({ query: ({ uuid, ...updates }) => { - return ({ - url: `/games/${uuid}`, - method: 'PATCH', - body: { uuid, ...updates } - }) + return ({ + url: `/games/${uuid}`, + method: 'PATCH', + body: { uuid, ...updates } + }) }, }), }), diff --git a/src/components/PlayGameSection/index.tsx b/src/components/PlayGameSection/index.tsx index 3872d81..26dbeb7 100644 --- a/src/components/PlayGameSection/index.tsx +++ b/src/components/PlayGameSection/index.tsx @@ -79,7 +79,7 @@ const PlayGameSection: React.FC = ({ } else { Comp = GAME_COMPONENTS[game.gameType.toUpperCase()]; if(children) { - return gameResults() && winners ? 0 ? = ({ ...rest }}>{children} : } else { - return gameResults() && winners ? data.filter(game => game.state === WegaState.PLAYING && game.players.some(predicate => predicate.uuid === userUuid )); const filterJoinableGames = (data: Wega[], userUuid: string) => data.filter(game => game.state === WegaState.PENDING && game.players.every(predicate => predicate.uuid !== userUuid )); +const filterWaitingGames = (data: Wega[], userUuid: string) => data.filter(game => game.state === WegaState.PENDING && game.players.some(predicate => predicate.uuid === userUuid )); const sortPlayableGames = (data: Wega[]) => data.sort((a: any, b: any) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()); -// const filterClaimableGames = (data: Wega[], userUuid: string) => data.filter(game => game.players.some(predicate => predicate.uuid === userUuid )); -// const attachGameWinners = (data: Wega[], winners: HexishString[]) => data.map(game => ({ ...game, winners })); -// const filterClaimableGames = (data: Wega[], userAddress: HexishString) => data.filter(game => game.players.some(predicate => predicate.walletAddress?.toLowerCase() !== userAddress.toLowerCase())); - export const JoinableAndPlayableGames: React.FC = ({ gamesCount, userUuid, ...rest }: JoinableAndPlayableGamesProps) => { const { data, isLoading, isSuccess} = useGetGamesQuery(undefined); const [gameIds, setGameIds] = useState(); @@ -25,7 +22,8 @@ export const JoinableAndPlayableGames: React.FC = const dataArray = data.ids.map((id: number) => data.entities[id]) as Wega[]; const playableGames = filterPlayableGames(dataArray, userUuid); const joinableGames = filterJoinableGames(dataArray, userUuid); - const sortedGameIds = sortPlayableGames([...playableGames, ...joinableGames]).map(game => game.id); + const waitingGames = filterWaitingGames(dataArray, userUuid); + const sortedGameIds = sortPlayableGames([...playableGames, ...joinableGames, ...waitingGames]).map(game => game.id); setGameIds(sortedGameIds); } }, [data, gamesCount, isSuccess]); diff --git a/src/containers/JoinGamePage/index.tsx b/src/containers/JoinGamePage/index.tsx index b5d5b67..a41f170 100644 --- a/src/containers/JoinGamePage/index.tsx +++ b/src/containers/JoinGamePage/index.tsx @@ -23,11 +23,12 @@ const JoinGamePage = () => { Join - {BADGE_TEXTS[game.gameType]} - +
+ Match wager }> { Navigating... - - -
+
+ + + +
+
diff --git a/src/containers/Navigation/index.tsx b/src/containers/Navigation/index.tsx index d203e07..54c7ece 100644 --- a/src/containers/Navigation/index.tsx +++ b/src/containers/Navigation/index.tsx @@ -23,8 +23,8 @@ const Navigation = () => { ` return ( - -
+ +
diff --git a/src/containers/Navigation/types.ts b/src/containers/Navigation/types.ts index 98952f6..46a9e6e 100644 --- a/src/containers/Navigation/types.ts +++ b/src/containers/Navigation/types.ts @@ -58,7 +58,7 @@ export const NavigationBar = styled.nav` right: 0; left: 0; transition: transform 500ms ease-out 100ms; - + z-index: 10000; &.nav-show { transform: initial; &::after { @@ -76,7 +76,7 @@ export const NavigationBar = styled.nav` right: 0; width: 100%; height: 100%; - ${tw`bg-pretu bg-opacity-90 z-[750] shadow-wega-nav`} + ${tw`bg-pretu bg-opacity-90 z-[7500] shadow-wega-nav`} // filter: blur(1rem); // -webkit-filter: blur(1rem); opacity: 0; @@ -93,7 +93,7 @@ export const NavigationBar = styled.nav` opacity: 0; // filter: blur(1rem); // -webkit-filter: blur(1rem); - ${tw`z-[745] bg-pretu bg-opacity-95`} + ${tw`z-[7450] bg-pretu bg-opacity-95`} transition: all 500ms ease-out 60ms; } &.nav-hide { diff --git a/src/containers/PlayGamePage/index.tsx b/src/containers/PlayGamePage/index.tsx index 0dda116..49af305 100644 --- a/src/containers/PlayGamePage/index.tsx +++ b/src/containers/PlayGamePage/index.tsx @@ -1,3 +1,4 @@ +import { useEffect } from 'react'; import Section from "../../common/Section" import { Helmet } from "react-helmet-async" import { useParams } from "react-router-dom" @@ -11,20 +12,25 @@ import { ComponentLoader } from "../../common/loaders" import PlayGameSection from "../../components/PlayGameSection" import { FloatingOrbs } from "../../common/FloatingOrbs" import MainContainer from '../../components/MainContainer'; -import { useWegaStore, useFirebaseData } from "../../hooks"; +import { useWegaStore, useFirebaseData, useNavigateTo } from "../../hooks"; import "twin.macro" const PlayGamePage = () => { const { user, wallet } = useWegaStore(); const params = useParams(); + const navigateToHomePage = useNavigateTo(); const { game, isGamePlayable, players, gameInfo, gameAttributes, playerFlipChoices } = useFirebaseData(params.id as string); + useEffect(() => { + // check if the user is a part of the game + if(wallet && game && !game.players.map(p => p.walletAddress?.toLowerCase()).includes(wallet?.address)) navigateToHomePage(`/`, 1, { replace: true }); + }, [wallet?.address]); return game && user && players && players.length > 0 && gameInfo && wallet ? ( <> Play - {BADGE_TEXTS[game.gameType.toUpperCase()]} - - + +
{
- { user?.uuid ? : gamesCount && !user.uuid ? <> : } + { user?.uuid ? : } + {/* { user?.uuid ? : gamesCount && !user.uuid ? <> : } */}
) diff --git a/src/containers/WalletProvider/index.tsx b/src/containers/WalletProvider/index.tsx index 37e7afc..1814bef 100644 --- a/src/containers/WalletProvider/index.tsx +++ b/src/containers/WalletProvider/index.tsx @@ -1,6 +1,6 @@ import { RainbowKitProvider, darkTheme, lightTheme } from '@rainbow-me/rainbowkit'; import wagmiConfig, { chains } from '../../libs/wagmi' -import { polygonMumbai, localhost } from 'wagmi/chains'; +import { polygonMumbai } from 'wagmi/chains'; import { WagmiConfig } from 'wagmi'; import WalletAvatar from '../../common/WalletAvatar'; import 'twin.macro'; @@ -15,7 +15,7 @@ const WalletProvider = (props: WalletConnectorProps) => {
diff --git a/src/hooks/useCreateGameParams.ts b/src/hooks/useCreateGameParams.ts index 7bb7e94..1598342 100644 --- a/src/hooks/useCreateGameParams.ts +++ b/src/hooks/useCreateGameParams.ts @@ -14,12 +14,12 @@ export function useCreateGameParams({ const [getUserUuid, setUserUuid] = useGetSet(undefined); useEffect(() => { - if(wallet && network && user) { + if((wallet && network && user) && !(getTokenAddress() && getPlayerAddress() && getUserUuid())) { setTokenAddress(SupportedWagerTokenAddresses(network?.id as number)[CurrencyTypes[CurrencyTypesEnum.USDC]]); setPlayerAddress(wallet.address as HexishString); setUserUuid(user.uuid as string); } - }, [ wallet, network, user ]); + }, [ network?.id ]); return { tokenAddress: getTokenAddress() as HexishString, playerAddress: getPlayerAddress() as HexishString, diff --git a/src/hooks/useFirebaseData.ts b/src/hooks/useFirebaseData.ts index 758ee50..bc12082 100644 --- a/src/hooks/useFirebaseData.ts +++ b/src/hooks/useFirebaseData.ts @@ -26,29 +26,31 @@ export function useFirebaseData(gameUuid: string) { const databaseRef = ref(database); onValue(databaseRef, (snapshot) => { const { games } = snapshot.val(); - setGame(games[gameUuid]); setGamesCount(Object.keys(games).length); - const { players, requiredPlayerNum, currentTurn, gameAttributes, gameType } = games[gameUuid]; - if(players.length === requiredPlayerNum) { - setIsGamePlayable(true); - } - if (players) { - setPlayersInGame(players); - setGameInfo(Object.assign({}, { currentRound: (Math.floor((currentTurn - 1) / requiredPlayerNum)), rollerIndex: (currentTurn % requiredPlayerNum), currentTurn })); - } - if (gameType === WegaTypes[WegaTypesEnum.COINFLIP]) { - if(gameAttributes.length > 0){ - setWegaAttributes(gameAttributes); - if(gameAttributes.length >= 1) { - setPlayerFlipChoices((s: any) => ({ - ...s, - playerOne: Number(gameAttributes.filter((a: any) => a.key === 'players[0].flipChoice')[0].value) as AllPossibleCoinSides }) - ) - if(gameAttributes.length === 2) { + if(gameUuid) { + setGame(games[gameUuid]); + const { players, requiredPlayerNum, currentTurn, gameAttributes, gameType } = games[gameUuid]; + if(players.length === requiredPlayerNum) { + setIsGamePlayable(true); + } + if (players) { + setPlayersInGame(players); + setGameInfo(Object.assign({}, { currentRound: (Math.floor((currentTurn - 1) / requiredPlayerNum)), rollerIndex: (currentTurn % requiredPlayerNum), currentTurn })); + } + if (gameType === WegaTypes[WegaTypesEnum.COINFLIP]) { + if(gameAttributes.length > 0){ + setWegaAttributes(gameAttributes); + if(gameAttributes.length >= 1) { setPlayerFlipChoices((s: any) => ({ ...s, - playerTwo: Number(gameAttributes.filter((a: any) => a.key === 'players[1].flipChoice')[0].value) as AllPossibleCoinSides }) + playerOne: Number(gameAttributes.filter((a: any) => a.key === 'players[0].flipChoice')[0].value) as AllPossibleCoinSides }) ) + if(gameAttributes.length === 2) { + setPlayerFlipChoices((s: any) => ({ + ...s, + playerTwo: Number(gameAttributes.filter((a: any) => a.key === 'players[1].flipChoice')[0].value) as AllPossibleCoinSides }) + ) + } } } } diff --git a/src/libs/drand/index.ts b/src/libs/drand/index.ts deleted file mode 100644 index 97979f4..0000000 --- a/src/libs/drand/index.ts +++ /dev/null @@ -1,70 +0,0 @@ -// import { useLocalStorage } from 'react-use' -import { convertBytesToNumber } from '../../utils' -type DrandMeta = { chainHash: string; round: number; signature: string; randomness: bigint;} -interface IDrandClient { - getRandomNumber(): Promise; - getLastRequestedDrandMeta(): string | null; - // eslint-disable-next-line no-unused-vars - setDrandMeta(drandMeta: DrandMeta): void; -} - -class DrandClient implements IDrandClient { - private metaStorageKey = 'drand_meta' - private baseUrl = 'https://api.drand.sh'; - private fetchSettings = { - headers: { - 'Access-Control-Allow-Origin': '*' - }, - credentials: 'same-origin' as RequestCredentials, - cache: 'no-cache' as RequestCache - } - getLastRequestedDrandMeta() { - return JSON.parse(localStorage.getItem(this.metaStorageKey) as string) || null; - }; - setDrandMeta(drandMeta: DrandMeta){ - localStorage.setItem(this.metaStorageKey, JSON.stringify(drandMeta)); - } - async getRandomNumber(): Promise { - const meta = this.getLastRequestedDrandMeta(); - if(meta){ - const newRound = meta.round++; - const data = await this.fetchDrand(meta.chainHash, newRound); - this.setDrandMeta(data) - return data; - } else { - const data = await this.fetchDrand(meta.chainHash); - this.setDrandMeta(data); - return data; - } - } - - async fetchDrand(lastChainHash: string, lastRound?: number){ - let fulfilled = false; - let result: DrandMeta = { - round: 0, - randomness: 0n, - signature: "", - chainHash: lastChainHash - } - while (!fulfilled) { - const res = await fetch(this.parseFetchUrl(lastChainHash, lastRound), this.fetchSettings); - const resBody = await res.text(); - const { randomness, round, signature } = JSON.parse(resBody); - // set fulfilled to false; - if(randomness || round || signature) { - result = Object.assign(result, { - round, - randomness: convertBytesToNumber(randomness), - signature: signature, - chainHash: lastChainHash, - }) - fulfilled = true; - } - } - return result; - } - parseFetchUrl(chainHash: string, round?: number): string { - return this.baseUrl.concat(`${chainHash}/public/${round ? round : 'latest'}`); - } -} -export const drandClient = new DrandClient(); \ No newline at end of file diff --git a/src/libs/wagmi/index.ts b/src/libs/wagmi/index.ts index 6c0f10c..7490576 100644 --- a/src/libs/wagmi/index.ts +++ b/src/libs/wagmi/index.ts @@ -11,11 +11,11 @@ import { tokenConfig, escrowConfig, gameControllerConfig, wegaRandomizerControll const { chains, publicClient } = configureChains( - [localhost, polygonMumbai], + [polygonMumbai, localhost], [ alchemyProvider({ apiKey: import.meta.env.VITE_RPC_PROVIDER_ALCHEMY as string }), publicProvider() -] + ] ); const projectId = import.meta.env.VITE_WALLET_CONNECT_ID as string; const { wallets } = getDefaultWallets({ diff --git a/src/models/wega.ts b/src/models/wega.ts index ca53da4..02bd6e7 100644 --- a/src/models/wega.ts +++ b/src/models/wega.ts @@ -28,6 +28,7 @@ export type Wega = { requiredPlayerNum: number; currentTurn: number; gameAttributes?: WegaAttributes; + gameWinners?: ({ winner: HexishString })[]; winners?: HexishString[]; } diff --git a/src/utils/abis.ts b/src/utils/abis.ts index 2337fce..eb2aecc 100644 --- a/src/utils/abis.ts +++ b/src/utils/abis.ts @@ -1,4 +1,4 @@ -// Generated by @wagmi/cli@1.3.0 on 11/26/2023 at 11:01:45 AM +// Generated by @wagmi/cli@1.3.0 on 11/27/2023 at 3:42:21 PM ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // AccessControlUpgradeable @@ -522,7 +522,7 @@ export const enumerableMapABI = [ /** * - - * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0xe2cDC641b8AF26a208402a3e218EE022E954Afd0) * - [__View Contract on Skale Calypso Nft Hub Testnet Skale Explorer__](https://staging-utter-unripe-menkar.explorer.staging-v3.skalenodes.com/address/0x0000000000000000000000000000000000000000) */ export const feeManagerABI = [ @@ -872,18 +872,18 @@ export const feeManagerABI = [ /** * - - * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0xe2cDC641b8AF26a208402a3e218EE022E954Afd0) * - [__View Contract on Skale Calypso Nft Hub Testnet Skale Explorer__](https://staging-utter-unripe-menkar.explorer.staging-v3.skalenodes.com/address/0x0000000000000000000000000000000000000000) */ export const feeManagerAddress = { - 1337: "0xf5059a5D33d5853360D16C683c16e67980206f36", - 80001: "0x0000000000000000000000000000000000000000", + 1337: "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0", + 80001: "0xe2cDC641b8AF26a208402a3e218EE022E954Afd0", 344106930: "0x0000000000000000000000000000000000000000" } as const /** * - - * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0xe2cDC641b8AF26a208402a3e218EE022E954Afd0) * - [__View Contract on Skale Calypso Nft Hub Testnet Skale Explorer__](https://staging-utter-unripe-menkar.explorer.staging-v3.skalenodes.com/address/0x0000000000000000000000000000000000000000) */ export const feeManagerConfig = { address: feeManagerAddress, abi: feeManagerABI } as const @@ -2625,7 +2625,7 @@ export const wegaABI = [ /** * - - * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x24133b29067AC3858B4F58112bCAC243941538c8) * - [__View Contract on Skale Calypso Nft Hub Testnet Skale Explorer__](https://staging-utter-unripe-menkar.explorer.staging-v3.skalenodes.com/address/0x0000000000000000000000000000000000000000) */ export const wegaCoinFlipGameABI = [ @@ -2979,18 +2979,18 @@ export const wegaCoinFlipGameABI = [ /** * - - * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x24133b29067AC3858B4F58112bCAC243941538c8) * - [__View Contract on Skale Calypso Nft Hub Testnet Skale Explorer__](https://staging-utter-unripe-menkar.explorer.staging-v3.skalenodes.com/address/0x0000000000000000000000000000000000000000) */ export const wegaCoinFlipGameAddress = { - 1337: "0x0E801D84Fa97b50751Dbf25036d067dCf18858bF", - 80001: "0x0000000000000000000000000000000000000000", + 1337: "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e", + 80001: "0x24133b29067AC3858B4F58112bCAC243941538c8", 344106930: "0x0000000000000000000000000000000000000000" } as const /** * - - * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x24133b29067AC3858B4F58112bCAC243941538c8) * - [__View Contract on Skale Calypso Nft Hub Testnet Skale Explorer__](https://staging-utter-unripe-menkar.explorer.staging-v3.skalenodes.com/address/0x0000000000000000000000000000000000000000) */ export const wegaCoinFlipGameConfig = { @@ -3004,7 +3004,7 @@ export const wegaCoinFlipGameConfig = { /** * - - * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x5581147651B29D44d4eD95099F1a53aAE052f797) * - [__View Contract on Skale Calypso Nft Hub Testnet Skale Explorer__](https://staging-utter-unripe-menkar.explorer.staging-v3.skalenodes.com/address/0x0000000000000000000000000000000000000000) */ export const wegaDiceGameABI = [ @@ -3358,18 +3358,18 @@ export const wegaDiceGameABI = [ /** * - - * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x5581147651B29D44d4eD95099F1a53aAE052f797) * - [__View Contract on Skale Calypso Nft Hub Testnet Skale Explorer__](https://staging-utter-unripe-menkar.explorer.staging-v3.skalenodes.com/address/0x0000000000000000000000000000000000000000) */ export const wegaDiceGameAddress = { - 1337: "0x9d4454B023096f34B160D6B654540c56A1F81688", - 80001: "0x0000000000000000000000000000000000000000", + 1337: "0x9A676e781A523b5d0C0e43731313A708CB607508", + 80001: "0x5581147651B29D44d4eD95099F1a53aAE052f797", 344106930: "0x0000000000000000000000000000000000000000" } as const /** * - - * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x5581147651B29D44d4eD95099F1a53aAE052f797) * - [__View Contract on Skale Calypso Nft Hub Testnet Skale Explorer__](https://staging-utter-unripe-menkar.explorer.staging-v3.skalenodes.com/address/0x0000000000000000000000000000000000000000) */ export const wegaDiceGameConfig = { address: wegaDiceGameAddress, abi: wegaDiceGameABI } as const @@ -3380,7 +3380,7 @@ export const wegaDiceGameConfig = { address: wegaDiceGameAddress, abi: wegaDiceG /** * - - * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x802361100a4772847DBc29BC59F76FD1F186E002) * - [__View Contract on Skale Calypso Nft Hub Testnet Skale Explorer__](https://staging-utter-unripe-menkar.explorer.staging-v3.skalenodes.com/address/0x0000000000000000000000000000000000000000) */ export const wegaErc20DummyABI = [ @@ -3577,18 +3577,18 @@ export const wegaErc20DummyABI = [ /** * - - * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x802361100a4772847DBc29BC59F76FD1F186E002) * - [__View Contract on Skale Calypso Nft Hub Testnet Skale Explorer__](https://staging-utter-unripe-menkar.explorer.staging-v3.skalenodes.com/address/0x0000000000000000000000000000000000000000) */ export const wegaErc20DummyAddress = { - 1337: "0x851356ae760d987E095750cCeb3bC6014560891C", - 80001: "0x0000000000000000000000000000000000000000", + 1337: "0x5FbDB2315678afecb367f032d93F642f64180aa3", + 80001: "0x802361100a4772847DBc29BC59F76FD1F186E002", 344106930: "0x0000000000000000000000000000000000000000" } as const /** * - - * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x802361100a4772847DBc29BC59F76FD1F186E002) * - [__View Contract on Skale Calypso Nft Hub Testnet Skale Explorer__](https://staging-utter-unripe-menkar.explorer.staging-v3.skalenodes.com/address/0x0000000000000000000000000000000000000000) */ export const wegaErc20DummyConfig = { @@ -3602,7 +3602,7 @@ export const wegaErc20DummyConfig = { /** * - - * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0xCEBc6b24362cA2F4fA625d340BeF8Af4F91DB5bB) * - [__View Contract on Skale Calypso Nft Hub Testnet Skale Explorer__](https://staging-utter-unripe-menkar.explorer.staging-v3.skalenodes.com/address/0x0000000000000000000000000000000000000000) */ export const wegaErc20EscrowABI = [ @@ -4116,18 +4116,18 @@ export const wegaErc20EscrowABI = [ /** * - - * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0xCEBc6b24362cA2F4fA625d340BeF8Af4F91DB5bB) * - [__View Contract on Skale Calypso Nft Hub Testnet Skale Explorer__](https://staging-utter-unripe-menkar.explorer.staging-v3.skalenodes.com/address/0x0000000000000000000000000000000000000000) */ export const wegaErc20EscrowAddress = { - 1337: "0x998abeb3E57409262aE5b751f60747921B33613E", - 80001: "0x0000000000000000000000000000000000000000", + 1337: "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707", + 80001: "0xCEBc6b24362cA2F4fA625d340BeF8Af4F91DB5bB", 344106930: "0x0000000000000000000000000000000000000000" } as const /** * - - * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0xCEBc6b24362cA2F4fA625d340BeF8Af4F91DB5bB) * - [__View Contract on Skale Calypso Nft Hub Testnet Skale Explorer__](https://staging-utter-unripe-menkar.explorer.staging-v3.skalenodes.com/address/0x0000000000000000000000000000000000000000) */ export const wegaErc20EscrowConfig = { @@ -4577,7 +4577,7 @@ export const wegaFeeAdminRoleABI = [ /** * - - * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0xe4da6EE02D91b7C03DB000B9295A815D6BEeC4ca) * - [__View Contract on Skale Calypso Nft Hub Testnet Skale Explorer__](https://staging-utter-unripe-menkar.explorer.staging-v3.skalenodes.com/address/0x0000000000000000000000000000000000000000) */ export const wegaGameControllerABI = [ @@ -5135,18 +5135,18 @@ export const wegaGameControllerABI = [ /** * - - * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0xe4da6EE02D91b7C03DB000B9295A815D6BEeC4ca) * - [__View Contract on Skale Calypso Nft Hub Testnet Skale Explorer__](https://staging-utter-unripe-menkar.explorer.staging-v3.skalenodes.com/address/0x0000000000000000000000000000000000000000) */ export const wegaGameControllerAddress = { - 1337: "0x36C02dA8a0983159322a80FFE9F24b1acfF8B570", - 80001: "0x0000000000000000000000000000000000000000", + 1337: "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE", + 80001: "0xe4da6EE02D91b7C03DB000B9295A815D6BEeC4ca", 344106930: "0x0000000000000000000000000000000000000000" } as const /** * - - * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0xe4da6EE02D91b7C03DB000B9295A815D6BEeC4ca) * - [__View Contract on Skale Calypso Nft Hub Testnet Skale Explorer__](https://staging-utter-unripe-menkar.explorer.staging-v3.skalenodes.com/address/0x0000000000000000000000000000000000000000) */ export const wegaGameControllerConfig = { @@ -5722,7 +5722,7 @@ export const wegaRandomizerConfig = { /** * - - * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0xcd44090c1BC8DC05298540488ca6FA058d27Ac70) * - [__View Contract on Skale Calypso Nft Hub Testnet Skale Explorer__](https://staging-utter-unripe-menkar.explorer.staging-v3.skalenodes.com/address/0x0000000000000000000000000000000000000000) */ export const wegaRandomizerControllerABI = [ @@ -6065,18 +6065,18 @@ export const wegaRandomizerControllerABI = [ /** * - - * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0xcd44090c1BC8DC05298540488ca6FA058d27Ac70) * - [__View Contract on Skale Calypso Nft Hub Testnet Skale Explorer__](https://staging-utter-unripe-menkar.explorer.staging-v3.skalenodes.com/address/0x0000000000000000000000000000000000000000) */ export const wegaRandomizerControllerAddress = { - 1337: "0x4826533B4897376654Bb4d4AD88B7faFD0C98528", - 80001: "0x0000000000000000000000000000000000000000", + 1337: "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6", + 80001: "0xcd44090c1BC8DC05298540488ca6FA058d27Ac70", 344106930: "0x0000000000000000000000000000000000000000" } as const /** * - - * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Polygon Mumbai Polygon Scan__](https://mumbai.polygonscan.com/address/0xcd44090c1BC8DC05298540488ca6FA058d27Ac70) * - [__View Contract on Skale Calypso Nft Hub Testnet Skale Explorer__](https://staging-utter-unripe-menkar.explorer.staging-v3.skalenodes.com/address/0x0000000000000000000000000000000000000000) */ export const wegaRandomizerControllerConfig = { diff --git a/src/utils/ethers-helpers.ts b/src/utils/ethers-helpers.ts index e40f27b..b8a5b7c 100644 --- a/src/utils/ethers-helpers.ts +++ b/src/utils/ethers-helpers.ts @@ -19,15 +19,15 @@ export function toBigIntInWei(value: number): bigint { } export const miniWalletAddress = (address: `0x${string}` | undefined) => { - return address?.slice(0, 6) + "..." + return address?.slice(0, 5) + "..." + address?.slice(address?.length - 3, address?.length) } export function interfaceIdFromAbi(abi: string[]) { return new Interface(abi); } -export function parseTopicDataFromEventLog(txLog: { data: string, topics: Array}, eventAbi: string[]){ - return interfaceIdFromAbi(eventAbi).parseLog(txLog)?.args.toObject(); +export function parseTopicDataFromEventLog(txLog: { data: string, topics: Array }, eventAbi: string[]){ + return interfaceIdFromAbi(eventAbi).parseLog({ data: txLog.data, topics: txLog.topics })?.args.toObject(); } export function isGameCreator( diff --git a/vite.config.ts b/vite.config.ts index a347dc4..4d96e05 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,12 +1,13 @@ import { defineConfig, loadEnv } from 'vite' -import react from '@vitejs/plugin-react' +import react from '@vitejs/plugin-react'; +import mkcert from 'vite-plugin-mkcert' // https://vitejs.dev/config/ export default ({ mode }) => { process.env = { ...process.env, ...loadEnv(mode, process.cwd())}; return defineConfig({ - + server: { https: true }, optimizeDeps: { esbuildOptions: { target: 'es2020', @@ -22,6 +23,7 @@ export default ({ mode }) => { plugins: ['babel-plugin-macros', 'babel-plugin-styled-components'] } }), + mkcert() ], })