@@ -35,19 +35,56 @@ blockchainApi.interceptors.request.use((config) => {
3535 return config ;
3636} ) ;
3737
38+ // Cache for latest block height
39+ let cachedBlockHeight : number | null = null ;
40+
41+ /**
42+ * Get the latest block height
43+ */
44+ const getLatestBlockHeight = async ( ) : Promise < number > => {
45+ if ( cachedBlockHeight !== null ) {
46+ return cachedBlockHeight ;
47+ }
48+
49+ try {
50+ // Try to get the latest block height from the API
51+ const response = await blockchainApi . get ( '/latestblock?format=json' ) ;
52+ if ( response . data ?. height ) {
53+ cachedBlockHeight = response . data . height ;
54+ return response . data . height ;
55+ }
56+
57+ // If that fails, try alternative API
58+ const altResponse = await axios . get ( '/api/v2/stats' ) ;
59+ if ( altResponse . data ?. blockHeight ) {
60+ cachedBlockHeight = altResponse . data . blockHeight ;
61+ return altResponse . data . blockHeight ;
62+ }
63+
64+ throw new Error ( 'Could not get latest block height' ) ;
65+ } catch ( error ) {
66+ console . warn ( 'Failed to get latest block height:' , error ) ;
67+ // Use a reasonable default
68+ return 830000 ;
69+ }
70+ } ;
71+
3872/**
3973 * Generate mock blocks for testing or API failure
4074 */
41- const generateMockBlocks = ( limit : number ) : BlockData [ ] => {
75+ const generateMockBlocks = async ( limit : number ) : Promise < BlockData [ ] > => {
4276 const mockBlocks : BlockData [ ] = [ ] ;
4377 const now = Math . floor ( Date . now ( ) / 1000 ) ;
4478 const miners = [ 'Foundry USA' , 'AntPool' , 'F2Pool' , 'Binance Pool' , 'ViaBTC' ] ;
4579
80+ // Get the latest block height to use as starting point
81+ const latestHeight = await getLatestBlockHeight ( ) ;
82+
4683 for ( let i = 0 ; i < limit ; i ++ ) {
4784 mockBlocks . push ( {
4885 hash : `000000000000000000${ Math . random ( ) . toString ( 16 ) . substring ( 2 , 14 ) } ` ,
49- height : 800000 - i ,
50- time : now - ( i * 600 ) ,
86+ height : latestHeight - i ,
87+ time : now - ( i * 600 ) , // Approximately 10 minutes per block
5188 size : 1000000 + Math . floor ( Math . random ( ) * 500000 ) ,
5289 txCount : 2000 + Math . floor ( Math . random ( ) * 1000 ) ,
5390 miner : miners [ Math . floor ( Math . random ( ) * miners . length ) ]
@@ -72,14 +109,21 @@ export const fetchLatestBlocks = async (limit: number = 10): Promise<BlockData[]
72109 throw new Error ( 'Invalid block data format received' ) ;
73110 }
74111
75- return response . data . blocks . slice ( 0 , limit ) . map ( ( block : any ) => ( {
112+ const blocks = response . data . blocks . slice ( 0 , limit ) . map ( ( block : any ) => ( {
76113 hash : block . hash || '' ,
77114 height : block . height || 0 ,
78115 time : block . time || Math . floor ( Date . now ( ) / 1000 ) ,
79116 size : block . size || 0 ,
80117 txCount : block . n_tx || 0 ,
81118 miner : extractMinerFromCoinbase ( block . miner || '' )
82119 } ) ) ;
120+
121+ // Update cached block height if we got valid data
122+ if ( blocks . length > 0 && blocks [ 0 ] . height > 0 ) {
123+ cachedBlockHeight = blocks [ 0 ] . height ;
124+ }
125+
126+ return blocks ;
83127 } catch ( primaryError ) {
84128 console . warn ( 'Primary API failed, trying alternative:' , primaryError ) ;
85129
@@ -95,17 +139,23 @@ export const fetchLatestBlocks = async (limit: number = 10): Promise<BlockData[]
95139 throw new Error ( 'Invalid block data from alternative API' ) ;
96140 }
97141
98- // If alternative API returns array directly
142+ let blocks : BlockData [ ] = [ ] ;
143+
144+ // Handle different API response structures
99145 if ( Array . isArray ( altResponse . data ) ) {
100- return altResponse . data . slice ( 0 , limit ) ;
146+ blocks = altResponse . data . slice ( 0 , limit ) ;
147+ } else if ( altResponse . data . blocks && Array . isArray ( altResponse . data . blocks ) ) {
148+ blocks = altResponse . data . blocks . slice ( 0 , limit ) ;
149+ } else {
150+ throw new Error ( 'Unexpected data structure from alternative API' ) ;
101151 }
102-
103- // If alternative API has different structure
104- if ( altResponse . data . blocks && Array . isArray ( altResponse . data . blocks ) ) {
105- return altResponse . data . blocks . slice ( 0 , limit ) ;
152+
153+ // Update cached block height if we got valid data
154+ if ( blocks . length > 0 && blocks [ 0 ] . height > 0 ) {
155+ cachedBlockHeight = blocks [ 0 ] . height ;
106156 }
107-
108- throw new Error ( 'Unexpected data structure from alternative API' ) ;
157+
158+ return blocks ;
109159 }
110160 } catch ( error ) {
111161 console . warn ( 'All APIs failed, using mock data:' , error ) ;
@@ -132,6 +182,11 @@ export const fetchNetworkStats = async (): Promise<NetworkInfo> => {
132182 if ( ! stats . data ) {
133183 throw new Error ( 'Invalid stats data received' ) ;
134184 }
185+
186+ // Update cached block height
187+ if ( latestBlock . data ?. height ) {
188+ cachedBlockHeight = latestBlock . data . height ;
189+ }
135190
136191 return {
137192 timestamp : Date . now ( ) ,
@@ -163,6 +218,11 @@ export const fetchNetworkStats = async (): Promise<NetworkInfo> => {
163218 if ( ! altResponse . data ) {
164219 throw new Error ( 'Invalid stats data from alternative API' ) ;
165220 }
221+
222+ // Update cached block height if available
223+ if ( altResponse . data . blockHeight ) {
224+ cachedBlockHeight = altResponse . data . blockHeight ;
225+ }
166226
167227 return altResponse . data ;
168228 }
@@ -174,9 +234,9 @@ export const fetchNetworkStats = async (): Promise<NetworkInfo> => {
174234 hashRate : 350.5 ,
175235 difficulty : 78.3 ,
176236 unconfirmedTxs : 12500 ,
177- blockHeight : 800000 ,
237+ blockHeight : await getLatestBlockHeight ( ) ,
178238 latestBlockHash : '000000000000000000' + Math . random ( ) . toString ( 16 ) . substring ( 2 , 14 ) ,
179- nextRetargetBlock : Math . ceil ( 800000 / 2016 ) * 2016 ,
239+ nextRetargetBlock : Math . ceil ( ( await getLatestBlockHeight ( ) ) / 2016 ) * 2016 ,
180240 mempoolSize : 250 ,
181241 totalTransactions : 850000000 ,
182242 avgBlockTime : 9.8 ,
0 commit comments