Skip to main content

Self-funding compliance agents

DPO2U includes a reference implementation of a self-funding compliance agent on the Midnight preview network. It is an existing system with its own wallet, its own DUST balance, an on-chain registry, and a verifiable ledger of what it has sealed and booked.

This page describes the architecture, the contracts, the cycle, and how anyone can verify the on-chain state independently. It is a description of the system as built; it does not make claims about uptime or current operational status.

Network

All on-chain components described here target the Midnight preview network. They are not deployed to a production network.

The cycle​

  1. Client pays. A client pays the agent in NIGHT for a compliance attestation. The reference repository includes a client-side script that performs this transfer from a separate wallet to the agent's address.
  2. Enqueue. The work item is appended to a queue file. Items arrive from the evaluation bridge, from the GitHub webhook, or from the internal POST /enqueue route (see below).
  3. Evaluate. The verdict is meant to come from a real DPO2U evaluation, not from hand-fed data (see the fallback caution below). The webhook calls the DPO2U MCP server's check_compliance tool and maps the score to a verdict (score >= 70 is PASS, 40 to 69 is REVIEW, below 40 is FAIL). Evaluations coming from the pilot-gateway are submitted through the /enqueue bridge. An evaluation-to-queue script turns a stored evaluation file into queue items.
  4. Seal. The agent submits the attestation to ComplianceRegistry, either as a score-private proof (attestCompliance) or as a generic use-case verdict keyed by evidence hash (attestUseCase).
  5. Split. For each priced attestation the agent books the fee in PaymentGateway (depositToTreasury) and records the split in FeeDistributor (distributeComplianceFee). The contract enforces a 40 / 60 ratio between the expert pool and the auditor pool.
  6. Pay its own DUST. Every transaction is paid with the agent's own DUST, which regenerates from the NIGHT it holds. Before each attestation a watchdog checks the DUST balance against a floor; if the balance is below the floor, the agent waits for regeneration instead of failing. The DUST cost of each attestation is measured and written to a ledger.
What the revenue contracts do and do not custody

PaymentGateway and FeeDistributor keep on-chain accounting counters tied to real attestations. The real NIGHT transfer from client to agent is a separate step (the client-pays script). ComplianceEscrowV2 is the contract that custodies native NIGHT.

Reference deployment record​

The reference deployment's revenue file (agent-revenue.json) holds 24 paid-cycle records on preview. Each record contains the evidence key, the fee, the transaction identifiers of the treasury booking and of the split, and the measured DUST cost.

Agent identity and ledger​

ElementWhere it lives
Agent identity and roleAgentRegistry (DID to status and role)
Agent wallet referenceAgentWalletFactory (DID to wallet address)
What the agent sealedComplianceRegistry (public verdicts and hashes)
What it earned and how it was splitPaymentGateway and FeeDistributor counters
What each attestation cost in DUSTlocal break-even ledger written by the agent

The agent runs as a warm process: it syncs its wallet once, keeps it hot, and drains the queue on an interval. A one-shot mode (--once) is also available.

Contract catalog​

The reference system has 14 Compact contracts. All of them keep personal data off-chain: they store hashes, identifiers, verdicts, and counters.

ContractWhat it does
AgentRegistryRegisters an agent DID with a role, tracks active or deactivated status, and counts agents.
AgentWalletFactoryMaps an agent DID to its wallet address and counts registered wallets.
ComplianceRegistryStores attestations: a score-private proof (score >= threshold, score never written) and generic use-case verdicts (PASS, FAIL, REVIEW) keyed by evidence hash, with anti-replay contexts. Also meters sponsored attestations.
ComplianceEscrowConditional payment state machine (create, attest-and-release, refund) gated on a score-private proof. Amounts are bookkeeping only.
ComplianceEscrowV2Same escrow logic with real custody of native NIGHT: it receives NIGHT from the payer and sends it to the beneficiary on a passing proof, or back to the payer on refund.
PaymentGatewayProtocol treasury and staking counters, plus non-custodial DUST-delegation records for the paymaster.
FeeDistributorSplits compliance fees between an expert pool and an auditor pool at 40 / 60, and keeps LP revenue-share accounting for the paymaster.
SolvencyRegistryProof-of-Reserve seal: proves reserves >= liabilities without disclosing either amount; writes only the verdict, a report reference, a period, and an anti-replay context.
TrustStackRegistryAnchors the hash of the audited compliance stack so a consumer can check it uses the same audited base.
LegalSourceManifestAnchors a citation to the hash of its canonical statute source, so a predicate can be traced back to the law it cites.
ConsentRegistryLGPD and GDPR consent records per hashed subject: grant, revoke, and update purposes (bitmask) with a policy version.
DataAuditLogProcessing-event trail in the spirit of LGPD Art. 37, with event types for collection, access, transfer, deletion, and breach, keyed by hashed controller.
DataSubjectRightsTracks data-subject right requests (LGPD Art. 18) and their status against the Art. 19 response deadline.
LgpdKitRegistryRegisters the hashes of a generated DPIA and privacy policy together with a 0 to 100 score and the auditor DID. Unlike ComplianceRegistry, the score here is stored on the ledger.

See the Smart contracts overview for the public/private boundary these contracts follow.

Continuous Compliance webhook​

The webhook turns a repository event into an on-chain attestation. It is a small, dependency-free HTTP service in the reference repository.

Flow: a push or pull request reaches POST /webhook/github; the service computes the evidence from the commit, asks the MCP server for an evaluation, enqueues the result for the agent, and sets a pull-request status to pending. When the agent seals the item, the status flips to success with a link to the verification page.

RoutePurpose
POST /webhook/githubReceives GitHub events. The HMAC signature (x-hub-signature-256) is verified when a webhook secret is configured.
POST /enqueueInternal bridge that enqueues a use-case seal without a GitHub payload (used by the pilot-gateway Midnight driver). Accepts verdict (PASS, FAIL, REVIEW or 0, 1, 2), evidence_hash, and optional use_case_id, metadata_hash, org, jurisdiction, commit, score, engine. Requires a bearer token when one is configured.
GET /verify/<use_case_id>/<evidence_hash>Human-readable page showing the on-chain attestation (verdict, transaction, block).
GET /api/attestation/<use_case_id>/<evidence_hash>JSON view of the same attestation, joined with the deployment provenance.
GET /agent/statusDUST health and agent address, used by a "fuel the agent" widget.
GET / and GET /healthLiveness response with the current queue length.

The queue has a back-pressure cap (configurable) so that an open endpoint cannot drain the agent's DUST.

Fallback behavior

If the MCP evaluation is unreachable or no API key is configured, the webhook falls back to a default PASS verdict so the pipeline does not break, and tags the engine as default. Treat attestations whose engine is default as unevaluated.

Proof-of-Reserve​

SolvencyRegistry is the Midnight analog of a Proof-of-Reserve seal. The entity proves in zero knowledge that its reserves cover its liabilities. Both amounts are private inputs and are never written; an insolvent entity cannot produce a valid proof, so no transaction exists to submit. What the ledger holds is the verdict (1 means solvent), the entity identifier, the off-chain reserve-report commitment, the reporting period, and a context that can be sealed only once.

There is intentionally no circuit that returns reserves or liabilities.

Paymaster and DUST relay​

DUST is non-transferable by protocol design, so it cannot be sold. The paymaster design sells sponsored capacity instead:

  1. Delegate. A NIGHT holder redirects the DUST their NIGHT generates to the controller's dust address, keeping custody of the NIGHT. The delegation is revocable. PaymentGateway.registerDustDelegation records the delegated capacity.
  2. Sponsor. The controller pays the DUST fee for a customer's attestation from the pooled capacity. ComplianceRegistry.recordSponsoredAttestation meters the usage per sponsor.
  3. Revenue. The customer pays the controller, and FeeDistributor.recordLpRevenue accrues each delegating holder's share. The design document frames this as a service revenue-share, not an investment return.

The dust-relay module in the reference repository is the reusable wallet-layer core for these legs.

How to verify​

Every verify-* script is read-only. It queries the public preview indexer, decodes the contract state with the contract's own ledger definition, and needs no wallet and no sync. Run them from the reference repository with npx tsx scripts/<name>.ts.

ScriptWhat it checks
verify-previewThat each deployed contract address has on-chain state on the public indexer.
verify-sealA single attestation: reads the use-case verdict for an evidence hash from ComplianceRegistry.
verify-revenueThe revenue ledger: treasury counter, expert and auditor pools, and total distributed.
verify-escrowAn escrow's status (0 pending, 1 released, 2 refunded).
verify-solvencyThe SolvencyRegistry entry for an entity: verdict, report reference, period.
verify-trustThe TrustStackRegistry and LegalSourceManifest anchors.
verify-paymasterDelegation records, sponsored-usage metering, and LP revenue-share ledgers.

Because the scripts read the public indexer rather than the agent's own files, they check the chain, not the agent's account of itself.

What's next​