deviant/scripts/registry-serve.mjs
walerikus 518a3ce174 chore: initial project baseline — full Deviant codebase under version control
Brings the whole project into git (previously only the on-ramp feature and
a few parallel files were tracked). Includes: wallet core (src/), CashScript
contracts/, the Capacitor shell (shells/), scripts/, tests, and the docs
corpus (wiki/, snapshots/, Parameters/, Archive/, KnowledgeBase text).

Excluded via .gitignore: node_modules/, dist/, .env (secrets), testnet WIF
key files (.chipnet-*.json, devWallets.ts), KnowledgeBase/RAW media (~9.6 GB),
transcripts/ (session logs), and machine-local config (.claude/*.local,
*.lock). Secret-scanned before commit — no credentials in the tree.

Note: src/swapMath.ts, src/swapBuilder.ts, contracts/OpenMintToken.cash are
legacy (OP_RETURN era) but still imported; committed as-is, flagged for a
separate removal once de-referenced.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 20:38:07 +02:00

74 lines
2.6 KiB
JavaScript

#!/usr/bin/env node
/**
* registry-serve.mjs — run a local Deviant registry server backed by a
* JSON file on disk.
*
* Env vars:
* REGISTRY_FILE Path to the tokens JSON. Default: ./.registry-tokens.json
* PORT HTTP port. Default: 3000
* HOST Bind address. Default: 127.0.0.1
* REGISTRY_NAME Display name in the feed. Default: 'Deviant Local Registry'
*
* The tokens file is a JSON array of portable token objects, e.g.:
* [
* { "version": 1, "id": "...", "tier": "B", "name": "Y", ... },
* ...
* ]
*
* The server re-reads the file on every request, so editing the file
* (or replacing it from a CI job) takes effect immediately.
*/
import { readFileSync, existsSync } from 'node:fs';
import { join } from 'node:path';
import { createRegistryServer } from '../src/registry/server.ts';
import { parseRegistryFeed } from '../src/token/portable.ts';
const ROOT = join(import.meta.dirname, '..');
const REGISTRY_FILE = process.env.REGISTRY_FILE ?? join(ROOT, '.registry-tokens.json');
const PORT = parseInt(process.env.PORT ?? '3000', 10);
const HOST = process.env.HOST ?? '127.0.0.1';
const REGISTRY_NAME = process.env.REGISTRY_NAME ?? 'Deviant Local Registry';
function loadTokens() {
if (!existsSync(REGISTRY_FILE)) {
console.warn(`(no tokens file at ${REGISTRY_FILE} — serving empty list)`);
return [];
}
try {
const raw = JSON.parse(readFileSync(REGISTRY_FILE, 'utf8'));
// Accept either a bare array of portable tokens, or a complete feed.
const feed = Array.isArray(raw)
? { version: 1, registry: REGISTRY_NAME, updatedAt: Date.now(), tokens: raw }
: raw;
const parsed = parseRegistryFeed(feed);
if (parsed.errors.length > 0) {
console.warn(`(${parsed.errors.length} entries had parse errors)`);
for (const e of parsed.errors) console.warn(` index ${e.index}: ${e.reason}`);
}
return parsed.tokens;
} catch (err) {
console.error(`Failed to load ${REGISTRY_FILE}: ${err.message}`);
return [];
}
}
const server = createRegistryServer({
tokens: () => loadTokens(),
registryName: REGISTRY_NAME,
});
server.start(PORT, HOST).then((port) => {
console.log(`Deviant registry serving at http://${HOST}:${port}`);
console.log(` GET /tokens — token feed`);
console.log(` GET /health — health check`);
console.log(` Source file: ${REGISTRY_FILE}`);
}).catch((err) => {
console.error(`Failed to start: ${err.message}`);
process.exit(1);
});
process.on('SIGINT', async () => {
console.log('\nShutting down…');
await server.stop();
process.exit(0);
});