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

Add withdraw functionality #281

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open

Add withdraw functionality #281

wants to merge 3 commits into from

Conversation

starknetdev
Copy link
Member

@starknetdev starknetdev commented Oct 9, 2024

  • add beasts fetcher
  • add withdraw button for eth, lords, beasts, GTs and bloberts
  • add balances of these in the profile dialog
  • add test withdrawal for 1 beast

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a new function to fetch beast token IDs from the blockchain.
    • Enhanced the ProfileDialog component to display additional information about golden tokens and beasts.
    • Integrated beast data retrieval into the main component for improved data management.
  • Bug Fixes

    • Updated the withdrawal functionality to support multiple asset transfers, including golden tokens, beasts, and bloberts, in a single operation.

These updates improve user experience by providing more comprehensive asset management and data visibility.

- add withdraw button for eth, lords, beasts, GTs and bloberts
- add balances of these in the profile dialog
- add test withdrawal for 1 beast
Copy link

vercel bot commented Oct 9, 2024

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

Name Status Preview Comments Updated (UTC)
loot-survivor ✅ Ready (Inspect) Visit Preview 💬 Add feedback Oct 9, 2024 8:58pm

Copy link

coderabbitai bot commented Oct 9, 2024

Walkthrough

This pull request introduces a new asynchronous function getBeasts for retrieving beast token IDs from a blockchain network. It updates the ProfileDialog component to display additional properties related to beasts and tokens. The withdraw function in syscalls.ts is modified to handle multiple beast IDs, and the page.tsx file is updated to manage state for beasts and integrate the fetching functionality. Overall, these changes enhance data management and user interface interactions within the application.

Changes

File Change Summary
ui/src/app/api/getBeasts.ts Added getBeasts function to fetch beast token IDs with pagination support.
ui/src/app/components/profile/ProfileDialog.tsx Updated ProfileDialog to include new props: goldenTokens, beasts, and blobertsData; modified rendering logic and withdraw method.
ui/src/app/lib/utils/syscalls.ts Modified withdraw function to accept beasts: number[] and handle multiple beast transfers.
ui/src/app/page.tsx Added state for beasts, integrated getBeasts function, and updated ProfileDialog props to include beasts and goldenTokens.

Possibly related PRs

  • Renew golden token indexing #279: The getGoldenTokens function introduced in this PR is related to the getBeasts function in the main PR, as both functions are designed to fetch data from a blockchain network using similar asynchronous patterns and parameters.

🐇 In the meadow, we hop and play,
New beasts are here, hip-hip-hooray!
With tokens and treasures, oh what a sight,
Our world grows brighter, day and night!
Fetching and sharing, a joyful spree,
Come join the fun, just you and me! 🌼✨


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 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: 9

🧹 Outside diff range and nitpick comments (2)
ui/src/app/components/profile/ProfileDialog.tsx (1)

125-125: Ensure beasts is not undefined before accessing length

While beasts is expected to be an array, there might be scenarios where it is undefined or null, leading to a runtime error when accessing beasts.length. To prevent this, add a null check.

Modify the code as follows:

- <p>{beasts.length}</p>
+ <p>{beasts?.length ?? 0}</p>

This change safely handles cases where beasts may not be defined by displaying 0 instead.

ui/src/app/lib/utils/syscalls.ts (1)

1555-1556: Remove unnecessary console log statement

The console.log statement is likely leftover from debugging and should be removed in production code to avoid unnecessary console output.

-      console.log(calls[calls.length - 1]);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 0370e3b and e2829c7.

📒 Files selected for processing (4)
  • ui/src/app/api/getBeasts.ts (1 hunks)
  • ui/src/app/components/profile/ProfileDialog.tsx (10 hunks)
  • ui/src/app/lib/utils/syscalls.ts (2 hunks)
  • ui/src/app/page.tsx (5 hunks)
🧰 Additional context used
🔇 Additional comments (11)
ui/src/app/page.tsx (6)

7-7: New import added for getBeasts function.

The getBeasts function is now imported from the API. This is likely related to the new functionality for fetching and displaying beast data.


99-99: New state variable added for beasts.

A new state variable beasts is initialized using the useState hook. This will be used to store the fetched beast data.


481-489: New function added to fetch beasts.

The handleFetchBeasts function is implemented to fetch beast data using the imported getBeasts function. This is a good addition to support the new beast-related functionality.


489-493: Updated useEffect hook to fetch beasts.

The useEffect hook now includes a call to handleFetchBeasts(). This ensures that beast data is fetched when the component mounts or when the address or network changes.


943-945: Updated ProfileDialog props.

The ProfileDialog component now receives goldenTokens, beasts, and blobertsData as props. This allows the component to display information about these assets.


Line range hint 1-954: Summary of changes: Beast functionality added successfully.

The changes in this file successfully implement the new beast-related functionality:

  1. A new import for the getBeasts function is added.
  2. A new state variable beasts is introduced to store the fetched beast data.
  3. A handleFetchBeasts function is implemented to fetch the beast data.
  4. The useEffect hook is updated to call handleFetchBeasts when necessary.
  5. The ProfileDialog component is updated to receive the new beast data as props.

These changes are consistent with the PR objective of adding withdraw functionality, specifically for beasts. The implementation appears to be clean and well-integrated into the existing codebase.

ui/src/app/api/getBeasts.ts (2)

35-36: Verify the necessity of parsing beast.tokenId with JSON.parse.

Using JSON.parse on beast.tokenId assumes that tokenId is a JSON-formatted string. If tokenId is already a primitive type (e.g., a string or number), parsing may not be necessary and could cause errors. Confirm the format of tokenId to ensure correct parsing.

To verify the format of tokenId, you can inspect sample data with the following script:

#!/bin/bash
# Description: Check the format of `tokenId` in beast objects.

# Test: Retrieve sample `tokenId` values. Expect: `tokenId` to be a JSON string if parsing is required.
rg --json -g '*.json' '"tokenId":' | jq '.tokenId'

15-15: ⚠️ Potential issue

Ensure network is defined before using non-null assertion !.

The non-null assertion operator ! is used on network (network!) to assert that it is not null or undefined. To prevent potential runtime errors, ensure that network is always defined when getBeasts is called, or include a validation check before its usage.

To verify all calls to getBeasts provide a valid network, you can run the following script:

ui/src/app/components/profile/ProfileDialog.tsx (1)

180-182: Verify that the withdraw function handles the new beasts parameter correctly

The withdraw function signature has been updated to include the beasts parameter. Ensure that all usages of this function pass the correct arguments and that the function implementation correctly processes the beasts array.

To confirm that the withdraw function is updated appropriately, you can search the codebase for its implementations:

This script searches for the withdraw function definition and its usages to ensure consistency across the codebase.

ui/src/app/lib/utils/syscalls.ts (2)

1543-1545: Re-enable withdrawals of ETH and Lords tokens if required

The code for transferring ETH and Lords tokens is commented out. If withdrawing these assets is intended, consider uncommenting and integrating these transactions.

Confirm whether the commented code for transferring ETH and Lords tokens should be active. If so, update the calls array accordingly.

       let calls = [];

-      // if (ethBalance > BigInt(0)) {
-      //   calls.push(transferEthTx);
-      // }

-      // if (lordsBalance > BigInt(0)) {
-      //   calls.push(transferLordsTx);
-      // }
+      if (ethBalance > BigInt(0)) {
+        calls.push(transferEthTx);
+      }

+      if (lordsBalance > BigInt(0)) {
+        calls.push(transferLordsTx);
+      }

Also, ensure that transferEthTx and transferLordsTx are properly defined and that the contracts support these operations.

Also applies to: 1547-1549


1529-1539: Validate beast IDs before processing

Ensure that the beast IDs provided are valid and owned by the user to prevent unintended errors or security issues.

Add validation logic before creating transfer transactions:

       // Create a transaction for each beast ID
+      // Validate beast IDs
+      const ownedBeasts = await getOwnedBeasts(account.address);
+      const validBeasts = beasts.filter((beastId) => ownedBeasts.includes(beastId));
+      if (validBeasts.length !== beasts.length) {
+        throw new Error("One or more beast IDs are invalid or not owned by the user.");
+      }
+
       const transferBeastTxs = validBeasts.map((beastId) => ({

Implement getOwnedBeasts to retrieve the list of beast IDs owned by the user.

Alternatively, you can verify ownership by running the following shell script:

Comment on lines +10 to +13
const recursiveFetch: any = async (
beasts: any[],
nextPageKey: string | null
) => {
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Specify explicit types for recursiveFetch.

Currently, the recursiveFetch function and its parameters are typed with any, which reduces the benefits of TypeScript's type safety. Consider defining explicit types for the function and its parameters to enhance code reliability and maintainability.

You can update the function signature as follows:

const recursiveFetch = async (
  beasts: number[],
  nextPageKey: string | null
): Promise<number[]> => {
  // function body
};

Comment on lines +33 to +38
beasts = beasts.concat(
data?.nfts?.map((beast: any) => {
const tokenId = JSON.parse(beast.tokenId);
return Number(tokenId);
})
);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Handle cases where data.nfts might be undefined.

The code attempts to map over data?.nfts, but if data.nfts is undefined, this could lead to unexpected behavior. Ensure that data.nfts is an array before mapping to prevent errors.

You can safely handle this scenario by adding a conditional check:

if (Array.isArray(data?.nfts)) {
  beasts = beasts.concat(
    data.nfts.map((beast: any) => {
      const tokenId = JSON.parse(beast.tokenId);
      return Number(tokenId);
    })
  );
}

Comment on lines +43 to +45
} catch (ex) {
console.log("error fetching beasts", ex);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Improve error handling in the catch block.

Currently, the catch block logs the error but allows the function to return potentially incomplete data. Consider throwing the error after logging to ensure that calling functions are aware of the failure and can handle it appropriately.

Update the catch block to re-throw the error:

} catch (ex) {
  console.log("error fetching beasts", ex);
  throw ex;
}

) => Promise<void>;
ethBalance: bigint;
lordsBalance: bigint;
ethContractAddress: string;
lordsContractAddress: string;
goldenTokens: number[];
beasts: number[];
blobertsData: any;
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Define a specific type for blobertsData instead of using any

Using the any type for blobertsData bypasses TypeScript's type checking, which can lead to runtime errors that are difficult to debug. To enhance type safety and code maintainability, consider defining an explicit interface for blobertsData.

For example, you can create an interface like:

interface BlobertsData {
  tokens: TokenType[]; // Replace `TokenType` with the actual token structure
  // Add other relevant properties here
}

Update the prop type accordingly:

- blobertsData: any;
+ blobertsData: BlobertsData;

Comment on lines +108 to +112
<p>{(Number(ethBalance) / 10 ** 18).toFixed(4).toString()}</p>
</span>
<span className="flex flex-row items-center">
<Lords className="self-center w-6 h-6 fill-current mr-1" />
<p>{(Number(lordsBalance) / 10 ** 18).toFixed(2).toString()}</p>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Avoid precision loss when converting bigint balances to Number

Converting ethBalance and lordsBalance from bigint to Number may cause precision loss for large values, resulting in inaccurate balance displays. To handle large integers safely, consider using a big number library like ethers.js.

First, install ethers if it's not already a dependency:

npm install ethers

Import the formatUnits function:

import { formatUnits } from "ethers/lib/utils";

Then, update the balance displays:

- <p>{(Number(ethBalance) / 10 ** 18).toFixed(4).toString()}</p>
+ <p>{parseFloat(formatUnits(ethBalance, 18)).toFixed(4)}</p>

- <p>{(Number(lordsBalance) / 10 ** 18).toFixed(2).toString()}</p>
+ <p>{parseFloat(formatUnits(lordsBalance, 18)).toFixed(2)}</p>

This ensures that large balances are formatted correctly without losing precision.

Comment on lines 1557 to 1559
const { transaction_hash } = await account.execute(
calls[calls.length - 1]
);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Execute all withdrawal transactions instead of only the last one

Currently, the code executes only the last transaction in the calls array, which means that if there are multiple beasts to withdraw, only the last beast will be processed.

To fix this, you should execute all transactions in the calls array. You can achieve this by passing the entire calls array to account.execute().

Apply this diff to execute all transactions:

-      const { transaction_hash } = await account.execute(
-        calls[calls.length - 1]
-      );
+      const { transaction_hash } = await account.execute(
+        calls
+      );
📝 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
const { transaction_hash } = await account.execute(
calls[calls.length - 1]
);
const { transaction_hash } = await account.execute(
calls
);

Comment on lines +1551 to +1554
if (beasts.length > 0) {
calls.push(...transferBeastTxs);
}

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Handle empty withdrawal requests gracefully

If the beasts array is empty, the calls array will also be empty, leading to an error when trying to access calls[calls.length - 1].

Add a check to ensure that there are transactions to execute:

       if (beasts.length > 0) {
         calls.push(...transferBeastTxs);
       }

+      if (calls.length === 0) {
+        throw new Error("No assets to withdraw.");
+      }
📝 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
if (beasts.length > 0) {
calls.push(...transferBeastTxs);
}
if (beasts.length > 0) {
calls.push(...transferBeastTxs);
}
if (calls.length === 0) {
throw new Error("No assets to withdraw.");
}

Comment on lines +1530 to +1539
const transferBeastTxs = beasts.map((beastId) => ({
contractAddress: beastsContract?.address ?? "",
entrypoint: "transfer_from",
calldata: [
account.address,
adminAccountAddress,
beastId.toString(),
"0x0",
],
}));
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider batch executing transfers for better efficiency

Creating individual transactions for each beast could be inefficient and may lead to performance issues. Consider batching the transfers if the contract supports it.

If the beastsContract supports a batch transfer method, you can modify the code as follows:

-      const transferBeastTxs = beasts.map((beastId) => ({
-        contractAddress: beastsContract?.address ?? "",
-        entrypoint: "transfer_from",
-        calldata: [
-          account.address,
-          adminAccountAddress,
-          beastId.toString(),
-          "0x0",
-        ],
-      }));
+      const transferBeastsTx = {
+        contractAddress: beastsContract?.address ?? "",
+        entrypoint: "batch_transfer_from",
+        calldata: [
+          account.address,
+          adminAccountAddress,
+          beasts.length.toString(),
+          ...beasts.map((beastId) => [beastId.toString(), "0x0"]).flat(),
+        ],
+      };

Ensure that batch_transfer_from is implemented in the beastsContract.

Committable suggestion was skipped due to low confidence.

Comment on lines +1573 to 1575
setIsWithdrawing(false);
throw error;
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Ensure setIsWithdrawing(false) is called in all code paths

In the catch block, after rethrowing the error, the setIsWithdrawing(false) call might not execute if an error occurs. This could leave the application in a loading state.

Consider moving setIsWithdrawing(false) to a finally block to ensure it executes regardless of whether an error occurs.

       setIsWithdrawing(false);
       throw error;
+    } finally {
+      setIsWithdrawing(false);
     }

Committable suggestion was skipped due to low confidence.

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: 2

🧹 Outside diff range and nitpick comments (5)
ui/src/app/components/profile/ProfileDialog.tsx (4)

2-2: LGTM! Consider defining a type for bloberts.

The new imports and interface changes align well with the added functionality for golden tokens, beasts, and bloberts. However, to improve type safety, consider defining a specific type for bloberts instead of using any[].

You could define a type like this:

type Blobert = {
  // Add relevant properties here
};

// Update the interface
bloberts: Blobert[];

This will provide better type checking and code completion for bloberts.

Also applies to: 26-31, 37-39


77-80: LGTM! Consider using object destructuring for network config.

The addition of tournamentEnded flag and network-specific addresses is well-implemented. To slightly improve readability, you could use object destructuring for the network config.

Consider refactoring like this:

const { goldenTokenAddress, tournamentWinnerAddress: blobertsAddress } = networkConfig[network!];

This makes it clearer that both addresses are coming from the same config object.


Line range hint 184-197: Consider adding a confirmation step and visual feedback for withdrawals.

The updated withdraw functionality now includes the new assets (golden tokens, beasts, bloberts) which is great. However, to enhance user experience and prevent accidental withdrawals, consider the following improvements:

  1. Add a confirmation dialog before initiating the withdrawal.
  2. Provide visual feedback during the withdrawal process (e.g., a loading spinner).
  3. Show a success or error message after the withdrawal attempt.

Here's a basic example of how you could implement this:

const [isWithdrawing, setIsWithdrawing] = useState(false);
const [withdrawResult, setWithdrawResult] = useState<'success' | 'error' | null>(null);

const handleWithdraw = async () => {
  if (window.confirm('Are you sure you want to withdraw all assets?')) {
    setIsWithdrawing(true);
    try {
      await withdraw(
        controllerDelegate,
        account!,
        ethBalance,
        lordsBalance,
        goldenTokenAddress,
        goldenTokens,
        beasts,
        blobertsAddress,
        blobertsData?.tokens,
        tournamentEnded
      );
      setWithdrawResult('success');
    } catch (error) {
      console.error('Withdrawal failed:', error);
      setWithdrawResult('error');
    } finally {
      setIsWithdrawing(false);
    }
  }
};

// In your JSX:
<Button
  size={"lg"}
  onClick={handleWithdraw}
  disabled={isWithdrawing || controllerDelegate === "0x0" || controllerDelegate === ""}
>
  {isWithdrawing ? 'Withdrawing...' : 'Withdraw'}
</Button>
{withdrawResult === 'success' && <p>Withdrawal successful!</p>}
{withdrawResult === 'error' && <p>Withdrawal failed. Please try again.</p>}

This implementation adds a confirmation step, shows a loading state, and provides feedback on the withdrawal result.


152-152: Consider improving layout consistency and accessibility.

The layout adjustments to accommodate new elements are good, and the responsive design choices (hiding certain elements on smaller screens) are appropriate. However, there are a few areas where consistency and accessibility could be improved:

  1. Consistency in text sizes: Some headings use text-2xl sm:text-4xl, while others only use text-2xl. Consider standardizing this across all headings.

  2. Accessibility: Ensure that all interactive elements (buttons, clickable areas) have appropriate ARIA labels for screen readers.

  3. Color contrast: Verify that the text colors (especially text-terminal-green) have sufficient contrast against the background for readability.

Here are some suggestions:

  1. Standardize heading sizes:
<h2 className="text-terminal-green text-2xl sm:text-4xl uppercase m-0">
  Withdraw
</h2>
  1. Add ARIA labels to buttons:
<Button
  aria-label="Copy address"
  onClick={handleCopy}
>
  Copy
</Button>
  1. Verify color contrast:
// Consider using a tool to check the contrast ratio between these colors
<h1 className="text-terminal-green">

These small improvements will enhance the overall user experience and accessibility of the component.

Also applies to: 208-208

ui/src/app/lib/utils/syscalls.ts (1)

1593-1593: Remove console log statement used for debugging

The console.log(calls); statement is likely intended for debugging purposes and should be removed to prevent unnecessary console output in production, which can clutter logs or potentially expose sensitive information.

Apply this diff to remove the debug statement:

- console.log(calls);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between e2829c7 and bf9c576.

📒 Files selected for processing (2)
  • ui/src/app/components/profile/ProfileDialog.tsx (10 hunks)
  • ui/src/app/lib/utils/syscalls.ts (2 hunks)
🧰 Additional context used

Comment on lines +115 to +148
<div className="flex flex-row gap-5">
<span className="flex flex-row items-center">
<Eth className="self-center w-6 h-6 fill-current mr-1" />
<p>{(Number(ethBalance) / 10 ** 18).toFixed(4).toString()}</p>
</span>
<span className="flex flex-row items-center">
<Lords className="self-center w-6 h-6 fill-current mr-1" />
<p>{(Number(lordsBalance) / 10 ** 18).toFixed(2).toString()}</p>
</span>
<span className="flex flex-row gap-1 items-center">
<Image
src={"/golden-token.png"}
alt="golden-tokens"
width={32}
height={32}
/>
<p>{goldenTokens?.length}</p>
</span>
<span className="flex flex-row items-center">
<GiBruteIcon className="self-center w-8 h-8 fill-current mr-1 text-terminal-yellow" />
<p>{beasts.length}</p>
</span>
{tournamentEnded && (
<span className="flex flex-row gap-1 items-center">
<Image
src={"/blobert.png"}
alt="bloberts"
width={32}
height={32}
/>
<p>{blobertsData?.tokens.length}</p>
</span>
)}
</div>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Improve balance display and consider using a big number library.

The new UI elements for displaying various asset balances greatly enhance the user experience. However, there's a potential issue with precision loss when converting bigint balances to Number for ETH and LORDS.

To address this, consider using a big number library like ethers.js for formatting. Here's an example of how you could refactor:

import { formatUnits } from "ethers/lib/utils";

// ...

<p>{parseFloat(formatUnits(ethBalance, 18)).toFixed(4)}</p>
<p>{parseFloat(formatUnits(lordsBalance, 18)).toFixed(2)}</p>

This approach ensures accurate representation of large balances without precision loss.

The display of golden tokens, beasts, and bloberts (when the tournament has ended) is well-implemented and provides a clear overview of the user's assets.

goldenTokens: number[],
beasts: number[],
blobertsAddress: string,
bloberts: any[],
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Specify a concrete type instead of any[] for bloberts

The parameter bloberts: any[] uses the any type, which reduces type safety and defeats the purpose of using TypeScript. Defining a specific interface or type for bloberts will enhance code reliability and maintainability.

Consider defining an interface for bloberts, for example:

interface Blobert {
  tokenId: number;
  /* other properties */
}

And update the function signature:

- bloberts: any[],
+ bloberts: Blobert[],

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.

1 participant