The ComplianceRegistry stores compliance attestations on-chain. The SettlementCoordinator checks this registry as a gate before allowing transitions past the compliance phase.
How it works
- Off-chain compliance oracle screens parties via LSEG World-Check (entity) and CipherOwl (wallet)
- Oracle submits attestation on-chain:
attest(settlementId, partyHash, status, refHash)
- When the engine proposes a transition past compliance, the SettlementCoordinator calls
areAllPartiesCleared(settlementId)
- If all parties have passing attestations, the transition is allowed
Functions
attest()
Submit a compliance attestation for a party in a settlement.
function attest(
bytes32 settlementId,
bytes32 partyHash,
ComplianceStatus status,
bytes32 referenceHash
) external
| Parameter | Description |
|---|
settlementId | UUID converted to bytes32 |
partyHash | keccak256(abi.encode(participantId_bytes32, walletAddress)) |
status | Pass (1), Flagged (2), or Fail (3) |
referenceHash | Keccak256 of the compliance provider’s reference ID |
No personal data is stored on-chain. The partyHash is a one-way hash that cannot be reversed to identify the party. The referenceHash is a hash of the provider’s reference ID, not the ID itself.
isCleared()
Check if a specific party has a passing attestation.
function isCleared(
bytes32 settlementId,
bytes32 partyHash
) external view returns (bool)
areAllPartiesCleared()
Check if all registered parties for a settlement have passing attestations. This is the function the SettlementCoordinator calls as a gate check.
function areAllPartiesCleared(
bytes32 settlementId
) external view returns (bool)
Party hash computation
Party hashes are computed as keccak256(abi.encode(participantId_bytes32, walletAddress)):
| Check type | participantId | walletAddress |
|---|
| Entity screening | Participant UUID as bytes32 | Zero address (0x0000...0000) |
| Wallet screening | Participant UUID as bytes32 | Actual wallet address |
This allows separate attestations for entity-level and wallet-level screening while maintaining a consistent hashing scheme.
Status mapping
| API Status | Contract Enum | uint8 Value |
|---|
| PASS | ComplianceStatus.Pass | 1 |
| FLAGGED | ComplianceStatus.Flagged | 2 |
| FAIL | ComplianceStatus.Fail | 3 |
Only Pass (1) counts as cleared for the gate check. Flagged and Fail both prevent the transition.
Open attestation interface
KeyStone operates the default compliance oracle, but the attestation interface is open:
- Platform-operated oracles: Platforms can run their own compliance screening and submit attestations directly
- Multi-attester: Templates can require attestations from multiple providers for higher assurance
- Verifiable: All attestations are permanent on-chain records - a false attestation is provable liability
This design separates the screening (off-chain, provider-specific) from the enforcement (on-chain, standardized gate check).
What KeyStone stores
KeyStone never stores raw KYC/AML data. The compliance flow stores:
| Layer | What is stored |
|---|
| Off-chain (KeyStone DB) | Compliance status (pass/fail/flagged) + reference ID pointing to provider’s record |
| On-chain (ComplianceRegistry) | Hashed party identifier + status enum + hashed reference ID |
The compliance provider (LSEG, CipherOwl) remains the source of truth for the actual screening data. KeyStone only records the outcome.