Skip to main content
Glama
Bichev
by Bichev
coinbase-client.js7.62 kB
import axios from 'axios'; import { CoinbaseAPIError, RateLimitError } from './types.js'; export class CoinbaseClient { client; baseUrl; requestCount = 0; requestWindow = Date.now(); maxRequestsPerMinute = 100; constructor(apiUrl = 'https://api.coinbase.com/v2') { this.baseUrl = apiUrl; this.client = axios.create({ baseURL: this.baseUrl, timeout: 10000, headers: { 'Accept': 'application/json', 'User-Agent': 'Coinbase-MCP-Server/1.0.0' } }); // Add request interceptor for rate limiting this.client.interceptors.request.use((config) => { this.checkRateLimit(); return config; }, (error) => Promise.reject(error)); // Add response interceptor for error handling this.client.interceptors.response.use((response) => response, (error) => { if (error.response) { throw new CoinbaseAPIError(error.response.data?.message || error.message, error.response.status, error.response.data); } throw error; }); } checkRateLimit() { const now = Date.now(); const oneMinute = 60 * 1000; // Reset counter if window has passed if (now - this.requestWindow > oneMinute) { this.requestCount = 0; this.requestWindow = now; } if (this.requestCount >= this.maxRequestsPerMinute) { throw new RateLimitError('Rate limit exceeded. Please wait before making more requests.', Math.ceil((oneMinute - (now - this.requestWindow)) / 1000)); } this.requestCount++; } /** * Get current spot price for a currency pair */ async getSpotPrice(currencyPair) { try { const response = await this.client.get(`/prices/${currencyPair}/spot`); return response.data; } catch (error) { throw this.handleError(error, 'Failed to fetch spot price'); } } /** * Get historical prices for a currency pair */ async getHistoricalPrices(currencyPair, start, end, period = 'day') { try { const params = { period }; if (start) params.start = start; if (end) params.end = end; const response = await this.client.get(`/prices/${currencyPair}/historic`, { params }); return response.data; } catch (error) { throw this.handleError(error, 'Failed to fetch historical prices'); } } /** * Get exchange rates for a currency */ async getExchangeRates(currency) { try { const response = await this.client.get(`/exchange-rates?currency=${currency}`); return response.data; } catch (error) { throw this.handleError(error, 'Failed to fetch exchange rates'); } } /** * List all currencies (both fiat and crypto) */ async getCurrencies() { try { const response = await this.client.get('/currencies'); return response.data; } catch (error) { throw this.handleError(error, 'Failed to fetch currencies'); } } /** * Get 24hr stats for a currency pair */ async getStats(currencyPair) { try { const response = await this.client.get(`/prices/${currencyPair}/stats`); return response.data; } catch (error) { throw this.handleError(error, 'Failed to fetch market stats'); } } /** * Get current server time */ async getTime() { try { const response = await this.client.get('/time'); return response.data; } catch (error) { throw this.handleError(error, 'Failed to fetch server time'); } } /** * Search for assets by name or symbol */ async searchAssets(query, limit = 10) { try { const currencies = await this.getCurrencies(); const searchTerm = query.toLowerCase(); return currencies.data .filter(asset => asset.name.toLowerCase().includes(searchTerm) || asset.code.toLowerCase().includes(searchTerm) || asset.id.toLowerCase().includes(searchTerm)) .slice(0, limit); } catch (error) { throw this.handleError(error, 'Failed to search assets'); } } /** * Get detailed information about a specific asset */ async getAssetDetails(assetId) { try { const currencies = await this.getCurrencies(); return currencies.data.find(asset => asset.id.toLowerCase() === assetId.toLowerCase() || asset.code.toLowerCase() === assetId.toLowerCase()) || null; } catch (error) { throw this.handleError(error, 'Failed to fetch asset details'); } } /** * Analyze price data for trends and patterns */ async analyzePriceData(currencyPair, _period, metrics = ['volatility', 'trend']) { try { // Get current price and stats const [spotPrice, stats] = await Promise.all([ this.getSpotPrice(currencyPair), this.getStats(currencyPair) ]); const currentPrice = parseFloat(spotPrice.data.amount); const open = parseFloat(stats.data.open); const high = parseFloat(stats.data.high); const low = parseFloat(stats.data.low); const volume = parseFloat(stats.data.volume); // Calculate basic metrics const priceChange24h = currentPrice - open; const priceChangePercent24h = ((currentPrice - open) / open) * 100; // Calculate volatility (simplified using high-low range) const volatility = ((high - low) / open) * 100; // Determine trend let trend = 'sideways'; if (priceChangePercent24h > 2) trend = 'bullish'; else if (priceChangePercent24h < -2) trend = 'bearish'; // Basic support and resistance levels const supportLevel = metrics.includes('support_resistance') ? low * 0.98 : undefined; const resistanceLevel = metrics.includes('support_resistance') ? high * 1.02 : undefined; return { currentPrice, volatility, trend, supportLevel, resistanceLevel, volume24h: metrics.includes('volume') ? volume : undefined, priceChange24h, priceChangePercent24h }; } catch (error) { throw this.handleError(error, 'Failed to analyze price data'); } } /** * Get popular trading pairs */ async getPopularPairs() { // Return commonly traded pairs with USD return [ 'BTC-USD', 'ETH-USD', 'LTC-USD', 'BCH-USD', 'ADA-USD', 'DOT-USD', 'UNI-USD', 'LINK-USD', 'XLM-USD', 'USDC-USD', 'AAVE-USD', 'SOL-USD', 'MATIC-USD', 'AVAX-USD', 'ALGO-USD' ]; } handleError(error, message) { if (error instanceof CoinbaseAPIError || error instanceof RateLimitError) { return error; } return new Error(`${message}: ${error.message}`); } } //# sourceMappingURL=coinbase-client.js.map

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Bichev/coinbase-chat-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server