@@ -19,6 +19,47 @@ export type ReservesResult =
1919 | { status : 'ok' ; data : ReservesSnapshot }
2020 | { status : 'unavailable' }
2121
22+ const INTEGER_STRING_PATTERN = / ^ - ? \d + $ /
23+
24+ function isRecord ( value : unknown ) : value is Record < string , unknown > {
25+ return typeof value === 'object' && value !== null && ! Array . isArray ( value )
26+ }
27+
28+ function isIntegerString ( value : unknown ) : value is string {
29+ return typeof value === 'string' && INTEGER_STRING_PATTERN . test ( value )
30+ }
31+
32+ function isValidDateString ( value : unknown ) : value is string {
33+ return typeof value === 'string' && ! Number . isNaN ( Date . parse ( value ) )
34+ }
35+
36+ function parseReservesSnapshot ( value : unknown ) : ReservesSnapshot | null {
37+ if ( ! isRecord ( value ) ) {
38+ return null
39+ }
40+
41+ const { at, fairCustodySats, wfairSupplyWei, deltaSats, pegHealthy } = value
42+ if (
43+ ! isValidDateString ( at ) ||
44+ ! isIntegerString ( fairCustodySats ) ||
45+ ! isIntegerString ( wfairSupplyWei ) ||
46+ ! isIntegerString ( deltaSats ) ||
47+ typeof pegHealthy !== 'boolean'
48+ ) {
49+ return null
50+ }
51+
52+ try {
53+ BigInt ( fairCustodySats )
54+ BigInt ( wfairSupplyWei )
55+ BigInt ( deltaSats )
56+ } catch {
57+ return null
58+ }
59+
60+ return { at, fairCustodySats, wfairSupplyWei, deltaSats, pegHealthy }
61+ }
62+
2263export function useWfairReserves ( ) {
2364 return useQuery < ReservesResult > ( {
2465 queryKey : [ 'wfair' , 'reserves' , RESERVES_ENDPOINT ] ,
@@ -31,7 +72,11 @@ export function useWfairReserves() {
3172 if ( ! response . ok ) {
3273 return { status : 'unavailable' }
3374 }
34- const data = ( await response . json ( ) ) as ReservesSnapshot
75+ const data = parseReservesSnapshot ( await response . json ( ) )
76+ if ( ! data ) {
77+ console . warn ( '[wfair-reserves] reserves API returned invalid data' )
78+ return { status : 'unavailable' }
79+ }
3580 return { status : 'ok' , data }
3681 } catch ( error ) {
3782 console . error ( '[wfair-reserves] reserves API unreachable:' , error )
0 commit comments