diff --git a/cache.ts b/cache.ts deleted file mode 100644 index aa2eb8e..0000000 --- a/cache.ts +++ /dev/null @@ -1,37 +0,0 @@ -import assert from "assert"; -import BN from "bn.js"; -import fetch from 'node-fetch'; - -let cachedQuotes: BN[] = []; - -assert(process.env.NEXT_PUBLIC_USDC_MINT, 'USDC_MINT is required'); -assert(process.env.NEXT_PUBLIC_MTM_TOKEN_MINT, 'MTM_TOKEN_MINT is required'); - -const MTM_TOKEN_MINT = process.env.NEXT_PUBLIC_MTM_TOKEN_MINT; -const USDC_MINT = process.env.NEXT_PUBLIC_USDC_MINT; - -export async function fetchAndCacheQuotes(): Promise { - try { - const url = `https://api.jup.ag/price/v2?ids=${USDC_MINT}&vsToken=${MTM_TOKEN_MINT}`; - const response = await fetch(url); - - if (!response.ok) { - throw new Error(`Failed to fetch quote: ${response.statusText}`); - } - - const quoteResponse = await response.json(); - const priceFromAPI = Number(quoteResponse['data'][USDC_MINT]['price']).toFixed(6); - const price = new BN(priceFromAPI.toString().replace('.', '')); - - cachedQuotes.push(price); - if (cachedQuotes.length > 3) { - cachedQuotes.shift(); - } - } catch (error) { - console.error('Error fetching quotes:', error); - } -} - -export function getLatestQuote(): BN | undefined { - return cachedQuotes[cachedQuotes.length - 1]; -} diff --git a/quotes-service.ts b/quotes-service.ts new file mode 100644 index 0000000..1904eca --- /dev/null +++ b/quotes-service.ts @@ -0,0 +1,43 @@ +import assert from "assert"; +import BN from "bn.js"; +import fetch from 'node-fetch'; + +assert(process.env.NEXT_PUBLIC_USDC_MINT, 'USDC_MINT is required'); +assert(process.env.NEXT_PUBLIC_MTM_TOKEN_MINT, 'MTM_TOKEN_MINT is required'); + +const MTM_TOKEN_MINT = process.env.NEXT_PUBLIC_MTM_TOKEN_MINT; +const USDC_MINT = process.env.NEXT_PUBLIC_USDC_MINT; + +class QuotesService { + private cachedQuotes: BN[] = []; + + async fetchAndCacheQuotes(): Promise { + try { + const url = `https://api.jup.ag/price/v2?ids=${USDC_MINT}&vsToken=${MTM_TOKEN_MINT}`; + const response = await fetch(url); + + if (!response.ok) { + throw new Error(`Failed to fetch quote: ${response.statusText}`); + } + + const quoteResponse = await response.json(); + const priceFromAPI = Number(quoteResponse['data'][USDC_MINT]['price']).toFixed(6); + const price = new BN(priceFromAPI.toString().replace('.', '')); + + this.cachedQuotes.push(price); + if (this.cachedQuotes.length > 3) { + this.cachedQuotes.shift(); + } + console.log('Cache updated: ', this.cachedQuotes); + } catch (error) { + console.error('Error fetching quotes:', error); + } + } + + getLatestQuote(): BN | undefined { + console.log({ cachedQuotes: this.cachedQuotes }); + return this.cachedQuotes[this.cachedQuotes.length - 1]; + } +} + +export { QuotesService }; diff --git a/server.ts b/server.ts index 16d841e..4d6c2a0 100644 --- a/server.ts +++ b/server.ts @@ -4,32 +4,30 @@ import next from 'next'; import dotenv from 'dotenv'; dotenv.config(); -import { fetchAndCacheQuotes, getLatestQuote } from './cache'; +import { QuotesService } from './quotes-service'; const port = parseInt(process.env.PORT || '3000', 10); const app = next({ dev: process.env.NODE_ENV !== 'production' }); const handle = app.getRequestHandler(); +const quotesService = new QuotesService(); + declare global { namespace NodeJS { interface Global { - quoteService: { - getLatestQuote: typeof getLatestQuote; - } - } + quotesService: typeof quotesService } } +} -// TODO: Look for a better way to use quoteService +// TODO: Look for a better way to use quotesService // Initialize the global quote service -(global as any).quoteService = { - getLatestQuote -}; +(global as any).quotesService = quotesService app.prepare().then(() => { const server = createServer(async (req, res) => { const parsedUrl = parse(req.url!, true); - (req as any).getLatestQuote = getLatestQuote; + (req as any).quotesService = quotesService; // Default Next.js request handling handle(req, res, parsedUrl); @@ -40,6 +38,6 @@ app.prepare().then(() => { }); // Initial call and interval setup - fetchAndCacheQuotes(); // Initial store - setInterval(fetchAndCacheQuotes, 5 * 60 * 1000); // Update cache every 5 minutes + quotesService.fetchAndCacheQuotes(); // Initial store + setInterval(() => quotesService.fetchAndCacheQuotes(), 5 * 60 * 1000); // Update cache every 5 minutes });