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