Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Staging #228

Open
wants to merge 19 commits into
base: develop
Choose a base branch
from
Open

Staging #228

wants to merge 19 commits into from

Conversation

okhaimie-dev
Copy link
Contributor

@okhaimie-dev okhaimie-dev commented Jan 14, 2025

Summary by CodeRabbit

Release Notes

  • New Features

    • Added trophy and achievement system for tracking player progress
    • Introduced new game tasks and trophy types
    • Enhanced player profile management
  • Improvements

    • Updated game namespace from "mancala_dev" to "mancala_alpha"
    • Refactored game systems and components
    • Improved error handling and state management
  • Performance

    • Optimized contract interactions
    • Updated Dojo engine dependencies
  • UI/UX

    • Refreshed visual styling for various components
    • Added new icons and visual elements
    • Improved connection and account management
  • Chores

    • Updated package and dependency versions
    • Restructured project modules and configurations

okhaimie-dev and others added 19 commits January 7, 2025 02:38
…pdated position data to include player and opponent states with native and non-native coordinates. Simplified position retrieval logic based on pit number and player type. Improved animation handling for seed positioning.
* opponents position update

* isNative confirmations

* pit 7 ops

* pit 7 plays

* pit 7 plays

* prettier

* update dojo config
* feat: fixed the trophy icon set

* feat: arcade progression wip

* feat: trophy element changes & controller client config

* feat: torii config

* feat: wip header
* fixed burner issue

* fixed burner issue

* fixed burner issue

* loading screen upgrade

* loading screen upgrade

* up update

* optimize tables

* update ui

* changed text color in game board

* added error boundary ui

* optimized user section

* optimized user section

* default url

* auto connect

* Merge into staging-ui-upgrade

* add eliza

* ui update

* ui update

* fixed build issue

* eliza starter

* eliza starter

* animate-spin

---------

Co-authored-by: kelvin_joshua <[email protected]>
* fix: patch first attempt

* fix: path2 achievements
Copy link

vercel bot commented Jan 14, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
mancala ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jan 14, 2025 10:59pm
mancala-pkco ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jan 14, 2025 10:59pm

Copy link

coderabbitai bot commented Jan 14, 2025

Walkthrough

This pull request introduces significant updates to the Mancala game project, focusing on transitioning from a development environment to an alpha stage. The changes span across multiple components, including client-side configuration, game mechanics, profile management, and contract systems. Key modifications include updating namespaces, introducing trophy and task systems, enhancing game interactions, and refactoring the overall project structure.

Changes

File/Group Change Summary
.gitignore Added .env and redundant node_modules entries
dev.sh New shell script for concurrent development server startup
dojoConfig.ts Updated Torii and master address configurations
package.json Modified dev script, updated dependencies
Client Components Numerous UI and interaction updates across various components
Contract Systems Comprehensive restructuring of game systems, introducing trophy and task implementations
Configuration Files Updated namespaces from mancala_dev to mancala_alpha

Sequence Diagram

sequenceDiagram
    participant Player
    participant GameSystem
    participant ProfileSystem
    participant AchievementSystem

    Player->>GameSystem: Create Game
    GameSystem->>ProfileSystem: Initialize Player Profile
    ProfileSystem-->>GameSystem: Profile Created
    GameSystem->>AchievementSystem: Register Initial Tasks
    Player->>GameSystem: Make Move
    GameSystem->>AchievementSystem: Update Player Progress
    AchievementSystem->>GameSystem: Progress Tracked
    GameSystem->>AchievementSystem: Check Trophy Conditions
    AchievementSystem-->>Player: Trophy Awarded
Loading

Possibly related PRs

Suggested reviewers

  • supreme2580

Finishing Touches

  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 35

🔭 Outside diff range comments (2)
contracts/src/tests/test_world.cairo (1)

Line range hint 46-46: Use set_caller_address instead of set_contract_address for changing the caller

You are using set_contract_address(ANYONE); to change the caller in the test. However, set_contract_address sets the address of the current contract, not the caller's address. To simulate calls from different accounts, you should use set_caller_address(ANYONE);.

Apply this diff to fix the issue:

-            set_contract_address(ANYONE);
+            set_caller_address(ANYONE);
contracts/dojo_dev.toml (1)

Line range hint 27-31: Security: IPFS credentials should not be in version control

The configuration file contains hardcoded IPFS credentials, which poses a security risk.

Consider:

  1. Moving credentials to environment variables
  2. Using a secure secrets management solution
  3. Rotating the exposed credentials immediately
-ipfs_config.username = "2EBrzr7ZASQZKH32sl2xWauXPSA"
-ipfs_config.password = "12290b883db9138a8ae3363b6739d220"
+ipfs_config.username = "${IPFS_USERNAME}"
+ipfs_config.password = "${IPFS_PASSWORD}"
🧹 Nitpick comments (48)
client/src/AppWrapper.tsx (2)

27-34: Consider enhancing edge case handling

While the current implementation is good, consider handling the case where currentStep exists but isn't a key in SETUP_STATUS_MESSAGES.

  return currentStep
-   ? SETUP_STATUS_MESSAGES[currentStep as keyof typeof SETUP_STATUS_MESSAGES]
+   ? SETUP_STATUS_MESSAGES[currentStep as keyof typeof SETUP_STATUS_MESSAGES] ?? "Setting up game..."
    : "Loading...";

48-53: Consider optimizing logo animation performance

The animated logo looks good, but continuous animation might impact performance on lower-end devices. Consider:

  • Using CSS animation-duration with a slower speed
  • Implementing will-change: transform for better performance
  • Adding @media (prefers-reduced-motion: reduce) support
- <img src={logo} width={126} height={126} alt="logo" className="animate-spin" />
+ <img 
+   src={logo} 
+   width={126} 
+   height={126} 
+   alt="logo" 
+   className="animate-spin motion-safe:animate-spin will-change-transform" 
+   style={{ animationDuration: '3s' }} 
+ />
client/src/components/lobby/leaderboard.tsx (3)

10-11: Consider using responsive design patterns.

The current implementation uses fixed dimensions which may cause layout issues on different screen sizes. Consider:

  1. Using relative units (e.g., vh, vw) or responsive classes for container heights
  2. Implementing responsive width classes instead of fixed pixel values
  3. Ensuring the scrollable div's height (500px) aligns with its container (437px)
-    <div className="bg-[#0F1116] bg-contain bg-center bg-no-repeat border-2 border-[#272A32] rounded-2xl w-[928px] h-[437px] flex flex-col items-center justify-center px-8">
-      <div className="w-[928px] rounded-t-xl rounded-b-xl fixed h-[500px] overflow-y-scroll hide-scrollbar pb-4">
+    <div className="bg-[#0F1116] bg-contain bg-center bg-no-repeat border-2 border-[#272A32] rounded-2xl w-full max-w-[928px] h-[437px] flex flex-col items-center justify-center px-8">
+      <div className="w-full rounded-t-xl rounded-b-xl fixed h-[437px] overflow-y-scroll hide-scrollbar pb-4">

20-26: Review sticky header positioning.

The negative top value in sticky positioning might cause inconsistent behavior across browsers. Consider using a positive offset and adjusting the container padding instead.

-            <thead className="sticky -top-3.5 bg-[#0F1116] z-10">
+            <thead className="sticky top-0 bg-[#0F1116] z-10">

35-105: Consider performance optimizations for large datasets.

The current implementation might face performance issues with large datasets. Consider:

  1. Implementing virtualization for the table rows
  2. Adding pagination or infinite scroll
  3. Memoizing the player row component

Would you like me to provide an example implementation using react-window or react-virtualized?

client/src/components/profile/game-history.tsx (2)

69-71: Consider adding error handling for the empty state check.

The empty state check could be more robust by handling undefined/null cases.

-  } else if (data?.length === 0) {
+  } else if (!data || data.length === 0) {

105-111: Improve date handling and memoize color calculations.

The color and date calculations could be optimized:

  1. Date parsing on every render
  2. Color calculations could be memoized
+ const memoizedColors = useMemo(() => {
+   return data?.map((_, index) => ({
+     challenger: colors[index % colors.length],
+     challenged: colors[(index + 3) % colors.length]
+   }));
+ }, [data?.length]);

  return (
    // ... in the map function:
-   const challengerColor = colors[index % colors.length];
-   const challengedColor = colors[(index + 3) % colors.length];
-   const date = new Date(item.date);
+   const { challenger: challengerColor, challenged: challengedColor } = memoizedColors[index];
+   const date = useMemo(() => new Date(item.date), [item.date]);
contracts/src/components/initializable.cairo (1)

34-34: Consider defining error messages in an errors module for consistency.

For better maintainability and consistency across components, define the error message 'Counter already initialized' in an errors module, similar to other components.

Apply this diff to refactor:

+// Errors
+mod errors {
+    const COUNTER_ALREADY_INITIALIZED: felt252 = 'Counter already initialized';
+}
 
...

-assert(current_game_counter.count == 0, 'Counter already initialized');
+assert(current_game_counter.count == 0, errors::COUNTER_ALREADY_INITIALIZED);
contracts/src/systems/profile.cairo (1)

38-46: Add input validation for name and new_uri parameters.

Currently, there is no validation on the name and new_uri parameters in the create_player_profile and update_player_profile functions. Consider adding input validation to ensure these parameters meet expected criteria (e.g., length limits, acceptable character sets) to enhance security and prevent potential issues.

contracts/src/components/profile.cairo (2)

27-39: Add input validation for name parameter in new_profile function.

To ensure data integrity and prevent potential issues, consider adding validation for the name parameter in the new_profile function.


41-55: Add input validation for name and new_uri parameters in update_player_profile function.

Adding input validation for the name and new_uri parameters in the update_player_profile function will enhance security and prevent potential issues.

client/src/components/header.tsx (1)

103-137: Simplify conditional rendering for better readability.

The current conditional rendering logic within the JSX is a bit complex and can be refactored for clarity. Consider creating separate components or helper functions for the different button states to make the code more maintainable and easier to read.

contracts/src/systems/mancala.cairo (1)

62-88: Add error handling for the initialization process.

In the dojo_init function, there is no error handling for the initialization processes of initializable and achievable components. Consider adding error handling or logging to capture any issues that may arise during initialization.

Apply this diff to add error handling:

fn dojo_init(self: @ContractState) {
-   self.initializable.initialize(self.world_storage());
+   let init_result = self.initializable.initialize(self.world_storage());
+   if init_result.is_err() {
+       // Handle the error accordingly
+   }

    // [Event] Emit all Trophy events
    let world = self.world(@NAMESPACE());
    let mut trophy_id: u8 = TROPHY_COUNT;
    while trophy_id > 0 {
        let trophy: Trophy = trophy_id.into();
        let create_result = self
            .achievable
            .create(
                world,
                id: trophy.identifier(),
                hidden: trophy.hidden(),
                index: trophy.index(),
                points: trophy.points(),
                start: trophy.start(),
                end: trophy.end(),
                group: trophy.group(),
                icon: trophy.icon(),
                title: trophy.title(),
                description: trophy.description(),
                tasks: trophy.tasks(),
                data: trophy.data(),
            );
+       if create_result.is_err() {
+           // Handle the error accordingly
+       }
        trophy_id -= 1;
    }
}
client/src/components/gameplay/game-board.tsx (2)

58-96: Consider refactoring duplicate useEffect hooks for better maintainability

The useEffect hooks for handling captures (lines 58~ to 76~) and extra turns (lines 78~ to 96~) have similar structures. Refactoring this logic into a reusable function or a custom hook can reduce code duplication and improve code maintainability.

Here's how you might abstract the common logic:

+const useGameEventNotification = (data, dataKey, titleMap, descriptionMap) => {
+  const { toast } = useToast();
+  useEffect(() => {
+    const events = data?.[dataKey]?.edges;
+    if (events && events.length > 0) {
+      const latestEvent = events[events.length - 1]?.node;
+
+      if (latestEvent) {
+        const isPlayerEvent = latestEvent.player === account.account?.address;
+
+        toast({
+          title: isPlayerEvent ? titleMap.player : titleMap.opponent,
+          description: isPlayerEvent
+            ? descriptionMap.player(latestEvent)
+            : descriptionMap.opponent(latestEvent),
+          duration: 3000,
+        });
+      }
+    }
+  }, [data, account.account?.address, toast]);
+};
+
 useEffect(() => {
-  const captures = captureData?.mancalaAlphaCaptureModels?.edges;
-  if (captures && captures.length > 0) {
-    const latestCapture = captures[captures.length - 1]?.node;
-
-    if (latestCapture) {
-      const isPlayerCapture =
-        latestCapture.player === account.account?.address;
-
-      toast({
-        title: isPlayerCapture ? "Seeds Captured!" : "Seeds Lost!",
-        description: isPlayerCapture
-          ? `You captured ${latestCapture.seed_count} seeds from pit ${latestCapture.pit_number}`
-          : `Opponent captured ${latestCapture.seed_count} seeds from pit ${latestCapture.pit_number}`,
-        duration: 3000,
-      });
-    }
-  }
+  useGameEventNotification(
+    captureData,
+    'mancalaAlphaCaptureModels',
+    { player: 'Seeds Captured!', opponent: 'Seeds Lost!' },
+    {
+      player: (event) => `You captured ${event.seed_count} seeds from pit ${event.pit_number}`,
+      opponent: (event) => `Opponent captured ${event.seed_count} seeds from pit ${event.pit_number}`,
+    }
+  );
 }, [captureData, account.account?.address, toast]);

 useEffect(() => {
-  const extraTurns = extraTurnData?.mancalaAlphaPlayerExtraTurnModels?.edges;
-  if (extraTurns && extraTurns.length > 0) {
-    const latestExtraTurn = extraTurns[extraTurns.length - 1]?.node;
-
-    if (latestExtraTurn) {
-      const isPlayerExtraTurn =
-        latestExtraTurn.player === account.account?.address;
-
-      toast({
-        title: isPlayerExtraTurn ? "Extra Turn!" : "Opponent Extra Turn",
-        description: isPlayerExtraTurn
-          ? "You get another turn!"
-          : "Opponent gets another turn",
-        duration: 3000,
-      });
-    }
-  }
+  useGameEventNotification(
+    extraTurnData,
+    'mancalaAlphaPlayerExtraTurnModels',
+    { player: 'Extra Turn!', opponent: 'Opponent Extra Turn' },
+    {
+      player: () => 'You get another turn!',
+      opponent: () => 'Opponent gets another turn',
+    }
+  );
 }, [extraTurnData, account.account?.address, toast]);

151-161: Simplify seed count retrieval using .find

When calculating player_pot_seed_count and opponent_pot_seed_count, you can replace the chained .filter() calls with a single .find() to improve efficiency and readability.

Here's the suggested change:

-player_pot_seed_count =
  game_players?.mancalaAlphaPitModels.edges
    .filter(
      (item: any) =>
        item?.node.player ===
          game_players?.mancalaAlphaPlayerModels.edges[player_position]?.node.address,
    )
    .filter((item: any) => item?.node.pit_number === 7)[0]?.node
    ?.seed_count || 0;
+player_pot_seed_count =
+  game_players?.mancalaAlphaPitModels.edges
+    .find(
+      (item: any) =>
+        item?.node.player ===
+          game_players?.mancalaAlphaPlayerModels.edges[player_position]?.node.address &&
+        item?.node.pit_number === 7,
+    )?.node
+    ?.seed_count || 0;

Apply the same logic to opponent_pot_seed_count.

client/src/components/gameplay/game-message.tsx (2)

205-285: Avoid logging sensitive game data in production

The console.log statements in constructElizaMessage (lines 207~ and 241~) can expose sensitive game data in the browser's console. Consider removing or conditioning these logs to prevent potential information leakage.

[security_issue]

Remove or conditionally disable debug logs:

-  console.log({ game_node });
...
-  console.log({
-    message
-  })

281-287: Optimize address normalization function

The normalizeAddress function can lead to inconsistent results if addresses are not in the expected format. Consider using a standardized library or method for address normalization to ensure consistency across different parts of the application.

Alternatively, adjust the function to handle different possible address formats robustly.

contracts/src/types/trophy.cairo (2)

28-40: Simplify level method implementation

The level method contains repeated patterns that can be simplified. As all trophies except Trophy::None have an associated level, consider refactoring to eliminate redundancy.

Example:

fn level(self: Trophy) -> u8 {
    match self {
        Trophy::None => 0,
        _ => {
            // Define a mapping from Trophy variant to level, if possible.
        },
    }
}

267-272: Implement a more informative print method

The print method currently prints the trophy's identifier. For better debugging and logging, consider including more descriptive information, such as the trophy's name or level.

Example:

fn print(self: Trophy) {
    self.title().print();
}
contracts/src/tests/test_world.cairo (1)

389-389: Consider removing commented-out code

The code at line 389~ is commented out. If this code is no longer needed, consider removing it to keep the codebase clean. If you plan to use it later, add a comment explaining its purpose.

client/src/components/profile/user-section.tsx (1)

113-113: Simplify null checks using optional chaining

You can simplify the null checks by using optional chaining when accessing event.target.files[0].

Apply this diff to simplify the code:

-        if (event.target.files && event.target.files[0]) {
+        if (event.target.files?.[0]) {
🧰 Tools
🪛 Biome (1.9.4)

[error] 113-113: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

contracts/src/components/playable.cairo (1)

243-264: Duplicate code when updating task progress

The code for updating task progress after capturing seeds is duplicated. Consider refactoring this into a helper function to improve maintainability.

Extract the repeated code into a function, for example:

fn update_task_progress(player_address: ContractAddress, captured_seeds: u8, world: WorldStorage) {
    let arcade_store: ArcadeStore = ArcadeStoreTrait::new(world);
    let task_id = Task::Collecting.identifier(0);
    let extractor_task_id = Task::Clearing.identifier(0);
    let time = get_block_timestamp();
    arcade_store.progress(player_address.into(), task_id, captured_seeds.into(), time);
    arcade_store.progress(player_address.into(), extractor_task_id, captured_seeds.into(), time);
}

Then call update_task_progress where needed.

client/src/lib/constants.ts (2)

783-812: Handle Possible Empty Results in New Queries

The new MancalaCaptureQuery and MancalaExtraTurnQuery have been added. Ensure that the application gracefully handles scenarios where these queries return empty results or errors to prevent runtime exceptions.

Consider adding default values or checks when processing the data returned by these queries.


813-1100: Optimize the positions Function for Maintainability

The positions function contains extensive hard-coded coordinate arrays, which can be difficult to maintain and prone to errors. Refactor the function to generate coordinates programmatically if possible.

Consider the following suggestions:

  • Mathematical Generation: Use mathematical formulas to calculate positions based on indices.

  • Data Structures: Store patterns or offsets in a data structure that can be looped over.

  • Helper Functions: Break down the coordinate generation into smaller helper functions for clarity.

Example refactor:

export const positions = (type: "player" | "opponent" | undefined) =>
  Array.from({ length: 7 }, (_, playerIndex) => {
    const xBase = type === "player" ? playerIndex * 120 : 600 - playerIndex * 120;
    const yBase = type === "player" ? 0 : -110;

    const generateCoords = () => {
      let coords = [];
      for (let i = 0; i < NUM_SEEDS; i++) {
        coords.push({
          x: xBase + calculateXOffset(i),
          y: yBase + calculateYOffset(i),
        });
      }
      return coords;
    };

    return {
      player: {
        native: generateCoords(),
        non_native: generateCoords(),
      },
      opponent: {
        native: generateCoords(),
        non_native: generateCoords(),
      },
    };
  });

Where calculateXOffset and calculateYOffset are functions that compute offsets.

contracts/src/elements/tasks/mastering.cairo (1)

11-11: Improve description grammar.

The current message "Get {} games win streak" could be clearer. Consider these alternatives:

  • "Get a {} game win streak"
  • "Win {} games in a row"
-        format!("Get {} games win streak", count)
+        format!("Get a {} game win streak", count)
contracts/src/elements/tasks/collecting.cairo (1)

11-11: Improve description clarity and grammar.

The current message has grammar issues and could be more concise:

  1. "seed" should be plural when count > 1
  2. "in game lifetime history" is verbose
-        format!("Collect {} seed in game lifetime history", count)
+        format!("Collect {} seeds throughout your games", count)
contracts/src/elements/trophies/interface.cairo (1)

4-15: Well-structured trophy system interface.

The TrophyTrait provides a comprehensive interface for trophy management with:

  • Clear separation between trophy attributes and tasks
  • Type-safe level parameters
  • Flexible task integration via BushidoTask

Consider adding documentation comments for each method to improve maintainability.

client/src/components/controller-trophy.tsx (1)

16-20: Add loading state to prevent multiple clicks.

The button should show a loading state while the profile is being opened.

+  const [isLoading, setIsLoading] = useState(false);
+
+  const handleTrophyClick = useCallback(async () => {
+    setIsLoading(true);
     if (!connector?.controller) {
       // error handling
+      setIsLoading(false);
       return;
     }
-    connector?.controller.openProfile("achievements");
+    try {
+      await connector.controller.openProfile("achievements");
+    } finally {
+      setIsLoading(false);
+    }
   }, [connector]);

   return (
-    <Button variant="outline" onClick={() => handleTrophyClick()}>
+    <Button variant="outline" onClick={handleTrophyClick} disabled={isLoading}>
       <Trophy />
     </Button>
   );
client/src/components/lobby/empty-duels.tsx (1)

3-3: Props interface should be extracted.

For better maintainability and reuse, define a separate props interface.

+interface EmptyDuelsProps {
+  message: string;
+  onCreateGame?: () => void;
+}
-export default function EmptyDuels({ message }: { message: string })
+export default function EmptyDuels({ message, onCreateGame }: EmptyDuelsProps)
contracts/src/lib.cairo (1)

21-51: Well-structured module organization!

The new module structure effectively separates concerns and provides a clear hierarchy for the game's components:

  • Components layer for core functionalities
  • Elements layer for task and trophy management
  • Systems layer for game mechanics
  • Types layer for shared enums

This organization promotes maintainability and follows good architectural practices.

Consider documenting the responsibility of each module layer in the README to help future contributors understand the codebase structure.

contracts/src/elements/trophies/victor.cairo (1)

3-54: Well-structured trophy implementation!

The implementation follows a clear pattern and provides all necessary properties for the trophy system.

Consider documenting magic numbers.

The implementation uses magic numbers for points (100) and count (100). Consider extracting these to named constants with documentation explaining their significance.

+/// Points awarded for achieving the Victor trophy
+const VICTOR_POINTS: u16 = 100;
+/// Number of tasks required to earn the Victor trophy
+const VICTOR_TASK_COUNT: u32 = 100;
+
 impl Victor of TrophyTrait {
     #[inline]
     fn points(level: u8) -> u16 {
-        100
+        VICTOR_POINTS
     }
     
     #[inline]
     fn count(level: u8) -> u32 {
-        100
+        VICTOR_TASK_COUNT
     }
 }
contracts/src/elements/trophies/dominator.cairo (1)

3-54: Consistent trophy implementation!

The implementation follows the same pattern as other trophies, maintaining consistency across the codebase.

Consider extracting common patterns and documenting magic numbers.

  1. The implementation uses magic numbers for points (50) and count (500). Consider extracting these to named constants.
  2. There's potential for code duplication across trophy implementations. Consider extracting common patterns into a base implementation.
+/// Points awarded for achieving the Dominator trophy
+const DOMINATOR_POINTS: u16 = 50;
+/// Number of tasks required to earn the Dominator trophy
+const DOMINATOR_TASK_COUNT: u32 = 500;
+
 impl Dominator of TrophyTrait {
     #[inline]
     fn points(level: u8) -> u16 {
-        50
+        DOMINATOR_POINTS
     }
     
     #[inline]
     fn count(level: u8) -> u32 {
-        500
+        DOMINATOR_TASK_COUNT
     }
 }

Consider creating a macro to reduce boilerplate across trophy implementations:

// Example macro (syntax may need adjustment)
macro_rules! implement_trophy {
    ($name:ident, $id:expr, $points:expr, $count:expr) => {
        impl $name of TrophyTrait {
            // Common implementation details...
        }
    }
}
client/src/components/boundaries/error-boundary.tsx (1)

16-29: Enhanced error UI with better visual hierarchy!

The updated error boundary provides a more polished and user-friendly experience.

Consider accessibility improvements.

While the UI looks good, consider enhancing accessibility:

  1. Add aria-label to the error container
  2. Ensure sufficient color contrast for text visibility
  3. Add aria-live region for screen readers
 <div
   role="alert"
+  aria-label="Error occurred"
   className="grid w-full h-screen place-items-center bg-[#0F1116] bg-[url('./assets/bg.png')] bg-cover bg-center"
 >
   <div className="flex flex-col items-center justify-center space-y-4">
-    <div className="flex flex-col items-center justify-center space-y-1.5 w-[400px] h-[275px] rounded-lg bg-[#4920003D] backdrop-blur-md">
+    <div 
+      className="flex flex-col items-center justify-center space-y-1.5 w-[400px] h-[275px] rounded-lg bg-[#4920003D] backdrop-blur-md"
+      aria-live="polite"
+    >
       <img src={logo} width={126} height={126} alt="logo" />
       <h2 className="text-white font-semibold">Ouch, an error occurred</h2>
-      <div className="text-white/80 text-center px-4">{error.message}</div>
+      <div className="text-white/90 text-center px-4">{error.message}</div>
client/src/pages/Home.tsx (1)

24-27: Consider adding loading state to the button.

The connection process might take time, and the button should reflect this state to improve user experience.

  <button className="bg-[#1A1D25] text-[#F58229] py-2.5 px-7 rounded-full flex flex-row items-center justify-center space-x-1">
    <Bubble />
-   <p>Go to lobby</p>
+   <p>{account ? 'Go to lobby' : 'Connecting...'}</p>
  </button>
contracts/src/elements/trophies/strategist.cairo (1)

80-83: Document the task type choice.

The use of Task::Mastering instead of Task::Collecting should be documented to explain the different requirements.

Add a comment explaining why Mastering tasks are used for the Strategist trophy:

  fn tasks(level: u8) -> Span<BushidoTask> {
+     // Using Mastering tasks as they represent strategic gameplay achievements
      let total: u32 = Self::count(level);
      Task::Mastering.tasks(level, total, total)
  }
client/src/components/pits.tsx (1)

56-56: Consider adding error handling for audio playback.

While the sound effect integration is good, consider wrapping the playEmptyPitSound() call in a try-catch block to handle potential audio playback failures gracefully.

-      playEmptyPitSound();
+      try {
+        playEmptyPitSound();
+      } catch (error) {
+        console.warn('Failed to play sound effect:', error);
+      }
client/src/components/seed.tsx (1)

24-34: Consider memoizing position calculations more efficiently.

The current implementation recalculates positions on every render. Consider simplifying the condition chain.

 const position = useMemo(() => {
-  return isNative && type === "player"
-    ? _positions[pit_number - 1]?.player?.native[seed_number - 1]
-    : isNative && type === "opponent"
-      ? _positions[pit_number - 1]?.opponent?.native[seed_number - 1]
-      : !isNative && type === "player"
-        ? _positions[pit_number - 1]?.player?.non_native[seed_number - 1]
-        : !isNative && type === "opponent"
-          ? _positions[pit_number - 1]?.opponent?.non_native[seed_number - 1]
-          : { x: 0, y: 0 };
+  if (!type || pit_number < 1 || seed_number < 1) {
+    return { x: 0, y: 0 };
+  }
+  const positionType = isNative ? 'native' : 'non_native';
+  return _positions[pit_number - 1]?.[type]?.[positionType]?.[seed_number - 1] || { x: 0, y: 0 };
 }, [isNative, type, _positions, pit_number, seed_number]);
client/src/pages/Profile.tsx (1)

39-44: Consider adding error handling for auto-connect.

While auto-connect improves UX, it should handle potential connection failures gracefully.

 useEffect(() => {
   if (!account?.account?.address) {
-    connect({ connector: connectors[0] });
+    try {
+      connect({ connector: connectors[0] });
+    } catch (error) {
+      console.error('Failed to auto-connect:', error);
+      // Consider showing a user-friendly error message
+    }
   }
 }, [account, connect, connectors]);
client/src/components/lobby/duels-skeleton.tsx (1)

43-43: Consider making the number of skeleton rows configurable.

The hardcoded value of 5 rows could be made configurable to better match different view states.

+const SKELETON_ROWS = 5;
 export function DuelsSkeleton() {
   return (
     // ...
-    {Array.from({ length: 5 }).map((_, index) => {
+    {Array.from({ length: SKELETON_ROWS }).map((_, index) => {
client/src/pages/games/Gameplay.tsx (1)

55-60: Consider user consent for automatic wallet connection.

While automatic connection enhances UX, it's best practice to request user consent before connecting to their wallet. Consider adding a connection prompt or button for better user control.

-  useEffect(() => {
-    if (!account?.account?.address) {
-      connect({ connector: connectors[0] });
-    }
-  }, [account, connect, connectors]);
+  useEffect(() => {
+    const autoConnect = localStorage.getItem('autoConnect') === 'true';
+    if (!account?.account?.address && autoConnect) {
+      connect({ connector: connectors[0] });
+    }
+  }, [account, connect, connectors]);
client/src/components/lobby/live-duels.tsx (1)

12-30: Consider making the filter condition more explicit.

While filtering out "0x0" addresses is correct, consider making the validation more explicit for better maintainability.

-  const data = games
-    ?.filter(
-      (game: any) =>
-        game.node.player_one !== "0x0" && game.node.player_two !== "0x0",
-    )
+  const isValidAddress = (address: string) => address !== "0x0";
+  const data = games
+    ?.filter(
+      (game: any) =>
+        isValidAddress(game.node.player_one) && isValidAddress(game.node.player_two),
+    )
contracts/src/utils/board.cairo (1)

Line range hint 214-243: LGTM! Consider documenting the return value.

The modification to return the total number of captured seeds is a good addition that could be useful for tracking game statistics or achievements. The implementation correctly calculates the total before modifying the game state.

Consider adding a comment to document that the function returns the total number of seeds captured, which could help other developers understand the purpose of this return value.

client/src/components/lobby/duels.tsx (2)

102-136: Consider extracting table components for better maintainability.

The table structure is well-organized but quite complex. Consider extracting the table header and row components to improve code maintainability and reusability.


291-330: Enhance accessibility for sharing buttons.

The sharing functionality is well-implemented, but consider adding ARIA labels and keyboard navigation support for better accessibility.

Example improvements:

-<div className="flex flex-row items-center justify-center space-x-1 pr-10 cursor-pointer"
+<button
+  aria-label={copied ? "Game link copied" : "Copy game link"}
+  className="flex flex-row items-center justify-center space-x-1 pr-10 cursor-pointer"
client/src/pages/Lobby.tsx (2)

373-397: Consider using radio group for player type selection.

The player type selection using buttons could be improved by using a radio group component for better accessibility and state management.

Example improvement:

-<div className="flex flex-row items-center justify-center space-x-3.5">
+<RadioGroup
+  value={playWith}
+  onValueChange={setPlayWith}
+  className="flex flex-row items-center justify-center space-x-3.5"
+>
   <button>Human Player</button>
   <button>Play with Eliza AI</button>
-</div>
+</RadioGroup>

400-408: Remove unnecessary fragment.

The fragment wrapper is redundant as it contains only one child element.

Apply this diff to fix the issue:

-{playWith === "Human" && (
-  <>
-    <input
-      className="p-2.5 w-72 rounded-xl border border-[#1D212B] bg-transparent outline-none placeholder:text-[#4F5666] placeholder:font-medium text-[#4F5666] font-medium"
-      placeholder="0x..."
-      onChange={(e) => setPlayer2(e.target.value)}
-    />
-  </>
-)}
+{playWith === "Human" && (
+  <input
+    className="p-2.5 w-72 rounded-xl border border-[#1D212B] bg-transparent outline-none placeholder:text-[#4F5666] placeholder:font-medium text-[#4F5666] font-medium"
+    placeholder="0x..."
+    onChange={(e) => setPlayer2(e.target.value)}
+  />
+)}
🧰 Tools
🪛 Biome (1.9.4)

[error] 401-407: Avoid using unnecessary Fragment.

A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment

(lint/complexity/noUselessFragments)

contracts/src/elements/trophies/extractor.cairo (1)

20-22: Consider extracting magic numbers as constants

The points() and count() methods use magic numbers (100 and 10000). Consider extracting these as named constants for better maintainability.

+const EXTRACTOR_POINTS: u16 = 100;
+const EXTRACTOR_COUNT: u32 = 10000;
+
 impl Extractor of TrophyTrait {
     #[inline]
     fn points(level: u8) -> u16 {
-        100
+        EXTRACTOR_POINTS
     }
     
     #[inline]
     fn count(level: u8) -> u32 {
-        10000
+        EXTRACTOR_COUNT
     }

Also applies to: 45-47

contracts/manifest_dev.json (1)

1611-1616: New achievement system implementation detected.

The addition of AchievableComponent and trophy-related events (TrophyCreation, TrophyProgression) suggests a new achievement system. This enhances the game's engagement mechanics.

Consider implementing the following for the achievement system:

  1. Achievement progress persistence
  2. Achievement notification system
  3. Achievement unlock conditions validation

Also applies to: 1961-1968

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9675cc8 and 4d6c4f9.

⛔ Files ignored due to path filters (39)
  • .github/workflows/test.yml is excluded by none and included by none
  • .gitignore is excluded by none and included by none
  • client/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml, !client/pnpm-lock.yaml and included by client/**
  • client/src/assets/bg.png is excluded by !**/*.png and included by client/**
  • client/src/assets/home-box.png is excluded by !**/*.png and included by client/**
  • client/src/assets/small-logo.png is excluded by !**/*.png and included by client/**
  • client/src/assets/square-avatar.png is excluded by !**/*.png and included by client/**
  • client/src/dojo/generated/generated.ts is excluded by !**/generated/** and included by client/**
  • client/src/dojo/generated/setup.ts is excluded by !**/generated/** and included by client/**
  • client/src/music/empty-pit.mp3 is excluded by !**/*.mp3 and included by client/**
  • client/src/music/seed-drop.mp3 is excluded by !**/*.mp3 and included by client/**
  • contracts/Scarb.lock is excluded by !**/*.lock and included by contracts/**
  • eliza-starter/.env.example is excluded by none and included by none
  • eliza-starter/.gitignore is excluded by none and included by none
  • eliza-starter/LICENSE is excluded by none and included by none
  • eliza-starter/README.md is excluded by none and included by none
  • eliza-starter/actions/join_game_action.ts is excluded by none and included by none
  • eliza-starter/actions/move_game_action.ts is excluded by none and included by none
  • eliza-starter/actions/new_game_action.ts is excluded by none and included by none
  • eliza-starter/characters/eliza.character.json is excluded by none and included by none
  • eliza-starter/characters/tate.character.json is excluded by none and included by none
  • eliza-starter/characters/trump.character.json is excluded by none and included by none
  • eliza-starter/dist/actions/join_game_action.d.ts is excluded by !**/dist/** and included by none
  • eliza-starter/dist/actions/move_game_action.d.ts is excluded by !**/dist/** and included by none
  • eliza-starter/dist/actions/new_game_action.d.ts is excluded by !**/dist/** and included by none
  • eliza-starter/dist/environment.d.ts is excluded by !**/dist/** and included by none
  • eliza-starter/dist/src/character.d.ts is excluded by !**/dist/** and included by none
  • eliza-starter/dist/src/index.d.ts is excluded by !**/dist/** and included by none
  • eliza-starter/dist/utils/index.d.ts is excluded by !**/dist/** and included by none
  • eliza-starter/environment.ts is excluded by none and included by none
  • eliza-starter/message-templates.json is excluded by none and included by none
  • eliza-starter/package.json is excluded by none and included by none
  • eliza-starter/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml and included by none
  • eliza-starter/src/character.ts is excluded by none and included by none
  • eliza-starter/src/index.ts is excluded by none and included by none
  • eliza-starter/tsconfig.json is excluded by none and included by none
  • eliza-starter/utils/index.ts is excluded by none and included by none
  • package.json is excluded by none and included by none
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml and included by none
📒 Files selected for processing (74)
  • client/.gitignore (1 hunks)
  • client/dev.sh (1 hunks)
  • client/dojoConfig.ts (1 hunks)
  • client/package.json (3 hunks)
  • client/src/App.tsx (2 hunks)
  • client/src/AppWrapper.tsx (2 hunks)
  • client/src/components/boundaries/error-boundary.tsx (2 hunks)
  • client/src/components/controller-trophy.tsx (1 hunks)
  • client/src/components/gameplay/end-game-button.tsx (1 hunks)
  • client/src/components/gameplay/game-board.tsx (7 hunks)
  • client/src/components/gameplay/game-message.tsx (6 hunks)
  • client/src/components/gameplay/game-navigation.tsx (1 hunks)
  • client/src/components/gameplay/restart-button.tsx (1 hunks)
  • client/src/components/gameplay/timeout-button.tsx (1 hunks)
  • client/src/components/header.tsx (3 hunks)
  • client/src/components/lobby/duels-skeleton.tsx (1 hunks)
  • client/src/components/lobby/duels.tsx (2 hunks)
  • client/src/components/lobby/empty-duels.tsx (1 hunks)
  • client/src/components/lobby/leaderboard.tsx (2 hunks)
  • client/src/components/lobby/live-duels.tsx (5 hunks)
  • client/src/components/message-area.tsx (2 hunks)
  • client/src/components/pits.tsx (3 hunks)
  • client/src/components/profile/empty-game-history.tsx (1 hunks)
  • client/src/components/profile/game-history-skeleton.tsx (1 hunks)
  • client/src/components/profile/game-history.tsx (1 hunks)
  • client/src/components/profile/user-section.tsx (5 hunks)
  • client/src/components/seed.tsx (2 hunks)
  • client/src/components/ui/dialog.tsx (1 hunks)
  • client/src/components/ui/svgs/bubble.tsx (1 hunks)
  • client/src/components/ui/svgs/users-plus.tsx (1 hunks)
  • client/src/dojo/DojoContext.tsx (2 hunks)
  • client/src/dojo/createSystemCalls.ts (1 hunks)
  • client/src/hooks/useAudioControl.ts (4 hunks)
  • client/src/hooks/useControllerData.ts (0 hunks)
  • client/src/lib/config.ts (1 hunks)
  • client/src/lib/constants.ts (9 hunks)
  • client/src/pages/Home.tsx (2 hunks)
  • client/src/pages/Leaderboard.tsx (0 hunks)
  • client/src/pages/Lobby.tsx (19 hunks)
  • client/src/pages/Profile.tsx (4 hunks)
  • client/src/pages/games/Gameplay.tsx (2 hunks)
  • contracts/.tool-versions (1 hunks)
  • contracts/Scarb.toml (2 hunks)
  • contracts/dojo_dev.toml (2 hunks)
  • contracts/dojo_sepolia.toml (2 hunks)
  • contracts/dojo_slot.toml (1 hunks)
  • contracts/manifest_dev.json (18 hunks)
  • contracts/manifest_sepolia.json (18 hunks)
  • contracts/src/components/initializable.cairo (1 hunks)
  • contracts/src/components/playable.cairo (14 hunks)
  • contracts/src/components/profile.cairo (1 hunks)
  • contracts/src/constants.cairo (1 hunks)
  • contracts/src/elements/tasks/clearing.cairo (1 hunks)
  • contracts/src/elements/tasks/collecting.cairo (1 hunks)
  • contracts/src/elements/tasks/dominating.cairo (1 hunks)
  • contracts/src/elements/tasks/interface.cairo (1 hunks)
  • contracts/src/elements/tasks/mastering.cairo (1 hunks)
  • contracts/src/elements/tasks/reigning.cairo (1 hunks)
  • contracts/src/elements/trophies/collector.cairo (1 hunks)
  • contracts/src/elements/trophies/dominator.cairo (1 hunks)
  • contracts/src/elements/trophies/extractor.cairo (1 hunks)
  • contracts/src/elements/trophies/interface.cairo (1 hunks)
  • contracts/src/elements/trophies/strategist.cairo (1 hunks)
  • contracts/src/elements/trophies/victor.cairo (1 hunks)
  • contracts/src/lib.cairo (1 hunks)
  • contracts/src/systems/actions.cairo (0 hunks)
  • contracts/src/systems/mancala.cairo (1 hunks)
  • contracts/src/systems/profile.cairo (1 hunks)
  • contracts/src/tests/setup.cairo (4 hunks)
  • contracts/src/tests/test_world.cairo (15 hunks)
  • contracts/src/types/task.cairo (1 hunks)
  • contracts/src/types/trophy.cairo (1 hunks)
  • contracts/src/utils/board.cairo (2 hunks)
  • contracts/torii_dev.toml (1 hunks)
💤 Files with no reviewable changes (3)
  • contracts/src/systems/actions.cairo
  • client/src/pages/Leaderboard.tsx
  • client/src/hooks/useControllerData.ts
✅ Files skipped from review due to trivial changes (9)
  • contracts/.tool-versions
  • client/src/components/gameplay/timeout-button.tsx
  • contracts/src/constants.cairo
  • client/src/components/gameplay/restart-button.tsx
  • client/src/components/gameplay/end-game-button.tsx
  • client/src/components/ui/svgs/users-plus.tsx
  • client/src/lib/config.ts
  • client/.gitignore
  • client/src/components/ui/svgs/bubble.tsx
🧰 Additional context used
🪛 Shellcheck (0.10.0)
client/dev.sh

[warning] 2-2: ShellCheck can't follow non-constant source. Use a directive to specify location.

(SC1090)

🪛 Biome (1.9.4)
client/src/pages/Lobby.tsx

[error] 401-407: Avoid using unnecessary Fragment.

A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment

(lint/complexity/noUselessFragments)

client/src/components/profile/user-section.tsx

[error] 113-113: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

client/src/pages/games/Gameplay.tsx

[error] 39-43: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

🪛 Gitleaks (8.21.2)
contracts/dojo_slot.toml

27-27: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

contracts/dojo_sepolia.toml

27-27: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test
🔇 Additional comments (58)
client/src/dojo/DojoContext.tsx (3)

27-27: LGTM: Client extraction from setup result

The addition of the client property aligns with the SetupResult type and maintains consistency with the context interface.


36-36: Good refactoring: Simplified burner manager data handling

The change to store the complete burner manager data improves maintainability by eliminating the need to manually update destructured properties when the burner manager interface changes.


43-46: LGTM: Robust context value construction

The changes provide:

  • Complete burner manager functionality through spreading
  • Proper fallback to masterAccount
  • Type-safe inclusion of the client property
client/src/AppWrapper.tsx (2)

3-3: Well-structured setup status messages

Good addition of user-friendly status messages with proper typing. The messages are clear and informative for users during the loading process.

Also applies to: 7-7, 10-19


22-25: LGTM: Type-safe state management

Good use of TypeScript's Partial type for setup status state management.

contracts/src/components/initializable.cairo (1)

1-45: Initialization logic is correctly implemented.

The initialize function properly sets up the game counter with appropriate checks and updates.

contracts/src/types/task.cairo (1)

1-81: LGTM!

The implementation of the Task enum and its associated traits is clean and well-structured. The conversion implementations between Task and u8 are correctly defined, and the match statements cover all task variants with appropriate default cases.

contracts/src/systems/mancala.cairo (1)

67-87: Verify the trophy initialization logic to prevent off-by-one errors.

In the loop initializing trophies, the loop decrements trophy_id until it reaches zero. Ensure that all intended trophies are initialized and that you're not missing the trophy with trophy_id zero if it's valid.

Run the following script to check the range of initialized trophies:

If trophy ID 0 is a valid trophy, consider adjusting the loop condition to include it.

✅ Verification successful

Trophy initialization logic is correct

The current implementation correctly initializes all valid trophies. Trophy ID 0 represents Trophy::None, which is a special case used to represent invalid or no trophy, and should not be initialized. The loop correctly processes all valid trophies from 9 down to 1, matching the TROPHY_COUNT of 9.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that trophies with IDs from 1 to TROPHY_COUNT are initialized.

# Test: Check for usage of trophy_id == 0
ast-grep --pattern $'let mut trophy_id: u8 = TROPHY_COUNT;\nwhile trophy_id > 0 {\n  $$$\n  trophy_id -= 1;\n}'

Length of output: 108


Script:

#!/bin/bash
# Find Trophy type definition and TROPHY_COUNT
ast-grep --pattern 'enum Trophy {'

# Find TROPHY_COUNT constant
rg "const TROPHY_COUNT" -A 2

# Look for any trophy with ID 0 references
rg "Trophy::(\w+) = 0" --type cairo

Length of output: 276


Script:

#!/bin/bash
# View trophy type definition
cat contracts/src/types/trophy.cairo

# Search for any zero references in trophy definitions without file type restriction
rg "Trophy::\w+ = 0" 

Length of output: 11443

client/src/components/gameplay/game-board.tsx (1)

206-215: Verify logic for determining isPlayerSeed

In the function determining isPlayerSeed (lines 206~ to 215~), ensure that the logic correctly handles cases where account.account?.address may be undefined or when the user is not logged in. This could lead to unexpected behavior when determining seed ownership.

client/src/components/gameplay/game-message.tsx (1)

132-154: Handle Eliza's states consistently in moveMessageOnTimer

In the moveMessageOnTimer function, the conditions for displaying Eliza's messages are nested within the check for game_node?.winner === "0x0". Ensure that the logic correctly handles scenarios where the game has a winner or the game status changes, to prevent inconsistent UI messages.

contracts/src/components/playable.cairo (2)

46-46: Validate state mutation with ref self

The change to use ref self: ComponentState<TState> indicates intentional state mutation. Ensure that this aligns with the component's design and that all state mutations are managed correctly.


228-234: Handle potential integer overflows when updating tasks

When updating task progress with arcade_store.progress, ensure that the captured_seeds value is within the expected range to prevent integer overflows.

client/src/lib/constants.ts (3)

619-655: Confirm Policy Targets and Methods Alignment

In the POLICIES array, the target for each policy has been updated to use MANCALA_ADDRESS and PROFILE_ADDRESS. Ensure that each method corresponds to the correct contract address and that the smart contracts expose these methods.


Line range hint 661-771: Update GraphQL Queries to Reflect New Backend Models

The GraphQL queries have been updated to use the mancalaAlpha namespace (e.g., mancalaAlphaMancalaBoardModels). Verify that the backend service has these models and that the queries will function as expected.


608-615: Verify the Accuracy of Contract Addresses

New constants MANCALA_ADDRESS, PROFILE_ADDRESS, and ELIZA_ADDRESS have been added. Please ensure that these addresses are correct and correspond to the intended smart contracts on the specified network.

Run the following script to verify the addresses:

✅ Verification successful

Contract Addresses Verified Successfully

The addresses are consistently used throughout the codebase and their usage patterns align with their intended purposes. MANCALA_ADDRESS is used for game operations, PROFILE_ADDRESS for profile management, and ELIZA_ADDRESS for AI opponent functionality.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the contract addresses are correctly defined.

# Expected addresses (update these with the correct values if known)
EXPECTED_MANCALA_ADDRESS="0x470f026bf97f0781492a95ebb9031da1c524601e8c2a285534545d33ca44797"
EXPECTED_PROFILE_ADDRESS="0x4a992660cbd6a91cda1e1697e43c52641f3818aeabcf96658a986322603ef85"
EXPECTED_ELIZA_ADDRESS="0x076795eb2cdc3e799364f661a409edbe0f204b67625b179a6880733893f7004d"

# Actual addresses from the code
ACTUAL_MANCALA_ADDRESS="0x470f026bf97f0781492a95ebb9031da1c524601e8c2a285534545d33ca44797"
ACTUAL_PROFILE_ADDRESS="0x4a992660cbd6a91cda1e1697e43c52641f3818aeabcf96658a986322603ef85"
ACTUAL_ELIZA_ADDRESS="0x076795eb2cdc3e799364f661a409edbe0f204b67625b179a6880733893f7004d"

# Verify addresses
if [ "$ACTUAL_MANCALA_ADDRESS" != "$EXPECTED_MANCALA_ADDRESS" ]; then
  echo "MANCALA_ADDRESS does not match the expected address."
fi

if [ "$ACTUAL_PROFILE_ADDRESS" != "$EXPECTED_PROFILE_ADDRESS" ]; then
  echo "PROFILE_ADDRESS does not match the expected address."
fi

if [ "$ACTUAL_ELIZA_ADDRESS" != "$EXPECTED_ELIZA_ADDRESS" ]; then
  echo "ELIZA_ADDRESS does not match the expected address."
fi

Length of output: 992


Script:

#!/bin/bash
# Search for occurrences of these addresses and related contract references
echo "=== Searching for MANCALA_ADDRESS ==="
rg -i "0x470f026bf97f0781492a95ebb9031da1c524601e8c2a285534545d33ca44797" --type ts --type js
rg -i "mancala.*address" --type ts --type js

echo -e "\n=== Searching for PROFILE_ADDRESS ==="
rg -i "0x4a992660cbd6a91cda1e1697e43c52641f3818aeabcf96658a986322603ef85" --type ts --type js
rg -i "profile.*address" --type ts --type js

echo -e "\n=== Searching for ELIZA_ADDRESS ==="
rg -i "0x076795eb2CDc3E799364F661A409EDBE0f204b67625B179a6880733893f7004d" --type ts --type js
rg -i "eliza.*address" --type ts --type js

echo -e "\n=== Looking for contract deployment files ==="
fd -e ts -e js -e json "deploy|contract" --type f

Length of output: 4188

contracts/src/elements/tasks/interface.cairo (1)

1-4: Introduce TaskTrait Interface Correctly

The TaskTrait is defined with two methods: identifier and description. Ensure that the return types and parameters match the intended use and that any implementing structures conform to this trait.

contracts/src/elements/tasks/clearing.cairo (1)

10-12: ⚠️ Potential issue

Ensure Proper String Handling in description Method

The description method uses format! to create a string. Verify that the format! macro is supported and that it returns a ByteArray as intended. In Cairo, string manipulation is limited, and you may need to construct the ByteArray manually.

Consider constructing the ByteArray explicitly:

     fn description(count: u32) -> ByteArray {
-        format!("Collect {} seed", count)
+        ByteArray::new("Collect ") + ByteArray::from_u32(count) + ByteArray::new(" seed")
     }

Ensure that the ByteArray operations are valid and that the necessary imports or helper functions are included.

Likely invalid or redundant comment.

contracts/src/elements/tasks/dominating.cairo (1)

1-13: LGTM! Clean and well-structured implementation.

The implementation correctly follows the TaskTrait interface with appropriate use of #[inline] attributes and clear description formatting.

contracts/src/elements/tasks/reigning.cairo (1)

1-13: LGTM! Clear and precise implementation.

The implementation correctly follows the TaskTrait interface with good description clarity by using "total" in the message.

client/dojoConfig.ts (2)

7-7: Environment change from test to staging confirmed.

The toriiUrl endpoint change from mancala-t to mancala-e aligns with the staging transition.


9-9: Verify the masterAddress case change.

The masterAddress has a case change from 'E' to 'e'. While Starknet addresses are case-insensitive for hex characters, let's verify this doesn't impact any existing integrations.

✅ Verification successful

Case difference in masterAddress is safe to proceed

The case change from 'E' to 'e' in the masterAddress is safe as:

  • Starknet addresses are case-insensitive for hex characters
  • The address appears in only two isolated contexts (contract config and client config)
  • No other variations or dependent code found that could be impacted
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any hardcoded references to the old address format
rg -i "0x02A54eFf65D55a2E7D2fC7E23eF0F0e6030dB0313b16c8F0eaD0b4a83807f6d6"

Length of output: 284


Script:

#!/bin/bash
# Search for imports of dojoConfig.ts and dojo_sepolia.toml
echo "=== Searching for dojoConfig.ts imports ==="
rg -l "dojoConfig"

echo -e "\n=== Searching for dojo_sepolia.toml usage ==="
rg -l "dojo_sepolia"

echo -e "\n=== Searching for any other variations of the address with different casing ==="
# Using parts of the address to catch any variations
rg -i "2[aA]54[eE][fF][fF].*2[eE]7[dD]2[fF][cC]7[eE]23"

Length of output: 754

client/src/pages/Home.tsx (1)

13-17: 🛠️ Refactor suggestion

Add error handling for connection logic.

The auto-connection logic should handle cases where no connectors are available to prevent potential runtime errors.

Consider adding error handling:

  useEffect(() => {
    if (!account?.address) {
+     if (connectors.length === 0) {
+       console.warn("No connectors available");
+       return;
+     }
      connect({ connector: connectors[0] });
    }
  }, [account, connect, connectors]);
contracts/src/elements/trophies/collector.cairo (1)

80-83: Verify task generation logic.

The task generation uses the same value for both parameters of tasks(), which might not be intentional.

✅ Verification successful

Task generation logic is correct

The consistent pattern of using the same value for both count and total parameters is intentional and correct. All trophy implementations follow this pattern, and the Task::tasks method uses these parameters for different purposes: count for description generation and total for task creation.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check task generation patterns across trophies
rg "Task::\w+\.tasks\(level, total, total\)" --type cairo

Length of output: 89


Script:

#!/bin/bash
# Search for task generation patterns without file type restriction
echo "=== Task generation patterns ==="
rg "Task::\w+\.tasks\(.*\)"

echo -e "\n=== Task enum definition ==="
rg "enum Task"

echo -e "\n=== All task method implementations ==="
rg "fn tasks.*->.*BushidoTask"

Length of output: 1425


Script:

#!/bin/bash
# Look for Task enum implementation and its tasks method
echo "=== Task implementation ==="
rg -A 10 "enum Task \{" contracts/src/types/task.cairo

echo -e "\n=== Task::tasks method implementation ==="
rg -A 5 "fn tasks\(" contracts/src/types/task.cairo

Length of output: 691

contracts/src/elements/trophies/strategist.cairo (1)

25-32: Points progression is well-balanced.

The doubling of points per level (20 → 40 → 80) provides a good balance between reward and challenge.

client/src/App.tsx (2)

18-23: Verify the configuration values for alpha deployment.

The namespace and slot values have been updated for alpha stage. Ensure these values match the deployment configuration.


65-72: 🛠️ Refactor suggestion

Clean up leaderboard-related code.

The leaderboard route has been removed, but there might be leftover references or components.

Ensure all leaderboard-related code is removed to maintain a clean codebase.

client/src/components/pits.tsx (1)

3-3: LGTM! Audio feedback integration looks good.

The addition of the useAudioControl hook and its integration enhances the user experience by providing audio feedback.

Also applies to: 47-47

contracts/src/tests/setup.cairo (3)

12-14: LGTM! System dispatcher transition looks good.

The transition from actions to a dedicated Mancala system dispatcher improves the code organization by making it more domain-specific.


74-77: LGTM! Systems struct initialization is correct.

The initialization of the Mancala system dispatcher is properly implemented.


49-53: Verify trophy system integration.

The addition of trophy-related events suggests a new achievement system. Please ensure that:

  1. Trophy creation and progression events are properly handled
  2. Achievement triggers are correctly implemented in the Mancala system
client/src/pages/Profile.tsx (1)

18-18: Verify data model transition to alpha environment.

The transition from dev to alpha environment (mancalaDevMancalaBoardModelsmancalaAlphaMancalaBoardModels) needs verification:

  1. Ensure all queries are updated consistently
  2. Verify data schema compatibility

Also applies to: 36-36

client/src/components/profile/game-history-skeleton.tsx (1)

8-77: LGTM! Skeleton UI improvements enhance user experience.

The restructured skeleton loading state using Material Tailwind components provides:

  • Better visual hierarchy with Card component
  • Improved layout organization
  • Consistent styling with the actual content
client/src/components/lobby/duels-skeleton.tsx (1)

7-81: LGTM! Consistent skeleton UI implementation.

The skeleton UI implementation maintains consistency with the game history component while providing:

  • Clean table layout
  • Proper spacing and alignment
  • Responsive design considerations
client/src/pages/games/Gameplay.tsx (2)

62-62: Clean component structure with proper styling.

The main component's structure is well-organized with appropriate styling and background implementation.


1-1: Environment transition looks good, but verify data model compatibility.

The transition from dev to alpha environment (mancalaDevMancalaBoardModelsmancalaAlphaMancalaBoardModels) is implemented correctly. The addition of connection management enhances user experience.

Run this script to verify the data model compatibility:

Also applies to: 5-5, 34-34, 39-40

client/src/components/ui/dialog.tsx (1)

1-120: Well-implemented dialog components with proper accessibility.

The dialog implementation follows best practices:

  • Uses Radix UI for robust accessibility
  • Proper TypeScript typing with forwardRef
  • Includes screen reader support
  • Clean component composition
client/src/dojo/createSystemCalls.ts (1)

62-64: Verify contract event emission order change.

The change from events[1] to events[0] suggests a modification in contract event emission order. While the optional chaining is a good addition, we should verify this change.

client/src/components/lobby/live-duels.tsx (1)

38-40: Good empty state handling.

The implementation of empty state with a customizable message is clean and user-friendly.

client/src/components/lobby/duels.tsx (1)

4-17: LGTM! Clean implementation of clipboard functionality.

The addition of clipboard-related icons and state management is well-structured and follows React best practices.

Also applies to: 94-95

contracts/torii_dev.toml (1)

17-20: Verify historical events configuration

The configuration tracks trophy-related events. Ensure these event names match the exact event names emitted by the contracts.

Let's verify the event names in the contracts:

✅ Verification successful

Event names in historical configuration are correct

The event names mancala_alpha-TrophyCreation and mancala_alpha-TrophyProgression match exactly with the events defined in the contracts and are consistently used across all configuration files.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for trophy-related event definitions
rg -A 2 "event\s+(TrophyCreation|TrophyProgression)" --type cairo

Length of output: 97


Script:

#!/bin/bash
# First find cairo files
echo "=== Finding Cairo files ==="
fd -e cairo

# Then search for trophy events (both with and without prefix)
echo -e "\n=== Searching for trophy events ==="
rg -i "event.*trophy(creation|progression)"

# Also search with exact names from config
echo -e "\n=== Searching for exact event names ==="
rg "mancala_alpha-TrophyCreation|mancala_alpha-TrophyProgression"

Length of output: 3208

contracts/Scarb.toml (1)

4-4: Version bump and dependency updates look good

The version bump to 0.3.0 is appropriate given the significant changes. Dependencies are correctly pinned to specific versions.

Also applies to: 13-14

contracts/dojo_slot.toml (2)

29-31: Security: Same IPFS credential exposure issue

Similar to dojo_dev.toml, this file also contains hardcoded IPFS credentials.


33-34: Verify raw event processing configuration

The configuration enables raw event processing and tracks trophy progression events. Ensure this aligns with the event processing capabilities of your infrastructure.

Let's verify the event processing setup:

✅ Verification successful

Raw event processing configuration is properly integrated

The configuration aligns with the project's infrastructure as evidenced by consistent raw event processing setup across development and Sepolia environments, proper manifest integration, and test coverage.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for raw event processing implementations
rg -l "TrophyProgression.*event" --type cairo

Length of output: 77


Script:

#!/bin/bash
# Search for TrophyProgression without file type restriction
rg -l "TrophyProgression"

# Search for event processing related configurations
rg -l "raw.*=.*true" --type toml

# Find all dojo_slot.toml files
fd "dojo_slot.toml"

Length of output: 398

contracts/dojo_sepolia.toml (3)

19-21: LGTM! Writers configuration updated for the new namespace.

The writers configuration has been properly updated to reflect the new namespace structure, including trophy-related components.


33-34: LGTM! Additional configuration flags for trophy system.

The raw flag and historical tracking for trophy progression have been properly configured.


7-8: Verify the configuration changes for the staging environment.

The changes in world configuration indicate a transition from development to alpha stage:

  • Seed updated to "mancala-achievement"
  • Namespace changed to "mancala_alpha"

These changes align with the staging objectives.

Run the following script to verify the configuration consistency across files:

Also applies to: 16-16

✅ Verification successful

Configuration changes for staging environment are properly implemented

The configuration changes show correct environment separation:

  • Staging environment (dojo_sepolia.toml) uses unique seed "mancala-achievement"
  • Development environments maintain original "mancala" seed
  • Namespace "mancala_alpha" is consistently set across all environments
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any inconsistencies in namespace and seed configuration
# across different environment files.

echo "Checking namespace and seed configuration..."
rg -l "mancala_dev|mancala_alpha|mancala-achievement" --type toml

Length of output: 268


Script:

#!/bin/bash
# Check actual content of configuration files for seed and namespace values
echo "Checking seed configurations..."
rg -A 1 -B 1 "^seed\s*=" --type toml

echo -e "\nChecking namespace configurations..."
rg -A 1 -B 1 "namespace" --type toml

Length of output: 1047

client/src/components/message-area.tsx (1)

60-60: Verify the useEffect dependencies are exhaustive.

The restart_game function has been added to the dependency array, but ensure all other dependencies used within the effect are also included.

Run the following script to check for potential missing dependencies:

client/package.json (3)

29-29: LGTM! New dependencies added.

The following dependencies have been added:

  • @headlessui/react for UI components
  • @radix-ui/react-dialog for dialog components
  • concurrently for running multiple commands

Also applies to: 36-36, 49-49


8-8: Verify the dev script changes.

The development script has been updated to use a shell script. Ensure that dev.sh exists and has proper execute permissions.

Run the following script to verify the dev script setup:

✅ Verification successful

Dev script exists but doesn't require execute permissions

The client/dev.sh file exists and is properly referenced in package.json. Since the script is executed using bash dev.sh rather than direct execution, it doesn't require execute permissions to work correctly.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify dev script existence and permissions

echo "Checking dev script..."
if [ -f "dev.sh" ]; then
  ls -l dev.sh
else
  echo "dev.sh not found"
fi

Length of output: 117


Script:

#!/bin/bash
# Description: Verify dev script in client directory

echo "Checking dev script in client directory..."
if [ -f "client/dev.sh" ]; then
  ls -l client/dev.sh
else
  echo "dev.sh not found in client directory"
fi

Length of output: 205


17-25: Review package version changes for compatibility.

Several package versions have been modified:

  • @cartridge/connector downgraded to ^0.5.5
  • @cartridge/controller upgraded to ^0.5.8
  • @dojoengine/* packages upgraded to 1.0.8

Run the following script to check for potential version conflicts:

✅ Verification successful

Package versions are compatible and well-structured

The version changes are safe because:

  • All @dojoengine packages (except recs) are consistently set to 1.0.8
  • @dojoengine/recs at ^2.0.13 is an intended different major version
  • @Cartridge packages use compatible version ranges
  • Required peer dependencies (e.g., starknet) are satisfied
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for potential version conflicts and security advisories

# Check npm for version compatibility
echo "Checking version compatibility..."
npm info "@cartridge/connector@^0.5.5" peerDependencies
npm info "@cartridge/controller@^0.5.8" peerDependencies
npm info "@dojoengine/[email protected]" peerDependencies

# Check for known vulnerabilities
echo "Checking for vulnerabilities..."
npm audit

Length of output: 703


Script:

#!/bin/bash
# Find all package.json files and their content
echo "=== Package.json files ==="
fd package.json --type f --exec cat {}

# Search for import statements of these packages
echo -e "\n=== Package imports ==="
rg -A 1 "from ['\"]@(cartridge|dojoengine)/" --type ts --type tsx --type js --type jsx

# Look for version-specific patterns or constraints
echo -e "\n=== Version constraints ==="
rg "(@cartridge|@dojoengine)" --type json

Length of output: 6713

contracts/manifest_sepolia.json (3)

1308-1314: Review state mutability changes in contract functions.

Several functions have had their state mutability changed from "view" to "external". This change affects how the functions can modify contract state.

Ensure that:

  1. All state-modifying functions are properly marked as "external"
  2. Pure view functions remain as "view"
  3. Access control is properly implemented for external functions

Also applies to: 1365-1505


1958-1968: LGTM! New trophy system events added.

Trophy-related events have been properly configured:

  • TrophyCreation
  • TrophyProgression

These align with the achievement system implementation.


4-5: Verify contract addresses and seed configuration.

The world configuration has been updated with new addresses and seed values. Ensure these values are correct for the respective environments.

Run the following script to verify contract addresses:

✅ Verification successful

Contract addresses and seed configurations verified successfully

The contract addresses and seed values are correctly configured and consistent across all environment files (manifest and dojo configuration files):

  • Sepolia environment with seed "mancala-achievement"
  • Dev environment with seed "mancala"
  • Slot environment with seed "mancala"
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify contract addresses across environments

echo "Checking contract addresses..."
rg -A 1 '"address":\s*"0x[a-fA-F0-9]+"' --type json

Length of output: 1829


Script:

#!/bin/bash
# Search for any references to these addresses in other files
# and check for any documentation about contract configurations

echo "Checking for address references and documentation..."
rg -l "0x2570a4240bf789d09bdbc2cb8f870ad7879b0737d453ee1d70f5dfaedd9f3f6|0x7e6333cfb9768d94ffa94daf40d8261b27a245a154e180e8ed052781a2e1779|0x4068272626b01237de6009110492f508fb9de4d9358b6ecf15ffb02a1c7e0a3"

echo -e "\nChecking for configuration documentation..."
fd -t f "README|CONTRIBUTING|DEPLOY|CONFIG" -e md -e txt

Length of output: 762


Script:

#!/bin/bash
# Check contracts README and verify configuration consistency

echo "Checking contracts README..."
cat contracts/README.md

echo -e "\nVerifying configuration consistency..."
echo "Sepolia configs:"
cat contracts/dojo_sepolia.toml

echo -e "\nDev configs:"
cat contracts/dojo_dev.toml

echo -e "\nSlot configs:"
cat contracts/dojo_slot.toml

Length of output: 6400

contracts/manifest_dev.json (5)

1255-1256: Contract deployment changes detected.

The contract address and class hash have been updated, indicating a new deployment. This is consistent with the transition to alpha stage.


Line range hint 1358-1506: Well-structured game system interface.

The IMancalaSystem interface provides a comprehensive set of functions for managing the Mancala game, including:

  • Game lifecycle (new_game, join_game, create_private_game)
  • Game mechanics (move, get_score, is_game_over)
  • Player management (timeout, forfeited)
  • Game state management (request_restart_game, restart_current_game)

All functions are correctly marked as external for proper access control.


Line range hint 1728-1750: Profile system implementation looks good.

The IPlayerProfile interface provides essential functionality for player profile management:

  • Profile creation with name
  • Profile updates with URI support
  • View-only functions for data safety

The implementation follows best practices for player data management.


1899-1930: Complete set of game models with proper alpha stage tagging.

The models cover all essential aspects of the game:

  • Game state (GameCounter, MancalaBoard)
  • Player data (Player, Profile)
  • Game mechanics (Pit, Seed)

All models are correctly tagged with mancala_alpha prefix.


1937-1968: Comprehensive event system for game actions and achievements.

The event system includes:

  1. Game mechanics events (Capture, EndTurn, PlayerMove)
  2. Special events (PlayerExtraTurn)
  3. Achievement events (TrophyCreation, TrophyProgression)

All events are properly tagged with mancala_alpha prefix and have unique selectors.

Comment on lines +70 to +72
{players[index]?.name
? players[index]?.name
: truncateString(address)}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve type safety in name rendering.

The optional chaining usage suggests potential type safety issues. Consider using proper TypeScript types and null coalescing.

-                              {players[index]?.name
-                                ? players[index]?.name
-                                : truncateString(address)}
+                              {players[index]?.name ?? truncateString(address)}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{players[index]?.name
? players[index]?.name
: truncateString(address)}
{players[index]?.name ?? truncateString(address)}

</td>
<td>
<p className="font-normal text-[#BDC2CC] text-center">
Lvl {wins < 4 ? 1 : Math.floor(wins / 4) + 1}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Extract level calculation logic.

The level calculation logic should be moved to a utility function for better maintainability and reusability.

+// In utils.ts
+export const calculatePlayerLevel = (wins: number): number => 
+  wins < 4 ? 1 : Math.floor(wins / 4) + 1;

+// In component
-                          Lvl {wins < 4 ? 1 : Math.floor(wins / 4) + 1}
+                          Lvl {calculatePlayerLevel(wins)}

Committable suggestion skipped: line range outside the PR's diff.

@@ -2,7 +2,7 @@ import mancala_duels_logo from "../../assets/mancala_duels.png";

export default function EmptyGameHistory({ id }: { id: string }) {
return (
<div className="w-[874px] h-[874px] bg-[url('./assets/lobby-box-long.png')] bg-contain bg-no-repeat p-8">
<div className="bg-[#0F1116] bg-contain bg-center bg-no-repeat border-2 border-[#272A32] rounded-2xl w-[full h-[437px] flex flex-col items-center justify-center">
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix CSS class syntax error and improve accessibility.

The className has syntax errors and accessibility can be improved:

  1. w-[full is missing a closing bracket
  2. Missing ARIA attributes for better screen reader support

Apply this diff to fix the issues:

-    <div className="bg-[#0F1116] bg-contain bg-center bg-no-repeat border-2 border-[#272A32] rounded-2xl w-[full h-[437px] flex flex-col items-center justify-center">
+    <div 
+      className="bg-[#0F1116] bg-contain bg-center bg-no-repeat border-2 border-[#272A32] rounded-2xl w-full h-[437px] flex flex-col items-center justify-center"
+      role="region"
+      aria-label="Empty game history">
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div className="bg-[#0F1116] bg-contain bg-center bg-no-repeat border-2 border-[#272A32] rounded-2xl w-[full h-[437px] flex flex-col items-center justify-center">
<div
className="bg-[#0F1116] bg-contain bg-center bg-no-repeat border-2 border-[#272A32] rounded-2xl w-full h-[437px] flex flex-col items-center justify-center"
role="region"
aria-label="Empty game history">

Comment on lines +102 to +170
>
<UserIcon
color="#F58229"
className="w-5 h-5 text-white"
/>
</div>
</div>
<p className="font-normal text-white">
{item.challenger.name
? item.challenger.name
: truncateString(
games[index].node.player_one,
)}
</p>
</div>
</td>
<td className="flex flex-row px-4 h-16 space-x-5 w-[200px] text-center border-y-2 border-[#1A1E25] bg-[#111419]">
{item.challenged !== "0x0" ? (
<div className="flex flex-row items-center space-x-2.5 w-fit">
<div
className="w-8 h-8 flex items-center justify-center rounded-full"
style={{ backgroundColor: challengedColor }}
>
<UserIcon color="#F58229" className="w-5 h-5 text-white" />
</div>
</td>
<td className="flex flex-row items-center p-4 space-x-5 w-[200px] justify-center">
{games[index].node.player_two !== "0x0" ? (
<div className="flex flex-row items-center space-x-2.5 w-fit">
{/* <img src={item.challenged.profilePicture} width={35} height={35} alt={`${item.challenged.name} profile picture`} className="rounded-full" /> */}
<div className="p-1 rounded-full bg-gradient-to-r bg-[#15181E] from-[#2E323A] via-[#4B505C] to-[#1D2026] relative">
<div
className="bg-[#FFE600] w-8 h-8 flex items-center justify-center rounded-full"
style={{ backgroundColor: challengedColor }}
>
<UserIcon
color="#F58229"
className="w-5 h-5 text-white"
/>
</div>
</div>
<p className="font-normal text-white">
{item.challenged.name
? item.challenged.name
: truncateString(
games[index].node.player_two,
)}
</p>
</div>
) : (
<p className="text-white">Matchmaking</p>
)}
</td>
<td className="w-[200px] text-center ml-8">
<p className="font-normal text-[#FAB580]">
{item.winner.name
? item.winner.name
: truncateString(games[index].node.winner)}
<Typography variant="paragraph" className="font-medium leading-none text-white">
{truncateString(item.challenged)}
</Typography>
</div>
) : (
<div className="flex flex-row items-center justify-center w-full h-16">
<p className="text-[#646976] font-semibold text-center w-full">
Matchmaking...
</p>
</td>
<td className="w-[200px] text-end pr-12">
<p className="font-normal text-[#F97E22]">
{date.toLocaleDateString()}
</p>
</td>
</tr>
);
})}
</tbody>
</table>
</div>
</div>
</Card>
</div>
)}
</td>
<td className="w-[125px] px-4 text-center h-16 flex flex-col justify-center bg-[#111419] border-y-2 border-[#1A1E25]">
<p className="font-normal text-[#FAB580]">
{truncateString(item.winner)}
</p>
</td>
<td className="w-[200px] px-4 text-end h-16 flex flex-col items-start justify-center bg-[#111419] border-y-2 border-r-2 border-[#1A1E25] rounded-r-xl">
<p className="font-normal text-[#F97E22] ml-2.5">
{date.toLocaleDateString().replace(/\//g, "-")}
</p>
</td>
</tr>
);
})}
</tbody>
</table>
</div>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Optimize performance and improve type safety.

The table body implementation has several areas for improvement:

  1. Fixed positioning with absolute dimensions could cause layout issues
  2. Missing TypeScript interfaces for data structure
  3. Potential performance issues with large datasets

Consider creating an interface for the game data:

interface GameHistoryItem {
  challenger: string;
  challenged: string;
  winner: string;
  date: string;
}

And optimize the table body:

-              <tbody className="h-[450px] w-[800px] rounded-b-xl fixed overflow-y-scroll overflow-x-clip space-y-2 bg-[#0F1116]">
+              <tbody className="max-h-[450px] w-full rounded-b-xl overflow-y-auto space-y-2 bg-[#0F1116]">

Also, consider implementing virtualization for better performance with large datasets using a library like react-window or react-virtualized.

Comment on lines +73 to +101
return (
<div className="w-full">
<Card className="w-full h-full bg-transparent">
<div className="w-full text-left bg-transparent table-auto">
<div className="flex flex-row items-center justify-between w-full bg-[#0F1116] pt-2 rounded-t-xl px-2.5">
<div className="flex flex-row items-center justify-between w-full">
{duels_header.map((head) => (
<div
key={head.id}
className={clsx(
head.id === 2
? "text-center ml-20"
: head.id === 3
? "text-center -ml-6"
: head.id === 4 && "-ml-16",
head.id === 5 && "hidden",
"w-[175px] p-4 text-start"
)}
>
<Typography
variant="small"
className="font-semibold leading-none text-[#BDC2CC]"
>
{head.name === "Winner" ? "Result" : head.name}
</Typography>
</div>
</div>
<div className="absolute h-[275px] w-[814px] overflow-y-scroll scrollbar-hidden">
<table className="w-full text-left table-auto">
<thead className="border-b border-[#313640] hidden">
<tr className="w-full bg-[#0F1116] flex flex-row items-center justify-between">
{duels_header.map((head) => (
<th key={head.id} className="p-4">
<Typography
variant="small"
className="font-medium leading-none text-[#BDC2CC]"
))}
</div>
</div>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve table header accessibility and responsiveness.

The table header structure needs accessibility improvements and better responsive design handling:

  1. Missing proper table semantics
  2. Hard-coded pixel values could break on different screen sizes
  3. Missing ARIA attributes
-    <div className="w-full">
-      <Card className="w-full h-full bg-transparent">
-        <div className="w-full text-left bg-transparent table-auto">
+    <div className="w-full" role="region" aria-label="Game history">
+      <Card className="w-full h-full bg-transparent">
+        <div className="w-full text-left bg-transparent">
+          <table className="w-full table-auto">
+            <thead>

Committable suggestion skipped: line range outside the PR's diff.

@@ -0,0 +1,20 @@
rpc = "https://api.cartridge.gg/x/starknet/sepolia"

allowed_origins = ["*"]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Security: Restrict CORS allowed origins

The configuration allows all origins ("*") for CORS, which is overly permissive. Additionally, there's a duplicate CORS setting in the [indexing] section.

Consider:

  1. Restricting allowed origins to specific domains
  2. Removing the duplicate CORS setting from the [indexing] section
-allowed_origins = ["*"]
+allowed_origins = ["https://your-domain.com", "https://staging.your-domain.com"]

[indexing]
-allowed_origins = ["*"]

Also applies to: 9-9

Comment on lines +29 to +31
ipfs_config.url = "https://ipfs.infura.io:5001"
ipfs_config.username = "2EBrzr7ZASQZKH32sl2xWauXPSA"
ipfs_config.password = "12290b883db9138a8ae3363b6739d220"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Security Issue: IPFS credentials exposed in configuration file.

The IPFS configuration contains sensitive credentials that should not be committed to the repository.

Recommendations:

  1. Remove the credentials from the configuration file
  2. Use environment variables or a secure secrets management system
  3. Update the .gitignore file to prevent accidental commits of sensitive data

Apply this diff to use environment variables instead:

-ipfs_config.username = "2EBrzr7ZASQZKH32sl2xWauXPSA"
-ipfs_config.password = "12290b883db9138a8ae3363b6739d220"
+ipfs_config.username = "${IPFS_USERNAME}"
+ipfs_config.password = "${IPFS_PASSWORD}"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ipfs_config.url = "https://ipfs.infura.io:5001"
ipfs_config.username = "2EBrzr7ZASQZKH32sl2xWauXPSA"
ipfs_config.password = "12290b883db9138a8ae3363b6739d220"
ipfs_config.url = "https://ipfs.infura.io:5001"
ipfs_config.username = "${IPFS_USERNAME}"
ipfs_config.password = "${IPFS_PASSWORD}"

@@ -28,6 +28,7 @@ export default function MessageArea({
const { system } = useDojo();
const [_, setRestarted] = useState(false);
const { gameId } = useParams();
// eslint-disable-next-line react-hooks/exhaustive-deps
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Avoid disabling ESLint rules without justification.

The ESLint rule for exhaustive dependencies is being disabled without explanation. This rule helps prevent bugs related to stale closures in React hooks.

Instead of disabling the rule:

  1. Add all required dependencies to the useEffect dependency array
  2. If certain dependencies need to be omitted, add a comment explaining why
  3. Consider using useCallback for the restart_game function if it needs to be stable across renders

@@ -3,7 +3,7 @@
"class_hash": "0x45575a88cc5cef1e444c77ce60b7b4c9e73a01cbbe20926d5a4c72a94011410",
"address": "0x7e6333cfb9768d94ffa94daf40d8261b27a245a154e180e8ed052781a2e1779",
"seed": "mancala",
"name": "Mancala",
"name": "RealmOfRa: Mancala",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Update project name in all manifest files

The project name has been updated to "RealmOfRa: Mancala" in manifest_dev.json, but it's still set as "Mancala" in:

  • manifest_sepolia.json
  • manifest_slot.json

Please synchronize the name across all manifest files to maintain consistency between environments.

🔗 Analysis chain

Verify name consistency across the codebase.

The project has been rebranded from "Mancala" to "RealmOfRa: Mancala". This change might require updates in related documentation, UI components, and other references.

Run this script to check for inconsistencies:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for inconsistent naming across the codebase

# Search for old name references
echo "Searching for old 'Mancala' references that might need updating..."
rg --type md --type txt --type yaml --type json "\"name\":\s*\"Mancala\"" || true

# Search for inconsistent new name references
echo "Checking for inconsistent 'RealmOfRa: Mancala' references..."
rg --type md --type txt --type yaml --type json "\"name\":\s*\"RealmOfRa:\s*Mancala\"" || true

Length of output: 611

Comment on lines +1308 to +1314
{
"type": "function",
"name": "dojo_init",
"inputs": [],
"outputs": [],
"state_mutability": "view"
},
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

State mutability mismatch in dojo_init function

The dojo_init implementation in contracts/src/systems/mancala.cairo performs state modifications (initializes world storage and emits events), but it's declared as a view function in the manifest files. This mismatch could lead to runtime issues.

  • Change state_mutability from "view" to an appropriate value in:
    • contracts/manifest_dev.json
    • contracts/manifest_sepolia.json
    • contracts/manifest_slot.json
🔗 Analysis chain

Verify dojo_init implementation.

The dojo_init function is marked as view-only, which is appropriate for initialization. However, ensure that any state modifications required during initialization are handled correctly.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for state modifications in dojo_init implementations

# Search for state modifications in dojo_init
echo "Checking dojo_init implementations for state modifications..."
ast-grep --pattern 'fn dojo_init($$$) { $$$ }'

Length of output: 181


Script:

#!/bin/bash
# Search for dojo_init across all files with context
echo "Searching for dojo_init definitions and usage..."
rg "dojo_init" -A 5 -B 5

# Also check for any files containing dojo_init in their name
echo -e "\nChecking for files containing dojo_init..."
fd "dojo.*init"

Length of output: 4377

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants