Initial commit
Some checks failed
CI / test (push) Has been cancelled
CI / security (push) Has been cancelled
CI / build (push) Has been cancelled

This commit is contained in:
defiQUG
2025-12-12 15:02:56 -08:00
commit 849e6a8357
891 changed files with 167728 additions and 0 deletions

View File

@@ -0,0 +1,53 @@
// FX Trading Flow End-to-End Tests
import request from 'supertest';
import app from '@/integration/api-gateway/app';
import { createTestSovereignBank, cleanDatabase } from '@/__tests__/utils/test-db';
import { testPrisma } from '@/__tests__/utils/test-db';
import { createAuthHeaders } from '@/__tests__/utils/test-auth';
describe('FX Trading Flow E2E', () => {
beforeEach(async () => {
await cleanDatabase();
});
afterAll(async () => {
await testPrisma.$disconnect();
});
it('should complete full FX trading workflow', async () => {
const bank = await createTestSovereignBank();
// Step 1: Submit FX order
const orderResponse = await request(app)
.post('/api/fx/orders')
.set(createAuthHeaders({ sovereignBankId: bank.id }))
.send({
pair: 'USD/EUR',
amount: '1000.00',
orderType: 'market',
settlement: 'RTGS',
});
expect([200, 201]).toContain(orderResponse.status);
const tradeId = orderResponse.body.data?.tradeId;
if (tradeId) {
// Step 2: Execute trade
const executeResponse = await request(app)
.post(`/api/fx/trades/${tradeId}/execute`)
.set(createAuthHeaders({ sovereignBankId: bank.id }));
expect([200, 201]).toContain(executeResponse.status);
// Step 3: Check trade status
const statusResponse = await request(app)
.get(`/api/fx/trades/${tradeId}`)
.set(createAuthHeaders({ sovereignBankId: bank.id }));
expect(statusResponse.status).toBe(200);
expect(['executed', 'settled']).toContain(statusResponse.body.data?.status);
}
});
});

View File

@@ -0,0 +1,57 @@
// Payment Flow End-to-End Tests
import request from 'supertest';
import app from '@/integration/api-gateway/app';
import { createTestSovereignBank, createTestBankAccount, cleanDatabase } from '@/__tests__/utils/test-db';
import { testPrisma } from '@/__tests__/utils/test-db';
import { createAuthHeaders } from '@/__tests__/utils/test-auth';
describe('Payment Flow E2E', () => {
beforeEach(async () => {
await cleanDatabase();
});
afterAll(async () => {
await testPrisma.$disconnect();
});
it('should complete a full payment flow', async () => {
const bank = await createTestSovereignBank();
const sourceAccount = await createTestBankAccount({
sovereignBankId: bank.id,
balance: '1000.00',
});
const destAccount = await createTestBankAccount({
sovereignBankId: bank.id,
balance: '500.00',
});
// Note: This test assumes payment routes are implemented
// Adjust based on actual API structure
const response = await request(app)
.post('/api/payments')
.set(createAuthHeaders({ sovereignBankId: bank.id }))
.send({
sourceAccountId: sourceAccount.id,
destinationAccountId: destAccount.id,
amount: '100.00',
currencyCode: 'USD',
paymentType: 'transfer',
});
// Verify response
expect([200, 201]).toContain(response.status);
// Verify balances updated
const updatedSource = await testPrisma.bankAccount.findUnique({
where: { id: sourceAccount.id },
});
const updatedDest = await testPrisma.bankAccount.findUnique({
where: { id: destAccount.id },
});
expect(updatedSource?.balance.toString()).toBe('900.00');
expect(updatedDest?.balance.toString()).toBe('600.00');
});
});

View File

@@ -0,0 +1,69 @@
// Settlement Workflow End-to-End Tests
import request from 'supertest';
import app from '@/integration/api-gateway/app';
import { createTestSovereignBank, createTestBankAccount, cleanDatabase } from '@/__tests__/utils/test-db';
import { testPrisma } from '@/__tests__/utils/test-db';
import { createAuthHeaders } from '@/__tests__/utils/test-auth';
describe('Settlement Workflow E2E', () => {
beforeEach(async () => {
await cleanDatabase();
});
afterAll(async () => {
await testPrisma.$disconnect();
});
it('should complete full settlement workflow', async () => {
const bank1 = await createTestSovereignBank({ sovereignCode: 'BANK1' });
const bank2 = await createTestSovereignBank({ sovereignCode: 'BANK2' });
const account1 = await createTestBankAccount({
sovereignBankId: bank1.id,
balance: '1000.00',
});
const account2 = await createTestBankAccount({
sovereignBankId: bank2.id,
balance: '500.00',
});
// Step 1: Initiate payment
const paymentResponse = await request(app)
.post('/api/payments')
.set(createAuthHeaders({ sovereignBankId: bank1.id }))
.send({
debtorAccount: account1.accountNumber,
creditorAccount: account2.accountNumber,
amount: '100.00',
currency: 'USD',
priority: 'NORMAL',
assetType: 'fiat',
});
expect([200, 201]).toContain(paymentResponse.status);
const paymentId = paymentResponse.body.data?.paymentId;
if (paymentId) {
// Step 2: Check payment status
const statusResponse = await request(app)
.get(`/api/payments/${paymentId}`)
.set(createAuthHeaders({ sovereignBankId: bank1.id }));
expect(statusResponse.status).toBe(200);
expect(statusResponse.body.data.status).toBe('settled');
}
// Step 3: Verify balances
const updatedAccount1 = await testPrisma.bankAccount.findUnique({
where: { id: account1.id },
});
const updatedAccount2 = await testPrisma.bankAccount.findUnique({
where: { id: account2.id },
});
expect(updatedAccount1?.balance.toString()).toBe('900.00');
expect(updatedAccount2?.balance.toString()).toBe('600.00');
});
});

View File

@@ -0,0 +1,46 @@
// Authentication Middleware Integration Tests
import request from 'supertest';
import app from '@/integration/api-gateway/app';
import { createAuthHeaders, createTestToken } from '@/__tests__/utils/test-auth';
describe('Authentication Middleware', () => {
describe('zeroTrustAuthMiddleware', () => {
it('should reject requests without token', async () => {
const response = await request(app).get('/api/health').expect(401);
expect(response.body.success).toBe(false);
expect(response.body.error.code).toBe('UNAUTHORIZED');
});
it('should reject requests with invalid token', async () => {
const response = await request(app)
.get('/api/health')
.set('authorization', 'SOV-TOKEN invalid-token')
.expect(401);
expect(response.body.success).toBe(false);
});
it('should accept requests with valid token', async () => {
// Note: This test may need adjustment based on actual route implementation
// Health endpoint should not require auth
const response = await request(app).get('/health').expect(200);
expect(response.body.status).toBe('healthy');
});
});
describe('Request Signature Verification', () => {
it('should require signature headers', async () => {
const token = createTestToken({ sovereignBankId: 'test-bank' });
const response = await request(app)
.get('/api/health')
.set('authorization', `SOV-TOKEN ${token}`)
.expect(401);
expect(response.body.error.message).toContain('signature');
});
});
});

View File

@@ -0,0 +1,47 @@
// Accounts API Integration Tests
import request from 'supertest';
import app from '@/integration/api-gateway/app';
import { createTestSovereignBank, cleanDatabase } from '@/__tests__/utils/test-db';
import { testPrisma } from '@/__tests__/utils/test-db';
import { createAuthHeaders } from '@/__tests__/utils/test-auth';
describe('Accounts API Integration', () => {
beforeEach(async () => {
await cleanDatabase();
});
afterAll(async () => {
await testPrisma.$disconnect();
});
describe('POST /api/accounts', () => {
it('should create a new account', async () => {
const bank = await createTestSovereignBank();
const response = await request(app)
.post('/api/accounts')
.set(createAuthHeaders({ sovereignBankId: bank.id }))
.send({
accountType: 'commercial',
currencyCode: 'USD',
assetType: 'fiat',
});
expect([200, 201]).toContain(response.status);
});
});
describe('GET /api/accounts/:id', () => {
it('should retrieve account details', async () => {
const bank = await createTestSovereignBank();
const response = await request(app)
.get('/api/accounts/test-id')
.set(createAuthHeaders({ sovereignBankId: bank.id }));
expect([200, 404]).toContain(response.status);
});
});
});

View File

@@ -0,0 +1,48 @@
// FX API Integration Tests
import request from 'supertest';
import app from '@/integration/api-gateway/app';
import { createTestSovereignBank, cleanDatabase } from '@/__tests__/utils/test-db';
import { testPrisma } from '@/__tests__/utils/test-db';
import { createAuthHeaders } from '@/__tests__/utils/test-auth';
describe('FX API Integration', () => {
beforeEach(async () => {
await cleanDatabase();
});
afterAll(async () => {
await testPrisma.$disconnect();
});
describe('POST /api/fx/orders', () => {
it('should submit an FX order', async () => {
const bank = await createTestSovereignBank();
const response = await request(app)
.post('/api/fx/orders')
.set(createAuthHeaders({ sovereignBankId: bank.id }))
.send({
pair: 'USD/EUR',
amount: '1000.00',
orderType: 'market',
settlement: 'RTGS',
});
expect([200, 201]).toContain(response.status);
});
});
describe('GET /api/fx/trades/:id', () => {
it('should retrieve FX trade details', async () => {
const bank = await createTestSovereignBank();
const response = await request(app)
.get('/api/fx/trades/test-id')
.set(createAuthHeaders({ sovereignBankId: bank.id }));
expect([200, 404]).toContain(response.status);
});
});
});

View File

@@ -0,0 +1,62 @@
// Ledger API Integration Tests
import request from 'supertest';
import app from '@/integration/api-gateway/app';
import { createTestSovereignBank, createTestBankAccount, cleanDatabase } from '@/__tests__/utils/test-db';
import { testPrisma } from '@/__tests__/utils/test-db';
import { createAuthHeaders } from '@/__tests__/utils/test-auth';
describe('Ledger API Integration', () => {
beforeEach(async () => {
await cleanDatabase();
});
afterAll(async () => {
await testPrisma.$disconnect();
});
describe('POST /api/ledger/entries', () => {
it('should create a ledger entry', async () => {
const bank = await createTestSovereignBank();
const debitAccount = await createTestBankAccount({
sovereignBankId: bank.id,
balance: '1000.00',
});
const creditAccount = await createTestBankAccount({
sovereignBankId: bank.id,
});
const response = await request(app)
.post('/api/ledger/entries')
.set(createAuthHeaders({ sovereignBankId: bank.id }))
.send({
ledgerId: 'MASTER',
debitAccountId: debitAccount.id,
creditAccountId: creditAccount.id,
amount: '100.00',
currencyCode: 'USD',
assetType: 'fiat',
transactionType: 'TYPE_A',
referenceId: 'TEST-REF-001',
});
expect([200, 201]).toContain(response.status);
expect(response.body.success).toBe(true);
});
});
describe('GET /api/ledger/entries/:id', () => {
it('should retrieve a ledger entry', async () => {
const bank = await createTestSovereignBank();
// Note: This test assumes the route exists
// Adjust based on actual API structure
const response = await request(app)
.get('/api/ledger/entries/test-id')
.set(createAuthHeaders({ sovereignBankId: bank.id }));
expect([200, 404]).toContain(response.status);
});
});
});

22
src/__tests__/setup.ts Normal file
View File

@@ -0,0 +1,22 @@
// Jest test setup
// Runs before all tests
import prisma from '@/shared/database/prisma';
// Set test environment
process.env.NODE_ENV = 'test';
process.env.DATABASE_URL = process.env.TEST_DATABASE_URL || 'postgresql://test:test@localhost:5432/dbis_test';
process.env.JWT_SECRET = 'test-jwt-secret-minimum-32-characters-long-for-testing';
process.env.ALLOWED_ORIGINS = 'http://localhost:3000';
process.env.LOG_LEVEL = 'error'; // Reduce log noise in tests
// Global test timeout
jest.setTimeout(10000);
// Cleanup after all tests
afterAll(async () => {
// Close any open connections
const prisma = new PrismaClient();
await prisma.$disconnect();
});

View File

@@ -0,0 +1,35 @@
// AML Compliance Unit Tests
import { createTestSovereignBank, cleanDatabase } from '@/__tests__/utils/test-db';
import { testPrisma } from '@/__tests__/utils/test-db';
describe('AML Compliance', () => {
beforeEach(async () => {
await cleanDatabase();
});
afterAll(async () => {
await testPrisma.$disconnect();
});
describe('Sanctions Screening', () => {
it('should screen transactions against sanctions list', async () => {
// This would test the actual AML service when implemented
// For now, this is a placeholder test structure
expect(true).toBe(true);
});
it('should flag high-risk transactions', async () => {
// Placeholder for AML risk scoring tests
expect(true).toBe(true);
});
});
describe('PEP Detection', () => {
it('should detect politically exposed persons', async () => {
// Placeholder for PEP detection tests
expect(true).toBe(true);
});
});
});

View File

@@ -0,0 +1,116 @@
// Complete Compliance Test Suite
import { createTestSovereignBank, cleanDatabase } from '@/__tests__/utils/test-db';
import { testPrisma } from '@/__tests__/utils/test-db';
import { amlService } from '@/core/compliance/aml.service';
import { ComplianceRecordType } from '@/shared/types';
describe('Compliance - Complete Test Suite', () => {
beforeEach(async () => {
await cleanDatabase();
});
afterAll(async () => {
await testPrisma.$disconnect();
});
describe('AML Screening', () => {
it('should screen transactions for AML violations', async () => {
const bank = await createTestSovereignBank();
const result = await amlService.screenTransaction({
transactionId: 'TEST-TX-001',
sourceAccountId: 'test-account-1',
destinationAccountId: 'test-account-2',
amount: '10000.00',
currencyCode: 'USD',
transactionType: 'transfer',
});
expect(result).toBeDefined();
expect(result.riskScore).toBeGreaterThanOrEqual(0);
expect(result.riskScore).toBeLessThanOrEqual(100);
});
it('should flag high-risk transactions', async () => {
const bank = await createTestSovereignBank();
// Large amount that should trigger AML
const result = await amlService.screenTransaction({
transactionId: 'TEST-TX-002',
sourceAccountId: 'test-account-1',
destinationAccountId: 'test-account-2',
amount: '1000000.00',
currencyCode: 'USD',
transactionType: 'transfer',
});
expect(result.riskScore).toBeGreaterThan(50);
});
});
describe('Sanctions Checking', () => {
it('should check entities against sanctions list', async () => {
const bank = await createTestSovereignBank();
const result = await amlService.checkSanctions({
entityId: 'test-entity',
entityType: 'account',
});
expect(result).toBeDefined();
expect(result.isSanctioned).toBeDefined();
});
});
describe('PEP Detection', () => {
it('should detect politically exposed persons', async () => {
const bank = await createTestSovereignBank();
const result = await amlService.checkPEP({
entityId: 'test-entity',
entityType: 'account',
});
expect(result).toBeDefined();
expect(result.isPEP).toBeDefined();
});
});
describe('Risk Scoring', () => {
it('should calculate comprehensive risk score', async () => {
const bank = await createTestSovereignBank();
const riskScore = await amlService.calculateRiskScore({
transactionId: 'TEST-TX-003',
sourceAccountId: 'test-account-1',
destinationAccountId: 'test-account-2',
amount: '50000.00',
currencyCode: 'USD',
});
expect(riskScore).toBeGreaterThanOrEqual(0);
expect(riskScore).toBeLessThanOrEqual(100);
});
});
describe('Compliance Record Creation', () => {
it('should create compliance record for flagged transactions', async () => {
const bank = await createTestSovereignBank();
const record = await amlService.createComplianceRecord({
entityId: 'test-entity',
entityType: 'transaction',
recordType: ComplianceRecordType.AML_ALERT,
riskScore: 75,
details: {
reason: 'High-value transaction',
},
});
expect(record.id).toBeDefined();
expect(record.status).toBeDefined();
});
});
});

View File

@@ -0,0 +1,124 @@
// FX Service Edge Cases Unit Tests
import { fxService } from '@/core/fx/fx.service';
import { createTestSovereignBank, cleanDatabase } from '@/__tests__/utils/test-db';
import { testPrisma } from '@/__tests__/utils/test-db';
import { FxOrderType, FxTradeType } from '@/shared/types';
describe('FxService - Edge Cases', () => {
beforeEach(async () => {
await cleanDatabase();
});
afterAll(async () => {
await testPrisma.$disconnect();
});
describe('Market Volatility', () => {
it('should handle rapid price changes', async () => {
const bank = await createTestSovereignBank();
const order1 = await fxService.submitOrder(bank.id, {
pair: 'USD/EUR',
amount: '1000.00',
orderType: FxOrderType.MARKET,
settlement: 'RTGS',
});
// Simulate rapid price change scenario
const order2 = await fxService.submitOrder(bank.id, {
pair: 'USD/EUR',
amount: '1000.00',
orderType: FxOrderType.MARKET,
settlement: 'RTGS',
});
expect(order1.tradeId).toBeDefined();
expect(order2.tradeId).toBeDefined();
});
});
describe('Order Matching', () => {
it('should match limit orders at correct price', async () => {
const bank = await createTestSovereignBank();
const order = await fxService.submitOrder(bank.id, {
pair: 'USD/EUR',
amount: '1000.00',
orderType: FxOrderType.LIMIT,
limitPrice: '0.85',
settlement: 'RTGS',
});
expect(order.tradeId).toBeDefined();
expect(order.status).toBe('pending');
});
it('should not match limit orders below market price', async () => {
const bank = await createTestSovereignBank();
// This test would need market price mocking
const order = await fxService.submitOrder(bank.id, {
pair: 'USD/EUR',
amount: '1000.00',
orderType: FxOrderType.LIMIT,
limitPrice: '0.50', // Unrealistically low
settlement: 'RTGS',
});
expect(order.status).toBe('pending');
});
});
describe('Settlement Failures', () => {
it('should handle settlement failure gracefully', async () => {
const bank = await createTestSovereignBank();
const order = await fxService.submitOrder(bank.id, {
pair: 'USD/EUR',
amount: '1000.00',
orderType: FxOrderType.MARKET,
settlement: 'RTGS',
});
// Attempt to execute
try {
await fxService.executeTrade(order.tradeId);
} catch (error) {
// Settlement failure should be handled
expect(error).toBeDefined();
}
});
});
describe('Invalid Currency Pairs', () => {
it('should reject invalid currency pair format', async () => {
const bank = await createTestSovereignBank();
await expect(
fxService.submitOrder(bank.id, {
pair: 'INVALID',
amount: '1000.00',
orderType: FxOrderType.MARKET,
settlement: 'RTGS',
})
).rejects.toThrow();
});
});
describe('Large Order Amounts', () => {
it('should handle very large FX orders', async () => {
const bank = await createTestSovereignBank();
const order = await fxService.submitOrder(bank.id, {
pair: 'USD/EUR',
amount: '999999999.99',
orderType: FxOrderType.MARKET,
settlement: 'RTGS',
});
expect(order.tradeId).toBeDefined();
});
});
});

View File

@@ -0,0 +1,82 @@
// FX Service Unit Tests
import { fxService } from '@/core/fx/fx.service';
import { createTestSovereignBank, cleanDatabase } from '@/__tests__/utils/test-db';
import { testPrisma } from '@/__tests__/utils/test-db';
import { FxOrderType, FxTradeType } from '@/shared/types';
describe('FxService', () => {
beforeEach(async () => {
await cleanDatabase();
});
afterAll(async () => {
await testPrisma.$disconnect();
});
describe('submitOrder', () => {
it('should submit a market order', async () => {
const bank = await createTestSovereignBank();
const result = await fxService.submitOrder(bank.id, {
pair: 'USD/EUR',
amount: '1000.00',
orderType: FxOrderType.MARKET,
settlement: 'RTGS',
});
expect(result.tradeId).toBeDefined();
expect(result.status).toBe('pending');
});
it('should submit a limit order with price', async () => {
const bank = await createTestSovereignBank();
const result = await fxService.submitOrder(bank.id, {
pair: 'USD/EUR',
amount: '1000.00',
orderType: FxOrderType.LIMIT,
limitPrice: '0.85',
settlement: 'RTGS',
});
expect(result.tradeId).toBeDefined();
});
it('should reject limit order without price', async () => {
const bank = await createTestSovereignBank();
await expect(
fxService.submitOrder(bank.id, {
pair: 'USD/EUR',
amount: '1000.00',
orderType: FxOrderType.LIMIT,
settlement: 'RTGS',
})
).rejects.toThrow();
});
});
describe('executeTrade', () => {
it('should execute a pending trade', async () => {
const bank = await createTestSovereignBank();
const orderResult = await fxService.submitOrder(bank.id, {
pair: 'USD/EUR',
amount: '1000.00',
orderType: FxOrderType.MARKET,
settlement: 'RTGS',
});
const trade = await fxService.executeTrade(orderResult.tradeId);
expect(trade.status).toBe('executed');
expect(trade.executedAt).toBeDefined();
});
it('should reject executing non-existent trade', async () => {
await expect(fxService.executeTrade('NON-EXISTENT')).rejects.toThrow();
});
});
});

View File

@@ -0,0 +1,148 @@
// Ledger Service Unit Tests
import { ledgerService } from '@/core/ledger/ledger.service';
import { createTestSovereignBank, createTestBankAccount, cleanDatabase } from '@/__tests__/utils/test-db';
import { testPrisma } from '@/__tests__/utils/test-db';
import { Decimal } from '@prisma/client/runtime/library';
describe('LedgerService', () => {
beforeEach(async () => {
await cleanDatabase();
});
afterAll(async () => {
await testPrisma.$disconnect();
});
describe('postEntry', () => {
it('should create a double-entry ledger entry', async () => {
const bank = await createTestSovereignBank();
const debitAccount = await createTestBankAccount({
sovereignBankId: bank.id,
accountNumber: 'DEBIT-001',
balance: '1000.00',
});
const creditAccount = await createTestBankAccount({
sovereignBankId: bank.id,
accountNumber: 'CREDIT-001',
balance: '500.00',
});
const result = await ledgerService.postEntry({
ledgerId: 'MASTER',
debitAccountId: debitAccount.id,
creditAccountId: creditAccount.id,
amount: '100.00',
currencyCode: 'USD',
assetType: 'fiat',
transactionType: 'TYPE_A',
referenceId: 'TEST-REF-001',
});
expect(result.status).toBe('posted');
expect(result.entryIds).toHaveLength(1);
// Verify balances updated
const updatedDebit = await testPrisma.bankAccount.findUnique({
where: { id: debitAccount.id },
});
const updatedCredit = await testPrisma.bankAccount.findUnique({
where: { id: creditAccount.id },
});
expect(updatedDebit?.balance.toString()).toBe('900.00');
expect(updatedCredit?.balance.toString()).toBe('600.00');
});
it('should validate debits equal credits', async () => {
const bank = await createTestSovereignBank();
const debitAccount = await createTestBankAccount({
sovereignBankId: bank.id,
});
const creditAccount = await createTestBankAccount({
sovereignBankId: bank.id,
});
await expect(
ledgerService.postEntry({
ledgerId: 'MASTER',
debitAccountId: debitAccount.id,
creditAccountId: creditAccount.id,
amount: '100.00',
currencyCode: 'USD',
assetType: 'fiat',
transactionType: 'TYPE_A',
referenceId: 'TEST-REF-002',
})
).resolves.toBeDefined();
});
it('should reject entry if debit account has insufficient balance', async () => {
const bank = await createTestSovereignBank();
const debitAccount = await createTestBankAccount({
sovereignBankId: bank.id,
balance: '50.00',
});
const creditAccount = await createTestBankAccount({
sovereignBankId: bank.id,
});
await expect(
ledgerService.postEntry({
ledgerId: 'MASTER',
debitAccountId: debitAccount.id,
creditAccountId: creditAccount.id,
amount: '100.00',
currencyCode: 'USD',
assetType: 'fiat',
transactionType: 'TYPE_A',
referenceId: 'TEST-REF-003',
})
).rejects.toThrow();
});
});
describe('hashChaining', () => {
it('should chain ledger entries with previous hash', async () => {
const bank = await createTestSovereignBank();
const debitAccount = await createTestBankAccount({
sovereignBankId: bank.id,
});
const creditAccount = await createTestBankAccount({
sovereignBankId: bank.id,
});
const entry1 = await ledgerService.postEntry({
ledgerId: 'MASTER',
debitAccountId: debitAccount.id,
creditAccountId: creditAccount.id,
amount: '100.00',
currencyCode: 'USD',
assetType: 'fiat',
transactionType: 'TYPE_A',
referenceId: 'TEST-REF-004',
});
const entry2 = await ledgerService.postEntry({
ledgerId: 'MASTER',
debitAccountId: debitAccount.id,
creditAccountId: creditAccount.id,
amount: '50.00',
currencyCode: 'USD',
assetType: 'fiat',
transactionType: 'TYPE_A',
referenceId: 'TEST-REF-005',
});
const ledgerEntry1 = await testPrisma.ledgerEntry.findUnique({
where: { id: entry1.entryIds[0] },
});
const ledgerEntry2 = await testPrisma.ledgerEntry.findUnique({
where: { id: entry2.entryIds[0] },
});
expect(ledgerEntry2?.previousHash).toBe(ledgerEntry1?.blockHash);
});
});
});

View File

@@ -0,0 +1,177 @@
// Payment Service Edge Cases Unit Tests
import { paymentService } from '@/core/payments/payment.service';
import { createTestSovereignBank, createTestBankAccount, cleanDatabase } from '@/__tests__/utils/test-db';
import { testPrisma } from '@/__tests__/utils/test-db';
import { PaymentPriority } from '@/shared/types';
describe('PaymentService - Edge Cases', () => {
beforeEach(async () => {
await cleanDatabase();
});
afterAll(async () => {
await testPrisma.$disconnect();
});
describe('Currency Mismatch Handling', () => {
it('should reject payment when currencies do not match', async () => {
const bank = await createTestSovereignBank();
const sourceAccount = await createTestBankAccount({
sovereignBankId: bank.id,
currencyCode: 'USD',
balance: '1000.00',
});
const destAccount = await createTestBankAccount({
sovereignBankId: bank.id,
currencyCode: 'EUR',
balance: '500.00',
});
await expect(
paymentService.initiatePayment({
debtorAccount: sourceAccount.accountNumber,
creditorAccount: destAccount.accountNumber,
amount: '100.00',
currency: 'USD',
priority: PaymentPriority.NORMAL,
assetType: 'fiat',
})
).rejects.toThrow();
});
});
describe('Large Amount Handling', () => {
it('should handle very large payment amounts', async () => {
const bank = await createTestSovereignBank();
const sourceAccount = await createTestBankAccount({
sovereignBankId: bank.id,
balance: '999999999.99',
});
const destAccount = await createTestBankAccount({
sovereignBankId: bank.id,
});
const result = await paymentService.initiatePayment({
debtorAccount: sourceAccount.accountNumber,
creditorAccount: destAccount.accountNumber,
amount: '999999999.99',
currency: 'USD',
priority: PaymentPriority.RTGS,
assetType: 'fiat',
});
expect(result.status).toBe('settled');
});
it('should reject payment exceeding account balance', async () => {
const bank = await createTestSovereignBank();
const sourceAccount = await createTestBankAccount({
sovereignBankId: bank.id,
balance: '1000.00',
});
const destAccount = await createTestBankAccount({
sovereignBankId: bank.id,
});
await expect(
paymentService.initiatePayment({
debtorAccount: sourceAccount.accountNumber,
creditorAccount: destAccount.accountNumber,
amount: '1001.00',
currency: 'USD',
priority: PaymentPriority.NORMAL,
assetType: 'fiat',
})
).rejects.toThrow('Insufficient');
});
});
describe('Concurrent Payments', () => {
it('should handle multiple concurrent payments from same account', async () => {
const bank = await createTestSovereignBank();
const sourceAccount = await createTestBankAccount({
sovereignBankId: bank.id,
balance: '1000.00',
});
const destAccount1 = await createTestBankAccount({
sovereignBankId: bank.id,
});
const destAccount2 = await createTestBankAccount({
sovereignBankId: bank.id,
});
// Simulate concurrent payments
const payment1 = paymentService.initiatePayment({
debtorAccount: sourceAccount.accountNumber,
creditorAccount: destAccount1.accountNumber,
amount: '300.00',
currency: 'USD',
priority: PaymentPriority.NORMAL,
assetType: 'fiat',
});
const payment2 = paymentService.initiatePayment({
debtorAccount: sourceAccount.accountNumber,
creditorAccount: destAccount2.accountNumber,
amount: '300.00',
currency: 'USD',
priority: PaymentPriority.NORMAL,
assetType: 'fiat',
});
const results = await Promise.allSettled([payment1, payment2]);
// At least one should succeed, but both might fail if balance is insufficient
const succeeded = results.filter((r) => r.status === 'fulfilled').length;
expect(succeeded).toBeGreaterThanOrEqual(0);
});
});
describe('Zero and Negative Amounts', () => {
it('should reject zero amount payments', async () => {
const bank = await createTestSovereignBank();
const sourceAccount = await createTestBankAccount({
sovereignBankId: bank.id,
balance: '1000.00',
});
const destAccount = await createTestBankAccount({
sovereignBankId: bank.id,
});
await expect(
paymentService.initiatePayment({
debtorAccount: sourceAccount.accountNumber,
creditorAccount: destAccount.accountNumber,
amount: '0.00',
currency: 'USD',
priority: PaymentPriority.NORMAL,
assetType: 'fiat',
})
).rejects.toThrow();
});
it('should reject negative amount payments', async () => {
const bank = await createTestSovereignBank();
const sourceAccount = await createTestBankAccount({
sovereignBankId: bank.id,
balance: '1000.00',
});
const destAccount = await createTestBankAccount({
sovereignBankId: bank.id,
});
await expect(
paymentService.initiatePayment({
debtorAccount: sourceAccount.accountNumber,
creditorAccount: destAccount.accountNumber,
amount: '-100.00',
currency: 'USD',
priority: PaymentPriority.NORMAL,
assetType: 'fiat',
})
).rejects.toThrow();
});
});
});

View File

@@ -0,0 +1,103 @@
// Payment Service Unit Tests
import { paymentService } from '@/core/payments/payment.service';
import { PaymentPriority } from '@/shared/types';
import { createTestSovereignBank, createTestBankAccount, cleanDatabase } from '@/__tests__/utils/test-db';
import { testPrisma } from '@/__tests__/utils/test-db';
import { Decimal } from '@prisma/client/runtime/library';
describe('PaymentService', () => {
beforeEach(async () => {
await cleanDatabase();
});
afterAll(async () => {
await testPrisma.$disconnect();
});
describe('processPayment', () => {
it('should process a valid payment', async () => {
const bank = await createTestSovereignBank();
const sourceAccount = await createTestBankAccount({
sovereignBankId: bank.id,
accountNumber: 'SOURCE-001',
balance: '1000.00',
});
const destinationAccount = await createTestBankAccount({
sovereignBankId: bank.id,
accountNumber: 'DEST-001',
balance: '500.00',
});
const result = await paymentService.initiatePayment({
debtorAccount: sourceAccount.accountNumber,
creditorAccount: destinationAccount.accountNumber,
amount: '100.00',
currency: 'USD',
priority: PaymentPriority.NORMAL,
assetType: 'fiat',
});
expect(result.status).toBe('completed');
expect(result.paymentId).toBeDefined();
// Verify balances
const updatedSource = await testPrisma.bankAccount.findUnique({
where: { id: sourceAccount.id },
});
const updatedDest = await testPrisma.bankAccount.findUnique({
where: { id: destinationAccount.id },
});
expect(updatedSource?.balance.toString()).toBe('900.00');
expect(updatedDest?.balance.toString()).toBe('600.00');
});
it('should reject payment with insufficient balance', async () => {
const bank = await createTestSovereignBank();
const sourceAccount = await createTestBankAccount({
sovereignBankId: bank.id,
balance: '50.00',
});
const destinationAccount = await createTestBankAccount({
sovereignBankId: bank.id,
});
await expect(
paymentService.initiatePayment({
debtorAccount: sourceAccount.accountNumber,
creditorAccount: destinationAccount.accountNumber,
amount: '100.00',
currency: 'USD',
priority: PaymentPriority.NORMAL,
assetType: 'fiat',
})
).rejects.toThrow();
});
it('should validate currency codes match', async () => {
const bank = await createTestSovereignBank();
const sourceAccount = await createTestBankAccount({
sovereignBankId: bank.id,
currencyCode: 'USD',
balance: '1000.00',
});
const destinationAccount = await createTestBankAccount({
sovereignBankId: bank.id,
currencyCode: 'EUR',
});
await expect(
paymentService.initiatePayment({
debtorAccount: sourceAccount.accountNumber,
creditorAccount: destinationAccount.accountNumber,
amount: '100.00',
currency: 'USD',
priority: PaymentPriority.NORMAL,
assetType: 'fiat',
})
).rejects.toThrow();
});
});
});

View File

@@ -0,0 +1,78 @@
// Atomic Settlement Service Unit Tests
import { atomicSettlementService } from '@/core/settlement/isn/atomic-settlement.service';
import { createTestSovereignBank, createTestBankAccount, cleanDatabase } from '@/__tests__/utils/test-db';
import { testPrisma } from '@/__tests__/utils/test-db';
describe('AtomicSettlementService', () => {
beforeEach(async () => {
await cleanDatabase();
});
afterAll(async () => {
await testPrisma.$disconnect();
});
describe('settleAtomically', () => {
it('should settle multiple transactions atomically', async () => {
const bank1 = await createTestSovereignBank({ sovereignCode: 'BANK1' });
const bank2 = await createTestSovereignBank({ sovereignCode: 'BANK2' });
const account1 = await createTestBankAccount({
sovereignBankId: bank1.id,
balance: '1000.00',
});
const account2 = await createTestBankAccount({
sovereignBankId: bank2.id,
balance: '500.00',
});
const result = await atomicSettlementService.settleAtomically({
transactions: [
{
sourceAccountId: account1.id,
destinationAccountId: account2.id,
amount: '100.00',
currencyCode: 'USD',
},
],
referenceId: 'ATOMIC-001',
});
expect(result.success).toBe(true);
expect(result.settlementTime).toBeGreaterThan(0);
});
it('should rollback all transactions if any fails', async () => {
const bank = await createTestSovereignBank();
const account1 = await createTestBankAccount({
sovereignBankId: bank.id,
balance: '50.00', // Insufficient for 100.00 transfer
});
const account2 = await createTestBankAccount({
sovereignBankId: bank.id,
});
await expect(
atomicSettlementService.settleAtomically({
transactions: [
{
sourceAccountId: account1.id,
destinationAccountId: account2.id,
amount: '100.00',
currencyCode: 'USD',
},
],
referenceId: 'ATOMIC-002',
})
).rejects.toThrow();
// Verify no changes were made
const updatedAccount1 = await testPrisma.bankAccount.findUnique({
where: { id: account1.id },
});
expect(updatedAccount1?.balance.toString()).toBe('50.00');
});
});
});

View File

@@ -0,0 +1,161 @@
// Comprehensive Settlement Tests
import { atomicSettlementService } from '@/core/settlement/isn/atomic-settlement.service';
import { createTestSovereignBank, createTestBankAccount, cleanDatabase } from '@/__tests__/utils/test-db';
import { testPrisma } from '@/__tests__/utils/test-db';
describe('Settlement - Comprehensive Tests', () => {
beforeEach(async () => {
await cleanDatabase();
});
afterAll(async () => {
await testPrisma.$disconnect();
});
describe('Cross-Chain Settlement', () => {
it('should settle transactions across different asset chains', async () => {
const bank1 = await createTestSovereignBank({ sovereignCode: 'BANK1' });
const bank2 = await createTestSovereignBank({ sovereignCode: 'BANK2' });
const account1 = await createTestBankAccount({
sovereignBankId: bank1.id,
assetType: 'fiat',
balance: '1000.00',
});
const account2 = await createTestBankAccount({
sovereignBankId: bank2.id,
assetType: 'cbdc',
balance: '500.00',
});
const result = await atomicSettlementService.settleAtomically({
transactions: [
{
sourceAccountId: account1.id,
destinationAccountId: account2.id,
amount: '100.00',
currencyCode: 'USD',
},
],
referenceId: 'CROSS-CHAIN-001',
});
expect(result.success).toBe(true);
});
});
describe('Atomic Rollback', () => {
it('should rollback all transactions if any fails', async () => {
const bank = await createTestSovereignBank();
const account1 = await createTestBankAccount({
sovereignBankId: bank.id,
balance: '50.00',
});
const account2 = await createTestBankAccount({
sovereignBankId: bank.id,
});
const account3 = await createTestBankAccount({
sovereignBankId: bank.id,
});
// First transaction should succeed, second should fail
await expect(
atomicSettlementService.settleAtomically({
transactions: [
{
sourceAccountId: account1.id,
destinationAccountId: account2.id,
amount: '30.00',
currencyCode: 'USD',
},
{
sourceAccountId: account1.id,
destinationAccountId: account3.id,
amount: '30.00', // This will fail due to insufficient balance
currencyCode: 'USD',
},
],
referenceId: 'ROLLBACK-001',
})
).rejects.toThrow();
// Verify no changes were made (rollback worked)
const updatedAccount1 = await testPrisma.bankAccount.findUnique({
where: { id: account1.id },
});
expect(updatedAccount1?.balance.toString()).toBe('50.00');
});
});
describe('Multi-Leg Transactions', () => {
it('should settle multi-legged transactions atomically', async () => {
const bank = await createTestSovereignBank();
const account1 = await createTestBankAccount({
sovereignBankId: bank.id,
balance: '1000.00',
});
const account2 = await createTestBankAccount({
sovereignBankId: bank.id,
balance: '500.00',
});
const account3 = await createTestBankAccount({
sovereignBankId: bank.id,
balance: '300.00',
});
const result = await atomicSettlementService.settleAtomically({
transactions: [
{
sourceAccountId: account1.id,
destinationAccountId: account2.id,
amount: '100.00',
currencyCode: 'USD',
},
{
sourceAccountId: account2.id,
destinationAccountId: account3.id,
amount: '50.00',
currencyCode: 'USD',
},
],
referenceId: 'MULTI-LEG-001',
});
expect(result.success).toBe(true);
expect(result.entryIds.length).toBeGreaterThan(0);
});
});
describe('Settlement Time Performance', () => {
it('should complete settlement within acceptable time', async () => {
const bank = await createTestSovereignBank();
const account1 = await createTestBankAccount({
sovereignBankId: bank.id,
balance: '1000.00',
});
const account2 = await createTestBankAccount({
sovereignBankId: bank.id,
});
const startTime = Date.now();
const result = await atomicSettlementService.settleAtomically({
transactions: [
{
sourceAccountId: account1.id,
destinationAccountId: account2.id,
amount: '100.00',
currencyCode: 'USD',
},
],
referenceId: 'PERF-001',
});
const endTime = Date.now();
expect(result.success).toBe(true);
expect(result.settlementTime).toBeLessThan(1000); // Should complete in < 1 second
expect(endTime - startTime).toBeLessThan(2000); // Actual time < 2 seconds
});
});
});

View File

@@ -0,0 +1,37 @@
// Test Authentication Utilities
// Helpers for authentication in tests
import jwt from 'jsonwebtoken';
import { JwtPayload } from '@/shared/types';
const TEST_JWT_SECRET = process.env.JWT_SECRET || 'test-jwt-secret-minimum-32-characters-long-for-testing';
/**
* Create a test JWT token
*/
export function createTestToken(payload: Partial<JwtPayload>): string {
const defaultPayload: JwtPayload = {
sovereignBankId: 'test-bank-id',
identityType: 'API',
apiRole: 'user',
iat: Math.floor(Date.now() / 1000),
exp: Math.floor(Date.now() / 1000) + 3600, // 1 hour
...payload,
};
return jwt.sign(defaultPayload, TEST_JWT_SECRET);
}
/**
* Create test request headers with authentication
*/
export function createAuthHeaders(payload?: Partial<JwtPayload>): Record<string, string> {
const token = createTestToken(payload || {});
return {
authorization: `SOV-TOKEN ${token}`,
'x-sov-signature': 'test-signature',
'x-sov-timestamp': Date.now().toString(),
'x-sov-nonce': 'test-nonce',
};
}

View File

@@ -0,0 +1,86 @@
// Test Database Utilities
// Helpers for database operations in tests
import { PrismaClient } from '@prisma/client';
import { Decimal } from '@prisma/client/runtime/library';
const testPrisma = new PrismaClient({
datasources: {
db: {
url: process.env.TEST_DATABASE_URL || 'postgresql://test:test@localhost:5432/dbis_test',
},
},
});
/**
* Clean database before each test
*/
export async function cleanDatabase(): Promise<void> {
// Delete in reverse order of dependencies
const tables = [
'LedgerEntry',
'BankAccount',
'SovereignIdentity',
'SovereignBank',
];
for (const table of tables) {
await (testPrisma as any)[table].deleteMany({});
}
}
/**
* Create a test sovereign bank
*/
export async function createTestSovereignBank(data?: {
sovereignCode?: string;
name?: string;
bic?: string;
}) {
return await testPrisma.sovereignBank.create({
data: {
sovereignCode: data?.sovereignCode || 'TEST',
name: data?.name || 'Test Bank',
bic: data?.bic || 'TESTXXXX',
status: 'active',
},
});
}
/**
* Create a test bank account
*/
export async function createTestBankAccount(data: {
sovereignBankId: string;
accountNumber?: string;
accountType?: string;
currencyCode?: string;
balance?: string;
}) {
return await testPrisma.bankAccount.create({
data: {
accountNumber: data.accountNumber || `ACC-${Date.now()}`,
sovereignBankId: data.sovereignBankId,
accountType: data.accountType || 'commercial',
currencyCode: data.currencyCode || 'USD',
balance: new Decimal(data.balance || '0'),
availableBalance: new Decimal(data.balance || '0'),
reservedBalance: new Decimal('0'),
status: 'active',
},
});
}
/**
* Rollback transaction wrapper for tests
*/
export async function withTransaction<T>(
callback: (tx: PrismaClient) => Promise<T>
): Promise<T> {
return await testPrisma.$transaction(async (tx) => {
return await callback(tx as PrismaClient);
});
}
export { testPrisma };

View File

@@ -0,0 +1,78 @@
// Test Data Factories
// Generate test data for various entities
import { v4 as uuidv4 } from 'uuid';
import { Decimal } from '@prisma/client/runtime/library';
export const testFactories = {
/**
* Create test sovereign bank data
*/
sovereignBank: (overrides?: Record<string, unknown>) => ({
sovereignCode: `TEST-${uuidv4().substring(0, 8)}`,
name: 'Test Sovereign Bank',
bic: `TEST${uuidv4().substring(0, 4)}`,
status: 'active',
...overrides,
}),
/**
* Create test bank account data
*/
bankAccount: (sovereignBankId: string, overrides?: Record<string, unknown>) => ({
accountNumber: `ACC-${uuidv4()}`,
sovereignBankId,
accountType: 'commercial',
currencyCode: 'USD',
balance: new Decimal('1000.00'),
availableBalance: new Decimal('1000.00'),
reservedBalance: new Decimal('0'),
status: 'active',
...overrides,
}),
/**
* Create test ledger entry data
*/
ledgerEntry: (
debitAccountId: string,
creditAccountId: string,
overrides?: Record<string, unknown>
) => ({
ledgerId: 'MASTER',
debitAccountId,
creditAccountId,
amount: new Decimal('100.00'),
currencyCode: 'USD',
assetType: 'fiat',
transactionType: 'TYPE_A',
referenceId: `REF-${uuidv4()}`,
blockHash: `HASH-${uuidv4()}`,
status: 'pending',
...overrides,
}),
/**
* Create test payment data
*/
payment: (overrides?: Record<string, unknown>) => ({
sourceAccountId: uuidv4(),
destinationAccountId: uuidv4(),
amount: '100.00',
currencyCode: 'USD',
paymentType: 'transfer',
...overrides,
}),
/**
* Create test FX order data
*/
fxOrder: (overrides?: Record<string, unknown>) => ({
pair: 'USD/EUR',
amount: '1000.00',
orderType: 'market',
settlement: 'RTGS',
...overrides,
}),
};

View File

@@ -0,0 +1,206 @@
// DBIS Accounting Standards Service
// Fair value marking, commodity feed integration
import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
export interface ValuationData {
assetType: string;
assetId: string;
fairValue: number;
currencyCode: string;
valuationDate: Date;
source: string;
}
export class AccountingStandardsService {
/**
* Get valuation rule for asset type
*/
async getValuationRule(assetType: string) {
return await prisma.valuationRule.findFirst({
where: {
assetType,
status: 'active',
effectiveDate: {
lte: new Date(),
},
OR: [
{ expiryDate: null },
{ expiryDate: { gte: new Date() } },
],
},
orderBy: { effectiveDate: 'desc' },
});
}
/**
* Mark asset to fair value
*/
async markToFairValue(assetId: string, assetType: string, fairValue: number, currencyCode: string) {
const rule = await this.getValuationRule(assetType);
if (!rule) {
throw new Error(`No valuation rule found for asset type: ${assetType}`);
}
// Update asset value based on type
switch (assetType) {
case 'commodity':
await this.updateCommodityValue(assetId, fairValue);
break;
case 'security':
await this.updateSecurityValue(assetId, fairValue);
break;
case 'fiat':
case 'cbdc':
// Fiat and CBDC are already at fair value
break;
default:
throw new Error(`Unsupported asset type for fair value marking: ${assetType}`);
}
// Log valuation
await prisma.auditLog.create({
data: {
eventType: 'valuation',
entityType: assetType,
entityId: assetId,
action: 'mark_to_fair_value',
details: {
fairValue,
currencyCode,
valuationMethod: rule.valuationMethod,
timestamp: new Date(),
},
},
});
}
/**
* Update commodity value
*/
private async updateCommodityValue(commodityId: string, fairValue: number) {
// In production, would update commodity price
// For now, update commodity spot price if exists
const commodity = await prisma.commodity.findFirst({
where: {
id: commodityId,
},
});
if (commodity) {
await prisma.commodity.update({
where: { id: commodityId },
data: {
spotPrice: new Decimal(fairValue),
lastUpdated: new Date(),
},
});
}
}
/**
* Update security value
*/
private async updateSecurityValue(securityId: string, fairValue: number) {
const security = await prisma.security.findFirst({
where: {
securityId,
},
});
if (security) {
await prisma.security.update({
where: { id: security.id },
data: {
price: new Decimal(fairValue),
updatedAt: new Date(),
},
});
}
}
/**
* Get commodity feed price
*/
async getCommodityFeedPrice(commodityType: string, unit: string): Promise<number | null> {
const commodity = await prisma.commodity.findUnique({
where: {
commodityType_unit: {
commodityType,
unit,
},
},
});
if (!commodity) {
return null;
}
return parseFloat(commodity.spotPrice.toString());
}
/**
* Get FX reference rate
*/
async getFXReferenceRate(baseCurrency: string, quoteCurrency: string): Promise<number | null> {
const fxPair = await prisma.fxPair.findFirst({
where: {
OR: [
{
baseCurrency,
quoteCurrency,
},
{
baseCurrency: quoteCurrency,
quoteCurrency: baseCurrency,
},
],
status: 'active',
},
include: {
trades: {
where: {
status: 'settled',
},
orderBy: { timestampUtc: 'desc' },
take: 1,
},
},
});
if (!fxPair || fxPair.trades.length === 0) {
return null;
}
return parseFloat(fxPair.trades[0].price.toString());
}
/**
* Create valuation rule
*/
async createValuationRule(
assetType: string,
valuationMethod: string,
feedSource?: string,
updateFrequency: string = 'real_time'
) {
return await prisma.valuationRule.create({
data: {
id: require('uuid').v4(),
ruleId: require('uuid').v4(),
assetType,
valuationMethod,
feedSource,
updateFrequency,
status: 'active',
effectiveDate: new Date(),
},
});
}
}
export const accountingStandardsService = new AccountingStandardsService();

View File

@@ -0,0 +1,422 @@
// DBIS Reporting Engine Service
// Generate consolidated statements, SCB reports
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
import { accountService } from '@/core/accounts/account.service';
import { treasuryService } from '@/core/treasury/treasury.service';
import prisma from '@/shared/database/prisma';
export interface ConsolidatedStatementData {
statementType: string;
periodStart: Date;
periodEnd: Date;
}
export interface SovereignReportData {
sovereignBankId: string;
reportType: string;
reportPeriod: string;
reportDate: Date;
}
export class ReportingEngineService {
/**
* Generate Consolidated Sovereign Liquidity Report (CSLR)
*/
async generateCSLR(periodStart: Date, periodEnd: Date) {
const banks = await prisma.sovereignBank.findMany({
where: { status: 'active' },
include: {
liquidityPools: true,
accounts: true,
},
});
const consolidatedData: Record<string, unknown> = {
periodStart,
periodEnd,
reportDate: new Date(),
totalBanks: banks.length,
liquidityByCurrency: {},
totalLiquidity: 0,
bankDetails: [],
};
for (const bank of banks) {
const bankLiquidity = bank.liquidityPools.reduce(
(sum, pool) => sum + parseFloat(pool.totalLiquidity.toString()),
0
);
const lcr = await treasuryService.calculateLCR(bank.id);
const nsfr = await treasuryService.calculateNSFR(bank.id);
consolidatedData.bankDetails.push({
sovereignBankId: bank.id,
sovereignCode: bank.sovereignCode,
name: bank.name,
totalLiquidity: bankLiquidity,
lcr,
nsfr,
});
// Aggregate by currency
for (const pool of bank.liquidityPools) {
const currency = pool.currencyCode;
if (!consolidatedData.liquidityByCurrency[currency]) {
consolidatedData.liquidityByCurrency[currency] = 0;
}
consolidatedData.liquidityByCurrency[currency] += parseFloat(pool.totalLiquidity.toString());
}
consolidatedData.totalLiquidity += bankLiquidity;
}
const statement = await prisma.consolidatedStatement.create({
data: {
id: uuidv4(),
statementId: uuidv4(),
statementType: 'CSLR',
reportDate: new Date(),
periodStart,
periodEnd,
status: 'final',
statementData: consolidatedData,
publishedAt: new Date(),
},
});
return statement;
}
/**
* Generate Cross-Border Settlement Exposures Report
*/
async generateCrossBorderExposureReport(periodStart: Date, periodEnd: Date) {
const settlements = await prisma.ledgerEntry.findMany({
where: {
timestampUtc: {
gte: periodStart,
lte: periodEnd,
},
status: 'settled',
},
include: {
debitAccount: {
include: {
sovereignBank: true,
},
},
creditAccount: {
include: {
sovereignBank: true,
},
},
},
});
const exposures: Record<string, unknown> = {};
const bankPairs: Record<string, number> = {};
for (const settlement of settlements) {
const debitBank = settlement.debitAccount.sovereignBank.sovereignCode;
const creditBank = settlement.creditAccount.sovereignBank.sovereignCode;
if (debitBank !== creditBank) {
const pairKey = `${debitBank}_${creditBank}`;
const amount = parseFloat(settlement.amount.toString());
if (!bankPairs[pairKey]) {
bankPairs[pairKey] = 0;
}
bankPairs[pairKey] += amount;
// Track exposure by bank
if (!exposures[debitBank]) {
exposures[debitBank] = { outbound: 0, inbound: 0 };
}
if (!exposures[creditBank]) {
exposures[creditBank] = { outbound: 0, inbound: 0 };
}
exposures[debitBank].outbound += amount;
exposures[creditBank].inbound += amount;
}
}
const reportData = {
periodStart,
periodEnd,
reportDate: new Date(),
totalCrossBorderSettlements: settlements.filter(
(s) => s.debitAccount.sovereignBankId !== s.creditAccount.sovereignBankId
).length,
exposures,
bankPairs,
};
const statement = await prisma.consolidatedStatement.create({
data: {
id: uuidv4(),
statementId: uuidv4(),
statementType: 'CrossBorderExposure',
reportDate: new Date(),
periodStart,
periodEnd,
status: 'final',
statementData: reportData,
publishedAt: new Date(),
},
});
return statement;
}
/**
* Generate CBDC Reserve Adequacy Statement
*/
async generateCBDCReserveAdequacy(periodStart: Date, periodEnd: Date) {
const cbdcIssuances = await prisma.cbdcIssuance.findMany({
where: {
timestampUtc: {
gte: periodStart,
lte: periodEnd,
},
},
include: {
sovereignBank: true,
},
});
const adequacyData: Record<string, unknown> = {
periodStart,
periodEnd,
reportDate: new Date(),
totalIssuances: cbdcIssuances.length,
bankAdequacy: [],
totalCBDCIssued: 0,
totalReserveBacking: 0,
};
for (const issuance of cbdcIssuances) {
const bankIssuances = cbdcIssuances.filter(
(i) => i.sovereignBankId === issuance.sovereignBankId
);
const totalIssued = bankIssuances.reduce(
(sum, i) => sum + parseFloat(i.amountMinted.toString()),
0
);
const totalBacking = bankIssuances.reduce(
(sum, i) => sum + parseFloat(i.reserveBacking?.toString() || '0'),
0
);
adequacyData.bankAdequacy.push({
sovereignBankId: issuance.sovereignBankId,
sovereignCode: issuance.sovereignBank.sovereignCode,
totalCBDCIssued: totalIssued,
totalReserveBacking: totalBacking,
adequacyRatio: totalBacking > 0 ? totalIssued / totalBacking : 0,
});
adequacyData.totalCBDCIssued += totalIssued;
adequacyData.totalReserveBacking += totalBacking;
}
const statement = await prisma.consolidatedStatement.create({
data: {
id: uuidv4(),
statementId: uuidv4(),
statementType: 'CBDCReserveAdequacy',
reportDate: new Date(),
periodStart,
periodEnd,
status: 'final',
statementData: adequacyData,
publishedAt: new Date(),
},
});
return statement;
}
/**
* Generate SCB daily liquidity window report
*/
async generateDailyLiquidityReport(sovereignBankId: string, reportDate: Date) {
const lcr = await treasuryService.calculateLCR(sovereignBankId);
const nsfr = await treasuryService.calculateNSFR(sovereignBankId);
const accounts = await accountService.getAccountsBySovereign(sovereignBankId);
const liquidityData = {
reportDate,
lcr,
nsfr,
totalAccounts: accounts.length,
totalBalance: accounts.reduce((sum, acc) => sum + parseFloat(acc.balance), 0),
availableBalance: accounts.reduce((sum, acc) => sum + parseFloat(acc.availableBalance), 0),
reservedBalance: accounts.reduce((sum, acc) => sum + parseFloat(acc.reservedBalance), 0),
};
const report = await prisma.sovereignReport.create({
data: {
id: uuidv4(),
sovereignBankId,
reportId: uuidv4(),
reportType: 'daily_liquidity',
reportPeriod: 'daily',
reportDate,
dueDate: new Date(reportDate.getTime() + 24 * 60 * 60 * 1000), // Next day
status: 'submitted',
reportData: liquidityData,
submittedAt: new Date(),
},
});
return report;
}
/**
* Generate SCB weekly FX reserve update
*/
async generateWeeklyFXReserveReport(sovereignBankId: string, reportDate: Date) {
const accounts = await accountService.getAccountsBySovereign(sovereignBankId);
const fxReserves: Record<string, number> = {};
for (const account of accounts) {
if (account.assetType === 'fiat' || account.assetType === 'cbdc') {
if (!fxReserves[account.currencyCode]) {
fxReserves[account.currencyCode] = 0;
}
fxReserves[account.currencyCode] += parseFloat(account.balance);
}
}
const report = await prisma.sovereignReport.create({
data: {
id: uuidv4(),
sovereignBankId,
reportId: uuidv4(),
reportType: 'weekly_fx_reserve',
reportPeriod: 'weekly',
reportDate,
dueDate: new Date(reportDate.getTime() + 7 * 24 * 60 * 60 * 1000), // Next week
status: 'submitted',
reportData: {
reportDate,
fxReserves,
totalReserves: Object.values(fxReserves).reduce((sum, val) => sum + val, 0),
},
submittedAt: new Date(),
},
});
return report;
}
/**
* Generate SCB monthly AML compliance results
*/
async generateMonthlyAMLComplianceReport(sovereignBankId: string, reportDate: Date) {
const monthStart = new Date(reportDate.getFullYear(), reportDate.getMonth(), 1);
const monthEnd = new Date(reportDate.getFullYear(), reportDate.getMonth() + 1, 0);
const complianceRecords = await prisma.complianceRecord.findMany({
where: {
sovereignBankId,
createdAt: {
gte: monthStart,
lte: monthEnd,
},
},
});
const reportData = {
reportDate,
monthStart,
monthEnd,
totalChecks: complianceRecords.length,
clearCount: complianceRecords.filter((r) => r.status === 'clear').length,
flaggedCount: complianceRecords.filter((r) => r.status === 'flagged').length,
blockedCount: complianceRecords.filter((r) => r.status === 'blocked').length,
averageRiskScore: complianceRecords.length > 0
? complianceRecords.reduce((sum, r) => sum + r.riskScore, 0) / complianceRecords.length
: 0,
};
const report = await prisma.sovereignReport.create({
data: {
id: uuidv4(),
sovereignBankId,
reportId: uuidv4(),
reportType: 'monthly_aml_compliance',
reportPeriod: 'monthly',
reportDate,
dueDate: new Date(reportDate.getFullYear(), reportDate.getMonth() + 1, 15), // 15th of next month
status: 'submitted',
reportData,
submittedAt: new Date(),
},
});
return report;
}
/**
* Generate SCB quarterly CBDC issuance audit
*/
async generateQuarterlyCBDCAudit(sovereignBankId: string, reportDate: Date) {
const quarterStart = new Date(reportDate.getFullYear(), Math.floor(reportDate.getMonth() / 3) * 3, 1);
const quarterEnd = new Date(reportDate.getFullYear(), Math.floor(reportDate.getMonth() / 3) * 3 + 3, 0);
const issuances = await prisma.cbdcIssuance.findMany({
where: {
sovereignBankId,
timestampUtc: {
gte: quarterStart,
lte: quarterEnd,
},
},
});
const reportData = {
reportDate,
quarterStart,
quarterEnd,
totalIssuances: issuances.length,
totalMinted: issuances.reduce((sum, i) => sum + parseFloat(i.amountMinted.toString()), 0),
totalBurned: issuances.reduce((sum, i) => sum + parseFloat(i.amountBurned.toString()), 0),
netChange: issuances.reduce((sum, i) => sum + parseFloat(i.netChange.toString()), 0),
issuances: issuances.map((i) => ({
recordId: i.recordId,
operationType: i.operationType,
amountMinted: parseFloat(i.amountMinted.toString()),
amountBurned: parseFloat(i.amountBurned.toString()),
reserveBacking: i.reserveBacking ? parseFloat(i.reserveBacking.toString()) : null,
timestampUtc: i.timestampUtc,
})),
};
const report = await prisma.sovereignReport.create({
data: {
id: uuidv4(),
sovereignBankId,
reportId: uuidv4(),
reportType: 'quarterly_cbdc_audit',
reportPeriod: 'quarterly',
reportDate,
dueDate: new Date(reportDate.getFullYear(), Math.floor(reportDate.getMonth() / 3) * 3 + 3, 15),
status: 'submitted',
reportData,
submittedAt: new Date(),
},
});
return report;
}
}
export const reportingEngineService = new ReportingEngineService();

View File

@@ -0,0 +1,192 @@
// Valuation Service
// Real-time fair value calculation
import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { accountingStandardsService } from './accounting-standards.service';
export class ValuationService {
/**
* Calculate real-time fair value for an asset
*/
async calculateFairValue(assetType: string, assetId: string, currencyCode: string): Promise<number> {
const rule = await accountingStandardsService.getValuationRule(assetType);
if (!rule) {
throw new Error(`No valuation rule found for asset type: ${assetType}`);
}
switch (rule.valuationMethod) {
case 'fair_value':
return await this.calculateFairValueDirect(assetType, assetId, currencyCode);
case 'commodity_feed':
return await this.calculateFromCommodityFeed(assetType, assetId, currencyCode);
case 'fx_reference_rate':
return await this.calculateFromFXRate(assetType, assetId, currencyCode);
default:
throw new Error(`Unsupported valuation method: ${rule.valuationMethod}`);
}
}
/**
* Calculate fair value directly (for fiat, CBDC)
*/
private async calculateFairValueDirect(
assetType: string,
assetId: string,
currencyCode: string
): Promise<number> {
if (assetType === 'fiat' || assetType === 'cbdc') {
// Fiat and CBDC are already at fair value (1:1)
const account = await prisma.bankAccount.findUnique({
where: { id: assetId },
});
if (account) {
return parseFloat(account.balance.toString());
}
}
throw new Error(`Cannot calculate fair value directly for asset type: ${assetType}`);
}
/**
* Calculate from commodity feed
*/
private async calculateFromCommodityFeed(
assetType: string,
assetId: string,
currencyCode: string
): Promise<number> {
if (assetType !== 'commodity') {
throw new Error('Commodity feed valuation only applies to commodities');
}
// Get commodity
const commodity = await prisma.commodity.findFirst({
where: { id: assetId },
});
if (!commodity) {
throw new Error(`Commodity not found: ${assetId}`);
}
// Get current price from feed
const price = await accountingStandardsService.getCommodityFeedPrice(
commodity.commodityType,
commodity.unit
);
if (!price) {
throw new Error(`No price feed available for commodity: ${commodity.commodityType}`);
}
// Get quantity from account or sub-ledger
const account = await prisma.bankAccount.findFirst({
where: {
assetType: 'commodity',
currencyCode: commodity.commodityType,
},
});
const quantity = account ? parseFloat(account.balance.toString()) : 0;
return price * quantity;
}
/**
* Calculate from FX reference rate
*/
private async calculateFromFXRate(
assetType: string,
assetId: string,
currencyCode: string
): Promise<number> {
// Get account
const account = await prisma.bankAccount.findUnique({
where: { id: assetId },
});
if (!account) {
throw new Error(`Account not found: ${assetId}`);
}
const baseAmount = parseFloat(account.balance.toString());
// If account currency matches target currency, no conversion needed
if (account.currencyCode === currencyCode) {
return baseAmount;
}
// Get FX rate
const fxRate = await accountingStandardsService.getFXReferenceRate(
account.currencyCode,
currencyCode
);
if (!fxRate) {
throw new Error(
`No FX rate available for ${account.currencyCode}/${currencyCode}`
);
}
return baseAmount * fxRate;
}
/**
* Mark all assets to fair value (batch operation)
*/
async markAllToFairValue(sovereignBankId?: string) {
const where: { assetType?: string; sovereignBankId?: string } = {};
if (sovereignBankId) {
where.sovereignBankId = sovereignBankId;
}
const accounts = await prisma.bankAccount.findMany({
where,
include: {
sovereignBank: true,
},
});
const results = [];
for (const account of accounts) {
try {
const fairValue = await this.calculateFairValue(
account.assetType,
account.id,
account.currencyCode
);
await accountingStandardsService.markToFairValue(
account.id,
account.assetType,
fairValue,
account.currencyCode
);
results.push({
accountId: account.id,
assetType: account.assetType,
fairValue,
success: true,
});
} catch (error) {
results.push({
accountId: account.id,
assetType: account.assetType,
error: error instanceof Error ? error.message : 'Unknown error',
success: false,
});
}
}
return results;
}
}
export const valuationService = new ValuationService();

View File

@@ -0,0 +1,117 @@
/**
* @swagger
* tags:
* name: Accounts
* description: Bank Account Management
*/
import { Router } from 'express';
import { zeroTrustAuthMiddleware } from '@/integration/api-gateway/middleware/auth.middleware';
import { accountService } from './account.service';
const router = Router();
/**
* @swagger
* /api/accounts:
* post:
* summary: Create a new bank account
* description: Create a new account for a sovereign bank
* tags: [Accounts]
* security:
* - SovereignToken: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - accountType
* - currencyCode
* properties:
* accountType:
* type: string
* enum: [sovereign, treasury, commercial, correspondent, settlement]
* currencyCode:
* type: string
* description: ISO 4217 currency code
* example: "USD"
* assetType:
* type: string
* enum: [fiat, cbdc, commodity, security]
* default: fiat
* reserveRequirement:
* type: string
* description: Reserve requirement percentage
* responses:
* 201:
* description: Account created successfully
* 400:
* description: Validation error
*/
router.post('/', zeroTrustAuthMiddleware, async (req, res, next) => {
try {
const sovereignBankId = (req as any).sovereignBankId;
const account = await accountService.createAccount(
sovereignBankId,
req.body.accountType,
req.body.currencyCode,
req.body.assetType,
req.body.reserveRequirement
);
res.status(201).json({
success: true,
data: account,
timestamp: new Date(),
});
} catch (error) {
next(error);
}
});
/**
* @swagger
* /api/accounts/{id}:
* get:
* summary: Get account by ID
* description: Retrieve account details
* tags: [Accounts]
* security:
* - SovereignToken: []
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Account retrieved
* 404:
* description: Account not found
*/
router.get('/:id', zeroTrustAuthMiddleware, async (req, res, next) => {
try {
const account = await accountService.getAccount(req.params.id);
if (!account) {
return res.status(404).json({
success: false,
error: { code: 'NOT_FOUND', message: 'Account not found' },
timestamp: new Date(),
});
}
res.json({
success: true,
data: account,
timestamp: new Date(),
});
} catch (error) {
next(error);
}
});
export default router;

View File

@@ -0,0 +1,205 @@
// Account Management Engine
import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { AccountType, AssetType, BankAccount } from '@/shared/types';
import { DbisError, ErrorCode } from '@/shared/types';
import { v4 as uuidv4 } from 'uuid';
export class AccountService {
/**
* Create a new bank account
*/
async createAccount(
sovereignBankId: string,
accountType: AccountType,
currencyCode: string,
assetType: AssetType = AssetType.FIAT,
reserveRequirement?: string
): Promise<BankAccount> {
const accountNumber = this.generateAccountNumber(sovereignBankId, accountType);
const account = await prisma.bankAccount.create({
data: {
accountNumber,
sovereignBankId,
accountType,
currencyCode,
assetType,
balance: new Decimal(0),
availableBalance: new Decimal(0),
reservedBalance: new Decimal(0),
reserveRequirement: reserveRequirement ? new Decimal(reserveRequirement) : null,
status: 'active',
},
});
return this.mapToBankAccount(account);
}
/**
* Get account by ID
*/
async getAccount(accountId: string): Promise<BankAccount | null> {
const account = await prisma.bankAccount.findUnique({
where: { id: accountId },
});
return account ? this.mapToBankAccount(account) : null;
}
/**
* Get account by account number
*/
async getAccountByNumber(accountNumber: string): Promise<BankAccount | null> {
const account = await prisma.bankAccount.findUnique({
where: { accountNumber },
});
return account ? this.mapToBankAccount(account) : null;
}
/**
* Get accounts for a sovereign bank
*/
async getAccountsBySovereign(
sovereignBankId: string,
accountType?: AccountType
): Promise<BankAccount[]> {
const where: any = { sovereignBankId };
if (accountType) {
where.accountType = accountType;
}
const accounts = await prisma.bankAccount.findMany({
where,
});
return accounts.map(this.mapToBankAccount);
}
/**
* Calculate account balance
*/
async calculateBalance(accountId: string): Promise<{
balance: string;
availableBalance: string;
reservedBalance: string;
}> {
const account = await prisma.bankAccount.findUnique({
where: { id: accountId },
});
if (!account) {
throw new DbisError(ErrorCode.NOT_FOUND, 'Account not found');
}
return {
balance: account.balance.toString(),
availableBalance: account.availableBalance.toString(),
reservedBalance: account.reservedBalance.toString(),
};
}
/**
* Reserve balance
*/
async reserveBalance(accountId: string, amount: string): Promise<void> {
const account = await prisma.bankAccount.findUnique({
where: { id: accountId },
});
if (!account) {
throw new DbisError(ErrorCode.NOT_FOUND, 'Account not found');
}
const amountDecimal = new Decimal(amount);
if (account.availableBalance.lt(amountDecimal)) {
throw new DbisError(ErrorCode.VALIDATION_ERROR, 'Insufficient available balance');
}
await prisma.bankAccount.update({
where: { id: accountId },
data: {
availableBalance: account.availableBalance.minus(amountDecimal),
reservedBalance: account.reservedBalance.plus(amountDecimal),
},
});
}
/**
* Release reserved balance
*/
async releaseReservedBalance(accountId: string, amount: string): Promise<void> {
const account = await prisma.bankAccount.findUnique({
where: { id: accountId },
});
if (!account) {
throw new DbisError(ErrorCode.NOT_FOUND, 'Account not found');
}
const amountDecimal = new Decimal(amount);
if (account.reservedBalance.lt(amountDecimal)) {
throw new DbisError(ErrorCode.VALIDATION_ERROR, 'Insufficient reserved balance');
}
await prisma.bankAccount.update({
where: { id: accountId },
data: {
availableBalance: account.availableBalance.plus(amountDecimal),
reservedBalance: account.reservedBalance.minus(amountDecimal),
},
});
}
/**
* Check reserve requirements
*/
async checkReserveRequirements(accountId: string): Promise<boolean> {
const account = await prisma.bankAccount.findUnique({
where: { id: accountId },
});
if (!account || !account.reserveRequirement) {
return true; // No requirement
}
const requiredReserve = account.balance.times(account.reserveRequirement);
const actualReserve = account.reservedBalance;
return actualReserve.gte(requiredReserve);
}
/**
* Generate account number
*/
private generateAccountNumber(sovereignBankId: string, accountType: AccountType): string {
const prefix = accountType.substring(0, 3).toUpperCase();
const timestamp = Date.now().toString(36).toUpperCase();
const random = Math.random().toString(36).substring(2, 6).toUpperCase();
return `${prefix}-${sovereignBankId.substring(0, 4)}-${timestamp}-${random}`;
}
/**
* Map Prisma model to BankAccount type
*/
private mapToBankAccount(account: any): BankAccount {
return {
id: account.id,
accountNumber: account.accountNumber,
sovereignBankId: account.sovereignBankId,
accountType: account.accountType as AccountType,
currencyCode: account.currencyCode,
assetType: account.assetType as AssetType,
balance: account.balance.toString(),
availableBalance: account.availableBalance.toString(),
reservedBalance: account.reservedBalance.toString(),
reserveRequirement: account.reserveRequirement?.toString(),
status: account.status,
};
}
}
export const accountService = new AccountService();

View File

@@ -0,0 +1,127 @@
// DBIS Admin Console - Corridor Controls Service
// Corridor caps, throttling, enable/disable
import prisma from '@/shared/database/prisma';
import { logger } from '@/infrastructure/monitoring/logger';
import { adminAuditService } from '@/core/admin/shared/admin-audit.service';
import { AdminPermission } from '@/core/admin/shared/permissions.constants';
import Decimal from 'decimal.js';
export interface CorridorCapUpdate {
routeId: string;
newCap: number;
reason: string;
}
export interface CorridorThrottleRequest {
routeId: string;
throttleRate: number; // 0-1, where 1 = no throttling, 0.5 = 50% throttling
reason: string;
}
export interface CorridorEnableDisable {
routeId: string;
action: 'enable' | 'disable';
reason: string;
}
export class CorridorControlsService {
/**
* Adjust corridor caps
*/
async adjustCorridorCaps(
employeeId: string,
update: CorridorCapUpdate
): Promise<{ success: boolean }> {
const route = await prisma.settlementRoute.findUnique({
where: { routeId: update.routeId },
});
if (!route) {
throw new Error('Route not found');
}
await adminAuditService.logAction({
employeeId,
action: 'adjust_corridor_caps',
permission: AdminPermission.CORRIDOR_ADJUST_CAPS,
resourceType: 'settlement_route',
resourceId: update.routeId,
beforeState: { cap: route.sireCost?.toString() },
afterState: { cap: update.newCap.toString() },
metadata: update,
});
// Update route (would need to add cap field to schema or use existing fields)
logger.info('Corridor cap adjusted', {
employeeId,
update,
});
return { success: true };
}
/**
* Throttle corridor
*/
async throttleCorridor(
employeeId: string,
request: CorridorThrottleRequest
): Promise<{ success: boolean }> {
await adminAuditService.logAction({
employeeId,
action: 'throttle_corridor',
permission: AdminPermission.CORRIDOR_THROTTLE,
resourceType: 'settlement_route',
resourceId: request.routeId,
metadata: request,
});
// Update route status or add throttling config
logger.info('Corridor throttled', {
employeeId,
request,
});
return { success: true };
}
/**
* Enable or disable corridor
*/
async enableDisableCorridor(
employeeId: string,
request: CorridorEnableDisable
): Promise<{ success: boolean }> {
const route = await prisma.settlementRoute.findUnique({
where: { routeId: request.routeId },
});
if (!route) {
throw new Error('Route not found');
}
await adminAuditService.logAction({
employeeId,
action: request.action === 'enable' ? 'enable_corridor' : 'disable_corridor',
permission: AdminPermission.CORRIDOR_ENABLE_DISABLE,
resourceType: 'settlement_route',
resourceId: request.routeId,
beforeState: { status: route.status },
afterState: { status: request.action === 'enable' ? 'active' : 'inactive' },
metadata: request,
});
await prisma.settlementRoute.update({
where: { routeId: request.routeId },
data: {
status: request.action === 'enable' ? 'active' : 'inactive',
},
});
return { success: true };
}
}
export const corridorControlsService = new CorridorControlsService();

View File

@@ -0,0 +1,183 @@
// DBIS Admin Console - GRU Controls Service
// GRU issuance, locks, circuit breakers, bond issuance windows
import prisma from '@/shared/database/prisma';
import { logger } from '@/infrastructure/monitoring/logger';
import { v4 as uuidv4 } from 'uuid';
import { adminAuditService } from '@/core/admin/shared/admin-audit.service';
import { AdminPermission } from '@/core/admin/shared/permissions.constants';
export interface GRUIssuanceProposal {
gruClass: string; // M00, M0, M1, SR-1, SR-2, SR-3
amount: number;
reason: string;
effectiveDate?: Date;
}
export interface GRULockRequest {
gruClass: string;
action: 'lock' | 'unlock';
reason: string;
}
export interface GRUCircuitBreakerConfig {
indexId: string;
maxIntradayMove: number; // e.g., 0.05 for 5%
enabled: boolean;
}
export interface GRUBondIssuanceWindow {
bondId: string;
action: 'open' | 'close';
reason?: string;
}
export class GRUControlsService {
/**
* Create GRU issuance proposal
*/
async createIssuanceProposal(
employeeId: string,
proposal: GRUIssuanceProposal
): Promise<{ proposalId: string; status: string }> {
// Log action
await adminAuditService.logAction({
employeeId,
action: 'create_gru_issuance_proposal',
permission: AdminPermission.GRU_ISSUANCE_PROPOSAL,
resourceType: 'gru_issuance',
metadata: proposal,
});
// Create proposal (would go through governance workflow)
const proposalId = uuidv4();
logger.info('GRU issuance proposal created', {
proposalId,
employeeId,
proposal,
});
return {
proposalId,
status: 'pending_governance_approval',
};
}
/**
* Lock or unlock GRU class
*/
async lockUnlockGRUClass(
employeeId: string,
request: GRULockRequest
): Promise<{ success: boolean; message: string }> {
await adminAuditService.logAction({
employeeId,
action: request.action === 'lock' ? 'lock_gru_class' : 'unlock_gru_class',
permission: AdminPermission.GRU_LOCK_UNLOCK,
resourceType: 'gru_class',
resourceId: request.gruClass,
metadata: request,
});
// Update GRU unit status (placeholder - would need proper implementation)
logger.info('GRU class lock/unlock', {
employeeId,
request,
});
return {
success: true,
message: `GRU class ${request.gruClass} ${request.action === 'lock' ? 'locked' : 'unlocked'}`,
};
}
/**
* Set circuit breakers for GRU index
*/
async setCircuitBreakers(
employeeId: string,
config: GRUCircuitBreakerConfig
): Promise<{ success: boolean }> {
await adminAuditService.logAction({
employeeId,
action: 'set_gru_circuit_breakers',
permission: AdminPermission.GRU_CIRCUIT_BREAKERS,
resourceType: 'gru_index',
resourceId: config.indexId,
beforeState: {},
afterState: config,
});
// Update GRU index
await prisma.gruIndex.updateMany({
where: { indexId: config.indexId },
data: {
circuitBreakerEnabled: config.enabled,
circuitBreakerThreshold: config.maxIntradayMove,
},
});
return { success: true };
}
/**
* Open or close GRU bond issuance window
*/
async manageBondIssuanceWindow(
employeeId: string,
request: GRUBondIssuanceWindow
): Promise<{ success: boolean }> {
await adminAuditService.logAction({
employeeId,
action: request.action === 'open' ? 'open_bond_issuance_window' : 'close_bond_issuance_window',
permission: AdminPermission.GRU_BOND_ISSUANCE_WINDOW,
resourceType: 'gru_bond',
resourceId: request.bondId,
metadata: request,
});
// Update bond
await prisma.gruBond.updateMany({
where: { bondId: request.bondId },
data: {
issuanceWindowOpen: request.action === 'open',
},
});
return { success: true };
}
/**
* Trigger emergency buy-back
*/
async triggerEmergencyBuyback(
employeeId: string,
bondId: string,
amount: number
): Promise<{ success: boolean; transactionId: string }> {
await adminAuditService.logAction({
employeeId,
action: 'trigger_emergency_buyback',
permission: AdminPermission.GRU_BOND_BUYBACK,
resourceType: 'gru_bond',
resourceId: bondId,
metadata: { amount },
});
// Would require multi-sig/governance confirmation in production
const transactionId = uuidv4();
logger.warn('Emergency buy-back triggered', {
employeeId,
bondId,
amount,
transactionId,
});
return { success: true, transactionId };
}
}
export const gruControlsService = new GRUControlsService();

View File

@@ -0,0 +1,110 @@
// DBIS Admin Console - Network Controls Service
// Subsystem quiesce, kill-switches, incident escalation
import { logger } from '@/infrastructure/monitoring/logger';
import { adminAuditService } from '@/core/admin/shared/admin-audit.service';
import { AdminPermission } from '@/core/admin/shared/permissions.constants';
export interface SubsystemQuiesceRequest {
subsystem: string; // GAS, QPS, Ω-Layer, GPN, GRU Engine, Metaverse MEN, 6G Edge Grid
action: 'quiesce' | 'resume';
reason: string;
}
export interface KillSwitchRequest {
scope: 'global' | 'scb' | 'corridor';
targetId?: string; // SCB ID or corridor ID if scope is not global
reason: string;
}
export interface IncidentEscalation {
incidentId: string;
priority: 'low' | 'medium' | 'high' | 'critical';
assignTo?: string;
notes?: string;
}
export class NetworkControlsService {
/**
* Quiesce or resume subsystem
*/
async quiesceSubsystem(
employeeId: string,
request: SubsystemQuiesceRequest
): Promise<{ success: boolean; message: string }> {
await adminAuditService.logAction({
employeeId,
action: request.action === 'quiesce' ? 'quiesce_subsystem' : 'resume_subsystem',
permission: AdminPermission.NETWORK_QUIESCE_SUBSYSTEM,
resourceType: 'network_subsystem',
resourceId: request.subsystem,
metadata: request,
});
// Would integrate with actual subsystem control
logger.warn('Subsystem quiesce/resume', {
employeeId,
request,
});
return {
success: true,
message: `Subsystem ${request.subsystem} ${request.action === 'quiesce' ? 'quiesced' : 'resumed'}`,
};
}
/**
* Activate kill switch
*/
async activateKillSwitch(
employeeId: string,
request: KillSwitchRequest
): Promise<{ success: boolean; killSwitchId: string }> {
await adminAuditService.logAction({
employeeId,
action: 'activate_kill_switch',
permission: AdminPermission.NETWORK_KILL_SWITCH,
resourceType: 'network',
resourceId: request.targetId || 'global',
metadata: request,
});
// Critical action - would require additional confirmation in production
logger.error('KILL SWITCH ACTIVATED', {
employeeId,
request,
});
return {
success: true,
killSwitchId: `killswitch-${Date.now()}`,
};
}
/**
* Escalate incident
*/
async escalateIncident(
employeeId: string,
escalation: IncidentEscalation
): Promise<{ success: boolean }> {
await adminAuditService.logAction({
employeeId,
action: 'escalate_incident',
permission: AdminPermission.NETWORK_ESCALATE_INCIDENT,
resourceType: 'incident',
resourceId: escalation.incidentId,
metadata: escalation,
});
logger.info('Incident escalated', {
employeeId,
escalation,
});
return { success: true };
}
}
export const networkControlsService = new NetworkControlsService();

View File

@@ -0,0 +1,225 @@
// DBIS Admin Console - CBDC & FX Service
// CBDC wallet schemas, FX/GRU/SSU routing
import prisma from '@/shared/database/prisma';
import { logger } from '@/infrastructure/monitoring/logger';
import Decimal from 'decimal.js';
export interface CBDCSchema {
scbId: string;
scbName: string;
cbdcTypes: Array<{
type: string; // rCBDC, wCBDC, iCBDC
status: 'active' | 'pending' | 'suspended';
inCirculation: number;
}>;
crossBorderCorridors: Array<{
targetSCB: string;
settlementAsset: string; // SSU, GRU
status: 'active' | 'pending';
}>;
}
export interface FXRouting {
corridors: Array<{
sourceSCB: string;
destinationSCB: string;
preferredSettlementAsset: string;
volume24h: number;
spreads: {
min: number;
max: number;
};
fees: {
min: number;
max: number;
};
circuitBreakers: {
enabled: boolean;
volatilityThreshold: number;
};
}>;
ssuUsage: {
totalVolume: number;
activeCorridors: number;
};
gruBridgeUsage: {
totalVolume: number;
activeCorridors: number;
};
}
export interface CBDCFXDashboard {
cbdcSchemas: CBDCSchema[];
fxRouting: FXRouting;
}
export class CBDCFXService {
/**
* Get CBDC & FX dashboard
*/
async getCBDCFXDashboard(): Promise<CBDCFXDashboard> {
const [cbdcSchemas, fxRouting] = await Promise.all([
this.getCBDCSchemas(),
this.getFXRouting(),
]);
return { cbdcSchemas, fxRouting };
}
/**
* Get CBDC schemas across all SCBs
*/
async getCBDCSchemas(): Promise<CBDCSchema[]> {
const scbs = await prisma.sovereignBank.findMany({
where: { status: 'active' },
});
const schemas: CBDCSchema[] = [];
for (const scb of scbs) {
// Get CBDC issuances
const issuances = await prisma.cbdcIssuance.findMany({
where: { sovereignBankId: scb.id },
});
// Get CBDC wallets
const wallets = await prisma.cbdcWallet.findMany({
where: { sovereignBankId: scb.id },
});
// Group by type
const cbdcTypes = [
{
type: 'rCBDC',
status: 'active' as const,
inCirculation: wallets
.filter((w) => w.walletType === 'retail')
.reduce((sum, w) => sum.plus(w.balance), new Decimal(0))
.toNumber(),
},
{
type: 'wCBDC',
status: 'active' as const,
inCirculation: wallets
.filter((w) => w.walletType === 'wholesale')
.reduce((sum, w) => sum.plus(w.balance), new Decimal(0))
.toNumber(),
},
{
type: 'iCBDC',
status: 'active' as const,
inCirculation: wallets
.filter((w) => w.walletType === 'institutional')
.reduce((sum, w) => sum.plus(w.balance), new Decimal(0))
.toNumber(),
},
];
// Get cross-border corridors
const routes = await prisma.settlementRoute.findMany({
where: {
OR: [{ sourceBankId: scb.id }, { destinationBankId: scb.id }],
status: 'active',
},
});
const crossBorderCorridors = routes.map((route) => ({
targetSCB: route.sourceBankId === scb.id ? route.destinationBankId : route.sourceBankId,
settlementAsset: 'SSU', // Default, would check actual usage
status: 'active' as const,
}));
schemas.push({
scbId: scb.id,
scbName: scb.name,
cbdcTypes,
crossBorderCorridors,
});
}
return schemas;
}
/**
* Get FX routing information
*/
async getFXRouting(): Promise<FXRouting> {
const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);
// Get all active routes
const routes = await prisma.settlementRoute.findMany({
where: { status: 'active' },
});
// Get FX trades
const fxTrades = await prisma.fxTrade.findMany({
where: {
createdAt: { gte: oneDayAgo },
},
});
// Get SSU transactions
const ssuTransactions = await prisma.ssuTransaction.findMany({
where: {
createdAt: { gte: oneDayAgo },
status: 'completed',
},
});
const ssuVolume = ssuTransactions.reduce(
(sum, t) => sum.plus(t.amount),
new Decimal(0)
).toNumber();
// Build corridors
const corridors = routes.map((route) => {
const routeTrades = fxTrades.filter(
(t) =>
(t.sovereignBankId === route.sourceBankId ||
t.sovereignBankId === route.destinationBankId) &&
t.baseCurrency === route.currencyCode
);
const volume24h = routeTrades
.filter((t) => t.status === 'executed')
.reduce((sum, t) => sum.plus(t.quantity), new Decimal(0))
.toNumber();
return {
sourceSCB: route.sourceBankId,
destinationSCB: route.destinationBankId,
preferredSettlementAsset: 'SSU', // Default
volume24h,
spreads: {
min: 0.0001,
max: 0.01,
},
fees: {
min: 0.001,
max: 0.05,
},
circuitBreakers: {
enabled: true,
volatilityThreshold: 0.05, // 5%
},
};
});
return {
corridors,
ssuUsage: {
totalVolume: ssuVolume,
activeCorridors: new Set(routes.map((r) => `${r.sourceBankId}-${r.destinationBankId}`))
.size,
},
gruBridgeUsage: {
totalVolume: 0, // Would calculate from GRU transactions
activeCorridors: 0,
},
};
}
}
export const cbdcFxService = new CBDCFXService();

View File

@@ -0,0 +1,176 @@
// DBIS Admin Console - GAS & QPS Control Service
// GAS atomic settlement control, QPS legacy rails management
import prisma from '@/shared/database/prisma';
import { logger } from '@/infrastructure/monitoring/logger';
import Decimal from 'decimal.js';
export interface GASMetrics {
atomicSettlementSuccessRate: number;
averageLatency: number;
perAssetBreakdown: {
currency: { successRate: number; volume: number };
cbdc: { successRate: number; volume: number };
commodity: { successRate: number; volume: number };
security: { successRate: number; volume: number };
};
assetLevelLimits: Array<{
assetClass: string;
maxNotionalPerSCB: number;
}>;
}
export interface QPSMetrics {
legacyRails: Array<{
railType: string; // SWIFT, ISO20022, RTGS
enabled: boolean;
volume24h: number;
errorRate: number;
}>;
mappingProfiles: Array<{
profileId: string;
profileName: string;
acceptedMessages: string[];
validationLevel: string;
}>;
}
export interface GASQPSDashboard {
gas: GASMetrics;
qps: QPSMetrics;
}
export class GASQPSService {
/**
* Get GAS & QPS dashboard
*/
async getGASQPSDashboard(): Promise<GASQPSDashboard> {
const [gas, qps] = await Promise.all([this.getGASMetrics(), this.getQPSMetrics()]);
return { gas, qps };
}
/**
* Get GAS metrics
*/
async getGASMetrics(): Promise<GASMetrics> {
const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);
// Get all atomic settlements in last 24 hours
const settlements = await prisma.atomicSettlement.findMany({
where: {
createdAt: { gte: oneDayAgo },
},
});
const total = settlements.length;
const successful = settlements.filter((s) => s.status === 'settled').length;
const successRate = total > 0 ? successful / total : 1.0;
// Calculate average latency
const settledSettlements = settlements.filter((s) => s.status === 'settled' && s.settlementTime);
const avgLatency =
settledSettlements.length > 0
? settledSettlements.reduce((sum, s) => sum + (s.settlementTime || 0), 0) /
settledSettlements.length
: 0;
// Per asset breakdown
const perAssetBreakdown = {
currency: { successRate: 0, volume: 0 },
cbdc: { successRate: 0, volume: 0 },
commodity: { successRate: 0, volume: 0 },
security: { successRate: 0, volume: 0 },
};
['currency', 'cbdc', 'commodity', 'security'].forEach((assetType) => {
const assetSettlements = settlements.filter((s) => s.assetType === assetType);
const assetSuccessful = assetSettlements.filter((s) => s.status === 'settled').length;
const assetVolume = assetSettlements
.filter((s) => s.status === 'settled')
.reduce((sum, s) => sum.plus(s.amount), new Decimal(0))
.toNumber();
perAssetBreakdown[assetType as keyof typeof perAssetBreakdown] = {
successRate: assetSettlements.length > 0 ? assetSuccessful / assetSettlements.length : 0,
volume: assetVolume,
};
});
// Asset level limits (placeholder - would come from configuration)
const assetLevelLimits = [
{ assetClass: 'currency', maxNotionalPerSCB: 1000000000 },
{ assetClass: 'cbdc', maxNotionalPerSCB: 500000000 },
{ assetClass: 'commodity', maxNotionalPerSCB: 200000000 },
{ assetClass: 'security', maxNotionalPerSCB: 1000000000 },
];
return {
atomicSettlementSuccessRate: successRate,
averageLatency: avgLatency,
perAssetBreakdown,
assetLevelLimits,
};
}
/**
* Get QPS metrics
*/
async getQPSMetrics(): Promise<QPSMetrics> {
const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);
// Get ISO 20022 messages (QPS)
const isoMessages = await prisma.isoMessage.findMany({
where: {
createdAt: { gte: oneDayAgo },
},
});
// Group by message type
const messageTypes = new Map<string, number>();
isoMessages.forEach((msg) => {
const count = messageTypes.get(msg.messageType) || 0;
messageTypes.set(msg.messageType, count + 1);
});
// Legacy rails (placeholder - would need actual QPS integration)
const legacyRails = [
{
railType: 'SWIFT',
enabled: true,
volume24h: isoMessages.filter((m) => m.messageType.includes('SWIFT')).length,
errorRate: 0.01,
},
{
railType: 'ISO20022',
enabled: true,
volume24h: isoMessages.length,
errorRate: 0.005,
},
{
railType: 'RTGS',
enabled: true,
volume24h: 0,
errorRate: 0,
},
];
// Mapping profiles (placeholder)
const mappingProfiles = [
{
profileId: 'default',
profileName: 'Default ISO 20022 Profile',
acceptedMessages: Array.from(messageTypes.keys()),
validationLevel: 'standard',
},
];
return {
legacyRails,
mappingProfiles,
};
}
}
export const gasQpsService = new GASQPSService();

View File

@@ -0,0 +1,356 @@
// DBIS Admin Console - Global Overview Dashboard Service
// Network health, settlement throughput, GRU & liquidity, risk flags, SCB status
import prisma from '@/shared/database/prisma';
import { logger } from '@/infrastructure/monitoring/logger';
import { dashboardService } from '@/core/compliance/regtech/dashboard.service';
import Decimal from 'decimal.js';
export interface NetworkHealthStatus {
subsystem: string;
status: 'healthy' | 'degraded' | 'down';
lastHeartbeat?: Date;
latency?: number;
errorRate?: number;
}
export interface SettlementThroughput {
txPerSecond: number;
dailyVolume: number;
byAssetType: {
fiat: number;
cbdc: number;
gru: number;
ssu: number;
commodities: number;
};
heatmap: Array<{
sourceSCB: string;
destinationSCB: string;
volume: number;
}>;
}
export interface GRULiquidityMetrics {
currentPrice: number;
volatility: number;
inCirculation: {
m00: number;
m0: number;
m1: number;
sr1: number;
sr2: number;
sr3: number;
};
}
export interface RiskFlags {
high: number;
medium: number;
low: number;
alerts: Array<{
id: string;
type: string;
severity: string;
description: string;
timestamp: Date;
}>;
}
export interface SCBStatus {
scbId: string;
name: string;
country: string;
bic?: string;
status: string;
connectivity: 'connected' | 'degraded' | 'disconnected';
latency?: number;
errorRate?: number;
openIncidents: number;
}
export interface GlobalOverviewDashboard {
networkHealth: NetworkHealthStatus[];
settlementThroughput: SettlementThroughput;
gruLiquidity: GRULiquidityMetrics;
riskFlags: RiskFlags;
scbStatus: SCBStatus[];
}
export class GlobalOverviewService {
/**
* Get global overview dashboard
*/
async getGlobalOverview(): Promise<GlobalOverviewDashboard> {
const [networkHealth, settlementThroughput, gruLiquidity, riskFlags, scbStatus] =
await Promise.all([
this.getNetworkHealth(),
this.getSettlementThroughput(),
this.getGRULiquidity(),
this.getRiskFlags(),
this.getSCBStatus(),
]);
return {
networkHealth,
settlementThroughput,
gruLiquidity,
riskFlags,
scbStatus,
};
}
/**
* Get network health status for all subsystems
*/
async getNetworkHealth(): Promise<NetworkHealthStatus[]> {
const subsystems: NetworkHealthStatus[] = [];
// GAS (Global Atomic Settlement)
try {
const gasSettlements = await prisma.atomicSettlement.findMany({
where: {
createdAt: {
gte: new Date(Date.now() - 5 * 60 * 1000), // Last 5 minutes
},
},
take: 100,
});
const successRate =
gasSettlements.length > 0
? gasSettlements.filter((s) => s.status === 'settled').length /
gasSettlements.length
: 1.0;
subsystems.push({
subsystem: 'GAS',
status: successRate > 0.95 ? 'healthy' : successRate > 0.8 ? 'degraded' : 'down',
errorRate: 1 - successRate,
});
} catch (error) {
logger.error('Error getting GAS health', { error });
subsystems.push({ subsystem: 'GAS', status: 'down' });
}
// QPS (Quantum Payment System) - placeholder
subsystems.push({
subsystem: 'QPS',
status: 'healthy',
});
// Ω-Layer (Omega Layer) - placeholder
subsystems.push({
subsystem: 'Ω-Layer',
status: 'healthy',
});
// GPN (Global Payment Network) - placeholder
subsystems.push({
subsystem: 'GPN',
status: 'healthy',
});
// GRU Engine - placeholder
subsystems.push({
subsystem: 'GRU Engine',
status: 'healthy',
});
// Metaverse MEN - placeholder
subsystems.push({
subsystem: 'Metaverse MEN',
status: 'healthy',
});
// 6G Edge Grid - placeholder
subsystems.push({
subsystem: '6G Edge Grid',
status: 'healthy',
});
return subsystems;
}
/**
* Get settlement throughput metrics
*/
async getSettlementThroughput(): Promise<SettlementThroughput> {
const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);
const oneMinuteAgo = new Date(Date.now() - 60 * 1000);
// Get all settlements in last 24 hours
const settlements = await prisma.atomicSettlement.findMany({
where: {
createdAt: {
gte: oneDayAgo,
},
},
});
// Get settlements in last minute for tx/sec
const recentSettlements = settlements.filter(
(s) => s.createdAt >= oneMinuteAgo
);
const txPerSecond = recentSettlements.length / 60;
// Calculate daily volume
const dailyVolume = settlements
.filter((s) => s.status === 'settled')
.reduce((sum, s) => sum.plus(s.amount), new Decimal(0))
.toNumber();
// Group by asset type
const byAssetType = {
fiat: 0,
cbdc: 0,
gru: 0,
ssu: 0,
commodities: 0,
};
settlements.forEach((s) => {
if (s.assetType === 'currency') byAssetType.fiat += parseFloat(s.amount.toString());
else if (s.assetType === 'cbdc') byAssetType.cbdc += parseFloat(s.amount.toString());
else if (s.assetType === 'commodity') byAssetType.commodities += parseFloat(s.amount.toString());
// GRU and SSU would need additional queries
});
// Heatmap: top corridors by volume
const corridorMap = new Map<string, number>();
settlements.forEach((s) => {
if (s.status === 'settled') {
const key = `${s.sourceBankId}-${s.destinationBankId}`;
const current = corridorMap.get(key) || 0;
corridorMap.set(key, current + parseFloat(s.amount.toString()));
}
});
const heatmap = Array.from(corridorMap.entries())
.map(([key, volume]) => {
const [source, dest] = key.split('-');
return { sourceSCB: source, destinationSCB: dest, volume };
})
.sort((a, b) => b.volume - a.volume)
.slice(0, 20); // Top 20
return {
txPerSecond,
dailyVolume,
byAssetType,
heatmap,
};
}
/**
* Get GRU & liquidity metrics
*/
async getGRULiquidity(): Promise<GRULiquidityMetrics> {
// Get GRU units
const gruUnits = await prisma.gruUnit.findMany({
where: { status: 'active' },
});
// Calculate in circulation by class
const inCirculation = {
m00: 0,
m0: 0,
m1: 0,
sr1: 0,
sr2: 0,
sr3: 0,
};
// Get GRU indexes for price
const indexes = await prisma.gruIndex.findMany({
where: { status: 'active' },
include: { priceHistory: { orderBy: { timestamp: 'desc' }, take: 2 } },
});
let currentPrice = 1.0; // Default
let volatility = 0.0;
if (indexes.length > 0 && indexes[0].priceHistory.length >= 2) {
const [latest, previous] = indexes[0].priceHistory;
currentPrice = parseFloat(latest.price.toString());
const prevPrice = parseFloat(previous.price.toString());
volatility = Math.abs((currentPrice - prevPrice) / prevPrice);
}
return {
currentPrice,
volatility,
inCirculation,
};
}
/**
* Get risk flags and alerts
*/
async getRiskFlags(): Promise<RiskFlags> {
const dashboard = await dashboardService.getIncidentAlertsDashboard();
const alerts = dashboard.incidentAlerts || [];
const high = alerts.filter((a) => a.severity === 'critical' || a.severity === 'high').length;
const medium = alerts.filter((a) => a.severity === 'medium').length;
const low = alerts.filter((a) => a.severity === 'low').length;
return {
high,
medium,
low,
alerts: alerts.slice(0, 10), // Top 10
};
}
/**
* Get SCB status table
*/
async getSCBStatus(): Promise<SCBStatus[]> {
const scbs = await prisma.sovereignBank.findMany({
where: { status: { in: ['active', 'suspended'] } },
});
const scbStatus: SCBStatus[] = [];
for (const scb of scbs) {
// Get recent settlements to determine connectivity
const recentSettlements = await prisma.atomicSettlement.findMany({
where: {
OR: [{ sourceBankId: scb.id }, { destinationBankId: scb.id }],
createdAt: {
gte: new Date(Date.now() - 5 * 60 * 1000), // Last 5 minutes
},
},
take: 10,
});
const connectivity =
recentSettlements.length > 0 ? 'connected' : 'degraded';
// Get open incidents (SRI enforcements)
const openIncidents = await prisma.sRIEnforcement.count({
where: {
sovereignBankId: scb.id,
status: 'active',
},
});
scbStatus.push({
scbId: scb.id,
name: scb.name,
country: scb.sovereignCode,
bic: scb.bic || undefined,
status: scb.status,
connectivity,
openIncidents,
});
}
return scbStatus;
}
}
export const globalOverviewService = new GlobalOverviewService();

View File

@@ -0,0 +1,224 @@
// DBIS Admin Console - GRU Command Center Service
// GRU Monetary, Indexes, Bonds, Supranational Pools
import prisma from '@/shared/database/prisma';
import { logger } from '@/infrastructure/monitoring/logger';
import Decimal from 'decimal.js';
export interface GRUMonetaryMetrics {
supply: {
m00: number;
m0: number;
m1: number;
sr1: number;
sr2: number;
sr3: number;
};
locked: {
m00: boolean;
m0: boolean;
m1: boolean;
sr1: boolean;
sr2: boolean;
sr3: boolean;
};
}
export interface GRUIndexInfo {
indexId: string;
indexName: string;
indexCode: string; // LiXAU, LiPMG, LiBMG1-3
currentPrice: number;
components: Array<{
asset: string;
weight: number;
}>;
priceHistory: Array<{
timestamp: Date;
price: number;
}>;
circuitBreakers: {
maxIntradayMove: number;
enabled: boolean;
};
}
export interface GRUBondInfo {
bondId: string;
bondName: string;
bondCode: string; // Li99PpOsB10, Li99PpAvB10
outstanding: number;
buyers: number;
yield: number;
issuanceWindow: 'open' | 'closed';
primaryMarketParams: Record<string, unknown>;
}
export interface GRUSupranationalPool {
poolId: string;
poolName: string;
totalReserves: number;
allocations: Array<{
reserveClass: string;
amount: number;
}>;
}
export interface GRUCommandDashboard {
monetary: GRUMonetaryMetrics;
indexes: GRUIndexInfo[];
bonds: GRUBondInfo[];
supranationalPools: GRUSupranationalPool[];
}
export class GRUCommandService {
/**
* Get GRU command center dashboard
*/
async getGRUCommandDashboard(): Promise<GRUCommandDashboard> {
const [monetary, indexes, bonds, supranationalPools] = await Promise.all([
this.getGRUMonetary(),
this.getGRUIndexes(),
this.getGRUBonds(),
this.getGRUSupranationalPools(),
]);
return {
monetary,
indexes,
bonds,
supranationalPools,
};
}
/**
* Get GRU monetary metrics
*/
async getGRUMonetary(): Promise<GRUMonetaryMetrics> {
// Get all GRU units
const gruUnits = await prisma.gruUnit.findMany({
where: { status: 'active' },
});
// Calculate supply by class (placeholder - would need proper aggregation)
const supply = {
m00: 0,
m0: 0,
m1: 0,
sr1: 0,
sr2: 0,
sr3: 0,
};
// Check locked status (placeholder)
const locked = {
m00: false,
m0: false,
m1: false,
sr1: false,
sr2: false,
sr3: false,
};
return { supply, locked };
}
/**
* Get GRU indexes
*/
async getGRUIndexes(): Promise<GRUIndexInfo[]> {
const indexes = await prisma.gruIndex.findMany({
where: { status: 'active' },
include: {
priceHistory: {
orderBy: { timestamp: 'desc' },
take: 100,
},
},
});
return indexes.map((index) => ({
indexId: index.indexId,
indexName: index.indexName,
indexCode: index.indexCode,
currentPrice: index.priceHistory.length > 0
? parseFloat(index.priceHistory[0].price.toString())
: 0,
components: (index.components as Array<{ asset: string; weight: number }>) || [],
priceHistory: index.priceHistory.map((ph) => ({
timestamp: ph.timestamp,
price: parseFloat(ph.price.toString()),
})),
circuitBreakers: {
maxIntradayMove: parseFloat(index.circuitBreakerThreshold?.toString() || '0.1'),
enabled: index.circuitBreakerEnabled || false,
},
}));
}
/**
* Get GRU bonds
*/
async getGRUBonds(): Promise<GRUBondInfo[]> {
const bonds = await prisma.gruBond.findMany({
where: { status: 'active' },
include: {
coupons: true,
pricing: {
orderBy: { calculatedAt: 'desc' },
take: 1,
},
},
});
return bonds.map((bond) => {
const latestPricing = bond.pricing[0];
const yieldValue = latestPricing
? parseFloat(latestPricing.yield.toString())
: 0;
return {
bondId: bond.bondId,
bondName: bond.bondName,
bondCode: bond.bondCode,
outstanding: parseFloat(bond.outstandingAmount.toString()),
buyers: bond.numberOfHolders || 0,
yield: yieldValue,
issuanceWindow: bond.issuanceWindowOpen ? 'open' : 'closed',
primaryMarketParams: {
minPurchase: parseFloat(bond.minPurchaseAmount?.toString() || '0'),
maxPurchase: parseFloat(bond.maxPurchaseAmount?.toString() || '0'),
},
};
});
}
/**
* Get GRU supranational pools
*/
async getGRUSupranationalPools(): Promise<GRUSupranationalPool[]> {
const pools = await prisma.gruReservePool.findMany({
where: { status: 'active' },
include: {
allocations: {
include: {
reserveClass: true,
},
},
},
});
return pools.map((pool) => ({
poolId: pool.poolId,
poolName: pool.poolName,
totalReserves: parseFloat(pool.totalReserves.toString()),
allocations: pool.allocations.map((alloc) => ({
reserveClass: alloc.reserveClass.className,
amount: parseFloat(alloc.amount.toString()),
})),
}));
}
}
export const gruCommandService = new GRUCommandService();

View File

@@ -0,0 +1,119 @@
// DBIS Admin Console - Metaverse & Edge Service
// Metaverse Nodes (MEN), 6G Edge GPU Grid
import prisma from '@/shared/database/prisma';
import { logger } from '@/infrastructure/monitoring/logger';
export interface MetaverseNode {
nodeId: string;
nodeName: string;
location: string;
status: 'active' | 'degraded' | 'down';
activeVolumes: number;
onRamps: Array<{
scbId: string;
enabled: boolean;
volume24h: number;
}>;
kycEnforcementLevel: 'low' | 'medium' | 'high';
limits: {
dailyLimit: number;
perTransactionLimit: number;
};
}
export interface EdgeNode {
regionId: string;
regionName: string;
nodeCount: number;
occupancy: number; // 0-100
latency: number;
priority: 'settlement' | 'rendering' | 'balanced';
status: 'active' | 'quarantined' | 'draining';
}
export interface MetaverseEdgeDashboard {
metaverseNodes: MetaverseNode[];
edgeNodes: EdgeNode[];
}
export class MetaverseEdgeService {
/**
* Get Metaverse & Edge dashboard
*/
async getMetaverseEdgeDashboard(): Promise<MetaverseEdgeDashboard> {
const [metaverseNodes, edgeNodes] = await Promise.all([
this.getMetaverseNodes(),
this.getEdgeNodes(),
]);
return { metaverseNodes, edgeNodes };
}
/**
* Get Metaverse nodes
*/
async getMetaverseNodes(): Promise<MetaverseNode[]> {
// Placeholder - would integrate with actual metaverse system
const nodes: MetaverseNode[] = [
{
nodeId: 'metaverse-dubai',
nodeName: 'MetaverseDubai',
location: 'Dubai',
status: 'active',
activeVolumes: 0,
onRamps: [],
kycEnforcementLevel: 'medium',
limits: {
dailyLimit: 1000000,
perTransactionLimit: 10000,
},
},
];
// Get SCBs to populate on-ramps
const scbs = await prisma.sovereignBank.findMany({
where: { status: 'active' },
take: 10,
});
nodes.forEach((node) => {
node.onRamps = scbs.map((scb) => ({
scbId: scb.id,
enabled: true,
volume24h: 0, // Would calculate from actual transactions
}));
});
return nodes;
}
/**
* Get 6G Edge GPU Grid nodes
*/
async getEdgeNodes(): Promise<EdgeNode[]> {
// Placeholder - would integrate with actual edge compute system
// 325 region nodes as mentioned in spec
const regions = [
{ id: 'region-001', name: 'North America East', nodeCount: 25 },
{ id: 'region-002', name: 'North America West', nodeCount: 20 },
{ id: 'region-003', name: 'Europe Central', nodeCount: 30 },
{ id: 'region-004', name: 'Asia Pacific', nodeCount: 40 },
{ id: 'region-005', name: 'Middle East', nodeCount: 15 },
// ... would have 325 total
];
return regions.map((region) => ({
regionId: region.id,
regionName: region.name,
nodeCount: region.nodeCount,
occupancy: Math.random() * 100, // Placeholder
latency: Math.random() * 100, // Placeholder
priority: 'balanced' as const,
status: 'active' as const,
}));
}
}
export const metaverseEdgeService = new MetaverseEdgeService();

View File

@@ -0,0 +1,218 @@
// DBIS Admin Console - Participants & Jurisdictions Service
// SCB directory, jurisdiction settings, corridor management
import prisma from '@/shared/database/prisma';
import { logger } from '@/infrastructure/monitoring/logger';
import Decimal from 'decimal.js';
export interface ParticipantInfo {
scbId: string;
name: string;
country: string;
bic?: string;
lei?: string;
status: string;
connectivity: 'connected' | 'degraded' | 'disconnected';
lastHeartbeat?: Date;
latency?: number;
errorRate?: number;
}
export interface JurisdictionSettings {
scbId: string;
allowedAssetClasses: string[];
corridorRules: Array<{
targetSCB: string;
caps: number;
allowedSettlementAssets: string[];
}>;
regulatoryProfiles: {
amlStrictness: 'low' | 'medium' | 'high';
sanctionsLists: string[];
reportingFrequency: string;
};
}
export interface CorridorInfo {
routeId: string;
sourceSCB: string;
destinationSCB: string;
currencyCode: string;
status: string;
volume24h: number;
latency: number;
errorRate: number;
}
export class ParticipantsService {
/**
* Get participant directory
*/
async getParticipantDirectory(): Promise<ParticipantInfo[]> {
const scbs = await prisma.sovereignBank.findMany({
orderBy: { name: 'asc' },
});
const participants: ParticipantInfo[] = [];
for (const scb of scbs) {
// Get recent activity to determine connectivity
const recentSettlements = await prisma.atomicSettlement.findMany({
where: {
OR: [{ sourceBankId: scb.id }, { destinationBankId: scb.id }],
createdAt: {
gte: new Date(Date.now() - 5 * 60 * 1000),
},
},
take: 10,
});
const connectivity =
recentSettlements.length > 0 ? 'connected' : 'degraded';
participants.push({
scbId: scb.id,
name: scb.name,
country: scb.sovereignCode,
bic: scb.bic || undefined,
lei: scb.lei || undefined,
status: scb.status,
connectivity,
lastHeartbeat: scb.updatedAt,
});
}
return participants;
}
/**
* Get participant details
*/
async getParticipantDetails(scbId: string): Promise<ParticipantInfo | null> {
const scb = await prisma.sovereignBank.findUnique({
where: { id: scbId },
});
if (!scb) {
return null;
}
const recentSettlements = await prisma.atomicSettlement.findMany({
where: {
OR: [{ sourceBankId: scb.id }, { destinationBankId: scb.id }],
createdAt: {
gte: new Date(Date.now() - 5 * 60 * 1000),
},
},
take: 100,
});
const successCount = recentSettlements.filter((s) => s.status === 'settled').length;
const errorRate = recentSettlements.length > 0 ? 1 - successCount / recentSettlements.length : 0;
return {
scbId: scb.id,
name: scb.name,
country: scb.sovereignCode,
bic: scb.bic || undefined,
lei: scb.lei || undefined,
status: scb.status,
connectivity: recentSettlements.length > 0 ? 'connected' : 'degraded',
lastHeartbeat: scb.updatedAt,
errorRate,
};
}
/**
* Get jurisdiction settings for SCB
*/
async getJurisdictionSettings(scbId: string): Promise<JurisdictionSettings | null> {
const scb = await prisma.sovereignBank.findUnique({
where: { id: scbId },
});
if (!scb) {
return null;
}
// Get corridors for this SCB
const routes = await prisma.settlementRoute.findMany({
where: {
OR: [{ sourceBankId: scbId }, { destinationBankId: scbId }],
status: 'active',
},
});
const corridorRules = routes.map((route) => ({
targetSCB: route.sourceBankId === scbId ? route.destinationBankId : route.sourceBankId,
caps: route.sireCost ? parseFloat(route.sireCost.toString()) : 0,
allowedSettlementAssets: [route.currencyCode],
}));
return {
scbId,
allowedAssetClasses: ['FIAT', 'CBDC', 'GRU', 'SSU', 'commodities'],
corridorRules,
regulatoryProfiles: {
amlStrictness: 'medium',
sanctionsLists: ['OFAC', 'EU', 'UN'],
reportingFrequency: 'daily',
},
};
}
/**
* Get all corridors
*/
async getCorridors(): Promise<CorridorInfo[]> {
const routes = await prisma.settlementRoute.findMany({
where: { status: 'active' },
include: {
routingDecisions: {
orderBy: { createdAt: 'desc' },
take: 1,
},
},
});
const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);
const corridors: CorridorInfo[] = [];
for (const route of routes) {
// Get 24h volume
const settlements = await prisma.atomicSettlement.findMany({
where: {
sourceBankId: route.sourceBankId,
destinationBankId: route.destinationBankId,
currencyCode: route.currencyCode,
createdAt: { gte: oneDayAgo },
},
});
const volume24h = settlements
.filter((s) => s.status === 'settled')
.reduce((sum, s) => sum.plus(s.amount), new Decimal(0))
.toNumber();
const successCount = settlements.filter((s) => s.status === 'settled').length;
const errorRate = settlements.length > 0 ? 1 - successCount / settlements.length : 0;
corridors.push({
routeId: route.routeId,
sourceSCB: route.sourceBankId,
destinationSCB: route.destinationBankId,
currencyCode: route.currencyCode,
status: route.status,
volume24h,
latency: route.estimatedLatency || 0,
errorRate,
});
}
return corridors;
}
}
export const participantsService = new ParticipantsService();

View File

@@ -0,0 +1,146 @@
// DBIS Admin Console - Risk & Compliance Service
// SARE, ARI, Ω-Layer consistency
import prisma from '@/shared/database/prisma';
import { logger } from '@/infrastructure/monitoring/logger';
import { dashboardService } from '@/core/compliance/regtech/dashboard.service';
export interface SARERiskHeatmap {
scbId: string;
scbName: string;
riskScore: number;
riskLevel: 'low' | 'medium' | 'high' | 'critical';
factors: Array<{
factor: string;
score: number;
}>;
}
export interface ARIAlert {
alertId: string;
type: string;
severity: 'low' | 'medium' | 'high' | 'critical';
description: string;
scbId?: string;
timestamp: Date;
status: 'new' | 'acknowledged' | 'under_investigation' | 'resolved';
}
export interface OmegaLayerIncident {
incidentId: string;
type: string;
severity: string;
description: string;
affectedSCBs: string[];
timestamp: Date;
status: 'active' | 'resolved';
}
export interface RiskComplianceDashboard {
sareHeatmap: SARERiskHeatmap[];
ariAlerts: ARIAlert[];
omegaLayerIncidents: OmegaLayerIncident[];
}
export class RiskComplianceService {
/**
* Get Risk & Compliance dashboard
*/
async getRiskComplianceDashboard(): Promise<RiskComplianceDashboard> {
const [sareHeatmap, ariAlerts, omegaLayerIncidents] = await Promise.all([
this.getSAREHeatmap(),
this.getARIAlerts(),
this.getOmegaLayerIncidents(),
]);
return { sareHeatmap, ariAlerts, omegaLayerIncidents };
}
/**
* Get SARE sovereign risk heatmap
*/
async getSAREHeatmap(): Promise<SARERiskHeatmap[]> {
const scbs = await prisma.sovereignBank.findMany({
where: { status: 'active' },
});
const heatmap: SARERiskHeatmap[] = [];
for (const scb of scbs) {
// Get latest SRI
const sri = await prisma.sovereignRiskIndex.findFirst({
where: { sovereignBankId: scb.id },
orderBy: { calculatedAt: 'desc' },
});
const riskScore = sri ? parseFloat(sri.sriScore.toString()) : 0;
let riskLevel: 'low' | 'medium' | 'high' | 'critical' = 'low';
if (riskScore >= 60) riskLevel = 'critical';
else if (riskScore >= 40) riskLevel = 'high';
else if (riskScore >= 20) riskLevel = 'medium';
heatmap.push({
scbId: scb.id,
scbName: scb.name,
riskScore,
riskLevel,
factors: [
{ factor: 'liquidity', score: riskScore * 0.3 },
{ factor: 'fx_stability', score: riskScore * 0.25 },
{ factor: 'cbdc_health', score: riskScore * 0.25 },
{ factor: 'commodity_exposure', score: riskScore * 0.2 },
],
});
}
return heatmap.sort((a, b) => b.riskScore - a.riskScore);
}
/**
* Get ARI regulatory alerts
*/
async getARIAlerts(): Promise<ARIAlert[]> {
// Get incident alerts from dashboard service
const dashboard = await dashboardService.getIncidentAlertsDashboard();
const alerts = dashboard.incidentAlerts || [];
return alerts.map((alert, index) => ({
alertId: `ari-${index}`,
type: alert.type,
severity: alert.severity as 'low' | 'medium' | 'high' | 'critical',
description: alert.description,
timestamp: alert.timestamp,
status: 'new' as const,
}));
}
/**
* Get Ω-Layer consistency incidents
*/
async getOmegaLayerIncidents(): Promise<OmegaLayerIncident[]> {
// Placeholder - would integrate with actual Ω-Layer monitoring
// Check for settlement inconsistencies
const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);
const failedSettlements = await prisma.atomicSettlement.findMany({
where: {
status: 'failed',
createdAt: { gte: oneDayAgo },
},
take: 10,
});
return failedSettlements.map((settlement) => ({
incidentId: settlement.settlementId,
type: 'settlement_failure',
severity: 'high',
description: `Settlement ${settlement.settlementId} failed`,
affectedSCBs: [settlement.sourceBankId, settlement.destinationBankId],
timestamp: settlement.createdAt,
status: 'active' as const,
}));
}
}
export const riskComplianceService = new RiskComplianceService();

View File

@@ -0,0 +1,340 @@
// DBIS Admin Console API Routes
import { Router } from 'express';
import { dbisAdminService } from './dbis-admin.service';
import { requireAdminPermission } from '@/integration/api-gateway/middleware/admin-permission.middleware';
import { AdminPermission } from '@/core/admin/shared/permissions.constants';
const router = Router();
// Global Overview Dashboard
router.get(
'/dashboard/overview',
requireAdminPermission(AdminPermission.VIEW_GLOBAL_OVERVIEW),
async (req, res, next) => {
try {
const overview = await dbisAdminService.globalOverview.getGlobalOverview();
res.json(overview);
} catch (error) {
next(error);
}
}
);
// Participants & Jurisdictions
router.get(
'/participants',
requireAdminPermission(AdminPermission.VIEW_PARTICIPANTS),
async (req, res, next) => {
try {
const participants = await dbisAdminService.participants.getParticipantDirectory();
res.json(participants);
} catch (error) {
next(error);
}
}
);
router.get(
'/participants/:scbId',
requireAdminPermission(AdminPermission.VIEW_PARTICIPANTS),
async (req, res, next) => {
try {
const participant = await dbisAdminService.participants.getParticipantDetails(
req.params.scbId
);
if (!participant) {
return res.status(404).json({ error: 'Participant not found' });
}
res.json(participant);
} catch (error) {
next(error);
}
}
);
router.get(
'/participants/:scbId/jurisdiction',
requireAdminPermission(AdminPermission.SCB_JURISDICTION_SETTINGS),
async (req, res, next) => {
try {
const settings = await dbisAdminService.participants.getJurisdictionSettings(
req.params.scbId
);
if (!settings) {
return res.status(404).json({ error: 'Jurisdiction settings not found' });
}
res.json(settings);
} catch (error) {
next(error);
}
}
);
router.get(
'/corridors',
requireAdminPermission(AdminPermission.VIEW_PARTICIPANTS),
async (req, res, next) => {
try {
const corridors = await dbisAdminService.participants.getCorridors();
res.json(corridors);
} catch (error) {
next(error);
}
}
);
// GRU Command Center
router.get(
'/gru/command',
requireAdminPermission(AdminPermission.VIEW_GRU_COMMAND),
async (req, res, next) => {
try {
const dashboard = await dbisAdminService.gruCommand.getGRUCommandDashboard();
res.json(dashboard);
} catch (error) {
next(error);
}
}
);
router.post(
'/gru/issuance/proposal',
requireAdminPermission(AdminPermission.GRU_ISSUANCE_PROPOSAL),
async (req, res, next) => {
try {
const employeeId = req.headers['x-employee-id'] as string || req.sovereignBankId || '';
const result = await dbisAdminService.gruControls.createIssuanceProposal(
employeeId,
req.body
);
res.status(201).json(result);
} catch (error) {
next(error);
}
}
);
router.post(
'/gru/lock',
requireAdminPermission(AdminPermission.GRU_LOCK_UNLOCK),
async (req, res, next) => {
try {
const employeeId = req.headers['x-employee-id'] as string || req.sovereignBankId || '';
const result = await dbisAdminService.gruControls.lockUnlockGRUClass(employeeId, req.body);
res.json(result);
} catch (error) {
next(error);
}
}
);
router.post(
'/gru/circuit-breakers',
requireAdminPermission(AdminPermission.GRU_CIRCUIT_BREAKERS),
async (req, res, next) => {
try {
const employeeId = req.headers['x-employee-id'] as string || req.sovereignBankId || '';
const result = await dbisAdminService.gruControls.setCircuitBreakers(employeeId, req.body);
res.json(result);
} catch (error) {
next(error);
}
}
);
router.post(
'/gru/bonds/window',
requireAdminPermission(AdminPermission.GRU_BOND_ISSUANCE_WINDOW),
async (req, res, next) => {
try {
const employeeId = req.headers['x-employee-id'] as string || req.sovereignBankId || '';
const result = await dbisAdminService.gruControls.manageBondIssuanceWindow(
employeeId,
req.body
);
res.json(result);
} catch (error) {
next(error);
}
}
);
router.post(
'/gru/bonds/buyback',
requireAdminPermission(AdminPermission.GRU_BOND_BUYBACK),
async (req, res, next) => {
try {
const employeeId = req.headers['x-employee-id'] as string || req.sovereignBankId || '';
const { bondId, amount } = req.body;
const result = await dbisAdminService.gruControls.triggerEmergencyBuyback(
employeeId,
bondId,
amount
);
res.json(result);
} catch (error) {
next(error);
}
}
);
// GAS & QPS
router.get(
'/gas-qps',
requireAdminPermission(AdminPermission.VIEW_GAS_QPS),
async (req, res, next) => {
try {
const dashboard = await dbisAdminService.gasQps.getGASQPSDashboard();
res.json(dashboard);
} catch (error) {
next(error);
}
}
);
// CBDC & FX
router.get(
'/cbdc-fx',
requireAdminPermission(AdminPermission.VIEW_CBDC_FX),
async (req, res, next) => {
try {
const dashboard = await dbisAdminService.cbdcFx.getCBDCFXDashboard();
res.json(dashboard);
} catch (error) {
next(error);
}
}
);
// Metaverse & Edge
router.get(
'/metaverse-edge',
requireAdminPermission(AdminPermission.VIEW_METAVERSE_EDGE),
async (req, res, next) => {
try {
const dashboard = await dbisAdminService.metaverseEdge.getMetaverseEdgeDashboard();
res.json(dashboard);
} catch (error) {
next(error);
}
}
);
// Risk & Compliance
router.get(
'/risk-compliance',
requireAdminPermission(AdminPermission.VIEW_RISK_COMPLIANCE),
async (req, res, next) => {
try {
const dashboard = await dbisAdminService.riskCompliance.getRiskComplianceDashboard();
res.json(dashboard);
} catch (error) {
next(error);
}
}
);
// Corridor Controls
router.post(
'/corridors/caps',
requireAdminPermission(AdminPermission.CORRIDOR_ADJUST_CAPS),
async (req, res, next) => {
try {
const employeeId = req.headers['x-employee-id'] as string || req.sovereignBankId || '';
const result = await dbisAdminService.corridorControls.adjustCorridorCaps(
employeeId,
req.body
);
res.json(result);
} catch (error) {
next(error);
}
}
);
router.post(
'/corridors/throttle',
requireAdminPermission(AdminPermission.CORRIDOR_THROTTLE),
async (req, res, next) => {
try {
const employeeId = req.headers['x-employee-id'] as string || req.sovereignBankId || '';
const result = await dbisAdminService.corridorControls.throttleCorridor(
employeeId,
req.body
);
res.json(result);
} catch (error) {
next(error);
}
}
);
router.post(
'/corridors/enable-disable',
requireAdminPermission(AdminPermission.CORRIDOR_ENABLE_DISABLE),
async (req, res, next) => {
try {
const employeeId = req.headers['x-employee-id'] as string || req.sovereignBankId || '';
const result = await dbisAdminService.corridorControls.enableDisableCorridor(
employeeId,
req.body
);
res.json(result);
} catch (error) {
next(error);
}
}
);
// Network Controls
router.post(
'/network/quiesce',
requireAdminPermission(AdminPermission.NETWORK_QUIESCE_SUBSYSTEM),
async (req, res, next) => {
try {
const employeeId = req.headers['x-employee-id'] as string || req.sovereignBankId || '';
const result = await dbisAdminService.networkControls.quiesceSubsystem(employeeId, req.body);
res.json(result);
} catch (error) {
next(error);
}
}
);
router.post(
'/network/kill-switch',
requireAdminPermission(AdminPermission.NETWORK_KILL_SWITCH),
async (req, res, next) => {
try {
const employeeId = req.headers['x-employee-id'] as string || req.sovereignBankId || '';
const result = await dbisAdminService.networkControls.activateKillSwitch(
employeeId,
req.body
);
res.json(result);
} catch (error) {
next(error);
}
}
);
router.post(
'/network/escalate',
requireAdminPermission(AdminPermission.NETWORK_ESCALATE_INCIDENT),
async (req, res, next) => {
try {
const employeeId = req.headers['x-employee-id'] as string || req.sovereignBankId || '';
const result = await dbisAdminService.networkControls.escalateIncident(
employeeId,
req.body
);
res.json(result);
} catch (error) {
next(error);
}
}
);
export default router;

View File

@@ -0,0 +1,60 @@
// DBIS Admin Console - Main Service
// Orchestrates all DBIS admin operations
import { globalOverviewService } from './dashboards/global-overview.service';
import { participantsService } from './dashboards/participants.service';
import { gruCommandService } from './dashboards/gru-command.service';
import { gasQpsService } from './dashboards/gas-qps.service';
import { cbdcFxService } from './dashboards/cbdc-fx.service';
import { metaverseEdgeService } from './dashboards/metaverse-edge.service';
import { riskComplianceService } from './dashboards/risk-compliance.service';
import { gruControlsService } from './controls/gru-controls.service';
import { corridorControlsService } from './controls/corridor-controls.service';
import { networkControlsService } from './controls/network-controls.service';
export class DBISAdminService {
// Dashboard services
get globalOverview() {
return globalOverviewService;
}
get participants() {
return participantsService;
}
get gruCommand() {
return gruCommandService;
}
get gasQps() {
return gasQpsService;
}
get cbdcFx() {
return cbdcFxService;
}
get metaverseEdge() {
return metaverseEdgeService;
}
get riskCompliance() {
return riskComplianceService;
}
// Control services
get gruControls() {
return gruControlsService;
}
get corridorControls() {
return corridorControlsService;
}
get networkControls() {
return networkControlsService;
}
}
export const dbisAdminService = new DBISAdminService();

View File

@@ -0,0 +1,80 @@
// SCB Admin Console - CBDC Controls Service
// CBDC parameters, GRU policies
import prisma from '@/shared/database/prisma';
import { logger } from '@/infrastructure/monitoring/logger';
import { adminAuditService } from '@/core/admin/shared/admin-audit.service';
import { AdminPermission } from '@/core/admin/shared/permissions.constants';
export interface CBDCParameterUpdate {
cbdcType: 'rCBDC' | 'wCBDC' | 'iCBDC';
parameters: {
rate?: number;
feeSchedule?: Record<string, number>;
velocityControls?: Record<string, unknown>;
};
}
export interface GRUPolicyUpdate {
policy: 'enable_domestic_interbank' | 'enable_cross_border' | 'commercial_gru_allowed';
enabled: boolean;
partnerSCBs?: string[]; // For cross-border policy
}
export class CBDCControlsService {
/**
* Update CBDC parameters
*/
async updateCBDCParameters(
employeeId: string,
scbId: string,
update: CBDCParameterUpdate
): Promise<{ success: boolean }> {
await adminAuditService.logAction({
employeeId,
action: 'update_cbdc_parameters',
permission: AdminPermission.CBDC_UPDATE_PARAMETERS,
resourceType: 'cbdc',
resourceId: `${scbId}-${update.cbdcType}`,
metadata: { scbId, ...update },
});
// Would update CBDC configuration
logger.info('CBDC parameters updated', {
employeeId,
scbId,
update,
});
return { success: true };
}
/**
* Update GRU policy
*/
async updateGRUPolicy(
employeeId: string,
scbId: string,
update: GRUPolicyUpdate
): Promise<{ success: boolean }> {
await adminAuditService.logAction({
employeeId,
action: 'update_gru_policy',
permission: AdminPermission.CBDC_UPDATE_PARAMETERS, // Using same permission
resourceType: 'gru_policy',
resourceId: scbId,
metadata: { scbId, ...update },
});
logger.info('GRU policy updated', {
employeeId,
scbId,
update,
});
return { success: true };
}
}
export const cbdcControlsService = new CBDCControlsService();

View File

@@ -0,0 +1,112 @@
// SCB Admin Console - FI Controls Service
// FI approval/suspension, API profiles, limits
import prisma from '@/shared/database/prisma';
import { logger } from '@/infrastructure/monitoring/logger';
import { adminAuditService } from '@/core/admin/shared/admin-audit.service';
import { AdminPermission } from '@/core/admin/shared/permissions.constants';
export interface FIApprovalRequest {
fiId: string;
action: 'approve' | 'suspend';
reason: string;
}
export interface FILimitsUpdate {
fiId: string;
limits: {
byAssetType?: Record<string, number>;
byCorridor?: Record<string, number>;
dailyLimit?: number;
};
}
export interface APIProfileAssignment {
fiId: string;
profileId: string;
endpoints: string[];
}
export class FIControlsService {
/**
* Approve or suspend FI
*/
async approveSuspendFI(
employeeId: string,
scbId: string,
request: FIApprovalRequest
): Promise<{ success: boolean }> {
await adminAuditService.logAction({
employeeId,
action: request.action === 'approve' ? 'approve_fi' : 'suspend_fi',
permission: AdminPermission.FI_APPROVE_SUSPEND,
resourceType: 'financial_institution',
resourceId: request.fiId,
metadata: { scbId, ...request },
});
// Would update FI status
logger.info('FI approval/suspension', {
employeeId,
scbId,
request,
});
return { success: true };
}
/**
* Set FI limits
*/
async setFILimits(
employeeId: string,
scbId: string,
update: FILimitsUpdate
): Promise<{ success: boolean }> {
await adminAuditService.logAction({
employeeId,
action: 'set_fi_limits',
permission: AdminPermission.FI_SET_LIMITS,
resourceType: 'financial_institution',
resourceId: update.fiId,
metadata: { scbId, ...update },
});
logger.info('FI limits updated', {
employeeId,
scbId,
update,
});
return { success: true };
}
/**
* Assign API profile to FI
*/
async assignAPIProfile(
employeeId: string,
scbId: string,
assignment: APIProfileAssignment
): Promise<{ success: boolean }> {
await adminAuditService.logAction({
employeeId,
action: 'assign_api_profile',
permission: AdminPermission.FI_API_PROFILES,
resourceType: 'financial_institution',
resourceId: assignment.fiId,
metadata: { scbId, ...assignment },
});
logger.info('API profile assigned', {
employeeId,
scbId,
assignment,
});
return { success: true };
}
}
export const fiControlsService = new FIControlsService();

View File

@@ -0,0 +1,134 @@
// SCB Admin Console - Corridor & FX Policy Service
// Corridor management, FX policy, settlement asset preferences
import prisma from '@/shared/database/prisma';
import { logger } from '@/infrastructure/monitoring/logger';
import Decimal from 'decimal.js';
export interface CorridorPolicy {
routeId: string;
targetSCB: string;
targetSCBName: string;
status: 'active' | 'pending' | 'suspended';
limits: {
dailyCap: number;
perTransactionLimit: number;
};
preferredSettlementAsset: string; // GRU, SSU, fiat
metaverseEnabled: boolean;
}
export interface FXPolicy {
corridors: Array<{
corridorId: string;
baseCurrency: string;
quoteCurrency: string;
spreads: {
min: number;
max: number;
};
fees: {
min: number;
max: number;
};
}>;
}
export interface CorridorPolicyDashboard {
corridors: CorridorPolicy[];
fxPolicy: FXPolicy;
}
export class CorridorPolicyService {
/**
* Get corridor & FX policy dashboard
*/
async getCorridorPolicyDashboard(scbId: string): Promise<CorridorPolicyDashboard> {
const [corridors, fxPolicy] = await Promise.all([
this.getCorridors(scbId),
this.getFXPolicy(scbId),
]);
return { corridors, fxPolicy };
}
/**
* Get corridors for SCB
*/
async getCorridors(scbId: string): Promise<CorridorPolicy[]> {
const routes = await prisma.settlementRoute.findMany({
where: {
OR: [{ sourceBankId: scbId }, { destinationBankId: scbId }],
status: 'active',
},
});
const corridors: CorridorPolicy[] = [];
for (const route of routes) {
const targetSCBId = route.sourceBankId === scbId ? route.destinationBankId : route.sourceBankId;
const targetSCB = await prisma.sovereignBank.findUnique({
where: { id: targetSCBId },
});
// Get 24h volume for limits
const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);
const settlements = await prisma.atomicSettlement.findMany({
where: {
sourceBankId: route.sourceBankId,
destinationBankId: route.destinationBankId,
createdAt: { gte: oneDayAgo },
},
});
const dailyVolume = settlements
.filter((s) => s.status === 'settled')
.reduce((sum, s) => sum.plus(s.amount), new Decimal(0))
.toNumber();
corridors.push({
routeId: route.routeId,
targetSCB: targetSCBId,
targetSCBName: targetSCB?.name || 'Unknown',
status: route.status === 'active' ? 'active' : 'suspended',
limits: {
dailyCap: dailyVolume * 1.5, // 150% of current volume
perTransactionLimit: 10000000, // Placeholder
},
preferredSettlementAsset: 'SSU', // Default
metaverseEnabled: false, // Placeholder
});
}
return corridors;
}
/**
* Get FX policy
*/
async getFXPolicy(scbId: string): Promise<FXPolicy> {
// Get FX pairs
const fxPairs = await prisma.fxPair.findMany({
where: { status: 'active' },
});
const corridors = fxPairs.map((pair) => ({
corridorId: pair.id,
baseCurrency: pair.baseCurrency,
quoteCurrency: pair.quoteCurrency,
spreads: {
min: 0.0001,
max: 0.01,
},
fees: {
min: 0.001,
max: 0.05,
},
}));
return { corridors };
}
}
export const corridorPolicyService = new CorridorPolicyService();

View File

@@ -0,0 +1,93 @@
// SCB Admin Console - FI Management Service
// FI directory, Nostro/Vostro accounts
import prisma from '@/shared/database/prisma';
import { logger } from '@/infrastructure/monitoring/logger';
export interface FIInfo {
fiId: string;
fiName: string;
bic?: string;
lei?: string;
regulatoryTier: string;
apiEnabled: boolean;
status: 'active' | 'suspended' | 'pending';
maxDailyLimits: {
byAssetType: Record<string, number>;
byCorridor: Record<string, number>;
};
}
export interface NostroVostroAccount {
accountId: string;
accountType: 'nostro' | 'vostro';
counterpartyFI: string;
currencyCode: string;
balance: number;
limits: {
dailyLimit: number;
perTransactionLimit: number;
};
status: 'active' | 'frozen' | 'closed';
}
export interface FIManagementDashboard {
fiDirectory: FIInfo[];
nostroVostroAccounts: NostroVostroAccount[];
}
export class FIManagementService {
/**
* Get FI management dashboard
*/
async getFIManagementDashboard(scbId: string): Promise<FIManagementDashboard> {
const [fiDirectory, nostroVostroAccounts] = await Promise.all([
this.getFIDirectory(scbId),
this.getNostroVostroAccounts(scbId),
]);
return { fiDirectory, nostroVostroAccounts };
}
/**
* Get FI directory
*/
async getFIDirectory(scbId: string): Promise<FIInfo[]> {
// Placeholder - would query actual FI table
// For now, return empty array as FIs might be stored differently
return [];
}
/**
* Get Nostro/Vostro accounts
*/
async getNostroVostroAccounts(scbId: string): Promise<NostroVostroAccount[]> {
// Placeholder - would query Nostro/Vostro account table
// These might be stored as BankAccount with specific types
const accounts = await prisma.bankAccount.findMany({
where: {
sovereignBankId: scbId,
accountType: {
in: ['nostro', 'vostro'],
},
},
take: 100,
});
return accounts.map((account) => ({
accountId: account.accountId,
accountType: account.accountType as 'nostro' | 'vostro',
counterpartyFI: account.counterpartyId || 'Unknown',
currencyCode: account.currencyCode,
balance: parseFloat(account.balance.toString()),
limits: {
dailyLimit: 1000000, // Placeholder
perTransactionLimit: 100000, // Placeholder
},
status: account.status === 'active' ? 'active' : 'frozen',
}));
}
}
export const fiManagementService = new FIManagementService();

View File

@@ -0,0 +1,289 @@
// SCB Admin Console - SCB Overview Dashboard Service
// Domestic network health, corridor view, local GRU & CBDC, risk & compliance
import prisma from '@/shared/database/prisma';
import { logger } from '@/infrastructure/monitoring/logger';
import { dashboardService } from '@/core/compliance/regtech/dashboard.service';
import Decimal from 'decimal.js';
export interface DomesticNetworkHealth {
fiCount: number;
activeFIs: number;
paymentRails: Array<{
railType: string;
status: 'active' | 'degraded' | 'down';
volume24h: number;
}>;
cbdcStatus: {
totalInCirculation: number;
wallets: {
retail: number;
wholesale: number;
institutional: number;
};
};
nostroVostroStatus: {
totalAccounts: number;
activeAccounts: number;
apiEnabled: boolean;
};
}
export interface CorridorView {
corridors: Array<{
targetSCB: string;
targetSCBName: string;
volume24h: number;
latency: number;
riskFlags: number;
preferredSettlementAsset: string;
}>;
}
export interface LocalGRUCBDC {
gruBalances: {
sr3: number;
m0: number;
};
cbdcInCirculation: {
rCBDC: number;
wCBDC: number;
iCBDC: number;
};
walletsByType: {
retail: number;
wholesale: number;
institutional: number;
};
}
export interface LocalRiskCompliance {
sareView: {
sovereignRisk: number;
fiLevelExposure: Array<{
fiId: string;
fiName: string;
exposure: number;
}>;
};
ariAlerts: Array<{
alertId: string;
type: string;
severity: string;
description: string;
timestamp: Date;
}>;
suspiciousFlows: Array<{
flowId: string;
description: string;
riskLevel: string;
}>;
}
export interface SCBOverviewDashboard {
domesticNetwork: DomesticNetworkHealth;
corridorView: CorridorView;
localGRUCBDC: LocalGRUCBDC;
riskCompliance: LocalRiskCompliance;
}
export class SCBOverviewService {
/**
* Get SCB overview dashboard
*/
async getSCBOverview(scbId: string): Promise<SCBOverviewDashboard> {
const [domesticNetwork, corridorView, localGRUCBDC, riskCompliance] = await Promise.all([
this.getDomesticNetworkHealth(scbId),
this.getCorridorView(scbId),
this.getLocalGRUCBDC(scbId),
this.getLocalRiskCompliance(scbId),
]);
return {
domesticNetwork,
corridorView,
localGRUCBDC,
riskCompliance,
};
}
/**
* Get domestic network health
*/
async getDomesticNetworkHealth(scbId: string): Promise<DomesticNetworkHealth> {
// Get CBDC wallets
const wallets = await prisma.cbdcWallet.findMany({
where: { sovereignBankId: scbId },
});
const cbdcInCirculation = wallets.reduce(
(sum, w) => sum.plus(w.balance),
new Decimal(0)
).toNumber();
// Get payment rails (placeholder)
const paymentRails = [
{
railType: 'RTGS',
status: 'active' as const,
volume24h: 0,
},
{
railType: 'CBDC',
status: 'active' as const,
volume24h: cbdcInCirculation,
},
];
return {
fiCount: 0, // Would query FI table
activeFIs: 0,
paymentRails,
cbdcStatus: {
totalInCirculation: cbdcInCirculation,
wallets: {
retail: wallets.filter((w) => w.walletType === 'retail').length,
wholesale: wallets.filter((w) => w.walletType === 'wholesale').length,
institutional: wallets.filter((w) => w.walletType === 'institutional').length,
},
},
nostroVostroStatus: {
totalAccounts: 0, // Would query Nostro/Vostro accounts
activeAccounts: 0,
apiEnabled: true,
},
};
}
/**
* Get corridor view
*/
async getCorridorView(scbId: string): Promise<CorridorView> {
const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);
// Get routes from this SCB
const routes = await prisma.settlementRoute.findMany({
where: {
OR: [{ sourceBankId: scbId }, { destinationBankId: scbId }],
status: 'active',
},
});
const corridors = [];
for (const route of routes) {
const targetSCBId = route.sourceBankId === scbId ? route.destinationBankId : route.sourceBankId;
const targetSCB = await prisma.sovereignBank.findUnique({
where: { id: targetSCBId },
});
// Get 24h volume
const settlements = await prisma.atomicSettlement.findMany({
where: {
sourceBankId: route.sourceBankId,
destinationBankId: route.destinationBankId,
createdAt: { gte: oneDayAgo },
},
});
const volume24h = settlements
.filter((s) => s.status === 'settled')
.reduce((sum, s) => sum.plus(s.amount), new Decimal(0))
.toNumber();
// Get risk flags (SRI enforcements)
const riskFlags = await prisma.sRIEnforcement.count({
where: {
sovereignBankId: targetSCBId,
status: 'active',
},
});
corridors.push({
targetSCB: targetSCBId,
targetSCBName: targetSCB?.name || 'Unknown',
volume24h,
latency: route.estimatedLatency || 0,
riskFlags,
preferredSettlementAsset: route.currencyCode,
});
}
return { corridors };
}
/**
* Get local GRU & CBDC
*/
async getLocalGRUCBDC(scbId: string): Promise<LocalGRUCBDC> {
// Get CBDC wallets
const wallets = await prisma.cbdcWallet.findMany({
where: { sovereignBankId: scbId },
});
const rCBDC = wallets
.filter((w) => w.walletType === 'retail')
.reduce((sum, w) => sum.plus(w.balance), new Decimal(0))
.toNumber();
const wCBDC = wallets
.filter((w) => w.walletType === 'wholesale')
.reduce((sum, w) => sum.plus(w.balance), new Decimal(0))
.toNumber();
const iCBDC = wallets
.filter((w) => w.walletType === 'institutional')
.reduce((sum, w) => sum.plus(w.balance), new Decimal(0))
.toNumber();
return {
gruBalances: {
sr3: 0, // Would query GRU balances
m0: 0,
},
cbdcInCirculation: {
rCBDC,
wCBDC,
iCBDC,
},
walletsByType: {
retail: wallets.filter((w) => w.walletType === 'retail').length,
wholesale: wallets.filter((w) => w.walletType === 'wholesale').length,
institutional: wallets.filter((w) => w.walletType === 'institutional').length,
},
};
}
/**
* Get local risk & compliance
*/
async getLocalRiskCompliance(scbId: string): Promise<LocalRiskCompliance> {
// Get SRI
const sri = await prisma.sovereignRiskIndex.findFirst({
where: { sovereignBankId: scbId },
orderBy: { calculatedAt: 'desc' },
});
// Get ARI alerts
const dashboard = await dashboardService.getIncidentAlertsDashboard(scbId);
const ariAlerts = (dashboard.incidentAlerts || []).map((alert, index) => ({
alertId: `ari-${scbId}-${index}`,
type: alert.type,
severity: alert.severity,
description: alert.description,
timestamp: alert.timestamp,
}));
return {
sareView: {
sovereignRisk: sri ? parseFloat(sri.sriScore.toString()) : 0,
fiLevelExposure: [], // Would query FI exposures
},
ariAlerts,
suspiciousFlows: [], // Would query suspicious transaction patterns
};
}
}
export const scbOverviewService = new SCBOverviewService();

View File

@@ -0,0 +1,172 @@
// SCB Admin Console API Routes
import { Router } from 'express';
import { scbAdminService } from './scb-admin.service';
import { requireAdminPermission, requireSCBAccess } from '@/integration/api-gateway/middleware/admin-permission.middleware';
import { AdminPermission } from '@/core/admin/shared/permissions.constants';
const router = Router();
// SCB Overview Dashboard
router.get(
'/dashboard/overview',
requireAdminPermission(AdminPermission.VIEW_SCB_OVERVIEW),
async (req, res, next) => {
try {
const scbId = req.sovereignBankId;
if (!scbId) {
return res.status(400).json({ error: 'Sovereign Bank ID required' });
}
const overview = await scbAdminService.overview.getSCBOverview(scbId);
res.json(overview);
} catch (error) {
next(error);
}
}
);
// FI Management
router.get(
'/fi',
requireAdminPermission(AdminPermission.VIEW_FI_MANAGEMENT),
async (req, res, next) => {
try {
const scbId = req.sovereignBankId;
if (!scbId) {
return res.status(400).json({ error: 'Sovereign Bank ID required' });
}
const dashboard = await scbAdminService.fiManagement.getFIManagementDashboard(scbId);
res.json(dashboard);
} catch (error) {
next(error);
}
}
);
router.post(
'/fi/approve-suspend',
requireAdminPermission(AdminPermission.FI_APPROVE_SUSPEND),
async (req, res, next) => {
try {
const scbId = req.sovereignBankId;
if (!scbId) {
return res.status(400).json({ error: 'Sovereign Bank ID required' });
}
const employeeId = req.headers['x-employee-id'] as string || scbId;
const result = await scbAdminService.fiControls.approveSuspendFI(
employeeId,
scbId,
req.body
);
res.json(result);
} catch (error) {
next(error);
}
}
);
router.post(
'/fi/limits',
requireAdminPermission(AdminPermission.FI_SET_LIMITS),
async (req, res, next) => {
try {
const scbId = req.sovereignBankId;
if (!scbId) {
return res.status(400).json({ error: 'Sovereign Bank ID required' });
}
const employeeId = req.headers['x-employee-id'] as string || scbId;
const result = await scbAdminService.fiControls.setFILimits(employeeId, scbId, req.body);
res.json(result);
} catch (error) {
next(error);
}
}
);
router.post(
'/fi/api-profile',
requireAdminPermission(AdminPermission.FI_API_PROFILES),
async (req, res, next) => {
try {
const scbId = req.sovereignBankId;
if (!scbId) {
return res.status(400).json({ error: 'Sovereign Bank ID required' });
}
const employeeId = req.headers['x-employee-id'] as string || scbId;
const result = await scbAdminService.fiControls.assignAPIProfile(
employeeId,
scbId,
req.body
);
res.json(result);
} catch (error) {
next(error);
}
}
);
// Corridor & FX Policy
router.get(
'/corridors',
requireAdminPermission(AdminPermission.VIEW_CORRIDOR_POLICY),
async (req, res, next) => {
try {
const scbId = req.sovereignBankId;
if (!scbId) {
return res.status(400).json({ error: 'Sovereign Bank ID required' });
}
const dashboard = await scbAdminService.corridorPolicy.getCorridorPolicyDashboard(scbId);
res.json(dashboard);
} catch (error) {
next(error);
}
}
);
// CBDC Controls
router.post(
'/cbdc/parameters',
requireAdminPermission(AdminPermission.CBDC_UPDATE_PARAMETERS),
async (req, res, next) => {
try {
const scbId = req.sovereignBankId;
if (!scbId) {
return res.status(400).json({ error: 'Sovereign Bank ID required' });
}
const employeeId = req.headers['x-employee-id'] as string || scbId;
const result = await scbAdminService.cbdcControls.updateCBDCParameters(
employeeId,
scbId,
req.body
);
res.json(result);
} catch (error) {
next(error);
}
}
);
router.post(
'/gru/policy',
requireAdminPermission(AdminPermission.CBDC_UPDATE_PARAMETERS),
async (req, res, next) => {
try {
const scbId = req.sovereignBankId;
if (!scbId) {
return res.status(400).json({ error: 'Sovereign Bank ID required' });
}
const employeeId = req.headers['x-employee-id'] as string || scbId;
const result = await scbAdminService.cbdcControls.updateGRUPolicy(
employeeId,
scbId,
req.body
);
res.json(result);
} catch (error) {
next(error);
}
}
);
export default router;

View File

@@ -0,0 +1,35 @@
// SCB Admin Console - Main Service
// Orchestrates all SCB admin operations
import { scbOverviewService } from './dashboards/scb-overview.service';
import { fiManagementService } from './dashboards/fi-management.service';
import { corridorPolicyService } from './dashboards/corridor-policy.service';
import { fiControlsService } from './controls/fi-controls.service';
import { cbdcControlsService } from './controls/cbdc-controls.service';
export class SCBAdminService {
// Dashboard services
get overview() {
return scbOverviewService;
}
get fiManagement() {
return fiManagementService;
}
get corridorPolicy() {
return corridorPolicyService;
}
// Control services
get fiControls() {
return fiControlsService;
}
get cbdcControls() {
return cbdcControlsService;
}
}
export const scbAdminService = new SCBAdminService();

View File

@@ -0,0 +1,100 @@
// Admin Audit Service
// Audit logging for all admin console actions
import { v4 as uuidv4 } from 'uuid';
import prisma from '@/shared/database/prisma';
import { logger } from '@/infrastructure/monitoring/logger';
import { AdminPermission } from './permissions.constants';
export interface AdminActionAudit {
employeeId: string;
action: string;
permission: AdminPermission;
resourceType: string;
resourceId?: string;
beforeState?: Record<string, unknown>;
afterState?: Record<string, unknown>;
metadata?: Record<string, unknown>;
ipAddress?: string;
userAgent?: string;
}
export class AdminAuditService {
/**
* Log admin action
*/
async logAction(audit: AdminActionAudit): Promise<void> {
try {
// Store in audit log (extend existing audit infrastructure)
// For now, we'll use logger and could extend to database table
logger.info('Admin action', {
auditId: uuidv4(),
employeeId: audit.employeeId,
action: audit.action,
permission: audit.permission,
resourceType: audit.resourceType,
resourceId: audit.resourceId,
beforeState: audit.beforeState,
afterState: audit.afterState,
metadata: audit.metadata,
ipAddress: audit.ipAddress,
userAgent: audit.userAgent,
timestamp: new Date(),
});
// TODO: Store in AdminActionAudit table when schema is added
} catch (error) {
logger.error('Error logging admin action', {
error: error instanceof Error ? error.message : 'Unknown error',
audit,
});
}
}
/**
* Get audit log for employee
*/
async getAuditLog(
employeeId?: string,
resourceType?: string,
limit: number = 100
): Promise<AdminActionAudit[]> {
try {
// TODO: Query from AdminActionAudit table
// For now, return empty array
return [];
} catch (error) {
logger.error('Error getting audit log', {
error: error instanceof Error ? error.message : 'Unknown error',
employeeId,
resourceType,
});
return [];
}
}
/**
* Export audit log for regulators
*/
async exportAuditLog(
startDate: Date,
endDate: Date,
employeeId?: string
): Promise<AdminActionAudit[]> {
try {
// TODO: Query and format for export
return [];
} catch (error) {
logger.error('Error exporting audit log', {
error: error instanceof Error ? error.message : 'Unknown error',
startDate,
endDate,
employeeId,
});
return [];
}
}
}
export const adminAuditService = new AdminAuditService();

View File

@@ -0,0 +1,192 @@
// Admin Permissions Service
// Permission checking and role management for admin consoles
import { AdminPermission, AdminRole, ROLE_PERMISSIONS } from './permissions.constants';
import { roleManagementService } from '@/core/operations/role-management.service';
import { logger } from '@/infrastructure/monitoring/logger';
export interface PermissionCheckResult {
allowed: boolean;
reason?: string;
}
export class AdminPermissionsService {
/**
* Check if employee has specific permission
*/
async hasPermission(
employeeId: string,
permission: AdminPermission
): Promise<boolean> {
try {
// First check if they have 'all' permission (DBIS Governor)
const hasAll = await roleManagementService.hasPermission(employeeId, 'all');
if (hasAll) {
return true;
}
// Get employee's role
const roleName = await this.getEmployeeRoleName(employeeId);
if (!roleName) {
return false;
}
// Map DBIS role names to AdminRole enum
const adminRole = this.mapRoleToAdminRole(roleName);
if (!adminRole) {
return false;
}
// Check if role has permission
const rolePermissions = ROLE_PERMISSIONS[adminRole] || [];
return rolePermissions.includes(permission);
} catch (error) {
logger.error('Error checking permission', {
employeeId,
permission,
error: error instanceof Error ? error.message : 'Unknown error',
});
return false;
}
}
/**
* Check permission with detailed result
*/
async checkPermission(
employeeId: string,
permission: AdminPermission
): Promise<PermissionCheckResult> {
const allowed = await this.hasPermission(employeeId, permission);
return {
allowed,
reason: allowed ? undefined : 'Insufficient permissions',
};
}
/**
* Check if employee can perform action on specific SCB
* SCB admins can only act on their own SCB
*/
async canActOnSCB(
employeeId: string,
targetSCBId: string,
employeeSCBId?: string
): Promise<boolean> {
// DBIS admins can act on any SCB
const hasAll = await roleManagementService.hasPermission(employeeId, 'all');
if (hasAll) {
return true;
}
// SCB admins can only act on their own SCB
if (employeeSCBId && employeeSCBId === targetSCBId) {
return true;
}
return false;
}
/**
* Get all permissions for an employee
*/
async getEmployeePermissions(employeeId: string): Promise<AdminPermission[]> {
try {
const hasAll = await roleManagementService.hasPermission(employeeId, 'all');
if (hasAll) {
// Return all permissions
return Object.values(AdminPermission);
}
// Get employee to find their role
const prisma = (await import('@/shared/database/prisma')).default;
const employee = await prisma.employeeCredential.findUnique({
where: { employeeId },
include: { role: true },
});
if (!employee || employee.status !== 'active') {
return [];
}
const adminRole = this.mapRoleToAdminRole(employee.role.roleName);
if (!adminRole) {
return [];
}
return ROLE_PERMISSIONS[adminRole] || [];
} catch (error) {
logger.error('Error getting employee permissions', {
employeeId,
error: error instanceof Error ? error.message : 'Unknown error',
});
return [];
}
}
/**
* Get employee's role name
*/
async getEmployeeRoleName(employeeId: string): Promise<string | null> {
try {
const prisma = (await import('@/shared/database/prisma')).default;
const employee = await prisma.employeeCredential.findUnique({
where: { employeeId },
include: { role: true },
});
return employee?.role.roleName || null;
} catch (error) {
logger.error('Error getting employee role', {
employeeId,
error: error instanceof Error ? error.message : 'Unknown error',
});
return null;
}
}
/**
* Map DBIS role name to AdminRole enum
*/
private mapRoleToAdminRole(roleName: string): AdminRole | null {
const roleMap: Record<string, AdminRole> = {
Governor: AdminRole.DBIS_SUPER_ADMIN,
MSC_Officer: AdminRole.DBIS_OPS,
CAA_Auditor: AdminRole.DBIS_RISK,
DBIS_Super_Admin: AdminRole.DBIS_SUPER_ADMIN,
DBIS_Ops: AdminRole.DBIS_OPS,
DBIS_Risk: AdminRole.DBIS_RISK,
SCB_Admin: AdminRole.SCB_ADMIN,
SCB_Risk: AdminRole.SCB_RISK,
SCB_Tech: AdminRole.SCB_TECH,
SCB_Read_Only: AdminRole.SCB_READ_ONLY,
};
return roleMap[roleName] || null;
}
/**
* Check if role is DBIS-level (can act globally)
*/
async isDBISLevel(employeeId: string): Promise<boolean> {
const hasAll = await roleManagementService.hasPermission(employeeId, 'all');
if (hasAll) {
return true;
}
const roleName = await this.getEmployeeRoleName(employeeId);
if (!roleName) {
return false;
}
const adminRole = this.mapRoleToAdminRole(roleName);
return (
adminRole === AdminRole.DBIS_SUPER_ADMIN ||
adminRole === AdminRole.DBIS_OPS ||
adminRole === AdminRole.DBIS_RISK
);
}
}
export const adminPermissionsService = new AdminPermissionsService();

View File

@@ -0,0 +1,217 @@
// Admin Console Permission Constants
// Granular permissions for DBIS and SCB admin consoles
export enum AdminPermission {
// GRU Management
GRU_CREATE_CLASS = 'gru:create_class',
GRU_CHANGE_CLASS = 'gru:change_class',
GRU_LOCK_UNLOCK = 'gru:lock_unlock',
GRU_ISSUANCE_PROPOSAL = 'gru:issuance_proposal',
GRU_INDEX_WEIGHT_ADJUST = 'gru:index_weight_adjust',
GRU_CIRCUIT_BREAKERS = 'gru:circuit_breakers',
GRU_BOND_ISSUANCE_WINDOW = 'gru:bond_issuance_window',
GRU_BOND_BUYBACK = 'gru:bond_buyback',
// Corridor Management
CORRIDOR_ADJUST_CAPS = 'corridor:adjust_caps',
CORRIDOR_THROTTLE = 'corridor:throttle',
CORRIDOR_ENABLE_DISABLE = 'corridor:enable_disable',
CORRIDOR_REQUEST_CHANGE = 'corridor:request_change',
// Network Controls
NETWORK_QUIESCE_SUBSYSTEM = 'network:quiesce_subsystem',
NETWORK_KILL_SWITCH = 'network:kill_switch',
NETWORK_ESCALATE_INCIDENT = 'network:escalate_incident',
// SCB Management
SCB_PAUSE_SETTLEMENT = 'scb:pause_settlement',
SCB_VIEW_DETAILS = 'scb:view_details',
SCB_IMPERSONATE_VIEW = 'scb:impersonate_view',
SCB_JURISDICTION_SETTINGS = 'scb:jurisdiction_settings',
// FI Management
FI_APPROVE_SUSPEND = 'fi:approve_suspend',
FI_SET_LIMITS = 'fi:set_limits',
FI_API_PROFILES = 'fi:api_profiles',
// CBDC Management
CBDC_APPROVE_TYPE = 'cbdc:approve_type',
CBDC_CROSS_BORDER_CORRIDOR = 'cbdc:cross_border_corridor',
CBDC_UPDATE_PARAMETERS = 'cbdc:update_parameters',
// GAS & QPS
GAS_SET_LIMITS = 'gas:set_limits',
GAS_ENABLE_DISABLE_SETTLEMENT = 'gas:enable_disable_settlement',
GAS_THROTTLE_BANDWIDTH = 'gas:throttle_bandwidth',
QPS_ENABLE_DISABLE = 'qps:enable_disable',
QPS_SET_MAPPING_PROFILES = 'qps:set_mapping_profiles',
// Metaverse & Edge
METAVERSE_ENABLE_ONRAMP = 'metaverse:enable_onramp',
METAVERSE_SET_LIMITS = 'metaverse:set_limits',
EDGE_DRAIN_LOAD = 'edge:drain_load',
EDGE_QUARANTINE = 'edge:quarantine',
// Risk & Compliance
RISK_ACKNOWLEDGE_ALERT = 'risk:acknowledge_alert',
RISK_TRIGGER_STRESS_TEST = 'risk:trigger_stress_test',
RISK_PUSH_POLICY_UPDATE = 'risk:push_policy_update',
RISK_MARK_SCENARIO = 'risk:mark_scenario',
// Nostro/Vostro
NOSTRO_VOSTRO_OPEN = 'nostro_vostro:open',
NOSTRO_VOSTRO_ADJUST_LIMITS = 'nostro_vostro:adjust_limits',
NOSTRO_VOSTRO_FREEZE = 'nostro_vostro:freeze',
// Developer & Integrations
API_KEY_ROTATE = 'api:key_rotate',
API_KEY_REVOKE = 'api:key_revoke',
API_SANDBOX_MODE = 'api:sandbox_mode',
// Security & Identity
RBAC_EDIT = 'rbac:edit',
AUDIT_EXPORT = 'audit:export',
// Read-only permissions
VIEW_GLOBAL_OVERVIEW = 'view:global_overview',
VIEW_PARTICIPANTS = 'view:participants',
VIEW_GRU_COMMAND = 'view:gru_command',
VIEW_GAS_QPS = 'view:gas_qps',
VIEW_CBDC_FX = 'view:cbdc_fx',
VIEW_METAVERSE_EDGE = 'view:metaverse_edge',
VIEW_RISK_COMPLIANCE = 'view:risk_compliance',
VIEW_SCB_OVERVIEW = 'view:scb_overview',
VIEW_FI_MANAGEMENT = 'view:fi_management',
VIEW_CORRIDOR_POLICY = 'view:corridor_policy',
}
export enum AdminRole {
DBIS_SUPER_ADMIN = 'DBIS_Super_Admin',
DBIS_OPS = 'DBIS_Ops',
DBIS_RISK = 'DBIS_Risk',
SCB_ADMIN = 'SCB_Admin',
SCB_RISK = 'SCB_Risk',
SCB_TECH = 'SCB_Tech',
SCB_READ_ONLY = 'SCB_Read_Only',
}
// Permission matrix: Role -> Permissions
export const ROLE_PERMISSIONS: Record<AdminRole, AdminPermission[]> = {
[AdminRole.DBIS_SUPER_ADMIN]: [
// All permissions
AdminPermission.GRU_CREATE_CLASS,
AdminPermission.GRU_CHANGE_CLASS,
AdminPermission.GRU_LOCK_UNLOCK,
AdminPermission.GRU_ISSUANCE_PROPOSAL,
AdminPermission.GRU_INDEX_WEIGHT_ADJUST,
AdminPermission.GRU_CIRCUIT_BREAKERS,
AdminPermission.GRU_BOND_ISSUANCE_WINDOW,
AdminPermission.GRU_BOND_BUYBACK,
AdminPermission.CORRIDOR_ADJUST_CAPS,
AdminPermission.CORRIDOR_THROTTLE,
AdminPermission.CORRIDOR_ENABLE_DISABLE,
AdminPermission.NETWORK_QUIESCE_SUBSYSTEM,
AdminPermission.NETWORK_KILL_SWITCH,
AdminPermission.NETWORK_ESCALATE_INCIDENT,
AdminPermission.SCB_PAUSE_SETTLEMENT,
AdminPermission.SCB_VIEW_DETAILS,
AdminPermission.SCB_IMPERSONATE_VIEW,
AdminPermission.SCB_JURISDICTION_SETTINGS,
AdminPermission.FI_APPROVE_SUSPEND,
AdminPermission.FI_SET_LIMITS,
AdminPermission.FI_API_PROFILES,
AdminPermission.CBDC_APPROVE_TYPE,
AdminPermission.CBDC_CROSS_BORDER_CORRIDOR,
AdminPermission.CBDC_UPDATE_PARAMETERS,
AdminPermission.GAS_SET_LIMITS,
AdminPermission.GAS_ENABLE_DISABLE_SETTLEMENT,
AdminPermission.GAS_THROTTLE_BANDWIDTH,
AdminPermission.QPS_ENABLE_DISABLE,
AdminPermission.QPS_SET_MAPPING_PROFILES,
AdminPermission.METAVERSE_ENABLE_ONRAMP,
AdminPermission.METAVERSE_SET_LIMITS,
AdminPermission.EDGE_DRAIN_LOAD,
AdminPermission.EDGE_QUARANTINE,
AdminPermission.RISK_ACKNOWLEDGE_ALERT,
AdminPermission.RISK_TRIGGER_STRESS_TEST,
AdminPermission.RISK_PUSH_POLICY_UPDATE,
AdminPermission.RISK_MARK_SCENARIO,
AdminPermission.NOSTRO_VOSTRO_OPEN,
AdminPermission.NOSTRO_VOSTRO_ADJUST_LIMITS,
AdminPermission.NOSTRO_VOSTRO_FREEZE,
AdminPermission.API_KEY_ROTATE,
AdminPermission.API_KEY_REVOKE,
AdminPermission.API_SANDBOX_MODE,
AdminPermission.RBAC_EDIT,
AdminPermission.AUDIT_EXPORT,
AdminPermission.VIEW_GLOBAL_OVERVIEW,
AdminPermission.VIEW_PARTICIPANTS,
AdminPermission.VIEW_GRU_COMMAND,
AdminPermission.VIEW_GAS_QPS,
AdminPermission.VIEW_CBDC_FX,
AdminPermission.VIEW_METAVERSE_EDGE,
AdminPermission.VIEW_RISK_COMPLIANCE,
AdminPermission.VIEW_SCB_OVERVIEW,
AdminPermission.VIEW_FI_MANAGEMENT,
AdminPermission.VIEW_CORRIDOR_POLICY,
],
[AdminRole.DBIS_OPS]: [
AdminPermission.VIEW_GLOBAL_OVERVIEW,
AdminPermission.VIEW_PARTICIPANTS,
AdminPermission.VIEW_GAS_QPS,
AdminPermission.VIEW_METAVERSE_EDGE,
AdminPermission.NETWORK_ESCALATE_INCIDENT,
AdminPermission.GAS_THROTTLE_BANDWIDTH,
AdminPermission.QPS_ENABLE_DISABLE,
AdminPermission.EDGE_DRAIN_LOAD,
AdminPermission.RISK_ACKNOWLEDGE_ALERT,
],
[AdminRole.DBIS_RISK]: [
AdminPermission.VIEW_GLOBAL_OVERVIEW,
AdminPermission.VIEW_RISK_COMPLIANCE,
AdminPermission.RISK_ACKNOWLEDGE_ALERT,
AdminPermission.RISK_TRIGGER_STRESS_TEST,
AdminPermission.RISK_MARK_SCENARIO,
AdminPermission.AUDIT_EXPORT,
],
[AdminRole.SCB_ADMIN]: [
AdminPermission.VIEW_SCB_OVERVIEW,
AdminPermission.VIEW_FI_MANAGEMENT,
AdminPermission.VIEW_CORRIDOR_POLICY,
AdminPermission.FI_APPROVE_SUSPEND,
AdminPermission.FI_SET_LIMITS,
AdminPermission.FI_API_PROFILES,
AdminPermission.CORRIDOR_REQUEST_CHANGE,
AdminPermission.CBDC_UPDATE_PARAMETERS,
AdminPermission.NOSTRO_VOSTRO_OPEN,
AdminPermission.NOSTRO_VOSTRO_ADJUST_LIMITS,
AdminPermission.NOSTRO_VOSTRO_FREEZE,
AdminPermission.API_KEY_ROTATE,
AdminPermission.API_KEY_REVOKE,
AdminPermission.API_SANDBOX_MODE,
AdminPermission.RISK_ACKNOWLEDGE_ALERT,
AdminPermission.RISK_TRIGGER_STRESS_TEST,
],
[AdminRole.SCB_RISK]: [
AdminPermission.VIEW_SCB_OVERVIEW,
AdminPermission.VIEW_FI_MANAGEMENT,
AdminPermission.VIEW_CORRIDOR_POLICY,
AdminPermission.RISK_ACKNOWLEDGE_ALERT,
AdminPermission.RISK_MARK_SCENARIO,
AdminPermission.RISK_TRIGGER_STRESS_TEST,
],
[AdminRole.SCB_TECH]: [
AdminPermission.VIEW_SCB_OVERVIEW,
AdminPermission.VIEW_FI_MANAGEMENT,
AdminPermission.FI_API_PROFILES,
AdminPermission.API_KEY_ROTATE,
AdminPermission.API_KEY_REVOKE,
AdminPermission.API_SANDBOX_MODE,
],
[AdminRole.SCB_READ_ONLY]: [
AdminPermission.VIEW_SCB_OVERVIEW,
AdminPermission.VIEW_FI_MANAGEMENT,
AdminPermission.VIEW_CORRIDOR_POLICY,
],
};

View File

@@ -0,0 +1,173 @@
// Gap Audit Engine Service
// Main gap scanning across multiverse systems, temporal ledgers, quantum chains, cognitive-intent layers, DLT/metaverse ecosystems
import prisma from '@/shared/database/prisma';
import { v4 as uuidv4 } from 'uuid';
import { logger } from '@/infrastructure/monitoring/logger';
import { gapDetectionService } from './gap-detection.service';
import { moduleGeneratorService } from './module-generator.service';
import { recommendationsEngineService } from './recommendations-engine.service';
export interface GapAuditRequest {
auditScope: Array<
'multiverse' | 'temporal' | 'quantum' | 'cognitive' | 'dlt' | 'metaverse'
>;
includeRecommendations?: boolean;
}
export interface GapAuditResult {
auditId: string;
gapsFound: number;
modulesGenerated: number;
recommendationsCount: number;
status: string;
}
export class GapAuditEngineService {
/**
* Execute comprehensive gap audit
* Scans all DBIS systems for gaps
*/
async executeGapAudit(
request: GapAuditRequest
): Promise<GapAuditResult> {
logger.info('Gap Audit: Starting comprehensive audit', { request });
const auditId = `GAP-AUDIT-${uuidv4()}`;
// Step 1: Create audit record
const audit = await prisma.gapAudit.create({
data: {
auditId,
auditScope: request.auditScope as any,
status: 'running',
},
});
try {
// Step 2: Scan for gaps in each scope
const allGaps: any[] = [];
for (const scope of request.auditScope) {
const gaps = await gapDetectionService.detectGaps(scope);
allGaps.push(...gaps);
// Save gap detections
for (const gap of gaps) {
await prisma.gapDetection.create({
data: {
detectionId: `GAP-DET-${uuidv4()}`,
auditId,
gapType: gap.gapType,
systemScope: scope,
description: gap.description,
severity: gap.severity,
status: 'detected',
},
});
}
}
// Step 3: Generate modules for detected gaps
let modulesGenerated = 0;
for (const gap of allGaps) {
if (gap.autoGenerate) {
const moduleId = await moduleGeneratorService.generateModule(
gap.gapType
);
if (moduleId) {
modulesGenerated++;
}
}
}
// Step 4: Generate recommendations if requested
let recommendationsCount = 0;
if (request.includeRecommendations) {
const recommendations =
await recommendationsEngineService.generateRecommendations(allGaps);
recommendationsCount = recommendations.length;
for (const recommendation of recommendations) {
await prisma.systemRecommendation.create({
data: {
recommendationId: `REC-${uuidv4()}`,
auditId,
recommendationType: recommendation.type,
title: recommendation.title,
description: recommendation.description,
priority: recommendation.priority,
status: 'pending',
},
});
}
}
// Step 5: Update audit status
await prisma.gapAudit.update({
where: { auditId },
data: {
status: 'completed',
gapsFound: allGaps.length,
modulesGenerated,
recommendationsCount,
completedAt: new Date(),
},
});
logger.info('Gap Audit: Audit completed', {
auditId,
gapsFound: allGaps.length,
modulesGenerated,
});
return {
auditId,
gapsFound: allGaps.length,
modulesGenerated,
recommendationsCount,
status: 'completed',
};
} catch (error) {
await prisma.gapAudit.update({
where: { auditId },
data: {
status: 'failed',
},
});
throw error;
}
}
/**
* Get audit by ID
*/
async getAudit(auditId: string) {
return await prisma.gapAudit.findUnique({
where: { auditId },
include: {
detections: true,
recommendations: true,
},
});
}
/**
* Get audit history
*/
async getAuditHistory(limit: number = 100) {
return await prisma.gapAudit.findMany({
orderBy: { createdAt: 'desc' },
take: limit,
include: {
detections: true,
recommendations: true,
},
});
}
}
export const gapAuditEngineService = new GapAuditEngineService();

View File

@@ -0,0 +1,84 @@
// Gap Audit API Routes
import { Router } from 'express';
import { gapAuditEngineService } from './gap-audit-engine.service';
import { moduleGeneratorService } from './module-generator.service';
import { zeroTrustAuthMiddleware } from '@/integration/api-gateway/middleware/auth.middleware';
const router = Router();
/**
* @route POST /api/gap-audit/execute
* @desc Execute gap audit
*/
router.post(
'/execute',
zeroTrustAuthMiddleware,
async (req, res, next) => {
try {
const result = await gapAuditEngineService.executeGapAudit(req.body);
res.json(result);
} catch (error) {
next(error);
}
}
);
/**
* @route GET /api/gap-audit/:auditId
* @desc Get audit by ID
*/
router.get(
'/:auditId',
zeroTrustAuthMiddleware,
async (req, res, next) => {
try {
const audit = await gapAuditEngineService.getAudit(req.params.auditId);
if (!audit) {
return res.status(404).json({ error: 'Audit not found' });
}
res.json(audit);
} catch (error) {
next(error);
}
}
);
/**
* @route GET /api/gap-audit/history
* @desc Get audit history
*/
router.get(
'/history',
zeroTrustAuthMiddleware,
async (req, res, next) => {
try {
const limit = parseInt(req.query.limit as string) || 100;
const history = await gapAuditEngineService.getAuditHistory(limit);
res.json(history);
} catch (error) {
next(error);
}
}
);
/**
* @route GET /api/gap-audit/modules
* @desc Get generated modules
*/
router.get(
'/modules',
zeroTrustAuthMiddleware,
async (req, res, next) => {
try {
const gapType = req.query.gapType as string | undefined;
const modules = await moduleGeneratorService.getGeneratedModules(gapType);
res.json(modules);
} catch (error) {
next(error);
}
}
);
export default router;

View File

@@ -0,0 +1,169 @@
// Gap Detection Service
// Gap detection algorithms for missing components, protocols, layers
import prisma from '@/shared/database/prisma';
import { logger } from '@/infrastructure/monitoring/logger';
export interface GapDetection {
gapType: string;
description: string;
severity: 'low' | 'medium' | 'high' | 'critical';
autoGenerate: boolean;
}
export class GapDetectionService {
/**
* Detect gaps in specified system scope
*/
async detectGaps(
scope: 'multiverse' | 'temporal' | 'quantum' | 'cognitive' | 'dlt' | 'metaverse'
): Promise<GapDetection[]> {
logger.info('Gap Detection: Scanning for gaps', { scope });
const gaps: GapDetection[] = [];
switch (scope) {
case 'multiverse':
gaps.push(...(await this.detectMultiverseGaps()));
break;
case 'temporal':
gaps.push(...(await this.detectTemporalGaps()));
break;
case 'quantum':
gaps.push(...(await this.detectQuantumGaps()));
break;
case 'cognitive':
gaps.push(...(await this.detectCognitiveGaps()));
break;
case 'dlt':
gaps.push(...(await this.detectDltGaps()));
break;
case 'metaverse':
gaps.push(...(await this.detectMetaverseGaps()));
break;
}
return gaps;
}
/**
* Detect gaps in multiverse systems
*/
private async detectMultiverseGaps(): Promise<GapDetection[]> {
const gaps: GapDetection[] = [];
// Check for missing multiverse settlement layers
const multiverseSettlements = await prisma.gasSettlement.count({
where: { networkType: 'multiversal' },
});
if (multiverseSettlements === 0) {
gaps.push({
gapType: 'multiverse_settlement_layer',
description: 'Missing multiverse settlement layer implementation',
severity: 'high',
autoGenerate: true,
});
}
return gaps;
}
/**
* Detect gaps in temporal systems
*/
private async detectTemporalGaps(): Promise<GapDetection[]> {
const gaps: GapDetection[] = [];
// Check for missing temporal ledger synchronization
// In production, would check actual temporal ledger systems
gaps.push({
gapType: 'temporal_ledger_sync',
description: 'Missing temporal ledger synchronization protocol',
severity: 'medium',
autoGenerate: false,
});
return gaps;
}
/**
* Detect gaps in quantum systems
*/
private async detectQuantumGaps(): Promise<GapDetection[]> {
const gaps: GapDetection[] = [];
// Check for missing quantum financial interfaces
const quantumProxies = await prisma.quantumProxyTransaction.count();
if (quantumProxies === 0) {
gaps.push({
gapType: 'quantum_financial_interface',
description: 'Missing quantum financial system interfaces',
severity: 'high',
autoGenerate: true,
});
}
return gaps;
}
/**
* Detect gaps in cognitive systems
*/
private async detectCognitiveGaps(): Promise<GapDetection[]> {
const gaps: GapDetection[] = [];
// Check for missing cognitive-intent layers
gaps.push({
gapType: 'cognitive_intent_layer',
description: 'Missing cognitive-intent processing layer',
severity: 'medium',
autoGenerate: false,
});
return gaps;
}
/**
* Detect gaps in DLT systems
*/
private async detectDltGaps(): Promise<GapDetection[]> {
const gaps: GapDetection[] = [];
// Check for missing DLT integration
gaps.push({
gapType: 'dlt_integration',
description: 'Missing DLT ecosystem integration',
severity: 'low',
autoGenerate: false,
});
return gaps;
}
/**
* Detect gaps in metaverse systems
*/
private async detectMetaverseGaps(): Promise<GapDetection[]> {
const gaps: GapDetection[] = [];
// Check for missing metaverse support tools
const metaverseNodes = await prisma.metaverseNode.count();
if (metaverseNodes === 0) {
gaps.push({
gapType: 'metaverse_support_tools',
description: 'Missing metaverse support and integration tools',
severity: 'medium',
autoGenerate: true,
});
}
return gaps;
}
}
export const gapDetectionService = new GapDetectionService();

View File

@@ -0,0 +1,167 @@
// Module Generator Service
// Auto-generation of missing modules (create_module(gap_type))
import prisma from '@/shared/database/prisma';
import { v4 as uuidv4 } from 'uuid';
import { logger } from '@/infrastructure/monitoring/logger';
export class ModuleGeneratorService {
/**
* Generate module for detected gap
* create_module(gap_type)
*/
async generateModule(gapType: string): Promise<string | null> {
logger.info('Module Generator: Generating module', { gapType });
// Determine module type and generate accordingly
let moduleId: string | null = null;
switch (gapType) {
case 'multiverse_settlement_layer':
moduleId = await this.generateMultiverseSettlementLayer();
break;
case 'quantum_financial_interface':
moduleId = await this.generateQuantumFinancialInterface();
break;
case 'metaverse_support_tools':
moduleId = await this.generateMetaverseSupportTools();
break;
case 'fx_layer':
moduleId = await this.generateFxLayer();
break;
case 'identity_anchor':
moduleId = await this.generateIdentityAnchor();
break;
case 'qfs_interface':
moduleId = await this.generateQfsInterface();
break;
case 'settlement_layer':
moduleId = await this.generateSettlementLayer();
break;
default:
logger.warn('Module Generator: Unknown gap type', { gapType });
return null;
}
if (moduleId) {
// Save generated module record
await prisma.generatedModule.create({
data: {
moduleId,
gapType,
moduleType: this.getModuleType(gapType),
status: 'generated',
},
});
}
return moduleId;
}
/**
* Generate multiverse settlement layer
*/
private async generateMultiverseSettlementLayer(): Promise<string> {
const moduleId = `MODULE-MULTIVERSE-SETTLE-${uuidv4()}`;
logger.info('Module Generator: Generated multiverse settlement layer', {
moduleId,
});
return moduleId;
}
/**
* Generate quantum financial interface
*/
private async generateQuantumFinancialInterface(): Promise<string> {
const moduleId = `MODULE-QFS-INTERFACE-${uuidv4()}`;
logger.info('Module Generator: Generated quantum financial interface', {
moduleId,
});
return moduleId;
}
/**
* Generate metaverse support tools
*/
private async generateMetaverseSupportTools(): Promise<string> {
const moduleId = `MODULE-METAVERSE-TOOLS-${uuidv4()}`;
logger.info('Module Generator: Generated metaverse support tools', {
moduleId,
});
return moduleId;
}
/**
* Generate FX layer
*/
private async generateFxLayer(): Promise<string> {
const moduleId = `MODULE-FX-LAYER-${uuidv4()}`;
logger.info('Module Generator: Generated FX layer', { moduleId });
return moduleId;
}
/**
* Generate identity anchor
*/
private async generateIdentityAnchor(): Promise<string> {
const moduleId = `MODULE-IDENTITY-ANCHOR-${uuidv4()}`;
logger.info('Module Generator: Generated identity anchor', { moduleId });
return moduleId;
}
/**
* Generate QFS interface
*/
private async generateQfsInterface(): Promise<string> {
const moduleId = `MODULE-QFS-${uuidv4()}`;
logger.info('Module Generator: Generated QFS interface', { moduleId });
return moduleId;
}
/**
* Generate settlement layer
*/
private async generateSettlementLayer(): Promise<string> {
const moduleId = `MODULE-SETTLE-LAYER-${uuidv4()}`;
logger.info('Module Generator: Generated settlement layer', { moduleId });
return moduleId;
}
/**
* Get module type from gap type
*/
private getModuleType(gapType: string): string {
const typeMap: Record<string, string> = {
multiverse_settlement_layer: 'settlement',
quantum_financial_interface: 'quantum',
metaverse_support_tools: 'metaverse',
fx_layer: 'fx',
identity_anchor: 'identity',
qfs_interface: 'quantum',
settlement_layer: 'settlement',
};
return typeMap[gapType] || 'unknown';
}
/**
* Get generated modules
*/
async getGeneratedModules(gapType?: string) {
return await prisma.generatedModule.findMany({
where: gapType ? { gapType } : {},
orderBy: { createdAt: 'desc' },
});
}
}
export const moduleGeneratorService = new ModuleGeneratorService();

View File

@@ -0,0 +1,97 @@
// Recommendations Engine Service
// System improvements, additional settlement layers, synthetic assets, AI supervisory engines
import { logger } from '@/infrastructure/monitoring/logger';
export interface Recommendation {
type: string;
title: string;
description: string;
priority: 'low' | 'medium' | 'high' | 'critical';
}
export class RecommendationsEngineService {
/**
* Generate recommendations based on detected gaps
*/
async generateRecommendations(gaps: any[]): Promise<Recommendation[]> {
logger.info('Recommendations Engine: Generating recommendations', {
gapsCount: gaps.length,
});
const recommendations: Recommendation[] = [];
// Generate recommendations based on gap types
for (const gap of gaps) {
switch (gap.gapType) {
case 'multiverse_settlement_layer':
recommendations.push({
type: 'settlement_layer',
title: 'Implement Multiverse Settlement Layer',
description:
'Add dedicated settlement layer for multiversal transactions',
priority: 'high',
});
break;
case 'quantum_financial_interface':
recommendations.push({
type: 'quantum_interface',
title: 'Enhance Quantum Financial Interfaces',
description:
'Expand quantum financial system interfaces for better integration',
priority: 'high',
});
break;
case 'metaverse_support_tools':
recommendations.push({
type: 'metaverse_tools',
title: 'Develop Metaverse Support Tools',
description:
'Create additional tools for metaverse economy management',
priority: 'medium',
});
break;
}
}
// Add general recommendations
recommendations.push({
type: 'system_improvement',
title: 'Additional Settlement Layers',
description:
'Consider implementing additional settlement layers for specialized use cases',
priority: 'medium',
});
recommendations.push({
type: 'synthetic_assets',
title: 'New Forms of Synthetic Assets',
description:
'Explore new synthetic asset types for enhanced liquidity options',
priority: 'low',
});
recommendations.push({
type: 'ai_supervisory',
title: 'Parallel AI Supervisory Engines',
description:
'Implement parallel AI supervisory engines for enhanced monitoring',
priority: 'medium',
});
recommendations.push({
type: 'cross_reality',
title: 'Cross-Reality Liquidity Upgrades',
description:
'Enhance cross-reality liquidity mechanisms for better stability',
priority: 'low',
});
return recommendations;
}
}
export const recommendationsEngineService = new RecommendationsEngineService();

View File

@@ -0,0 +1,145 @@
// BEIE Incentive Service
// CBDC micro-rewards and SSU fee adjustments
import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
import { beieMetricsService } from './beie-metrics.service';
export interface CreateIncentiveRequest {
entityId: string;
entityType: string; // retail_cbdc_user, institution, sovereign
incentiveType: string; // cbdc_micro_reward, ssu_fee_adjustment
incentiveAmount?: string;
incentiveReason: string; // stabilizing_behavior, low_risk_flow
expiresAt?: Date;
}
export interface IncentiveResult {
incentiveId: string;
status: string;
}
export class BeieIncentiveService {
/**
* Create behavioral incentive
*/
async createIncentive(request: CreateIncentiveRequest): Promise<IncentiveResult> {
// Calculate incentive amount if not provided
let incentiveAmount = new Decimal(0);
if (request.incentiveAmount) {
incentiveAmount = new Decimal(request.incentiveAmount);
} else {
incentiveAmount = await this.calculateIncentiveAmount(
request.entityId,
request.entityType,
request.incentiveType
);
}
const incentiveId = `BEIE-INC-${uuidv4()}`;
const incentive = await prisma.behavioralIncentive.create({
data: {
incentiveId,
entityId: request.entityId,
entityType: request.entityType,
incentiveType: request.incentiveType,
incentiveAmount,
incentiveReason: request.incentiveReason,
status: 'pending',
expiresAt: request.expiresAt || null,
},
});
// Auto-apply if conditions are met
await this.applyIncentive(incentiveId);
return {
incentiveId: incentive.incentiveId,
status: incentive.status,
};
}
/**
* Calculate incentive amount based on behavior
*/
private async calculateIncentiveAmount(
entityId: string,
entityType: string,
incentiveType: string
): Promise<Decimal> {
// Get behavioral metrics
const metrics = await beieMetricsService.getMetrics(entityId);
let amount = new Decimal(0);
if (incentiveType === 'cbdc_micro_reward') {
// Reward for stabilizing behaviors
const ccv = metrics.find((m) => m.metricType === 'ccv');
if (ccv) {
const ccvValue = parseFloat(ccv.metricValue.toString());
// Higher CCV (spending) = higher reward
amount = new Decimal(ccvValue * 10); // Scale factor
}
} else if (incentiveType === 'ssu_fee_adjustment') {
// Lower fees for low-risk flow patterns
const ilb = metrics.find((m) => m.metricType === 'ilb');
if (ilb) {
const ilbValue = parseFloat(ilb.metricValue.toString());
// Negative ILB (dumping) = fee increase, Positive (hoarding) = fee decrease
amount = new Decimal(ilbValue * -5); // Negative for fee reduction
}
}
return amount;
}
/**
* Apply incentive
*/
async applyIncentive(incentiveId: string): Promise<void> {
const incentive = await prisma.behavioralIncentive.findUnique({
where: { incentiveId },
});
if (!incentive || incentive.status !== 'pending') {
return;
}
// In production, this would actually apply the incentive (transfer funds, adjust fees, etc.)
await prisma.behavioralIncentive.update({
where: { incentiveId },
data: {
status: 'applied',
appliedAt: new Date(),
},
});
}
/**
* Get incentive
*/
async getIncentive(incentiveId: string) {
return await prisma.behavioralIncentive.findUnique({
where: { incentiveId },
});
}
/**
* List incentives for entity
*/
async listIncentives(entityId: string, status?: string) {
return await prisma.behavioralIncentive.findMany({
where: {
entityId,
...(status ? { status } : {}),
},
orderBy: { createdAt: 'desc' },
});
}
}
export const beieIncentiveService = new BeieIncentiveService();

View File

@@ -0,0 +1,137 @@
// BEIE Metrics Service
// CCV, ILB, SRP calculation
import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
export interface CalculateMetricRequest {
entityId: string;
entityType: string; // retail_cbdc_user, institution, sovereign_liquidity_actor
metricType: string; // ccv, ilb, srp
}
export interface MetricResult {
metricId: string;
metricValue: string;
metricType: string;
}
export class BeieMetricsService {
/**
* Calculate behavioral metric
*/
async calculateMetric(request: CalculateMetricRequest): Promise<MetricResult> {
let metricValue: Decimal;
switch (request.metricType) {
case 'ccv':
metricValue = await this.calculateCCV(request.entityId, request.entityType);
break;
case 'ilb':
metricValue = await this.calculateILB(request.entityId, request.entityType);
break;
case 'srp':
metricValue = await this.calculateSRP(request.entityId, request.entityType);
break;
default:
throw new Error(`Unknown metric type: ${request.metricType}`);
}
const metricId = `BEIE-METRIC-${uuidv4()}`;
await prisma.behavioralMetric.create({
data: {
metricId,
entityId: request.entityId,
entityType: request.entityType,
metricType: request.metricType,
metricValue,
calculatedAt: new Date(),
},
});
return {
metricId,
metricValue: metricValue.toString(),
metricType: request.metricType,
};
}
/**
* Calculate Consumer CBDC Velocity (CCV)
* Tracks spending patterns
*/
private async calculateCCV(entityId: string, entityType: string): Promise<Decimal> {
// In production, this would analyze actual CBDC transaction data
// For now, return a simulated value based on entity type
if (entityType !== 'retail_cbdc_user') {
return new Decimal(0);
}
// Simulate CCV calculation (would use real transaction data)
// CCV = total_spending / time_period / average_balance
const simulatedCCV = 0.5 + Math.random() * 0.5; // 0.5 to 1.0
return new Decimal(simulatedCCV);
}
/**
* Calculate Institutional Liquidity Behavior (ILB)
* Predicts institutional hoarding or dumping
*/
private async calculateILB(entityId: string, entityType: string): Promise<Decimal> {
// In production, this would analyze institutional liquidity patterns
if (entityType !== 'institution') {
return new Decimal(0);
}
// Simulate ILB calculation
// ILB = liquidity_velocity / liquidity_holdings_ratio
// Positive = hoarding, Negative = dumping
const simulatedILB = -0.3 + Math.random() * 0.6; // -0.3 to 0.3
return new Decimal(simulatedILB);
}
/**
* Calculate Sovereign Reaction Profile (SRP)
* Forecasts SCB responses to shocks
*/
private async calculateSRP(entityId: string, entityType: string): Promise<Decimal> {
// In production, this would use historical SCB response data
if (entityType !== 'sovereign_liquidity_actor') {
return new Decimal(0);
}
// Simulate SRP calculation
// SRP = reaction_speed * intervention_probability * policy_effectiveness
const simulatedSRP = 0.3 + Math.random() * 0.4; // 0.3 to 0.7
return new Decimal(simulatedSRP);
}
/**
* Get latest metric for entity
*/
async getLatestMetric(entityId: string, metricType: string) {
return await prisma.behavioralMetric.findFirst({
where: {
entityId,
metricType,
},
orderBy: { calculatedAt: 'desc' },
});
}
/**
* Get all metrics for entity
*/
async getMetrics(entityId: string) {
return await prisma.behavioralMetric.findMany({
where: { entityId },
orderBy: { calculatedAt: 'desc' },
});
}
}
export const beieMetricsService = new BeieMetricsService();

View File

@@ -0,0 +1,198 @@
// BEIE Penalty Service
// Predictive penalty contract application
// Logic: if (SRP_risk > threshold) impose_liquidity_penalty()
import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
import { beieMetricsService } from './beie-metrics.service';
export interface CreatePenaltyRequest {
entityId: string;
entityType: string; // retail_cbdc_user, institution, sovereign
penaltyType: string; // liquidity_penalty, fee_increase, access_restriction
penaltyAmount?: string;
penaltyReason: string; // risky_behavior_detected, srp_risk_threshold_exceeded
threshold?: string;
predictiveContract?: Record<string, unknown>;
}
export interface PenaltyResult {
penaltyId: string;
status: string;
}
export class BeiePenaltyService {
/**
* Create behavioral penalty
* Auto-applied when risky behavior detected
*/
async createPenalty(request: CreatePenaltyRequest): Promise<PenaltyResult> {
// Get SRP risk score
const srpMetric = await beieMetricsService.getLatestMetric(
request.entityId,
'srp'
);
let riskScore = new Decimal(0);
if (srpMetric) {
riskScore = srpMetric.metricValue;
} else {
// Calculate SRP if not available
const metric = await beieMetricsService.calculateMetric({
entityId: request.entityId,
entityType: request.entityType,
metricType: 'srp',
});
riskScore = new Decimal(metric.metricValue);
}
// Use provided threshold or default
const threshold = request.threshold
? new Decimal(request.threshold)
: new Decimal(0.5);
// Check if SRP_risk > threshold
if (riskScore.gt(threshold)) {
// Calculate penalty amount if not provided
let penaltyAmount = new Decimal(0);
if (request.penaltyAmount) {
penaltyAmount = new Decimal(request.penaltyAmount);
} else {
penaltyAmount = await this.calculatePenaltyAmount(
request.penaltyType,
riskScore,
threshold
);
}
const penaltyId = `BEIE-PEN-${uuidv4()}`;
const penalty = await prisma.behavioralPenalty.create({
data: {
penaltyId,
entityId: request.entityId,
entityType: request.entityType,
penaltyType: request.penaltyType,
penaltyAmount,
penaltyReason: request.penaltyReason,
riskScore,
threshold,
predictiveContract: request.predictiveContract || null,
status: 'pending',
},
});
// Auto-apply penalty
await this.applyPenalty(penaltyId);
return {
penaltyId: penalty.penaltyId,
status: penalty.status,
};
} else {
throw new Error(
`Risk score ${riskScore.toString()} does not exceed threshold ${threshold.toString()}`
);
}
}
/**
* Calculate penalty amount
*/
private async calculatePenaltyAmount(
penaltyType: string,
riskScore: Decimal,
threshold: Decimal
): Promise<Decimal> {
// Calculate excess risk
const excessRisk = riskScore.minus(threshold);
// Base penalty amounts
const basePenalties: Record<string, number> = {
liquidity_penalty: 1000,
fee_increase: 100,
access_restriction: 0, // No monetary amount
};
const basePenalty = basePenalties[penaltyType] || 100;
// Scale by excess risk
return new Decimal(basePenalty * parseFloat(excessRisk.toString()));
}
/**
* Apply penalty
* Logic: if (SRP_risk > threshold) impose_liquidity_penalty()
*/
async applyPenalty(penaltyId: string): Promise<void> {
const penalty = await prisma.behavioralPenalty.findUnique({
where: { penaltyId },
});
if (!penalty || penalty.status !== 'pending') {
return;
}
// In production, this would actually apply the penalty
// (deduct funds, increase fees, restrict access, etc.)
await prisma.behavioralPenalty.update({
where: { penaltyId },
data: {
status: 'applied',
appliedAt: new Date(),
},
});
}
/**
* Check and auto-apply penalties based on SRP risk
*/
async checkAndApplyPenalties(entityId: string, entityType: string): Promise<void> {
const srpMetric = await beieMetricsService.getLatestMetric(entityId, 'srp');
if (!srpMetric) {
return;
}
const riskScore = srpMetric.metricValue;
const threshold = new Decimal(0.5); // Default threshold
if (riskScore.gt(threshold)) {
// Auto-create and apply penalty
await this.createPenalty({
entityId,
entityType,
penaltyType: 'liquidity_penalty',
penaltyReason: 'srp_risk_threshold_exceeded',
threshold: threshold.toString(),
});
}
}
/**
* Get penalty
*/
async getPenalty(penaltyId: string) {
return await prisma.behavioralPenalty.findUnique({
where: { penaltyId },
});
}
/**
* List penalties for entity
*/
async listPenalties(entityId: string, status?: string) {
return await prisma.behavioralPenalty.findMany({
where: {
entityId,
...(status ? { status } : {}),
},
orderBy: { createdAt: 'desc' },
});
}
}
export const beiePenaltyService = new BeiePenaltyService();

View File

@@ -0,0 +1,145 @@
// BEIE Profile Service
// Behavioral profile management
import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
import { beieMetricsService } from './beie-metrics.service';
export interface CreateProfileRequest {
entityId: string;
entityType: string; // retail_cbdc_user, institution, sovereign
}
export interface ProfileResult {
profileId: string;
riskLevel: string;
}
export class BeieProfileService {
/**
* Create or update behavioral profile
*/
async createOrUpdateProfile(request: CreateProfileRequest): Promise<ProfileResult> {
// Calculate all metrics
const ccv = await beieMetricsService.calculateMetric({
entityId: request.entityId,
entityType: request.entityType,
metricType: 'ccv',
});
const ilb = await beieMetricsService.calculateMetric({
entityId: request.entityId,
entityType: request.entityType,
metricType: 'ilb',
});
const srp = await beieMetricsService.calculateMetric({
entityId: request.entityId,
entityType: request.entityType,
metricType: 'srp',
});
// Calculate risk level
const riskLevel = this.calculateRiskLevel(
parseFloat(ccv.metricValue),
parseFloat(ilb.metricValue),
parseFloat(srp.metricValue)
);
// Check if profile exists
const existing = await prisma.behavioralProfile.findFirst({
where: {
entityId: request.entityId,
entityType: request.entityType,
},
});
if (existing) {
// Update existing profile
const updated = await prisma.behavioralProfile.update({
where: { profileId: existing.profileId },
data: {
ccvScore: new Decimal(ccv.metricValue),
ilbScore: new Decimal(ilb.metricValue),
srpScore: new Decimal(srp.metricValue),
riskLevel,
lastUpdated: new Date(),
},
});
return {
profileId: updated.profileId,
riskLevel: updated.riskLevel,
};
} else {
// Create new profile
const profileId = `BEIE-PROF-${uuidv4()}`;
const profile = await prisma.behavioralProfile.create({
data: {
profileId,
entityId: request.entityId,
entityType: request.entityType,
ccvScore: new Decimal(ccv.metricValue),
ilbScore: new Decimal(ilb.metricValue),
srpScore: new Decimal(srp.metricValue),
riskLevel,
},
});
return {
profileId: profile.profileId,
riskLevel: profile.riskLevel,
};
}
}
/**
* Calculate risk level from metrics
*/
private calculateRiskLevel(ccv: number, ilb: number, srp: number): string {
// Weighted risk calculation
// Higher SRP = higher risk
// Negative ILB (dumping) = higher risk
// Lower CCV = higher risk (not spending)
const riskScore = srp * 0.5 + Math.abs(ilb) * 0.3 + (1 - ccv) * 0.2;
if (riskScore >= 0.7) {
return 'critical';
} else if (riskScore >= 0.5) {
return 'high';
} else if (riskScore >= 0.3) {
return 'medium';
} else {
return 'low';
}
}
/**
* Get profile
*/
async getProfile(entityId: string, entityType: string) {
return await prisma.behavioralProfile.findFirst({
where: {
entityId,
entityType,
},
});
}
/**
* List profiles by risk level
*/
async listProfiles(riskLevel?: string) {
return await prisma.behavioralProfile.findMany({
where: riskLevel ? { riskLevel } : undefined,
orderBy: { lastUpdated: 'desc' },
});
}
}
export const beieProfileService = new BeieProfileService();

View File

@@ -0,0 +1,200 @@
// BEIE API Routes
import { Router } from 'express';
import { beieMetricsService } from './beie-metrics.service';
import { beieIncentiveService } from './beie-incentive.service';
import { beiePenaltyService } from './beie-penalty.service';
import { beieProfileService } from './beie-profile.service';
const router = Router();
/**
* @swagger
* /api/v1/beie/metric:
* post:
* summary: Calculate behavioral metric
*/
router.post('/metric', async (req, res, next) => {
try {
const result = await beieMetricsService.calculateMetric(req.body);
res.json(result);
} catch (error) {
next(error);
}
});
/**
* @swagger
* /api/v1/beie/metrics/:entityId:
* get:
* summary: Get all metrics for entity
*/
router.get('/metrics/:entityId', async (req, res, next) => {
try {
const metrics = await beieMetricsService.getMetrics(req.params.entityId);
res.json(metrics);
} catch (error) {
next(error);
}
});
/**
* @swagger
* /api/v1/beie/incentive:
* post:
* summary: Create behavioral incentive
*/
router.post('/incentive', async (req, res, next) => {
try {
const result = await beieIncentiveService.createIncentive(req.body);
res.json(result);
} catch (error) {
next(error);
}
});
/**
* @swagger
* /api/v1/beie/incentive/:incentiveId:
* get:
* summary: Get incentive
*/
router.get('/incentive/:incentiveId', async (req, res, next) => {
try {
const incentive = await beieIncentiveService.getIncentive(req.params.incentiveId);
if (!incentive) {
return res.status(404).json({ error: 'Incentive not found' });
}
res.json(incentive);
} catch (error) {
next(error);
}
});
/**
* @swagger
* /api/v1/beie/incentives/:entityId:
* get:
* summary: List incentives for entity
*/
router.get('/incentives/:entityId', async (req, res, next) => {
try {
const { status } = req.query;
const incentives = await beieIncentiveService.listIncentives(
req.params.entityId,
status as string | undefined
);
res.json(incentives);
} catch (error) {
next(error);
}
});
/**
* @swagger
* /api/v1/beie/penalty:
* post:
* summary: Create behavioral penalty
*/
router.post('/penalty', async (req, res, next) => {
try {
const result = await beiePenaltyService.createPenalty(req.body);
res.json(result);
} catch (error) {
next(error);
}
});
/**
* @swagger
* /api/v1/beie/penalty/check/:entityId:
* post:
* summary: Check and auto-apply penalties
*/
router.post('/penalty/check/:entityId', async (req, res, next) => {
try {
const { entityType } = req.body;
await beiePenaltyService.checkAndApplyPenalties(req.params.entityId, entityType);
res.json({ status: 'checked' });
} catch (error) {
next(error);
}
});
/**
* @swagger
* /api/v1/beie/penalties/:entityId:
* get:
* summary: List penalties for entity
*/
router.get('/penalties/:entityId', async (req, res, next) => {
try {
const { status } = req.query;
const penalties = await beiePenaltyService.listPenalties(
req.params.entityId,
status as string | undefined
);
res.json(penalties);
} catch (error) {
next(error);
}
});
/**
* @swagger
* /api/v1/beie/profile:
* post:
* summary: Create or update behavioral profile
*/
router.post('/profile', async (req, res, next) => {
try {
const result = await beieProfileService.createOrUpdateProfile(req.body);
res.json(result);
} catch (error) {
next(error);
}
});
/**
* @swagger
* /api/v1/beie/profile/:entityId:
* get:
* summary: Get behavioral profile
*/
router.get('/profile/:entityId', async (req, res, next) => {
try {
const { entityType } = req.query;
if (!entityType) {
return res.status(400).json({ error: 'entityType is required' });
}
const profile = await beieProfileService.getProfile(
req.params.entityId,
entityType as string
);
if (!profile) {
return res.status(404).json({ error: 'Profile not found' });
}
res.json(profile);
} catch (error) {
next(error);
}
});
/**
* @swagger
* /api/v1/beie/profiles:
* get:
* summary: List profiles by risk level
*/
router.get('/profiles', async (req, res, next) => {
try {
const { riskLevel } = req.query;
const profiles = await beieProfileService.listProfiles(riskLevel as string | undefined);
res.json(profiles);
} catch (error) {
next(error);
}
});
export default router;

View File

@@ -0,0 +1,130 @@
// CBDC Transaction Modes - Online, Offline, Dual-Mode
import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { CbdcOfflineCapsule } from '@/shared/types';
import { encryptionService } from '@/infrastructure/encryption/encryption.service';
import { DEFAULT_CONFIG } from '@/shared/constants';
import { v4 as uuidv4 } from 'uuid';
export class CbdcTransactionService {
/**
* Create offline transaction capsule
*/
async createOfflineCapsule(
senderWalletId: string,
receiverWalletId: string,
amount: string
): Promise<CbdcOfflineCapsule> {
const capsuleId = `CAPSULE-${uuidv4()}`;
const doubleSpendToken = encryptionService.generateNonce();
const timestamp = new Date();
// Create signature payload
const payload = JSON.stringify({
capsuleId,
senderWalletId,
receiverWalletId,
amount,
timestamp: timestamp.toISOString(),
doubleSpendToken,
});
const signature = encryptionService.hash(payload);
const capsule = await prisma.cbdcOfflineCapsule.create({
data: {
capsuleId,
senderWalletId,
receiverWalletId,
amount: new Decimal(amount),
timestamp,
expiryWindow: DEFAULT_CONFIG.OFFLINE_CAPSULE_EXPIRY_SECONDS,
doubleSpendToken,
signature,
status: 'pending',
},
});
return {
capsuleId: capsule.capsuleId,
senderWalletId: capsule.senderWalletId,
receiverWalletId: capsule.receiverWalletId,
amount: capsule.amount.toString(),
timestamp: capsule.timestamp,
expiryWindow: capsule.expiryWindow,
doubleSpendToken: capsule.doubleSpendToken,
signature: capsule.signature,
};
}
/**
* Validate and sync offline capsule
*/
async validateAndSyncCapsule(capsuleId: string): Promise<boolean> {
const capsule = await prisma.cbdcOfflineCapsule.findUnique({
where: { capsuleId },
});
if (!capsule) {
return false;
}
// Check expiry
const now = new Date();
const expiryTime = new Date(capsule.timestamp.getTime() + capsule.expiryWindow * 1000);
if (now > expiryTime) {
await prisma.cbdcOfflineCapsule.update({
where: { capsuleId },
data: { status: 'rejected' },
});
return false;
}
// Check double-spend
const existingCapsule = await prisma.cbdcOfflineCapsule.findFirst({
where: {
doubleSpendToken: capsule.doubleSpendToken,
status: { in: ['validated', 'synced'] },
},
});
if (existingCapsule && existingCapsule.capsuleId !== capsuleId) {
await prisma.cbdcOfflineCapsule.update({
where: { capsuleId },
data: { status: 'rejected' },
});
return false;
}
// Validate signature
const payload = JSON.stringify({
capsuleId: capsule.capsuleId,
senderWalletId: capsule.senderWalletId,
receiverWalletId: capsule.receiverWalletId,
amount: capsule.amount.toString(),
timestamp: capsule.timestamp.toISOString(),
doubleSpendToken: capsule.doubleSpendToken,
});
const computedSignature = encryptionService.hash(payload);
if (computedSignature !== capsule.signature) {
return false;
}
// Mark as validated and synced
await prisma.cbdcOfflineCapsule.update({
where: { capsuleId },
data: {
status: 'synced',
syncedAt: new Date(),
},
});
return true;
}
}
export const cbdcTransactionService = new CbdcTransactionService();

View File

@@ -0,0 +1,75 @@
// CBDC Wallet System
import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { CbdcWallet, CbdcWalletType } from '@/shared/types';
import { v4 as uuidv4 } from 'uuid';
export class CbdcWalletService {
/**
* Create CBDC wallet
*/
async createWallet(
sovereignBankId: string,
walletType: CbdcWalletType,
currencyCode: string
): Promise<CbdcWallet> {
const walletId = `WALLET-${uuidv4()}`;
const wallet = await prisma.cbdcWallet.create({
data: {
walletId,
sovereignBankId,
walletType,
currencyCode,
balance: new Decimal(0),
status: 'active',
tieredAccess: this.getDefaultTieredAccess(walletType),
},
});
return {
id: wallet.id,
walletId: wallet.walletId,
sovereignBankId: wallet.sovereignBankId,
walletType: wallet.walletType as CbdcWalletType,
currencyCode: wallet.currencyCode,
balance: wallet.balance.toString(),
status: wallet.status,
tieredAccess: wallet.tieredAccess as Record<string, unknown> | undefined,
};
}
/**
* Get default tiered access configuration
*/
private getDefaultTieredAccess(walletType: CbdcWalletType): Record<string, unknown> {
switch (walletType) {
case CbdcWalletType.RETAIL:
return {
maxTransactionAmount: '10000',
dailyLimit: '50000',
requiresKYC: true,
};
case CbdcWalletType.WHOLESALE:
return {
maxTransactionAmount: '100000000',
dailyLimit: '1000000000',
requiresKYC: true,
};
case CbdcWalletType.INSTITUTIONAL:
return {
maxTransactionAmount: '1000000000',
dailyLimit: '10000000000',
requiresKYC: true,
smartContractEnabled: true,
};
default:
return {};
}
}
}
export const cbdcWalletService = new CbdcWalletService();

View File

@@ -0,0 +1,173 @@
// CBDC Engine - Minting, Burning, Distribution
import { Decimal } from '@prisma/client/runtime/library';
import {
CbdcOperationType,
CbdcIssuance,
AssetType,
} from '@/shared/types';
import { ledgerService } from '@/core/ledger/ledger.service';
import { accountService } from '@/core/accounts/account.service';
import { LedgerEntryType } from '@/shared/types';
import { v4 as uuidv4 } from 'uuid';
import { DbisError, ErrorCode } from '@/shared/types';
import prisma from '@/shared/database/prisma';
export class CbdcService {
/**
* Mint CBDC
*/
async mintCbdc(
sovereignBankId: string,
walletId: string | null,
amount: string,
operatorIdentity: string,
reason?: string
): Promise<CbdcIssuance> {
// Verify 1:1 reserve backing
await this.verifyReserveBacking(sovereignBankId, amount);
const recordId = `CBDC-MINT-${uuidv4()}`;
// Get treasury account for the sovereign bank
const treasuryAccount = await this.getTreasuryAccount(sovereignBankId, 'OMDC');
// Create CBDC issuance record
const issuance = await prisma.cbdcIssuance.create({
data: {
recordId,
sovereignBankId,
walletId,
amountMinted: new Decimal(amount),
amountBurned: new Decimal(0),
netChange: new Decimal(amount),
operationType: CbdcOperationType.MINT,
operatorIdentity,
reserveBacking: new Decimal(amount), // 1:1 backing
timestampUtc: new Date(),
metadata: reason ? { reason } : null,
},
});
// Create ledger entry
const ledgerId = `${sovereignBankId}-CBDC`;
await ledgerService.postDoubleEntry(
ledgerId,
treasuryAccount.id, // Debit: Treasury account
treasuryAccount.id, // Credit: CBDC wallet (simplified)
amount,
'OMDC',
AssetType.CBDC,
LedgerEntryType.TYPE_B, // CBDC issuance
recordId,
undefined,
{ operationType: 'mint', walletId, reason }
);
return this.mapToCbdcIssuance(issuance);
}
/**
* Burn CBDC
*/
async burnCbdc(
sovereignBankId: string,
walletId: string | null,
amount: string,
operatorIdentity: string,
reason?: string
): Promise<CbdcIssuance> {
const recordId = `CBDC-BURN-${uuidv4()}`;
// Get treasury account
const treasuryAccount = await this.getTreasuryAccount(sovereignBankId, 'OMDC');
// Create CBDC issuance record
const issuance = await prisma.cbdcIssuance.create({
data: {
recordId,
sovereignBankId,
walletId,
amountMinted: new Decimal(0),
amountBurned: new Decimal(amount),
netChange: new Decimal(amount).neg(),
operationType: CbdcOperationType.BURN,
operatorIdentity,
timestampUtc: new Date(),
metadata: reason ? { reason } : null,
},
});
// Create ledger entry
const ledgerId = `${sovereignBankId}-CBDC`;
await ledgerService.postDoubleEntry(
ledgerId,
treasuryAccount.id, // Debit: CBDC wallet
treasuryAccount.id, // Credit: Treasury account (simplified)
amount,
'OMDC',
AssetType.CBDC,
LedgerEntryType.TYPE_B, // CBDC redemption
recordId,
undefined,
{ operationType: 'burn', walletId, reason }
);
return this.mapToCbdcIssuance(issuance);
}
/**
* Verify 1:1 reserve backing
*/
private async verifyReserveBacking(sovereignBankId: string, amount: string): Promise<void> {
// Get reserve account
const reserveAccount = await this.getTreasuryAccount(sovereignBankId, 'OMF');
const reserveBalance = parseFloat(reserveAccount.balance);
const mintAmount = parseFloat(amount);
if (reserveBalance < mintAmount) {
throw new DbisError(
ErrorCode.VALIDATION_ERROR,
'Insufficient reserve backing for CBDC minting'
);
}
}
/**
* Get treasury account for a sovereign bank
*/
private async getTreasuryAccount(sovereignBankId: string, currencyCode: string) {
const accounts = await accountService.getAccountsBySovereign(sovereignBankId);
const treasuryAccount = accounts.find(
(acc) => acc.accountType === 'treasury' && acc.currencyCode === currencyCode
);
if (!treasuryAccount) {
throw new DbisError(ErrorCode.NOT_FOUND, 'Treasury account not found');
}
return treasuryAccount;
}
/**
* Map Prisma model to CbdcIssuance type
*/
private mapToCbdcIssuance(issuance: any): CbdcIssuance {
return {
id: issuance.id,
recordId: issuance.recordId,
sovereignBankId: issuance.sovereignBankId,
walletId: issuance.walletId || undefined,
amountMinted: issuance.amountMinted.toString(),
amountBurned: issuance.amountBurned.toString(),
netChange: issuance.netChange.toString(),
operationType: issuance.operationType as CbdcOperationType,
operatorIdentity: issuance.operatorIdentity,
reserveBacking: issuance.reserveBacking?.toString(),
timestampUtc: issuance.timestampUtc,
};
}
}
export const cbdcService = new CbdcService();

View File

@@ -0,0 +1,101 @@
// FACE Behavioral Engine Service
// AI behavioral engine (integrates with Volume V SARE)
import prisma from '@/shared/database/prisma';
import { v4 as uuidv4 } from 'uuid';
export interface CreateBehavioralEngineRequest {
economyId: string;
engineConfig: Record<string, unknown>;
behaviorModel: string;
}
export class FaceBehavioralService {
/**
* Create or update behavioral engine
*/
async createBehavioralEngine(request: CreateBehavioralEngineRequest) {
// Check if engine already exists
const existing = await prisma.faceBehavioralEngine.findUnique({
where: { economyId: request.economyId },
});
if (existing) {
return prisma.faceBehavioralEngine.update({
where: { engineId: existing.engineId },
data: {
engineConfig: request.engineConfig,
behaviorModel: request.behaviorModel,
lastUpdated: new Date(),
},
});
}
const engineId = `FACE-BE-${uuidv4()}`;
const engine = await prisma.faceBehavioralEngine.create({
data: {
engineId,
economyId: request.economyId,
engineConfig: request.engineConfig,
behaviorModel: request.behaviorModel,
status: 'active',
lastUpdated: new Date(),
},
});
return engine;
}
/**
* Get behavioral engine for economy
*/
async getBehavioralEngine(economyId: string) {
const engine = await prisma.faceBehavioralEngine.findUnique({
where: { economyId },
include: {
economy: true,
},
});
if (!engine) {
throw new Error(`Behavioral engine not found for economy: ${economyId}`);
}
return engine;
}
/**
* Analyze behavior (integrates with SARE from Volume V)
*/
async analyzeBehavior(economyId: string, behaviorData: Record<string, unknown>) {
const engine = await this.getBehavioralEngine(economyId);
// In production, this would:
// 1. Feed behavior data to AI model
// 2. Integrate with SARE (Sovereign AI Risk Engine) from Volume V
// 3. Generate behavioral insights and predictions
// Mock analysis
const analysis = {
velocity: behaviorData.velocity as number || 0,
circulation: behaviorData.circulation as number || 0,
riskLevel: 'medium',
recommendations: [] as string[],
};
if (analysis.velocity < 0.5) {
analysis.recommendations.push('Low velocity detected - consider supply adjustment');
}
if (analysis.velocity > 2.0) {
analysis.recommendations.push('High velocity detected - consider stabilization measures');
}
return analysis;
}
}
export const faceBehavioralService = new FaceBehavioralService();

View File

@@ -0,0 +1,107 @@
// FACE Economy Service
// Economy lifecycle management
import prisma from '@/shared/database/prisma';
import { v4 as uuidv4 } from 'uuid';
export interface CreateFaceEconomyRequest {
sovereignBankId: string;
economyName: string;
description: string;
economyType: 'retail' | 'wholesale' | 'hybrid';
}
export class FaceEconomyService {
/**
* Create FACE economy
*/
async createEconomy(request: CreateFaceEconomyRequest) {
const economyId = `FACE-${uuidv4()}`;
const economy = await prisma.faceEconomy.create({
data: {
economyId,
sovereignBankId: request.sovereignBankId,
economyName: request.economyName,
description: request.description,
economyType: request.economyType,
status: 'active',
activatedAt: new Date(),
},
});
return economy;
}
/**
* Get economy by ID
*/
async getEconomy(economyId: string) {
const economy = await prisma.faceEconomy.findUnique({
where: { economyId },
include: {
sovereignBank: true,
behavioralEngine: true,
supplyContracts: true,
stabilizationContracts: true,
incentives: true,
},
});
if (!economy) {
throw new Error(`Economy not found: ${economyId}`);
}
return economy;
}
/**
* Get economies for sovereign bank
*/
async getEconomiesForBank(sovereignBankId: string) {
return prisma.faceEconomy.findMany({
where: {
sovereignBankId,
status: 'active',
},
include: {
behavioralEngine: true,
_count: {
select: {
supplyContracts: true,
stabilizationContracts: true,
incentives: true,
},
},
},
});
}
/**
* Suspend economy
*/
async suspendEconomy(economyId: string) {
return prisma.faceEconomy.update({
where: { economyId },
data: {
status: 'suspended',
},
});
}
/**
* Archive economy
*/
async archiveEconomy(economyId: string) {
return prisma.faceEconomy.update({
where: { economyId },
data: {
status: 'archived',
},
});
}
}
export const faceEconomyService = new FaceEconomyService();

View File

@@ -0,0 +1,147 @@
// FACE Incentive Service
// Reward/penalty system
import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
export interface CreateIncentiveRequest {
economyId: string;
incentiveType: 'reward' | 'penalty' | 'predictive_nudge';
targetBehavior: string;
incentiveAmount: number;
conditions: Record<string, unknown>;
}
export class FaceIncentiveService {
/**
* Create incentive
*/
async createIncentive(request: CreateIncentiveRequest) {
const incentiveId = `FACE-INC-${uuidv4()}`;
const incentive = await prisma.faceIncentive.create({
data: {
incentiveId,
economyId: request.economyId,
incentiveType: request.incentiveType,
targetBehavior: request.targetBehavior,
incentiveAmount: new Decimal(request.incentiveAmount),
conditions: request.conditions,
status: 'active',
},
});
return incentive;
}
/**
* Check and apply incentive
*/
async checkAndApplyIncentive(
incentiveId: string,
behaviorData: Record<string, unknown>
) {
const incentive = await prisma.faceIncentive.findUnique({
where: { incentiveId },
include: {
economy: true,
},
});
if (!incentive) {
throw new Error(`Incentive not found: ${incentiveId}`);
}
if (incentive.status !== 'active') {
return { applied: false, reason: 'Incentive not active' };
}
// Check conditions
const conditionsMet = this.checkConditions(incentive.conditions, behaviorData);
if (!conditionsMet) {
return { applied: false, reason: 'Conditions not met' };
}
// Apply incentive
// In production, this would:
// - For rewards: credit CBDC wallet, apply fee reduction, etc.
// - For penalties: charge fee, restrict access, etc.
// - For predictive nudges: send notification, adjust rates, etc.
await prisma.faceIncentive.update({
where: { incentiveId },
data: {
status: 'applied',
appliedAt: new Date(),
},
});
return {
applied: true,
incentiveType: incentive.incentiveType,
amount: incentive.incentiveAmount.toString(),
targetBehavior: incentive.targetBehavior,
};
}
/**
* Check if conditions are met
*/
private checkConditions(
conditions: Record<string, unknown>,
behaviorData: Record<string, unknown>
): boolean {
// Simple condition checking
// In production, would use more sophisticated rule engine
for (const [key, value] of Object.entries(conditions)) {
if (key === 'min_velocity' && (behaviorData.velocity as number) < (value as number)) {
return false;
}
if (key === 'max_velocity' && (behaviorData.velocity as number) > (value as number)) {
return false;
}
if (key === 'min_circulation' && (behaviorData.circulation as number) < (value as number)) {
return false;
}
}
return true;
}
/**
* Get incentives for economy
*/
async getIncentivesForEconomy(economyId: string) {
return prisma.faceIncentive.findMany({
where: { economyId },
orderBy: {
createdAt: 'desc',
},
});
}
/**
* Get incentive by ID
*/
async getIncentive(incentiveId: string) {
const incentive = await prisma.faceIncentive.findUnique({
where: { incentiveId },
include: {
economy: true,
},
});
if (!incentive) {
throw new Error(`Incentive not found: ${incentiveId}`);
}
return incentive;
}
}
export const faceIncentiveService = new FaceIncentiveService();

View File

@@ -0,0 +1,136 @@
// FACE Stabilization Contract Service
// Auto-stabilization: if SRI_risk > threshold: impose_rate_adjustment()
import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
import { sriCalculatorService } from '@/core/risk/sri/sri-calculator.service';
export interface CreateStabilizationContractRequest {
economyId: string;
sriThreshold: number;
rateAdjustmentRule: Record<string, unknown>;
adjustmentType: 'interest_rate' | 'liquidity_rate' | 'fee_adjustment';
}
export class FaceStabilizationService {
/**
* Create stabilization contract
*/
async createStabilizationContract(request: CreateStabilizationContractRequest) {
const contractId = `FACE-STAB-${uuidv4()}`;
const contract = await prisma.faceStabilizationContract.create({
data: {
contractId,
economyId: request.economyId,
contractType: 'auto_stabilization',
sriThreshold: new Decimal(request.sriThreshold),
rateAdjustmentRule: request.rateAdjustmentRule || {
rule: 'if SRI_risk > threshold: impose_rate_adjustment()',
},
adjustmentType: request.adjustmentType,
status: 'active',
},
});
return contract;
}
/**
* Check and execute stabilization contract
*/
async checkStabilizationContract(contractId: string) {
const contract = await prisma.faceStabilizationContract.findUnique({
where: { contractId },
include: {
economy: true,
},
});
if (!contract) {
throw new Error(`Stabilization contract not found: ${contractId}`);
}
if (contract.status !== 'active') {
return { triggered: false, reason: 'Contract not active' };
}
// Get current SRI for the sovereign bank
const sriResult = await sriCalculatorService.calculateSRI(contract.economy.sovereignBankId);
const currentSRI = sriResult.sriScore;
const threshold = parseFloat(contract.sriThreshold.toString());
// if SRI_risk > threshold: impose_rate_adjustment()
if (currentSRI > threshold) {
// Calculate adjustment based on SRI excess
const excess = currentSRI - threshold;
const adjustmentPercentage = Math.min(excess * 0.1, 5); // Max 5% adjustment
// In production, this would actually adjust rates in the system
// For now, just record the adjustment
const adjustment = {
type: contract.adjustmentType,
percentage: adjustmentPercentage,
sriExcess: excess,
timestamp: new Date().toISOString(),
};
// Update contract
await prisma.faceStabilizationContract.update({
where: { contractId },
data: {
lastTriggeredAt: new Date(),
},
});
return {
triggered: true,
currentSRI,
threshold,
adjustment,
};
}
return {
triggered: false,
reason: 'SRI within acceptable threshold',
currentSRI,
threshold,
};
}
/**
* Get stabilization contracts for economy
*/
async getContractsForEconomy(economyId: string) {
return prisma.faceStabilizationContract.findMany({
where: { economyId },
orderBy: {
createdAt: 'desc',
},
});
}
/**
* Get contract by ID
*/
async getContract(contractId: string) {
const contract = await prisma.faceStabilizationContract.findUnique({
where: { contractId },
include: {
economy: true,
},
});
if (!contract) {
throw new Error(`Stabilization contract not found: ${contractId}`);
}
return contract;
}
}
export const faceStabilizationService = new FaceStabilizationService();

View File

@@ -0,0 +1,164 @@
// FACE Supply Contract Service
// Automatic supply contracts: if velocity < target: mint_cbdc() elif velocity > danger_threshold: burn_cbdc()
import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
import { cbdcService } from '@/core/cbdc/cbdc.service';
export interface CreateSupplyContractRequest {
economyId: string;
velocityTarget: number;
velocityDangerThreshold: number;
mintCondition?: Record<string, unknown>;
burnCondition?: Record<string, unknown>;
}
export class FaceSupplyService {
/**
* Create supply contract
*/
async createSupplyContract(request: CreateSupplyContractRequest) {
const contractId = `FACE-SUPPLY-${uuidv4()}`;
const contract = await prisma.faceSupplyContract.create({
data: {
contractId,
economyId: request.economyId,
contractType: 'automatic_supply_adjustment',
velocityTarget: new Decimal(request.velocityTarget),
velocityDangerThreshold: new Decimal(request.velocityDangerThreshold),
mintCondition: request.mintCondition || {
condition: 'if velocity < target: mint_cbdc()',
},
burnCondition: request.burnCondition || {
condition: 'elif velocity > danger_threshold: burn_cbdc()',
},
status: 'active',
},
});
return contract;
}
/**
* Check and execute supply contract
*/
async checkSupplyContract(contractId: string, currentVelocity: number) {
const contract = await prisma.faceSupplyContract.findUnique({
where: { contractId },
include: {
economy: true,
},
});
if (!contract) {
throw new Error(`Supply contract not found: ${contractId}`);
}
if (contract.status !== 'active') {
return { triggered: false, reason: 'Contract not active' };
}
const velocity = new Decimal(currentVelocity);
const target = contract.velocityTarget;
const dangerThreshold = contract.velocityDangerThreshold;
let action: 'mint' | 'burn' | null = null;
let amount: Decimal | null = null;
// if velocity < target: mint_cbdc()
if (velocity.lt(target)) {
action = 'mint';
// Calculate mint amount based on velocity gap
const gap = target.minus(velocity);
amount = gap.times(1000000); // Simplified: 1M per 0.1 velocity gap
}
// elif velocity > danger_threshold: burn_cbdc()
else if (velocity.gt(dangerThreshold)) {
action = 'burn';
// Calculate burn amount based on excess velocity
const excess = velocity.minus(dangerThreshold);
amount = excess.times(1000000); // Simplified: 1M per 0.1 velocity excess
}
if (action && amount) {
// Execute action
const economy = contract.economy;
const operatorIdentity = `FACE-AUTO-${contractId}`;
if (action === 'mint') {
await cbdcService.mintCbdc(
economy.sovereignBankId,
null, // No specific wallet
amount.toString(),
operatorIdentity,
`FACE automatic supply adjustment: velocity ${currentVelocity} < target ${target}`
);
} else if (action === 'burn') {
await cbdcService.burnCbdc(
economy.sovereignBankId,
null, // No specific wallet
amount.toString(),
operatorIdentity,
`FACE automatic supply adjustment: velocity ${currentVelocity} > danger threshold ${dangerThreshold}`
);
}
// Update contract
await prisma.faceSupplyContract.update({
where: { contractId },
data: {
lastTriggeredAt: new Date(),
},
});
return {
triggered: true,
action,
amount: amount.toString(),
velocity: currentVelocity,
};
}
return {
triggered: false,
reason: 'Velocity within acceptable range',
velocity: currentVelocity,
};
}
/**
* Get supply contracts for economy
*/
async getContractsForEconomy(economyId: string) {
return prisma.faceSupplyContract.findMany({
where: { economyId },
orderBy: {
createdAt: 'desc',
},
});
}
/**
* Get contract by ID
*/
async getContract(contractId: string) {
const contract = await prisma.faceSupplyContract.findUnique({
where: { contractId },
include: {
economy: true,
},
});
if (!contract) {
throw new Error(`Supply contract not found: ${contractId}`);
}
return contract;
}
}
export const faceSupplyService = new FaceSupplyService();

View File

@@ -0,0 +1,153 @@
// FACE API Routes
import { Router } from 'express';
import { faceEconomyService } from './face-economy.service';
import { faceBehavioralService } from './face-behavioral.service';
import { faceSupplyService } from './face-supply.service';
import { faceStabilizationService } from './face-stabilization.service';
import { faceIncentiveService } from './face-incentive.service';
const router = Router();
// Economy routes
router.post('/economies', async (req, res, next) => {
try {
const economy = await faceEconomyService.createEconomy(req.body);
res.json(economy);
} catch (error) {
next(error);
}
});
router.get('/economies', async (req, res, next) => {
try {
const economies = await faceEconomyService.getEconomiesForBank(req.query.sovereignBankId as string);
res.json(economies);
} catch (error) {
next(error);
}
});
router.get('/economies/:economyId', async (req, res, next) => {
try {
const economy = await faceEconomyService.getEconomy(req.params.economyId);
res.json(economy);
} catch (error) {
next(error);
}
});
// Behavioral engine routes
router.post('/behavioral', async (req, res, next) => {
try {
const engine = await faceBehavioralService.createBehavioralEngine(req.body);
res.json(engine);
} catch (error) {
next(error);
}
});
router.get('/behavioral/:economyId', async (req, res, next) => {
try {
const engine = await faceBehavioralService.getBehavioralEngine(req.params.economyId);
res.json(engine);
} catch (error) {
next(error);
}
});
router.post('/behavioral/:economyId/analyze', async (req, res, next) => {
try {
const analysis = await faceBehavioralService.analyzeBehavior(req.params.economyId, req.body);
res.json(analysis);
} catch (error) {
next(error);
}
});
// Supply contract routes
router.post('/supply', async (req, res, next) => {
try {
const contract = await faceSupplyService.createSupplyContract(req.body);
res.json(contract);
} catch (error) {
next(error);
}
});
router.get('/supply/:economyId', async (req, res, next) => {
try {
const contracts = await faceSupplyService.getContractsForEconomy(req.params.economyId);
res.json(contracts);
} catch (error) {
next(error);
}
});
router.post('/supply/:contractId/check', async (req, res, next) => {
try {
const result = await faceSupplyService.checkSupplyContract(req.params.contractId, req.body.currentVelocity);
res.json(result);
} catch (error) {
next(error);
}
});
// Stabilization contract routes
router.post('/stabilization', async (req, res, next) => {
try {
const contract = await faceStabilizationService.createStabilizationContract(req.body);
res.json(contract);
} catch (error) {
next(error);
}
});
router.get('/stabilization/:economyId', async (req, res, next) => {
try {
const contracts = await faceStabilizationService.getContractsForEconomy(req.params.economyId);
res.json(contracts);
} catch (error) {
next(error);
}
});
router.post('/stabilization/:contractId/check', async (req, res, next) => {
try {
const result = await faceStabilizationService.checkStabilizationContract(req.params.contractId);
res.json(result);
} catch (error) {
next(error);
}
});
// Incentive routes
router.post('/incentives', async (req, res, next) => {
try {
const incentive = await faceIncentiveService.createIncentive(req.body);
res.json(incentive);
} catch (error) {
next(error);
}
});
router.get('/incentives/:economyId', async (req, res, next) => {
try {
const incentives = await faceIncentiveService.getIncentivesForEconomy(req.params.economyId);
res.json(incentives);
} catch (error) {
next(error);
}
});
router.post('/incentives/:incentiveId/apply', async (req, res, next) => {
try {
const result = await faceIncentiveService.checkAndApplyIncentive(req.params.incentiveId, req.body);
res.json(result);
} catch (error) {
next(error);
}
});
export default router;

View File

@@ -0,0 +1,41 @@
// CBDC Compliance Board Service
// CCEB enforcement
import prisma from '@/shared/database/prisma';
import { v4 as uuidv4 } from 'uuid';
export class CbdcComplianceBoardService {
/**
* Initialize or get CCEB
*/
async initializeCCEB() {
const existing = await prisma.cbdcComplianceBoard.findFirst({
where: { status: 'active' },
});
if (existing) {
return existing;
}
return await prisma.cbdcComplianceBoard.create({
data: {
boardId: `CCEB-${uuidv4()}`,
boardName: 'CBDC Compliance & Enforcement Board',
memberCount: 0,
enforcementLevel: 'binding',
status: 'active',
},
});
}
/**
* Get CCEB
*/
async getCCEB() {
return await this.initializeCCEB();
}
}
export const cbdcComplianceBoardService = new CbdcComplianceBoardService();

View File

@@ -0,0 +1,48 @@
// CBDC Governance API Routes
import { Router } from 'express';
import { cbdcSupplyControlService } from './cbdc-supply-control.service';
import { cbdcVelocityControlService } from './cbdc-velocity-control.service';
import { cbdcLiquidityManagementService } from './cbdc-liquidity-management.service';
import { cbdcMonetarySimulationService } from './cbdc-monetary-simulation.service';
const router = Router();
router.post('/supply-control', async (req, res, next) => {
try {
const control = await cbdcSupplyControlService.createSupplyControl(req.body);
res.status(201).json(control);
} catch (error) {
next(error);
}
});
router.post('/velocity-control', async (req, res, next) => {
try {
const control = await cbdcVelocityControlService.createVelocityControl(req.body);
res.status(201).json(control);
} catch (error) {
next(error);
}
});
router.post('/liquidity-window', async (req, res, next) => {
try {
const window = await cbdcLiquidityManagementService.createLiquidityWindow(req.body);
res.status(201).json(window);
} catch (error) {
next(error);
}
});
router.post('/simulation', async (req, res, next) => {
try {
const simulation = await cbdcMonetarySimulationService.runSimulation(req.body);
res.json(simulation);
} catch (error) {
next(error);
}
});
export default router;

View File

@@ -0,0 +1,103 @@
// CBDC Liquidity Management Service
// Liquidity windows, CBDC-to-SSU swaps
import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
export interface LiquidityWindowRequest {
sovereignBankId: string;
windowType: string; // standing, emergency
availableLiquidity: number;
swapRate?: number;
}
export class CbdcLiquidityManagementService {
/**
* Create liquidity window
*/
async createLiquidityWindow(request: LiquidityWindowRequest) {
return await prisma.cbdcLiquidityWindow.create({
data: {
windowId: `WINDOW-${uuidv4()}`,
sovereignBankId: request.sovereignBankId,
windowType: request.windowType,
availableLiquidity: new Decimal(request.availableLiquidity),
swapRate: request.swapRate ? new Decimal(request.swapRate) : null,
status: 'open',
},
});
}
/**
* Close liquidity window
*/
async closeLiquidityWindow(windowId: string) {
return await prisma.cbdcLiquidityWindow.update({
where: { windowId },
data: {
status: 'closed',
closedAt: new Date(),
},
});
}
/**
* Get open liquidity windows
*/
async getOpenWindows(sovereignBankId?: string) {
const where: any = {
status: 'open',
};
if (sovereignBankId) {
where.sovereignBankId = sovereignBankId;
}
return await prisma.cbdcLiquidityWindow.findMany({
where,
});
}
/**
* Execute CBDC-to-SSU swap
*/
async executeCbdcToSsuSwap(
windowId: string,
cbdcAmount: number,
swapRate: number
) {
const window = await prisma.cbdcLiquidityWindow.findUnique({
where: { windowId },
});
if (!window || window.status !== 'open') {
throw new Error('Liquidity window not available');
}
const ssuAmount = cbdcAmount * swapRate;
const available = parseFloat(window.availableLiquidity.toString());
if (available < cbdcAmount) {
throw new Error('Insufficient liquidity');
}
// Update available liquidity
await prisma.cbdcLiquidityWindow.update({
where: { windowId },
data: {
availableLiquidity: new Decimal(available - cbdcAmount),
},
});
return {
cbdcAmount,
ssuAmount,
swapRate,
};
}
}
export const cbdcLiquidityManagementService = new CbdcLiquidityManagementService();

View File

@@ -0,0 +1,53 @@
// CBDC Monetary Committee Service
// SCB Monetary Committees
import prisma from '@/shared/database/prisma';
import { v4 as uuidv4 } from 'uuid';
export class CbdcMonetaryCommitteeService {
/**
* Create monetary committee
*/
async createCommittee(
sovereignBankId: string,
committeeName: string,
memberCount?: number,
votingMechanism: string = 'simple_majority'
) {
return await prisma.cbdcMonetaryCommittee.create({
data: {
committeeId: `COMMITTEE-${uuidv4()}`,
sovereignBankId,
committeeName,
memberCount,
votingMechanism,
status: 'active',
},
});
}
/**
* Get committee by ID
*/
async getCommittee(committeeId: string) {
return await prisma.cbdcMonetaryCommittee.findUnique({
where: { committeeId },
});
}
/**
* Get committees for bank
*/
async getCommitteesForBank(sovereignBankId: string) {
return await prisma.cbdcMonetaryCommittee.findMany({
where: {
sovereignBankId,
status: 'active',
},
});
}
}
export const cbdcMonetaryCommitteeService = new CbdcMonetaryCommitteeService();

View File

@@ -0,0 +1,133 @@
// CBDC Monetary Simulation Service
// Simulation: impact = CBDC_supply_change * velocity_factor * FX_reserve_strength
import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
export interface MonetarySimulationRequest {
simulationType: string;
sovereignBankId?: string;
supplyChange?: number;
velocityFactor?: number;
fxReserveStrength?: number;
}
export class CbdcMonetarySimulationService {
/**
* Run monetary simulation
*/
async runSimulation(request: MonetarySimulationRequest) {
const simulationId = `SIM-${uuidv4()}`;
const simulation = await prisma.cbdcMonetarySimulation.create({
data: {
simulationId,
sovereignBankId: request.sovereignBankId,
simulationType: request.simulationType,
supplyChange: request.supplyChange ? new Decimal(request.supplyChange) : null,
velocityFactor: request.velocityFactor ? new Decimal(request.velocityFactor) : null,
fxReserveStrength: request.fxReserveStrength ? new Decimal(request.fxReserveStrength) : null,
status: 'running',
},
});
// Calculate impact score
const impactScore = this.calculateImpactScore(
request.supplyChange || 0,
request.velocityFactor || 1,
request.fxReserveStrength || 1
);
// Run simulation logic based on type
const simulationResults = await this.executeSimulation(
request.simulationType,
impactScore,
request
);
// Update simulation with results
await prisma.cbdcMonetarySimulation.update({
where: { simulationId },
data: {
impactScore: new Decimal(impactScore),
simulationResults,
status: 'completed',
completedAt: new Date(),
},
});
return simulation;
}
/**
* Calculate impact score
*/
private calculateImpactScore(
supplyChange: number,
velocityFactor: number,
fxReserveStrength: number
): number {
// impact = CBDC_supply_change * velocity_factor * FX_reserve_strength
return supplyChange * velocityFactor * fxReserveStrength;
}
/**
* Execute simulation based on type
*/
private async executeSimulation(
simulationType: string,
impactScore: number,
request: MonetarySimulationRequest
): Promise<Record<string, unknown>> {
// Simulate different types
const results: Record<string, unknown> = {
impactScore,
simulationType,
};
switch (simulationType) {
case 'cross_border_flows':
results.flows = {};
break;
case 'liquidity_shock':
results.shockImpact = {};
break;
case 'fx_spillover':
results.spilloverEffect = {};
break;
case 'commodity_backed_circulation':
results.circulation = {};
break;
}
return results;
}
/**
* Get simulation by ID
*/
async getSimulation(simulationId: string) {
return await prisma.cbdcMonetarySimulation.findUnique({
where: { simulationId },
});
}
/**
* Get simulations by type
*/
async getSimulationsByType(simulationType: string) {
return await prisma.cbdcMonetarySimulation.findMany({
where: {
simulationType,
},
orderBy: {
startedAt: 'desc',
},
});
}
}
export const cbdcMonetarySimulationService = new CbdcMonetarySimulationService();

View File

@@ -0,0 +1,87 @@
// CBDC Supply Control Service
// Issue/Burn with dual-signature, stress-adjusted caps
import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
export interface SupplyControlRequest {
sovereignBankId: string;
operationType: string; // issue, burn
amount: number;
dualSignature1: string;
dualSignature2: string;
stressAdjustedCap?: number;
committeeId?: string;
}
export class CbdcSupplyControlService {
/**
* Create supply control operation
*/
async createSupplyControl(request: SupplyControlRequest) {
return await prisma.cbdcSupplyControl.create({
data: {
controlId: `SUPPLY-${uuidv4()}`,
committeeId: request.committeeId,
sovereignBankId: request.sovereignBankId,
operationType: request.operationType,
amount: new Decimal(request.amount),
dualSignature1: request.dualSignature1,
dualSignature2: request.dualSignature2,
stressAdjustedCap: request.stressAdjustedCap ? new Decimal(request.stressAdjustedCap) : null,
status: 'pending',
},
});
}
/**
* Approve supply control
*/
async approveSupplyControl(controlId: string) {
return await prisma.cbdcSupplyControl.update({
where: { controlId },
data: {
status: 'approved',
approvedAt: new Date(),
},
});
}
/**
* Execute supply control
*/
async executeSupplyControl(controlId: string) {
return await prisma.cbdcSupplyControl.update({
where: { controlId },
data: {
status: 'executed',
executedAt: new Date(),
},
});
}
/**
* Get supply controls
*/
async getSupplyControls(sovereignBankId?: string, status?: string) {
const where: any = {};
if (sovereignBankId) {
where.sovereignBankId = sovereignBankId;
}
if (status) {
where.status = status;
}
return await prisma.cbdcSupplyControl.findMany({
where,
orderBy: {
createdAt: 'desc',
},
});
}
}
export const cbdcSupplyControlService = new CbdcSupplyControlService();

View File

@@ -0,0 +1,95 @@
// CBDC Velocity Control Service
// Wallet limits, spending categories, throttles
import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
export interface VelocityControlRequest {
sovereignBankId: string;
walletId?: string;
walletLevelLimit?: number;
spendingCategory?: string;
timeBasedThrottle?: Record<string, unknown>;
committeeId?: string;
effectiveDate: Date;
expiryDate?: Date;
}
export class CbdcVelocityControlService {
/**
* Create velocity control
*/
async createVelocityControl(request: VelocityControlRequest) {
return await prisma.cbdcVelocityControl.create({
data: {
controlId: `VELOCITY-${uuidv4()}`,
committeeId: request.committeeId,
sovereignBankId: request.sovereignBankId,
walletId: request.walletId,
walletLevelLimit: request.walletLevelLimit ? new Decimal(request.walletLevelLimit) : null,
spendingCategory: request.spendingCategory,
timeBasedThrottle: request.timeBasedThrottle || null,
status: 'active',
effectiveDate: request.effectiveDate,
expiryDate: request.expiryDate || null,
},
});
}
/**
* Get active velocity controls
*/
async getActiveControls(sovereignBankId?: string, walletId?: string) {
const where: any = {
status: 'active',
effectiveDate: {
lte: new Date(),
},
OR: [
{ expiryDate: null },
{ expiryDate: { gte: new Date() } },
],
};
if (sovereignBankId) {
where.sovereignBankId = sovereignBankId;
}
if (walletId) {
where.walletId = walletId;
}
return await prisma.cbdcVelocityControl.findMany({
where,
});
}
/**
* Check velocity limit
*/
async checkVelocityLimit(
walletId: string,
amount: number,
category?: string
): Promise<boolean> {
const controls = await this.getActiveControls(undefined, walletId);
for (const control of controls) {
// Check category match
if (control.spendingCategory && category && control.spendingCategory !== category) {
continue;
}
// Check wallet level limit
if (control.walletLevelLimit && amount > parseFloat(control.walletLevelLimit.toString())) {
return false;
}
}
return true;
}
}
export const cbdcVelocityControlService = new CbdcVelocityControlService();

View File

@@ -0,0 +1,41 @@
// DBIS Monetary Council Service
// MSC coordination
import prisma from '@/shared/database/prisma';
import { v4 as uuidv4 } from 'uuid';
export class DbisMonetaryCouncilService {
/**
* Initialize or get MSC
*/
async initializeMSC() {
const existing = await prisma.dbisMonetaryCouncil.findFirst({
where: { status: 'active' },
});
if (existing) {
return existing;
}
return await prisma.dbisMonetaryCouncil.create({
data: {
councilId: `MSC-${uuidv4()}`,
councilName: 'DBIS Monetary & Settlement Council',
memberCount: 0,
votingMechanism: 'supermajority_2_3',
status: 'active',
},
});
}
/**
* Get MSC
*/
async getMSC() {
return await this.initializeMSC();
}
}
export const dbisMonetaryCouncilService = new DbisMonetaryCouncilService();

View File

@@ -0,0 +1,329 @@
// CIM Contracts Service
// DBIS Contract Templates (DBIS-CT) management
// Unified rule validation
// Time-locked cross-border contracts
// Condition-based execution
import prisma from '@/shared/database/prisma';
import { v4 as uuidv4 } from 'uuid';
export interface CimContractTemplateRequest {
templateCode: string;
templateName: string;
templateType: string;
contractLogic: Record<string, unknown>;
validationRules: Record<string, unknown>;
}
export interface CimContractExecutionRequest {
templateCode: string;
parameters: Record<string, unknown>;
signatories: string[];
executionTime?: Date;
conditions?: Record<string, unknown>;
}
export class CimContractsService {
/**
* Create DBIS Contract Template (DBIS-CT)
*/
async createContractTemplate(
request: CimContractTemplateRequest
): Promise<string> {
const templateId = `CIM-TEMPLATE-${uuidv4()}`;
const template = await prisma.cimContractTemplate.create({
data: {
templateId,
templateCode: request.templateCode,
templateName: request.templateName,
templateType: request.templateType,
contractLogic: request.contractLogic as any,
validationRules: request.validationRules as any,
status: 'active',
version: 1,
effectiveDate: new Date(),
},
});
return template.templateId;
}
/**
* Get contract template by code
*/
async getContractTemplate(templateCode: string) {
return await prisma.cimContractTemplate.findFirst({
where: {
templateCode,
status: 'active',
},
orderBy: { version: 'desc' },
});
}
/**
* List all active contract templates
*/
async listContractTemplates(templateType?: string) {
return await prisma.cimContractTemplate.findMany({
where: {
...(templateType && { templateType }),
status: 'active',
},
orderBy: { templateCode: 'asc' },
});
}
/**
* Validate contract against unified rules
*/
async validateContract(
templateCode: string,
parameters: Record<string, unknown>
): Promise<{ valid: boolean; errors: string[] }> {
const template = await this.getContractTemplate(templateCode);
if (!template) {
return {
valid: false,
errors: ['Contract template not found'],
};
}
const validationRules = template.validationRules as Record<string, unknown>;
const errors: string[] = [];
// Apply unified rule validation
for (const [ruleKey, ruleValue] of Object.entries(validationRules)) {
const paramValue = parameters[ruleKey];
if (ruleValue === 'required' && !paramValue) {
errors.push(`Required parameter ${ruleKey} is missing`);
}
if (typeof ruleValue === 'object' && ruleValue !== null) {
const rule = ruleValue as Record<string, unknown>;
// Type validation
if (rule.type && typeof paramValue !== rule.type) {
errors.push(`Parameter ${ruleKey} must be of type ${rule.type}`);
}
// Range validation
if (rule.min !== undefined && (paramValue as number) < (rule.min as number)) {
errors.push(`Parameter ${ruleKey} must be at least ${rule.min}`);
}
if (rule.max !== undefined && (paramValue as number) > (rule.max as number)) {
errors.push(`Parameter ${ruleKey} must be at most ${rule.max}`);
}
}
}
return {
valid: errors.length === 0,
errors,
};
}
/**
* Create time-locked cross-border contract
*/
async createTimeLockedContract(
request: CimContractExecutionRequest
): Promise<string> {
const template = await this.getContractTemplate(request.templateCode);
if (!template) {
throw new Error('Contract template not found');
}
// Validate contract
const validation = await this.validateContract(
request.templateCode,
request.parameters
);
if (!validation.valid) {
throw new Error(`Contract validation failed: ${validation.errors.join(', ')}`);
}
// Create smart contract with time-lock
const contractId = `CIM-CONTRACT-${uuidv4()}`;
// Calculate execution time if not provided
const executionTime = request.executionTime || new Date();
const contract = await prisma.smartContract.create({
data: {
contractId,
sovereignBankId: '', // Will be set during execution
templateType: `DBIS-CT:${request.templateCode}`,
contractState: 'draft',
parameters: {
...request.parameters,
executionTime: executionTime.toISOString(),
conditions: request.conditions,
} as any,
signatories: request.signatories as any,
},
});
return contract.contractId;
}
/**
* Execute condition-based contract
*/
async executeConditionBasedContract(
contractId: string
): Promise<boolean> {
const contract = await prisma.smartContract.findUnique({
where: { contractId },
});
if (!contract) {
return false;
}
const parameters = contract.parameters as Record<string, unknown>;
const conditions = parameters.conditions as Record<string, unknown> | undefined;
if (!conditions) {
return false;
}
// Evaluate conditions
const conditionsMet = await this.evaluateConditions(conditions);
if (!conditionsMet) {
return false;
}
// Check if execution time has been reached
const executionTime = parameters.executionTime as string | undefined;
if (executionTime) {
const execTime = new Date(executionTime);
if (new Date() < execTime) {
return false; // Not yet time to execute
}
}
// Execute contract
const contractLogic = await this.getContractLogic(contract.templateType);
const executionResult = await this.executeContractLogic(
contractLogic,
parameters
);
// Update contract
await prisma.smartContract.update({
where: { contractId },
data: {
contractState: 'executed',
executionResult: executionResult as any,
executedAt: new Date(),
},
});
return true;
}
/**
* Evaluate contract conditions
*/
private async evaluateConditions(
conditions: Record<string, unknown>
): Promise<boolean> {
// In production, this would evaluate complex conditions
// For now, simple evaluation
for (const [key, value] of Object.entries(conditions)) {
// Example: Check if account balance meets condition
if (key === 'minBalance') {
// Would check actual balance here
// For now, assume condition is met
}
}
return true;
}
/**
* Get contract logic from template
*/
private async getContractLogic(
templateType: string
): Promise<Record<string, unknown> | null> {
const templateCode = templateType.replace('DBIS-CT:', '');
const template = await this.getContractTemplate(templateCode);
return template?.contractLogic as Record<string, unknown> | null;
}
/**
* Execute contract logic
*/
private async executeContractLogic(
contractLogic: Record<string, unknown> | null,
parameters: Record<string, unknown>
): Promise<Record<string, unknown>> {
if (!contractLogic) {
return { status: 'no_logic' };
}
// In production, this would execute the contract logic
// For now, return success
return {
status: 'executed',
executedAt: new Date().toISOString(),
parameters,
};
}
/**
* Update contract template
*/
async updateContractTemplate(
templateCode: string,
updates: Partial<CimContractTemplateRequest>
): Promise<string> {
const existingTemplate = await this.getContractTemplate(templateCode);
if (!existingTemplate) {
throw new Error('Contract template not found');
}
// Create new version
const templateId = `CIM-TEMPLATE-${uuidv4()}`;
const template = await prisma.cimContractTemplate.create({
data: {
templateId,
templateCode,
templateName: updates.templateName || existingTemplate.templateName,
templateType: updates.templateType || existingTemplate.templateType,
contractLogic: (updates.contractLogic || existingTemplate.contractLogic) as any,
validationRules: (updates.validationRules || existingTemplate.validationRules) as any,
status: 'active',
version: existingTemplate.version + 1,
effectiveDate: new Date(),
},
});
// Archive old version
await prisma.cimContractTemplate.update({
where: { templateId: existingTemplate.templateId },
data: {
status: 'superseded',
expiryDate: new Date(),
},
});
return template.templateId;
}
}
export const cimContractsService = new CimContractsService();

View File

@@ -0,0 +1,213 @@
// CIM Identity Service
// Shared KYC/AML standards enforcement
// Cross-certification of sovereign identities
// HSM-signed CBDC wallet identity management
// Identity mapping registry
import prisma from '@/shared/database/prisma';
import { v4 as uuidv4 } from 'uuid';
import { createHash } from 'crypto';
export interface CimIdentityMappingRequest {
sourceSovereignBankId: string;
targetSovereignBankId: string;
sourceIdentityId: string;
targetIdentityId: string;
identityType: string;
certificationLevel: string;
}
export interface CrossCertificationResult {
mappingId: string;
crossCertificationHash: string;
status: string;
}
export class CimIdentityService {
/**
* Map cross-sovereign identity
*/
async mapIdentity(
request: CimIdentityMappingRequest
): Promise<CrossCertificationResult> {
const mappingId = `CIM-MAP-${uuidv4()}`;
// Generate cross-certification hash
const crossCertHash = this.generateCrossCertificationHash(
request.sourceIdentityId,
request.targetIdentityId,
request.identityType
);
// Create identity mapping
const mapping = await prisma.cimIdentityMapping.create({
data: {
mappingId,
sourceSovereignBankId: request.sourceSovereignBankId,
targetSovereignBankId: request.targetSovereignBankId,
sourceIdentityId: request.sourceIdentityId,
targetIdentityId: request.targetIdentityId,
identityType: request.identityType,
certificationLevel: request.certificationLevel,
crossCertificationHash: crossCertHash,
status: 'active',
},
});
return {
mappingId: mapping.mappingId,
crossCertificationHash: mapping.crossCertificationHash || '',
status: mapping.status,
};
}
/**
* Generate cross-certification hash
*/
private generateCrossCertificationHash(
sourceIdentityId: string,
targetIdentityId: string,
identityType: string
): string {
const combined = `${sourceIdentityId}:${targetIdentityId}:${identityType}`;
return createHash('sha3-256').update(combined).digest('hex');
}
/**
* Verify cross-sovereign identity
*/
async verifyCrossSovereignIdentity(
sourceSovereignBankId: string,
identityId: string,
identityType: string
): Promise<boolean> {
const mapping = await prisma.cimIdentityMapping.findFirst({
where: {
sourceSovereignBankId,
sourceIdentityId: identityId,
identityType,
status: 'active',
},
});
return !!mapping;
}
/**
* Get identity mappings for a sovereign bank
*/
async getIdentityMappings(
sovereignBankId: string,
identityType?: string
) {
return await prisma.cimIdentityMapping.findMany({
where: {
OR: [
{ sourceSovereignBankId: sovereignBankId },
{ targetSovereignBankId: sovereignBankId },
],
...(identityType && { identityType }),
status: 'active',
},
});
}
/**
* Enforce shared KYC/AML standards
*/
async enforceKycAmlStandards(
sovereignBankId: string,
identityType: string
): Promise<boolean> {
// Get minimum standards
const minimumStandards = this.getMinimumStandards(identityType);
// Verify against standards
const mappings = await this.getIdentityMappings(sovereignBankId, identityType);
// Check if all mappings meet minimum standards
for (const mapping of mappings) {
if (!this.meetsStandards(mapping.certificationLevel, minimumStandards)) {
return false;
}
}
return true;
}
/**
* Get minimum KYC/AML standards
*/
private getMinimumStandards(identityType: string): string[] {
const standards: Record<string, string[]> = {
kyc: ['basic', 'enhanced'],
aml: ['enhanced', 'sovereign'],
cbdc_wallet: ['basic', 'enhanced', 'sovereign'],
};
return standards[identityType] || ['basic'];
}
/**
* Check if certification level meets standards
*/
private meetsStandards(
certificationLevel: string,
minimumStandards: string[]
): boolean {
const levels: Record<string, number> = {
basic: 1,
enhanced: 2,
sovereign: 3,
};
const certificationValue = levels[certificationLevel] || 0;
const minValue = Math.min(
...minimumStandards.map((s) => levels[s] || 0)
);
return certificationValue >= minValue;
}
/**
* Get HSM-signed CBDC wallet identity
*/
async getCbdcWalletIdentity(walletId: string): Promise<string | null> {
// In production, this would retrieve from HSM
// For now, generate a signature reference
const wallet = await prisma.cbdcWallet.findUnique({
where: { walletId },
});
if (!wallet) {
return null;
}
// Generate HSM identity reference
const identityData = {
walletId: wallet.walletId,
sovereignBankId: wallet.sovereignBankId,
walletType: wallet.walletType,
};
return createHash('sha3-256')
.update(JSON.stringify(identityData))
.digest('hex');
}
/**
* Revoke identity mapping
*/
async revokeIdentityMapping(mappingId: string): Promise<void> {
await prisma.cimIdentityMapping.update({
where: { mappingId },
data: {
status: 'revoked',
},
});
}
}
export const cimIdentityService = new CimIdentityService();

View File

@@ -0,0 +1,333 @@
// CIM Interledger Service
// CBDC cross-border conversion
// Dual-posting (SCB + DBIS) synchronization
// FX-linked CBDC conversions
// Interledger routing
import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
import { ledgerService } from '@/core/ledger/ledger.service';
import { createHash } from 'crypto';
export interface CimInterledgerConversionRequest {
sourceSovereignBankId: string;
targetSovereignBankId: string;
sourceCbdcCode: string;
targetCbdcCode: string;
amount: string;
conversionType: string;
fxRate?: string;
}
export interface InterledgerConversionResult {
conversionId: string;
scbLedgerHash: string;
dbisLedgerHash: string;
status: string;
}
export class CimInterledgerService {
/**
* Execute CBDC interledger conversion
*/
async convertCbdc(
request: CimInterledgerConversionRequest
): Promise<InterledgerConversionResult> {
const conversionId = `CIM-CONV-${uuidv4()}`;
try {
// Step 1: Calculate FX rate if not provided
let fxRate = request.fxRate
? new Decimal(request.fxRate)
: await this.calculateFxRate(
request.sourceCbdcCode,
request.targetCbdcCode
);
// Step 2: Post to SCB ledger (source)
const scbHash = await this.postToScbLedger(request, conversionId);
// Step 3: Post to DBIS master ledger
const dbisHash = await this.postToDbisLedger(request, conversionId, fxRate);
// Step 4: Create conversion record
const conversion = await prisma.cimInterledgerConversion.create({
data: {
conversionId,
sourceSovereignBankId: request.sourceSovereignBankId,
targetSovereignBankId: request.targetSovereignBankId,
sourceCbdcCode: request.sourceCbdcCode,
targetCbdcCode: request.targetCbdcCode,
amount: new Decimal(request.amount),
fxRate,
conversionType: request.conversionType,
dualPostingStatus: 'both_posted',
scbLedgerHash: scbHash,
dbisLedgerHash: dbisHash,
status: 'completed',
completedAt: new Date(),
},
});
return {
conversionId: conversion.conversionId,
scbLedgerHash: conversion.scbLedgerHash || '',
dbisLedgerHash: conversion.dbisLedgerHash || '',
status: conversion.status,
};
} catch (error) {
// Create failed conversion
await prisma.cimInterledgerConversion.create({
data: {
conversionId,
sourceSovereignBankId: request.sourceSovereignBankId,
targetSovereignBankId: request.targetSovereignBankId,
sourceCbdcCode: request.sourceCbdcCode,
targetCbdcCode: request.targetCbdcCode,
amount: new Decimal(request.amount),
fxRate: request.fxRate ? new Decimal(request.fxRate) : null,
conversionType: request.conversionType,
dualPostingStatus: 'pending',
status: 'failed',
},
});
throw error;
}
}
/**
* Calculate FX rate between two CBDCs
*/
private async calculateFxRate(
sourceCbdcCode: string,
targetCbdcCode: string
): Promise<Decimal> {
// In production, this would query the FX service
// For now, return a default rate
const fxPair = await prisma.fxPair.findFirst({
where: {
baseCurrency: sourceCbdcCode,
quoteCurrency: targetCbdcCode,
status: 'active',
},
});
if (fxPair) {
// Get latest trade price
const latestTrade = await prisma.fxTrade.findFirst({
where: {
fxPairId: fxPair.id,
status: 'executed',
},
orderBy: { executedAt: 'desc' },
});
if (latestTrade) {
return new Decimal(latestTrade.price);
}
}
// Default rate of 1:1 if no FX data available
return new Decimal(1);
}
/**
* Post to SCB ledger (source sovereign bank)
*/
private async postToScbLedger(
request: CimInterledgerConversionRequest,
conversionId: string
): Promise<string> {
// Get CBDC wallet for source
const sourceWallet = await prisma.cbdcWallet.findFirst({
where: {
sovereignBankId: request.sourceSovereignBankId,
currencyCode: request.sourceCbdcCode,
status: 'active',
},
});
if (!sourceWallet) {
throw new Error('Source CBDC wallet not found');
}
// Post debit entry to source wallet
// In a real implementation, this would use the ledger service
// For now, we'll generate a hash
const entryData = {
conversionId,
sourceWalletId: sourceWallet.walletId,
amount: request.amount,
currencyCode: request.sourceCbdcCode,
timestamp: new Date().toISOString(),
};
return createHash('sha3-256')
.update(JSON.stringify(entryData))
.digest('hex');
}
/**
* Post to DBIS master ledger
*/
private async postToDbisLedger(
request: CimInterledgerConversionRequest,
conversionId: string,
fxRate: Decimal
): Promise<string> {
// Get accounts
const sourceAccounts = await prisma.bankAccount.findMany({
where: {
sovereignBankId: request.sourceSovereignBankId,
currencyCode: request.sourceCbdcCode,
assetType: 'cbdc',
status: 'active',
},
take: 1,
});
const targetAccounts = await prisma.bankAccount.findMany({
where: {
sovereignBankId: request.targetSovereignBankId,
currencyCode: request.targetCbdcCode,
assetType: 'cbdc',
status: 'active',
},
take: 1,
});
if (sourceAccounts.length === 0 || targetAccounts.length === 0) {
throw new Error('Accounts not found for DBIS ledger posting');
}
// Calculate target amount
const sourceAmount = new Decimal(request.amount);
const targetAmount = sourceAmount.mul(fxRate);
// Post to DBIS master ledger
const result = await ledgerService.postDoubleEntry(
'Master',
sourceAccounts[0].id,
targetAccounts[0].id,
targetAmount.toString(),
request.targetCbdcCode,
'cbdc',
'Type_A',
conversionId,
undefined,
{
conversionType: request.conversionType,
fxRate: fxRate.toString(),
sourceAmount: request.amount,
}
);
// Get block hash
const ledgerEntry = await prisma.ledgerEntry.findUnique({
where: { id: result.entryIds[0] },
});
return ledgerEntry?.blockHash || '';
}
/**
* Synchronize dual-posting status
*/
async synchronizeDualPosting(conversionId: string): Promise<void> {
const conversion = await prisma.cimInterledgerConversion.findUnique({
where: { conversionId },
});
if (!conversion) {
throw new Error('Conversion not found');
}
// Check posting status
let dualPostingStatus = conversion.dualPostingStatus;
if (conversion.scbLedgerHash && !conversion.dbisLedgerHash) {
dualPostingStatus = 'scb_posted';
} else if (!conversion.scbLedgerHash && conversion.dbisLedgerHash) {
dualPostingStatus = 'dbis_posted';
} else if (conversion.scbLedgerHash && conversion.dbisLedgerHash) {
dualPostingStatus = 'both_posted';
}
// Update status
if (dualPostingStatus !== conversion.dualPostingStatus) {
await prisma.cimInterledgerConversion.update({
where: { conversionId },
data: {
dualPostingStatus,
...(dualPostingStatus === 'both_posted' && {
status: 'completed',
completedAt: new Date(),
}),
},
});
}
}
/**
* Get interledger conversions
*/
async getInterledgerConversions(
sovereignBankId?: string,
status?: string,
limit: number = 100
) {
return await prisma.cimInterledgerConversion.findMany({
where: {
...(sovereignBankId && {
OR: [
{ sourceSovereignBankId: sovereignBankId },
{ targetSovereignBankId: sovereignBankId },
],
}),
...(status && { status }),
},
orderBy: { createdAt: 'desc' },
take: limit,
});
}
/**
* Route interledger transaction
*/
async routeInterledgerTransaction(
sourceBankId: string,
targetBankId: string,
amount: string
): Promise<string[]> {
// Determine optimal routing path
// SCB → SCB (direct)
// SCB → DBIS → SCB (via DBIS)
// SCB → DBIS → Private Bank
const routes: string[] = [];
// Check if direct route exists
const directRoute = await prisma.settlementRoute.findFirst({
where: {
sourceBankId,
destinationBankId: targetBankId,
status: 'active',
},
});
if (directRoute) {
routes.push('scb_to_scb');
} else {
// Route via DBIS
routes.push('scb_to_dbis_to_scb');
}
return routes;
}
}
export const cimInterledgerService = new CimInterledgerService();

View File

@@ -0,0 +1,303 @@
// CIM Offline Service
// Cross-sovereign capsule recognition
// Double-spend protection registry
// Global capsule synchronization
import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
import { createHash } from 'crypto';
export interface CimOfflineCapsuleRequest {
sourceSovereignBankId: string;
targetSovereignBankId: string;
senderWalletId: string;
receiverWalletId: string;
amount: string;
expiryWindow: number;
}
export interface CrossSovereignCapsuleResult {
capsuleId: string;
doubleSpendToken: string;
signature: string;
crossSovereignRecognition: boolean;
}
export class CimOfflineService {
/**
* Create cross-sovereign offline capsule
*/
async createCrossSovereignCapsule(
request: CimOfflineCapsuleRequest
): Promise<CrossSovereignCapsuleResult> {
const capsuleId = `CIM-CAPSULE-${uuidv4()}`;
const doubleSpendToken = this.generateDoubleSpendToken();
const timestamp = new Date();
// Create signature payload
const payload = {
capsuleId,
sourceSovereignBankId: request.sourceSovereignBankId,
targetSovereignBankId: request.targetSovereignBankId,
senderWalletId: request.senderWalletId,
receiverWalletId: request.receiverWalletId,
amount: request.amount,
timestamp: timestamp.toISOString(),
doubleSpendToken,
expiryWindow: request.expiryWindow,
};
const signature = this.generateCapsuleSignature(payload);
// Create capsule
const capsule = await prisma.cimOfflineCapsule.create({
data: {
capsuleId,
sourceSovereignBankId: request.sourceSovereignBankId,
targetSovereignBankId: request.targetSovereignBankId,
senderWalletId: request.senderWalletId,
receiverWalletId: request.receiverWalletId,
amount: new Decimal(request.amount),
timestamp,
expiryWindow: request.expiryWindow,
doubleSpendToken,
signature,
crossSovereignRecognition: false, // Will be set during sync
globalSyncStatus: 'pending',
},
});
return {
capsuleId: capsule.capsuleId,
doubleSpendToken: capsule.doubleSpendToken,
signature: capsule.signature,
crossSovereignRecognition: false,
};
}
/**
* Generate double-spend token
*/
private generateDoubleSpendToken(): string {
return createHash('sha3-256')
.update(uuidv4() + Date.now().toString())
.digest('hex');
}
/**
* Generate capsule signature
*/
private generateCapsuleSignature(payload: Record<string, unknown>): string {
const payloadString = JSON.stringify(payload);
return createHash('sha3-256').update(payloadString).digest('hex');
}
/**
* Recognize cross-sovereign capsule
*/
async recognizeCrossSovereignCapsule(
capsuleId: string,
targetSovereignBankId: string
): Promise<boolean> {
const capsule = await prisma.cimOfflineCapsule.findUnique({
where: { capsuleId },
});
if (!capsule) {
return false;
}
// Verify capsule is for this target sovereign
if (capsule.targetSovereignBankId !== targetSovereignBankId) {
return false;
}
// Check double-spend protection
const isDoubleSpend = await this.checkDoubleSpend(capsule.doubleSpendToken);
if (isDoubleSpend) {
await prisma.cimOfflineCapsule.update({
where: { capsuleId },
data: {
globalSyncStatus: 'rejected',
},
});
return false;
}
// Recognize capsule
await prisma.cimOfflineCapsule.update({
where: { capsuleId },
data: {
crossSovereignRecognition: true,
globalSyncStatus: 'recognized',
},
});
return true;
}
/**
* Check double-spend protection
*/
async checkDoubleSpend(doubleSpendToken: string): Promise<boolean> {
// Check if token already exists in global registry
const existingCapsule = await prisma.cimOfflineCapsule.findFirst({
where: {
doubleSpendToken,
globalSyncStatus: {
in: ['recognized', 'synced'],
},
},
});
// Also check in regular offline capsules
const regularCapsule = await prisma.cbdcOfflineCapsule.findFirst({
where: {
doubleSpendToken,
status: {
in: ['validated', 'synced'],
},
},
});
return !!(existingCapsule || regularCapsule);
}
/**
* Sync capsule globally
*/
async syncCapsuleGlobally(capsuleId: string): Promise<boolean> {
const capsule = await prisma.cimOfflineCapsule.findUnique({
where: { capsuleId },
});
if (!capsule) {
return false;
}
if (capsule.globalSyncStatus !== 'recognized') {
return false;
}
// Check expiry window
const expiryTime = new Date(
capsule.timestamp.getTime() + capsule.expiryWindow * 1000
);
if (new Date() > expiryTime) {
await prisma.cimOfflineCapsule.update({
where: { capsuleId },
data: {
globalSyncStatus: 'rejected',
},
});
return false;
}
// Verify signature
const payload = {
capsuleId: capsule.capsuleId,
sourceSovereignBankId: capsule.sourceSovereignBankId,
targetSovereignBankId: capsule.targetSovereignBankId,
senderWalletId: capsule.senderWalletId,
receiverWalletId: capsule.receiverWalletId,
amount: capsule.amount.toString(),
timestamp: capsule.timestamp.toISOString(),
doubleSpendToken: capsule.doubleSpendToken,
expiryWindow: capsule.expiryWindow,
};
const expectedSignature = this.generateCapsuleSignature(payload);
if (capsule.signature !== expectedSignature) {
await prisma.cimOfflineCapsule.update({
where: { capsuleId },
data: {
globalSyncStatus: 'rejected',
},
});
return false;
}
// Sync capsule
await prisma.cimOfflineCapsule.update({
where: { capsuleId },
data: {
globalSyncStatus: 'synced',
syncedAt: new Date(),
},
});
// Also sync to regular offline capsule registry
await prisma.cbdcOfflineCapsule.upsert({
where: { capsuleId },
update: {
status: 'synced',
syncedAt: new Date(),
},
create: {
capsuleId,
senderWalletId: capsule.senderWalletId,
receiverWalletId: capsule.receiverWalletId,
amount: capsule.amount,
timestamp: capsule.timestamp,
expiryWindow: capsule.expiryWindow,
doubleSpendToken: capsule.doubleSpendToken,
signature: capsule.signature,
status: 'synced',
syncedAt: new Date(),
},
});
return true;
}
/**
* Get capsules for synchronization
*/
async getPendingCapsules(
sovereignBankId?: string,
limit: number = 100
) {
return await prisma.cimOfflineCapsule.findMany({
where: {
...(sovereignBankId && {
OR: [
{ sourceSovereignBankId: sovereignBankId },
{ targetSovereignBankId: sovereignBankId },
],
}),
globalSyncStatus: {
in: ['pending', 'recognized'],
},
},
orderBy: { createdAt: 'asc' },
take: limit,
});
}
/**
* Get double-spend registry status
*/
async getDoubleSpendRegistryStatus(doubleSpendToken: string) {
const crossSovereignCapsule = await prisma.cimOfflineCapsule.findFirst({
where: { doubleSpendToken },
});
const regularCapsule = await prisma.cbdcOfflineCapsule.findFirst({
where: { doubleSpendToken },
});
return {
exists: !!(crossSovereignCapsule || regularCapsule),
crossSovereignCapsule,
regularCapsule,
};
}
}
export const cimOfflineService = new CimOfflineService();

View File

@@ -0,0 +1,134 @@
// CIM API Routes
import { Router } from 'express';
import { cimIdentityService } from './cim-identity.service';
import { cimInterledgerService } from './cim-interledger.service';
import { cimContractsService } from './cim-contracts.service';
import { cimOfflineService } from './cim-offline.service';
const router = Router();
/**
* @swagger
* /api/v1/cim/identity/map:
* post:
* summary: Map cross-sovereign identity
* description: Create identity mapping between sovereign banks for CBDC interoperability
* tags: [CBDC, CIM]
* security:
* - SovereignToken: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - sourceSovereignId
* - targetSovereignId
* - identityType
* properties:
* sourceSovereignId:
* type: string
* description: Source sovereign bank ID
* targetSovereignId:
* type: string
* description: Target sovereign bank ID
* identityType:
* type: string
* enum: [Sovereign, Institutional, Retail, Contract]
* responses:
* 200:
* description: Identity mapped successfully
* 400:
* description: Validation error
* 401:
* description: Unauthorized
*/
router.post('/identity/map', async (req, res, next) => {
try {
const result = await cimIdentityService.mapIdentity(req.body);
res.json(result);
} catch (error) {
next(error);
}
});
/**
* @swagger
* /api/v1/cim/interledger/convert:
* post:
* summary: CBDC interledger conversion
* description: Convert CBDC from one sovereign ledger to another
* tags: [CBDC, CIM]
* security:
* - SovereignToken: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - sourceCbdcId
* - targetSovereignId
* - amount
* properties:
* sourceCbdcId:
* type: string
* targetSovereignId:
* type: string
* amount:
* type: string
* example: "1000.00"
* responses:
* 200:
* description: Conversion completed
* 400:
* description: Validation error
*/
router.post('/interledger/convert', async (req, res, next) => {
try {
const result = await cimInterledgerService.convertCbdc(req.body);
res.json(result);
} catch (error) {
next(error);
}
});
/**
* @swagger
* /api/v1/cim/contracts/templates:
* get:
* summary: List DBIS-CT templates
*/
router.get('/contracts/templates', async (req, res, next) => {
try {
const { templateType } = req.query;
const templates = await cimContractsService.listContractTemplates(
templateType as string
);
res.json(templates);
} catch (error) {
next(error);
}
});
/**
* @swagger
* /api/v1/cim/offline/sync-capsule:
* post:
* summary: Sync offline capsule
*/
router.post('/offline/sync-capsule', async (req, res, next) => {
try {
const { capsuleId } = req.body;
const result = await cimOfflineService.syncCapsuleGlobally(capsuleId);
res.json({ success: result });
} catch (error) {
next(error);
}
});
export default router;

View File

@@ -0,0 +1,207 @@
// Global CBDC Tokenomics Framework (GCTF) - API Routes
import { Router } from 'express';
import { gctfService } from './gctf.service';
import { CBDCUnitType } from './types';
const router = Router();
/**
* @swagger
* tags:
* name: CBDC Tokenomics
* description: Global CBDC Tokenomics Framework (GCTF)
*/
/**
* @swagger
* /api/gctf/issue:
* post:
* summary: Issue new CBDC tokens
* description: Issue new CBDC tokens through the Global CBDC Tokenomics Framework
* tags: [CBDC Tokenomics]
* security:
* - SovereignToken: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - amount
* - sovereignBankId
* properties:
* amount:
* type: string
* sovereignBankId:
* type: string
* responses:
* 200:
* description: CBDC tokens issued
*/
router.post('/issue', async (req, res) => {
try {
const adjustment = await gctfService.issueCBDC(req.body);
res.json(adjustment);
} catch (error) {
res.status(500).json({ error: (error as Error).message });
}
});
/**
* POST /api/gctf/burn
* Burn CBDC tokens
*/
router.post('/burn', async (req, res) => {
try {
const adjustment = await gctfService.burnCBDC(req.body);
res.json(adjustment);
} catch (error) {
res.status(500).json({ error: (error as Error).message });
}
});
/**
* GET /api/gctf/supply-mechanics/:sovereignBankId/:unitType
* Get supply mechanics for a CBDC unit
*/
router.get('/supply-mechanics/:sovereignBankId/:unitType', async (req, res) => {
try {
const { sovereignBankId, unitType } = req.params;
const mechanics = await gctfService.getSupplyMechanics(
sovereignBankId,
unitType as CBDCUnitType
);
res.json(mechanics);
} catch (error) {
res.status(500).json({ error: (error as Error).message });
}
});
/**
* POST /api/gctf/velocity-controls
* Configure velocity controls
*/
router.post('/velocity-controls', async (req, res) => {
try {
const { sovereignBankId, unitType, ...controls } = req.body;
const velocityControl = await gctfService.configureVelocityControls(
sovereignBankId,
unitType as CBDCUnitType,
controls
);
res.json(velocityControl);
} catch (error) {
res.status(500).json({ error: (error as Error).message });
}
});
/**
* POST /api/gctf/quarantine/enable
* Enable sovereign quarantine mode
*/
router.post('/quarantine/enable', async (req, res) => {
try {
const { sovereignBankId, unitType, endDate } = req.body;
const controls = await gctfService.enableQuarantineMode(
sovereignBankId,
unitType as CBDCUnitType,
endDate ? new Date(endDate) : undefined
);
res.json(controls);
} catch (error) {
res.status(500).json({ error: (error as Error).message });
}
});
/**
* POST /api/gctf/quarantine/disable
* Disable sovereign quarantine mode
*/
router.post('/quarantine/disable', async (req, res) => {
try {
const { sovereignBankId, unitType } = req.body;
const controls = await gctfService.disableQuarantineMode(
sovereignBankId,
unitType as CBDCUnitType
);
res.json(controls);
} catch (error) {
res.status(500).json({ error: (error as Error).message });
}
});
/**
* GET /api/gctf/config/:sovereignBankId/:unitType
* Get tokenomics configuration
*/
router.get('/config/:sovereignBankId/:unitType', async (req, res) => {
try {
const { sovereignBankId, unitType } = req.params;
const config = await gctfService.getTokenomicsConfig(
sovereignBankId,
unitType as CBDCUnitType
);
res.json(config);
} catch (error) {
res.status(500).json({ error: (error as Error).message });
}
});
/**
* POST /api/gctf/calculate-issuance
* Calculate CBDC issuance using the rule
*/
router.post('/calculate-issuance', async (req, res) => {
try {
const { demandAdjustment, settlementVolume, factor, stressPenalties } = req.body;
const rule = gctfService.calculateIssuanceRule(
demandAdjustment,
settlementVolume,
factor,
stressPenalties
);
res.json(rule);
} catch (error) {
res.status(500).json({ error: (error as Error).message });
}
});
/**
* POST /api/gctf/check-velocity
* Check if a transaction is allowed under velocity controls
*/
router.post('/check-velocity', async (req, res) => {
try {
const { sovereignBankId, unitType, transactionAmount, category } = req.body;
const result = await gctfService.checkVelocityControls(
sovereignBankId,
unitType as CBDCUnitType,
transactionAmount,
category
);
res.json(result);
} catch (error) {
res.status(500).json({ error: (error as Error).message });
}
});
export default router;

View File

@@ -0,0 +1,306 @@
// Global CBDC Tokenomics Framework (GCTF) - Core Service
import { Decimal } from 'decimal.js';
import {
CBDCUnitType,
CBDCIssuancePolicy,
CBDCSupplyMechanics,
CBDCIssuanceRule,
CBDCVelocityControl,
CBDCTokenomicsConfig,
CBDCIssuanceRequest,
CBDCBurnRequest,
CBDCSupplyAdjustment,
} from './types';
import { logger } from '@/infrastructure/monitoring/logger';
import { v4 as uuidv4 } from 'uuid';
export class GCTFService {
/**
* Calculate CBDC issuance using the rule:
* CBDC_new = demand_adjustment + (settlement_volume * factor) - stress_penalties
*/
calculateIssuanceRule(
demandAdjustment: number,
settlementVolume: string,
factor: number,
stressPenalties: number
): CBDCIssuanceRule {
const settlementDecimal = new Decimal(settlementVolume);
const calculatedSupply = new Decimal(demandAdjustment)
.plus(settlementDecimal.times(factor))
.minus(stressPenalties)
.toString();
return {
demandAdjustment,
settlementVolume,
factor,
stressPenalties,
calculatedSupply,
};
}
/**
* Get or create supply mechanics for a CBDC unit
*/
async getSupplyMechanics(
sovereignBankId: string,
unitType: CBDCUnitType
): Promise<CBDCSupplyMechanics> {
// In real implementation, fetch from database
// For now, return default structure
return {
sovereignBankId,
unitType,
currentSupply: '0',
issuancePolicy: CBDCIssuancePolicy.DEMAND_DRIVEN,
lastIssuance: new Date(),
lastBurn: new Date(),
};
}
/**
* Issue new CBDC tokens
*/
async issueCBDC(request: CBDCIssuanceRequest): Promise<CBDCSupplyAdjustment> {
logger.info(`GCTF: Issuing ${request.amount} ${request.unitType} for ${request.sovereignBankId}`);
// Verify issuance is allowed based on policy
const supplyMechanics = await this.getSupplyMechanics(
request.sovereignBankId,
request.unitType
);
// Check max supply if set
if (supplyMechanics.maxSupply) {
const current = new Decimal(supplyMechanics.currentSupply);
const max = new Decimal(supplyMechanics.maxSupply);
const requested = new Decimal(request.amount);
if (current.plus(requested).gt(max)) {
throw new Error(
`Issuance would exceed max supply. Current: ${current}, Max: ${max}, Requested: ${requested}`
);
}
}
// Verify reserve backing if required
if (supplyMechanics.issuancePolicy === CBDCIssuancePolicy.RESERVE_BACKED) {
await this.verifyReserveBacking(
request.sovereignBankId,
request.unitType,
request.amount
);
}
const adjustment: CBDCSupplyAdjustment = {
sovereignBankId: request.sovereignBankId,
unitType: request.unitType,
adjustment: request.amount,
reason: request.reason,
timestamp: new Date(),
};
// In real implementation, update database and ledger
logger.info(`GCTF: Issued ${request.amount} ${request.unitType}`);
return adjustment;
}
/**
* Burn CBDC tokens
*/
async burnCBDC(request: CBDCBurnRequest): Promise<CBDCSupplyAdjustment> {
logger.info(`GCTF: Burning ${request.amount} ${request.unitType} for ${request.sovereignBankId}`);
const supplyMechanics = await this.getSupplyMechanics(
request.sovereignBankId,
request.unitType
);
const current = new Decimal(supplyMechanics.currentSupply);
const requested = new Decimal(request.amount);
if (requested.gt(current)) {
throw new Error(
`Burn amount exceeds current supply. Current: ${current}, Requested: ${requested}`
);
}
const adjustment: CBDCSupplyAdjustment = {
sovereignBankId: request.sovereignBankId,
unitType: request.unitType,
adjustment: `-${request.amount}`, // Negative for burn
reason: request.reason,
timestamp: new Date(),
};
// In real implementation, update database and ledger
logger.info(`GCTF: Burned ${request.amount} ${request.unitType}`);
return adjustment;
}
/**
* Configure velocity controls for a CBDC unit
*/
async configureVelocityControls(
sovereignBankId: string,
unitType: CBDCUnitType,
controls: Partial<CBDCVelocityControl>
): Promise<CBDCVelocityControl> {
logger.info(`GCTF: Configuring velocity controls for ${unitType}`, {
sovereignBankId,
});
const velocityControl: CBDCVelocityControl = {
sovereignBankId,
unitType,
...controls,
};
// In real implementation, save to database
return velocityControl;
}
/**
* Enable sovereign quarantine mode
*/
async enableQuarantineMode(
sovereignBankId: string,
unitType: CBDCUnitType,
endDate?: Date
): Promise<CBDCVelocityControl> {
logger.warn(`GCTF: Enabling quarantine mode for ${unitType}`, {
sovereignBankId,
});
const controls = await this.configureVelocityControls(sovereignBankId, unitType, {
sovereignQuarantineMode: true,
quarantineStartDate: new Date(),
quarantineEndDate: endDate,
});
return controls;
}
/**
* Disable sovereign quarantine mode
*/
async disableQuarantineMode(
sovereignBankId: string,
unitType: CBDCUnitType
): Promise<CBDCVelocityControl> {
logger.info(`GCTF: Disabling quarantine mode for ${unitType}`, {
sovereignBankId,
});
const controls = await this.configureVelocityControls(sovereignBankId, unitType, {
sovereignQuarantineMode: false,
quarantineEndDate: new Date(),
});
return controls;
}
/**
* Get tokenomics configuration
*/
async getTokenomicsConfig(
sovereignBankId: string,
unitType: CBDCUnitType
): Promise<CBDCTokenomicsConfig> {
const supplyMechanics = await this.getSupplyMechanics(sovereignBankId, unitType);
// In real implementation, fetch velocity controls from database
const velocityControls: CBDCVelocityControl | undefined = undefined;
const config: CBDCTokenomicsConfig = {
sovereignBankId,
unitType,
supplyMechanics,
velocityControls,
monetaryPolicy: {
reserveRequirement: 0.1, // 10% default
},
programmableCompliance: {
enabled: true,
rules: [],
},
};
return config;
}
/**
* Verify reserve backing for issuance
*/
private async verifyReserveBacking(
sovereignBankId: string,
unitType: CBDCUnitType,
amount: string
): Promise<void> {
// In real implementation, check reserve accounts
logger.info(`GCTF: Verifying reserve backing for ${amount} ${unitType}`);
// Placeholder - would check actual reserves
}
/**
* Apply velocity controls to a transaction
*/
async checkVelocityControls(
sovereignBankId: string,
unitType: CBDCUnitType,
transactionAmount: string,
category?: string
): Promise<{ allowed: boolean; reason?: string }> {
// In real implementation, fetch velocity controls and check
const controls = await this.getVelocityControls(sovereignBankId, unitType);
if (controls?.sovereignQuarantineMode) {
return {
allowed: false,
reason: 'Sovereign quarantine mode is active',
};
}
// Check spending category restrictions
if (category && controls?.spendingCategoryRestrictions) {
const restriction = controls.spendingCategoryRestrictions.find(
(r) => r.category === category
);
if (restriction && !restriction.allowed) {
return {
allowed: false,
reason: `Category ${category} is restricted`,
};
}
if (restriction && new Decimal(transactionAmount).gt(restriction.maxAmount)) {
return {
allowed: false,
reason: `Transaction amount exceeds category limit`,
};
}
}
// Check cross-border routing limits
// This would be checked in the routing layer
return { allowed: true };
}
/**
* Get velocity controls
*/
private async getVelocityControls(
sovereignBankId: string,
unitType: CBDCUnitType
): Promise<CBDCVelocityControl | null> {
// In real implementation, fetch from database
return null;
}
}
export const gctfService = new GCTFService();

View File

@@ -0,0 +1,6 @@
// Global CBDC Tokenomics Framework (GCTF) - Module Exports
export * from './types';
export * from './gctf.service';
export { default as gctfRoutes } from './gctf.routes';

View File

@@ -0,0 +1,98 @@
// Global CBDC Tokenomics Framework (GCTF) - Type Definitions
export enum CBDCUnitType {
RETAIL = 'rCBDC', // Retail CBDC - Consumer money
WHOLESALE = 'wCBDC', // Wholesale CBDC - Interbank settlement token
INSTITUTIONAL = 'iCBDC', // Institutional CBDC - For regulated corporates, supranationals
}
export enum CBDCIssuancePolicy {
DEMAND_DRIVEN = 'DEMAND_DRIVEN',
FIXED_SUPPLY = 'FIXED_SUPPLY',
RESERVE_BACKED = 'RESERVE_BACKED',
HYBRID = 'HYBRID',
}
export interface CBDCSupplyMechanics {
sovereignBankId: string;
unitType: CBDCUnitType;
currentSupply: string; // Decimal as string
maxSupply?: string; // Optional max supply cap
issuancePolicy: CBDCIssuancePolicy;
reserveBacking?: string; // For reserve-backed CBDCs
commodityBacking?: string; // For commodity-backed CBDCs
lastIssuance: Date;
lastBurn: Date;
}
export interface CBDCIssuanceRule {
demandAdjustment: number; // Adjustment based on demand
settlementVolume: string; // Current settlement volume
factor: number; // Issuance factor (0-1)
stressPenalties: number; // Penalties during stress periods
calculatedSupply: string; // CBDC_new = demand_adjustment + (settlement_volume * factor) - stress_penalties
}
export interface CBDCVelocityControl {
sovereignBankId: string;
unitType: CBDCUnitType;
transactionVelocityCap?: {
daily: number;
weekly: number;
monthly: number;
};
spendingCategoryRestrictions?: {
category: string;
maxAmount: string;
allowed: boolean;
}[];
crossBorderRoutingLimit?: {
maxAmount: string;
maxTransactions: number;
timeWindow: 'DAILY' | 'WEEKLY' | 'MONTHLY';
};
sovereignQuarantineMode?: boolean; // Active during crises
quarantineStartDate?: Date;
quarantineEndDate?: Date;
}
export interface CBDCTokenomicsConfig {
sovereignBankId: string;
unitType: CBDCUnitType;
supplyMechanics: CBDCSupplyMechanics;
velocityControls?: CBDCVelocityControl;
monetaryPolicy: {
interestRate?: number; // If applicable
reserveRequirement?: number;
fxBandWidth?: number;
};
programmableCompliance: {
enabled: boolean;
rules: string[]; // Smart contract rule identifiers
};
}
export interface CBDCIssuanceRequest {
sovereignBankId: string;
unitType: CBDCUnitType;
amount: string;
reason: string;
operatorIdentity: string;
}
export interface CBDCBurnRequest {
sovereignBankId: string;
unitType: CBDCUnitType;
amount: string;
reason: string;
operatorIdentity: string;
}
export interface CBDCSupplyAdjustment {
sovereignBankId: string;
unitType: CBDCUnitType;
adjustment: string; // Positive for issuance, negative for burn
reason: string;
timestamp: Date;
}

View File

@@ -0,0 +1,277 @@
// Quantum Capsule Service
// Offline capsule management with double-spend prevention
import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
import { createHash } from 'crypto';
import { quantumCryptoService } from '@/infrastructure/quantum/quantum-crypto.service';
export interface CapsuleCreationRequest {
senderWalletId: string;
receiverWalletId: string;
amount: string;
expiryWindow: number; // seconds
}
export interface CapsuleResult {
capsuleId: string;
doubleSpendToken: string;
pqcSignature: string;
status: string;
}
export class QuantumCapsuleService {
/**
* Create offline quantum capsule
*/
async createCapsule(
request: CapsuleCreationRequest
): Promise<CapsuleResult> {
const senderWallet = await prisma.quantumWallet.findUnique({
where: { walletId: request.senderWalletId },
});
if (!senderWallet) {
throw new Error(`Sender wallet not found: ${request.senderWalletId}`);
}
// Check balance
if (senderWallet.balance.lessThan(new Decimal(request.amount))) {
throw new Error('Insufficient balance');
}
// Generate double-spend token
const doubleSpendToken = this.generateDoubleSpendToken(
request.senderWalletId,
request.receiverWalletId,
request.amount
);
// Create capsule payload
const capsulePayload = {
senderWalletId: request.senderWalletId,
receiverWalletId: request.receiverWalletId,
amount: request.amount,
timestamp: new Date().toISOString(),
doubleSpendToken,
expiryWindow: request.expiryWindow,
};
const payloadString = JSON.stringify(capsulePayload);
// Sign with PQC (Dilithium)
const pqcSignature = await this.signWithPQC(
payloadString,
senderWallet.dilithiumKeyId
);
// Create capsule
const capsuleId = `CAPSULE-${uuidv4()}`;
const capsule = await prisma.quantumWalletCapsule.create({
data: {
capsuleId,
senderWalletId: request.senderWalletId,
receiverWalletId: request.receiverWalletId,
amount: new Decimal(request.amount),
timestamp: new Date(),
expiryWindow: request.expiryWindow,
doubleSpendToken,
pqcSignature,
status: 'pending',
},
});
// Reserve balance
await prisma.quantumWallet.update({
where: { walletId: request.senderWalletId },
data: {
balance: senderWallet.balance.minus(new Decimal(request.amount)),
},
});
return {
capsuleId: capsule.capsuleId,
doubleSpendToken: capsule.doubleSpendToken,
pqcSignature: capsule.pqcSignature,
status: capsule.status,
};
}
/**
* Validate capsule (dual verification: SCB + DBIS)
*/
async validateCapsule(capsuleId: string): Promise<{
valid: boolean;
scbVerified: boolean;
dbisVerified: boolean;
}> {
const capsule = await prisma.quantumWalletCapsule.findUnique({
where: { capsuleId },
include: { wallet: true },
});
if (!capsule) {
return { valid: false, scbVerified: false, dbisVerified: false };
}
// Check double-spend token
const existingCapsule = await prisma.quantumWalletCapsule.findFirst({
where: {
doubleSpendToken: capsule.doubleSpendToken,
NOT: { capsuleId: capsule.capsuleId },
status: { in: ['validated', 'synced'] },
},
});
if (existingCapsule) {
return { valid: false, scbVerified: false, dbisVerified: false };
}
// Verify PQC signature (SCB verification)
const capsulePayload = {
senderWalletId: capsule.senderWalletId,
receiverWalletId: capsule.receiverWalletId,
amount: capsule.amount.toString(),
timestamp: capsule.timestamp.toISOString(),
doubleSpendToken: capsule.doubleSpendToken,
expiryWindow: capsule.expiryWindow,
};
const payloadString = JSON.stringify(capsulePayload);
const scbVerified = await this.verifyPQCSignature(
payloadString,
capsule.pqcSignature,
capsule.wallet.dilithiumKeyId
);
// DBIS verification (simplified - in production would have separate DBIS verification)
const dbisVerified = scbVerified; // For now, use same verification
const valid = scbVerified && dbisVerified;
if (valid) {
await prisma.quantumWalletCapsule.update({
where: { capsuleId },
data: {
scbVerification: true,
dbisVerification: true,
status: 'validated',
},
});
}
return {
valid,
scbVerified,
dbisVerified,
};
}
/**
* Sync capsule (finalize offline transaction)
*/
async syncCapsule(capsuleId: string): Promise<void> {
const capsule = await prisma.quantumWalletCapsule.findUnique({
where: { capsuleId },
include: { wallet: true },
});
if (!capsule) {
throw new Error(`Capsule not found: ${capsuleId}`);
}
if (capsule.status !== 'validated') {
throw new Error(`Capsule must be validated before sync: ${capsule.status}`);
}
// Update receiver wallet balance
const receiverWallet = await prisma.quantumWallet.findUnique({
where: { walletId: capsule.receiverWalletId },
});
if (!receiverWallet) {
throw new Error(`Receiver wallet not found: ${capsule.receiverWalletId}`);
}
await prisma.quantumWallet.update({
where: { walletId: capsule.receiverWalletId },
data: {
balance: receiverWallet.balance.plus(capsule.amount),
},
});
// Mark capsule as synced
await prisma.quantumWalletCapsule.update({
where: { capsuleId },
data: {
status: 'synced',
syncedAt: new Date(),
},
});
}
/**
* Generate double-spend token
*/
private generateDoubleSpendToken(
senderWalletId: string,
receiverWalletId: string,
amount: string
): string {
const data = `${senderWalletId}:${receiverWalletId}:${amount}:${Date.now()}`;
return createHash('sha3-256').update(data).digest('hex');
}
/**
* Sign with PQC
*/
private async signWithPQC(message: string, dilithiumKeyId: string): Promise<string> {
// Get key
const key = await prisma.cryptographicKey.findUnique({
where: { keyId: dilithiumKeyId },
});
if (!key) {
throw new Error(`Key not found: ${dilithiumKeyId}`);
}
// In production, would use actual PQC library
// For now, generate signature hash
const signature = createHash('sha3-256')
.update(message + key.publicKey)
.digest('hex');
return `PQC-SIG-${signature}`;
}
/**
* Verify PQC signature
*/
private async verifyPQCSignature(
message: string,
signature: string,
dilithiumKeyId: string
): Promise<boolean> {
// Get key
const key = await prisma.cryptographicKey.findUnique({
where: { keyId: dilithiumKeyId },
});
if (!key) {
return false;
}
// In production, would use actual PQC library
// For now, verify signature format
const expectedSignature = createHash('sha3-256')
.update(message + key.publicKey)
.digest('hex');
return signature === `PQC-SIG-${expectedSignature}`;
}
}
export const quantumCapsuleService = new QuantumCapsuleService();

View File

@@ -0,0 +1,170 @@
// Quantum Wallet Service
// Wallet creation with PQC keys (Dilithium signatures, Kyber key exchange)
import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
import { quantumCryptoService } from '@/infrastructure/quantum/quantum-crypto.service';
import { createHash } from 'crypto';
export interface QuantumWalletRequest {
sovereignBankId: string;
walletType: string; // retail, wholesale, institutional
currencyCode: string;
}
export interface QuantumWalletResult {
walletId: string;
dilithiumKeyId: string;
kyberKeyId: string;
hsmIdentityCert: string;
status: string;
}
export class QuantumWalletService {
/**
* Create quantum-safe wallet
*/
async createWallet(
request: QuantumWalletRequest
): Promise<QuantumWalletResult> {
const walletId = `QWALLET-${uuidv4()}`;
// Generate PQC key pairs
// Dilithium for signatures
const dilithiumKey = await quantumCryptoService.generatePQCKeyPair(
'CRYSTALS-Dilithium',
`quantum_wallet_signature_${walletId}`
);
// Kyber for key exchange
const kyberKey = await quantumCryptoService.generatePQCKeyPair(
'CRYSTALS-Kyber',
`quantum_wallet_key_exchange_${walletId}`
);
// Generate HSM-bound identity certificate
const hsmIdentityCert = await this.generateHSMIdentityCert(
walletId,
request.sovereignBankId,
dilithiumKey.keyId,
kyberKey.keyId
);
// Create quantum wallet
const wallet = await prisma.quantumWallet.create({
data: {
walletId,
sovereignBankId: request.sovereignBankId,
walletType: request.walletType,
currencyCode: request.currencyCode,
balance: new Decimal(0),
dilithiumKeyId: dilithiumKey.keyId,
kyberKeyId: kyberKey.keyId,
hsmIdentityCert,
status: 'active',
},
});
return {
walletId: wallet.walletId,
dilithiumKeyId: wallet.dilithiumKeyId,
kyberKeyId: wallet.kyberKeyId,
hsmIdentityCert: wallet.hsmIdentityCert,
status: wallet.status,
};
}
/**
* Generate HSM-bound identity certificate
*/
private async generateHSMIdentityCert(
walletId: string,
sovereignBankId: string,
dilithiumKeyId: string,
kyberKeyId: string
): Promise<string> {
// In production, this would call actual HSM
// For now, generate a certificate hash
const certData = {
walletId,
sovereignBankId,
dilithiumKeyId,
kyberKeyId,
timestamp: new Date().toISOString(),
};
const certString = JSON.stringify(certData);
const certHash = createHash('sha3-256').update(certString).digest('hex');
const cert = `HSM-CERT-${certHash}`;
return cert;
}
/**
* Get wallet details
*/
async getWallet(walletId: string): Promise<any> {
const wallet = await prisma.quantumWallet.findUnique({
where: { walletId },
});
if (!wallet) {
throw new Error(`Wallet not found: ${walletId}`);
}
return wallet;
}
/**
* Update wallet balance
*/
async updateBalance(walletId: string, amount: string, operation: 'add' | 'subtract'): Promise<void> {
const wallet = await prisma.quantumWallet.findUnique({
where: { walletId },
});
if (!wallet) {
throw new Error(`Wallet not found: ${walletId}`);
}
const currentBalance = wallet.balance;
const amountDecimal = new Decimal(amount);
const newBalance = operation === 'add'
? currentBalance.plus(amountDecimal)
: currentBalance.minus(amountDecimal);
if (newBalance.isNegative()) {
throw new Error('Insufficient balance');
}
await prisma.quantumWallet.update({
where: { walletId },
data: { balance: newBalance },
});
}
/**
* Suspend wallet
*/
async suspendWallet(walletId: string): Promise<void> {
await prisma.quantumWallet.update({
where: { walletId },
data: { status: 'suspended' },
});
}
/**
* Revoke wallet
*/
async revokeWallet(walletId: string): Promise<void> {
await prisma.quantumWallet.update({
where: { walletId },
data: { status: 'revoked' },
});
}
}
export const quantumWalletService = new QuantumWalletService();

View File

@@ -0,0 +1,154 @@
// Wallet Attestation Service
// Device attestation (12-hour cycle)
import prisma from '@/shared/database/prisma';
import { v4 as uuidv4 } from 'uuid';
import { createHash } from 'crypto';
export interface AttestationRequest {
walletId: string;
deviceAttestation: Record<string, unknown>;
}
export interface AttestationResult {
waoId: string;
attestationHash: string;
attestationCycle: number;
expiresAt: Date;
}
export class WalletAttestationService {
/**
* Create wallet attestation object (WAO)
*/
async createAttestation(
request: AttestationRequest
): Promise<AttestationResult> {
const wallet = await prisma.quantumWallet.findUnique({
where: { walletId: request.walletId },
});
if (!wallet) {
throw new Error(`Wallet not found: ${request.walletId}`);
}
// Calculate attestation cycle (12-hour cycles since wallet creation)
const walletCreated = wallet.createdAt;
const now = new Date();
const hoursSinceCreation = (now.getTime() - walletCreated.getTime()) / (1000 * 60 * 60);
const attestationCycle = Math.floor(hoursSinceCreation / 12);
// Generate attestation hash
const attestationData = {
walletId: request.walletId,
deviceAttestation: request.deviceAttestation,
attestationCycle,
timestamp: now.toISOString(),
};
const attestationString = JSON.stringify(attestationData);
const attestationHash = createHash('sha3-256').update(attestationString).digest('hex');
// Calculate expiry (next 12-hour cycle)
const expiresAt = new Date(walletCreated);
expiresAt.setHours(expiresAt.getHours() + (attestationCycle + 1) * 12);
// Create WAO
const waoId = `WAO-${uuidv4()}`;
const wao = await prisma.walletAttestationObject.create({
data: {
waoId,
walletId: request.walletId,
deviceAttestation: request.deviceAttestation,
attestationHash,
attestationCycle,
status: 'valid',
expiresAt,
},
});
// Update wallet with WAO reference
await prisma.quantumWallet.update({
where: { walletId: request.walletId },
data: { waoId: wao.waoId },
});
return {
waoId: wao.waoId,
attestationHash: wao.attestationHash,
attestationCycle: wao.attestationCycle,
expiresAt: wao.expiresAt,
};
}
/**
* Verify attestation
*/
async verifyAttestation(waoId: string): Promise<boolean> {
const wao = await prisma.walletAttestationObject.findUnique({
where: { waoId },
});
if (!wao) {
return false;
}
// Check if expired
if (new Date() > wao.expiresAt) {
await prisma.walletAttestationObject.update({
where: { waoId },
data: { status: 'expired' },
});
return false;
}
// Check status
return wao.status === 'valid';
}
/**
* Revoke attestation
*/
async revokeAttestation(waoId: string): Promise<void> {
await prisma.walletAttestationObject.update({
where: { waoId },
data: { status: 'revoked' },
});
}
/**
* Get current attestation for wallet
*/
async getCurrentAttestation(walletId: string): Promise<any | null> {
const wao = await prisma.walletAttestationObject.findFirst({
where: {
walletId,
status: 'valid',
},
orderBy: { attestedAt: 'desc' },
});
return wao;
}
/**
* Check if attestation needs renewal
*/
async needsRenewal(walletId: string): Promise<boolean> {
const wao = await this.getCurrentAttestation(walletId);
if (!wao) {
return true;
}
// Check if expires within 1 hour
const oneHourFromNow = new Date();
oneHourFromNow.setHours(oneHourFromNow.getHours() + 1);
return wao.expiresAt < oneHourFromNow;
}
}
export const walletAttestationService = new WalletAttestationService();

View File

@@ -0,0 +1,130 @@
// Wallet Risk Service
// Real-time risk scoring
import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
export interface RiskScoreRequest {
walletId: string;
}
export interface RiskScoreResult {
scoreId: string;
riskScore: string;
riskFactors: Record<string, unknown>;
}
export class WalletRiskService {
/**
* Calculate wallet risk score
*/
async calculateRiskScore(
request: RiskScoreRequest
): Promise<RiskScoreResult> {
const wallet = await prisma.quantumWallet.findUnique({
where: { walletId: request.walletId },
include: {
attestations: {
orderBy: { attestedAt: 'desc' },
take: 1,
},
riskScores: {
orderBy: { calculatedAt: 'desc' },
take: 5,
},
},
});
if (!wallet) {
throw new Error(`Wallet not found: ${request.walletId}`);
}
const riskFactors: Record<string, unknown> = {};
let riskScore = 0;
// Factor 1: Wallet type (retail = lower risk, institutional = higher risk)
const typeRisk = wallet.walletType === 'retail' ? 10 : wallet.walletType === 'wholesale' ? 30 : 50;
riskFactors.walletType = typeRisk;
riskScore += typeRisk;
// Factor 2: Attestation status
const latestAttestation = wallet.attestations[0];
if (!latestAttestation || latestAttestation.status !== 'valid') {
riskFactors.attestationStatus = 30;
riskScore += 30;
} else {
riskFactors.attestationStatus = 0;
}
// Factor 3: Balance (higher balance = higher risk)
const balanceRisk = wallet.balance.greaterThan(new Decimal(1000000))
? 20
: wallet.balance.greaterThan(new Decimal(100000))
? 10
: 0;
riskFactors.balance = balanceRisk;
riskScore += balanceRisk;
// Factor 4: Recent risk history
if (wallet.riskScores.length > 0) {
const avgRecentScore = wallet.riskScores.reduce(
(sum, rs) => sum.plus(rs.riskScore),
new Decimal(0)
).div(wallet.riskScores.length);
const historyRisk = avgRecentScore.greaterThan(new Decimal(70)) ? 20 : 0;
riskFactors.history = historyRisk;
riskScore += historyRisk;
}
// Normalize to 0-100 scale
riskScore = Math.min(100, Math.max(0, riskScore));
// Create risk score record
const scoreId = `RISK-${uuidv4()}`;
const score = await prisma.walletRiskScore.create({
data: {
scoreId,
walletId: request.walletId,
riskScore: new Decimal(riskScore),
riskFactors,
},
});
return {
scoreId: score.scoreId,
riskScore: score.riskScore.toString(),
riskFactors: score.riskFactors as Record<string, unknown>,
};
}
/**
* Get latest risk score
*/
async getLatestRiskScore(walletId: string): Promise<any | null> {
const score = await prisma.walletRiskScore.findFirst({
where: { walletId },
orderBy: { calculatedAt: 'desc' },
});
return score;
}
/**
* Get risk score history
*/
async getRiskScoreHistory(walletId: string, limit: number = 10): Promise<any[]> {
const scores = await prisma.walletRiskScore.findMany({
where: { walletId },
orderBy: { calculatedAt: 'desc' },
take: limit,
});
return scores;
}
}
export const walletRiskService = new WalletRiskService();

View File

@@ -0,0 +1,181 @@
// ZK-CBDC Validation: Mode 1 - ZK-Balance Proofs (zkBP)
// Prove wallet has sufficient funds without revealing amount
import prisma from '@/shared/database/prisma';
import { v4 as uuidv4 } from 'uuid';
import { logger } from '@/infrastructure/monitoring/logger';
export interface ZkBalanceProofRequest {
walletId: string;
requiredAmount: string; // Amount to prove (not revealed in proof)
currencyCode: string;
}
export interface ZkBalanceProof {
proofId: string;
proofData: string;
publicInputs: {
walletId: string;
currencyCode: string;
sufficient: boolean; // Only this is revealed, not the actual amount
};
}
export class ZkBalanceProofService {
/**
* Generate ZK-Balance Proof
* Proves wallet has >= requiredAmount without revealing the actual balance
*/
async generateBalanceProof(request: ZkBalanceProofRequest): Promise<ZkBalanceProof> {
const proofId = `ZKBP-${uuidv4()}`;
// Get wallet balance (in production, this would be done securely)
const wallet = await this.getWalletBalance(request.walletId, request.currencyCode);
if (!wallet) {
throw new Error('Wallet not found');
}
const actualBalance = parseFloat(wallet.balance);
const requiredAmount = parseFloat(request.requiredAmount);
// Check if balance is sufficient
const sufficient = actualBalance >= requiredAmount;
if (!sufficient) {
throw new Error('Insufficient balance');
}
// Generate ZK proof (simplified - in production would use actual ZK library)
// The proof demonstrates: balance >= requiredAmount without revealing balance
const proofData = await this.generateZkProof({
balance: actualBalance,
requiredAmount,
walletId: request.walletId,
});
// Create proof record
await prisma.zkProof.create({
data: {
proofId,
walletId: request.walletId,
proofType: 'zkBP',
proofData,
publicInputs: {
walletId: request.walletId,
currencyCode: request.currencyCode,
sufficient: true,
} as unknown as Record<string, unknown>,
verificationKey: 'default_zkbp_vk', // In production, use actual verification key
status: 'verified',
verifiedAt: new Date(),
},
});
logger.info('ZK-CBDC: Generated ZK-Balance Proof', {
proofId,
walletId: request.walletId,
sufficient,
});
return {
proofId,
proofData,
publicInputs: {
walletId: request.walletId,
currencyCode: request.currencyCode,
sufficient: true,
},
};
}
/**
* Verify ZK-Balance Proof
*/
async verifyBalanceProof(proofId: string): Promise<boolean> {
const proof = await prisma.zkProof.findUnique({
where: { proofId },
});
if (!proof || proof.proofType !== 'zkBP') {
return false;
}
// Verify proof (simplified - in production would use ZK verification)
const isValid = await this.verifyZkProof(proof.proofData, proof.publicInputs as unknown as Record<string, unknown>);
if (isValid) {
await prisma.zkProof.update({
where: { proofId },
data: {
status: 'verified',
verifiedAt: new Date(),
},
});
}
return isValid;
}
/**
* Get wallet balance (internal)
*/
private async getWalletBalance(walletId: string, currencyCode: string) {
// In production, this would query CBDC wallet system
// For now, simplified lookup
return await prisma.bankAccount.findFirst({
where: {
accountNumber: walletId,
currencyCode,
assetType: 'cbdc',
},
select: {
balance: true,
},
});
}
/**
* Generate ZK proof (placeholder - in production would use circom/snarkjs)
*/
private async generateZkProof(data: {
balance: number;
requiredAmount: number;
walletId: string;
}): Promise<string> {
// In production, this would:
// 1. Create circuit witness
// 2. Generate proof using snarkjs or similar
// 3. Return proof data
// For now, return a placeholder proof
return JSON.stringify({
type: 'zkBP',
balance: data.balance,
requiredAmount: data.requiredAmount,
proof: 'placeholder_zk_proof',
});
}
/**
* Verify ZK proof (placeholder)
*/
private async verifyZkProof(proofData: string, publicInputs: Record<string, unknown>): Promise<boolean> {
// In production, this would:
// 1. Parse proof data
// 2. Verify using snarkjs or similar
// 3. Return verification result
// For now, simplified check
try {
const proof = JSON.parse(proofData);
return proof.type === 'zkBP' && publicInputs.sufficient === true;
} catch {
return false;
}
}
}
export const zkBalanceProofService = new ZkBalanceProofService();

View File

@@ -0,0 +1,72 @@
// ZK-CBDC API Routes
import { Router } from 'express';
import { zkBalanceProofService } from './zk-balance-proof.service';
import { zkComplianceProofService } from './zk-compliance-proof.service';
import { zkIdentityProofService } from './zk-identity-proof.service';
import { zkVerificationService } from './zk-verification.service';
const router = Router();
/**
* @swagger
* /api/v1/zk-cbdc/balance-proof:
* post:
* summary: Generate ZK-Balance Proof
*/
router.post('/balance-proof', async (req, res, next) => {
try {
const result = await zkBalanceProofService.generateBalanceProof(req.body);
res.json(result);
} catch (error) {
next(error);
}
});
/**
* @swagger
* /api/v1/zk-cbdc/compliance-proof:
* post:
* summary: Generate ZK-Compliance Proof
*/
router.post('/compliance-proof', async (req, res, next) => {
try {
const result = await zkComplianceProofService.generateComplianceProof(req.body);
res.json(result);
} catch (error) {
next(error);
}
});
/**
* @swagger
* /api/v1/zk-cbdc/identity-proof:
* post:
* summary: Generate ZK-Identity Proof
*/
router.post('/identity-proof', async (req, res, next) => {
try {
const result = await zkIdentityProofService.generateIdentityProof(req.body);
res.json(result);
} catch (error) {
next(error);
}
});
/**
* @swagger
* /api/v1/zk-cbdc/verify:
* post:
* summary: Verify CBDC transfer
*/
router.post('/verify', async (req, res, next) => {
try {
const result = await zkVerificationService.verifyCbdcTransfer(req.body);
res.json(result);
} catch (error) {
next(error);
}
});
export default router;

View File

@@ -0,0 +1,218 @@
// ZK-CBDC Validation: Mode 2 - ZK-Compliance Proofs (zkCP)
// AML rules satisfied, sanctions clear, transaction within policy limits
import prisma from '@/shared/database/prisma';
import { v4 as uuidv4 } from 'uuid';
import { logger } from '@/infrastructure/monitoring/logger';
import { amlVelocityEngineService } from '@/core/compliance/ai/aml-velocity-engine.service';
export interface ZkComplianceProofRequest {
walletId: string;
transactionAmount: string;
destinationWalletId: string;
currencyCode: string;
}
export interface ZkComplianceProof {
proofId: string;
proofData: string;
publicInputs: {
walletId: string;
compliant: boolean; // Only this is revealed, not the compliance details
amlClear: boolean;
sanctionsClear: boolean;
policyCompliant: boolean;
};
}
export class ZkComplianceProofService {
/**
* Generate ZK-Compliance Proof
* Proves compliance without revealing compliance details
*/
async generateComplianceProof(request: ZkComplianceProofRequest): Promise<ZkComplianceProof> {
const proofId = `ZKCP-${uuidv4()}`;
// Perform compliance checks (without revealing details in proof)
const complianceChecks = await this.performComplianceChecks(request);
// Check if all compliance checks pass
const compliant =
complianceChecks.amlClear &&
complianceChecks.sanctionsClear &&
complianceChecks.policyCompliant;
if (!compliant) {
throw new Error('Compliance check failed');
}
// Generate ZK proof
const proofData = await this.generateZkProof({
walletId: request.walletId,
transactionAmount: request.transactionAmount,
destinationWalletId: request.destinationWalletId,
complianceChecks,
});
// Create proof record
await prisma.zkProof.create({
data: {
proofId,
walletId: request.walletId,
proofType: 'zkCP',
proofData,
publicInputs: {
walletId: request.walletId,
compliant: true,
amlClear: true,
sanctionsClear: true,
policyCompliant: true,
} as unknown as Record<string, unknown>,
verificationKey: 'default_zkcp_vk',
status: 'verified',
verifiedAt: new Date(),
},
});
logger.info('ZK-CBDC: Generated ZK-Compliance Proof', {
proofId,
walletId: request.walletId,
compliant,
});
return {
proofId,
proofData,
publicInputs: {
walletId: request.walletId,
compliant: true,
amlClear: true,
sanctionsClear: true,
policyCompliant: true,
},
};
}
/**
* Perform compliance checks
*/
private async performComplianceChecks(request: ZkComplianceProofRequest): Promise<{
amlClear: boolean;
sanctionsClear: boolean;
policyCompliant: boolean;
}> {
// AML check
const amlAnomalies = await amlVelocityEngineService.detectVelocityAnomalies(
request.walletId,
'wallet',
3600000 // 1 hour
);
const amlClear = amlAnomalies.length === 0;
// Sanctions check (simplified)
const sanctionsClear = await this.checkSanctions(request.walletId, request.destinationWalletId);
// Policy compliance check
const policyCompliant = await this.checkPolicyLimits(
request.walletId,
request.transactionAmount,
request.currencyCode
);
return {
amlClear,
sanctionsClear,
policyCompliant,
};
}
/**
* Check sanctions (simplified)
*/
private async checkSanctions(walletId: string, destinationWalletId: string): Promise<boolean> {
// In production, this would query sanctions screening system
// For now, simplified check
return true;
}
/**
* Check policy limits
*/
private async checkPolicyLimits(
walletId: string,
amount: string,
currencyCode: string
): Promise<boolean> {
// In production, this would check transaction limits, velocity limits, etc.
// For now, simplified check
const amountNum = parseFloat(amount);
const maxTransactionLimit = 1000000; // $1M limit
return amountNum <= maxTransactionLimit;
}
/**
* Generate ZK proof (placeholder)
*/
private async generateZkProof(data: {
walletId: string;
transactionAmount: string;
destinationWalletId: string;
complianceChecks: {
amlClear: boolean;
sanctionsClear: boolean;
policyCompliant: boolean;
};
}): Promise<string> {
// In production, use actual ZK library
return JSON.stringify({
type: 'zkCP',
walletId: data.walletId,
compliant: data.complianceChecks.amlClear && data.complianceChecks.sanctionsClear && data.complianceChecks.policyCompliant,
proof: 'placeholder_zk_proof',
});
}
/**
* Verify ZK-Compliance Proof
*/
async verifyComplianceProof(proofId: string): Promise<boolean> {
const proof = await prisma.zkProof.findUnique({
where: { proofId },
});
if (!proof || proof.proofType !== 'zkCP') {
return false;
}
// Verify proof
const publicInputs = proof.publicInputs as unknown as {
compliant?: boolean;
amlClear?: boolean;
sanctionsClear?: boolean;
policyCompliant?: boolean;
};
const isValid =
publicInputs.compliant === true &&
publicInputs.amlClear === true &&
publicInputs.sanctionsClear === true &&
publicInputs.policyCompliant === true;
if (isValid) {
await prisma.zkProof.update({
where: { proofId },
data: {
status: 'verified',
verifiedAt: new Date(),
},
});
}
return isValid;
}
}
export const zkComplianceProofService = new ZkComplianceProofService();

View File

@@ -0,0 +1,173 @@
// ZK-CBDC Validation: Mode 3 - ZK-Identity Proofs (zkIP)
// Wallet ownership verification without identity disclosure
import prisma from '@/shared/database/prisma';
import { v4 as uuidv4 } from 'uuid';
import { logger } from '@/infrastructure/monitoring/logger';
import { gbigService } from '@/core/identity/gbig/gbig.service';
export interface ZkIdentityProofRequest {
walletId: string;
identityClaim: string; // Claim to prove (e.g., "wallet belongs to verified entity")
}
export interface ZkIdentityProof {
proofId: string;
proofData: string;
publicInputs: {
walletId: string;
verified: boolean; // Only this is revealed, not the identity
kycLevel: number; // Can reveal KYC level without revealing identity
};
}
export class ZkIdentityProofService {
/**
* Generate ZK-Identity Proof
* Proves wallet belongs to verified entity without revealing identity
*/
async generateIdentityProof(request: ZkIdentityProofRequest): Promise<ZkIdentityProof> {
const proofId = `ZKIP-${uuidv4()}`;
// Get identity information from GBIG (in production, this would be done securely)
const identityInfo = await this.getIdentityInfo(request.walletId);
if (!identityInfo || !identityInfo.verified) {
throw new Error('Wallet identity not verified');
}
// Generate ZK proof
const proofData = await this.generateZkProof({
walletId: request.walletId,
identityId: identityInfo.identityId,
kycLevel: identityInfo.kycLevel,
verified: identityInfo.verified,
});
// Create proof record
await prisma.zkProof.create({
data: {
proofId,
walletId: request.walletId,
proofType: 'zkIP',
proofData,
publicInputs: {
walletId: request.walletId,
verified: true,
kycLevel: identityInfo.kycLevel,
} as unknown as Record<string, unknown>,
verificationKey: 'default_zkip_vk',
status: 'verified',
verifiedAt: new Date(),
},
});
logger.info('ZK-CBDC: Generated ZK-Identity Proof', {
proofId,
walletId: request.walletId,
verified: true,
});
return {
proofId,
proofData,
publicInputs: {
walletId: request.walletId,
verified: true,
kycLevel: identityInfo.kycLevel,
},
};
}
/**
* Get identity information (internal)
*/
private async getIdentityInfo(walletId: string): Promise<{
identityId: string;
verified: boolean;
kycLevel: number;
} | null> {
// Query GBIG for wallet identity
// In production, this would use GBIG service
// For now, simplified lookup
try {
// Simplified: assume wallet has identity if it exists in accounts
const account = await prisma.bankAccount.findFirst({
where: {
accountNumber: walletId,
assetType: 'cbdc',
},
});
if (!account) {
return null;
}
// In production, would query GBIG for actual identity
return {
identityId: `IDENTITY-${walletId}`,
verified: true,
kycLevel: 2, // Default KYC level
};
} catch (error) {
logger.error('Failed to get identity info', { error, walletId });
return null;
}
}
/**
* Generate ZK proof (placeholder)
*/
private async generateZkProof(data: {
walletId: string;
identityId: string;
kycLevel: number;
verified: boolean;
}): Promise<string> {
// In production, use actual ZK library
return JSON.stringify({
type: 'zkIP',
walletId: data.walletId,
verified: data.verified,
kycLevel: data.kycLevel,
proof: 'placeholder_zk_proof',
});
}
/**
* Verify ZK-Identity Proof
*/
async verifyIdentityProof(proofId: string): Promise<boolean> {
const proof = await prisma.zkProof.findUnique({
where: { proofId },
});
if (!proof || proof.proofType !== 'zkIP') {
return false;
}
// Verify proof
const publicInputs = proof.publicInputs as unknown as {
verified?: boolean;
kycLevel?: number;
};
const isValid = publicInputs.verified === true && publicInputs.kycLevel !== undefined;
if (isValid) {
await prisma.zkProof.update({
where: { proofId },
data: {
status: 'verified',
verifiedAt: new Date(),
},
});
}
return isValid;
}
}
export const zkIdentityProofService = new ZkIdentityProofService();

View File

@@ -0,0 +1,170 @@
// ZK-CBDC Verification Service
// Smart contract verification: if zkBP && zkCP && zkIP: execute_CBDC_transfer()
import prisma from '@/shared/database/prisma';
import { logger } from '@/infrastructure/monitoring/logger';
import { zkBalanceProofService } from './zk-balance-proof.service';
import { zkComplianceProofService } from './zk-compliance-proof.service';
import { zkIdentityProofService } from './zk-identity-proof.service';
export interface ZkVerificationRequest {
walletId: string;
transactionAmount: string;
destinationWalletId: string;
currencyCode: string;
contractId?: string;
}
export interface ZkVerificationResult {
verificationId: string;
zkbpResult: boolean;
zkcpResult: boolean;
zkipResult: boolean;
overallResult: boolean;
canExecute: boolean;
}
export class ZkVerificationService {
/**
* Verify all ZK proofs for CBDC transfer
* if zkBP && zkCP && zkIP: execute_CBDC_transfer()
*/
async verifyCbdcTransfer(request: ZkVerificationRequest): Promise<ZkVerificationResult> {
const verificationId = `ZK-VERIFY-${uuidv4()}`;
try {
// Generate and verify ZK-Balance Proof
const zkbpProof = await zkBalanceProofService.generateBalanceProof({
walletId: request.walletId,
requiredAmount: request.transactionAmount,
currencyCode: request.currencyCode,
});
const zkbpResult = await zkBalanceProofService.verifyBalanceProof(zkbpProof.proofId);
// Generate and verify ZK-Compliance Proof
const zkcpProof = await zkComplianceProofService.generateComplianceProof({
walletId: request.walletId,
transactionAmount: request.transactionAmount,
destinationWalletId: request.destinationWalletId,
currencyCode: request.currencyCode,
});
const zkcpResult = await zkComplianceProofService.verifyComplianceProof(zkcpProof.proofId);
// Generate and verify ZK-Identity Proof
const zkipProof = await zkIdentityProofService.generateIdentityProof({
walletId: request.walletId,
identityClaim: 'wallet belongs to verified entity',
});
const zkipResult = await zkIdentityProofService.verifyIdentityProof(zkipProof.proofId);
// Overall result: all proofs must be valid
const overallResult = zkbpResult && zkcpResult && zkipResult;
// Create verification record
await prisma.zkVerification.create({
data: {
verificationId,
proofId: zkbpProof.proofId, // Reference to one of the proofs
contractId: request.contractId || null,
verificationType: 'combined',
zkbpResult,
zkcpResult,
zkipResult,
overallResult,
status: overallResult ? 'verified' : 'rejected',
verifiedAt: overallResult ? new Date() : null,
},
});
logger.info('ZK-CBDC: Verification completed', {
verificationId,
zkbpResult,
zkcpResult,
zkipResult,
overallResult,
});
return {
verificationId,
zkbpResult,
zkcpResult,
zkipResult,
overallResult,
canExecute: overallResult,
};
} catch (error) {
logger.error('ZK-CBDC: Verification failed', { error, request });
// Create failed verification record
await prisma.zkVerification.create({
data: {
verificationId,
proofId: '',
contractId: request.contractId || null,
verificationType: 'combined',
zkbpResult: false,
zkcpResult: false,
zkipResult: false,
overallResult: false,
status: 'rejected',
},
});
return {
verificationId,
zkbpResult: false,
zkcpResult: false,
zkipResult: false,
overallResult: false,
canExecute: false,
};
}
}
/**
* Execute CBDC transfer if verification passes
*/
async executeCbdcTransferIfVerified(
verificationId: string,
transferRequest: {
sourceWalletId: string;
destinationWalletId: string;
amount: string;
currencyCode: string;
}
): Promise<{ executed: boolean; transactionId?: string }> {
const verification = await prisma.zkVerification.findUnique({
where: { verificationId },
});
if (!verification || !verification.overallResult) {
logger.warn('ZK-CBDC: Transfer not executed - verification failed', { verificationId });
return { executed: false };
}
// Execute transfer (in production, would call CBDC transaction service)
try {
// Simplified transfer execution
const transactionId = `CBDC-TX-${Date.now()}`;
logger.info('ZK-CBDC: Executing CBDC transfer', {
verificationId,
transactionId,
transferRequest,
});
// In production, would actually execute the transfer
return {
executed: true,
transactionId,
};
} catch (error) {
logger.error('ZK-CBDC: Transfer execution failed', { error, verificationId });
return { executed: false };
}
}
}
export const zkVerificationService = new ZkVerificationService();

View File

@@ -0,0 +1,44 @@
// Clearing & Settlement Module
import prisma from '@/shared/database/prisma';
import { ledgerService } from '@/core/ledger/ledger.service';
import { paymentService } from '@/core/payments/payment.service';
import { AssetType, PaymentRequest, PaymentPriority } from '@/shared/types';
import { v4 as uuidv4 } from 'uuid';
export class ClearingService {
/**
* Process clearing through DBIS Clearing House (DCH)
*/
async processClearing(request: PaymentRequest): Promise<string> {
// Process payment through clearing house
const paymentStatus = await paymentService.initiatePayment(request);
// Apply multi-tier netting if applicable
if (request.priority === PaymentPriority.DNS) {
await this.applyNetting(request);
}
return paymentStatus.paymentId;
}
/**
* Apply multi-tier netting for DNS payments
*/
private async applyNetting(request: PaymentRequest): Promise<void> {
// In production, this would aggregate multiple payments and net them
// For now, simplified implementation
}
/**
* Enforce settlement finality
*/
async enforceSettlementFinality(paymentId: string): Promise<boolean> {
const paymentStatus = await paymentService.getPaymentStatus(paymentId);
return paymentStatus.status === 'settled';
}
}
export const clearingService = new ClearingService();

View File

@@ -0,0 +1,147 @@
// MACE Allocation Service
// Optimal collateral allocation logic
import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
import { maceOptimizationService } from './mace-optimization.service';
export interface AllocationRequest {
requiredAmount: string;
currencyCode: string;
assetTypes: string[]; // fiat, cbdc, commodity, security, ssu
targetBankId?: string;
}
export interface AllocationResult {
collateralId: string;
allocations: Array<{
assetType: string;
amount: string;
valuation: string;
}>;
totalValuation: string;
}
export class MaceAllocationService {
/**
* Allocate multi-asset collateral
*/
async allocateCollateral(
request: AllocationRequest
): Promise<AllocationResult> {
// Get available assets
const availableAssets = await this.getAvailableAssets(
request.assetTypes,
request.targetBankId
);
// Optimize allocation
const optimization = await maceOptimizationService.optimizeAllocation({
requiredAmount: request.requiredAmount,
currencyCode: request.currencyCode,
availableAssets,
targetBankId: request.targetBankId,
});
// Create collateral allocations
const collateralId = `COLL-${uuidv4()}`;
const allocations = [];
for (const allocation of optimization.optimalAllocation) {
const valuation = await this.valuateAsset(
allocation.assetType,
allocation.amount,
request.currencyCode
);
await prisma.multiAssetCollateral.create({
data: {
collateralId: `${collateralId}-${allocation.assetType}`,
assetType: allocation.assetType,
assetId: allocation.assetId,
amount: new Decimal(allocation.amount),
valuation,
status: 'active',
},
});
allocations.push({
assetType: allocation.assetType,
amount: allocation.amount,
valuation: valuation.toString(),
});
}
// Calculate total valuation
const totalValuation = allocations.reduce(
(sum, alloc) => sum.plus(new Decimal(alloc.valuation)),
new Decimal(0)
);
// Apply optimization
await maceOptimizationService.applyOptimization(optimization.optimizationId);
return {
collateralId,
allocations,
totalValuation: totalValuation.toString(),
};
}
/**
* Get available assets
*/
private async getAvailableAssets(
assetTypes: string[],
targetBankId?: string
): Promise<Array<{ assetType: string; assetId?: string; amount: string }>> {
// In production, would query actual asset holdings
// For now, return mock data
const assets: Array<{ assetType: string; assetId?: string; amount: string }> = [];
for (const assetType of assetTypes) {
assets.push({
assetType,
amount: '1000000', // Mock amount
});
}
return assets;
}
/**
* Valuate asset
*/
private async valuateAsset(
assetType: string,
amount: string,
targetCurrency: string
): Promise<Decimal> {
// In production, would use actual valuation service
// For now, return amount as valuation (1:1)
return new Decimal(amount);
}
/**
* Release collateral
*/
async releaseCollateral(collateralId: string): Promise<void> {
await prisma.multiAssetCollateral.updateMany({
where: {
collateralId: {
startsWith: collateralId,
},
status: 'active',
},
data: {
status: 'released',
releasedAt: new Date(),
},
});
}
}
export const maceAllocationService = new MaceAllocationService();

View File

@@ -0,0 +1,105 @@
// MACE Monitoring Service
// Real-time collateral monitoring
import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
export interface MonitoringRequest {
collateralId: string;
}
export interface MonitoringResult {
collateralId: string;
totalValuation: string;
haircutAdjustedValue: string;
status: string;
alerts: string[];
}
export class MaceMonitoringService {
/**
* Monitor collateral
*/
async monitorCollateral(
request: MonitoringRequest
): Promise<MonitoringResult> {
const collaterals = await prisma.multiAssetCollateral.findMany({
where: {
collateralId: {
startsWith: request.collateralId,
},
status: 'active',
},
});
if (collaterals.length === 0) {
throw new Error(`Collateral not found: ${request.collateralId}`);
}
// Calculate total valuation
const totalValuation = collaterals.reduce(
(sum, coll) => sum.plus(coll.valuation),
new Decimal(0)
);
// Calculate haircut-adjusted value
let haircutAdjustedValue = new Decimal(0);
const alerts: string[] = [];
for (const coll of collaterals) {
const haircut = await this.getHaircut(coll.assetType);
const adjustedValue = coll.valuation.mul(new Decimal(100).minus(haircut)).div(100);
haircutAdjustedValue = haircutAdjustedValue.plus(adjustedValue);
// Check for alerts
if (coll.valuation.lessThan(new Decimal(1000))) {
alerts.push(`Low valuation for ${coll.assetType}: ${coll.valuation.toString()}`);
}
}
// Check overall status
let status = 'healthy';
if (haircutAdjustedValue.lessThan(totalValuation.mul(0.9))) {
status = 'warning';
alerts.push('Haircut-adjusted value below 90% of total valuation');
}
return {
collateralId: request.collateralId,
totalValuation: totalValuation.toString(),
haircutAdjustedValue: haircutAdjustedValue.toString(),
status,
alerts,
};
}
/**
* Get haircut
*/
private async getHaircut(assetType: string): Promise<Decimal> {
const haircut = await prisma.collateralHaircut.findFirst({
where: {
assetType,
status: 'active',
},
});
return haircut ? haircut.haircutRate : new Decimal(5); // Default 5%
}
/**
* Get all active collaterals
*/
async getActiveCollaterals(): Promise<any[]> {
const collaterals = await prisma.multiAssetCollateral.findMany({
where: { status: 'active' },
orderBy: { allocatedAt: 'desc' },
});
return collaterals;
}
}
export const maceMonitoringService = new MaceMonitoringService();

View File

@@ -0,0 +1,246 @@
// MACE Optimization Service
// Optimal collateral allocation: argmin(haircuts + fx_cost + liquidity_weight + risk_penalty(SRI))
import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
import { sriCalculatorService } from '@/core/risk/sri/sri-calculator.service';
export interface OptimizationRequest {
requiredAmount: string;
currencyCode: string;
availableAssets: Array<{
assetType: string;
assetId?: string;
amount: string;
}>;
targetBankId?: string;
}
export interface OptimizationResult {
optimizationId: string;
optimalAllocation: Array<{
assetType: string;
assetId?: string;
amount: string;
cost: string;
}>;
totalCost: string;
status: string;
}
export class MaceOptimizationService {
/**
* Calculate optimal collateral allocation
* argmin(haircuts + fx_cost + liquidity_weight + risk_penalty(SRI))
*/
async optimizeAllocation(
request: OptimizationRequest
): Promise<OptimizationResult> {
const requiredAmount = new Decimal(request.requiredAmount);
const optimizationId = `OPT-${uuidv4()}`;
// Get haircuts and liquidity weights for each asset type
const assetCosts = await Promise.all(
request.availableAssets.map(async (asset) => {
const cost = await this.calculateAssetCost(
asset.assetType,
asset.amount,
request.currencyCode,
request.targetBankId
);
return {
...asset,
cost: cost.totalCost,
haircut: cost.haircut,
fxCost: cost.fxCost,
liquidityWeight: cost.liquidityWeight,
riskPenalty: cost.riskPenalty,
};
})
);
// Sort by total cost (ascending)
assetCosts.sort((a, b) => a.cost.comparedTo(b.cost));
// Greedy allocation: use cheapest assets first
const optimalAllocation: Array<{
assetType: string;
assetId?: string;
amount: string;
cost: string;
}> = [];
let remainingAmount = requiredAmount;
let totalCost = new Decimal(0);
for (const asset of assetCosts) {
if (remainingAmount.isZero()) {
break;
}
const availableAmount = new Decimal(asset.amount);
const allocationAmount = remainingAmount.lessThan(availableAmount)
? remainingAmount
: availableAmount;
const allocationCost = asset.cost.mul(allocationAmount).div(requiredAmount);
optimalAllocation.push({
assetType: asset.assetType,
assetId: asset.assetId,
amount: allocationAmount.toString(),
cost: allocationCost.toString(),
});
totalCost = totalCost.plus(allocationCost);
remainingAmount = remainingAmount.minus(allocationAmount);
}
if (!remainingAmount.isZero()) {
throw new Error('Insufficient collateral available');
}
// Create optimization record
const optimization = await prisma.collateralOptimization.create({
data: {
optimizationId,
collateralId: uuidv4(), // Would link to actual collateral
optimizationType: 'allocation',
optimalAllocation: optimalAllocation,
totalCost,
calculationMethod: 'argmin',
status: 'pending',
},
});
return {
optimizationId: optimization.optimizationId,
optimalAllocation,
totalCost: totalCost.toString(),
status: optimization.status,
};
}
/**
* Calculate asset cost
*/
private async calculateAssetCost(
assetType: string,
amount: string,
targetCurrency: string,
targetBankId?: string
): Promise<{
totalCost: Decimal;
haircut: Decimal;
fxCost: Decimal;
liquidityWeight: Decimal;
riskPenalty: Decimal;
}> {
// Get haircut
const haircut = await this.getHaircut(assetType);
const haircutCost = new Decimal(amount).mul(haircut).div(100);
// Get FX cost (if asset currency differs from target)
const fxCost = await this.getFxCost(assetType, targetCurrency);
const fxCostAmount = new Decimal(amount).mul(fxCost).div(100);
// Get liquidity weight
const liquidityWeight = await this.getLiquidityWeight(assetType);
const liquidityCost = new Decimal(amount).mul(liquidityWeight).div(100);
// Get risk penalty (SRI-based)
const riskPenalty = targetBankId
? await this.getRiskPenalty(targetBankId)
: new Decimal(0);
const riskCost = new Decimal(amount).mul(riskPenalty).div(100);
// Total cost = haircuts + fx_cost + liquidity_weight + risk_penalty
const totalCost = haircutCost.plus(fxCostAmount).plus(liquidityCost).plus(riskCost);
return {
totalCost,
haircut,
fxCost,
liquidityWeight,
riskPenalty,
};
}
/**
* Get haircut for asset type
*/
private async getHaircut(assetType: string): Promise<Decimal> {
const haircut = await prisma.collateralHaircut.findFirst({
where: {
assetType,
status: 'active',
},
});
return haircut ? haircut.haircutRate : new Decimal(5); // Default 5%
}
/**
* Get FX cost
*/
private async getFxCost(assetType: string, targetCurrency: string): Promise<Decimal> {
// In production, would calculate actual FX conversion cost
// For now, return minimal cost
return new Decimal(0.1); // 0.1%
}
/**
* Get liquidity weight
*/
private async getLiquidityWeight(assetType: string): Promise<Decimal> {
const liquidity = await prisma.collateralLiquidity.findFirst({
where: {
assetType,
status: 'active',
},
});
return liquidity ? liquidity.liquidityWeight : new Decimal(1); // Default 1%
}
/**
* Get risk penalty (SRI-based)
*/
private async getRiskPenalty(sovereignBankId: string): Promise<Decimal> {
const sri = await prisma.sovereignRiskIndex.findFirst({
where: {
sovereignBankId,
status: 'active',
},
orderBy: { calculatedAt: 'desc' },
});
if (!sri) {
return new Decimal(0);
}
// Convert SRI score (0-100) to penalty (0-5%)
const sriScore = parseFloat(sri.sriScore.toString());
const penalty = new Decimal(sriScore).div(100).mul(5); // Max 5% penalty
return penalty;
}
/**
* Apply optimization
*/
async applyOptimization(optimizationId: string): Promise<void> {
await prisma.collateralOptimization.update({
where: { optimizationId },
data: {
status: 'applied',
appliedAt: new Date(),
},
});
}
}
export const maceOptimizationService = new MaceOptimizationService();

View File

@@ -0,0 +1,140 @@
// MACE Valuation Service
// Multi-asset valuation
import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
export interface ValuationRequest {
assetType: string;
amount: string;
currencyCode: string;
}
export interface ValuationResult {
valuation: string;
currencyCode: string;
fxRate?: string;
}
export class MaceValuationService {
/**
* Valuate asset
*/
async valuateAsset(request: ValuationRequest): Promise<ValuationResult> {
switch (request.assetType) {
case 'fiat':
return this.valuateFiat(request);
case 'cbdc':
return this.valuateCBDC(request);
case 'commodity':
return this.valuateCommodity(request);
case 'security':
return this.valuateSecurity(request);
case 'ssu':
return this.valuateSSU(request);
default:
throw new Error(`Unsupported asset type: ${request.assetType}`);
}
}
/**
* Valuate fiat
*/
private async valuateFiat(request: ValuationRequest): Promise<ValuationResult> {
// Fiat is already in currency, return as-is
return {
valuation: request.amount,
currencyCode: request.currencyCode,
};
}
/**
* Valuate CBDC
*/
private async valuateCBDC(request: ValuationRequest): Promise<ValuationResult> {
// CBDC is 1:1 with fiat, return as-is
return {
valuation: request.amount,
currencyCode: request.currencyCode,
};
}
/**
* Valuate commodity
*/
private async valuateCommodity(request: ValuationRequest): Promise<ValuationResult> {
// Get commodity price
const commodity = await prisma.commodity.findFirst({
where: {
commodityType: request.currencyCode, // Using currencyCode as commodity type
},
});
if (!commodity) {
throw new Error(`Commodity not found: ${request.currencyCode}`);
}
const amount = new Decimal(request.amount);
const valuation = amount.mul(commodity.spotPrice);
return {
valuation: valuation.toString(),
currencyCode: 'USD', // Commodities typically valued in USD
fxRate: commodity.spotPrice.toString(),
};
}
/**
* Valuate security
*/
private async valuateSecurity(request: ValuationRequest): Promise<ValuationResult> {
// Get security price
const security = await prisma.securitiesSubLedger.findFirst({
where: {
securityId: request.currencyCode, // Using currencyCode as security ID
},
});
if (!security || !security.price) {
throw new Error(`Security not found or no price: ${request.currencyCode}`);
}
const amount = new Decimal(request.amount);
const valuation = amount.mul(security.price);
return {
valuation: valuation.toString(),
currencyCode: request.currencyCode,
fxRate: security.price.toString(),
};
}
/**
* Valuate SSU
*/
private async valuateSSU(request: ValuationRequest): Promise<ValuationResult> {
// Get SSU conversion rate
const ssu = await prisma.syntheticSettlementUnit.findFirst({
where: {
status: 'active',
},
});
if (!ssu || !ssu.conversionRate) {
throw new Error('SSU not found or no conversion rate');
}
const amount = new Decimal(request.amount);
const valuation = amount.mul(ssu.conversionRate);
return {
valuation: valuation.toString(),
currencyCode: request.currencyCode,
fxRate: ssu.conversionRate.toString(),
};
}
}
export const maceValuationService = new MaceValuationService();

View File

@@ -0,0 +1,90 @@
// CBDS API Routes
import { Router } from 'express';
import { cdtService } from './cdt-service';
import { reserveCertificateService } from './reserve-certificate.service';
import { cdtSettlementService } from './cdt-settlement.service';
const router = Router();
/**
* @swagger
* /api/v1/cbds/cdt/mint:
* post:
* summary: Mint CDT from reserves
*/
router.post('/cdt/mint', async (req, res, next) => {
try {
const cdtId = await cdtService.mintCdt(req.body);
res.json({ cdtId });
} catch (error) {
next(error);
}
});
/**
* @swagger
* /api/v1/cbds/cdt/burn:
* post:
* summary: Burn CDT
*/
router.post('/cdt/burn', async (req, res, next) => {
try {
const { cdtId, reason } = req.body;
const result = await cdtService.burnCdt(cdtId, reason);
res.json({ success: result });
} catch (error) {
next(error);
}
});
/**
* @swagger
* /api/v1/cbds/cdt/:cdtId:
* get:
* summary: Get CDT details
*/
router.get('/cdt/:cdtId', async (req, res, next) => {
try {
const cdt = await cdtService.getCdt(req.params.cdtId);
if (!cdt) {
return res.status(404).json({ error: 'CDT not found' });
}
res.json(cdt);
} catch (error) {
next(error);
}
});
/**
* @swagger
* /api/v1/cbds/reserve-certificate/create:
* post:
* summary: Create reserve certificate
*/
router.post('/reserve-certificate/create', async (req, res, next) => {
try {
const certificateId = await reserveCertificateService.createReserveCertificate(req.body);
res.json({ certificateId });
} catch (error) {
next(error);
}
});
/**
* @swagger
* /api/v1/cbds/settle:
* post:
* summary: Execute CDT settlement
*/
router.post('/settle', async (req, res, next) => {
try {
const transactionId = await cdtSettlementService.executeSettlement(req.body);
res.json({ transactionId });
} catch (error) {
next(error);
}
});
export default router;

View File

@@ -0,0 +1,237 @@
// CDT Service
// CDT tokenization from physical reserves
// Reserve certificate verification
// CDT structure: {commodity_type, weight, reserve_certificate, custodian, sovereign_issuer, timestamp, signature}
// CDT minting and burning
import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
import { reserveCertificateService } from './reserve-certificate.service';
import { createHash } from 'crypto';
export interface CdtMintRequest {
commodityType: string;
weight: string;
unit: string;
reserveCertificateId: string;
custodianId: string;
sovereignIssuerId: string;
}
export interface CdtStructure {
commodityType: string;
weight: Decimal;
reserveCertificate: string;
custodian: string;
sovereignIssuer: string;
timestamp: Date;
signature: string;
}
export class CdtService {
/**
* Mint CDT from reserves
*/
async mintCdt(request: CdtMintRequest): Promise<string> {
// Verify reserve certificate
const certificate = await reserveCertificateService.verifyCertificate(
request.reserveCertificateId
);
if (!certificate || certificate.verificationStatus !== 'verified') {
throw new Error('Reserve certificate not verified');
}
// Verify custodian
const custodian = await prisma.commodityCustodian.findUnique({
where: { custodianId: request.custodianId },
});
if (!custodian || custodian.approvalStatus !== 'approved') {
throw new Error('Custodian not approved');
}
// Verify certificate belongs to custodian
if (certificate.custodianId !== request.custodianId) {
throw new Error('Reserve certificate does not belong to custodian');
}
// Generate CDT ID
const cdtId = `CDT-${request.commodityType}-${uuidv4()}`;
// Create CDT structure
const cdtStructure = await this.createCdtStructure(request, cdtId);
// Create CDT
const cdt = await prisma.commodityDigitalToken.create({
data: {
cdtId,
commodityType: request.commodityType.toUpperCase(),
weight: new Decimal(request.weight),
unit: request.unit,
reserveCertificateId: request.reserveCertificateId,
custodianId: request.custodianId,
sovereignIssuerId: request.sovereignIssuerId,
timestamp: new Date(),
signature: cdtStructure.signature,
status: 'active',
},
});
return cdt.cdtId;
}
/**
* Create CDT structure
*/
private async createCdtStructure(
request: CdtMintRequest,
cdtId: string
): Promise<CdtStructure> {
// Get certificate hash
const certificate = await prisma.commodityReserveCertificate.findUnique({
where: { certificateId: request.reserveCertificateId },
});
if (!certificate) {
throw new Error('Reserve certificate not found');
}
// Create CDT structure
const cdtData = {
commodity_type: request.commodityType.toUpperCase(),
weight: request.weight,
reserve_certificate: certificate.certificateHash,
custodian: request.custodianId,
sovereign_issuer: request.sovereignIssuerId,
timestamp: new Date().toISOString(),
};
// Generate signature (in production, this would be HSM-signed)
const signature = this.generateSignature(cdtData);
return {
commodityType: request.commodityType.toUpperCase(),
weight: new Decimal(request.weight),
reserveCertificate: certificate.certificateHash,
custodian: request.custodianId,
sovereignIssuer: request.sovereignIssuerId,
timestamp: new Date(),
signature,
};
}
/**
* Generate CDT signature
*/
private generateSignature(cdtData: Record<string, unknown>): string {
const dataString = JSON.stringify(cdtData);
return createHash('sha256').update(dataString).digest('hex');
}
/**
* Burn CDT
*/
async burnCdt(cdtId: string, reason?: string): Promise<boolean> {
const cdt = await prisma.commodityDigitalToken.findUnique({
where: { cdtId },
});
if (!cdt || cdt.status !== 'active') {
throw new Error('CDT not found or not active');
}
// Create burn transaction
await prisma.cdtTransaction.create({
data: {
transactionId: `CDT-TX-BURN-${uuidv4()}`,
cdtId,
transactionType: 'burn',
amount: cdt.weight,
status: 'completed',
completedAt: new Date(),
},
});
// Update CDT status
await prisma.commodityDigitalToken.update({
where: { cdtId },
data: {
status: 'burned',
},
});
return true;
}
/**
* Get CDT by ID
*/
async getCdt(cdtId: string) {
return await prisma.commodityDigitalToken.findUnique({
where: { cdtId },
include: {
reserveCertificate: true,
custodian: true,
transactions: {
orderBy: { createdAt: 'desc' },
take: 10,
},
},
});
}
/**
* List CDTs by commodity type
*/
async listCdts(
commodityType?: string,
status?: string,
limit: number = 100
) {
return await prisma.commodityDigitalToken.findMany({
where: {
...(commodityType && { commodityType }),
...(status && { status }),
},
orderBy: { createdAt: 'desc' },
take: limit,
});
}
/**
* Verify CDT structure
*/
async verifyCdtStructure(cdtId: string): Promise<boolean> {
const cdt = await prisma.commodityDigitalToken.findUnique({
where: { cdtId },
include: {
reserveCertificate: true,
},
});
if (!cdt) {
return false;
}
// Reconstruct CDT structure
const cdtData = {
commodity_type: cdt.commodityType,
weight: cdt.weight.toString(),
reserve_certificate: cdt.reserveCertificate.certificateHash,
custodian: cdt.custodianId,
sovereign_issuer: cdt.sovereignIssuerId,
timestamp: cdt.timestamp.toISOString(),
};
// Verify signature
const dataString = JSON.stringify(cdtData);
const expectedSignature = createHash('sha256').update(dataString).digest('hex');
return cdt.signature === expectedSignature;
}
}
export const cdtService = new CdtService();

View File

@@ -0,0 +1,305 @@
// CDT Settlement Service
// SSU derivatives settlement
// Direct exchange: CDT ↔ CBDC
// Cross-commodity swaps
// Multi-leg commodity settlements
import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
export interface CdtSettlementRequest {
cdtId: string;
targetAssetType: string; // ssu, cbdc, commodity
targetAssetId?: string;
targetAmount?: string;
sourceBankId?: string;
destinationBankId?: string;
}
export interface CrossCommoditySwapRequest {
sourceCdtId: string;
targetCommodityType: string;
targetAmount: string;
}
export class CdtSettlementService {
/**
* Execute CDT settlement
*/
async executeSettlement(
request: CdtSettlementRequest
): Promise<string> {
const cdt = await prisma.commodityDigitalToken.findUnique({
where: { cdtId: request.cdtId },
});
if (!cdt || cdt.status !== 'active') {
throw new Error('CDT not found or not active');
}
let transactionType = 'transfer';
// Determine settlement type
if (request.targetAssetType === 'ssu') {
transactionType = 'ssu_derivative';
return await this.settleSsuDerivative(request);
} else if (request.targetAssetType === 'cbdc') {
transactionType = 'exchange_cbdc';
return await this.exchangeCdtForCbdc(request);
} else if (request.targetAssetType === 'commodity') {
transactionType = 'cross_commodity_swap';
return await this.executeCrossCommoditySwap({
sourceCdtId: request.cdtId,
targetCommodityType: request.targetAssetId || '',
targetAmount: request.targetAmount || cdt.weight.toString(),
});
} else {
throw new Error(`Unsupported target asset type: ${request.targetAssetType}`);
}
}
/**
* Settle SSU derivative
*/
private async settleSsuDerivative(
request: CdtSettlementRequest
): Promise<string> {
const transactionId = `CDT-TX-SSU-${uuidv4()}`;
// Create transaction
await prisma.cdtTransaction.create({
data: {
transactionId,
cdtId: request.cdtId,
transactionType: 'ssu_derivative',
sourceBankId: request.sourceBankId || null,
destinationBankId: request.destinationBankId || null,
targetAssetType: 'ssu',
targetAssetId: request.targetAssetId || null,
amount: new Decimal(0), // Will be calculated based on SSU value
status: 'completed',
completedAt: new Date(),
},
});
// In production, this would:
// 1. Calculate SSU equivalent value
// 2. Execute SSU transfer
// 3. Update balances
return transactionId;
}
/**
* Exchange CDT for CBDC
*/
private async exchangeCdtForCbdc(
request: CdtSettlementRequest
): Promise<string> {
const cdt = await prisma.commodityDigitalToken.findUnique({
where: { cdtId: request.cdtId },
include: {
reserveCertificate: true,
},
});
if (!cdt) {
throw new Error('CDT not found');
}
// Get commodity spot price
const commodity = await prisma.commodity.findFirst({
where: {
commodityType: cdt.commodityType,
unit: cdt.unit,
},
});
if (!commodity) {
throw new Error('Commodity pricing not found');
}
// Calculate CBDC amount (CDT weight * spot price)
const cdtValue = cdt.weight.mul(commodity.spotPrice);
const cbdcAmount = request.targetAmount
? new Decimal(request.targetAmount)
: cdtValue;
const transactionId = `CDT-TX-CBDC-${uuidv4()}`;
// Create transaction
await prisma.cdtTransaction.create({
data: {
transactionId,
cdtId: request.cdtId,
transactionType: 'exchange_cbdc',
sourceBankId: request.sourceBankId || null,
destinationBankId: request.destinationBankId || null,
targetAssetType: 'cbdc',
targetAssetId: request.targetAssetId || null,
amount: cbdcAmount,
status: 'completed',
completedAt: new Date(),
},
});
// In production, this would:
// 1. Transfer CDT
// 2. Mint/transfer CBDC
// 3. Update balances
return transactionId;
}
/**
* Execute cross-commodity swap
*/
async executeCrossCommoditySwap(
request: CrossCommoditySwapRequest
): Promise<string> {
const sourceCdt = await prisma.commodityDigitalToken.findUnique({
where: { cdtId: request.sourceCdtId },
include: {
reserveCertificate: true,
},
});
if (!sourceCdt || sourceCdt.status !== 'active') {
throw new Error('Source CDT not found or not active');
}
// Get commodity prices
const sourceCommodity = await prisma.commodity.findFirst({
where: {
commodityType: sourceCdt.commodityType,
unit: sourceCdt.unit,
},
});
const targetCommodity = await prisma.commodity.findFirst({
where: {
commodityType: request.targetCommodityType.toUpperCase(),
unit: sourceCdt.unit, // Assume same unit
},
});
if (!sourceCommodity || !targetCommodity) {
throw new Error('Commodity pricing not found');
}
// Calculate swap ratio
const sourceValue = sourceCdt.weight.mul(sourceCommodity.spotPrice);
const targetPrice = targetCommodity.spotPrice;
const targetWeight = sourceValue.div(targetPrice);
const transactionId = `CDT-TX-SWAP-${uuidv4()}`;
// Create transaction
await prisma.cdtTransaction.create({
data: {
transactionId,
cdtId: request.sourceCdtId,
transactionType: 'cross_commodity_swap',
targetAssetType: 'commodity',
targetAssetId: request.targetCommodityType.toUpperCase(),
amount: targetWeight,
status: 'completed',
completedAt: new Date(),
},
});
// In production, this would:
// 1. Burn source CDT
// 2. Mint target CDT
// 3. Update balances
return transactionId;
}
/**
* Execute multi-leg commodity settlement
*/
async executeMultiLegSettlement(
legs: Array<{
cdtId: string;
targetAssetType: string;
targetAssetId?: string;
amount?: string;
}>
): Promise<string[]> {
const transactionIds: string[] = [];
try {
// Execute all legs
for (const leg of legs) {
const transactionId = await this.executeSettlement({
cdtId: leg.cdtId,
targetAssetType: leg.targetAssetType,
targetAssetId: leg.targetAssetId,
targetAmount: leg.amount,
});
transactionIds.push(transactionId);
}
return transactionIds;
} catch (error) {
// Rollback on error
for (const transactionId of transactionIds) {
try {
await prisma.cdtTransaction.update({
where: { transactionId },
data: {
status: 'failed',
},
});
} catch (rollbackError) {
// Ignore rollback errors
}
}
throw error;
}
}
/**
* Get CDT transactions
*/
async getCdtTransactions(
cdtId?: string,
transactionType?: string,
status?: string,
limit: number = 100
) {
return await prisma.cdtTransaction.findMany({
where: {
...(cdtId && { cdtId }),
...(transactionType && { transactionType }),
...(status && { status }),
},
orderBy: { createdAt: 'desc' },
take: limit,
});
}
/**
* Get transaction by ID
*/
async getTransaction(transactionId: string) {
return await prisma.cdtTransaction.findUnique({
where: { transactionId },
include: {
cdt: {
include: {
reserveCertificate: true,
},
},
},
});
}
}
export const cdtSettlementService = new CdtSettlementService();

Some files were not shown because too many files have changed in this diff Show More