libid_contracts/bindings/ceremony.rs
1//! Bindings for the ceremony verification path (`solidity/contracts/ceremony/`):
2//! the Notary Service every notarized session is authenticated through, the
3//! Proof Verifier that routes a claim to the Platform Verifier registered for
4//! its version, and the Google JWT root list the `google/v1` verifier reads.
5
6/// Bindings for `ceremony/NotaryService.sol` (which implements
7/// `INotaryService`).
8///
9/// Authenticates one attestation and charges one fee for it. The digest is
10/// derived from the attested bytes on chain, never taken from the caller
11/// (REQ-COMMON-33), which is why `verify` is not on this interface: a
12/// consumer contract calls it with the fee attached, and the decoded record
13/// comes back to that contract, not to an off-chain reader. What an operator
14/// does from here is hold the trusted key set, set the fee and withdraw what
15/// accrued.
16#[allow(clippy::too_many_arguments, unused_attributes)]
17mod notary_service_inner {
18 use alloy::sol;
19
20 sol! {
21 #[sol(rpc)]
22 interface NotaryService {
23 /// `notary_` is the first trusted key; `fee_` may be zero (a
24 /// deployment may meter at no charge, and the exact-value rule
25 /// still applies).
26 function initialize(address owner_, address notary_, uint256 fee_) external;
27 /// What one verification costs, in the chain's native asset.
28 /// Readable before a submission is built, so it can be bounded.
29 function fee() external view returns (uint256);
30 function setFee(uint256 fee_) external;
31 /// Add or remove a trusted notary key. Several are held at once so
32 /// a rotation can overlap: add the incoming key, remove the
33 /// outgoing one once nothing can still present under it.
34 function setNotary(address key, bool trusted_) external;
35 function isTrustedNotary(address key) external view returns (bool);
36 /// Fees accrue here rather than being forwarded per verification.
37 function withdraw(address to, uint256 amount) external;
38
39 function owner() external view returns (address);
40 function pendingOwner() external view returns (address);
41 function transferOwnership(address newOwner) external;
42 function acceptOwnership() external;
43
44 event FeeChanged(uint256 previousFee, uint256 newFee);
45 event NotaryTrustChanged(address indexed key, bool trusted);
46 event FeesWithdrawn(address indexed to, uint256 amount);
47 }
48 }
49}
50
51pub use notary_service_inner::NotaryService;
52
53/// Bindings for `ceremony/CeremonyProofVerifier.sol` (which implements
54/// `IProofVerifier`).
55///
56/// The Supported Version Set: which Platform Verifier answers for a
57/// `(platformId, verifierVersion)` pair. Governance registers one with
58/// `setVerifier`; `IdentityNames.claim` dispatches through `verify`, which is
59/// not on this interface for the same reason `NotaryService.verify` is not —
60/// it is called by the consumer contract with the fee attached.
61#[allow(clippy::too_many_arguments, unused_attributes)]
62mod proof_verifier_inner {
63 use alloy::sol;
64
65 sol! {
66 #[sol(rpc)]
67 interface CeremonyProofVerifier {
68 function initialize(address owner_) external;
69 /// Register (or, with the zero address, remove) the Platform
70 /// Verifier for a pair. The verifier must serve `platformId`.
71 function setVerifier(bytes32 platformId, uint16 verifierVersion, address verifier) external;
72 /// The Platform Verifier registered for a pair, or zero.
73 function verifierOf(bytes32 platformId, uint16 verifierVersion) external view returns (address);
74 /// What one claim under this pair costs: the registered
75 /// verifier's quote, forwarded whole.
76 function quote(bytes32 platformId, uint16 verifierVersion) external view returns (uint256);
77 /// Whether any version is registered for the platform at all.
78 function verifiesPlatform(bytes32 platformId) external view returns (bool);
79 /// This chain's identifier, as the digest construction takes it.
80 function chainId() external view returns (bytes32);
81
82 function owner() external view returns (address);
83 function pendingOwner() external view returns (address);
84 function transferOwnership(address newOwner) external;
85 function acceptOwnership() external;
86
87 event VerifierConfigured(bytes32 indexed platformId, uint16 indexed verifierVersion, address verifier);
88 }
89 }
90}
91
92pub use proof_verifier_inner::CeremonyProofVerifier;
93
94/// Bindings for `ceremony/GoogleJwtRoots.sol` — the signing keys the
95/// `google/v1` Platform Verifier trusts, and until when. Starts EMPTY:
96/// Google names bind only once a notarized reading of Google's JWKS has
97/// landed here.
98///
99/// The list is two generations of Google's key set and nothing else:
100/// `current` is the latest reading applied, `previous` the reading before
101/// it, kept for the tokens still in flight under a key Google has since
102/// dropped. A newer reading of the same set restarts `current`'s clock
103/// (`ReadingRefreshed`); a newer reading of a different set shifts `current`
104/// into `previous` and drops what `previous` held (`KeysRotated`). A
105/// generation is trusted until `READING_LIFETIME` after its reading's own
106/// `createdAt`, so there is nothing to prune or untrust by hand.
107///
108/// A rotation is an ordinary notarized session: the keeper reveals the whole
109/// `GET /oauth2/v3/certs` exchange, `rotate` hands the attested bytes and the
110/// notary's proof to the Notary Service with the Notary Fee attached (read
111/// it with `quoteRotation`, which is the service's `fee()`), and the contract
112/// reads the JWKS out of the transcript it vouched for.
113#[allow(clippy::too_many_arguments, unused_attributes)]
114mod google_jwt_roots_inner {
115 use alloy::sol;
116
117 sol! {
118 #[sol(rpc)]
119 interface GoogleJwtRoots {
120 /// One reading of Google's key set: the notary's clock, and the
121 /// limb hash of every modulus it listed, in Google's order.
122 #[derive(Debug, serde::Serialize, serde::Deserialize)]
123 struct Generation {
124 uint64 observedAt;
125 bytes32[] moduli;
126 }
127
128 function initialize(address owner_, address notary_) external;
129 /// The Notary Service a rotation is verified through.
130 function notaryService() external view returns (address);
131 function setNotaryService(address notary_) external;
132 /// What one rotation costs beyond gas: the Notary Fee, forwarded
133 /// whole. `rotate` must be sent with exactly this value.
134 function quoteRotation() external view returns (uint256);
135 /// Permissionless. `attestedData` is the ceremony-common section
136 /// 9.1 record of the JWKS session, `proof` the notary's
137 /// authentication of it (a 65-byte EIP-191 signature today). A
138 /// reading dated no later than the current generation is refused
139 /// with `NotNewer(createdAt, observedAt)`, and the revert hands
140 /// the fee back.
141 function rotate(bytes calldata attestedData, bytes calldata proof) external payable;
142
143 /// What `GooglePlatformVerifier` reads: modulus hash -> when it
144 /// stops being trusted, zero when neither generation lists it.
145 function trustedHashExpiresAt(bytes32 modulusHash) external view returns (uint256);
146 /// Both generations, as stored.
147 function currentKeys() external view returns (Generation memory current, Generation memory previous);
148 /// The current generation's `observedAt`: the notary's clock on
149 /// the reading in force.
150 function freshestObservedAt() external view returns (uint256);
151 /// True until the current generation is guaranteed trusted
152 /// `RENEWAL_MARGIN` from now; true on an empty list.
153 function needsRotation() external view returns (bool);
154 function READING_LIFETIME() external view returns (uint256);
155 function RENEWAL_MARGIN() external view returns (uint256);
156 function MAX_KEYS() external view returns (uint256);
157
158 function owner() external view returns (address);
159 function pendingOwner() external view returns (address);
160 function transferOwnership(address newOwner) external;
161 function acceptOwnership() external;
162
163 event NotaryServiceChanged(address notary);
164 /// A different set landed: `kids` and `moduli` in the order
165 /// Google listed them, `observedAt` the notary's clock.
166 event KeysRotated(uint64 observedAt, string[] kids, bytes32[] moduli);
167 /// A newer reading of the set already current.
168 event ReadingRefreshed(uint64 observedAt);
169 }
170 }
171}
172
173pub use google_jwt_roots_inner::GoogleJwtRoots;