revert: non-custodial — client supplies addresses+paths to POST /wallets/create

This commit is contained in:
ZOMBIIIIIII
2026-05-11 19:51:10 +03:00
parent 8d91dbeb14
commit c8bc40af97
20 changed files with 122 additions and 1475 deletions

View File

@@ -1,61 +0,0 @@
/**
* Audit log — append-only JSON lines в отдельный файл `logs/audit.log`.
* Используется для критических операций: mnemonic reveal, custodial sign.
*
* НИКОГДА не пишет sensitive данные (mnemonic / privkey / etc.) — только мета.
*/
import { promises as fs } from 'fs';
import path from 'path';
import { logger } from './logger';
import { getTraceId } from './trace-store';
const AUDIT_DIR = path.resolve(__dirname, '../../../../logs');
const AUDIT_FILE = path.join(AUDIT_DIR, 'audit.log');
let initialized = false;
async function ensureFile(): Promise<void> {
if (initialized) return;
try {
await fs.mkdir(AUDIT_DIR, { recursive: true });
// Создать с правами 0600 если файла нет
const handle = await fs.open(AUDIT_FILE, 'a', 0o600);
await handle.close();
try {
await fs.chmod(AUDIT_FILE, 0o600);
} catch {
// chmod может не работать на Windows — игнор
}
initialized = true;
} catch (err: any) {
logger.error(`Audit log init failed: ${err.message}`);
}
}
export interface AuditEntry {
event: string; // 'mnemonic.reveal', 'wallet.create', 'wallet.send', etc.
userId: string;
ip?: string | null;
meta?: Record<string, unknown>;
result?: 'success' | 'failure';
errorCode?: string;
}
export async function auditLog(entry: AuditEntry): Promise<void> {
await ensureFile();
const line = JSON.stringify({
timestamp: new Date().toISOString(),
trace_id: getTraceId(),
...entry,
});
try {
await fs.appendFile(AUDIT_FILE, line + '\n', { mode: 0o600 });
} catch (err: any) {
// Если audit-log не записался — логируем в обычный logger как ошибку,
// но НЕ блокируем основной флоу
logger.error(`Audit log write failed: ${err.message}`);
}
}