@thurinlabs/identity-kit 1.3.7 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,606 +1,186 @@
1
1
  import {
2
2
  ARWEAVE_GATEWAY,
3
3
  AUTHORIZATION_TYPES,
4
+ CLAIM_CHECK_LABEL,
5
+ CLAIM_LIMIT,
6
+ CONTRACT_ERROR_TEXT,
4
7
  EIP712_NAME,
5
8
  EIP712_VERSION,
6
9
  ENS_HINT_KEY,
7
10
  ENS_TEXT_RESOLVER_ABI,
8
11
  FARCASTER_HUB,
9
- IDENTITY_ERROR_TEXT,
10
- IDENTITY_KINDS,
11
12
  IPFS_GATEWAY,
12
13
  IPFS_GATEWAYS,
13
14
  KNOWN_KINDS,
15
+ MAX_KIND_BYTES,
14
16
  MAX_RECORD_BYTES,
15
17
  NETWORKS,
16
18
  NFT_AVATAR_ABI,
19
+ OWNER_REVOKE_REASONS,
17
20
  REGISTRY_ABI,
18
21
  REGISTRY_ADDRESS,
19
- addPointer,
22
+ REVOKE_REASONS,
23
+ addRelease,
20
24
  attestTypedData,
21
25
  authorizationDigest,
22
26
  avatarFallbacks,
23
27
  avatarUrl,
24
28
  bytesToFingerprint,
25
29
  chainFor,
26
- decodeRecord,
30
+ checkKindName,
31
+ checkRecordValue,
32
+ claimCheckText,
33
+ claimFateText,
34
+ claimFates,
35
+ claimSignature,
36
+ contractErrorName,
37
+ contractErrorText,
27
38
  displayUrl,
28
- encodeRecord,
39
+ encryptRefusalText,
40
+ encryptTo,
41
+ encryptionKeyFor,
29
42
  ensHintFor,
30
43
  ensHintValue,
31
44
  ensHintWrite,
32
- fetchEFPGraph,
45
+ expiresSoon,
46
+ expiresSoonText,
33
47
  fetchEnsHint,
34
48
  fetchRecords,
49
+ findOwners,
35
50
  fingerprintHash,
36
51
  fingerprintToBytes,
52
+ formatClaimDate,
37
53
  getRegistry,
38
54
  hasEmailUserID,
39
55
  identifyProof,
40
- identityErrorKind,
41
56
  isNetworkName,
57
+ keyChangedText,
42
58
  keyIdOf,
43
59
  keyIdToBytes,
60
+ keyProblemText,
61
+ keyStanding,
44
62
  kindName,
45
- needsRpcProbe,
63
+ leanKey,
64
+ markCompromisedTypedData,
46
65
  nftAvatarImage,
47
66
  normalizeFingerprint,
67
+ pageRecords,
48
68
  parseNftAvatar,
49
69
  parsePgpKey,
50
- parsePointer,
51
70
  parseRecord,
71
+ parseReleases,
72
+ payloadText,
73
+ pickRecords,
52
74
  proofHref,
53
75
  proofSecondaryHref,
76
+ readClaims,
54
77
  reattestTypedData,
55
78
  recordKind,
56
79
  registryDomain,
57
- renderPointer,
80
+ renderReleases,
58
81
  revokeTypedData,
82
+ sameFingerprint,
59
83
  setRecordTypedData,
84
+ signatureEmail,
85
+ sshKeys,
86
+ statementText,
60
87
  stripEmailUserIDs,
61
88
  updateKeyTypedData,
62
89
  verifyAttestation,
63
90
  verifyClearsigned,
64
- verifyProof
65
- } from "./chunk-ROQWHCHP.js";
66
-
67
- // src/provider.tsx
68
- import { useMemo } from "react";
69
- import { WagmiProvider, createConfig, http, useConfig } from "wagmi";
70
- import { mainnet, sepolia, foundry } from "wagmi/chains";
71
- import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
72
-
73
- // src/context.ts
74
- import { createContext, useContext } from "react";
75
- var defaultConfig = {
76
- baseUrl: "https://thurin.id",
77
- network: "mainnet"
78
- };
79
- var IdentityKitContext = createContext(defaultConfig);
80
- function useIdentityKitConfig() {
81
- return useContext(IdentityKitContext);
82
- }
83
-
84
- // src/provider.tsx
85
- import { Fragment, jsx } from "react/jsx-runtime";
86
- var defaultQueryClient = new QueryClient({
87
- defaultOptions: {
88
- queries: {
89
- staleTime: 6e4,
90
- retry: 1
91
- }
92
- }
93
- });
94
- function createDefaultWagmiConfig(rpcUrl, network) {
95
- const url = rpcUrl || getRegistry(network).defaultRpcUrl;
96
- if (network === "sepolia") return createConfig({ chains: [sepolia], transports: { [sepolia.id]: http(url) } });
97
- if (network === "local") return createConfig({ chains: [foundry], transports: { [foundry.id]: http(url) } });
98
- return createConfig({ chains: [mainnet], transports: { [mainnet.id]: http(url) } });
99
- }
100
- function WagmiDetector({ children, rpcUrl, network }) {
101
- let hasWagmi = false;
102
- try {
103
- useConfig();
104
- hasWagmi = true;
105
- } catch {
106
- }
107
- const wagmiConfig = useMemo(() => createDefaultWagmiConfig(rpcUrl, network), [rpcUrl, network]);
108
- if (hasWagmi) {
109
- return /* @__PURE__ */ jsx(Fragment, { children });
110
- }
111
- return /* @__PURE__ */ jsx(WagmiProvider, { config: wagmiConfig, children: /* @__PURE__ */ jsx(QueryClientProvider, { client: defaultQueryClient, children }) });
112
- }
113
- function IdentityKitProvider({
114
- children,
115
- rpcUrl,
116
- neynarApiKey,
117
- farcasterHub,
118
- baseUrl = "https://thurin.id",
119
- network = "mainnet",
120
- registryAddress
121
- }) {
122
- const config = useMemo(
123
- () => ({ rpcUrl, neynarApiKey, farcasterHub, baseUrl, network, registryAddress }),
124
- [rpcUrl, neynarApiKey, farcasterHub, baseUrl, network, registryAddress]
125
- );
126
- return /* @__PURE__ */ jsx(IdentityKitContext.Provider, { value: config, children: /* @__PURE__ */ jsx(WagmiDetector, { rpcUrl, network, children }) });
127
- }
128
-
129
- // src/components/ThurinCard/ThurinCard.tsx
130
- import { useEffect, useState } from "react";
131
-
132
- // src/hooks/useThurinIdentity.ts
133
- import { useBlockNumber, useEnsAddress, useEnsName } from "wagmi";
134
- import { normalize } from "viem/ens";
135
-
136
- // src/hooks/useAttestations.ts
137
- import { useReadContract, useReadContracts } from "wagmi";
138
- import { useQuery } from "@tanstack/react-query";
139
- import { hexToString } from "viem";
140
- function useAttestations(address) {
141
- const config = useIdentityKitConfig();
142
- const registry = getRegistry(config.network, config.registryAddress);
143
- const chain = chainFor(config.network);
144
- const owner = address;
145
- const { data: rows, isLoading: rowsLoading, isFetched: rowsFetched, error: rowsError, refetch: refetchRows } = useReadContract({
146
- address: registry.address,
147
- abi: REGISTRY_ABI,
148
- functionName: "attestationsOf",
149
- args: owner ? [owner] : void 0,
150
- chainId: chain.id,
151
- query: { enabled: !!owner }
152
- });
153
- const count = rows?.length ?? 0;
154
- const contracts = owner && rows ? rows.map((_, i) => ({
155
- address: registry.address,
156
- abi: REGISTRY_ABI,
157
- functionName: "getPayload",
158
- args: [owner, BigInt(i)],
159
- chainId: chain.id
160
- })) : [];
161
- const { data: payloads, isLoading: payloadsLoading, error: payloadsError, refetch: refetchPayloads } = useReadContracts({
162
- contracts,
163
- query: { enabled: contracts.length > 0 }
164
- });
165
- const payloadsReady = count === 0 || payloads !== void 0 && payloads.length === count;
166
- const { data: claims, isLoading: verifyLoading } = useQuery({
167
- queryKey: ["attestations", config.network, registry.address, address, count, payloadsReady],
168
- queryFn: async () => {
169
- if (!rows || !address) return [];
170
- const results = [];
171
- for (let i = 0; i < rows.length; i++) {
172
- const row = rows[i];
173
- const payload = payloads?.[i];
174
- let pgpSignature = null;
175
- let pgpPublicKey = null;
176
- if (payload && payload.status === "success") {
177
- const [sigHex, keyHex] = payload.result;
178
- pgpSignature = hexToString(sigHex);
179
- pgpPublicKey = hexToString(keyHex);
180
- }
181
- const fingerprint = bytesToFingerprint(row.fingerprint);
182
- const verification = pgpPublicKey && pgpSignature ? await verifyAttestation({ pgpPublicKey, pgpSignature, fingerprint, ethAddress: address }) : null;
183
- const revokedAt = Number(row.revokedAt);
184
- results.push({
185
- index: i,
186
- fingerprint,
187
- createdAt: Number(row.createdAt),
188
- revoked: revokedAt !== 0,
189
- revokedAt: revokedAt === 0 ? null : revokedAt,
190
- messageVersion: Number(row.messageVersion),
191
- pgpSignature,
192
- pgpPublicKey,
193
- verification
194
- });
195
- }
196
- return results;
197
- },
198
- enabled: !!rows && payloadsReady,
199
- staleTime: 3e5
200
- });
201
- const isLoading = rowsLoading || !!owner && !rowsFetched || payloadsLoading || verifyLoading || !!owner && rows !== void 0 && !payloadsReady;
202
- const activeClaims = (claims || []).filter((c) => !c.revoked);
203
- const verifiedClaims = activeClaims.filter((c) => c.verification?.verified);
204
- const currentFingerprint = verifiedClaims.length > 0 ? verifiedClaims[verifiedClaims.length - 1].fingerprint : null;
205
- return {
206
- claims: claims || [],
207
- totalClaims: count,
208
- activeClaims: activeClaims.length,
209
- currentFingerprint,
210
- isLoading,
211
- /** A registry read failed (the RPC may be down; useThurinIdentity finds out which). */
212
- error: rowsError ?? payloadsError ?? null,
213
- refetch: () => {
214
- if (owner) {
215
- refetchRows();
216
- if (contracts.length > 0) refetchPayloads();
217
- }
218
- }
219
- };
220
- }
221
-
222
- // src/hooks/useEFPGraph.ts
223
- import { useQuery as useQuery2 } from "@tanstack/react-query";
224
- function useEFPGraph(address) {
225
- const { data, isLoading } = useQuery2({
226
- queryKey: ["efp-graph", address],
227
- queryFn: () => fetchEFPGraph(address),
228
- enabled: !!address,
229
- staleTime: 3e5
230
- });
231
- return {
232
- efp: data ?? null,
233
- isLoading
234
- };
235
- }
236
-
237
- // src/hooks/usePGPProofs.ts
238
- import { useQuery as useQuery3 } from "@tanstack/react-query";
239
- function usePGPProofs(fingerprint, armoredKey) {
240
- const config = useIdentityKitConfig();
241
- const { data } = useQuery3({
242
- // The key is large; key the query on its length + fingerprint, which
243
- // changes whenever a different attestation's key is supplied.
244
- queryKey: ["pgp-proofs", fingerprint, armoredKey?.length ?? 0],
245
- queryFn: async () => {
246
- if (!fingerprint || !armoredKey) return { keyInfo: null, proofs: [] };
247
- const keyInfo = await parsePgpKey(armoredKey);
248
- if (!keyInfo) return { keyInfo: null, proofs: [] };
249
- const identified = keyInfo.notations.map((n) => identifyProof(n)).filter((p) => p !== null && p.provider !== "unknown");
250
- const proofs = await Promise.all(
251
- identified.map(async (proof) => {
252
- const result = await verifyProof(proof, fingerprint, { neynarApiKey: config.neynarApiKey, farcasterHub: config.farcasterHub });
253
- return {
254
- provider: proof.provider,
255
- label: proof.label,
256
- url: proof.url,
257
- displayUrl: displayUrl(proof),
258
- href: proofHref(proof),
259
- secondaryHref: proofSecondaryHref(proof),
260
- status: result.verified ? "verified" : "unverified",
261
- reason: result.reason
262
- };
263
- })
264
- );
265
- const byAccount = /* @__PURE__ */ new Map();
266
- for (const p of proofs) {
267
- const key = `${p.provider}:${p.displayUrl}`;
268
- const prev = byAccount.get(key);
269
- if (!prev || p.status === "verified" && prev.status !== "verified") {
270
- byAccount.set(key, p);
271
- }
272
- }
273
- return { keyInfo, proofs: [...byAccount.values()] };
274
- },
275
- enabled: !!fingerprint && !!armoredKey,
276
- staleTime: 3e5
277
- });
278
- return {
279
- keyInfo: data?.keyInfo ?? null,
280
- proofs: data?.proofs ?? [],
281
- // Report loading whenever a fingerprint is set but its proofs haven't
282
- // resolved yet. Using react-query's own isLoading leaves a gap while the
283
- // query is enabling (fingerprint just became known), during which the card
284
- // would briefly paint without proof badges and then pop them in.
285
- isLoading: !!fingerprint && !!armoredKey && data === void 0
286
- };
287
- }
288
-
289
- // src/hooks/useSafeAvatar.ts
290
- import { useEnsText, useReadContract as useReadContract2 } from "wagmi";
291
- import { useQuery as useQuery4 } from "@tanstack/react-query";
292
- function useSafeAvatar(name, chainId) {
293
- const { data: raw } = useEnsText({ name, key: "avatar", chainId, query: { enabled: !!name } });
294
- const direct = avatarUrl(raw);
295
- const nft = direct ? null : parseNftAvatar(raw);
296
- const { data: tokenUri } = useReadContract2({
297
- address: nft?.contract,
298
- abi: NFT_AVATAR_ABI,
299
- functionName: nft?.standard === "erc1155" ? "uri" : "tokenURI",
300
- args: nft ? [nft.tokenId] : void 0,
301
- chainId,
302
- query: { enabled: !!nft && nft.chainId === chainId }
303
- });
304
- const { data: image } = useQuery4({
305
- queryKey: ["thurin-nft-avatar", tokenUri, nft?.tokenId.toString()],
306
- queryFn: () => nftAvatarImage(tokenUri, nft.tokenId).catch(() => null),
307
- enabled: typeof tokenUri === "string" && !!nft
308
- });
309
- return direct ?? image ?? null;
310
- }
311
-
312
- // src/hooks/useThurinIdentity.ts
313
- function isAddress(value) {
314
- return /^0x[0-9a-fA-F]{40}$/.test(value);
315
- }
316
- function safeNormalize(name) {
317
- try {
318
- return normalize(name);
319
- } catch {
320
- return void 0;
321
- }
322
- }
323
- function useThurinIdentity(ensOrAddress) {
324
- const chain = chainFor(useIdentityKitConfig().network);
325
- const isAddr = ensOrAddress ? isAddress(ensOrAddress) : false;
326
- const ensInput = ensOrAddress && !isAddr ? safeNormalize(ensOrAddress) : void 0;
327
- const { data: resolvedAddress, error: ensError, isFetched: ensFetched, refetch: refetchEns } = useEnsAddress({
328
- name: ensInput,
329
- chainId: chain.id,
330
- query: { enabled: !!ensInput }
331
- });
332
- const address = isAddr ? ensOrAddress : resolvedAddress ?? null;
333
- const { data: ensName } = useEnsName({
334
- address,
335
- chainId: chain.id,
336
- query: { enabled: !!address }
337
- });
338
- const displayName = ensInput || ensName || null;
339
- const ensAvatar = useSafeAvatar(displayName ? safeNormalize(displayName) : void 0, chain.id);
340
- const {
341
- claims,
342
- totalClaims,
343
- activeClaims,
344
- currentFingerprint,
345
- isLoading: claimsLoading,
346
- error: claimsError,
347
- refetch: refetchClaims
348
- } = useAttestations(address);
349
- const currentClaim = [...claims].reverse().find(
350
- (c) => !c.revoked && c.verification?.verified && c.fingerprint === currentFingerprint
351
- );
352
- const {
353
- keyInfo: pgpKeyInfo,
354
- proofs,
355
- isLoading: proofsLoading
356
- } = usePGPProofs(currentFingerprint, currentClaim?.pgpPublicKey ?? null);
357
- const { efp, isLoading: efpLoading } = useEFPGraph(address);
358
- const lookup = { ensEmpty: !!ensInput && ensFetched && !resolvedAddress, ensFailed: !!ensError, claimsFailed: !!claimsError };
359
- const probeNeeded = needsRpcProbe(lookup);
360
- const probe = useBlockNumber({
361
- chainId: chain.id,
362
- scopeKey: `thurin-rpc-probe:${ensOrAddress ?? ""}`,
363
- query: { enabled: probeNeeded, retry: 0, staleTime: 0, gcTime: 0 }
364
- });
365
- const rpcAnswered = !probeNeeded || probe.isFetching ? void 0 : probe.isSuccess ? true : probe.isError ? false : void 0;
366
- const errorKind = identityErrorKind({ ...lookup, rpcAnswered });
367
- const probing = probeNeeded && rpcAnswered === void 0;
368
- const retry = () => {
369
- if (ensInput) refetchEns();
370
- refetchClaims();
371
- if (probeNeeded) probe.refetch();
372
- };
373
- return {
374
- address,
375
- ensName: displayName,
376
- ensAvatar,
377
- claims,
378
- totalClaims,
379
- activeClaims,
380
- currentFingerprint,
381
- pgpKeyInfo,
382
- proofs,
383
- efp,
384
- // "Not finished" counts as loading, including queries paused in a background tab: the card
385
- // must not render defaults (zeros) for an identity it hasn't looked up yet.
386
- isLoading: !!ensInput && !ensFetched || claimsLoading || proofsLoading || efpLoading || probing,
387
- error: errorKind ? new Error(IDENTITY_ERROR_TEXT[errorKind]) : null,
388
- errorKind,
389
- retry
390
- };
391
- }
392
-
393
- // src/components/ThurinCard/ThurinCard.tsx
394
- import { jsx as jsx2, jsxs } from "react/jsx-runtime";
395
- function ThurinLogo() {
396
- return /* @__PURE__ */ jsxs("svg", { className: "thurin-card-avatar-placeholder", viewBox: "0 0 100 100", xmlns: "http://www.w3.org/2000/svg", children: [
397
- /* @__PURE__ */ jsx2("circle", { cx: "50", cy: "50", r: "50", fill: "var(--thurin-surface-deep)" }),
398
- /* @__PURE__ */ jsx2("path", { d: "M25 80 Q25 25 50 25 Q75 25 75 50", fill: "none", stroke: "#7c9a3e", strokeWidth: "4", strokeLinecap: "round" }),
399
- /* @__PURE__ */ jsx2("path", { d: "M33 75 Q33 35 50 35 Q67 35 67 52", fill: "none", stroke: "#7c9a3e", strokeWidth: "4", strokeLinecap: "round" }),
400
- /* @__PURE__ */ jsx2("path", { d: "M41 70 Q41 45 50 45 Q59 45 59 55", fill: "none", stroke: "#c9a227", strokeWidth: "4", strokeLinecap: "round" }),
401
- /* @__PURE__ */ jsx2("path", { d: "M50 65 L50 53", fill: "none", stroke: "#c9a227", strokeWidth: "4", strokeLinecap: "round" })
402
- ] });
403
- }
404
- function Avatar({ src, alt }) {
405
- const [tries, setTries] = useState([]);
406
- useEffect(() => {
407
- setTries(src ? [src, ...avatarFallbacks(src)] : []);
408
- }, [src]);
409
- if (!tries.length) return /* @__PURE__ */ jsx2(ThurinLogo, {});
410
- return /* @__PURE__ */ jsx2("img", { className: "thurin-card-avatar", src: tries[0], alt, onError: () => setTries((t) => t.slice(1)) });
411
- }
412
- function ThurinCard({ ens, address, theme = "thurin" }) {
413
- const input = ens || address;
414
- const identity = useThurinIdentity(input);
415
- const config = useIdentityKitConfig();
416
- const profileUrl = identity.address ? `${config.baseUrl}/eth/${identity.address}` : ens ? `${config.baseUrl}/ens/${ens}` : null;
417
- if (identity.isLoading) {
418
- return /* @__PURE__ */ jsx2("div", { className: "thurin-card", "data-thurin-theme": theme, children: /* @__PURE__ */ jsx2("div", { className: "thurin-card-loading", children: "Loading identity..." }) });
419
- }
420
- const displayAddress = identity.address || null;
421
- if (identity.errorKind) {
422
- return /* @__PURE__ */ jsxs("div", { className: "thurin-card", "data-thurin-theme": theme, children: [
423
- /* @__PURE__ */ jsxs("div", { className: "thurin-card-header", children: [
424
- /* @__PURE__ */ jsx2(ThurinLogo, {}),
425
- /* @__PURE__ */ jsx2("div", { children: /* @__PURE__ */ jsx2("div", { className: "thurin-card-name", children: identity.ensName || ens || address }) })
426
- ] }),
427
- /* @__PURE__ */ jsxs("div", { className: "thurin-card-error", role: "status", children: [
428
- identity.error?.message,
429
- identity.errorKind !== "not-found" && /* @__PURE__ */ jsx2("button", { type: "button", className: "thurin-card-retry", onClick: identity.retry, children: "Try again" })
430
- ] }),
431
- profileUrl && identity.errorKind !== "not-found" && /* @__PURE__ */ jsx2("a", { className: "thurin-card-link", href: profileUrl, target: "_blank", rel: "noopener noreferrer", children: "View on Thurin" })
432
- ] });
433
- }
434
- const verifiedProofs = identity.proofs.filter((p) => p.status === "verified").length;
435
- const hasVerifiedPgp = identity.claims.some((c) => c.verification?.verified && !c.revoked);
436
- return /* @__PURE__ */ jsxs("div", { className: "thurin-card", "data-thurin-theme": theme, children: [
437
- /* @__PURE__ */ jsxs("a", { className: "thurin-card-header", href: profileUrl || void 0, target: "_blank", rel: "noopener noreferrer", children: [
438
- /* @__PURE__ */ jsx2(Avatar, { src: identity.ensAvatar, alt: identity.ensName || "" }),
439
- /* @__PURE__ */ jsxs("div", { children: [
440
- identity.ensName && /* @__PURE__ */ jsx2("div", { className: "thurin-card-name", children: identity.ensName }),
441
- displayAddress && /* @__PURE__ */ jsx2("div", { className: "thurin-card-address", children: displayAddress })
442
- ] })
443
- ] }),
444
- /* @__PURE__ */ jsxs("div", { className: "thurin-card-stats", children: [
445
- /* @__PURE__ */ jsxs("div", { className: "thurin-card-stat", children: [
446
- /* @__PURE__ */ jsx2("span", { className: "thurin-card-stat-value", children: identity.activeClaims }),
447
- /* @__PURE__ */ jsx2("span", { className: "thurin-card-stat-label", children: "Attestations" })
448
- ] }),
449
- /* @__PURE__ */ jsxs("div", { className: "thurin-card-stat", children: [
450
- /* @__PURE__ */ jsx2("span", { className: "thurin-card-stat-value", children: verifiedProofs }),
451
- /* @__PURE__ */ jsx2("span", { className: "thurin-card-stat-label", children: "Proofs" })
452
- ] }),
453
- /* @__PURE__ */ jsxs("div", { className: "thurin-card-stat", children: [
454
- /* @__PURE__ */ jsx2("span", { className: "thurin-card-stat-value", children: identity.efp ? identity.efp.followers : "\u2013" }),
455
- /* @__PURE__ */ jsx2("span", { className: "thurin-card-stat-label", children: "Followers" })
456
- ] })
457
- ] }),
458
- /* @__PURE__ */ jsxs("div", { className: "thurin-card-badges", children: [
459
- hasVerifiedPgp && /* @__PURE__ */ jsx2("span", { className: "thurin-card-badge thurin-card-badge--verified", children: "PGP Verified" }),
460
- identity.efp?.hasEfp && /* @__PURE__ */ jsx2("span", { className: "thurin-card-badge thurin-card-badge--verified", children: "EFP" }),
461
- identity.proofs.map((p, i) => /* @__PURE__ */ jsx2(
462
- "span",
463
- {
464
- className: `thurin-card-badge thurin-card-badge--${p.status === "verified" ? "verified" : "unverified"}`,
465
- children: p.label
466
- },
467
- i
468
- ))
469
- ] }),
470
- profileUrl && /* @__PURE__ */ jsx2(
471
- "a",
472
- {
473
- className: "thurin-card-link",
474
- href: profileUrl,
475
- target: "_blank",
476
- rel: "noopener noreferrer",
477
- children: "View on Thurin"
478
- }
479
- )
480
- ] });
481
- }
482
-
483
- // src/hooks/useEnsHint.ts
484
- import { useEnsText as useEnsText2 } from "wagmi";
485
- import { normalize as normalize2 } from "viem/ens";
486
- function safeNormalize2(name) {
487
- try {
488
- return normalize2(name);
489
- } catch {
490
- return void 0;
491
- }
492
- }
493
- function useEnsHint(name, verifiedFingerprint) {
494
- const chain = chainFor(useIdentityKitConfig().network);
495
- const ensName = name ? safeNormalize2(name) : void 0;
496
- const { data, isLoading, refetch } = useEnsText2({
497
- name: ensName,
498
- key: ENS_HINT_KEY,
499
- chainId: chain.id,
500
- query: { enabled: !!ensName }
501
- });
502
- return { ...ensHintFor(data ?? null, verifiedFingerprint), isLoading: !!ensName && isLoading, refetch: () => {
503
- void refetch();
504
- } };
505
- }
506
-
507
- // src/hooks/useRecords.ts
508
- import { useReadContracts as useReadContracts2 } from "wagmi";
509
- import { useQuery as useQuery5 } from "@tanstack/react-query";
510
- function useRecords(address, index, kinds = IDENTITY_KINDS, armoredKey) {
511
- const config = useIdentityKitConfig();
512
- const registry = getRegistry(config.network, config.registryAddress);
513
- const chain = chainFor(config.network);
514
- const owner = address;
515
- const enabled = !!owner && index !== void 0 && index !== null;
516
- const contracts = enabled ? kinds.map((kind) => ({ address: registry.address, abi: REGISTRY_ABI, functionName: "record", args: [owner, BigInt(index), recordKind(kind)], chainId: chain.id })) : [];
517
- const { data: raw, isLoading: readLoading, refetch } = useReadContracts2({ contracts, query: { enabled: contracts.length > 0 } });
518
- const texts = (raw ?? []).map((r) => r.status === "success" ? decodeRecord(r.result) : "");
519
- const { data: records, isLoading: parseLoading } = useQuery5({
520
- queryKey: ["records", config.network, registry.address, address, index, kinds.join(","), texts.join(" "), armoredKey ?? ""],
521
- queryFn: async () => {
522
- const out = [];
523
- for (let i = 0; i < kinds.length; i++) if (texts[i]) out.push(await parseRecord(kinds[i], texts[i], { armoredKey: armoredKey ?? void 0 }));
524
- return out;
525
- },
526
- enabled: enabled && raw !== void 0
527
- });
528
- return { records: records ?? [], isLoading: enabled && (readLoading || parseLoading), refetch: () => {
529
- void refetch();
530
- } };
531
- }
91
+ verifyProof,
92
+ verifyStatementSignature
93
+ } from "./chunk-AAJWERE2.js";
532
94
  export {
533
95
  ARWEAVE_GATEWAY,
534
96
  AUTHORIZATION_TYPES,
97
+ CLAIM_CHECK_LABEL,
98
+ CLAIM_LIMIT,
99
+ CONTRACT_ERROR_TEXT,
535
100
  EIP712_NAME,
536
101
  EIP712_VERSION,
537
102
  ENS_HINT_KEY,
538
103
  ENS_TEXT_RESOLVER_ABI,
539
104
  FARCASTER_HUB,
540
- IDENTITY_ERROR_TEXT,
541
- IDENTITY_KINDS,
542
105
  IPFS_GATEWAY,
543
106
  IPFS_GATEWAYS,
544
- IdentityKitProvider,
545
107
  KNOWN_KINDS,
108
+ MAX_KIND_BYTES,
546
109
  MAX_RECORD_BYTES,
547
110
  NETWORKS,
548
111
  NFT_AVATAR_ABI,
112
+ OWNER_REVOKE_REASONS,
549
113
  REGISTRY_ABI,
550
114
  REGISTRY_ADDRESS,
551
- ThurinCard,
552
- addPointer,
115
+ REVOKE_REASONS,
116
+ addRelease,
553
117
  attestTypedData,
554
118
  authorizationDigest,
555
119
  avatarFallbacks,
556
120
  avatarUrl,
557
121
  bytesToFingerprint,
558
122
  chainFor,
559
- decodeRecord,
123
+ checkKindName,
124
+ checkRecordValue,
125
+ claimCheckText,
126
+ claimFateText,
127
+ claimFates,
128
+ claimSignature,
129
+ contractErrorName,
130
+ contractErrorText,
560
131
  displayUrl,
561
- encodeRecord,
132
+ encryptRefusalText,
133
+ encryptTo,
134
+ encryptionKeyFor,
562
135
  ensHintFor,
563
136
  ensHintValue,
564
137
  ensHintWrite,
565
- fetchEFPGraph,
138
+ expiresSoon,
139
+ expiresSoonText,
566
140
  fetchEnsHint,
567
141
  fetchRecords,
142
+ findOwners,
568
143
  fingerprintHash,
569
144
  fingerprintToBytes,
145
+ formatClaimDate,
570
146
  getRegistry,
571
147
  hasEmailUserID,
572
148
  identifyProof,
573
- identityErrorKind,
574
149
  isNetworkName,
150
+ keyChangedText,
575
151
  keyIdOf,
576
152
  keyIdToBytes,
153
+ keyProblemText,
154
+ keyStanding,
577
155
  kindName,
578
- needsRpcProbe,
156
+ leanKey,
157
+ markCompromisedTypedData,
579
158
  nftAvatarImage,
580
159
  normalizeFingerprint,
160
+ pageRecords,
581
161
  parseNftAvatar,
582
162
  parsePgpKey,
583
- parsePointer,
584
163
  parseRecord,
164
+ parseReleases,
165
+ payloadText,
166
+ pickRecords,
585
167
  proofHref,
586
168
  proofSecondaryHref,
169
+ readClaims,
587
170
  reattestTypedData,
588
171
  recordKind,
589
172
  registryDomain,
590
- renderPointer,
173
+ renderReleases,
591
174
  revokeTypedData,
175
+ sameFingerprint,
592
176
  setRecordTypedData,
177
+ signatureEmail,
178
+ sshKeys,
179
+ statementText,
593
180
  stripEmailUserIDs,
594
181
  updateKeyTypedData,
595
- useAttestations,
596
- useEFPGraph,
597
- useEnsHint,
598
- usePGPProofs,
599
- useRecords,
600
- useSafeAvatar,
601
- useThurinIdentity,
602
182
  verifyAttestation,
603
183
  verifyClearsigned,
604
- verifyProof
184
+ verifyProof,
185
+ verifyStatementSignature
605
186
  };
606
- //# sourceMappingURL=index.js.map