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                address walletAddress;
194                bytes32 domainHash;
195                bytes32 clientRandom;
196                bytes32 serverRandom;
197                bytes serverEphemeralKey;
198                bytes32 transcriptRoot;
199                uint256 timestamp;
200                bytes32[] domainPath;
201                bytes32[] usernamePath;
202                bytes32[] endpointPath;
203                bytes32[] idPath;
204            }
205
206            /// The proof plus the strings it is checked against. A verifier
207            /// takes one `bytes` argument, so they travel together.
208            #[derive(Debug, serde::Serialize, serde::Deserialize)]
209            struct GitHubProof {
210                FullTlsProof tls;
211                string domain;
212                string handle;
213                string userId;
214                string endpoint;
215            }
216
217            #[derive(Debug, serde::Serialize, serde::Deserialize)]
218            struct ResponseShape {
219                string endpoint;
220                string handlePrefix;
221                string idPrefix;
222                string idSuffix;
223            }
224
225            function initialize(
226                address owner_,
227                address notaryContract_,
228                ResponseShape calldata shape_
229            ) external;
230            function setResponseShape(ResponseShape calldata shape_) external;
231
232            function notaryContract() external view returns (address);
233            function notary() external view returns (address);
234            function platformName() external view returns (string memory);
235        }
236    }
237}
238
239pub use github_verifier_inner::GitHubIdentityVerifier;
240
241/// Bindings for `identity/GoogleIdentityVerifier.sol`.
242#[allow(clippy::too_many_arguments, unused_attributes)]
243mod google_verifier_inner {
244    use alloy::sol;
245
246    sol! {
247        #[sol(rpc)]
248        interface GoogleIdentityVerifier {
249            /// One proof over a Google-signed id_token. Identity binds on
250            /// `sub` (the immutable Google account id).
251            #[derive(Debug, serde::Serialize, serde::Deserialize)]
252            struct UserProof {
253                bytes honkProof;
254                bytes32[] publicInputs;
255                string email;
256                address sessionKey;
257                string sub;
258            }
259
260            function initialize(address owner_, address honkVerifier_, address jwksRoots_) external;
261            function setTrust(address honkVerifier_, address jwksRoots_) external;
262
263            function honkVerifier() external view returns (address);
264            function jwksRoots() external view returns (address);
265            function platformName() external view returns (string memory);
266        }
267    }
268}
269
270pub use google_verifier_inner::GoogleIdentityVerifier;
271
272/// Bindings for `identity/IdentityJwksRoots.sol` — the naming system's own
273/// Google JWKS trust list. Starts EMPTY: Google names bind only once a
274/// notarized reading of Google's JWKS has landed here.
275#[allow(clippy::too_many_arguments, unused_attributes)]
276mod jwks_roots_inner {
277    use alloy::sol;
278
279    sol! {
280        #[sol(rpc)]
281        interface IdentityJwksRoots {
282            #[derive(Debug, serde::Serialize, serde::Deserialize)]
283            struct NotarizedJwksProof {
284                bytes notarySignature;
285                bytes32 domainHash;
286                bytes32 clientRandom;
287                bytes32 serverRandom;
288                bytes serverEphemeralKey;
289                bytes32 transcriptRoot;
290                uint256 timestamp;
291                bytes32[] domainPath;
292                bytes32[] endpointPath;
293            }
294
295            #[derive(Debug, serde::Serialize, serde::Deserialize)]
296            struct JwkClaim {
297                bytes jwkBytes;
298                bytes32[] jwkPath;
299                bytes kid;
300                bytes nB64url;
301            }
302
303            #[derive(Debug, serde::Serialize, serde::Deserialize)]
304            struct RootInfo {
305                bytes32 kidHash;
306                bytes32 modulusHash;
307                uint256 observedAt;
308                uint256 expiresAt;
309            }
310
311            function initialize(address owner_, address notaryContract_) external;
312            function untrustModulus(bytes32 modulusHash) external;
313            function rotate(NotarizedJwksProof calldata proof, JwkClaim[] calldata claims) external;
314            function prune() external;
315            function trustedHashExpiresAt(bytes32 modulusHash) external view returns (uint256);
316            function notaryContract() external view returns (address);
317            function notary() external view returns (address);
318            function currentRoots() external view returns (RootInfo[] memory);
319            function freshestObservedAt() external view returns (uint256);
320            function needsRotation() external view returns (bool);
321
322            event ModulusRotated(bytes32 indexed kidHash, string kid, bytes32 modulusHash, uint256 expiresAt);
323            event ModulusUntrusted(bytes32 indexed modulusHash);
324            event RootApplied(bytes32 indexed kidHash, bytes32 indexed modulusHash, uint256 observedAt, uint256 expiresAt);
325            event RootPruned(bytes32 indexed kidHash, bytes32 modulusHash);
326        }
327    }
328}
329
330pub use jwks_roots_inner::IdentityJwksRoots;