Initial project setup: Add contracts, API definitions, tests, and documentation

- Add Foundry project configuration (foundry.toml, foundry.lock)
- Add Solidity contracts (TokenFactory138, BridgeVault138, ComplianceRegistry, etc.)
- Add API definitions (OpenAPI, GraphQL, gRPC, AsyncAPI)
- Add comprehensive test suite (unit, integration, fuzz, invariants)
- Add API services (REST, GraphQL, orchestrator, packet service)
- Add documentation (ISO20022 mapping, runbooks, adapter guides)
- Add development tools (RBC tool, Swagger UI, mock server)
- Update OpenZeppelin submodules to v5.0.0
This commit is contained in:
defiQUG
2025-12-12 10:59:41 -08:00
parent 26b5aaf932
commit 651ff4f7eb
281 changed files with 24813 additions and 2 deletions

View File

@@ -0,0 +1,27 @@
/**
* ISO-20022 Orchestrator Service
* Manages trigger state machine and coordinates rail adapters
*/
import express from 'express';
import { orchestratorRouter } from './routes/orchestrator';
import { triggerStateMachine } from './services/state-machine';
import { isoRouter } from './services/iso-router';
const app = express();
const PORT = process.env.PORT || 3002;
app.use(express.json());
// Orchestrator API routes
app.use('/v1/orchestrator', orchestratorRouter);
// ISO-20022 router
app.use('/v1/iso', isoRouter);
app.listen(PORT, () => {
console.log(`Orchestrator service listening on port ${PORT}`);
});
export default app;

View File

@@ -0,0 +1,47 @@
/**
* Orchestrator API routes
*/
import { Router, Request, Response } from 'express';
import { triggerStateMachine } from '../services/state-machine';
export const orchestratorRouter = Router();
orchestratorRouter.post('/triggers/:triggerId/validate-and-lock', async (req: Request, res: Response) => {
try {
const trigger = await triggerStateMachine.validateAndLock(req.params.triggerId);
res.json(trigger);
} catch (error: any) {
res.status(400).json({ error: error.message });
}
});
orchestratorRouter.post('/triggers/:triggerId/mark-submitted', async (req: Request, res: Response) => {
try {
const { railTxRef } = req.body;
const trigger = await triggerStateMachine.markSubmitted(req.params.triggerId, railTxRef);
res.json(trigger);
} catch (error: any) {
res.status(400).json({ error: error.message });
}
});
orchestratorRouter.post('/triggers/:triggerId/confirm-settled', async (req: Request, res: Response) => {
try {
const trigger = await triggerStateMachine.confirmSettled(req.params.triggerId);
res.json(trigger);
} catch (error: any) {
res.status(400).json({ error: error.message });
}
});
orchestratorRouter.post('/triggers/:triggerId/confirm-rejected', async (req: Request, res: Response) => {
try {
const { reason } = req.body;
const trigger = await triggerStateMachine.confirmRejected(req.params.triggerId, reason);
res.json(trigger);
} catch (error: any) {
res.status(400).json({ error: error.message });
}
});

View File

@@ -0,0 +1,60 @@
/**
* ISO-20022 Router
* Routes ISO-20022 messages to appropriate handlers and creates canonical messages
*/
import { Router } from 'express';
import { readFileSync } from 'fs';
import { join } from 'path';
import * as yaml from 'js-yaml';
// Load ISO-20022 mappings
const mappingsPath = join(__dirname, '../../../packages/schemas/iso20022-mapping/message-mappings.yaml');
const mappings = yaml.load(readFileSync(mappingsPath, 'utf-8')) as any;
export const isoRouter = Router();
export const isoRouterService = {
/**
* Normalize ISO-20022 message to canonical format
*/
async normalizeMessage(msgType: string, payload: string, rail: string): Promise<any> {
const mapping = mappings.mappings[msgType];
if (!mapping) {
throw new Error(`Unknown message type: ${msgType}`);
}
// TODO: Parse XML payload and extract fields according to mapping
// TODO: Create canonical message
throw new Error('Not implemented');
},
/**
* Create trigger from canonical message
*/
async createTrigger(canonicalMessage: any, rail: string): Promise<string> {
// TODO: Create trigger in database/state
// TODO: Publish trigger.created event
throw new Error('Not implemented');
},
/**
* Route inbound message
*/
async routeInbound(msgType: string, payload: string, rail: string): Promise<string> {
const canonicalMessage = await this.normalizeMessage(msgType, payload, rail);
const triggerId = await this.createTrigger(canonicalMessage, rail);
return triggerId;
},
/**
* Route outbound message
*/
async routeOutbound(msgType: string, payload: string, rail: string, config: any): Promise<string> {
const canonicalMessage = await this.normalizeMessage(msgType, payload, rail);
// TODO: Additional validation for outbound
const triggerId = await this.createTrigger(canonicalMessage, rail);
return triggerId;
},
};

View File

@@ -0,0 +1,81 @@
/**
* Trigger state machine
* Manages trigger lifecycle: CREATED -> VALIDATED -> SUBMITTED -> PENDING -> SETTLED/REJECTED
*/
export enum TriggerState {
CREATED = 'CREATED',
VALIDATED = 'VALIDATED',
SUBMITTED_TO_RAIL = 'SUBMITTED_TO_RAIL',
PENDING = 'PENDING',
SETTLED = 'SETTLED',
REJECTED = 'REJECTED',
CANCELLED = 'CANCELLED',
RECALLED = 'RECALLED',
}
export interface Trigger {
triggerId: string;
state: TriggerState;
rail: string;
msgType: string;
instructionId: string;
// ... other fields
}
export const triggerStateMachine = {
/**
* Validate and lock trigger
*/
async validateAndLock(triggerId: string): Promise<Trigger> {
// TODO: Validate trigger, lock funds on-chain
// Transition: CREATED -> VALIDATED
throw new Error('Not implemented');
},
/**
* Mark trigger as submitted to rail
*/
async markSubmitted(triggerId: string, railTxRef: string): Promise<Trigger> {
// TODO: Update trigger with rail transaction reference
// Transition: VALIDATED -> SUBMITTED_TO_RAIL -> PENDING
throw new Error('Not implemented');
},
/**
* Confirm trigger settled
*/
async confirmSettled(triggerId: string): Promise<Trigger> {
// TODO: Finalize on-chain, release locks if needed
// Transition: PENDING -> SETTLED
throw new Error('Not implemented');
},
/**
* Confirm trigger rejected
*/
async confirmRejected(triggerId: string, reason?: string): Promise<Trigger> {
// TODO: Release locks, handle rejection
// Transition: PENDING -> REJECTED
throw new Error('Not implemented');
},
/**
* Check if state transition is valid
*/
isValidTransition(from: TriggerState, to: TriggerState): boolean {
const validTransitions: Record<TriggerState, TriggerState[]> = {
[TriggerState.CREATED]: [TriggerState.VALIDATED, TriggerState.CANCELLED],
[TriggerState.VALIDATED]: [TriggerState.SUBMITTED_TO_RAIL, TriggerState.CANCELLED],
[TriggerState.SUBMITTED_TO_RAIL]: [TriggerState.PENDING, TriggerState.REJECTED],
[TriggerState.PENDING]: [TriggerState.SETTLED, TriggerState.REJECTED, TriggerState.RECALLED],
[TriggerState.SETTLED]: [],
[TriggerState.REJECTED]: [],
[TriggerState.CANCELLED]: [],
[TriggerState.RECALLED]: [],
};
return validTransitions[from]?.includes(to) ?? false;
},
};