Skip to main content

libid_contracts/bindings/
identity.rs

1//! Bindings for the identity-names stack (`solidity/contracts/identity/`):
2//! `IdentityNames`, the per-platform verifiers, and the Google JWKS trust
3//! list.
4
5/// Bindings for `identity/IdentityNames.sol`.
6///
7/// `Rules` mirrors `HandleNormalizer.Rules` — the normalization rules the
8/// contract stores per platform. Platform ids are `keccak256` of the
9/// platform's domain string.
10#[allow(clippy::too_many_arguments, unused_attributes)]
11mod names_inner {
12    use alloy::sol;
13
14    sol! {
15        #[sol(rpc)]
16        interface IdentityNames {
17            #[derive(Debug, serde::Serialize, serde::Deserialize)]
18            struct Rules {
19                uint16 maxLength;
20                bool stripLeadingAt;
21                bool isEmail;
22                bool allowUnderscore;
23                bool allowHyphen;
24            }
25
26            function initialize(address owner_) external;
27
28            /// The keyspace half: what a handle on this platform means. It
29            /// does not vary by proof version — two versions normalizing
30            /// differently would put one handle on two nodes.
31            function setPlatform(bytes32 platformId, Rules calldata rules) external;
32
33            /// One proof format for one platform. The first version installed
34            /// becomes the platform's default; later ones do not move it, so a
35            /// format can be deployed and exercised before anybody is sent to
36            /// it.
37            function setVerifier(
38                bytes32 platformId,
39                uint32 version,
40                address verifier,
41                uint64 maxFutureObservation
42            ) external;
43            function setLatestVersion(bytes32 platformId, uint32 version) external;
44            function retireVerifier(bytes32 platformId, uint32 version) external;
45
46            function verifierOf(bytes32 platformId, uint32 version) external view returns (address);
47            function latestVersionOf(bytes32 platformId) external view returns (uint32);
48            function INITIAL_VERSION() external view returns (uint32);
49
50            function bind(bytes32 platformId, bytes calldata proof, bool publishName) external;
51            function bindAtVersion(
52                bytes32 platformId,
53                uint32 version,
54                bytes calldata proof,
55                bool publishName
56            ) external;
57            function unpublish(bytes32 platformId) external;
58            function resolveId(bytes32 platformId, string calldata userId) external view returns (address);
59            function resolveHandle(bytes32 platformId, string calldata handle) external view returns (address);
60            function resolvePair(bytes32 platformId, string calldata handle, string calldata userId) external view returns (address);
61            function reverseOf(address wallet, bytes32 platformId) external view returns (string memory);
62            function primaryOf(address wallet, bytes32 platformId) external view returns (string memory);
63
64            /// Carries the proof version that established the binding, which
65            /// is how an operator learns whether a format is still in use
66            /// before retiring it.
67            event IdentityBound(
68                address indexed owner,
69                bytes32 indexed idNode,
70                bytes32 indexed handleNode,
71                bytes32 platformId,
72                string userId,
73                string handle,
74                uint64 observedAt,
75                bool published,
76                uint32 version
77            );
78            event HandleRetired(bytes32 indexed platformId, bytes32 indexed handleNode, address indexed owner);
79            event PlatformConfigured(bytes32 indexed platformId);
80            event VerifierConfigured(
81                bytes32 indexed platformId,
82                uint32 indexed version,
83                address verifier,
84                uint64 maxFutureObservation
85            );
86            event VerifierRetired(bytes32 indexed platformId, uint32 indexed version);
87            event LatestVersionChanged(bytes32 indexed platformId, uint32 indexed version);
88            event NameUnpublished(address indexed owner, bytes32 indexed platformId);
89        }
90    }
91}
92
93pub use names_inner::IdentityNames;
94
95/// The claim every identity verifier returns
96/// (`identity/IIdentityVerifier.sol`).
97#[allow(clippy::too_many_arguments, unused_attributes)]
98mod verifier_iface_inner {
99    use alloy::sol;
100
101    sol! {
102        #[sol(rpc)]
103        interface IIdentityVerifier {
104            #[derive(Debug, serde::Serialize, serde::Deserialize)]
105            struct IdentityClaim {
106                string userId;
107                string handle;
108                address target;
109                uint64 observedAt;
110            }
111
112            function verify(bytes calldata proof) external view returns (IdentityClaim memory claim);
113            function platformName() external view returns (string memory);
114        }
115    }
116}
117
118pub use verifier_iface_inner::IIdentityVerifier;
119
120/// Bindings for `identity/XIdentityVerifier.sol`.
121#[allow(clippy::too_many_arguments, unused_attributes)]
122mod x_verifier_inner {
123    use alloy::sol;
124
125    sol! {
126        #[sol(rpc)]
127        interface XIdentityVerifier {
128            #[derive(Debug, serde::Serialize, serde::Deserialize)]
129            struct MeAttestation {
130                bytes32 bearerHash;
131                uint32 bearerRangeStart;
132                uint32 bearerRangeEnd;
133                bytes sentRevealed;
134                uint32 sentPrefixEnd;
135                uint32 sentSuffixEnd;
136                bytes recvRevealed;
137                string handle;
138                string userId;
139                address sessionAddr;
140                uint64 timestamp;
141                bytes notarySignature;
142            }
143
144            #[derive(Debug, serde::Serialize, serde::Deserialize)]
145            struct XProof {
146                bytes proof;
147                bytes32[] publicInputs;
148                MeAttestation meAttest;
149            }
150
151            #[derive(Debug, serde::Serialize, serde::Deserialize)]
152            struct ResponseShape {
153                string platformName;
154                string endpoint;
155                string handlePrefix;
156                string idPrefix;
157                string idSuffix;
158            }
159
160            function initialize(
161                address owner_,
162                address notaryContract_,
163                address honkVerifier_,
164                ResponseShape calldata shape_
165            ) external;
166            function setHonkVerifier(address honkVerifier_) external;
167            function setResponseShape(ResponseShape calldata shape_) external;
168
169            function notaryContract() external view returns (address);
170            function notary() external view returns (address);
171            function platformName() external view returns (string memory);
172            function endpoint() external view returns (string memory);
173            function handlePrefix() external view returns (string memory);
174            function idPrefix() external view returns (string memory);
175            function idSuffix() external view returns (string memory);
176        }
177    }
178}
179
180pub use x_verifier_inner::XIdentityVerifier;
181
182/// Bindings for `identity/GitHubIdentityVerifier.sol`.
183#[allow(clippy::too_many_arguments, unused_attributes)]
184mod github_verifier_inner {
185    use alloy::sol;
186
187    sol! {
188        #[sol(rpc)]
189        interface GitHubIdentityVerifier {
190            #[derive(Debug, serde::Serialize, serde::Deserialize)]
191            struct FullTlsProof {
192                bytes notarySignature;
193                bytes backendSignature;
194                address userAddress;
195                address walletAddress;
196                bytes32 domainHash;
197                bytes32 clientRandom;
198                bytes32 serverRandom;
199                bytes serverEphemeralKey;
200                bytes32 transcriptRoot;
201                uint256 timestamp;
202                bytes32[] domainPath;
203                bytes32[] usernamePath;
204                bytes32[] endpointPath;
205                bytes32[] idPath;
206            }
207
208            /// The proof plus the strings it is checked against. A verifier
209            /// takes one `bytes` argument, so they travel together.
210            #[derive(Debug, serde::Serialize, serde::Deserialize)]
211            struct GitHubProof {
212                FullTlsProof tls;
213                string domain;
214                string handle;
215                string userId;
216                string endpoint;
217            }
218
219            #[derive(Debug, serde::Serialize, serde::Deserialize)]
220            struct ResponseShape {
221                string endpoint;
222                string handlePrefix;
223                string idPrefix;
224                string idSuffix;
225            }
226
227            function initialize(
228                address owner_,
229                address notaryContract_,
230                address backend_,
231                ResponseShape calldata shape_
232            ) external;
233            function setBackend(address backend_) external;
234            function setResponseShape(ResponseShape calldata shape_) external;
235
236            function notaryContract() external view returns (address);
237            function notary() external view returns (address);
238            function backend() external view returns (address);
239            function platformName() external view returns (string memory);
240        }
241    }
242}
243
244pub use github_verifier_inner::GitHubIdentityVerifier;
245
246/// Bindings for `identity/GoogleIdentityVerifier.sol`.
247#[allow(clippy::too_many_arguments, unused_attributes)]
248mod google_verifier_inner {
249    use alloy::sol;
250
251    sol! {
252        #[sol(rpc)]
253        interface GoogleIdentityVerifier {
254            /// One proof over a Google-signed id_token. Identity binds on
255            /// `sub` (the immutable Google account id).
256            #[derive(Debug, serde::Serialize, serde::Deserialize)]
257            struct UserProof {
258                bytes honkProof;
259                bytes32[] publicInputs;
260                string email;
261                address sessionKey;
262                string sub;
263            }
264
265            function initialize(address owner_, address honkVerifier_, address jwksRoots_) external;
266            function setTrust(address honkVerifier_, address jwksRoots_) external;
267
268            function honkVerifier() external view returns (address);
269            function jwksRoots() external view returns (address);
270            function platformName() external view returns (string memory);
271        }
272    }
273}
274
275pub use google_verifier_inner::GoogleIdentityVerifier;
276
277/// Bindings for `identity/IdentityJwksRoots.sol` — the naming system's own
278/// Google JWKS trust list. Starts EMPTY: Google names bind only once a
279/// notarized reading of Google's JWKS has landed here.
280#[allow(clippy::too_many_arguments, unused_attributes)]
281mod jwks_roots_inner {
282    use alloy::sol;
283
284    sol! {
285        #[sol(rpc)]
286        interface IdentityJwksRoots {
287            #[derive(Debug, serde::Serialize, serde::Deserialize)]
288            struct NotarizedJwksProof {
289                bytes notarySignature;
290                bytes32 domainHash;
291                bytes32 clientRandom;
292                bytes32 serverRandom;
293                bytes serverEphemeralKey;
294                bytes32 transcriptRoot;
295                uint256 timestamp;
296                bytes32[] domainPath;
297                bytes32[] endpointPath;
298            }
299
300            #[derive(Debug, serde::Serialize, serde::Deserialize)]
301            struct JwkClaim {
302                bytes jwkBytes;
303                bytes32[] jwkPath;
304                bytes kid;
305                bytes nB64url;
306            }
307
308            #[derive(Debug, serde::Serialize, serde::Deserialize)]
309            struct RootInfo {
310                bytes32 kidHash;
311                bytes32 modulusHash;
312                uint256 observedAt;
313                uint256 expiresAt;
314            }
315
316            function initialize(address owner_, address notaryContract_) external;
317            function untrustModulus(bytes32 modulusHash) external;
318            function rotate(NotarizedJwksProof calldata proof, JwkClaim[] calldata claims) external;
319            function prune() external;
320            function trustedHashExpiresAt(bytes32 modulusHash) external view returns (uint256);
321            function notaryContract() external view returns (address);
322            function notary() external view returns (address);
323            function currentRoots() external view returns (RootInfo[] memory);
324            function freshestObservedAt() external view returns (uint256);
325            function needsRotation() external view returns (bool);
326
327            event ModulusRotated(bytes32 indexed kidHash, string kid, bytes32 modulusHash, uint256 expiresAt);
328            event ModulusUntrusted(bytes32 indexed modulusHash);
329            event RootApplied(bytes32 indexed kidHash, bytes32 indexed modulusHash, uint256 observedAt, uint256 expiresAt);
330            event RootPruned(bytes32 indexed kidHash, bytes32 modulusHash);
331        }
332    }
333}
334
335pub use jwks_roots_inner::IdentityJwksRoots;