Skip to content

Compact Contract Surface

The Compact contract stores Midnight DID state and proves controller-authorized state transitions. The TypeScript API exposes ergonomic add/update/remove helpers, but the contract intentionally keeps the exported circuit count small.

Contract Responsibilities

The contract enforces:

  • controller authorization through wallet-local Jubjub Schnorr signatures;
  • active/deactivated state checks;
  • exact ledger identifier existence and uniqueness;
  • supported opaque JWK key/curve profiles;
  • native SchnorrJubjub point storage;
  • relation cleanup invariants where the operation requires it.

The SDK/domain/resolver layers enforce DID URL subject binding, fragment normalization, DID Core object shape, service endpoint shape, JWK canonicality, and resolved DID Document output.

Circuit Map

CircuitAPI helperLedger fieldsMutation style
rotateControllerKeyrotateControllerKeycontrollerPublicKey, updated, versionReplaces the controller Jubjub public key with a locally derived public key
setVerificationMethodaddVerificationMethod, updateVerificationMethodverificationMethodsMapMutation.Insert or MapMutation.Update
removeVerificationMethodremoveVerificationMethodverificationMethods, relation setsRemove after relation cleanup
setSchnorrJubjubVerificationMethodaddSchnorrJubjubVerificationMethod, updateSchnorrJubjubVerificationMethodschnorrJubjubVerificationMethodsMapMutation.Insert or MapMutation.Update
removeSchnorrJubjubVerificationMethodremoveSchnorrJubjubVerificationMethodschnorrJubjubVerificationMethods, relation setsRemove after relation cleanup
verifySchnorrJubjubDigestSignatureverifySchnorrJubjubDigestSignatureReads schnorrJubjubVerificationMethodsNon-mutating transaction-backed proof
setVerificationMethodRelationaddVerificationMethodRelation, removeVerificationMethodRelationauthentication, assertionMethod, keyAgreement, capabilityInvocation, capabilityDelegationSetMutation.Insert or SetMutation.Remove
setServiceaddService, updateServiceservicesMapMutation.Insert or MapMutation.Update
removeServiceremoveServiceservicesRemove by id
setAlsoKnownAsaddAlsoKnownAs, removeAlsoKnownAsalsoKnownAsSetMutation.Insert or SetMutation.Remove
deactivatedeactivateactive, deactivated, updated, versionFinal lifecycle transition

Circuit Artifact Profile

The following profile is generated from the managed DID artifacts compiled with Compact toolchain 0.30.0. The k and row values come from zkir compile -v; artifact sizes are byte sizes for files under packages/contract/src/managed/did.

Circuitkrowsprover keyverifier keybzkirzkir
rotateControllerKey111,840688,661 B1,591 B681 B10,113 B
setVerificationMethod122,1611,348,160 B1,591 B1,336 B18,133 B
removeVerificationMethod111,831688,870 B1,591 B1,056 B16,187 B
setSchnorrJubjubVerificationMethod112,030689,482 B1,591 B1,191 B16,426 B
removeSchnorrJubjubVerificationMethod111,831688,833 B1,591 B1,050 B16,142 B
verifySchnorrJubjubDigestSignature111,608687,799 B1,591 B381 B4,847 B
setVerificationMethodRelation122,4461,351,617 B1,591 B2,825 B36,577 B
setService111,991689,327 B1,591 B1,037 B14,595 B
removeService111,806688,589 B1,591 B699 B10,019 B
setAlsoKnownAs111,974689,247 B1,591 B1,086 B14,730 B
deactivate111,804688,590 B1,591 B670 B9,955 B

Why The Surface Is Small

Every exported Compact circuit produces proving/verifier artifacts and contributes to deployment footprint. A symmetric add/update/remove circuit for every API helper can exceed current standalone Midnight block limits.

The contract therefore exports compact set/toggle circuits and uses explicit mutation enums instead of ambiguous booleans. The API can still expose natural helpers such as addVerificationMethod and updateVerificationMethod; those helpers map to the same circuit with the appropriate mutation value.

Key Storage

Non-native JWK keys are stored as opaque canonical strings in verificationMethods. SchnorrJubjub keys are stored as native JubjubPoint values in schnorrJubjubVerificationMethods. Resolvers merge both maps into the final DID Document.

See Key Model for the supported key profiles and controller authorization signature model.

Ledger-Bound SchnorrJubjub Verification

verifySchnorrJubjubDigestSignature accepts a verification method id, private digest, and private signature. It reads the public key from schnorrJubjubVerificationMethods, so the proof is tied to the current DID ledger state instead of a caller-supplied public key.

Last updated:

Midnight DID reference implementation