diff --git a/packages/backend/.env.example b/packages/backend/.env.example index 5e12c99..5601ebf 100644 --- a/packages/backend/.env.example +++ b/packages/backend/.env.example @@ -7,3 +7,4 @@ SUPABASE_PROJECT_ID SUPABASE_ACCESS_TOKEN SUPABASE_SERVICE_ROLE_KEY JWT_SECRET_KEY +WALLET_PRIVATE_KEY diff --git a/packages/backend/app.ts b/packages/backend/app.ts index c68f00f..0e166bb 100644 --- a/packages/backend/app.ts +++ b/packages/backend/app.ts @@ -5,7 +5,12 @@ import { playedGamesRouter } from "./microservices/played-games/played-games.rou import { playerGameHistoryRouter } from "./microservices/player-game-history/player-game-history.routes"; import { playersRouter } from "./microservices/players/players.routes"; import { seasonsRouter } from "./microservices/seasons/seasons.routes"; -import { RedisService, SupabaseService, WSService } from "./services"; +import { + EthersService, + RedisService, + SupabaseService, + WSService, +} from "./services"; import cors from "cors"; import "dotenv/config"; import type { Express, NextFunction, Request, Response } from "express"; @@ -69,6 +74,7 @@ app.use( SupabaseService.init(), RedisService.init(), WSService.init(server), + EthersService.init(), ]); const env: string = process.env.NODE_ENV || "development"; if (env !== "test") { diff --git a/packages/backend/microservices/arcade-contract/arcade-game.service.ts b/packages/backend/microservices/arcade-contract/arcade-game.service.ts deleted file mode 100644 index 825a74a..0000000 --- a/packages/backend/microservices/arcade-contract/arcade-game.service.ts +++ /dev/null @@ -1,144 +0,0 @@ -import { SupabaseService } from "../../services"; -import { - ARCADE_ABI, - ARCADE_CONTRACT_ADDRESS, -} from "../../utils/constants/contracts.constants"; -import { NETWORK_RPC_URL } from "../../utils/constants/network-config.constants"; -import { - MappedPlayedGame, - MappedPlayer, -} from "../../utils/types/mappers.types"; -import { Contract, ethers } from "ethers"; - -export class ArcadeService { - public static arcade_contract: Contract; - public static provider: ethers.JsonRpcProvider; - - public static async init(chain_id: number) { - this.provider = new ethers.JsonRpcProvider(NETWORK_RPC_URL[chain_id]); - this.arcade_contract = new ethers.Contract( - ARCADE_CONTRACT_ADDRESS[chain_id], - ARCADE_ABI, - this.provider, - ); - } - - public static async createGame( - game_id: MappedPlayedGame["game_id"], - player_1_address: MappedPlayer["wallet_address"], - player_2_address: MappedPlayer["wallet_address"], - game_tier_id: MappedPlayedGame["game_tier_id"], - is_betting_active: boolean, - ) { - try { - const { data: game_tier_data, error: game_tier_error } = - await SupabaseService.getSupabase() - .from("game_tiers") - .select() - .eq("game_tier_id", game_tier_id); - - if (game_tier_error) { - console.error(game_tier_error); - throw game_tier_error; - } - - const tx = await this.arcade_contract.createGame( - game_id, - player_1_address, - player_2_address, - BigInt(game_tier_data[0].usd_amount * Math.pow(10, 6)), - is_betting_active, - ); - - await tx.wait(); - - return tx; - } catch (error) { - console.error(error); - throw error; - } - } - - public static async endGame( - game_id: MappedPlayedGame["game_id"], - winner: MappedPlayer["wallet_address"], - loser: MappedPlayer["wallet_address"], - ) { - try { - const tx = await this.arcade_contract.endGame( - game_id, - winner, - loser, - ); - - await tx.wait(); - - return tx; - } catch (error) { - console.error(error); - throw error; - } - } - - public static async withdrawUserReward( - user_address: MappedPlayer["wallet_address"], - amount: number, - ) { - try { - const tx = await this.arcade_contract.withdrawReward( - user_address, - BigInt(amount * Math.pow(10, 6)), - ); - - await tx.wait(); - - return tx; - } catch (error) { - console.error(error); - throw error; - } - } - - public static async withdrawOwnerPool() { - try { - const tx = await this.arcade_contract.withdrawOwnerPool(); - - await tx.wait(); - - return tx; - } catch (error) { - console.error(error); - throw error; - } - } - - public static async updatePoolPercentages( - rewardPoolPercentage: number, - ownerPoolPercentage: number, - winnerPercentage: number, - ) { - try { - if ( - rewardPoolPercentage + - ownerPoolPercentage + - winnerPercentage !== - 100 - ) { - throw new Error("Percentages do not add up to 100"); - } - - const tx = await this.arcade_contract.updatePercentages( - rewardPoolPercentage, - ownerPoolPercentage, - winnerPercentage, - ); - - await tx.wait(); - - return tx; - } catch (error) { - console.error(error); - throw error; - } - } -} diff --git a/packages/backend/microservices/game-tiers/game-tier.schema.ts b/packages/backend/microservices/game-tiers/game-tier.schema.ts new file mode 100644 index 0000000..43db22f --- /dev/null +++ b/packages/backend/microservices/game-tiers/game-tier.schema.ts @@ -0,0 +1,12 @@ +import { type MappedGameTier } from "../../utils/types/mappers.types"; +import { type PartialYupSchema } from "../../utils/types/shared.types"; +import * as yup from "yup"; + +export const getTierParams = yup + .object() + .shape>({ + tier_id: yup.string().trim().required(), + }) + .strict() + .noUnknown() + .required(); diff --git a/packages/backend/microservices/game-tiers/game-tiers.routes.ts b/packages/backend/microservices/game-tiers/game-tiers.routes.ts index a7928fd..06c5f80 100644 --- a/packages/backend/microservices/game-tiers/game-tiers.routes.ts +++ b/packages/backend/microservices/game-tiers/game-tiers.routes.ts @@ -1,4 +1,7 @@ -import { fetchGameTiers } from "./game-tiers.service"; +import { validateQuery } from "../../middlewares/rest"; +import { MappedGameTier } from "../../utils/types/mappers.types"; +import { getTierParams } from "./game-tier.schema"; +import { fetchGameTier, fetchGameTiers } from "./game-tiers.service"; import type { NextFunction, Request, Response } from "express"; import { Router } from "express"; @@ -20,4 +23,26 @@ const handleGetTiers = async ( } }; +const handleGetTier = async ( + req: Request, + res: Response, + next: NextFunction, +) => { + try { + const { tier_id } = req.params as unknown as MappedGameTier; + const data = await fetchGameTier(tier_id); + return res.json({ + success: true, + data, + }); + } catch (error) { + next(error); + } +}; + gameTiersRouter.get("/", handleGetTiers); +gameTiersRouter.get( + "/:tier_id", + validateQuery("params", getTierParams), + handleGetTier, +); diff --git a/packages/backend/microservices/game-tiers/game-tiers.service.ts b/packages/backend/microservices/game-tiers/game-tiers.service.ts index 6091809..7c238f7 100644 --- a/packages/backend/microservices/game-tiers/game-tiers.service.ts +++ b/packages/backend/microservices/game-tiers/game-tiers.service.ts @@ -1,4 +1,5 @@ import { SupabaseService } from "../../services"; +import { MappedGameTier } from "../../utils/types/mappers.types"; export const fetchGameTiers = async () => { const { data, error } = await SupabaseService.getSupabase() @@ -12,3 +13,18 @@ export const fetchGameTiers = async () => { return data; }; + +export const fetchGameTier = async (tier_id: MappedGameTier["tier_id"]) => { + const { data, error } = await SupabaseService.getSupabase() + .from("game_tiers") + .select() + .eq("tier_id", tier_id) + .single(); + + if (error) { + console.error(error); + throw error; + } + + return data; +}; diff --git a/packages/backend/microservices/played-games/played-games.routes.ts b/packages/backend/microservices/played-games/played-games.routes.ts index bafc3d6..e4c7545 100644 --- a/packages/backend/microservices/played-games/played-games.routes.ts +++ b/packages/backend/microservices/played-games/played-games.routes.ts @@ -1,20 +1,27 @@ import { validateQuery } from "../../middlewares/rest"; -import { MappedPlayer } from "../../utils/types/mappers.types"; -import { getUserGamesParams } from "./played-games.schema"; -import { fetchAllUserGames } from "./played-games.service"; +import { MappedPlayedGame } from "../../utils/types/mappers.types"; +import { + postPlayerAttestationBody, + postPlayerAttestationParams, +} from "./played-games.schema"; +import { setAttestationAndWithdrawRewards } from "./played-games.service"; import type { NextFunction, Request, Response } from "express"; import { Router } from "express"; export const playedGamesRouter = Router(); -const handleAllUserGames = async ( +const handleGameAttestation = async ( req: Request, res: Response, next: NextFunction, ) => { try { - const { player_id } = req.params as MappedPlayer; - const data = await fetchAllUserGames(player_id); + const { played_game_id } = req.params as unknown as MappedPlayedGame; + const { attestation_hash } = req.body as unknown as MappedPlayedGame; + const data = await setAttestationAndWithdrawRewards( + played_game_id, + attestation_hash, + ); return res.json({ success: true, data, @@ -24,8 +31,9 @@ const handleAllUserGames = async ( } }; -playedGamesRouter.get( - "/:player_id", - validateQuery("params", getUserGamesParams), - handleAllUserGames, +playedGamesRouter.post( + "/:played_game_id/attestation", + validateQuery("params", postPlayerAttestationParams), + validateQuery("body", postPlayerAttestationBody), + handleGameAttestation, ); diff --git a/packages/backend/microservices/played-games/played-games.schema.ts b/packages/backend/microservices/played-games/played-games.schema.ts index 0ee1bbf..ae2df74 100644 --- a/packages/backend/microservices/played-games/played-games.schema.ts +++ b/packages/backend/microservices/played-games/played-games.schema.ts @@ -1,11 +1,20 @@ -import { type MappedPlayer } from "../../utils/types/mappers.types"; +import { type MappedPlayedGame } from "../../utils/types/mappers.types"; import { type PartialYupSchema } from "../../utils/types/shared.types"; import * as yup from "yup"; -export const getUserGamesParams = yup +export const postPlayerAttestationParams = yup .object() - .shape>({ - player_id: yup.string().trim().required(), + .shape>({ + played_game_id: yup.string().trim().required(), + }) + .strict() + .noUnknown() + .required(); + +export const postPlayerAttestationBody = yup + .object() + .shape>({ + attestation_hash: yup.string().trim().required(), }) .strict() .noUnknown() diff --git a/packages/backend/microservices/played-games/played-games.service.ts b/packages/backend/microservices/played-games/played-games.service.ts index cdb3b22..4799f0a 100644 --- a/packages/backend/microservices/played-games/played-games.service.ts +++ b/packages/backend/microservices/played-games/played-games.service.ts @@ -1,24 +1,42 @@ -import { SupabaseService } from "../../services"; +import { EthersService, SupabaseService } from "../../services"; import { MappedPlayedGame, MappedPlayer, } from "../../utils/types/mappers.types"; +import { fetchGameTier } from "../game-tiers/game-tiers.service"; +import { fetchPlayerDetailsFromUserId } from "../players/players.service"; -export const fetchAllUserGames = async ( - player_id: MappedPlayer["player_id"], +export const setAttestationAndWithdrawRewards = async ( + played_game_id: MappedPlayedGame["played_game_id"], + attestation_hash: MappedPlayedGame["attestation_hash"], ) => { - const { data, error } = await SupabaseService.getSupabase() - .from("played_games") - .select() - .or(`player_1_id.eq.${player_id},player_2_id.eq.${player_id}`) - .order("created_at", { ascending: false }); + const { data: playedGameData, error: playedGameError } = + await SupabaseService.getSupabase() + .from("played_games") + .update({ + attestation_hash, + }) + .eq("played_game_id", played_game_id) + .select() + .single(); - if (error) { - console.error(error); - throw error; + if (playedGameError) { + console.error(playedGameError); + throw playedGameError; } - return data; + const winnerData = await fetchPlayerDetailsFromUserId( + playedGameData.winner_id!, + ); + const tierData = await fetchGameTier(playedGameData.game_tier_id); + + await EthersService.withdrawUserReward( + winnerData.wallet_address, + playedGameData.chain_id, + tierData.usd_amount, + ); + + return playedGameData; }; export const createGame = async ( @@ -69,6 +87,26 @@ export const addPlayer2ToGame = async ( return data; }; +export const fetchPlayersDetailsForPlayedGame = async ( + played_game_id: MappedPlayedGame["played_game_id"], +) => { + const { data, error } = await SupabaseService.getSupabase() + .from("played_games") + .select("*,player_1:player_1_id(*),player_2:player_2_id(*)") + .eq("played_game_id", played_game_id) + .single(); + + if (error) { + console.error(error); + throw error; + } + + return { + player_1: data.player_1 as unknown as MappedPlayer, + player_2: data.player_2 as unknown as MappedPlayer, + }; +}; + export const setWinnerToGame = async ( played_game_id: MappedPlayedGame["played_game_id"], winner_id: MappedPlayedGame["winner_id"], diff --git a/packages/backend/microservices/players/players.routes.ts b/packages/backend/microservices/players/players.routes.ts index 23b786f..5b5121e 100644 --- a/packages/backend/microservices/players/players.routes.ts +++ b/packages/backend/microservices/players/players.routes.ts @@ -1,7 +1,11 @@ import { validateQuery } from "../../middlewares/rest"; import { type MappedPlayer } from "../../utils/types/mappers.types"; import { getUserParams, userAuthBody } from "./players.schema"; -import { createJWToken, createUser, fetchUserDetails } from "./players.service"; +import { + createJWToken, + createUser, + fetchPlayerDetailsFromEmailId, +} from "./players.service"; import type { NextFunction, Request, Response } from "express"; import { Router } from "express"; @@ -14,7 +18,7 @@ const handleGetUser = async ( ) => { try { const { player_id } = req.params as MappedPlayer; - const data = await fetchUserDetails(player_id); + const data = await fetchPlayerDetailsFromEmailId(player_id); return res.json({ success: true, data, @@ -32,7 +36,7 @@ const handlerUserAuth = async ( try { const { email_id, name, profile_photo, wallet_address } = req.body as MappedPlayer; - let user = await fetchUserDetails(email_id); + let user = await fetchPlayerDetailsFromEmailId(email_id); if (!user) { user = await createUser({ email_id, diff --git a/packages/backend/microservices/players/players.service.ts b/packages/backend/microservices/players/players.service.ts index 03fe48f..7ac92ce 100644 --- a/packages/backend/microservices/players/players.service.ts +++ b/packages/backend/microservices/players/players.service.ts @@ -10,7 +10,9 @@ export const createJWToken = (user: MappedPlayer) => { return token; }; -export const fetchUserDetails = async (email_id: MappedPlayer["email_id"]) => { +export const fetchPlayerDetailsFromEmailId = async ( + email_id: MappedPlayer["email_id"], +) => { const { data, error } = await SupabaseService.getSupabase() .from("players") .select() @@ -25,6 +27,23 @@ export const fetchUserDetails = async (email_id: MappedPlayer["email_id"]) => { return data; }; +export const fetchPlayerDetailsFromUserId = async ( + player_id: MappedPlayer["player_id"], +) => { + const { data, error } = await SupabaseService.getSupabase() + .from("players") + .select() + .eq("player_id", player_id) + .single(); + + if (error) { + console.error(error); + throw error; + } + + return data; +}; + export const createUser = async ({ email_id, name, diff --git a/packages/backend/microservices/rock-paper-scissors/rock-paper-scissors.routes.ts b/packages/backend/microservices/rock-paper-scissors/rock-paper-scissors.routes.ts index 57db023..6d771ea 100644 --- a/packages/backend/microservices/rock-paper-scissors/rock-paper-scissors.routes.ts +++ b/packages/backend/microservices/rock-paper-scissors/rock-paper-scissors.routes.ts @@ -1,4 +1,4 @@ -import { RedisService } from "../../services"; +import { EthersService, RedisService } from "../../services"; import { parseStringifiedValues, stringifyObjectValues, @@ -7,6 +7,7 @@ import { import { addPlayer2ToGame, createGame, + fetchPlayersDetailsForPlayedGame, setWinnerToGame, } from "../played-games/played-games.service"; import { @@ -35,11 +36,11 @@ export const RockPaperScissorsRoutes = async ( async ({ game_id, tier_id, + chain_id, player_id, }: RockPaperScissors.JoinEvent["payload"]) => { - console.log(1); try { - const roomKey: string = `${season_id}::${game_id}::${tier_id}`; + const roomKey: string = `${season_id}::${game_id}::${tier_id}::${chain_id}`; const logId: string = `[${season_id}][${game_id}][${tier_id}][${player_id}]`; let room_id: string | null = @@ -144,6 +145,18 @@ export const RockPaperScissorsRoutes = async ( ); if (gameState.player1 && gameState.player2) { + const { player_1, player_2 } = + await fetchPlayersDetailsForPlayedGame(room_id); + + await EthersService.createContractGame( + room_id, + player_1.wallet_address, + player_2.wallet_address, + tier_id, + true, + chain_id, + ); + const stakingEvent: RockPaperScissors.StakingEvent = { type: "staking", payload: { @@ -214,6 +227,7 @@ export const RockPaperScissorsRoutes = async ( move, room_id, player_id, + chain_id, }: RockPaperScissors.MoveEvent["payload"]) => { try { const gameState = @@ -287,6 +301,20 @@ export const RockPaperScissorsRoutes = async ( roundEndEvent.payload, ); } else { + const { player_1, player_2 } = + await fetchPlayersDetailsForPlayedGame(room_id); + + await EthersService.endGame( + room_id, + gameState.winner_id === player_1.player_id + ? player_1.wallet_address + : player_2.wallet_address, + gameState.winner_id === player_1.player_id + ? player_2.wallet_address + : player_1.wallet_address, + chain_id, + ); + await setWinnerToGame(room_id, gameState.winner_id); await RedisClient.del(room_id); diff --git a/packages/backend/services/ethers.service.ts b/packages/backend/services/ethers.service.ts new file mode 100644 index 0000000..7830061 --- /dev/null +++ b/packages/backend/services/ethers.service.ts @@ -0,0 +1,167 @@ +import { fetchGameTier } from "../microservices/game-tiers/game-tiers.service"; +import { + MappedGameTier, + MappedPlayedGame, + MappedPlayer, +} from "../utils/types/mappers.types"; +import { Contracts } from "common"; +import { ethers } from "ethers"; + +export class EthersService { + private static privateKey: string | null = + process.env.WALLET_PRIVATE_KEY || null; + + private static config: { + [chainId: number]: { + wallet: ethers.Wallet; + provider: ethers.Provider; + contract: ethers.Contract; + }; + } = {}; + + public static async init() { + if (!this.privateKey) { + throw new Error("Missing environment variables."); + } + + Object.keys(Contracts.CHAIN_CONFIG).forEach((chainId) => { + const chainIdNum = Number(chainId); + const provider = new ethers.JsonRpcProvider( + Contracts.NETWORK_RPC_URL[chainIdNum], + ); + + const wallet = new ethers.Wallet(this.privateKey!, provider); + const contract = new ethers.Contract( + Contracts.ARCADE_CONTRACT_ADDRESS[chainIdNum], + Contracts.ARCADE_ABI, + wallet.provider, + ); + + this.config[chainIdNum] = { + contract, + provider, + wallet, + }; + + console.info(`Config created for Chain ID ${chainIdNum}`); + }); + + console.info("EthersService initiated successfully!"); + } + + public static async createContractGame( + game_id: MappedPlayedGame["game_id"], + player_1_address: MappedPlayer["wallet_address"], + player_2_address: MappedPlayer["wallet_address"], + game_tier_id: MappedPlayedGame["game_tier_id"], + is_betting_active: boolean, + chain_id: MappedPlayedGame["chain_id"], + ) { + try { + const { usd_amount } = await fetchGameTier(game_tier_id); + + const tx = await this.config[chain_id].contract.createGame( + game_id, + player_1_address, + player_2_address, + BigInt(usd_amount * Math.pow(10, 6)), + is_betting_active, + ); + + await tx.wait(); + + return tx; + } catch (error) { + console.error(error); + throw error; + } + } + + public static async endGame( + game_id: MappedPlayedGame["game_id"], + winner: MappedPlayer["wallet_address"], + loser: MappedPlayer["wallet_address"], + chain_id: MappedPlayedGame["chain_id"], + ) { + try { + const tx = await this.config[chain_id].contract.endGame( + game_id, + winner, + loser, + ); + + await tx.wait(); + + return tx; + } catch (error) { + console.error(error); + throw error; + } + } + + public static async withdrawUserReward( + user_address: MappedPlayer["wallet_address"], + chain_id: MappedPlayedGame["chain_id"], + amount: MappedGameTier["usd_amount"], + ) { + try { + const tx = await this.config[chain_id].contract.withdrawReward( + user_address, + BigInt(amount * Math.pow(10, 6)), + ); + + await tx.wait(); + + return tx; + } catch (error) { + console.error(error); + throw error; + } + } + + public static async withdrawOwnerPool( + chain_id: MappedPlayedGame["chain_id"], + ) { + try { + const tx = await this.config[chain_id].contract.withdrawOwnerPool(); + + await tx.wait(); + + return tx; + } catch (error) { + console.error(error); + throw error; + } + } + + public static async updatePoolPercentages( + chain_id: MappedPlayedGame["chain_id"], + rewardPoolPercentage: number, + ownerPoolPercentage: number, + winnerPercentage: number, + ) { + try { + if ( + rewardPoolPercentage + + ownerPoolPercentage + + winnerPercentage !== + 100 + ) { + throw new Error("Percentages do not add up to 100"); + } + + const tx = await this.config[chain_id].contract.updatePercentages( + rewardPoolPercentage, + ownerPoolPercentage, + winnerPercentage, + ); + + await tx.wait(); + + return tx; + } catch (error) { + console.error(error); + throw error; + } + } +} diff --git a/packages/backend/services/index.ts b/packages/backend/services/index.ts index 02e118c..5ad568c 100644 --- a/packages/backend/services/index.ts +++ b/packages/backend/services/index.ts @@ -1,5 +1,6 @@ import "dotenv/config"; +export { EthersService } from "./ethers.service"; export { RedisService } from "./redis.service"; export { SupabaseService } from "./supabase.service"; export { WSService } from "./ws.service"; diff --git a/packages/backend/utils/constants/contracts.constants.ts b/packages/backend/utils/constants/contracts.constants.ts deleted file mode 100644 index 07654fd..0000000 --- a/packages/backend/utils/constants/contracts.constants.ts +++ /dev/null @@ -1,536 +0,0 @@ -export const ARCADE_ABI = [ - { - inputs: [ - { - internalType: "contract IERC20", - name: "_token", - type: "address", - }, - ], - stateMutability: "nonpayable", - type: "constructor", - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "uint256", - name: "gameId", - type: "uint256", - }, - { - indexed: true, - internalType: "address", - name: "player", - type: "address", - }, - { - indexed: false, - internalType: "uint256", - name: "amount", - type: "uint256", - }, - ], - name: "BetPlaced", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "uint256", - name: "gameId", - type: "uint256", - }, - { - indexed: true, - internalType: "address", - name: "player1", - type: "address", - }, - { - indexed: true, - internalType: "address", - name: "player2", - type: "address", - }, - { - indexed: false, - internalType: "uint256", - name: "betAmount", - type: "uint256", - }, - ], - name: "GameCreated", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "uint256", - name: "gameId", - type: "uint256", - }, - { - indexed: true, - internalType: "address", - name: "winner", - type: "address", - }, - { - indexed: false, - internalType: "uint256", - name: "reward", - type: "uint256", - }, - ], - name: "GameEnded", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "owner", - type: "address", - }, - { - indexed: false, - internalType: "uint256", - name: "amount", - type: "uint256", - }, - ], - name: "OwnerWithdraw", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "uint256", - name: "rewardPoolPercentage", - type: "uint256", - }, - { - indexed: false, - internalType: "uint256", - name: "ownerPercentage", - type: "uint256", - }, - { - indexed: false, - internalType: "uint256", - name: "winPercentage", - type: "uint256", - }, - ], - name: "PercentagesUpdated", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "user", - type: "address", - }, - { - indexed: false, - internalType: "uint256", - name: "amount", - type: "uint256", - }, - ], - name: "RewardWithdrawn", - type: "event", - }, - { - inputs: [ - { - internalType: "address", - name: "_player1", - type: "address", - }, - { - internalType: "address", - name: "_player2", - type: "address", - }, - { - internalType: "uint256", - name: "_betAmount", - type: "uint256", - }, - { - internalType: "bool", - name: "_isBettingActive", - type: "bool", - }, - ], - name: "createGame", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "uint256", - name: "_gameId", - type: "uint256", - }, - { - internalType: "address", - name: "_winner", - type: "address", - }, - { - internalType: "address", - name: "_loser", - type: "address", - }, - ], - name: "endGame", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [], - name: "gameCounter", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - name: "games", - outputs: [ - { - internalType: "address", - name: "player1", - type: "address", - }, - { - internalType: "address", - name: "player2", - type: "address", - }, - { - internalType: "uint256", - name: "betAmount", - type: "uint256", - }, - { - internalType: "bool", - name: "isBettingActive", - type: "bool", - }, - { - internalType: "bool", - name: "player1Deposit", - type: "bool", - }, - { - internalType: "bool", - name: "player2Deposit", - type: "bool", - }, - { - internalType: "address", - name: "winner", - type: "address", - }, - { - internalType: "bool", - name: "isGameOver", - type: "bool", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "uint256", - name: "_gameId", - type: "uint256", - }, - ], - name: "getGameDetails", - outputs: [ - { - components: [ - { - internalType: "address", - name: "player1", - type: "address", - }, - { - internalType: "address", - name: "player2", - type: "address", - }, - { - internalType: "uint256", - name: "betAmount", - type: "uint256", - }, - { - internalType: "bool", - name: "isBettingActive", - type: "bool", - }, - { - internalType: "bool", - name: "player1Deposit", - type: "bool", - }, - { - internalType: "bool", - name: "player2Deposit", - type: "bool", - }, - { - internalType: "address", - name: "winner", - type: "address", - }, - { - internalType: "bool", - name: "isGameOver", - type: "bool", - }, - ], - internalType: "struct Arcade.Game", - name: "", - type: "tuple", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "address", - name: "_user", - type: "address", - }, - ], - name: "getUserBalance", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [], - name: "owner", - outputs: [ - { - internalType: "address", - name: "", - type: "address", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [], - name: "ownerPercentage", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "uint256", - name: "_gameId", - type: "uint256", - }, - { - internalType: "uint256", - name: "_amount", - type: "uint256", - }, - ], - name: "placeBet", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [], - name: "rewardPool", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [], - name: "rewardPoolPercentage", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [], - name: "token", - outputs: [ - { - internalType: "contract IERC20", - name: "", - type: "address", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "uint256", - name: "_rewardPoolPercentage", - type: "uint256", - }, - { - internalType: "uint256", - name: "_ownerPercentage", - type: "uint256", - }, - { - internalType: "uint256", - name: "_winPercentage", - type: "uint256", - }, - ], - name: "updatePercentages", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "address", - name: "", - type: "address", - }, - ], - name: "userBalances", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [], - name: "winPercentage", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [], - name: "withdrawOwnerPool", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "address", - name: "_userAddress", - type: "address", - }, - { - internalType: "uint256", - name: "_amount", - type: "uint256", - }, - ], - name: "withdrawReward", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, -]; - -export const ARCADE_CONTRACT_ADDRESS: { [chainId: number]: string } = { - 296: "0xfcd63e6f3116809F54D8242d75Dfb80cB9a87916", // Hedera - 31: "0xeFF531D43600a925C0d282f755bA0D39aA82eF14", // Rootstock - 2810: "0x24C6434B4779Cecd89075A936d11fd6Aec055166", // Morph L2 -}; - -export const TOKEN_CONTRACT_ADDRESS: { [chainId: number]: string } = { - 296: "0x0e76A3D0B12385a030525b4252A775b4437fFaa7", // Hedera - 31: "0x24C6434B4779Cecd89075A936d11fd6Aec055166", // Rootstock - 2810: "0x9E12AD42c4E4d2acFBADE01a96446e48e6764B98", // Morph L2 -}; diff --git a/packages/backend/utils/constants/network-config.constants.ts b/packages/backend/utils/constants/network-config.constants.ts deleted file mode 100644 index 19f390f..0000000 --- a/packages/backend/utils/constants/network-config.constants.ts +++ /dev/null @@ -1,5 +0,0 @@ -export const NETWORK_RPC_URL: { [chainId: number]: string } = { - 296: "0x0e76A3D0B12385a030525b4252A775b4437fFaa7", // Hedera - 31: "0x24C6434B4779Cecd89075A936d11fd6Aec055166", // Rootstock - 2810: "0x9E12AD42c4E4d2acFBADE01a96446e48e6764B98", // Morph L2 -}; diff --git a/packages/backend/utils/types/database.types.ts b/packages/backend/utils/types/database.types.ts index e7a74b9..f0a6cc6 100644 --- a/packages/backend/utils/types/database.types.ts +++ b/packages/backend/utils/types/database.types.ts @@ -1,393 +1,390 @@ export type Json = - | string - | number - | boolean - | null - | { [key: string]: Json | undefined } - | Json[]; + | string + | number + | boolean + | null + | { [key: string]: Json | undefined } + | Json[] export type Database = { - public: { - Tables: { - game_tiers: { - Row: { - created_at: string; - name: string; - point_weight: number; - tier_id: string; - usd_amount: number; - }; - Insert: { - created_at?: string; - name: string; - point_weight: number; - tier_id?: string; - usd_amount: number; - }; - Update: { - created_at?: string; - name?: string; - point_weight?: number; - tier_id?: string; - usd_amount?: number; - }; - Relationships: []; - }; - games: { - Row: { - cover_image: string; - created_at: string; - description: string; - game_id: string; - icon_image: string; - max_occupancy: number; - name: string; - slug: string; - }; - Insert: { - cover_image: string; - created_at?: string; - description: string; - game_id?: string; - icon_image: string; - max_occupancy?: number; - name: string; - slug: string; - }; - Update: { - cover_image?: string; - created_at?: string; - description?: string; - game_id?: string; - icon_image?: string; - max_occupancy?: number; - name?: string; - slug?: string; - }; - Relationships: []; - }; - played_games: { - Row: { - attestation_hash: string | null; - created_at: string; - game_id: string; - game_tier_id: string; - is_active: boolean; - played_game_id: string; - player_1_id: string | null; - player_2_id: string | null; - season_id: string; - winner_id: string | null; - }; - Insert: { - attestation_hash?: string | null; - created_at?: string; - game_id?: string; - game_tier_id?: string; - is_active?: boolean; - played_game_id?: string; - player_1_id?: string | null; - player_2_id?: string | null; - season_id: string; - winner_id?: string | null; - }; - Update: { - attestation_hash?: string | null; - created_at?: string; - game_id?: string; - game_tier_id?: string; - is_active?: boolean; - played_game_id?: string; - player_1_id?: string | null; - player_2_id?: string | null; - season_id?: string; - winner_id?: string | null; - }; - Relationships: [ - { - foreignKeyName: "played_games_game_id_fkey"; - columns: ["game_id"]; - isOneToOne: false; - referencedRelation: "games"; - referencedColumns: ["game_id"]; - }, - { - foreignKeyName: "played_games_game_tier_id_fkey"; - columns: ["game_tier_id"]; - isOneToOne: false; - referencedRelation: "game_tiers"; - referencedColumns: ["tier_id"]; - }, - { - foreignKeyName: "played_games_player_1_id_fkey"; - columns: ["player_1_id"]; - isOneToOne: false; - referencedRelation: "leaderboard"; - referencedColumns: ["player_id"]; - }, - { - foreignKeyName: "played_games_player_1_id_fkey"; - columns: ["player_1_id"]; - isOneToOne: false; - referencedRelation: "player_game_history"; - referencedColumns: ["player_id"]; - }, - { - foreignKeyName: "played_games_player_1_id_fkey"; - columns: ["player_1_id"]; - isOneToOne: false; - referencedRelation: "players"; - referencedColumns: ["player_id"]; - }, - { - foreignKeyName: "played_games_player_2_id_fkey"; - columns: ["player_2_id"]; - isOneToOne: false; - referencedRelation: "leaderboard"; - referencedColumns: ["player_id"]; - }, - { - foreignKeyName: "played_games_player_2_id_fkey"; - columns: ["player_2_id"]; - isOneToOne: false; - referencedRelation: "player_game_history"; - referencedColumns: ["player_id"]; - }, - { - foreignKeyName: "played_games_player_2_id_fkey"; - columns: ["player_2_id"]; - isOneToOne: false; - referencedRelation: "players"; - referencedColumns: ["player_id"]; - }, - { - foreignKeyName: "played_games_season_id_fkey"; - columns: ["season_id"]; - isOneToOne: false; - referencedRelation: "seasons"; - referencedColumns: ["season_id"]; - }, - { - foreignKeyName: "played_games_winner_id_fkey"; - columns: ["winner_id"]; - isOneToOne: false; - referencedRelation: "leaderboard"; - referencedColumns: ["player_id"]; - }, - { - foreignKeyName: "played_games_winner_id_fkey"; - columns: ["winner_id"]; - isOneToOne: false; - referencedRelation: "player_game_history"; - referencedColumns: ["player_id"]; - }, - { - foreignKeyName: "played_games_winner_id_fkey"; - columns: ["winner_id"]; - isOneToOne: false; - referencedRelation: "players"; - referencedColumns: ["player_id"]; - }, - ]; - }; - players: { - Row: { - created_at: string; - email_id: string; - name: string; - player_id: string; - profile_photo: string; - wallet_address: string; - }; - Insert: { - created_at?: string; - email_id: string; - name: string; - player_id?: string; - profile_photo: string; - wallet_address: string; - }; - Update: { - created_at?: string; - email_id?: string; - name?: string; - player_id?: string; - profile_photo?: string; - wallet_address?: string; - }; - Relationships: []; - }; - seasons: { - Row: { - created_at: string; - ended_on: string; - name: string; - reward_pool_usd: number; - season_id: string; - started_on: string; - }; - Insert: { - created_at?: string; - ended_on: string; - name?: string; - reward_pool_usd?: number; - season_id?: string; - started_on: string; - }; - Update: { - created_at?: string; - ended_on?: string; - name?: string; - reward_pool_usd?: number; - season_id?: string; - started_on?: string; - }; - Relationships: []; - }; - }; - Views: { - leaderboard: { - Row: { - games_played: number | null; - games_won: number | null; - name: string | null; - player_id: string | null; - profile_photo: string | null; - rank: number | null; - season_id: string | null; - total_points: number | null; - wallet_address: string | null; - }; - Relationships: [ - { - foreignKeyName: "played_games_season_id_fkey"; - columns: ["season_id"]; - isOneToOne: false; - referencedRelation: "seasons"; - referencedColumns: ["season_id"]; - }, - ]; - }; - player_game_history: { - Row: { - created_at: string | null; - enemy_name: string | null; - enemy_profile_photo: string | null; - enemy_wallet_address: string | null; - game_name: string | null; - played_game_id: string | null; - player_id: string | null; - season_id: string | null; - tier_name: string | null; - winner_id: string | null; - }; - Relationships: [ - { - foreignKeyName: "played_games_season_id_fkey"; - columns: ["season_id"]; - isOneToOne: false; - referencedRelation: "seasons"; - referencedColumns: ["season_id"]; - }, - ]; - }; - }; - Functions: { - [_ in never]: never; - }; - Enums: { - [_ in never]: never; - }; - CompositeTypes: { - [_ in never]: never; - }; - }; -}; + public: { + Tables: { + game_tiers: { + Row: { + created_at: string + name: string + point_weight: number + tier_id: string + usd_amount: number + } + Insert: { + created_at?: string + name: string + point_weight: number + tier_id?: string + usd_amount: number + } + Update: { + created_at?: string + name?: string + point_weight?: number + tier_id?: string + usd_amount?: number + } + Relationships: [] + } + games: { + Row: { + cover_image: string + created_at: string + description: string + game_id: string + icon_image: string + max_occupancy: number + name: string + slug: string + } + Insert: { + cover_image: string + created_at?: string + description: string + game_id?: string + icon_image: string + max_occupancy?: number + name: string + slug: string + } + Update: { + cover_image?: string + created_at?: string + description?: string + game_id?: string + icon_image?: string + max_occupancy?: number + name?: string + slug?: string + } + Relationships: [] + } + played_games: { + Row: { + attestation_hash: string | null + chain_id: number + created_at: string + game_id: string + game_tier_id: string + is_active: boolean + played_game_id: string + player_1_id: string | null + player_2_id: string | null + season_id: string + winner_id: string | null + } + Insert: { + attestation_hash?: string | null + chain_id?: number + created_at?: string + game_id?: string + game_tier_id?: string + is_active?: boolean + played_game_id?: string + player_1_id?: string | null + player_2_id?: string | null + season_id: string + winner_id?: string | null + } + Update: { + attestation_hash?: string | null + chain_id?: number + created_at?: string + game_id?: string + game_tier_id?: string + is_active?: boolean + played_game_id?: string + player_1_id?: string | null + player_2_id?: string | null + season_id?: string + winner_id?: string | null + } + Relationships: [ + { + foreignKeyName: "played_games_game_id_fkey" + columns: ["game_id"] + isOneToOne: false + referencedRelation: "games" + referencedColumns: ["game_id"] + }, + { + foreignKeyName: "played_games_game_tier_id_fkey" + columns: ["game_tier_id"] + isOneToOne: false + referencedRelation: "game_tiers" + referencedColumns: ["tier_id"] + }, + { + foreignKeyName: "played_games_player_1_id_fkey" + columns: ["player_1_id"] + isOneToOne: false + referencedRelation: "leaderboard" + referencedColumns: ["player_id"] + }, + { + foreignKeyName: "played_games_player_1_id_fkey" + columns: ["player_1_id"] + isOneToOne: false + referencedRelation: "player_game_history" + referencedColumns: ["player_id"] + }, + { + foreignKeyName: "played_games_player_1_id_fkey" + columns: ["player_1_id"] + isOneToOne: false + referencedRelation: "players" + referencedColumns: ["player_id"] + }, + { + foreignKeyName: "played_games_player_2_id_fkey" + columns: ["player_2_id"] + isOneToOne: false + referencedRelation: "leaderboard" + referencedColumns: ["player_id"] + }, + { + foreignKeyName: "played_games_player_2_id_fkey" + columns: ["player_2_id"] + isOneToOne: false + referencedRelation: "player_game_history" + referencedColumns: ["player_id"] + }, + { + foreignKeyName: "played_games_player_2_id_fkey" + columns: ["player_2_id"] + isOneToOne: false + referencedRelation: "players" + referencedColumns: ["player_id"] + }, + { + foreignKeyName: "played_games_season_id_fkey" + columns: ["season_id"] + isOneToOne: false + referencedRelation: "seasons" + referencedColumns: ["season_id"] + }, + { + foreignKeyName: "played_games_winner_id_fkey" + columns: ["winner_id"] + isOneToOne: false + referencedRelation: "leaderboard" + referencedColumns: ["player_id"] + }, + { + foreignKeyName: "played_games_winner_id_fkey" + columns: ["winner_id"] + isOneToOne: false + referencedRelation: "player_game_history" + referencedColumns: ["player_id"] + }, + { + foreignKeyName: "played_games_winner_id_fkey" + columns: ["winner_id"] + isOneToOne: false + referencedRelation: "players" + referencedColumns: ["player_id"] + }, + ] + } + players: { + Row: { + created_at: string + email_id: string + name: string + player_id: string + profile_photo: string + wallet_address: string + } + Insert: { + created_at?: string + email_id: string + name: string + player_id?: string + profile_photo: string + wallet_address: string + } + Update: { + created_at?: string + email_id?: string + name?: string + player_id?: string + profile_photo?: string + wallet_address?: string + } + Relationships: [] + } + seasons: { + Row: { + created_at: string + ended_on: string + name: string + reward_pool_usd: number + season_id: string + started_on: string + } + Insert: { + created_at?: string + ended_on: string + name?: string + reward_pool_usd?: number + season_id?: string + started_on: string + } + Update: { + created_at?: string + ended_on?: string + name?: string + reward_pool_usd?: number + season_id?: string + started_on?: string + } + Relationships: [] + } + } + Views: { + leaderboard: { + Row: { + games_played: number | null + games_won: number | null + name: string | null + player_id: string | null + profile_photo: string | null + rank: number | null + season_id: string | null + total_points: number | null + wallet_address: string | null + } + Relationships: [ + { + foreignKeyName: "played_games_season_id_fkey" + columns: ["season_id"] + isOneToOne: false + referencedRelation: "seasons" + referencedColumns: ["season_id"] + }, + ] + } + player_game_history: { + Row: { + created_at: string | null + enemy_name: string | null + enemy_profile_photo: string | null + enemy_wallet_address: string | null + game_name: string | null + played_game_id: string | null + player_id: string | null + season_id: string | null + tier_name: string | null + winner_id: string | null + } + Relationships: [ + { + foreignKeyName: "played_games_season_id_fkey" + columns: ["season_id"] + isOneToOne: false + referencedRelation: "seasons" + referencedColumns: ["season_id"] + }, + ] + } + } + Functions: { + [_ in never]: never + } + Enums: { + [_ in never]: never + } + CompositeTypes: { + [_ in never]: never + } + } +} -type PublicSchema = Database[Extract]; +type PublicSchema = Database[Extract] export type Tables< - PublicTableNameOrOptions extends - | keyof (PublicSchema["Tables"] & PublicSchema["Views"]) - | { schema: keyof Database }, - TableName extends PublicTableNameOrOptions extends { - schema: keyof Database; - } - ? keyof (Database[PublicTableNameOrOptions["schema"]]["Tables"] & - Database[PublicTableNameOrOptions["schema"]]["Views"]) - : never = never, + PublicTableNameOrOptions extends + | keyof (PublicSchema["Tables"] & PublicSchema["Views"]) + | { schema: keyof Database }, + TableName extends PublicTableNameOrOptions extends { schema: keyof Database } + ? keyof (Database[PublicTableNameOrOptions["schema"]]["Tables"] & + Database[PublicTableNameOrOptions["schema"]]["Views"]) + : never = never, > = PublicTableNameOrOptions extends { schema: keyof Database } - ? (Database[PublicTableNameOrOptions["schema"]]["Tables"] & - Database[PublicTableNameOrOptions["schema"]]["Views"])[TableName] extends { - Row: infer R; + ? (Database[PublicTableNameOrOptions["schema"]]["Tables"] & + Database[PublicTableNameOrOptions["schema"]]["Views"])[TableName] extends { + Row: infer R + } + ? R + : never + : PublicTableNameOrOptions extends keyof (PublicSchema["Tables"] & + PublicSchema["Views"]) + ? (PublicSchema["Tables"] & + PublicSchema["Views"])[PublicTableNameOrOptions] extends { + Row: infer R } - ? R - : never - : PublicTableNameOrOptions extends keyof (PublicSchema["Tables"] & - PublicSchema["Views"]) - ? (PublicSchema["Tables"] & - PublicSchema["Views"])[PublicTableNameOrOptions] extends { - Row: infer R; - } - ? R - : never - : never; + ? R + : never + : never export type TablesInsert< - PublicTableNameOrOptions extends - | keyof PublicSchema["Tables"] - | { schema: keyof Database }, - TableName extends PublicTableNameOrOptions extends { - schema: keyof Database; - } - ? keyof Database[PublicTableNameOrOptions["schema"]]["Tables"] - : never = never, + PublicTableNameOrOptions extends + | keyof PublicSchema["Tables"] + | { schema: keyof Database }, + TableName extends PublicTableNameOrOptions extends { schema: keyof Database } + ? keyof Database[PublicTableNameOrOptions["schema"]]["Tables"] + : never = never, > = PublicTableNameOrOptions extends { schema: keyof Database } - ? Database[PublicTableNameOrOptions["schema"]]["Tables"][TableName] extends { - Insert: infer I; + ? Database[PublicTableNameOrOptions["schema"]]["Tables"][TableName] extends { + Insert: infer I + } + ? I + : never + : PublicTableNameOrOptions extends keyof PublicSchema["Tables"] + ? PublicSchema["Tables"][PublicTableNameOrOptions] extends { + Insert: infer I } - ? I - : never - : PublicTableNameOrOptions extends keyof PublicSchema["Tables"] - ? PublicSchema["Tables"][PublicTableNameOrOptions] extends { - Insert: infer I; - } - ? I - : never - : never; + ? I + : never + : never export type TablesUpdate< - PublicTableNameOrOptions extends - | keyof PublicSchema["Tables"] - | { schema: keyof Database }, - TableName extends PublicTableNameOrOptions extends { - schema: keyof Database; - } - ? keyof Database[PublicTableNameOrOptions["schema"]]["Tables"] - : never = never, + PublicTableNameOrOptions extends + | keyof PublicSchema["Tables"] + | { schema: keyof Database }, + TableName extends PublicTableNameOrOptions extends { schema: keyof Database } + ? keyof Database[PublicTableNameOrOptions["schema"]]["Tables"] + : never = never, > = PublicTableNameOrOptions extends { schema: keyof Database } - ? Database[PublicTableNameOrOptions["schema"]]["Tables"][TableName] extends { - Update: infer U; + ? Database[PublicTableNameOrOptions["schema"]]["Tables"][TableName] extends { + Update: infer U + } + ? U + : never + : PublicTableNameOrOptions extends keyof PublicSchema["Tables"] + ? PublicSchema["Tables"][PublicTableNameOrOptions] extends { + Update: infer U } - ? U - : never - : PublicTableNameOrOptions extends keyof PublicSchema["Tables"] - ? PublicSchema["Tables"][PublicTableNameOrOptions] extends { - Update: infer U; - } - ? U - : never - : never; + ? U + : never + : never export type Enums< - PublicEnumNameOrOptions extends - | keyof PublicSchema["Enums"] - | { schema: keyof Database }, - EnumName extends PublicEnumNameOrOptions extends { schema: keyof Database } - ? keyof Database[PublicEnumNameOrOptions["schema"]]["Enums"] - : never = never, + PublicEnumNameOrOptions extends + | keyof PublicSchema["Enums"] + | { schema: keyof Database }, + EnumName extends PublicEnumNameOrOptions extends { schema: keyof Database } + ? keyof Database[PublicEnumNameOrOptions["schema"]]["Enums"] + : never = never, > = PublicEnumNameOrOptions extends { schema: keyof Database } - ? Database[PublicEnumNameOrOptions["schema"]]["Enums"][EnumName] - : PublicEnumNameOrOptions extends keyof PublicSchema["Enums"] - ? PublicSchema["Enums"][PublicEnumNameOrOptions] - : never; + ? Database[PublicEnumNameOrOptions["schema"]]["Enums"][EnumName] + : PublicEnumNameOrOptions extends keyof PublicSchema["Enums"] + ? PublicSchema["Enums"][PublicEnumNameOrOptions] + : never diff --git a/packages/frontend/src/utils/constants/contracts.constants.ts b/packages/common/contracts/index.ts similarity index 80% rename from packages/frontend/src/utils/constants/contracts.constants.ts rename to packages/common/contracts/index.ts index ba071e2..1744b8c 100644 --- a/packages/frontend/src/utils/constants/contracts.constants.ts +++ b/packages/common/contracts/index.ts @@ -1,3 +1,5 @@ +import { type CustomChainConfig, CHAIN_NAMESPACES } from "@web3auth/base"; + export const ARCADE_ABI = [ { inputs: [ @@ -747,13 +749,91 @@ export const ERC_20_ABI = [ ]; export const ARCADE_CONTRACT_ADDRESS: { [chainId: number]: string } = { - 296: "0xdD049Fc4b926A7857c012354e578c6da1c5B8316", // Hedera - 31: "0xdD049Fc4b926A7857c012354e578c6DA1C5B8316", // Rootstock - 2810: "0xeff531D43600A925c0D282f755bA0d39AA82EF14", // Morph L2 + 296: "0xdD049Fc4b926A7857c012354e578c6da1c5B8316", // * INFO: Hedera + 31: "0xdD049Fc4b926A7857c012354e578c6DA1C5B8316", // * INFO: Rootstock + 2810: "0xeff531D43600A925c0D282f755bA0d39AA82EF14", // * INFO: Morph L2 }; export const TOKEN_CONTRACT_ADDRESS: { [chainId: number]: string } = { - 296: "0x24C6434B4779Cecd89075A936d11fd6Aec055166", // Hedera - 31: "0x24C6434B4779Cecd89075A936d11fd6Aec055166", // Rootstock - 2810: "0x9E12AD42c4E4d2acFBADE01a96446e48e6764B98", // Morph L2 + 296: "0x24C6434B4779Cecd89075A936d11fd6Aec055166", // * INFO: Hedera + 31: "0x24C6434B4779Cecd89075A936d11fd6Aec055166", // * INFO: Rootstock + 2810: "0x9E12AD42c4E4d2acFBADE01a96446e48e6764B98", // * INFO: Morph L2 +}; + +export const NETWORK_RPC_URL: { [chainId: number]: string } = { + 296: "0x0e76A3D0B12385a030525b4252A775b4437fFaa7", // * Hedera + 31: "0x24C6434B4779Cecd89075A936d11fd6Aec055166", // * Rootstock + 2810: "0x9E12AD42c4E4d2acFBADE01a96446e48e6764B98", // * Morph L2 }; + +export const CHAIN_CONFIG: { [key: number]: CustomChainConfig } = { + 296: { + chainNamespace: CHAIN_NAMESPACES.EIP155, + chainId: "0x128", + rpcTarget: "https://testnet.hashio.io/api", + displayName: "Hedera Testnet", + blockExplorerUrl: "https://hashscan.io/testnet/", + ticker: "HBAR", + tickerName: "HBAR", + logo: "https://cryptologos.cc/logos/hedera-hbar-logo.png?v=033", + isTestnet: true, + }, + 2810: { + chainNamespace: CHAIN_NAMESPACES.EIP155, + chainId: "0xa96", + rpcTarget: "https://rpc-testnet.morphl2.io", + displayName: "Morph Testnet", + blockExplorerUrl: "https://explorer-testnet.morphl2.io/", + ticker: "ETH", + tickerName: "ETH", + logo: "https://morphl2brand.notion.site/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ffcab2c10-8da9-4414-aa63-4998ddf62e78%2F64fbcffc-0e7c-45e1-8900-1bb36dc90924%2FFrame_1597882262.png?table=block&id=0e6a22c3-ed4e-4c25-9575-11b95b1eade9&spaceId=fcab2c10-8da9-4414-aa63-4998ddf62e78&width=2000&userId=&cache=v2", + isTestnet: true, + }, + 31: { + chainNamespace: CHAIN_NAMESPACES.EIP155, + chainId: "0x1f", + rpcTarget: "https://public-node.testnet.rsk.co", + displayName: "Rootstock Testnet", + blockExplorerUrl: "https://explorer.testnet.rootstock.io/", + ticker: "tRBTC", + tickerName: "tRBTC", + logo: "https://pbs.twimg.com/profile_images/1592915327343624195/HPPSuVx3_400x400.jpg", + isTestnet: true, + }, +}; + +export const CHAINS: Array = [ + { + chainNamespace: CHAIN_NAMESPACES.EIP155, + chainId: "0x128", + rpcTarget: "https://testnet.hashio.io/api", + displayName: "Hedera Testnet", + blockExplorerUrl: "https://hashscan.io/testnet/", + ticker: "HBAR", + tickerName: "HBAR", + logo: "https://cryptologos.cc/logos/hedera-hbar-logo.png?v=033", + isTestnet: true, + }, + { + chainNamespace: CHAIN_NAMESPACES.EIP155, + chainId: "0xAFA", + rpcTarget: "https://rpc-quicknode-holesky.morphl2.io", + displayName: "Morph Testnet", + blockExplorerUrl: "https://explorer-testnet.morphl2.io/", + ticker: "ETH", + tickerName: "ETH", + logo: "/morph-l2.svg", + isTestnet: true, + }, + { + chainNamespace: CHAIN_NAMESPACES.EIP155, + chainId: "0x1f", + rpcTarget: "https://public-node.testnet.rsk.co", + displayName: "Rootstock Testnet", + blockExplorerUrl: "https://explorer.testnet.rootstock.io/", + ticker: "tRBTC", + tickerName: "tRBTC", + logo: "https://pbs.twimg.com/profile_images/1592915327343624195/HPPSuVx3_400x400.jpg", + isTestnet: true, + }, +]; diff --git a/packages/common/index.ts b/packages/common/index.ts index 7002189..2a10abf 100644 --- a/packages/common/index.ts +++ b/packages/common/index.ts @@ -1,4 +1,5 @@ import * as ConnectFour from "./connect-four"; +import * as Contracts from "./contracts"; import * as RockPaperScissors from "./rock-paper-scissors"; export const rankOwnRewardPercentage = 50; @@ -22,4 +23,4 @@ export type ErrorEvent = { payload: object; }; -export { ConnectFour, RockPaperScissors }; +export { ConnectFour, Contracts, RockPaperScissors }; diff --git a/packages/common/package.json b/packages/common/package.json index 0ba786a..5f2ca9f 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -12,5 +12,8 @@ "license": "ISC", "devDependencies": { "typescript": "^5.5.4" + }, + "dependencies": { + "@web3auth/base": "^8.12.4" } } diff --git a/packages/common/rock-paper-scissors/index.ts b/packages/common/rock-paper-scissors/index.ts index 2fe7796..b59fafd 100644 --- a/packages/common/rock-paper-scissors/index.ts +++ b/packages/common/rock-paper-scissors/index.ts @@ -10,6 +10,7 @@ export type JoinEvent = { player_id: string; game_id: string; tier_id: string; + chain_id: number; }; }; @@ -28,6 +29,7 @@ export type MoveEvent = { player_id: string; room_id: string; move: Move; + chain_id: number; }; }; diff --git a/packages/frontend/src/app/components/shared/season-dropdown.tsx b/packages/frontend/src/app/components/shared/season-dropdown.tsx index 84f7648..d7c4aaf 100644 --- a/packages/frontend/src/app/components/shared/season-dropdown.tsx +++ b/packages/frontend/src/app/components/shared/season-dropdown.tsx @@ -14,8 +14,13 @@ const SeasonDropdown: React.FC<{ selectedSeasonEnded: boolean; }> = ({ seasons, selectedSeason, setSelectedSeason, selectedSeasonEnded }) => { const [dropdownOpen, setDropdownOpen] = useState(false); + const [loading, setLoading] = useState(false); - return ( + return loading ? ( +

+ Curating the seasons... +

+ ) : ( Promise.resolve(function Game({ tier }: Props) { const { user } = useWeb3AuthContext(); + const { selectedChain } = useSelectedChainContext(); const player_user_id = user!.data.player_id; const player_token = user!.token; @@ -248,6 +250,7 @@ export default dynamic( player_id: player_user_id, game_id: RockPaperScissors.gameId, tier_id: tier, + chain_id: parseInt(selectedChain.chainId, 16), } satisfies RockPaperScissors.JoinEvent["payload"] ); diff --git a/packages/frontend/src/app/layout.tsx b/packages/frontend/src/app/layout.tsx index 0d34d1c..9cd5c6e 100644 --- a/packages/frontend/src/app/layout.tsx +++ b/packages/frontend/src/app/layout.tsx @@ -5,6 +5,7 @@ import clsx from "clsx"; import Footer from "./components/Footer"; import { Web3AuthContextProvider } from "@/utils/context/web3auth.context"; import Header from "./components/Header"; +import { SelectedChainContextProvider } from "@/utils/context/selected-chain.context"; const inter = Inter({ subsets: ["latin"], @@ -37,9 +38,11 @@ export default function RootLayout({ )} > -
-
{children}
-