-
Notifications
You must be signed in to change notification settings - Fork 7
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
Renew golden token indexing #279
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,53 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { Network } from "@/app/hooks/useUIStore"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { networkConfig } from "@/app/lib/networkConfig"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { indexAddress } from "@/app/lib/utils"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export const getGoldenTokens = async ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
owner: string, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goldenTokenAddress: string, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
network: Network | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
): Promise<number[]> => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const recursiveFetch: any = async ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goldenTokens: any[], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
nextPageKey: string | null | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let url = `${ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
networkConfig[network!].blastUrl | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}/builder/getWalletNFTs?contractAddress=${goldenTokenAddress}&walletAddress=${indexAddress( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
owner | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
).toLowerCase()}&pageSize=100`; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (nextPageKey) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
url += `&pageKey=${nextPageKey}`; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+10
to
+22
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Improve type safety and security in URL construction
Apply this diff to address these issues: - const recursiveFetch: any = async (
- goldenTokens: any[],
+ const recursiveFetch = async (
+ goldenTokens: number[],
nextPageKey: string | null
- ) => {
+ ): Promise<number[]> => {
+ if (!network) {
+ throw new Error("Network is not defined");
+ }
let url = `${
- networkConfig[network!].blastUrl
+ networkConfig[network].blastUrl
- }/builder/getWalletNFTs?contractAddress=${goldenTokenAddress}&walletAddress=${indexAddress(
- owner
- ).toLowerCase()}&pageSize=100`;
+ }/builder/getWalletNFTs?contractAddress=${encodeURIComponent(goldenTokenAddress)}&walletAddress=${encodeURIComponent(indexAddress(owner).toLowerCase())}&pageSize=100`;
if (nextPageKey) {
- url += `&pageKey=${nextPageKey}`;
+ url += `&pageKey=${encodeURIComponent(nextPageKey)}`;
} 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const response = await fetch(url, { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
method: "GET", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
headers: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"Content-Type": "application/json", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+24
to
+31
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Improve error handling in the fetch request
Apply this diff to improve error handling: try {
const response = await fetch(url, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
+ if (!response.ok) {
+ throw new Error(`HTTP error! Status: ${response.status}`);
+ }
const data = await response.json();
// ... rest of the code
} catch (ex) {
- console.log("error fetching golden tokens", ex);
+ console.error("Error fetching golden tokens:", ex);
+ throw new Error(`Failed to fetch golden tokens: ${ex.message}`);
} 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const data = await response.json(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+25
to
+32
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add response status check before parsing JSON Currently, the code assumes that the fetch request is successful and proceeds to parse the response JSON. To handle potential HTTP errors, check Apply this diff to add a response status check: try {
const response = await fetch(url, {
method: "GET",
// headers...
});
+ if (!response.ok) {
+ throw new Error(`HTTP error! Status: ${response.status}`);
+ }
const data = await response.json();
// Process data...
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goldenTokens = goldenTokens.concat( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
data?.nfts?.map((goldenToken: any) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const tokenId = JSON.parse(goldenToken.tokenId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return Number(tokenId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+34
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid unnecessary Using Apply this diff to simplify the code: const data = await response.json();
goldenTokens = goldenTokens.concat(
(data?.nfts ?? []).map((goldenToken: any) => {
- const tokenId = JSON.parse(goldenToken.tokenId);
+ const tokenId = Number(goldenToken.tokenId);
return tokenId;
})
); 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+32
to
+38
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Handle cases where If Apply this diff to add a default empty array if const data = await response.json();
goldenTokens = goldenTokens.concat(
- data?.nfts?.map((goldenToken: any) => {
+ (data?.nfts ?? []).map((goldenToken: any) => {
const tokenId = Number(goldenToken.tokenId);
return tokenId;
})
); 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (data.nextPageKey) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return recursiveFetch(goldenTokens, data.nextPageKey); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} catch (ex) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
console.log("error fetching golden tokens", ex); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return goldenTokens; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+32
to
+48
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Refactor data processing and pagination logic
Apply this diff to address the immediate issues: const data = await response.json();
goldenTokens = goldenTokens.concat(
- data?.nfts?.map((goldenToken: any) => {
+ (data?.nfts ?? []).map((goldenToken: any) => {
- const tokenId = JSON.parse(goldenToken.tokenId);
- return Number(tokenId);
+ return Number(goldenToken.tokenId);
})
);
if (data.nextPageKey) {
return recursiveFetch(goldenTokens, data.nextPageKey);
} Consider refactoring the entire function to use an iterative approach: const fetchAllPages = async (): Promise<number[]> => {
let goldenTokens: number[] = [];
let nextPageKey: string | null = null;
do {
// Construct URL (with proper encoding)
try {
// Fetch and process data
// Update nextPageKey
} catch (ex) {
console.error("Error fetching golden tokens:", ex);
break;
}
} while (nextPageKey);
return goldenTokens;
}; |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let goldenTokenData = await recursiveFetch([], null); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return goldenTokenData; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,7 +13,7 @@ import useUIStore from "@/app/hooks/useUIStore"; | |
import { battle } from "@/app/lib/constants"; | ||
import { networkConfig } from "@/app/lib/networkConfig"; | ||
import { formatLords } from "@/app/lib/utils"; | ||
import { Adventurer, FormData, GameToken } from "@/app/types"; | ||
import { Adventurer, FormData } from "@/app/types"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Codebase verification Action Required: Remaining References to The following files still reference
Please update these references to ensure consistency and type safety across the codebase. 🔗 Analysis chainApproved: Updated imports and SpawnProps interface The changes to the imports and To ensure this change is consistently applied throughout the codebase, please run the following script: Also applies to: 33-37 🏁 Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Description: Check for any remaining usage of lordsBalance or goldenTokenData in SpawnProps
# Search for lordsBalance in SpawnProps
echo "Checking for lordsBalance in SpawnProps:"
rg --type typescript 'SpawnProps.*lordsBalance'
# Search for goldenTokenData in SpawnProps
echo "Checking for goldenTokenData in SpawnProps:"
rg --type typescript 'SpawnProps.*goldenTokenData'
# Search for usage of goldenTokens in SpawnProps
echo "Checking for goldenTokens in SpawnProps:"
rg --type typescript 'SpawnProps.*goldenTokens'
Length of output: 536 Script: #!/bin/bash
# Description: Check for any remaining usage of lordsBalance or goldenTokenData in SpawnProps
# Define the search patterns
PATTERNS=("lordsBalance" "goldenTokenData")
# Iterate over each pattern and search in .ts and .tsx files
for pattern in "${PATTERNS[@]}"; do
echo "Checking for ${pattern} in SpawnProps:"
rg "${pattern}" --glob "*.ts" --glob "*.tsx"
done
# Additionally, check for usage of goldenTokens in SpawnProps
echo "Checking for goldenTokens in SpawnProps:"
rg "goldenTokens" --glob "*.ts" --glob "*.tsx"
Length of output: 3865 |
||
import Image from "next/image"; | ||
import Lords from "public/icons/lords.svg"; | ||
import { useEffect, useMemo, useState } from "react"; | ||
|
@@ -30,25 +30,21 @@ export interface SpawnProps { | |
costToPlay?: number | ||
) => Promise<void>; | ||
handleBack: () => void; | ||
lordsBalance?: bigint; | ||
goldenTokenData: any; | ||
goldenTokens: number[]; | ||
blobertsData: any; | ||
gameContract: Contract; | ||
getBalances: () => Promise<void>; | ||
mintLords: (lordsAmount: number) => Promise<void>; | ||
costToPlay: bigint; | ||
} | ||
|
||
export const Spawn = ({ | ||
formData, | ||
spawn, | ||
handleBack, | ||
lordsBalance, | ||
goldenTokenData, | ||
goldenTokens, | ||
blobertsData, | ||
gameContract, | ||
getBalances, | ||
mintLords, | ||
costToPlay, | ||
}: SpawnProps) => { | ||
const [paymentInitiated, setPaymentInitiated] = useState(false); | ||
|
@@ -89,11 +85,6 @@ export const Spawn = ({ | |
} | ||
}; | ||
|
||
const goldenTokens = goldenTokenData?.getERC721Tokens; | ||
const goldenTokenIds: number[] = goldenTokens?.map( | ||
(token: GameToken) => token.token_id | ||
); | ||
|
||
const getUsableGoldenToken = async (tokenIds: number[]) => { | ||
// Loop through contract calls to see if the token is usable, if none then return 0 | ||
for (let tokenId of tokenIds) { | ||
|
@@ -133,7 +124,7 @@ export const Spawn = ({ | |
const tournamentEnded = process.env.NEXT_PUBLIC_TOURNAMENT_ENDED === "true"; | ||
|
||
useEffect(() => { | ||
getUsableGoldenToken(goldenTokenIds ?? []); | ||
getUsableGoldenToken(goldenTokens ?? []); | ||
if (tournamentEnded) { | ||
getUsableBlobertToken(blobertTokenIds ?? []); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,21 @@ | ||
"use client"; | ||
|
||
import { useEffect, useState } from "react"; | ||
import { ApolloProvider } from "@apollo/client"; | ||
import BurnerLoader from "@/app/components/animations/BurnerLoader"; | ||
import Intro from "@/app/components/intro/Intro"; | ||
import LoginIntro from "@/app/components/onboarding/Intro"; | ||
Comment on lines
+3
to
+5
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Clarify Component Naming to Avoid Confusion The imports on lines 3-5 include both import BurnerLoader from "@/app/components/animations/BurnerLoader";
import Intro from "@/app/components/intro/Intro";
import LoginIntro from "@/app/components/onboarding/Intro"; Having components with similar names can lead to confusion and maintainability issues. Consider renaming |
||
import { ControllerProvider } from "@/app/context/ControllerContext"; | ||
import { gameClient, goldenTokenClient } from "@/app/lib/clients"; | ||
import useUIStore from "@/app/hooks/useUIStore"; | ||
import { StarknetProvider } from "@/app/provider"; | ||
import { DojoProvider } from "@/app/dojo/DojoContext"; | ||
import { setup } from "@/app/dojo/setup"; | ||
import LoginIntro from "@/app/components/onboarding/Intro"; | ||
import Intro from "@/app/components/intro/Intro"; | ||
import "@/app/globals.css"; | ||
import { BurnerManager } from "@dojoengine/create-burner"; | ||
import { RpcProvider } from "starknet"; | ||
import Head from "@/app/head"; | ||
import useUIStore from "@/app/hooks/useUIStore"; | ||
import { gameClient } from "@/app/lib/clients"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ensure On line 12, the import { gameClient } from "@/app/lib/clients"; Later, in the <ApolloProvider client={gameClient(networkConfig[network].lsGQLURL!)}> The exclamation mark |
||
import { StarknetProvider } from "@/app/provider"; | ||
import { ApolloProvider } from "@apollo/client"; | ||
import { BurnerManager } from "@dojoengine/create-burner"; | ||
import { Analytics } from "@vercel/analytics/react"; | ||
import BurnerLoader from "@/app/components/animations/BurnerLoader"; | ||
import { useEffect, useState } from "react"; | ||
import { RpcProvider } from "starknet"; | ||
import { networkConfig } from "./lib/networkConfig"; | ||
|
||
type SetupResult = { | ||
|
@@ -83,15 +83,11 @@ export default function RootLayout({ | |
</main> | ||
) : ( | ||
<ApolloProvider client={gameClient(networkConfig[network].lsGQLURL!)}> | ||
<ApolloProvider | ||
client={goldenTokenClient(networkConfig[network].tokensGQLURL)} | ||
> | ||
<ControllerProvider> | ||
<StarknetProvider network={network}> | ||
<DojoProvider value={setupResult}>{children}</DojoProvider> | ||
</StarknetProvider> | ||
</ControllerProvider> | ||
</ApolloProvider> | ||
<ControllerProvider> | ||
<StarknetProvider network={network}> | ||
<DojoProvider value={setupResult}>{children}</DojoProvider> | ||
</StarknetProvider> | ||
</ControllerProvider> | ||
</ApolloProvider> | ||
)} | ||
</body> | ||
|
There was a problem hiding this comment.
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 instead of using
any
Using
any
defeats TypeScript's static type checking. Consider defining explicit types for therecursiveFetch
function and its parameters to enhance type safety and maintainability.Apply this diff to specify explicit types:
📝 Committable suggestion