|
3 | 3 | import { useCallback, useEffect, useRef, useState } from "react"; |
4 | 4 | import { isAddress } from "viem"; |
5 | 5 | import { useBlockNumber, useReadContract } from "wagmi"; |
6 | | -import { nftValidationCache } from "@/lib/nft/cache/NFTCacheManager"; |
| 6 | + |
| 7 | +// Simple in-memory cache for validation results |
| 8 | +const validationCache = new Map< |
| 9 | + string, |
| 10 | + { data: any; timestamp: number; blockNumber: number } |
| 11 | +>(); |
7 | 12 |
|
8 | 13 | // ERC165 interface IDs |
9 | 14 | const ERC165_INTERFACE_ID = "0x01ffc9a7"; |
@@ -84,19 +89,15 @@ export function useEnhancedNFTValidation( |
84 | 89 | useEffect(() => { |
85 | 90 | if (!isValidAddress || !cacheKey || !enableCaching || forceFresh) return; |
86 | 91 |
|
87 | | - const cached = nftValidationCache.get(cacheKey, Number(currentBlock)); |
88 | | - if (cached) { |
| 92 | + const cached = validationCache.get(cacheKey); |
| 93 | + if ( |
| 94 | + cached && |
| 95 | + (!currentBlock || cached.blockNumber >= Number(currentBlock) - 100) |
| 96 | + ) { |
89 | 97 | setResult({ |
90 | | - ...cached, |
| 98 | + ...cached.data, |
91 | 99 | fromCache: true, |
92 | | - cacheAge: |
93 | | - Date.now() - |
94 | | - (nftValidationCache |
95 | | - .getEntries() |
96 | | - ?.find( |
97 | | - (entry: { key: string; entry: { timestamp: number } }) => |
98 | | - entry.key === cacheKey, |
99 | | - )?.entry.timestamp || 0), |
| 100 | + cacheAge: Date.now() - cached.timestamp, |
100 | 101 | }); |
101 | 102 | return; |
102 | 103 | } |
@@ -178,19 +179,15 @@ export function useEnhancedNFTValidation( |
178 | 179 |
|
179 | 180 | // Check if we have results |
180 | 181 | if (cacheKey && enableCaching && !forceFresh) { |
181 | | - const cached = nftValidationCache.get(cacheKey, Number(currentBlock)); |
182 | | - if (cached) { |
| 182 | + const cached = validationCache.get(cacheKey); |
| 183 | + if ( |
| 184 | + cached && |
| 185 | + (!currentBlock || cached.blockNumber >= Number(currentBlock) - 100) |
| 186 | + ) { |
183 | 187 | setResult({ |
184 | | - ...cached, |
| 188 | + ...cached.data, |
185 | 189 | fromCache: true, |
186 | | - cacheAge: |
187 | | - Date.now() - |
188 | | - (nftValidationCache |
189 | | - .getEntries() |
190 | | - ?.find( |
191 | | - (entry: { key: string; entry: { timestamp: number } }) => |
192 | | - entry.key === cacheKey, |
193 | | - )?.entry.timestamp || 0), |
| 190 | + cacheAge: Date.now() - cached.timestamp, |
194 | 191 | }); |
195 | 192 | return; |
196 | 193 | } |
@@ -236,12 +233,11 @@ export function useEnhancedNFTValidation( |
236 | 233 |
|
237 | 234 | // Cache the result |
238 | 235 | if (cacheKey && enableCaching && validationResult.isValid) { |
239 | | - nftValidationCache.set( |
240 | | - cacheKey, |
241 | | - validationResult, |
242 | | - Number(currentBlock), |
243 | | - 300000, // 5 minutes |
244 | | - ); |
| 236 | + validationCache.set(cacheKey, { |
| 237 | + data: validationResult, |
| 238 | + timestamp: Date.now(), |
| 239 | + blockNumber: Number(currentBlock) || 0, |
| 240 | + }); |
245 | 241 | } |
246 | 242 |
|
247 | 243 | setResult(validationResult); |
@@ -305,13 +301,20 @@ export function useEnhancedNFTValidation( |
305 | 301 |
|
306 | 302 | // Clear cache if it exists |
307 | 303 | if (cacheKey) { |
308 | | - nftValidationCache.delete(cacheKey); |
| 304 | + validationCache.delete(cacheKey); |
309 | 305 | } |
310 | 306 | }, [cacheKey]); |
311 | 307 |
|
312 | 308 | // Get cache stats |
313 | 309 | const getCacheStats = useCallback(() => { |
314 | | - return nftValidationCache.instance.getStats(); |
| 310 | + return { |
| 311 | + size: validationCache.size, |
| 312 | + entries: Array.from(validationCache.entries()).map(([key, value]) => ({ |
| 313 | + key, |
| 314 | + age: Date.now() - value.timestamp, |
| 315 | + blockNumber: value.blockNumber, |
| 316 | + })), |
| 317 | + }; |
315 | 318 | }, []); |
316 | 319 |
|
317 | 320 | return { |
@@ -351,10 +354,10 @@ export function useBatchNFTValidation( |
351 | 354 |
|
352 | 355 | // Check cache first |
353 | 356 | const cacheKey = `nft-validation-${address.toLowerCase()}`; |
354 | | - const cached = nftValidationCache.get(cacheKey); |
| 357 | + const cached = validationCache.get(cacheKey); |
355 | 358 |
|
356 | 359 | if (cached && !options.forceFresh) { |
357 | | - validationResults[address] = { ...cached, fromCache: true }; |
| 360 | + validationResults[address] = { ...cached.data, fromCache: true }; |
358 | 361 | } else { |
359 | 362 | // Would need to implement actual validation here |
360 | 363 | // For now, mark as pending |
@@ -388,26 +391,46 @@ export function useBatchNFTValidation( |
388 | 391 | * Hook to get validation statistics |
389 | 392 | */ |
390 | 393 | export function useNFTValidationStats() { |
391 | | - const [stats, setStats] = useState(nftValidationCache.instance.getStats()); |
| 394 | + const getStats = useCallback( |
| 395 | + () => ({ |
| 396 | + size: validationCache.size, |
| 397 | + entries: Array.from(validationCache.entries()).map(([key, value]) => ({ |
| 398 | + key, |
| 399 | + age: Date.now() - value.timestamp, |
| 400 | + blockNumber: value.blockNumber, |
| 401 | + })), |
| 402 | + }), |
| 403 | + [], |
| 404 | + ); |
| 405 | + |
| 406 | + const [stats, setStats] = useState(getStats()); |
392 | 407 |
|
393 | 408 | useEffect(() => { |
394 | 409 | const interval = setInterval(() => { |
395 | | - setStats(nftValidationCache.instance.getStats()); |
| 410 | + setStats(getStats()); |
396 | 411 | }, 5000); // Update every 5 seconds |
397 | 412 |
|
398 | 413 | return () => clearInterval(interval); |
399 | | - }, []); |
| 414 | + }, [getStats]); |
400 | 415 |
|
401 | 416 | const clearCache = useCallback(() => { |
402 | | - nftValidationCache.clear(); |
403 | | - setStats(nftValidationCache.instance.getStats()); |
404 | | - }, []); |
| 417 | + validationCache.clear(); |
| 418 | + setStats(getStats()); |
| 419 | + }, [getStats]); |
405 | 420 |
|
406 | 421 | const cleanup = useCallback(() => { |
407 | | - const removed = nftValidationCache.instance.cleanup(); |
408 | | - setStats(nftValidationCache.instance.getStats()); |
| 422 | + // Remove entries older than 5 minutes |
| 423 | + const fiveMinutesAgo = Date.now() - 300000; |
| 424 | + let removed = 0; |
| 425 | + for (const [key, value] of validationCache.entries()) { |
| 426 | + if (value.timestamp < fiveMinutesAgo) { |
| 427 | + validationCache.delete(key); |
| 428 | + removed++; |
| 429 | + } |
| 430 | + } |
| 431 | + setStats(getStats()); |
409 | 432 | return removed; |
410 | | - }, []); |
| 433 | + }, [getStats]); |
411 | 434 |
|
412 | 435 | return { |
413 | 436 | stats, |
|
0 commit comments