-
Notifications
You must be signed in to change notification settings - Fork 140
#1127 fix github verification #1183
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
base: testnet
Are you sure you want to change the base?
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,37 @@ | ||
| import React, { useCallback, useRef } from 'react'; | ||
| import { IdentityRefreshContext } from '../../hooks/useIdentityRefresh'; | ||
|
|
||
| interface IdentityRefreshProviderProps { | ||
| children: React.ReactNode; | ||
| } | ||
|
|
||
| export const IdentityRefreshProvider: React.FC<IdentityRefreshProviderProps> = ({ children }) => { | ||
| const refreshCallbacks = useRef<Map<string, () => void>>(new Map()); | ||
|
|
||
| const registerRefreshCallback = useCallback((tokenId: string, callback: () => void) => { | ||
| refreshCallbacks.current.set(tokenId, callback); | ||
| }, []); | ||
|
|
||
| const unregisterRefreshCallback = useCallback((tokenId: string) => { | ||
| refreshCallbacks.current.delete(tokenId); | ||
| }, []); | ||
|
|
||
| const refreshIdentity = useCallback((tokenId: string) => { | ||
| const callback = refreshCallbacks.current.get(tokenId); | ||
| if (callback) { | ||
| callback(); | ||
| } | ||
| }, []); | ||
|
|
||
| return ( | ||
| <IdentityRefreshContext.Provider | ||
| value={{ | ||
| refreshIdentity, | ||
| registerRefreshCallback, | ||
| unregisterRefreshCallback, | ||
| }} | ||
| > | ||
| {children} | ||
| </IdentityRefreshContext.Provider> | ||
| ); | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| import { createContext, useContext } from 'react'; | ||
|
|
||
| interface IdentityRefreshContextType { | ||
| refreshIdentity: (tokenId: string) => void; | ||
| registerRefreshCallback: (tokenId: string, callback: () => void) => void; | ||
| unregisterRefreshCallback: (tokenId: string) => void; | ||
| } | ||
|
|
||
| export const IdentityRefreshContext = createContext<IdentityRefreshContextType | null>(null); | ||
|
|
||
| export const useIdentityRefresh = () => { | ||
| const context = useContext(IdentityRefreshContext); | ||
| if (!context) { | ||
| throw new Error('useIdentityRefresh must be used within an IdentityRefreshProvider'); | ||
| } | ||
| return context; | ||
| }; |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -3,11 +3,12 @@ import { useAtom } from "jotai"; | |||||||||||||||||
| import { atomWithStorage } from "jotai/utils"; | ||||||||||||||||||
| import { useEffect } from "react"; | ||||||||||||||||||
| import { hexToDecimal } from "../utils/feltService"; | ||||||||||||||||||
| import { NotificationType } from "../utils/constants"; | ||||||||||||||||||
| import { NotificationType, TransactionType } from "../utils/constants"; | ||||||||||||||||||
| import { | ||||||||||||||||||
| RejectedTransactionReceiptResponse, | ||||||||||||||||||
| RevertedTransactionReceiptResponse, | ||||||||||||||||||
| } from "starknet"; | ||||||||||||||||||
| import { useIdentityRefresh } from "./useIdentityRefresh"; | ||||||||||||||||||
|
|
||||||||||||||||||
| const notificationsAtom = atomWithStorage<SIDNotification<NotificationData>[]>( | ||||||||||||||||||
| "userNotifications_SID", | ||||||||||||||||||
|
|
@@ -18,6 +19,14 @@ export function useNotificationManager() { | |||||||||||||||||
| const { provider } = useProvider(); | ||||||||||||||||||
| const { address } = useAccount(); | ||||||||||||||||||
| const [notifications, setNotifications] = useAtom(notificationsAtom); | ||||||||||||||||||
|
|
||||||||||||||||||
| let refreshIdentity: ((tokenId: string) => void) | null = null; | ||||||||||||||||||
| try { | ||||||||||||||||||
| const context = useIdentityRefresh(); | ||||||||||||||||||
| refreshIdentity = context.refreshIdentity; | ||||||||||||||||||
| } catch { | ||||||||||||||||||
|
|
||||||||||||||||||
| } | ||||||||||||||||||
|
Comment on lines
+23
to
+29
Contributor
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. Critical: Fix conditional hook usage and empty catch block. Two issues here:
Apply this diff to fix both issues: - let refreshIdentity: ((tokenId: string) => void) | null = null;
- try {
- const context = useIdentityRefresh();
- refreshIdentity = context.refreshIdentity;
- } catch {
-
- }
+ const { refreshIdentity } = useIdentityRefresh();If the provider might not be available, consider using a default context value or ensuring the provider is always present. 📝 Committable suggestion
Suggested change
🧰 Tools🪛 Biome (2.1.2)[error] 25-25: This hook is being called conditionally, but all hooks must be called in the exact same order in every component render. For React to preserve state between calls, hooks needs to be called unconditionally and always in the same order. (lint/correctness/useHookAtTopLevel) 🪛 ESLint[error] 27-29: Empty block statement. (no-empty) 🤖 Prompt for AI Agents |
||||||||||||||||||
|
|
||||||||||||||||||
| useEffect(() => { | ||||||||||||||||||
| const checkTransactionStatus = async ( | ||||||||||||||||||
|
|
@@ -58,6 +67,21 @@ export function useNotificationManager() { | |||||||||||||||||
| transactionReceipt.finality_status; | ||||||||||||||||||
| updatedTransactions[index].data.status = "success"; | ||||||||||||||||||
| setNotifications(updatedTransactions); | ||||||||||||||||||
|
|
||||||||||||||||||
| const verificationTypes = [ | ||||||||||||||||||
| TransactionType.VERIFIER_GITHUB, | ||||||||||||||||||
| TransactionType.VERIFIER_TWITTER, | ||||||||||||||||||
| TransactionType.VERIFIER_DISCORD, | ||||||||||||||||||
| TransactionType.VERIFIER_POP | ||||||||||||||||||
| ]; | ||||||||||||||||||
|
|
||||||||||||||||||
| if (verificationTypes.includes(transaction.type) && refreshIdentity) { | ||||||||||||||||||
| const subtextMatch = notification.subtext?.match(/Starknet ID #(\d+)/); | ||||||||||||||||||
| if (subtextMatch) { | ||||||||||||||||||
| const tokenId = subtextMatch[1]; | ||||||||||||||||||
| setTimeout(() => refreshIdentity(tokenId), 1000); | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
| }; | ||||||||||||||||||
|
|
@@ -67,7 +91,7 @@ export function useNotificationManager() { | |||||||||||||||||
| }, 5000); | ||||||||||||||||||
|
|
||||||||||||||||||
| return () => clearInterval(intervalId); | ||||||||||||||||||
| }, [notifications, address, provider, setNotifications]); | ||||||||||||||||||
| }, [notifications, address, provider, setNotifications, refreshIdentity]); | ||||||||||||||||||
|
|
||||||||||||||||||
| const filteredNotifications = address | ||||||||||||||||||
| ? notifications.filter( | ||||||||||||||||||
|
|
||||||||||||||||||
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.
Critical: Fix conditional hook usage violation.
The
useIdentityRefreshhook is being called conditionally inside a try-catch block, which violates React's Rules of Hooks. This can cause unpredictable behavior and state corruption.Apply this diff to fix the hooks violation:
If you need to handle the case where the provider might not be available, consider using a default context value or ensuring the provider is always present in the component tree.
📝 Committable suggestion
🧰 Tools
🪛 Biome (2.1.2)
[error] 41-41: This hook is being called conditionally, but all hooks must be called in the exact same order in every component render.
For React to preserve state between calls, hooks needs to be called unconditionally and always in the same order.
See https://reactjs.org/docs/hooks-rules.html#only-call-hooks-at-the-top-level
(lint/correctness/useHookAtTopLevel)
🤖 Prompt for AI Agents