**Motivations:** - Corriger erreurs de syntaxe dans api-anchorage (bloc else non fermé, variable dupliquée) - Refactorer api-relay pour extraire setupRoutes et améliorer la structure **Root causes:** - api-anchorage: bloc else non fermé après verrouillage UTXO, variable totalInputAmount déclarée deux fois - api-relay: code dupliqué dans main(), besoin de meilleure séparation des responsabilités **Correctifs:** - api-anchorage: fermeture bloc else ligne 392, renommage totalInputAmount en totalInputAmountForFee dans calcul frais, utilisation totalSelectedAmount pour plusieurs UTXOs **Evolutions:** - api-relay: extraction setupRoutes() depuis main(), refactoring routes (keys, messages, signatures), middleware auth, index.ts restructuré **Pages affectées:** - api-anchorage: bitcoin-rpc.js - api-relay: index.ts, middleware/auth.ts, routes (keys, messages, signatures), services/storage.ts - data: sync-utxos.log
103 lines
2.9 KiB
TypeScript
103 lines
2.9 KiB
TypeScript
import { Router, type Request, type Response } from 'express';
|
|
import type { StorageServiceInterface } from '../services/storageInterface.js';
|
|
import type { RelayService } from '../services/relay.js';
|
|
import type { MsgChiffre, StoredMessage } from '../types/message.js';
|
|
import { validateMsgChiffre } from '../lib/validate.js';
|
|
import { logger } from '../lib/logger.js';
|
|
|
|
function handleGetMessages(
|
|
storage: StorageServiceInterface,
|
|
req: Request,
|
|
res: Response,
|
|
): void {
|
|
try {
|
|
const start = parseInt(req.query.start as string, 10);
|
|
const end = parseInt(req.query.end as string, 10);
|
|
const service = req.query.service as string | undefined;
|
|
|
|
if (isNaN(start) || isNaN(end)) {
|
|
res.status(400).json({ error: 'start and end timestamps required' });
|
|
return;
|
|
}
|
|
|
|
const messages = storage.getMessages(start, end, service);
|
|
const msgChiffres: MsgChiffre[] = messages.map((m) => m.msg);
|
|
res.json(msgChiffres);
|
|
} catch (error) {
|
|
logger.error({ err: error }, 'Error getting messages');
|
|
res.status(500).json({ error: 'Internal server error' });
|
|
}
|
|
}
|
|
|
|
function handlePostMessage(
|
|
storage: StorageServiceInterface,
|
|
relay: RelayService,
|
|
req: Request,
|
|
res: Response,
|
|
): void {
|
|
void (async (): Promise<void> => {
|
|
try {
|
|
if (!validateMsgChiffre(req.body)) {
|
|
res.status(400).json({ error: 'Invalid message format' });
|
|
return;
|
|
}
|
|
const msg = req.body as MsgChiffre;
|
|
|
|
const alreadySeen = storage.hasSeenHash(msg.hash);
|
|
const stored: StoredMessage = {
|
|
msg,
|
|
received_at: Date.now(),
|
|
relayed: false,
|
|
};
|
|
|
|
storage.storeMessage(stored);
|
|
|
|
if (!alreadySeen) {
|
|
await relay.relayMessage(msg);
|
|
stored.relayed = true;
|
|
}
|
|
|
|
res.status(201).json({ hash: msg.hash, stored: true });
|
|
} catch (error) {
|
|
logger.error({ err: error }, 'Error storing message');
|
|
res.status(500).json({ error: 'Internal server error' });
|
|
}
|
|
})();
|
|
}
|
|
|
|
function handleGetMessageByHash(
|
|
storage: StorageServiceInterface,
|
|
req: Request,
|
|
res: Response,
|
|
): void {
|
|
try {
|
|
const hash = req.params.hash as string;
|
|
if (hash.length === 0) {
|
|
res.status(400).json({ error: 'Hash parameter required' });
|
|
return;
|
|
}
|
|
const stored = storage.getMessage(hash);
|
|
if (stored === undefined) {
|
|
res.status(404).json({ error: 'Message not found' });
|
|
return;
|
|
}
|
|
res.json(stored.msg);
|
|
} catch (error) {
|
|
logger.error({ err: error }, 'Error getting message by hash');
|
|
res.status(500).json({ error: 'Internal server error' });
|
|
}
|
|
}
|
|
|
|
export function createMessagesRouter(
|
|
storage: StorageServiceInterface,
|
|
relay: RelayService,
|
|
): Router {
|
|
const router = Router();
|
|
|
|
router.get('/', (req, res) => handleGetMessages(storage, req, res));
|
|
router.post('/', (req, res) => handlePostMessage(storage, relay, req, res));
|
|
router.get('/:hash', (req, res) => handleGetMessageByHash(storage, req, res));
|
|
|
|
return router;
|
|
}
|