UNPKG

@cygnus-wealth/asset-valuator

Version:

Asset valuation library for retrieving and converting cryptocurrency prices

94 lines (93 loc) 3.36 kB
import { DecentralizedAggregator } from './providers/decentralized-aggregator.js'; import { TestPriceProvider } from './providers/test-price-provider.js'; export class AssetValuator { constructor(providerOrEnv, environment) { this.cache = new Map(); this.cacheTimeout = 60000; // 1 minute if (typeof providerOrEnv === 'string') { this.environment = providerOrEnv; this.provider = this.selectProvider(providerOrEnv); } else { this.environment = environment || 'production'; this.provider = providerOrEnv || this.selectProvider(this.environment); } } selectProvider(env) { switch (env) { case 'local': return new TestPriceProvider(); case 'production': case 'testnet': default: return new DecentralizedAggregator(); } } getCacheKey(base, quote) { return `${this.environment}:${base.toUpperCase()}_${quote.toUpperCase()}`; } async getCachedOrFetchPrice(symbol, currency) { const cacheKey = this.getCacheKey(symbol, currency); const cached = this.cache.get(cacheKey); if (cached && Date.now() - cached.timestamp < this.cacheTimeout) { return cached.price; } const priceData = await this.provider.fetchPrice(symbol, currency); this.cache.set(cacheKey, { price: priceData.price, timestamp: Date.now() }); return priceData.price; } async getPrice(base, quote = 'USD') { const price = await this.getCachedOrFetchPrice(base, quote); return { base: base.toUpperCase(), quote: quote.toUpperCase(), price, timestamp: new Date() }; } async convert(options) { const { from, to, amount = 1 } = options; if (from.toUpperCase() === to.toUpperCase()) { return amount; } if (to.toUpperCase() === 'USD') { const price = await this.getCachedOrFetchPrice(from, 'USD'); return price * amount; } if (from.toUpperCase() === 'USD') { const price = await this.getCachedOrFetchPrice(to, 'USD'); return amount / price; } // For crypto-to-crypto conversions, use USD as intermediate const fromPriceInUSD = await this.getCachedOrFetchPrice(from, 'USD'); const toPriceInUSD = await this.getCachedOrFetchPrice(to, 'USD'); return (fromPriceInUSD / toPriceInUSD) * amount; } async getPrices(symbols, quote = 'USD') { const prices = await this.provider.fetchMultiplePrices(symbols, quote); const timestamp = new Date(); // Update cache for (const priceData of prices) { const cacheKey = this.getCacheKey(priceData.symbol, quote); this.cache.set(cacheKey, { price: priceData.price, timestamp: Date.now() }); } return prices.map(p => ({ base: p.symbol, quote: quote.toUpperCase(), price: p.price, timestamp })); } setCacheTimeout(milliseconds) { this.cacheTimeout = milliseconds; } clearCache() { this.cache.clear(); } }