forked from mito-systems/sol-mem-gen
Create class for quotes service
This commit is contained in:
parent
c1b0ad6ec5
commit
f712adfec2
37
cache.ts
37
cache.ts
@ -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<void> {
|
|
||||||
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];
|
|
||||||
}
|
|
43
quotes-service.ts
Normal file
43
quotes-service.ts
Normal file
@ -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<void> {
|
||||||
|
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 };
|
20
server.ts
20
server.ts
@ -4,32 +4,30 @@ import next from 'next';
|
|||||||
import dotenv from 'dotenv';
|
import dotenv from 'dotenv';
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
import { fetchAndCacheQuotes, getLatestQuote } from './cache';
|
import { QuotesService } from './quotes-service';
|
||||||
|
|
||||||
const port = parseInt(process.env.PORT || '3000', 10);
|
const port = parseInt(process.env.PORT || '3000', 10);
|
||||||
const app = next({ dev: process.env.NODE_ENV !== 'production' });
|
const app = next({ dev: process.env.NODE_ENV !== 'production' });
|
||||||
const handle = app.getRequestHandler();
|
const handle = app.getRequestHandler();
|
||||||
|
|
||||||
|
const quotesService = new QuotesService();
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
namespace NodeJS {
|
namespace NodeJS {
|
||||||
interface Global {
|
interface Global {
|
||||||
quoteService: {
|
quotesService: typeof quotesService
|
||||||
getLatestQuote: typeof getLatestQuote;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Look for a better way to use quoteService
|
// TODO: Look for a better way to use quotesService
|
||||||
// Initialize the global quote service
|
// Initialize the global quote service
|
||||||
(global as any).quoteService = {
|
(global as any).quotesService = quotesService
|
||||||
getLatestQuote
|
|
||||||
};
|
|
||||||
|
|
||||||
app.prepare().then(() => {
|
app.prepare().then(() => {
|
||||||
const server = createServer(async (req, res) => {
|
const server = createServer(async (req, res) => {
|
||||||
const parsedUrl = parse(req.url!, true);
|
const parsedUrl = parse(req.url!, true);
|
||||||
(req as any).getLatestQuote = getLatestQuote;
|
(req as any).quotesService = quotesService;
|
||||||
|
|
||||||
// Default Next.js request handling
|
// Default Next.js request handling
|
||||||
handle(req, res, parsedUrl);
|
handle(req, res, parsedUrl);
|
||||||
@ -40,6 +38,6 @@ app.prepare().then(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Initial call and interval setup
|
// Initial call and interval setup
|
||||||
fetchAndCacheQuotes(); // Initial store
|
quotesService.fetchAndCacheQuotes(); // Initial store
|
||||||
setInterval(fetchAndCacheQuotes, 5 * 60 * 1000); // Update cache every 5 minutes
|
setInterval(() => quotesService.fetchAndCacheQuotes(), 5 * 60 * 1000); // Update cache every 5 minutes
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user