import { CoinMarketData, CoinDetail, GlobalData, TrendingCoin, SearchResult } from '../types/index.ts'; const COINGECKO_BASE = 'https://api.coingecko.com/api/v3'; export interface MarketChartData { prices: [number, number][]; market_caps: [number, number][]; total_volumes: [number, number][]; } const MOCK_MARKETS: CoinMarketData[] = [ { id: 'bitcoin', symbol: 'btc', name: 'Bitcoin', image: 'https://assets.coingecko.com/coins/images/1/large/bitcoin.png', current_price: 64231.50, market_cap: 1260000000000, market_cap_rank: 1, fully_diluted_valuation: 1350000000000, total_volume: 35000000000, high_24h: 65000, low_24h: 63000, price_change_24h: 1231, price_change_percentage_24h: 1.95, market_cap_change_24h: 24000000000, market_cap_change_percentage_24h: 1.9, circulating_supply: 19600000, total_supply: 21000000, max_supply: 21000000, ath: 73000, ath_change_percentage: -12, ath_date: '2024-03-14', atl: 67, atl_change_percentage: 95000, atl_date: '2013-07-06', roi: null, last_updated: new Date().toISOString(), sparkline_in_7d: { price: [63000, 63500, 64000, 63800, 64500, 65000, 64231] } }, { id: 'ethereum', symbol: 'eth', name: 'Ethereum', image: 'https://assets.coingecko.com/coins/images/279/large/ethereum.png', current_price: 3450.20, market_cap: 415000000000, market_cap_rank: 2, fully_diluted_valuation: 415000000000, total_volume: 15000000000, high_24h: 3550, low_24h: 3350, price_change_24h: 50, price_change_percentage_24h: 1.45, market_cap_change_24h: 5000000000, market_cap_change_percentage_24h: 1.4, circulating_supply: 120000000, total_supply: 120000000, max_supply: null, ath: 4878, ath_change_percentage: -29, ath_date: '2021-11-10', atl: 0.42, atl_change_percentage: 820000, atl_date: '2015-10-20', roi: null, last_updated: new Date().toISOString(), sparkline_in_7d: { price: [3300, 3350, 3400, 3380, 3450, 3500, 3450] } }, { id: 'solana', symbol: 'sol', name: 'Solana', image: 'https://assets.coingecko.com/coins/images/4128/large/solana.png', current_price: 145.50, market_cap: 65000000000, market_cap_rank: 5, fully_diluted_valuation: 82000000000, total_volume: 4000000000, high_24h: 155, low_24h: 140, price_change_24h: -5, price_change_percentage_24h: -3.2, market_cap_change_24h: -2000000000, market_cap_change_percentage_24h: -3.1, circulating_supply: 445000000, total_supply: 570000000, max_supply: null, ath: 259, ath_change_percentage: -44, ath_date: '2021-11-06', atl: 0.50, atl_change_percentage: 29000, atl_date: '2020-05-11', roi: null, last_updated: new Date().toISOString(), sparkline_in_7d: { price: [150, 155, 152, 148, 145, 146, 145] } } ]; export const cryptoService = { ping: async () => { try { const res = await fetch(`${COINGECKO_BASE}/ping`, { mode: 'cors' }); return res.ok; } catch { return false; } }, getMarkets: async (vsCurrency: string = 'usd', perPage: number = 10, page: number = 1): Promise => { try { const res = await fetch( `${COINGECKO_BASE}/coins/markets?vs_currency=${vsCurrency}&order=market_cap_desc&per_page=${perPage}&page=${page}&sparkline=true&price_change_percentage=24h,7d`, { mode: 'cors' } ); if (!res.ok) throw new Error('Market data fetch failed'); return await res.json(); } catch (error) { console.warn("Crypto API unavailable, using simulated node data", error); return MOCK_MARKETS.slice(0, perPage); } }, getCoinById: async (id: string): Promise => { try { const res = await fetch(`${COINGECKO_BASE}/coins/${id}?localization=false&tickers=true&market_data=true&community_data=true&developer_data=true&sparkline=true`, { mode: 'cors' }); if (!res.ok) throw new Error('Coin details fetch failed'); return await res.json(); } catch (error) { console.warn(`Details for ${id} unavailable`, error); const mock = MOCK_MARKETS.find(m => m.id === id) as any; if (mock) { return { ...mock, description: { en: `Institutional-grade ledger summary for ${mock.name}. Handshake verified.` }, links: { homepage: ['#'], blockchain_site: ['#'], official_forum_url: [], chat_url: [], announcement_url: [], twitter_screen_name: '', facebook_username: '', bitcointalk_thread_identifier: null, telegram_channel_identifier: '', subreddit_url: '', repos_url: { github: [], bitbucket: [] } }, genesis_date: '2009-01-03', sentiment_votes_up_percentage: 85, sentiment_votes_down_percentage: 15 }; } return null; } }, getMarketChart: async (id: string, days: string = '7', vsCurrency: string = 'usd'): Promise => { try { const res = await fetch(`${COINGECKO_BASE}/coins/${id}/market_chart?vs_currency=${vsCurrency}&days=${days}`, { mode: 'cors' }); if (!res.ok) throw new Error('Market chart fetch failed'); return await res.json(); } catch (error) { console.warn(`Chart data for ${id} unavailable`, error); const mock = MOCK_MARKETS.find(m => m.id === id); if (mock) { const now = Date.now(); const prices: [number, number][] = mock.sparkline_in_7d!.price.map((p, i) => [now - (7 - i) * 86400000, p]); return { prices, market_caps: [], total_volumes: [] }; } return null; } }, getGlobal: async (): Promise => { try { const res = await fetch(`${COINGECKO_BASE}/global`, { mode: 'cors' }); if (!res.ok) throw new Error('Global data fetch failed'); const data = await res.json(); return data.data; } catch (error) { console.warn("Global market metrics unavailable", error); return { active_cryptocurrencies: 12400, upcoming_icos: 0, ongoing_icos: 42, ended_icos: 3401, markets: 900, total_market_cap: { usd: 2400000000000 }, total_volume: { usd: 85000000000 }, market_cap_percentage: { btc: 52.1, eth: 17.2 }, market_cap_change_percentage_24h_usd: 1.2, updated_at: Date.now() / 1000 }; } }, getTrending: async (): Promise => { try { const res = await fetch(`${COINGECKO_BASE}/search/trending`, { mode: 'cors' }); if (!res.ok) throw new Error('Trending fetch failed'); const data = await res.json(); return data.coins; } catch (error) { console.warn("Trending data unavailable", error); return MOCK_MARKETS.map((m, i) => ({ item: { id: m.id, coin_id: i, name: m.name, symbol: m.symbol, market_cap_rank: m.market_cap_rank, thumb: m.image, small: m.image, large: m.image, slug: m.id, price_btc: 1, score: i, data: { price: m.current_price, price_btc: '1', price_change_percentage_24h: { usd: m.price_change_percentage_24h }, market_cap: m.market_cap.toString(), total_volume: m.total_volume.toString(), sparkline: '' } } })); } }, search: async (query: string): Promise => { try { const res = await fetch(`${COINGECKO_BASE}/search?query=${query}`, { mode: 'cors' }); if (!res.ok) throw new Error('Search failed'); return await res.json(); } catch (error) { console.warn(`Search for ${query} unavailable`, error); return { coins: MOCK_MARKETS.filter(m => m.name.toLowerCase().includes(query.toLowerCase())).map(m => ({ id: m.id, name: m.name, api_symbol: m.symbol, symbol: m.symbol, market_cap_rank: m.market_cap_rank, thumb: m.image, large: m.image })), exchanges: [], nfts: [], categories: [] }; } } };