From 8484e274dbfb7dbb00f90cae184fe853aa3f74b3 Mon Sep 17 00:00:00 2001 From: Aashutosh Rathi Date: Thu, 1 Aug 2024 13:51:46 +0530 Subject: [PATCH] Refactor keys and handle rejected sign (#13) * rm: initialmode, fetch highscores from server and more * fix some race conditions * fix: prevent actions from from popping up post sign cancel * return when sign rejected * fix: send gameInputs * feat: show unique address in leaderboard * use hosted api --- client/game/tickRecorder.ts | 2 +- client/rpc/api.ts | 3 ++- rollup/index.ts | 50 ++++++++++-------------------------- rollup/stackr/action.ts | 2 +- rollup/stackr/transitions.ts | 6 ++--- 5 files changed, 21 insertions(+), 42 deletions(-) diff --git a/client/game/tickRecorder.ts b/client/game/tickRecorder.ts index ae0890c..458889e 100644 --- a/client/game/tickRecorder.ts +++ b/client/game/tickRecorder.ts @@ -66,7 +66,7 @@ export class TickRecorder { gameId: getFromStore(StorageKey.GAME_ID), timestamp: Date.now(), score, - ticks: this.serializedTicks(), + gameInputs: this.serializedTicks(), }; await endGame(payload); diff --git a/client/rpc/api.ts b/client/rpc/api.ts index 0d32485..2a72cb0 100644 --- a/client/rpc/api.ts +++ b/client/rpc/api.ts @@ -2,7 +2,7 @@ import { getAddress } from "viem"; import { addToStore, getFromStore, StorageKey } from "./storage"; import { getWalletClient } from "./wallet"; -const API_URL = "http://localhost:3210"; +const API_URL = "https://api.comets.stf.xyz"; const fetchMruInfo = async () => { const response = await fetch(`${API_URL}/info`); @@ -33,6 +33,7 @@ const submitAction = async (transition: string, inputs: any) => { }); } catch (e) { console.error("Error signing message", e); + return; } const response = await fetch(`${API_URL}/${transition}`, { diff --git a/rollup/index.ts b/rollup/index.ts index 7f5e5d0..7555d4a 100644 --- a/rollup/index.ts +++ b/rollup/index.ts @@ -6,9 +6,8 @@ import { } from "@stackr/sdk"; import { HDNodeWallet, Wallet } from "ethers"; import express from "express"; -import { readFileSync } from "fs"; import { stackrConfig } from "./stackr.config"; -import { StartGameSchema, EndGameSchema } from "./stackr/action"; +import { EndGameSchema, StartGameSchema } from "./stackr/action"; import { machine, MACHINE_ID } from "./stackr/machine"; const PORT = process.env.PORT || 3210; @@ -39,36 +38,6 @@ const mru = await MicroRollup({ stfSchemaMap, }); -const notMain = async () => { - await mru.init(); - - const filePath = "./ticks.json"; - let jsonData; - try { - const data = readFileSync(filePath, "utf8"); - jsonData = JSON.parse(data); - } catch (error) { - console.error("Error reading or parsing the file:", error); - return null; - } - - console.log("Found", jsonData.keypresses.length, "ticks"); - const inputs = { - gameId: 1, - ...jsonData, - }; - - const signature = await signMessage(wallet, EndGameSchema, inputs); - const incrementAction = EndGameSchema.actionFrom({ - inputs, - signature, - msgSender: wallet.address, - }); - - const ack = await mru.submitAction("endGame", incrementAction); - // console.log(ack); -}; - const main = async () => { await mru.init(); @@ -113,8 +82,19 @@ const main = async () => { app.get("/leaderboard", async (_req, res) => { const { state } = stateMachine; - const topTen = [...state.games] - .sort((a, b) => b.score - a.score) + const sortedScores = [...state.games].sort((a, b) => b.score - a.score); + // make sure to return one entry per player + const players = new Set(); + + // TODO: store this in app instance later + const topTen = sortedScores + .filter((game) => { + if (players.has(game.player)) { + return false; + } + players.add(game.player); + return true; + }) .slice(0, 10); const leaderboard = topTen.map((game) => ({ @@ -167,5 +147,3 @@ const main = async () => { }; main(); - -// notMain(); diff --git a/rollup/stackr/action.ts b/rollup/stackr/action.ts index 5e023de..dfedd69 100644 --- a/rollup/stackr/action.ts +++ b/rollup/stackr/action.ts @@ -8,7 +8,7 @@ export const EndGameSchema = new ActionSchema("endGame", { gameId: SolidityType.UINT, timestamp: SolidityType.UINT, // nonce score: SolidityType.UINT, - ticks: [ + gameInputs: [ { v: SolidityType.STRING, }, diff --git a/rollup/stackr/transitions.ts b/rollup/stackr/transitions.ts index b5a1710..58a685b 100644 --- a/rollup/stackr/transitions.ts +++ b/rollup/stackr/transitions.ts @@ -11,7 +11,7 @@ export type CreateGame = { export type ValidateGameInput = { gameId: number; score: number; - ticks: { v: string }[]; + gameInputs: { v: string }[]; }; const startGame: STF = { @@ -37,7 +37,7 @@ const startGame: STF = { const endGame: STF = { handler: ({ state, inputs, msgSender }) => { - const { ticks, gameId, score } = inputs; + const { gameInputs, gameId, score } = inputs; const { games } = state; if (!games[gameId]) { throw new Error("Game not found"); @@ -53,7 +53,7 @@ const endGame: STF = { const world = new World(0); const gameMode = new GameMode(world); - for (const t of ticks) { + for (const t of gameInputs) { gameMode.deserializeAndUpdate(1 / 60, t); }