Expand ecash explorer capabilities
Add Fedimint discovery, dual SQLite/Postgres storage, richer review handling, and generated social imagery.
This commit is contained in:
+24
-8
@@ -12,22 +12,31 @@ export function createApp(): Hono {
|
||||
app.use('/api/*', cors());
|
||||
app.use('/icons/*', cors());
|
||||
|
||||
app.get('/api/health', (c) => {
|
||||
const health = getHealth();
|
||||
app.get('/api/health', async (c) => {
|
||||
const health = await getHealth();
|
||||
c.header('Cache-Control', 'no-store');
|
||||
return c.json(health, health.status === 'ok' ? 200 : 503);
|
||||
});
|
||||
|
||||
app.get('/api/stats', (c) => c.json(getStats()));
|
||||
app.get('/api/stats', async (c) => c.json(await getStats()));
|
||||
|
||||
app.get('/api/mints', (c) => {
|
||||
/*
|
||||
* The whole index, every ecosystem, each item carrying its `type`.
|
||||
*
|
||||
* `?type=cashu` / `?type=fedimint` narrows it, which is what the two list pages ask
|
||||
* for at build time. Unknown values are passed through rather than rejected: they
|
||||
* return an empty list, which is the honest answer to "show me the ecosystem this
|
||||
* build does not have".
|
||||
*/
|
||||
app.get('/api/mints', async (c) => {
|
||||
const raw = c.req.query('limit');
|
||||
const limit = raw ? Number.parseInt(raw, 10) : undefined;
|
||||
return c.json(listMints(Number.isFinite(limit) ? limit : undefined));
|
||||
const type = c.req.query('type')?.trim() || undefined;
|
||||
return c.json(await listMints(Number.isFinite(limit) ? limit : undefined, type));
|
||||
});
|
||||
|
||||
app.get('/api/mints/:host', (c) => {
|
||||
const detail = getMintDetail(c.req.param('host'));
|
||||
app.get('/api/mints/:host', async (c) => {
|
||||
const detail = await getMintDetail(c.req.param('host'));
|
||||
if (!detail) return c.json({ error: 'not_found', message: 'No mint with that host' }, 404);
|
||||
return c.json(detail);
|
||||
});
|
||||
@@ -38,7 +47,14 @@ export function createApp(): Hono {
|
||||
serveStatic({
|
||||
root: path.relative(process.cwd(), config.iconDir) || '.',
|
||||
rewriteRequestPath: (p) => p.replace(/^\/icons/, ''),
|
||||
onFound: (_p, c) => c.header('Cache-Control', 'public, max-age=86400'),
|
||||
onFound: (_p, c) => {
|
||||
c.header('Cache-Control', 'public, max-age=86400');
|
||||
// These files came from mint operators. nosniff pins the served type, and the
|
||||
// sandbox neutralizes anything script-capable (an SVG cached before icons.ts
|
||||
// stopped accepting them) when the file is opened directly on this origin.
|
||||
c.header('X-Content-Type-Options', 'nosniff');
|
||||
c.header('Content-Security-Policy', 'sandbox');
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user