- 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
146 lines
5.4 KiB
Markdown
146 lines
5.4 KiB
Markdown
# ISO-20022 Message Type to Trigger Type Mapping
|
|
|
|
## Overview
|
|
|
|
This document maps ISO-20022 message types to trigger types and orchestrator actions in the ChainID 138 eMoney Token Factory payment rails system.
|
|
|
|
## Message Family Overview
|
|
|
|
| Family | Purpose | Key Messages |
|
|
|--------|---------|--------------|
|
|
| **pacs** | Payment clearing and settlement | pacs.008, pacs.009, pacs.002, pacs.004 |
|
|
| **pain** | Payment initiation | pain.001 |
|
|
| **camt** | Cash management and reporting | camt.052, camt.053, camt.054, camt.056, camt.029 |
|
|
|
|
## Message Type to Trigger Mapping
|
|
|
|
### Outbound Initiation Messages
|
|
|
|
| ISO-20022 Message | Description | Trigger Type | Direction | Orchestrator Action |
|
|
|-------------------|-------------|--------------|-----------|---------------------|
|
|
| `pain.001` | Customer Credit Transfer Initiation | OUTBOUND | Chain → Rail | `validateAndLock()` → `markSubmitted()` |
|
|
| `pacs.008` | FIToFICustomerCreditTransfer | OUTBOUND | Chain → Rail | `validateAndLock()` → `markSubmitted()` |
|
|
| `pacs.009` | FinancialInstitutionCreditTransfer | OUTBOUND | Chain → Rail | `validateAndLock()` → `markSubmitted()` |
|
|
|
|
### Inbound Notification Messages
|
|
|
|
| ISO-20022 Message | Description | Trigger Type | Direction | Orchestrator Action |
|
|
|-------------------|-------------|--------------|-----------|---------------------|
|
|
| `camt.054` | BankToCustomerDebitCreditNotification | INBOUND | Rail → Chain | `confirmSettled()` (mint tokens) |
|
|
| `pacs.002` | Payment Status Report | INBOUND | Rail → Chain | `confirmSettled()` or `confirmRejected()` |
|
|
| `camt.052` | BankToCustomerAccountReport | INBOUND | Rail → Chain | Status update (informational) |
|
|
| `camt.053` | BankToCustomerStatement | INBOUND | Rail → Chain | Status update (informational) |
|
|
|
|
### Return/Reversal Messages
|
|
|
|
| ISO-20022 Message | Description | Trigger Type | Direction | Orchestrator Action |
|
|
|-------------------|-------------|--------------|-----------|---------------------|
|
|
| `pacs.004` | Payment Return | RETURN | Rail → Chain | `confirmRejected()` (release escrow) |
|
|
| `camt.056` | FIToFIPaymentCancellationRequest | CANCELLATION | Rail → Chain | `confirmCancelled()` (release escrow) |
|
|
| `camt.029` | ResolutionOfInvestigation | RESOLUTION | Rail → Chain | Status update or `confirmRejected()` |
|
|
|
|
## Trigger State Transitions
|
|
|
|
### Outbound Flow
|
|
|
|
```
|
|
CREATED → VALIDATED → SUBMITTED_TO_RAIL → PENDING → SETTLED
|
|
↓
|
|
REJECTED
|
|
↓
|
|
CANCELLED
|
|
↓
|
|
RECALLED
|
|
```
|
|
|
|
### Inbound Flow
|
|
|
|
```
|
|
CREATED → VALIDATED → SUBMITTED_TO_RAIL → PENDING → SETTLED
|
|
↓
|
|
REJECTED
|
|
```
|
|
|
|
## Message Type Constants
|
|
|
|
### Library: ISO20022Types
|
|
|
|
```solidity
|
|
bytes32 public constant PAIN_001 = keccak256("pain.001");
|
|
bytes32 public constant PACS_002 = keccak256("pacs.002");
|
|
bytes32 public constant PACS_004 = keccak256("pacs.004");
|
|
bytes32 public constant PACS_008 = keccak256("pacs.008");
|
|
bytes32 public constant PACS_009 = keccak256("pacs.009");
|
|
bytes32 public constant CAMT_052 = keccak256("camt.052");
|
|
bytes32 public constant CAMT_053 = keccak256("camt.053");
|
|
bytes32 public constant CAMT_054 = keccak256("camt.054");
|
|
bytes32 public constant CAMT_056 = keccak256("camt.056");
|
|
bytes32 public constant CAMT_029 = keccak256("camt.029");
|
|
```
|
|
|
|
## Rail-Specific Message Usage
|
|
|
|
### Fedwire
|
|
|
|
- **Outbound**: `pacs.008` (primary), `pain.001` (alternative)
|
|
- **Inbound**: `camt.054`, `pacs.002`
|
|
- **Returns**: `pacs.004`
|
|
|
|
### SWIFT
|
|
|
|
- **Outbound**: `pacs.008`, `pacs.009`
|
|
- **Inbound**: `camt.054`, `pacs.002`
|
|
- **Returns**: `pacs.004`
|
|
- **Cancellations**: `camt.056`
|
|
|
|
### SEPA
|
|
|
|
- **Outbound**: `pain.001` (SCT/SCT Inst)
|
|
- **Inbound**: `camt.054`
|
|
- **Returns**: `pacs.004`
|
|
|
|
### RTGS (Generic)
|
|
|
|
- **Outbound**: `pacs.008` (most common), jurisdiction-specific variants
|
|
- **Inbound**: `camt.054`, `pacs.002`
|
|
- **Returns**: `pacs.004`
|
|
|
|
## Message Payload Structure
|
|
|
|
### CanonicalMessage (On-Chain)
|
|
|
|
```solidity
|
|
struct CanonicalMessage {
|
|
bytes32 msgType; // ISO-20022 message type hash
|
|
bytes32 instructionId; // Unique instruction reference
|
|
bytes32 endToEndId; // End-to-end reference (optional)
|
|
bytes32 accountRefId; // Hashed account reference
|
|
bytes32 counterpartyRefId; // Hashed counterparty reference
|
|
address token; // eMoney token address
|
|
uint256 amount; // Transfer amount
|
|
bytes32 currencyCode; // Currency code hash
|
|
bytes32 payloadHash; // Hash of full ISO-20022 XML payload
|
|
}
|
|
```
|
|
|
|
## Idempotency
|
|
|
|
All messages are idempotent by `instructionId`. Duplicate submissions with the same `instructionId` are rejected by `RailTriggerRegistry`.
|
|
|
|
## Status Codes
|
|
|
|
### pacs.002 Status Values
|
|
|
|
- `ACSC` - AcceptedSettlementCompleted → `confirmSettled()`
|
|
- `RJCT` - Rejected → `confirmRejected()`
|
|
- `PNDG` - Pending → No action (wait for final status)
|
|
- `CANC` - Cancelled → `confirmCancelled()`
|
|
|
|
## Implementation Notes
|
|
|
|
1. **Full Payload Storage**: Full ISO-20022 XML payloads stored off-chain; only `payloadHash` on-chain
|
|
2. **Message Validation**: Adapters validate ISO-20022 schema before submission
|
|
3. **Error Handling**: Invalid messages trigger `confirmRejected()` with appropriate reason codes
|
|
4. **Reconciliation**: Use `instructionId` and `endToEndId` for end-to-end reconciliation
|
|
|