1- import axios , { AxiosError } from 'axios' ;
1+ import axios from 'axios' ;
22import { AddressResponse , TransactionResponse , BitcoinPrice , LiveTransaction , NetworkInfo , BlockData , BlockInfo } from '../types' ;
33import blockApi from './blockApi' ;
44import { isBlockHash } from './validation' ;
55
66// Base URL should be absolute when running in Docker
77const API_BASE_URL = '/api/v2' ;
88const BLOCKCHAIN_API_URL = '/block_api' ;
9+ const API_BLOCKCHAIN = '/blockapi/'
910
1011const userAgents = [
1112 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36' ,
@@ -16,6 +17,16 @@ const userAgents = [
1617const getRandomUserAgent = ( ) => {
1718 return userAgents [ Math . floor ( Math . random ( ) * userAgents . length ) ] ;
1819} ;
20+ // Create separate axios instances for different APIs
21+ const blockchainapi = axios . create ( {
22+ baseURL : API_BLOCKCHAIN ,
23+ headers : {
24+ 'Accept' : 'application/json' ,
25+ 'Content-Type' : 'application/json' ,
26+ } ,
27+ timeout : 5000 , // Reduced timeout to 5 seconds
28+ validateStatus : ( status ) => status >= 200 && status < 500
29+ } ) ;
1930
2031// Create separate axios instances for different APIs
2132const bitcoinApi = axios . create ( {
@@ -44,6 +55,12 @@ bitcoinApi.interceptors.request.use((config) => {
4455 return config ;
4556} ) ;
4657
58+ // Add request interceptor to rotate User-Agent
59+ blockchainapi . interceptors . request . use ( ( config ) => {
60+ config . headers [ 'User-Agent' ] = getRandomUserAgent ( ) ;
61+ return config ;
62+ } ) ;
63+
4764blockchainApi . interceptors . request . use ( ( config ) => {
4865 config . headers [ 'User-Agent' ] = getRandomUserAgent ( ) ;
4966 return config ;
@@ -114,7 +131,7 @@ export const fetchAddressInfo = async (address: string): Promise<AddressResponse
114131export const fetchTransactionInfo = async ( txid : string ) : Promise < TransactionResponse > => {
115132 try {
116133 const response = await retryRequest ( ( ) =>
117- blockchainApi . get ( `/rawtx /${ txid } ?format=json ` )
134+ bitcoinApi . get ( `/tx /${ txid } ` )
118135 ) ;
119136
120137 if ( ! response . data ) {
@@ -123,26 +140,23 @@ export const fetchTransactionInfo = async (txid: string): Promise<TransactionRes
123140
124141 const data = response . data ;
125142
126- // Process the transaction data
127- const processedData : TransactionResponse = {
128- txid : data . hash ,
129- blockHeight : data . block_height || 0 ,
130- blockTime : data . time || Math . floor ( Date . now ( ) / 1000 ) ,
143+ return {
144+ txid : data . txid ,
145+ blockHeight : data . blockHeight || 0 ,
146+ blockTime : data . blockTime || Math . floor ( Date . now ( ) / 1000 ) ,
131147 confirmations : data . confirmations || 0 ,
132- fees : data . fee ? ( data . fee / 100000000 ) . toString ( ) : '0' , // Convert satoshis to BTC
148+ fees : data . fees || '0' ,
133149 size : data . size || 0 ,
134- value : data . total ? ( data . total / 100000000 ) . toString ( ) : '0' , // Convert satoshis to BTC
135- vin : ( data . inputs || [ ] ) . map ( ( input : any ) => ( {
136- addresses : input . prev_out ?. addr ? [ input . prev_out . addr ] : [ ] ,
137- value : input . prev_out ?. value ? ( input . prev_out . value / 100000000 ) . toString ( ) : '0' // Convert satoshis to BTC
150+ value : data . value || '0' ,
151+ vin : ( data . vin || [ ] ) . map ( ( input : any ) => ( {
152+ addresses : input . addresses || [ ] ,
153+ value : input . value || '0'
138154 } ) ) ,
139- vout : ( data . out || [ ] ) . map ( ( output : any ) => ( {
140- addresses : output . addr ? [ output . addr ] : [ ] ,
141- value : output . value ? ( output . value / 100000000 ) . toString ( ) : '0' // Convert satoshis to BTC
155+ vout : ( data . vout || [ ] ) . map ( ( output : any ) => ( {
156+ addresses : output . addresses || [ ] ,
157+ value : output . value || '0'
142158 } ) )
143159 } ;
144-
145- return processedData ;
146160 } catch ( error ) {
147161 console . error ( 'Error fetching transaction info:' , error ) ;
148162 if ( axios . isAxiosError ( error ) ) {
@@ -153,29 +167,28 @@ export const fetchTransactionInfo = async (txid: string): Promise<TransactionRes
153167 }
154168} ;
155169
170+
156171export const fetchBitcoinPrice = async ( ) : Promise < BitcoinPrice > => {
157172 try {
158- // Use a direct API endpoint with a short timeout
159- const response = await axios . get ( '/block_api/q/24hrprice' , {
160- timeout : 3000
173+ // Use a more reliable API endpoint with simpler data structure
174+ const response = await axios . get ( 'https://api.coingecko.com/api/v3/simple/price' , {
175+ params : {
176+ ids : 'bitcoin' ,
177+ vs_currencies : 'usd' ,
178+ include_24hr_change : true
179+ } ,
180+ timeout : 10000
161181 } ) ;
162182
163- // Parse the price from the response
164- let price = 0 ;
165- try {
166- price = parseFloat ( response . data ) ;
167- if ( isNaN ( price ) ) {
168- throw new Error ( 'Invalid price format' ) ;
169- }
170- } catch ( e ) {
171- // Default price if parsing fails
172- price = 65000 + Math . random ( ) * 2000 ;
183+ if ( ! response . data ?. bitcoin ) {
184+ throw new Error ( 'Invalid price data received' ) ;
173185 }
174-
175- // Get yesterday's price to calculate 24h change
176- const yesterdayPrice = price * ( 1 - ( Math . random ( ) * 0.05 - 0.025 ) ) ; // Simulate a change between -2.5% and +2.5%
177- const change = ( ( price - yesterdayPrice ) / yesterdayPrice ) * 100 ;
178186
187+ // Fix: Ensure we're working with primitive types only
188+ const price = Number ( response . data . bitcoin . usd ) || 0 ;
189+ const change = Number ( response . data . bitcoin . usd_24h_change ) || 0 ;
190+
191+ // Return a simple object with primitive values
179192 return {
180193 USD : {
181194 last : price ,
@@ -196,7 +209,6 @@ export const fetchBitcoinPrice = async (): Promise<BitcoinPrice> => {
196209 } ;
197210 }
198211} ;
199-
200212export const fetchLiveTransactions = async ( ) : Promise < LiveTransaction [ ] > => {
201213 try {
202214 const response = await blockchainApi . get ( '/unconfirmed-transactions?format=json' , {
@@ -290,7 +302,7 @@ export const fetchLatestBlocks = async (limit: number = 10): Promise<BlockData[]
290302 try {
291303 // Try blockchain.info API first
292304 try {
293- const response = await blockchainApi . get ( '/blocks?format=json' ) ;
305+ const response = await blockchainapi . get ( '/blocks?format=json' ) ;
294306
295307 if ( ! response . data || ! Array . isArray ( response . data . blocks ) ) {
296308 throw new Error ( 'Invalid block data format received' ) ;
0 commit comments