@thurinlabs/identity-kit 1.3.5 → 1.3.7
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/README.md +12 -10
- package/dist/{chunk-YTO7Z5SI.cjs → chunk-OIE72R6J.cjs} +45 -30
- package/dist/chunk-OIE72R6J.cjs.map +1 -0
- package/dist/{chunk-CF64QQZO.js → chunk-ROQWHCHP.js} +41 -26
- package/dist/{chunk-CF64QQZO.js.map → chunk-ROQWHCHP.js.map} +1 -1
- package/dist/core.cjs +8 -2
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +34 -5
- package/dist/core.d.ts +34 -5
- package/dist/core.js +7 -1
- package/dist/embed.global.js +56 -38
- package/dist/embed.global.js.map +1 -1
- package/dist/index.cjs +54 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +23 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-YTO7Z5SI.cjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -59,7 +59,10 @@
|
|
|
59
59
|
|
|
60
60
|
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
var _chunkOIE72R6Jcjs = require('./chunk-OIE72R6J.cjs');
|
|
63
66
|
|
|
64
67
|
// src/provider.tsx
|
|
65
68
|
var _react = require('react');
|
|
@@ -89,7 +92,7 @@ var defaultQueryClient = new (0, _reactquery.QueryClient)({
|
|
|
89
92
|
}
|
|
90
93
|
});
|
|
91
94
|
function createDefaultWagmiConfig(rpcUrl, network) {
|
|
92
|
-
const url = rpcUrl ||
|
|
95
|
+
const url = rpcUrl || _chunkOIE72R6Jcjs.getRegistry.call(void 0, network).defaultRpcUrl;
|
|
93
96
|
if (network === "sepolia") return _wagmi.createConfig.call(void 0, { chains: [_chains.sepolia], transports: { [_chains.sepolia.id]: _wagmi.http.call(void 0, url) } });
|
|
94
97
|
if (network === "local") return _wagmi.createConfig.call(void 0, { chains: [_chains.foundry], transports: { [_chains.foundry.id]: _wagmi.http.call(void 0, url) } });
|
|
95
98
|
return _wagmi.createConfig.call(void 0, { chains: [_chains.mainnet], transports: { [_chains.mainnet.id]: _wagmi.http.call(void 0, url) } });
|
|
@@ -111,17 +114,21 @@ function IdentityKitProvider({
|
|
|
111
114
|
children,
|
|
112
115
|
rpcUrl,
|
|
113
116
|
neynarApiKey,
|
|
117
|
+
farcasterHub,
|
|
114
118
|
baseUrl = "https://thurin.id",
|
|
115
119
|
network = "mainnet",
|
|
116
120
|
registryAddress
|
|
117
121
|
}) {
|
|
118
122
|
const config = _react.useMemo.call(void 0,
|
|
119
|
-
() => ({ rpcUrl, neynarApiKey, baseUrl, network, registryAddress }),
|
|
120
|
-
[rpcUrl, neynarApiKey, baseUrl, network, registryAddress]
|
|
123
|
+
() => ({ rpcUrl, neynarApiKey, farcasterHub, baseUrl, network, registryAddress }),
|
|
124
|
+
[rpcUrl, neynarApiKey, farcasterHub, baseUrl, network, registryAddress]
|
|
121
125
|
);
|
|
122
126
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, IdentityKitContext.Provider, { value: config, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, WagmiDetector, { rpcUrl, network, children }) });
|
|
123
127
|
}
|
|
124
128
|
|
|
129
|
+
// src/components/ThurinCard/ThurinCard.tsx
|
|
130
|
+
|
|
131
|
+
|
|
125
132
|
// src/hooks/useThurinIdentity.ts
|
|
126
133
|
|
|
127
134
|
var _ens = require('viem/ens');
|
|
@@ -132,12 +139,12 @@ var _ens = require('viem/ens');
|
|
|
132
139
|
var _viem = require('viem');
|
|
133
140
|
function useAttestations(address) {
|
|
134
141
|
const config = useIdentityKitConfig();
|
|
135
|
-
const registry =
|
|
136
|
-
const chain =
|
|
142
|
+
const registry = _chunkOIE72R6Jcjs.getRegistry.call(void 0, config.network, config.registryAddress);
|
|
143
|
+
const chain = _chunkOIE72R6Jcjs.chainFor.call(void 0, config.network);
|
|
137
144
|
const owner = address;
|
|
138
145
|
const { data: rows, isLoading: rowsLoading, isFetched: rowsFetched, error: rowsError, refetch: refetchRows } = _wagmi.useReadContract.call(void 0, {
|
|
139
146
|
address: registry.address,
|
|
140
|
-
abi:
|
|
147
|
+
abi: _chunkOIE72R6Jcjs.REGISTRY_ABI,
|
|
141
148
|
functionName: "attestationsOf",
|
|
142
149
|
args: owner ? [owner] : void 0,
|
|
143
150
|
chainId: chain.id,
|
|
@@ -146,7 +153,7 @@ function useAttestations(address) {
|
|
|
146
153
|
const count = _nullishCoalesce(_optionalChain([rows, 'optionalAccess', _2 => _2.length]), () => ( 0));
|
|
147
154
|
const contracts = owner && rows ? rows.map((_, i) => ({
|
|
148
155
|
address: registry.address,
|
|
149
|
-
abi:
|
|
156
|
+
abi: _chunkOIE72R6Jcjs.REGISTRY_ABI,
|
|
150
157
|
functionName: "getPayload",
|
|
151
158
|
args: [owner, BigInt(i)],
|
|
152
159
|
chainId: chain.id
|
|
@@ -171,8 +178,8 @@ function useAttestations(address) {
|
|
|
171
178
|
pgpSignature = _viem.hexToString.call(void 0, sigHex);
|
|
172
179
|
pgpPublicKey = _viem.hexToString.call(void 0, keyHex);
|
|
173
180
|
}
|
|
174
|
-
const fingerprint =
|
|
175
|
-
const verification = pgpPublicKey && pgpSignature ? await
|
|
181
|
+
const fingerprint = _chunkOIE72R6Jcjs.bytesToFingerprint.call(void 0, row.fingerprint);
|
|
182
|
+
const verification = pgpPublicKey && pgpSignature ? await _chunkOIE72R6Jcjs.verifyAttestation.call(void 0, { pgpPublicKey, pgpSignature, fingerprint, ethAddress: address }) : null;
|
|
176
183
|
const revokedAt = Number(row.revokedAt);
|
|
177
184
|
results.push({
|
|
178
185
|
index: i,
|
|
@@ -217,7 +224,7 @@ function useAttestations(address) {
|
|
|
217
224
|
function useEFPGraph(address) {
|
|
218
225
|
const { data, isLoading } = _reactquery.useQuery.call(void 0, {
|
|
219
226
|
queryKey: ["efp-graph", address],
|
|
220
|
-
queryFn: () =>
|
|
227
|
+
queryFn: () => _chunkOIE72R6Jcjs.fetchEFPGraph.call(void 0, address),
|
|
221
228
|
enabled: !!address,
|
|
222
229
|
staleTime: 3e5
|
|
223
230
|
});
|
|
@@ -237,19 +244,19 @@ function usePGPProofs(fingerprint, armoredKey) {
|
|
|
237
244
|
queryKey: ["pgp-proofs", fingerprint, _nullishCoalesce(_optionalChain([armoredKey, 'optionalAccess', _6 => _6.length]), () => ( 0))],
|
|
238
245
|
queryFn: async () => {
|
|
239
246
|
if (!fingerprint || !armoredKey) return { keyInfo: null, proofs: [] };
|
|
240
|
-
const keyInfo = await
|
|
247
|
+
const keyInfo = await _chunkOIE72R6Jcjs.parsePgpKey.call(void 0, armoredKey);
|
|
241
248
|
if (!keyInfo) return { keyInfo: null, proofs: [] };
|
|
242
|
-
const identified = keyInfo.notations.map((n) =>
|
|
249
|
+
const identified = keyInfo.notations.map((n) => _chunkOIE72R6Jcjs.identifyProof.call(void 0, n)).filter((p) => p !== null && p.provider !== "unknown");
|
|
243
250
|
const proofs = await Promise.all(
|
|
244
251
|
identified.map(async (proof) => {
|
|
245
|
-
const result = await
|
|
252
|
+
const result = await _chunkOIE72R6Jcjs.verifyProof.call(void 0, proof, fingerprint, { neynarApiKey: config.neynarApiKey, farcasterHub: config.farcasterHub });
|
|
246
253
|
return {
|
|
247
254
|
provider: proof.provider,
|
|
248
255
|
label: proof.label,
|
|
249
256
|
url: proof.url,
|
|
250
|
-
displayUrl:
|
|
251
|
-
href:
|
|
252
|
-
secondaryHref:
|
|
257
|
+
displayUrl: _chunkOIE72R6Jcjs.displayUrl.call(void 0, proof),
|
|
258
|
+
href: _chunkOIE72R6Jcjs.proofHref.call(void 0, proof),
|
|
259
|
+
secondaryHref: _chunkOIE72R6Jcjs.proofSecondaryHref.call(void 0, proof),
|
|
253
260
|
status: result.verified ? "verified" : "unverified",
|
|
254
261
|
reason: result.reason
|
|
255
262
|
};
|
|
@@ -284,11 +291,11 @@ function usePGPProofs(fingerprint, armoredKey) {
|
|
|
284
291
|
|
|
285
292
|
function useSafeAvatar(name, chainId) {
|
|
286
293
|
const { data: raw } = _wagmi.useEnsText.call(void 0, { name, key: "avatar", chainId, query: { enabled: !!name } });
|
|
287
|
-
const direct =
|
|
288
|
-
const nft = direct ? null :
|
|
294
|
+
const direct = _chunkOIE72R6Jcjs.avatarUrl.call(void 0, raw);
|
|
295
|
+
const nft = direct ? null : _chunkOIE72R6Jcjs.parseNftAvatar.call(void 0, raw);
|
|
289
296
|
const { data: tokenUri } = _wagmi.useReadContract.call(void 0, {
|
|
290
297
|
address: _optionalChain([nft, 'optionalAccess', _9 => _9.contract]),
|
|
291
|
-
abi:
|
|
298
|
+
abi: _chunkOIE72R6Jcjs.NFT_AVATAR_ABI,
|
|
292
299
|
functionName: _optionalChain([nft, 'optionalAccess', _10 => _10.standard]) === "erc1155" ? "uri" : "tokenURI",
|
|
293
300
|
args: nft ? [nft.tokenId] : void 0,
|
|
294
301
|
chainId,
|
|
@@ -296,7 +303,7 @@ function useSafeAvatar(name, chainId) {
|
|
|
296
303
|
});
|
|
297
304
|
const { data: image } = _reactquery.useQuery.call(void 0, {
|
|
298
305
|
queryKey: ["thurin-nft-avatar", tokenUri, _optionalChain([nft, 'optionalAccess', _11 => _11.tokenId, 'access', _12 => _12.toString, 'call', _13 => _13()])],
|
|
299
|
-
queryFn: () =>
|
|
306
|
+
queryFn: () => _chunkOIE72R6Jcjs.nftAvatarImage.call(void 0, tokenUri, nft.tokenId).catch(() => null),
|
|
300
307
|
enabled: typeof tokenUri === "string" && !!nft
|
|
301
308
|
});
|
|
302
309
|
return _nullishCoalesce(_nullishCoalesce(direct, () => ( image)), () => ( null));
|
|
@@ -314,7 +321,7 @@ function safeNormalize(name) {
|
|
|
314
321
|
}
|
|
315
322
|
}
|
|
316
323
|
function useThurinIdentity(ensOrAddress) {
|
|
317
|
-
const chain =
|
|
324
|
+
const chain = _chunkOIE72R6Jcjs.chainFor.call(void 0, useIdentityKitConfig().network);
|
|
318
325
|
const isAddr = ensOrAddress ? isAddress(ensOrAddress) : false;
|
|
319
326
|
const ensInput = ensOrAddress && !isAddr ? safeNormalize(ensOrAddress) : void 0;
|
|
320
327
|
const { data: resolvedAddress, error: ensError, isFetched: ensFetched, refetch: refetchEns } = _wagmi.useEnsAddress.call(void 0, {
|
|
@@ -349,14 +356,14 @@ function useThurinIdentity(ensOrAddress) {
|
|
|
349
356
|
} = usePGPProofs(currentFingerprint, _nullishCoalesce(_optionalChain([currentClaim, 'optionalAccess', _16 => _16.pgpPublicKey]), () => ( null)));
|
|
350
357
|
const { efp, isLoading: efpLoading } = useEFPGraph(address);
|
|
351
358
|
const lookup = { ensEmpty: !!ensInput && ensFetched && !resolvedAddress, ensFailed: !!ensError, claimsFailed: !!claimsError };
|
|
352
|
-
const probeNeeded =
|
|
359
|
+
const probeNeeded = _chunkOIE72R6Jcjs.needsRpcProbe.call(void 0, lookup);
|
|
353
360
|
const probe = _wagmi.useBlockNumber.call(void 0, {
|
|
354
361
|
chainId: chain.id,
|
|
355
362
|
scopeKey: `thurin-rpc-probe:${_nullishCoalesce(ensOrAddress, () => ( ""))}`,
|
|
356
363
|
query: { enabled: probeNeeded, retry: 0, staleTime: 0, gcTime: 0 }
|
|
357
364
|
});
|
|
358
365
|
const rpcAnswered = !probeNeeded || probe.isFetching ? void 0 : probe.isSuccess ? true : probe.isError ? false : void 0;
|
|
359
|
-
const errorKind =
|
|
366
|
+
const errorKind = _chunkOIE72R6Jcjs.identityErrorKind.call(void 0, { ...lookup, rpcAnswered });
|
|
360
367
|
const probing = probeNeeded && rpcAnswered === void 0;
|
|
361
368
|
const retry = () => {
|
|
362
369
|
if (ensInput) refetchEns();
|
|
@@ -377,7 +384,7 @@ function useThurinIdentity(ensOrAddress) {
|
|
|
377
384
|
// "Not finished" counts as loading, including queries paused in a background tab: the card
|
|
378
385
|
// must not render defaults (zeros) for an identity it hasn't looked up yet.
|
|
379
386
|
isLoading: !!ensInput && !ensFetched || claimsLoading || proofsLoading || efpLoading || probing,
|
|
380
|
-
error: errorKind ? new Error(
|
|
387
|
+
error: errorKind ? new Error(_chunkOIE72R6Jcjs.IDENTITY_ERROR_TEXT[errorKind]) : null,
|
|
381
388
|
errorKind,
|
|
382
389
|
retry
|
|
383
390
|
};
|
|
@@ -394,6 +401,14 @@ function ThurinLogo() {
|
|
|
394
401
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M50 65 L50 53", fill: "none", stroke: "#c9a227", strokeWidth: "4", strokeLinecap: "round" })
|
|
395
402
|
] });
|
|
396
403
|
}
|
|
404
|
+
function Avatar({ src, alt }) {
|
|
405
|
+
const [tries, setTries] = _react.useState.call(void 0, []);
|
|
406
|
+
_react.useEffect.call(void 0, () => {
|
|
407
|
+
setTries(src ? [src, ..._chunkOIE72R6Jcjs.avatarFallbacks.call(void 0, src)] : []);
|
|
408
|
+
}, [src]);
|
|
409
|
+
if (!tries.length) return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ThurinLogo, {});
|
|
410
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "img", { className: "thurin-card-avatar", src: tries[0], alt, onError: () => setTries((t) => t.slice(1)) });
|
|
411
|
+
}
|
|
397
412
|
function ThurinCard({ ens, address, theme = "thurin" }) {
|
|
398
413
|
const input = ens || address;
|
|
399
414
|
const identity = useThurinIdentity(input);
|
|
@@ -420,14 +435,7 @@ function ThurinCard({ ens, address, theme = "thurin" }) {
|
|
|
420
435
|
const hasVerifiedPgp = identity.claims.some((c) => _optionalChain([c, 'access', _19 => _19.verification, 'optionalAccess', _20 => _20.verified]) && !c.revoked);
|
|
421
436
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "thurin-card", "data-thurin-theme": theme, children: [
|
|
422
437
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "a", { className: "thurin-card-header", href: profileUrl || void 0, target: "_blank", rel: "noopener noreferrer", children: [
|
|
423
|
-
|
|
424
|
-
"img",
|
|
425
|
-
{
|
|
426
|
-
className: "thurin-card-avatar",
|
|
427
|
-
src: identity.ensAvatar,
|
|
428
|
-
alt: identity.ensName || ""
|
|
429
|
-
}
|
|
430
|
-
) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ThurinLogo, {}),
|
|
438
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, Avatar, { src: identity.ensAvatar, alt: identity.ensName || "" }),
|
|
431
439
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
|
|
432
440
|
identity.ensName && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "thurin-card-name", children: identity.ensName }),
|
|
433
441
|
displayAddress && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "thurin-card-address", children: displayAddress })
|
|
@@ -483,15 +491,15 @@ function safeNormalize2(name) {
|
|
|
483
491
|
}
|
|
484
492
|
}
|
|
485
493
|
function useEnsHint(name, verifiedFingerprint) {
|
|
486
|
-
const chain =
|
|
494
|
+
const chain = _chunkOIE72R6Jcjs.chainFor.call(void 0, useIdentityKitConfig().network);
|
|
487
495
|
const ensName = name ? safeNormalize2(name) : void 0;
|
|
488
496
|
const { data, isLoading, refetch } = _wagmi.useEnsText.call(void 0, {
|
|
489
497
|
name: ensName,
|
|
490
|
-
key:
|
|
498
|
+
key: _chunkOIE72R6Jcjs.ENS_HINT_KEY,
|
|
491
499
|
chainId: chain.id,
|
|
492
500
|
query: { enabled: !!ensName }
|
|
493
501
|
});
|
|
494
|
-
return { ...
|
|
502
|
+
return { ..._chunkOIE72R6Jcjs.ensHintFor.call(void 0, _nullishCoalesce(data, () => ( null)), verifiedFingerprint), isLoading: !!ensName && isLoading, refetch: () => {
|
|
495
503
|
void refetch();
|
|
496
504
|
} };
|
|
497
505
|
}
|
|
@@ -499,20 +507,20 @@ function useEnsHint(name, verifiedFingerprint) {
|
|
|
499
507
|
// src/hooks/useRecords.ts
|
|
500
508
|
|
|
501
509
|
|
|
502
|
-
function useRecords(address, index, kinds =
|
|
510
|
+
function useRecords(address, index, kinds = _chunkOIE72R6Jcjs.IDENTITY_KINDS, armoredKey) {
|
|
503
511
|
const config = useIdentityKitConfig();
|
|
504
|
-
const registry =
|
|
505
|
-
const chain =
|
|
512
|
+
const registry = _chunkOIE72R6Jcjs.getRegistry.call(void 0, config.network, config.registryAddress);
|
|
513
|
+
const chain = _chunkOIE72R6Jcjs.chainFor.call(void 0, config.network);
|
|
506
514
|
const owner = address;
|
|
507
515
|
const enabled = !!owner && index !== void 0 && index !== null;
|
|
508
|
-
const contracts = enabled ? kinds.map((kind) => ({ address: registry.address, abi:
|
|
516
|
+
const contracts = enabled ? kinds.map((kind) => ({ address: registry.address, abi: _chunkOIE72R6Jcjs.REGISTRY_ABI, functionName: "record", args: [owner, BigInt(index), _chunkOIE72R6Jcjs.recordKind.call(void 0, kind)], chainId: chain.id })) : [];
|
|
509
517
|
const { data: raw, isLoading: readLoading, refetch } = _wagmi.useReadContracts.call(void 0, { contracts, query: { enabled: contracts.length > 0 } });
|
|
510
|
-
const texts = (_nullishCoalesce(raw, () => ( []))).map((r) => r.status === "success" ?
|
|
518
|
+
const texts = (_nullishCoalesce(raw, () => ( []))).map((r) => r.status === "success" ? _chunkOIE72R6Jcjs.decodeRecord.call(void 0, r.result) : "");
|
|
511
519
|
const { data: records, isLoading: parseLoading } = _reactquery.useQuery.call(void 0, {
|
|
512
520
|
queryKey: ["records", config.network, registry.address, address, index, kinds.join(","), texts.join(" "), _nullishCoalesce(armoredKey, () => ( ""))],
|
|
513
521
|
queryFn: async () => {
|
|
514
522
|
const out = [];
|
|
515
|
-
for (let i = 0; i < kinds.length; i++) if (texts[i]) out.push(await
|
|
523
|
+
for (let i = 0; i < kinds.length; i++) if (texts[i]) out.push(await _chunkOIE72R6Jcjs.parseRecord.call(void 0, kinds[i], texts[i], { armoredKey: _nullishCoalesce(armoredKey, () => ( void 0)) }));
|
|
516
524
|
return out;
|
|
517
525
|
},
|
|
518
526
|
enabled: enabled && raw !== void 0
|
|
@@ -591,5 +599,8 @@ function useRecords(address, index, kinds = _chunkYTO7Z5SIcjs.IDENTITY_KINDS, ar
|
|
|
591
599
|
|
|
592
600
|
|
|
593
601
|
|
|
594
|
-
|
|
602
|
+
|
|
603
|
+
|
|
604
|
+
|
|
605
|
+
exports.ARWEAVE_GATEWAY = _chunkOIE72R6Jcjs.ARWEAVE_GATEWAY; exports.AUTHORIZATION_TYPES = _chunkOIE72R6Jcjs.AUTHORIZATION_TYPES; exports.EIP712_NAME = _chunkOIE72R6Jcjs.EIP712_NAME; exports.EIP712_VERSION = _chunkOIE72R6Jcjs.EIP712_VERSION; exports.ENS_HINT_KEY = _chunkOIE72R6Jcjs.ENS_HINT_KEY; exports.ENS_TEXT_RESOLVER_ABI = _chunkOIE72R6Jcjs.ENS_TEXT_RESOLVER_ABI; exports.FARCASTER_HUB = _chunkOIE72R6Jcjs.FARCASTER_HUB; exports.IDENTITY_ERROR_TEXT = _chunkOIE72R6Jcjs.IDENTITY_ERROR_TEXT; exports.IDENTITY_KINDS = _chunkOIE72R6Jcjs.IDENTITY_KINDS; exports.IPFS_GATEWAY = _chunkOIE72R6Jcjs.IPFS_GATEWAY; exports.IPFS_GATEWAYS = _chunkOIE72R6Jcjs.IPFS_GATEWAYS; exports.IdentityKitProvider = IdentityKitProvider; exports.KNOWN_KINDS = _chunkOIE72R6Jcjs.KNOWN_KINDS; exports.MAX_RECORD_BYTES = _chunkOIE72R6Jcjs.MAX_RECORD_BYTES; exports.NETWORKS = _chunkOIE72R6Jcjs.NETWORKS; exports.NFT_AVATAR_ABI = _chunkOIE72R6Jcjs.NFT_AVATAR_ABI; exports.REGISTRY_ABI = _chunkOIE72R6Jcjs.REGISTRY_ABI; exports.REGISTRY_ADDRESS = _chunkOIE72R6Jcjs.REGISTRY_ADDRESS; exports.ThurinCard = ThurinCard; exports.addPointer = _chunkOIE72R6Jcjs.addPointer; exports.attestTypedData = _chunkOIE72R6Jcjs.attestTypedData; exports.authorizationDigest = _chunkOIE72R6Jcjs.authorizationDigest; exports.avatarFallbacks = _chunkOIE72R6Jcjs.avatarFallbacks; exports.avatarUrl = _chunkOIE72R6Jcjs.avatarUrl; exports.bytesToFingerprint = _chunkOIE72R6Jcjs.bytesToFingerprint; exports.chainFor = _chunkOIE72R6Jcjs.chainFor; exports.decodeRecord = _chunkOIE72R6Jcjs.decodeRecord; exports.displayUrl = _chunkOIE72R6Jcjs.displayUrl; exports.encodeRecord = _chunkOIE72R6Jcjs.encodeRecord; exports.ensHintFor = _chunkOIE72R6Jcjs.ensHintFor; exports.ensHintValue = _chunkOIE72R6Jcjs.ensHintValue; exports.ensHintWrite = _chunkOIE72R6Jcjs.ensHintWrite; exports.fetchEFPGraph = _chunkOIE72R6Jcjs.fetchEFPGraph; exports.fetchEnsHint = _chunkOIE72R6Jcjs.fetchEnsHint; exports.fetchRecords = _chunkOIE72R6Jcjs.fetchRecords; exports.fingerprintHash = _chunkOIE72R6Jcjs.fingerprintHash; exports.fingerprintToBytes = _chunkOIE72R6Jcjs.fingerprintToBytes; exports.getRegistry = _chunkOIE72R6Jcjs.getRegistry; exports.hasEmailUserID = _chunkOIE72R6Jcjs.hasEmailUserID; exports.identifyProof = _chunkOIE72R6Jcjs.identifyProof; exports.identityErrorKind = _chunkOIE72R6Jcjs.identityErrorKind; exports.isNetworkName = _chunkOIE72R6Jcjs.isNetworkName; exports.keyIdOf = _chunkOIE72R6Jcjs.keyIdOf; exports.keyIdToBytes = _chunkOIE72R6Jcjs.keyIdToBytes; exports.kindName = _chunkOIE72R6Jcjs.kindName; exports.needsRpcProbe = _chunkOIE72R6Jcjs.needsRpcProbe; exports.nftAvatarImage = _chunkOIE72R6Jcjs.nftAvatarImage; exports.normalizeFingerprint = _chunkOIE72R6Jcjs.normalizeFingerprint; exports.parseNftAvatar = _chunkOIE72R6Jcjs.parseNftAvatar; exports.parsePgpKey = _chunkOIE72R6Jcjs.parsePgpKey; exports.parsePointer = _chunkOIE72R6Jcjs.parsePointer; exports.parseRecord = _chunkOIE72R6Jcjs.parseRecord; exports.proofHref = _chunkOIE72R6Jcjs.proofHref; exports.proofSecondaryHref = _chunkOIE72R6Jcjs.proofSecondaryHref; exports.reattestTypedData = _chunkOIE72R6Jcjs.reattestTypedData; exports.recordKind = _chunkOIE72R6Jcjs.recordKind; exports.registryDomain = _chunkOIE72R6Jcjs.registryDomain; exports.renderPointer = _chunkOIE72R6Jcjs.renderPointer; exports.revokeTypedData = _chunkOIE72R6Jcjs.revokeTypedData; exports.setRecordTypedData = _chunkOIE72R6Jcjs.setRecordTypedData; exports.stripEmailUserIDs = _chunkOIE72R6Jcjs.stripEmailUserIDs; exports.updateKeyTypedData = _chunkOIE72R6Jcjs.updateKeyTypedData; exports.useAttestations = useAttestations; exports.useEFPGraph = useEFPGraph; exports.useEnsHint = useEnsHint; exports.usePGPProofs = usePGPProofs; exports.useRecords = useRecords; exports.useSafeAvatar = useSafeAvatar; exports.useThurinIdentity = useThurinIdentity; exports.verifyAttestation = _chunkOIE72R6Jcjs.verifyAttestation; exports.verifyClearsigned = _chunkOIE72R6Jcjs.verifyClearsigned; exports.verifyProof = _chunkOIE72R6Jcjs.verifyProof;
|
|
595
606
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/ben/code/thurinlabs/identity-kit/dist/index.cjs","../src/provider.tsx","../src/context.ts","../src/hooks/useThurinIdentity.ts","../src/hooks/useAttestations.ts","../src/hooks/useEFPGraph.ts","../src/hooks/usePGPProofs.ts","../src/hooks/useSafeAvatar.ts","../src/components/ThurinCard/ThurinCard.tsx","../src/hooks/useEnsHint.ts","../src/hooks/useRecords.ts"],"names":["useQuery","jsx","safeNormalize","normalize"],"mappings":"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,MAAA;AACA,sBAAA;AACE,wBAAA;AAIA,wBAAA;AACF,MAAA;AACF,IAAA;AAEA,oBAAA;AACG,MAAA;AAGc,sBAAA;AAGL,MAAA;AACP,QAAA;AAAA,QAAA;AAEY,UAAA;AAEV,UAAA;AAAE,QAAA;AAHE,QAAA;AAKR,MAAA;AACH,IAAA;AAGE,IAAA;AAAC,MAAA;AAAA,MAAA;AACW,QAAA;AACJ,QAAA;AACC,QAAA;AACH,QAAA;AACL,QAAA;AAAA,MAAA;AAED,IAAA;AAEJ,EAAA;AAEJ;AR6UqB;AACA;AS1dZ;AACA;AAKAC;AACH,EAAA;AAASC,IAAAA;AAAwB,EAAA;AAAS,IAAA;AAAU,EAAA;AAC1D;AAO2B;AACX,EAAA;AACE,EAAA;AACF,EAAA;AACN,IAAA;AACD,IAAA;AACU,IAAA;AACN,IAAA;AACV,EAAA;AACW,EAAA;AAAgH,IAAA;AAAI,EAAA;AAClI;ATwdqB;AACA;AUlfZ;AACAH;AAUkB;AACV,EAAA;AACE,EAAA;AACH,EAAA;AACA,EAAA;AACI,EAAA;AAEA,EAAA;AAGC,EAAA;AAEJ,EAAA;AACD,EAAA;AACD,IAAA;AACF,IAAA;AACsB,MAAA;AAChB,MAAA;AACN,MAAA;AACT,IAAA;AACS,IAAA;AACV,EAAA;AAEiB,EAAA;AAAkG,IAAA;AAAI,EAAA;AAC1H;AVweqB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/ben/code/thurinlabs/identity-kit/dist/index.cjs","sourcesContent":[null,"import { type ReactNode, useMemo } from 'react'\nimport { WagmiProvider, createConfig, http, useConfig } from 'wagmi'\nimport { mainnet, sepolia, foundry } from 'wagmi/chains'\nimport { getRegistry } from './core/contract'\nimport type { NetworkName } from './core/contract'\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query'\nimport { IdentityKitContext } from './context'\nimport type { IdentityKitConfig } from './core/types'\n\nconst defaultQueryClient = new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 60_000,\n retry: 1,\n },\n },\n})\n\nexport { chainFor } from './core/contract'\n\nfunction createDefaultWagmiConfig(rpcUrl: string | undefined, network: NetworkName) {\n const url = rpcUrl || getRegistry(network).defaultRpcUrl\n // Spelled out per network: wagmi types `transports` by the exact chain ids.\n if (network === 'sepolia') return createConfig({ chains: [sepolia], transports: { [sepolia.id]: http(url) } })\n if (network === 'local') return createConfig({ chains: [foundry], transports: { [foundry.id]: http(url) } })\n return createConfig({ chains: [mainnet], transports: { [mainnet.id]: http(url) } })\n}\n\nfunction WagmiDetector({ children, rpcUrl, network }: { children: ReactNode; rpcUrl?: string; network: NetworkName }) {\n // Try to use existing wagmi config\n let hasWagmi = false\n try {\n useConfig()\n hasWagmi = true\n } catch {\n // No WagmiProvider above us\n }\n\n const wagmiConfig = useMemo(() => createDefaultWagmiConfig(rpcUrl, network), [rpcUrl, network])\n\n if (hasWagmi) {\n return <>{children}</>\n }\n\n return (\n <WagmiProvider config={wagmiConfig}>\n <QueryClientProvider client={defaultQueryClient}>\n {children}\n </QueryClientProvider>\n </WagmiProvider>\n )\n}\n\nexport interface IdentityKitProviderProps extends IdentityKitConfig {\n children: ReactNode\n}\n\nexport function IdentityKitProvider({\n children,\n rpcUrl,\n neynarApiKey,\n baseUrl = 'https://thurin.id',\n network = 'mainnet',\n registryAddress,\n}: IdentityKitProviderProps) {\n const config = useMemo(\n () => ({ rpcUrl, neynarApiKey, baseUrl, network, registryAddress }),\n [rpcUrl, neynarApiKey, baseUrl, network, registryAddress],\n )\n\n return (\n <IdentityKitContext.Provider value={config}>\n <WagmiDetector rpcUrl={rpcUrl} network={network}>\n {children}\n </WagmiDetector>\n </IdentityKitContext.Provider>\n )\n}\n","import { createContext, useContext } from 'react'\nimport type { IdentityKitConfig } from './core/types'\n\nconst defaultConfig: IdentityKitConfig = {\n baseUrl: 'https://thurin.id',\n network: 'mainnet',\n}\n\nexport const IdentityKitContext = createContext<IdentityKitConfig>(defaultConfig)\n\nexport function useIdentityKitConfig(): IdentityKitConfig {\n return useContext(IdentityKitContext)\n}\n","import { useBlockNumber, useEnsAddress, useEnsName } from 'wagmi'\nimport { identityErrorKind, needsRpcProbe, IDENTITY_ERROR_TEXT } from '../core/identityError'\nimport { useIdentityKitConfig } from '../context'\nimport { chainFor } from '../provider'\nimport { normalize } from 'viem/ens'\nimport { useAttestations } from './useAttestations'\nimport { useEFPGraph } from './useEFPGraph'\nimport { usePGPProofs } from './usePGPProofs'\nimport { useSafeAvatar } from './useSafeAvatar'\nimport type { ThurinIdentity } from '../core/types'\n\nfunction isAddress(value: string): boolean {\n return /^0x[0-9a-fA-F]{40}$/.test(value)\n}\n\nfunction safeNormalize(name: string): string | undefined {\n try {\n return normalize(name)\n } catch {\n return undefined\n }\n}\n\nexport function useThurinIdentity(ensOrAddress: string | undefined | null): ThurinIdentity {\n const chain = chainFor(useIdentityKitConfig().network)\n const isAddr = ensOrAddress ? isAddress(ensOrAddress) : false\n const ensInput = ensOrAddress && !isAddr ? safeNormalize(ensOrAddress) : undefined\n\n // Resolve ENS → address\n const { data: resolvedAddress, error: ensError, isFetched: ensFetched, refetch: refetchEns } = useEnsAddress({\n name: ensInput,\n chainId: chain.id,\n query: { enabled: !!ensInput },\n })\n\n const address = isAddr ? ensOrAddress! : resolvedAddress ?? null\n\n // Reverse resolve address → ENS\n const { data: ensName } = useEnsName({\n address: address as `0x${string}` | undefined,\n chainId: chain.id,\n query: { enabled: !!address },\n })\n\n const displayName = ensInput || ensName || null\n\n const ensAvatar = useSafeAvatar(displayName ? safeNormalize(displayName) : undefined, chain.id)\n\n // On-chain attestations\n const {\n claims,\n totalClaims,\n activeClaims,\n currentFingerprint,\n isLoading: claimsLoading,\n error: claimsError,\n refetch: refetchClaims,\n } = useAttestations(address)\n\n // PGP proofs come from the key stored in the current attestation — the\n // latest claim that is active and whose signature verified (the same rule\n // useAttestations uses to pick currentFingerprint).\n const currentClaim = [...claims].reverse().find(\n (c) => !c.revoked && c.verification?.verified && c.fingerprint === currentFingerprint,\n )\n const {\n keyInfo: pgpKeyInfo,\n proofs,\n isLoading: proofsLoading,\n } = usePGPProofs(currentFingerprint, currentClaim?.pgpPublicKey ?? null)\n\n // EFP social graph\n const { efp, isLoading: efpLoading } = useEFPGraph(address)\n\n // An empty ENS result or a failed read might just be a dead RPC; ask it for the block\n // number before saying anything about the identity (core/identityError.ts).\n const lookup = { ensEmpty: !!ensInput && ensFetched && !resolvedAddress, ensFailed: !!ensError, claimsFailed: !!claimsError }\n const probeNeeded = needsRpcProbe(lookup)\n // useBlockNumber, not usePublicClient: the latter attaches every public action to the client,\n // which put ~360 KB more into the standalone embed (1.3.4). Own scope per identity and no\n // caching, so an earlier answer can't make a dead RPC look alive.\n const probe = useBlockNumber({\n chainId: chain.id,\n scopeKey: `thurin-rpc-probe:${ensOrAddress ?? ''}`,\n query: { enabled: probeNeeded, retry: 0, staleTime: 0, gcTime: 0 },\n })\n const rpcAnswered = !probeNeeded || probe.isFetching ? undefined : probe.isSuccess ? true : probe.isError ? false : undefined\n const errorKind = identityErrorKind({ ...lookup, rpcAnswered })\n const probing = probeNeeded && rpcAnswered === undefined\n const retry = () => {\n if (ensInput) refetchEns()\n refetchClaims()\n if (probeNeeded) probe.refetch()\n }\n\n return {\n address,\n ensName: displayName,\n ensAvatar,\n claims,\n totalClaims,\n activeClaims,\n currentFingerprint,\n pgpKeyInfo,\n proofs,\n efp,\n // \"Not finished\" counts as loading, including queries paused in a background tab: the card\n // must not render defaults (zeros) for an identity it hasn't looked up yet.\n isLoading: (!!ensInput && !ensFetched) || claimsLoading || proofsLoading || efpLoading || probing,\n error: errorKind ? new Error(IDENTITY_ERROR_TEXT[errorKind]) : null,\n errorKind,\n retry,\n }\n}\n","import { useReadContract, useReadContracts } from 'wagmi'\nimport { useQuery } from '@tanstack/react-query'\nimport { hexToString } from 'viem'\nimport { REGISTRY_ABI, getRegistry } from '../core/contract'\nimport { bytesToFingerprint } from '../core/fingerprint'\nimport { chainFor } from '../provider'\nimport { verifyAttestation } from '../core/pgp'\nimport { useIdentityKitConfig } from '../context'\nimport type { Attestation } from '../core/types'\n\n/**\n * On-chain attestations for an address, read straight from the v2 registry:\n * `attestationsOf` for the history, `getPayload` for each stored signature + key.\n * No event logs, so any RPC works. Each claim is verified off-chain.\n */\nexport function useAttestations(address: string | undefined | null) {\n const config = useIdentityKitConfig()\n const registry = getRegistry(config.network, config.registryAddress)\n const chain = chainFor(config.network)\n const owner = address as `0x${string}` | undefined\n\n const { data: rows, isLoading: rowsLoading, isFetched: rowsFetched, error: rowsError, refetch: refetchRows } = useReadContract({\n address: registry.address,\n abi: REGISTRY_ABI,\n functionName: 'attestationsOf',\n args: owner ? [owner] : undefined,\n chainId: chain.id,\n query: { enabled: !!owner },\n })\n\n const count = rows?.length ?? 0\n\n const contracts = owner && rows\n ? rows.map((_, i) => ({\n address: registry.address,\n abi: REGISTRY_ABI,\n functionName: 'getPayload' as const,\n args: [owner, BigInt(i)] as const,\n chainId: chain.id,\n }))\n : []\n\n const { data: payloads, isLoading: payloadsLoading, error: payloadsError, refetch: refetchPayloads } = useReadContracts({\n contracts,\n query: { enabled: contracts.length > 0 },\n })\n\n const payloadsReady = count === 0 || (payloads !== undefined && payloads.length === count)\n\n const { data: claims, isLoading: verifyLoading } = useQuery({\n queryKey: ['attestations', config.network, registry.address, address, count, payloadsReady],\n queryFn: async (): Promise<Attestation[]> => {\n if (!rows || !address) return []\n const results: Attestation[] = []\n\n for (let i = 0; i < rows.length; i++) {\n const row = rows[i]\n const payload = payloads?.[i]\n let pgpSignature: string | null = null\n let pgpPublicKey: string | null = null\n if (payload && payload.status === 'success') {\n const [sigHex, keyHex] = payload.result as readonly [`0x${string}`, `0x${string}`]\n pgpSignature = hexToString(sigHex)\n pgpPublicKey = hexToString(keyHex)\n }\n\n const fingerprint = bytesToFingerprint(row.fingerprint)\n const verification = pgpPublicKey && pgpSignature\n ? await verifyAttestation({ pgpPublicKey, pgpSignature, fingerprint, ethAddress: address })\n : null\n\n const revokedAt = Number(row.revokedAt)\n results.push({\n index: i,\n fingerprint,\n createdAt: Number(row.createdAt),\n revoked: revokedAt !== 0,\n revokedAt: revokedAt === 0 ? null : revokedAt,\n messageVersion: Number(row.messageVersion),\n pgpSignature,\n pgpPublicKey,\n verification,\n })\n }\n return results\n },\n enabled: !!rows && payloadsReady,\n staleTime: 300_000,\n })\n\n // Not fetched yet counts as loading (a paused query in a background tab is not \"no claims\").\n const isLoading = rowsLoading || (!!owner && !rowsFetched) || payloadsLoading || verifyLoading || (!!owner && rows !== undefined && !payloadsReady)\n\n const activeClaims = (claims || []).filter((c) => !c.revoked)\n // The current identity is the latest claim that is both active and has a\n // verified signature binding the key to this address. A claim whose signature\n // has not verified must not surface the key's proofs or user data.\n const verifiedClaims = activeClaims.filter((c) => c.verification?.verified)\n const currentFingerprint = verifiedClaims.length > 0\n ? verifiedClaims[verifiedClaims.length - 1].fingerprint\n : null\n\n return {\n claims: claims || [],\n totalClaims: count,\n activeClaims: activeClaims.length,\n currentFingerprint,\n isLoading,\n /** A registry read failed (the RPC may be down; useThurinIdentity finds out which). */\n error: (rowsError ?? payloadsError ?? null) as Error | null,\n refetch: () => { if (owner) { refetchRows(); if (contracts.length > 0) refetchPayloads() } },\n }\n}\n","import { useQuery } from '@tanstack/react-query'\nimport { fetchEFPGraph } from '../core/efp'\nimport type { EFPGraph } from '../core/types'\n\nexport function useEFPGraph(address: string | undefined | null) {\n const { data, isLoading } = useQuery<EFPGraph | null>({\n queryKey: ['efp-graph', address],\n queryFn: () => fetchEFPGraph(address!),\n enabled: !!address,\n staleTime: 300_000,\n })\n\n return {\n efp: data ?? null,\n isLoading,\n }\n}\n","import { useQuery } from '@tanstack/react-query'\nimport { parsePgpKey } from '../core/pgp'\nimport { identifyProof, verifyProof, displayUrl, proofHref, proofSecondaryHref } from '../core/proofs'\nimport { useIdentityKitConfig } from '../context'\nimport type { PGPKeyInfo, ProofResult } from '../core/types'\n\n/**\n * Proofs for an identity, read from the PGP key stored in its on-chain\n * attestation. No keyserver is consulted: keys.openpgp.org only serves user\n * IDs whose email is verified and drops non-email user IDs entirely, so it can\n * never carry the published (non-email) identity that holds the notations.\n *\n * @param fingerprint the attested fingerprint (proofs must name it)\n * @param armoredKey the attestation's `pgpPublicKey`\n */\nexport function usePGPProofs(fingerprint: string | undefined | null, armoredKey: string | undefined | null) {\n const config = useIdentityKitConfig()\n\n const { data } = useQuery({\n // The key is large; key the query on its length + fingerprint, which\n // changes whenever a different attestation's key is supplied.\n queryKey: ['pgp-proofs', fingerprint, armoredKey?.length ?? 0],\n queryFn: async (): Promise<{ keyInfo: PGPKeyInfo | null; proofs: ProofResult[] }> => {\n if (!fingerprint || !armoredKey) return { keyInfo: null, proofs: [] }\n\n const keyInfo = await parsePgpKey(armoredKey)\n if (!keyInfo) return { keyInfo: null, proofs: [] }\n\n // Identify proofs from notations. Drop unrecognized targets (provider\n // 'unknown') so the card doesn't render \"Unknown\" badges for platforms\n // Thurin has no verifier for — matching the explorer's behavior.\n const identified = keyInfo.notations\n .map((n) => identifyProof(n))\n .filter((p): p is NonNullable<typeof p> => p !== null && p.provider !== 'unknown')\n\n // Verify all proofs in parallel\n const proofs: ProofResult[] = await Promise.all(\n identified.map(async (proof) => {\n const result = await verifyProof(proof, fingerprint, config.neynarApiKey)\n return {\n provider: proof.provider,\n label: proof.label,\n url: proof.url,\n displayUrl: displayUrl(proof),\n href: proofHref(proof),\n secondaryHref: proofSecondaryHref(proof),\n status: result.verified ? 'verified' as const : 'unverified' as const,\n reason: result.reason,\n }\n }),\n )\n\n // Collapse proofs that resolve to the same account — the same target is\n // often listed under both proof@thurin.id and proof@ariadne.id (and can\n // be reached via more than one proof URL). Key by provider + display\n // identity, preferring a verified result.\n const byAccount = new Map<string, ProofResult>()\n for (const p of proofs) {\n const key = `${p.provider}:${p.displayUrl}`\n const prev = byAccount.get(key)\n if (!prev || (p.status === 'verified' && prev.status !== 'verified')) {\n byAccount.set(key, p)\n }\n }\n\n return { keyInfo, proofs: [...byAccount.values()] }\n },\n enabled: !!fingerprint && !!armoredKey,\n staleTime: 300_000,\n })\n\n return {\n keyInfo: data?.keyInfo ?? null,\n proofs: data?.proofs ?? [],\n // Report loading whenever a fingerprint is set but its proofs haven't\n // resolved yet. Using react-query's own isLoading leaves a gap while the\n // query is enabling (fingerprint just became known), during which the card\n // would briefly paint without proof badges and then pop them in.\n isLoading: !!fingerprint && !!armoredKey && data === undefined,\n }\n}\n","import { useEnsText, useReadContract } from 'wagmi'\nimport { useQuery } from '@tanstack/react-query'\nimport { avatarUrl, parseNftAvatar, nftAvatarImage, NFT_AVATAR_ABI } from '../core/avatar'\n\n/**\n * The avatar to show for a normalized ENS name, or null. Reads the raw `avatar` record and\n * loads only what `avatarUrl` allows (see core/avatar.ts); wagmi's useEnsAvatar would fetch\n * whatever host the name's owner chose.\n */\nexport function useSafeAvatar(name: string | undefined, chainId: number): string | null {\n const { data: raw } = useEnsText({ name, key: 'avatar', chainId, query: { enabled: !!name } })\n const direct = avatarUrl(raw)\n const nft = direct ? null : parseNftAvatar(raw)\n const { data: tokenUri } = useReadContract({\n address: nft?.contract,\n abi: NFT_AVATAR_ABI,\n functionName: nft?.standard === 'erc1155' ? 'uri' : 'tokenURI',\n args: nft ? [nft.tokenId] : undefined,\n chainId,\n query: { enabled: !!nft && nft.chainId === chainId },\n })\n const { data: image } = useQuery({\n queryKey: ['thurin-nft-avatar', tokenUri, nft?.tokenId.toString()],\n queryFn: () => nftAvatarImage(tokenUri as string, nft!.tokenId).catch(() => null),\n enabled: typeof tokenUri === 'string' && !!nft,\n })\n return direct ?? image ?? null\n}\n","import { useThurinIdentity } from '../../hooks/useThurinIdentity'\nimport { useIdentityKitConfig } from '../../context'\nimport type { Theme } from '../../core/types'\nimport '../../themes/index.css'\nimport './ThurinCard.css'\n\nfunction ThurinLogo() {\n return (\n <svg className=\"thurin-card-avatar-placeholder\" viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"50\" cy=\"50\" r=\"50\" fill=\"var(--thurin-surface-deep)\" />\n <path d=\"M25 80 Q25 25 50 25 Q75 25 75 50\" fill=\"none\" stroke=\"#7c9a3e\" strokeWidth=\"4\" strokeLinecap=\"round\"/>\n <path d=\"M33 75 Q33 35 50 35 Q67 35 67 52\" fill=\"none\" stroke=\"#7c9a3e\" strokeWidth=\"4\" strokeLinecap=\"round\"/>\n <path d=\"M41 70 Q41 45 50 45 Q59 45 59 55\" fill=\"none\" stroke=\"#c9a227\" strokeWidth=\"4\" strokeLinecap=\"round\"/>\n <path d=\"M50 65 L50 53\" fill=\"none\" stroke=\"#c9a227\" strokeWidth=\"4\" strokeLinecap=\"round\"/>\n </svg>\n )\n}\n\nexport interface ThurinCardProps {\n ens?: string\n address?: string\n theme?: Theme\n}\n\nexport function ThurinCard({ ens, address, theme = 'thurin' }: ThurinCardProps) {\n const input = ens || address\n const identity = useThurinIdentity(input)\n const config = useIdentityKitConfig()\n\n const profileUrl = identity.address\n ? `${config.baseUrl}/eth/${identity.address}`\n : ens\n ? `${config.baseUrl}/ens/${ens}`\n : null\n\n if (identity.isLoading) {\n return (\n <div className=\"thurin-card\" data-thurin-theme={theme}>\n <div className=\"thurin-card-loading\">Loading identity...</div>\n </div>\n )\n }\n\n const displayAddress = identity.address || null\n\n // A failed lookup says so, instead of rendering zeros that read as facts.\n if (identity.errorKind) {\n return (\n <div className=\"thurin-card\" data-thurin-theme={theme}>\n <div className=\"thurin-card-header\">\n <ThurinLogo />\n <div>\n <div className=\"thurin-card-name\">{identity.ensName || ens || address}</div>\n </div>\n </div>\n <div className=\"thurin-card-error\" role=\"status\">\n {identity.error?.message}\n {identity.errorKind !== 'not-found' && (\n <button type=\"button\" className=\"thurin-card-retry\" onClick={identity.retry}>Try again</button>\n )}\n </div>\n {profileUrl && identity.errorKind !== 'not-found' && (\n <a className=\"thurin-card-link\" href={profileUrl} target=\"_blank\" rel=\"noopener noreferrer\">View on Thurin</a>\n )}\n </div>\n )\n }\n\n const verifiedProofs = identity.proofs.filter((p) => p.status === 'verified').length\n const hasVerifiedPgp = identity.claims.some((c) => c.verification?.verified && !c.revoked)\n\n return (\n <div className=\"thurin-card\" data-thurin-theme={theme}>\n <a className=\"thurin-card-header\" href={profileUrl || undefined} target=\"_blank\" rel=\"noopener noreferrer\">\n {identity.ensAvatar ? (\n <img\n className=\"thurin-card-avatar\"\n src={identity.ensAvatar}\n alt={identity.ensName || ''}\n />\n ) : (\n <ThurinLogo />\n )}\n <div>\n {identity.ensName && (\n <div className=\"thurin-card-name\">{identity.ensName}</div>\n )}\n {displayAddress && (\n <div className=\"thurin-card-address\">{displayAddress}</div>\n )}\n </div>\n </a>\n\n <div className=\"thurin-card-stats\">\n <div className=\"thurin-card-stat\">\n <span className=\"thurin-card-stat-value\">{identity.activeClaims}</span>\n <span className=\"thurin-card-stat-label\">Attestations</span>\n </div>\n <div className=\"thurin-card-stat\">\n <span className=\"thurin-card-stat-value\">{verifiedProofs}</span>\n <span className=\"thurin-card-stat-label\">Proofs</span>\n </div>\n <div className=\"thurin-card-stat\">\n <span className=\"thurin-card-stat-value\">\n {/* EFP answers separately; a null graph means it didn't, so don't claim zero. */}\n {identity.efp ? identity.efp.followers : '–'}\n </span>\n <span className=\"thurin-card-stat-label\">Followers</span>\n </div>\n </div>\n\n <div className=\"thurin-card-badges\">\n {hasVerifiedPgp && (\n <span className=\"thurin-card-badge thurin-card-badge--verified\">PGP Verified</span>\n )}\n {identity.efp?.hasEfp && (\n <span className=\"thurin-card-badge thurin-card-badge--verified\">EFP</span>\n )}\n {identity.proofs.map((p, i) => (\n <span\n key={i}\n className={`thurin-card-badge thurin-card-badge--${p.status === 'verified' ? 'verified' : 'unverified'}`}\n >\n {p.label}\n </span>\n ))}\n </div>\n\n {profileUrl && (\n <a\n className=\"thurin-card-link\"\n href={profileUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n View on Thurin\n </a>\n )}\n </div>\n )\n}\n","import { useEnsText } from 'wagmi'\nimport { normalize } from 'viem/ens'\nimport { useIdentityKitConfig } from '../context'\nimport { chainFor } from '../provider'\nimport { ENS_HINT_KEY, ensHintFor, type EnsHint } from '../core/ensHint'\n\nfunction safeNormalize(name: string): string | undefined {\n try { return normalize(name) } catch { return undefined }\n}\n\n/**\n * A name's `id.thurin` record against the fingerprint the registry verifies for its\n * address. `state` is `match`, `unset`, or `mismatch`; the last one is the signal worth\n * showing — a name advertising a key its address has not claimed.\n */\nexport function useEnsHint(name: string | undefined | null, verifiedFingerprint: string | null | undefined): EnsHint & { isLoading: boolean; refetch: () => void } {\n const chain = chainFor(useIdentityKitConfig().network)\n const ensName = name ? safeNormalize(name) : undefined\n const { data, isLoading, refetch } = useEnsText({\n name: ensName,\n key: ENS_HINT_KEY,\n chainId: chain.id,\n query: { enabled: !!ensName },\n })\n return { ...ensHintFor(data ?? null, verifiedFingerprint), isLoading: !!ensName && isLoading, refetch: () => { void refetch() } }\n}\n","import { useReadContracts } from 'wagmi'\nimport { useQuery } from '@tanstack/react-query'\nimport { REGISTRY_ABI, getRegistry } from '../core/contract'\nimport { chainFor } from '../provider'\nimport { useIdentityKitConfig } from '../context'\nimport { IDENTITY_KINDS, decodeRecord, parseRecord, recordKind, type ParsedRecord } from '../core/records'\n\n/**\n * The records on one claim, for the kinds given (default: the kinds an identity page shows),\n * read in one multicall and parsed. Kinds with no record are left out.\n */\nexport function useRecords(address: string | undefined | null, index: number | undefined | null, kinds: readonly string[] = IDENTITY_KINDS, armoredKey?: string | null) {\n const config = useIdentityKitConfig()\n const registry = getRegistry(config.network, config.registryAddress)\n const chain = chainFor(config.network)\n const owner = address as `0x${string}` | undefined\n const enabled = !!owner && index !== undefined && index !== null\n\n const contracts = enabled\n ? kinds.map(kind => ({ address: registry.address, abi: REGISTRY_ABI, functionName: 'record' as const, args: [owner!, BigInt(index!), recordKind(kind)] as const, chainId: chain.id }))\n : []\n const { data: raw, isLoading: readLoading, refetch } = useReadContracts({ contracts, query: { enabled: contracts.length > 0 } })\n\n const texts = (raw ?? []).map(r => (r.status === 'success' ? decodeRecord(r.result as `0x${string}`) : ''))\n const { data: records, isLoading: parseLoading } = useQuery({\n queryKey: ['records', config.network, registry.address, address, index, kinds.join(','), texts.join(' '), armoredKey ?? ''],\n queryFn: async (): Promise<ParsedRecord[]> => {\n const out: ParsedRecord[] = []\n for (let i = 0; i < kinds.length; i++) if (texts[i]) out.push(await parseRecord(kinds[i], texts[i], { armoredKey: armoredKey ?? undefined }))\n return out\n },\n enabled: enabled && raw !== undefined,\n })\n\n return { records: records ?? [], isLoading: enabled && (readLoading || parseLoading), refetch: () => { void refetch() } }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/ben/code/thurinlabs/identity-kit/dist/index.cjs","../src/provider.tsx","../src/context.ts","../src/components/ThurinCard/ThurinCard.tsx","../src/hooks/useThurinIdentity.ts","../src/hooks/useAttestations.ts","../src/hooks/useEFPGraph.ts","../src/hooks/usePGPProofs.ts","../src/hooks/useSafeAvatar.ts","../src/hooks/useEnsHint.ts","../src/hooks/useRecords.ts"],"names":["useQuery","jsx","safeNormalize","normalize"],"mappings":"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AGT,QAAA;AAGH,MAAA;AACF,IAAA;AAEA,oBAAA;AACE,sBAAA;AACE,wBAAA;AACA,wBAAA;AACF,MAAA;AACA,sBAAA;AACE,wBAAA;AACA,wBAAA;AACF,MAAA;AACA,sBAAA;AACE,wBAAA;AAIA,wBAAA;AACF,MAAA;AACF,IAAA;AAEA,oBAAA;AACG,MAAA;AAGc,sBAAA;AAGL,MAAA;AACP,QAAA;AAAA,QAAA;AAEY,UAAA;AAEV,UAAA;AAAE,QAAA;AAHE,QAAA;AAKR,MAAA;AACH,IAAA;AAGE,IAAA;AAAC,MAAA;AAAA,MAAA;AACW,QAAA;AACJ,QAAA;AACC,QAAA;AACH,QAAA;AACL,QAAA;AAAA,MAAA;AAED,IAAA;AAEJ,EAAA;AAEJ;AHmVqB;AACA;ASleZ;AACA;AAKAC;AACH,EAAA;AAASC,IAAAA;AAAwB,EAAA;AAAS,IAAA;AAAU,EAAA;AAC1D;AAO2B;AACX,EAAA;AACE,EAAA;AACF,EAAA;AACN,IAAA;AACD,IAAA;AACU,IAAA;AACN,IAAA;AACV,EAAA;AACW,EAAA;AAAgH,IAAA;AAAI,EAAA;AAClI;ATgeqB;AACA;AU1fZ;AACAH;AAUkB;AACV,EAAA;AACE,EAAA;AACH,EAAA;AACA,EAAA;AACI,EAAA;AAEA,EAAA;AAGC,EAAA;AAEJ,EAAA;AACD,EAAA;AACD,IAAA;AACF,IAAA;AACsB,MAAA;AAChB,MAAA;AACN,MAAA;AACT,IAAA;AACS,IAAA;AACV,EAAA;AAEiB,EAAA;AAAkG,IAAA;AAAI,EAAA;AAC1H;AVgfqB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/ben/code/thurinlabs/identity-kit/dist/index.cjs","sourcesContent":[null,"import { type ReactNode, useMemo } from 'react'\nimport { WagmiProvider, createConfig, http, useConfig } from 'wagmi'\nimport { mainnet, sepolia, foundry } from 'wagmi/chains'\nimport { getRegistry } from './core/contract'\nimport type { NetworkName } from './core/contract'\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query'\nimport { IdentityKitContext } from './context'\nimport type { IdentityKitConfig } from './core/types'\n\nconst defaultQueryClient = new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 60_000,\n retry: 1,\n },\n },\n})\n\nexport { chainFor } from './core/contract'\n\nfunction createDefaultWagmiConfig(rpcUrl: string | undefined, network: NetworkName) {\n const url = rpcUrl || getRegistry(network).defaultRpcUrl\n // Spelled out per network: wagmi types `transports` by the exact chain ids.\n if (network === 'sepolia') return createConfig({ chains: [sepolia], transports: { [sepolia.id]: http(url) } })\n if (network === 'local') return createConfig({ chains: [foundry], transports: { [foundry.id]: http(url) } })\n return createConfig({ chains: [mainnet], transports: { [mainnet.id]: http(url) } })\n}\n\nfunction WagmiDetector({ children, rpcUrl, network }: { children: ReactNode; rpcUrl?: string; network: NetworkName }) {\n // Try to use existing wagmi config\n let hasWagmi = false\n try {\n useConfig()\n hasWagmi = true\n } catch {\n // No WagmiProvider above us\n }\n\n const wagmiConfig = useMemo(() => createDefaultWagmiConfig(rpcUrl, network), [rpcUrl, network])\n\n if (hasWagmi) {\n return <>{children}</>\n }\n\n return (\n <WagmiProvider config={wagmiConfig}>\n <QueryClientProvider client={defaultQueryClient}>\n {children}\n </QueryClientProvider>\n </WagmiProvider>\n )\n}\n\nexport interface IdentityKitProviderProps extends IdentityKitConfig {\n children: ReactNode\n}\n\nexport function IdentityKitProvider({\n children,\n rpcUrl,\n neynarApiKey,\n farcasterHub,\n baseUrl = 'https://thurin.id',\n network = 'mainnet',\n registryAddress,\n}: IdentityKitProviderProps) {\n const config = useMemo(\n () => ({ rpcUrl, neynarApiKey, farcasterHub, baseUrl, network, registryAddress }),\n [rpcUrl, neynarApiKey, farcasterHub, baseUrl, network, registryAddress],\n )\n\n return (\n <IdentityKitContext.Provider value={config}>\n <WagmiDetector rpcUrl={rpcUrl} network={network}>\n {children}\n </WagmiDetector>\n </IdentityKitContext.Provider>\n )\n}\n","import { createContext, useContext } from 'react'\nimport type { IdentityKitConfig } from './core/types'\n\nconst defaultConfig: IdentityKitConfig = {\n baseUrl: 'https://thurin.id',\n network: 'mainnet',\n}\n\nexport const IdentityKitContext = createContext<IdentityKitConfig>(defaultConfig)\n\nexport function useIdentityKitConfig(): IdentityKitConfig {\n return useContext(IdentityKitContext)\n}\n","import { useEffect, useState } from 'react'\nimport { useThurinIdentity } from '../../hooks/useThurinIdentity'\nimport { avatarFallbacks } from '../../core/avatar'\nimport { useIdentityKitConfig } from '../../context'\nimport type { Theme } from '../../core/types'\nimport '../../themes/index.css'\nimport './ThurinCard.css'\n\nfunction ThurinLogo() {\n return (\n <svg className=\"thurin-card-avatar-placeholder\" viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"50\" cy=\"50\" r=\"50\" fill=\"var(--thurin-surface-deep)\" />\n <path d=\"M25 80 Q25 25 50 25 Q75 25 75 50\" fill=\"none\" stroke=\"#7c9a3e\" strokeWidth=\"4\" strokeLinecap=\"round\"/>\n <path d=\"M33 75 Q33 35 50 35 Q67 35 67 52\" fill=\"none\" stroke=\"#7c9a3e\" strokeWidth=\"4\" strokeLinecap=\"round\"/>\n <path d=\"M41 70 Q41 45 50 45 Q59 45 59 55\" fill=\"none\" stroke=\"#c9a227\" strokeWidth=\"4\" strokeLinecap=\"round\"/>\n <path d=\"M50 65 L50 53\" fill=\"none\" stroke=\"#c9a227\" strokeWidth=\"4\" strokeLinecap=\"round\"/>\n </svg>\n )\n}\n\n// The avatar, retried through the other IPFS gateways if one fails, then the logo.\nfunction Avatar({ src, alt }: { src: string | null; alt: string }) {\n const [tries, setTries] = useState<string[]>([])\n useEffect(() => { setTries(src ? [src, ...avatarFallbacks(src)] : []) }, [src])\n if (!tries.length) return <ThurinLogo />\n return <img className=\"thurin-card-avatar\" src={tries[0]} alt={alt} onError={() => setTries((t) => t.slice(1))} />\n}\n\nexport interface ThurinCardProps {\n ens?: string\n address?: string\n theme?: Theme\n}\n\nexport function ThurinCard({ ens, address, theme = 'thurin' }: ThurinCardProps) {\n const input = ens || address\n const identity = useThurinIdentity(input)\n const config = useIdentityKitConfig()\n\n const profileUrl = identity.address\n ? `${config.baseUrl}/eth/${identity.address}`\n : ens\n ? `${config.baseUrl}/ens/${ens}`\n : null\n\n if (identity.isLoading) {\n return (\n <div className=\"thurin-card\" data-thurin-theme={theme}>\n <div className=\"thurin-card-loading\">Loading identity...</div>\n </div>\n )\n }\n\n const displayAddress = identity.address || null\n\n // A failed lookup says so, instead of rendering zeros that read as facts.\n if (identity.errorKind) {\n return (\n <div className=\"thurin-card\" data-thurin-theme={theme}>\n <div className=\"thurin-card-header\">\n <ThurinLogo />\n <div>\n <div className=\"thurin-card-name\">{identity.ensName || ens || address}</div>\n </div>\n </div>\n <div className=\"thurin-card-error\" role=\"status\">\n {identity.error?.message}\n {identity.errorKind !== 'not-found' && (\n <button type=\"button\" className=\"thurin-card-retry\" onClick={identity.retry}>Try again</button>\n )}\n </div>\n {profileUrl && identity.errorKind !== 'not-found' && (\n <a className=\"thurin-card-link\" href={profileUrl} target=\"_blank\" rel=\"noopener noreferrer\">View on Thurin</a>\n )}\n </div>\n )\n }\n\n const verifiedProofs = identity.proofs.filter((p) => p.status === 'verified').length\n const hasVerifiedPgp = identity.claims.some((c) => c.verification?.verified && !c.revoked)\n\n return (\n <div className=\"thurin-card\" data-thurin-theme={theme}>\n <a className=\"thurin-card-header\" href={profileUrl || undefined} target=\"_blank\" rel=\"noopener noreferrer\">\n <Avatar src={identity.ensAvatar} alt={identity.ensName || ''} />\n <div>\n {identity.ensName && (\n <div className=\"thurin-card-name\">{identity.ensName}</div>\n )}\n {displayAddress && (\n <div className=\"thurin-card-address\">{displayAddress}</div>\n )}\n </div>\n </a>\n\n <div className=\"thurin-card-stats\">\n <div className=\"thurin-card-stat\">\n <span className=\"thurin-card-stat-value\">{identity.activeClaims}</span>\n <span className=\"thurin-card-stat-label\">Attestations</span>\n </div>\n <div className=\"thurin-card-stat\">\n <span className=\"thurin-card-stat-value\">{verifiedProofs}</span>\n <span className=\"thurin-card-stat-label\">Proofs</span>\n </div>\n <div className=\"thurin-card-stat\">\n <span className=\"thurin-card-stat-value\">\n {/* EFP answers separately; a null graph means it didn't, so don't claim zero. */}\n {identity.efp ? identity.efp.followers : '–'}\n </span>\n <span className=\"thurin-card-stat-label\">Followers</span>\n </div>\n </div>\n\n <div className=\"thurin-card-badges\">\n {hasVerifiedPgp && (\n <span className=\"thurin-card-badge thurin-card-badge--verified\">PGP Verified</span>\n )}\n {identity.efp?.hasEfp && (\n <span className=\"thurin-card-badge thurin-card-badge--verified\">EFP</span>\n )}\n {identity.proofs.map((p, i) => (\n <span\n key={i}\n className={`thurin-card-badge thurin-card-badge--${p.status === 'verified' ? 'verified' : 'unverified'}`}\n >\n {p.label}\n </span>\n ))}\n </div>\n\n {profileUrl && (\n <a\n className=\"thurin-card-link\"\n href={profileUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n View on Thurin\n </a>\n )}\n </div>\n )\n}\n","import { useBlockNumber, useEnsAddress, useEnsName } from 'wagmi'\nimport { identityErrorKind, needsRpcProbe, IDENTITY_ERROR_TEXT } from '../core/identityError'\nimport { useIdentityKitConfig } from '../context'\nimport { chainFor } from '../provider'\nimport { normalize } from 'viem/ens'\nimport { useAttestations } from './useAttestations'\nimport { useEFPGraph } from './useEFPGraph'\nimport { usePGPProofs } from './usePGPProofs'\nimport { useSafeAvatar } from './useSafeAvatar'\nimport type { ThurinIdentity } from '../core/types'\n\nfunction isAddress(value: string): boolean {\n return /^0x[0-9a-fA-F]{40}$/.test(value)\n}\n\nfunction safeNormalize(name: string): string | undefined {\n try {\n return normalize(name)\n } catch {\n return undefined\n }\n}\n\nexport function useThurinIdentity(ensOrAddress: string | undefined | null): ThurinIdentity {\n const chain = chainFor(useIdentityKitConfig().network)\n const isAddr = ensOrAddress ? isAddress(ensOrAddress) : false\n const ensInput = ensOrAddress && !isAddr ? safeNormalize(ensOrAddress) : undefined\n\n // Resolve ENS → address\n const { data: resolvedAddress, error: ensError, isFetched: ensFetched, refetch: refetchEns } = useEnsAddress({\n name: ensInput,\n chainId: chain.id,\n query: { enabled: !!ensInput },\n })\n\n const address = isAddr ? ensOrAddress! : resolvedAddress ?? null\n\n // Reverse resolve address → ENS\n const { data: ensName } = useEnsName({\n address: address as `0x${string}` | undefined,\n chainId: chain.id,\n query: { enabled: !!address },\n })\n\n const displayName = ensInput || ensName || null\n\n const ensAvatar = useSafeAvatar(displayName ? safeNormalize(displayName) : undefined, chain.id)\n\n // On-chain attestations\n const {\n claims,\n totalClaims,\n activeClaims,\n currentFingerprint,\n isLoading: claimsLoading,\n error: claimsError,\n refetch: refetchClaims,\n } = useAttestations(address)\n\n // PGP proofs come from the key stored in the current attestation — the\n // latest claim that is active and whose signature verified (the same rule\n // useAttestations uses to pick currentFingerprint).\n const currentClaim = [...claims].reverse().find(\n (c) => !c.revoked && c.verification?.verified && c.fingerprint === currentFingerprint,\n )\n const {\n keyInfo: pgpKeyInfo,\n proofs,\n isLoading: proofsLoading,\n } = usePGPProofs(currentFingerprint, currentClaim?.pgpPublicKey ?? null)\n\n // EFP social graph\n const { efp, isLoading: efpLoading } = useEFPGraph(address)\n\n // An empty ENS result or a failed read might just be a dead RPC; ask it for the block\n // number before saying anything about the identity (core/identityError.ts).\n const lookup = { ensEmpty: !!ensInput && ensFetched && !resolvedAddress, ensFailed: !!ensError, claimsFailed: !!claimsError }\n const probeNeeded = needsRpcProbe(lookup)\n // useBlockNumber, not usePublicClient: the latter attaches every public action to the client,\n // which put ~360 KB more into the standalone embed (1.3.4). Own scope per identity and no\n // caching, so an earlier answer can't make a dead RPC look alive.\n const probe = useBlockNumber({\n chainId: chain.id,\n scopeKey: `thurin-rpc-probe:${ensOrAddress ?? ''}`,\n query: { enabled: probeNeeded, retry: 0, staleTime: 0, gcTime: 0 },\n })\n const rpcAnswered = !probeNeeded || probe.isFetching ? undefined : probe.isSuccess ? true : probe.isError ? false : undefined\n const errorKind = identityErrorKind({ ...lookup, rpcAnswered })\n const probing = probeNeeded && rpcAnswered === undefined\n const retry = () => {\n if (ensInput) refetchEns()\n refetchClaims()\n if (probeNeeded) probe.refetch()\n }\n\n return {\n address,\n ensName: displayName,\n ensAvatar,\n claims,\n totalClaims,\n activeClaims,\n currentFingerprint,\n pgpKeyInfo,\n proofs,\n efp,\n // \"Not finished\" counts as loading, including queries paused in a background tab: the card\n // must not render defaults (zeros) for an identity it hasn't looked up yet.\n isLoading: (!!ensInput && !ensFetched) || claimsLoading || proofsLoading || efpLoading || probing,\n error: errorKind ? new Error(IDENTITY_ERROR_TEXT[errorKind]) : null,\n errorKind,\n retry,\n }\n}\n","import { useReadContract, useReadContracts } from 'wagmi'\nimport { useQuery } from '@tanstack/react-query'\nimport { hexToString } from 'viem'\nimport { REGISTRY_ABI, getRegistry } from '../core/contract'\nimport { bytesToFingerprint } from '../core/fingerprint'\nimport { chainFor } from '../provider'\nimport { verifyAttestation } from '../core/pgp'\nimport { useIdentityKitConfig } from '../context'\nimport type { Attestation } from '../core/types'\n\n/**\n * On-chain attestations for an address, read straight from the v2 registry:\n * `attestationsOf` for the history, `getPayload` for each stored signature + key.\n * No event logs, so any RPC works. Each claim is verified off-chain.\n */\nexport function useAttestations(address: string | undefined | null) {\n const config = useIdentityKitConfig()\n const registry = getRegistry(config.network, config.registryAddress)\n const chain = chainFor(config.network)\n const owner = address as `0x${string}` | undefined\n\n const { data: rows, isLoading: rowsLoading, isFetched: rowsFetched, error: rowsError, refetch: refetchRows } = useReadContract({\n address: registry.address,\n abi: REGISTRY_ABI,\n functionName: 'attestationsOf',\n args: owner ? [owner] : undefined,\n chainId: chain.id,\n query: { enabled: !!owner },\n })\n\n const count = rows?.length ?? 0\n\n const contracts = owner && rows\n ? rows.map((_, i) => ({\n address: registry.address,\n abi: REGISTRY_ABI,\n functionName: 'getPayload' as const,\n args: [owner, BigInt(i)] as const,\n chainId: chain.id,\n }))\n : []\n\n const { data: payloads, isLoading: payloadsLoading, error: payloadsError, refetch: refetchPayloads } = useReadContracts({\n contracts,\n query: { enabled: contracts.length > 0 },\n })\n\n const payloadsReady = count === 0 || (payloads !== undefined && payloads.length === count)\n\n const { data: claims, isLoading: verifyLoading } = useQuery({\n queryKey: ['attestations', config.network, registry.address, address, count, payloadsReady],\n queryFn: async (): Promise<Attestation[]> => {\n if (!rows || !address) return []\n const results: Attestation[] = []\n\n for (let i = 0; i < rows.length; i++) {\n const row = rows[i]\n const payload = payloads?.[i]\n let pgpSignature: string | null = null\n let pgpPublicKey: string | null = null\n if (payload && payload.status === 'success') {\n const [sigHex, keyHex] = payload.result as readonly [`0x${string}`, `0x${string}`]\n pgpSignature = hexToString(sigHex)\n pgpPublicKey = hexToString(keyHex)\n }\n\n const fingerprint = bytesToFingerprint(row.fingerprint)\n const verification = pgpPublicKey && pgpSignature\n ? await verifyAttestation({ pgpPublicKey, pgpSignature, fingerprint, ethAddress: address })\n : null\n\n const revokedAt = Number(row.revokedAt)\n results.push({\n index: i,\n fingerprint,\n createdAt: Number(row.createdAt),\n revoked: revokedAt !== 0,\n revokedAt: revokedAt === 0 ? null : revokedAt,\n messageVersion: Number(row.messageVersion),\n pgpSignature,\n pgpPublicKey,\n verification,\n })\n }\n return results\n },\n enabled: !!rows && payloadsReady,\n staleTime: 300_000,\n })\n\n // Not fetched yet counts as loading (a paused query in a background tab is not \"no claims\").\n const isLoading = rowsLoading || (!!owner && !rowsFetched) || payloadsLoading || verifyLoading || (!!owner && rows !== undefined && !payloadsReady)\n\n const activeClaims = (claims || []).filter((c) => !c.revoked)\n // The current identity is the latest claim that is both active and has a\n // verified signature binding the key to this address. A claim whose signature\n // has not verified must not surface the key's proofs or user data.\n const verifiedClaims = activeClaims.filter((c) => c.verification?.verified)\n const currentFingerprint = verifiedClaims.length > 0\n ? verifiedClaims[verifiedClaims.length - 1].fingerprint\n : null\n\n return {\n claims: claims || [],\n totalClaims: count,\n activeClaims: activeClaims.length,\n currentFingerprint,\n isLoading,\n /** A registry read failed (the RPC may be down; useThurinIdentity finds out which). */\n error: (rowsError ?? payloadsError ?? null) as Error | null,\n refetch: () => { if (owner) { refetchRows(); if (contracts.length > 0) refetchPayloads() } },\n }\n}\n","import { useQuery } from '@tanstack/react-query'\nimport { fetchEFPGraph } from '../core/efp'\nimport type { EFPGraph } from '../core/types'\n\nexport function useEFPGraph(address: string | undefined | null) {\n const { data, isLoading } = useQuery<EFPGraph | null>({\n queryKey: ['efp-graph', address],\n queryFn: () => fetchEFPGraph(address!),\n enabled: !!address,\n staleTime: 300_000,\n })\n\n return {\n efp: data ?? null,\n isLoading,\n }\n}\n","import { useQuery } from '@tanstack/react-query'\nimport { parsePgpKey } from '../core/pgp'\nimport { identifyProof, verifyProof, displayUrl, proofHref, proofSecondaryHref } from '../core/proofs'\nimport { useIdentityKitConfig } from '../context'\nimport type { PGPKeyInfo, ProofResult } from '../core/types'\n\n/**\n * Proofs for an identity, read from the PGP key stored in its on-chain\n * attestation. No keyserver is consulted: keys.openpgp.org only serves user\n * IDs whose email is verified and drops non-email user IDs entirely, so it can\n * never carry the published (non-email) identity that holds the notations.\n *\n * @param fingerprint the attested fingerprint (proofs must name it)\n * @param armoredKey the attestation's `pgpPublicKey`\n */\nexport function usePGPProofs(fingerprint: string | undefined | null, armoredKey: string | undefined | null) {\n const config = useIdentityKitConfig()\n\n const { data } = useQuery({\n // The key is large; key the query on its length + fingerprint, which\n // changes whenever a different attestation's key is supplied.\n queryKey: ['pgp-proofs', fingerprint, armoredKey?.length ?? 0],\n queryFn: async (): Promise<{ keyInfo: PGPKeyInfo | null; proofs: ProofResult[] }> => {\n if (!fingerprint || !armoredKey) return { keyInfo: null, proofs: [] }\n\n const keyInfo = await parsePgpKey(armoredKey)\n if (!keyInfo) return { keyInfo: null, proofs: [] }\n\n // Identify proofs from notations. Drop unrecognized targets (provider\n // 'unknown') so the card doesn't render \"Unknown\" badges for platforms\n // Thurin has no verifier for — matching the explorer's behavior.\n const identified = keyInfo.notations\n .map((n) => identifyProof(n))\n .filter((p): p is NonNullable<typeof p> => p !== null && p.provider !== 'unknown')\n\n // Verify all proofs in parallel\n const proofs: ProofResult[] = await Promise.all(\n identified.map(async (proof) => {\n const result = await verifyProof(proof, fingerprint, { neynarApiKey: config.neynarApiKey, farcasterHub: config.farcasterHub })\n return {\n provider: proof.provider,\n label: proof.label,\n url: proof.url,\n displayUrl: displayUrl(proof),\n href: proofHref(proof),\n secondaryHref: proofSecondaryHref(proof),\n status: result.verified ? 'verified' as const : 'unverified' as const,\n reason: result.reason,\n }\n }),\n )\n\n // Collapse proofs that resolve to the same account — the same target is\n // often listed under both proof@thurin.id and proof@ariadne.id (and can\n // be reached via more than one proof URL). Key by provider + display\n // identity, preferring a verified result.\n const byAccount = new Map<string, ProofResult>()\n for (const p of proofs) {\n const key = `${p.provider}:${p.displayUrl}`\n const prev = byAccount.get(key)\n if (!prev || (p.status === 'verified' && prev.status !== 'verified')) {\n byAccount.set(key, p)\n }\n }\n\n return { keyInfo, proofs: [...byAccount.values()] }\n },\n enabled: !!fingerprint && !!armoredKey,\n staleTime: 300_000,\n })\n\n return {\n keyInfo: data?.keyInfo ?? null,\n proofs: data?.proofs ?? [],\n // Report loading whenever a fingerprint is set but its proofs haven't\n // resolved yet. Using react-query's own isLoading leaves a gap while the\n // query is enabling (fingerprint just became known), during which the card\n // would briefly paint without proof badges and then pop them in.\n isLoading: !!fingerprint && !!armoredKey && data === undefined,\n }\n}\n","import { useEnsText, useReadContract } from 'wagmi'\nimport { useQuery } from '@tanstack/react-query'\nimport { avatarUrl, parseNftAvatar, nftAvatarImage, NFT_AVATAR_ABI } from '../core/avatar'\n\n/**\n * The avatar to show for a normalized ENS name, or null. Reads the raw `avatar` record and\n * loads only what `avatarUrl` allows (see core/avatar.ts); wagmi's useEnsAvatar would fetch\n * whatever host the name's owner chose.\n */\nexport function useSafeAvatar(name: string | undefined, chainId: number): string | null {\n const { data: raw } = useEnsText({ name, key: 'avatar', chainId, query: { enabled: !!name } })\n const direct = avatarUrl(raw)\n const nft = direct ? null : parseNftAvatar(raw)\n const { data: tokenUri } = useReadContract({\n address: nft?.contract,\n abi: NFT_AVATAR_ABI,\n functionName: nft?.standard === 'erc1155' ? 'uri' : 'tokenURI',\n args: nft ? [nft.tokenId] : undefined,\n chainId,\n query: { enabled: !!nft && nft.chainId === chainId },\n })\n const { data: image } = useQuery({\n queryKey: ['thurin-nft-avatar', tokenUri, nft?.tokenId.toString()],\n queryFn: () => nftAvatarImage(tokenUri as string, nft!.tokenId).catch(() => null),\n enabled: typeof tokenUri === 'string' && !!nft,\n })\n return direct ?? image ?? null\n}\n","import { useEnsText } from 'wagmi'\nimport { normalize } from 'viem/ens'\nimport { useIdentityKitConfig } from '../context'\nimport { chainFor } from '../provider'\nimport { ENS_HINT_KEY, ensHintFor, type EnsHint } from '../core/ensHint'\n\nfunction safeNormalize(name: string): string | undefined {\n try { return normalize(name) } catch { return undefined }\n}\n\n/**\n * A name's `id.thurin` record against the fingerprint the registry verifies for its\n * address. `state` is `match`, `unset`, or `mismatch`; the last one is the signal worth\n * showing — a name advertising a key its address has not claimed.\n */\nexport function useEnsHint(name: string | undefined | null, verifiedFingerprint: string | null | undefined): EnsHint & { isLoading: boolean; refetch: () => void } {\n const chain = chainFor(useIdentityKitConfig().network)\n const ensName = name ? safeNormalize(name) : undefined\n const { data, isLoading, refetch } = useEnsText({\n name: ensName,\n key: ENS_HINT_KEY,\n chainId: chain.id,\n query: { enabled: !!ensName },\n })\n return { ...ensHintFor(data ?? null, verifiedFingerprint), isLoading: !!ensName && isLoading, refetch: () => { void refetch() } }\n}\n","import { useReadContracts } from 'wagmi'\nimport { useQuery } from '@tanstack/react-query'\nimport { REGISTRY_ABI, getRegistry } from '../core/contract'\nimport { chainFor } from '../provider'\nimport { useIdentityKitConfig } from '../context'\nimport { IDENTITY_KINDS, decodeRecord, parseRecord, recordKind, type ParsedRecord } from '../core/records'\n\n/**\n * The records on one claim, for the kinds given (default: the kinds an identity page shows),\n * read in one multicall and parsed. Kinds with no record are left out.\n */\nexport function useRecords(address: string | undefined | null, index: number | undefined | null, kinds: readonly string[] = IDENTITY_KINDS, armoredKey?: string | null) {\n const config = useIdentityKitConfig()\n const registry = getRegistry(config.network, config.registryAddress)\n const chain = chainFor(config.network)\n const owner = address as `0x${string}` | undefined\n const enabled = !!owner && index !== undefined && index !== null\n\n const contracts = enabled\n ? kinds.map(kind => ({ address: registry.address, abi: REGISTRY_ABI, functionName: 'record' as const, args: [owner!, BigInt(index!), recordKind(kind)] as const, chainId: chain.id }))\n : []\n const { data: raw, isLoading: readLoading, refetch } = useReadContracts({ contracts, query: { enabled: contracts.length > 0 } })\n\n const texts = (raw ?? []).map(r => (r.status === 'success' ? decodeRecord(r.result as `0x${string}`) : ''))\n const { data: records, isLoading: parseLoading } = useQuery({\n queryKey: ['records', config.network, registry.address, address, index, kinds.join(','), texts.join(' '), armoredKey ?? ''],\n queryFn: async (): Promise<ParsedRecord[]> => {\n const out: ParsedRecord[] = []\n for (let i = 0; i < kinds.length; i++) if (texts[i]) out.push(await parseRecord(kinds[i], texts[i], { armoredKey: armoredKey ?? undefined }))\n return out\n },\n enabled: enabled && raw !== undefined,\n })\n\n return { records: records ?? [], isLoading: enabled && (readLoading || parseLoading), refetch: () => { void refetch() } }\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import { IdentityKitConfig, Theme, ThurinIdentity, Attestation, EFPGraph, PGPKeyInfo, ProofResult, EnsHint, ParsedRecord } from './core.cjs';
|
|
4
|
-
export { ARWEAVE_GATEWAY, AUTHORIZATION_TYPES, AttestAuthorization, AuthorizationAction, EIP712_NAME, EIP712_VERSION, ENS_HINT_KEY, ENS_TEXT_RESOLVER_ABI, EnsHintState, EnsTextReader, IDENTITY_ERROR_TEXT, IDENTITY_KINDS, IPFS_GATEWAY, IdentityErrorKind, IdentityLookupState, KNOWN_KINDS, KnownKind, MAX_RECORD_BYTES, NETWORKS, NFT_AVATAR_ABI, NetworkName, NftAvatar, Notation, PGPVerification, PointerEntry, PointerRecord, Proof, REGISTRY_ABI, REGISTRY_ADDRESS, ReattestAuthorization, RecordData, RecordReader, RegistryDeployment, RevokeAuthorization, SetRecordAuthorization, StrippedKey, SubkeyInfo, UpdateKeyAuthorization, addPointer, attestTypedData, authorizationDigest, avatarUrl, bytesToFingerprint, chainFor, decodeRecord, displayUrl, encodeRecord, ensHintFor, ensHintValue, ensHintWrite, fetchEFPGraph, fetchEnsHint, fetchRecords, fingerprintHash, fingerprintToBytes, getRegistry, hasEmailUserID, identifyProof, identityErrorKind, isNetworkName, keyIdOf, keyIdToBytes, kindName, needsRpcProbe, nftAvatarImage, normalizeFingerprint, parseNftAvatar, parsePgpKey, parsePointer, parseRecord, proofHref, proofSecondaryHref, reattestTypedData, recordKind, registryDomain, renderPointer, revokeTypedData, setRecordTypedData, stripEmailUserIDs, updateKeyTypedData, verifyAttestation, verifyClearsigned, verifyProof } from './core.cjs';
|
|
4
|
+
export { ARWEAVE_GATEWAY, AUTHORIZATION_TYPES, AttestAuthorization, AuthorizationAction, EIP712_NAME, EIP712_VERSION, ENS_HINT_KEY, ENS_TEXT_RESOLVER_ABI, EnsHintState, EnsTextReader, FARCASTER_HUB, IDENTITY_ERROR_TEXT, IDENTITY_KINDS, IPFS_GATEWAY, IPFS_GATEWAYS, IdentityErrorKind, IdentityLookupState, KNOWN_KINDS, KnownKind, MAX_RECORD_BYTES, NETWORKS, NFT_AVATAR_ABI, NetworkName, NftAvatar, Notation, PGPVerification, PointerEntry, PointerRecord, Proof, ProofOptions, REGISTRY_ABI, REGISTRY_ADDRESS, ReattestAuthorization, RecordData, RecordReader, RegistryDeployment, RevokeAuthorization, SetRecordAuthorization, StrippedKey, SubkeyInfo, UpdateKeyAuthorization, addPointer, attestTypedData, authorizationDigest, avatarFallbacks, avatarUrl, bytesToFingerprint, chainFor, decodeRecord, displayUrl, encodeRecord, ensHintFor, ensHintValue, ensHintWrite, fetchEFPGraph, fetchEnsHint, fetchRecords, fingerprintHash, fingerprintToBytes, getRegistry, hasEmailUserID, identifyProof, identityErrorKind, isNetworkName, keyIdOf, keyIdToBytes, kindName, needsRpcProbe, nftAvatarImage, normalizeFingerprint, parseNftAvatar, parsePgpKey, parsePointer, parseRecord, proofHref, proofSecondaryHref, reattestTypedData, recordKind, registryDomain, renderPointer, revokeTypedData, setRecordTypedData, stripEmailUserIDs, updateKeyTypedData, verifyAttestation, verifyClearsigned, verifyProof } from './core.cjs';
|
|
5
5
|
import 'viem';
|
|
6
6
|
|
|
7
7
|
interface IdentityKitProviderProps extends IdentityKitConfig {
|
|
8
8
|
children: ReactNode;
|
|
9
9
|
}
|
|
10
|
-
declare function IdentityKitProvider({ children, rpcUrl, neynarApiKey, baseUrl, network, registryAddress, }: IdentityKitProviderProps): react_jsx_runtime.JSX.Element;
|
|
10
|
+
declare function IdentityKitProvider({ children, rpcUrl, neynarApiKey, farcasterHub, baseUrl, network, registryAddress, }: IdentityKitProviderProps): react_jsx_runtime.JSX.Element;
|
|
11
11
|
|
|
12
12
|
interface ThurinCardProps {
|
|
13
13
|
ens?: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import { IdentityKitConfig, Theme, ThurinIdentity, Attestation, EFPGraph, PGPKeyInfo, ProofResult, EnsHint, ParsedRecord } from './core.js';
|
|
4
|
-
export { ARWEAVE_GATEWAY, AUTHORIZATION_TYPES, AttestAuthorization, AuthorizationAction, EIP712_NAME, EIP712_VERSION, ENS_HINT_KEY, ENS_TEXT_RESOLVER_ABI, EnsHintState, EnsTextReader, IDENTITY_ERROR_TEXT, IDENTITY_KINDS, IPFS_GATEWAY, IdentityErrorKind, IdentityLookupState, KNOWN_KINDS, KnownKind, MAX_RECORD_BYTES, NETWORKS, NFT_AVATAR_ABI, NetworkName, NftAvatar, Notation, PGPVerification, PointerEntry, PointerRecord, Proof, REGISTRY_ABI, REGISTRY_ADDRESS, ReattestAuthorization, RecordData, RecordReader, RegistryDeployment, RevokeAuthorization, SetRecordAuthorization, StrippedKey, SubkeyInfo, UpdateKeyAuthorization, addPointer, attestTypedData, authorizationDigest, avatarUrl, bytesToFingerprint, chainFor, decodeRecord, displayUrl, encodeRecord, ensHintFor, ensHintValue, ensHintWrite, fetchEFPGraph, fetchEnsHint, fetchRecords, fingerprintHash, fingerprintToBytes, getRegistry, hasEmailUserID, identifyProof, identityErrorKind, isNetworkName, keyIdOf, keyIdToBytes, kindName, needsRpcProbe, nftAvatarImage, normalizeFingerprint, parseNftAvatar, parsePgpKey, parsePointer, parseRecord, proofHref, proofSecondaryHref, reattestTypedData, recordKind, registryDomain, renderPointer, revokeTypedData, setRecordTypedData, stripEmailUserIDs, updateKeyTypedData, verifyAttestation, verifyClearsigned, verifyProof } from './core.js';
|
|
4
|
+
export { ARWEAVE_GATEWAY, AUTHORIZATION_TYPES, AttestAuthorization, AuthorizationAction, EIP712_NAME, EIP712_VERSION, ENS_HINT_KEY, ENS_TEXT_RESOLVER_ABI, EnsHintState, EnsTextReader, FARCASTER_HUB, IDENTITY_ERROR_TEXT, IDENTITY_KINDS, IPFS_GATEWAY, IPFS_GATEWAYS, IdentityErrorKind, IdentityLookupState, KNOWN_KINDS, KnownKind, MAX_RECORD_BYTES, NETWORKS, NFT_AVATAR_ABI, NetworkName, NftAvatar, Notation, PGPVerification, PointerEntry, PointerRecord, Proof, ProofOptions, REGISTRY_ABI, REGISTRY_ADDRESS, ReattestAuthorization, RecordData, RecordReader, RegistryDeployment, RevokeAuthorization, SetRecordAuthorization, StrippedKey, SubkeyInfo, UpdateKeyAuthorization, addPointer, attestTypedData, authorizationDigest, avatarFallbacks, avatarUrl, bytesToFingerprint, chainFor, decodeRecord, displayUrl, encodeRecord, ensHintFor, ensHintValue, ensHintWrite, fetchEFPGraph, fetchEnsHint, fetchRecords, fingerprintHash, fingerprintToBytes, getRegistry, hasEmailUserID, identifyProof, identityErrorKind, isNetworkName, keyIdOf, keyIdToBytes, kindName, needsRpcProbe, nftAvatarImage, normalizeFingerprint, parseNftAvatar, parsePgpKey, parsePointer, parseRecord, proofHref, proofSecondaryHref, reattestTypedData, recordKind, registryDomain, renderPointer, revokeTypedData, setRecordTypedData, stripEmailUserIDs, updateKeyTypedData, verifyAttestation, verifyClearsigned, verifyProof } from './core.js';
|
|
5
5
|
import 'viem';
|
|
6
6
|
|
|
7
7
|
interface IdentityKitProviderProps extends IdentityKitConfig {
|
|
8
8
|
children: ReactNode;
|
|
9
9
|
}
|
|
10
|
-
declare function IdentityKitProvider({ children, rpcUrl, neynarApiKey, baseUrl, network, registryAddress, }: IdentityKitProviderProps): react_jsx_runtime.JSX.Element;
|
|
10
|
+
declare function IdentityKitProvider({ children, rpcUrl, neynarApiKey, farcasterHub, baseUrl, network, registryAddress, }: IdentityKitProviderProps): react_jsx_runtime.JSX.Element;
|
|
11
11
|
|
|
12
12
|
interface ThurinCardProps {
|
|
13
13
|
ens?: string;
|
package/dist/index.js
CHANGED
|
@@ -5,9 +5,11 @@ import {
|
|
|
5
5
|
EIP712_VERSION,
|
|
6
6
|
ENS_HINT_KEY,
|
|
7
7
|
ENS_TEXT_RESOLVER_ABI,
|
|
8
|
+
FARCASTER_HUB,
|
|
8
9
|
IDENTITY_ERROR_TEXT,
|
|
9
10
|
IDENTITY_KINDS,
|
|
10
11
|
IPFS_GATEWAY,
|
|
12
|
+
IPFS_GATEWAYS,
|
|
11
13
|
KNOWN_KINDS,
|
|
12
14
|
MAX_RECORD_BYTES,
|
|
13
15
|
NETWORKS,
|
|
@@ -17,6 +19,7 @@ import {
|
|
|
17
19
|
addPointer,
|
|
18
20
|
attestTypedData,
|
|
19
21
|
authorizationDigest,
|
|
22
|
+
avatarFallbacks,
|
|
20
23
|
avatarUrl,
|
|
21
24
|
bytesToFingerprint,
|
|
22
25
|
chainFor,
|
|
@@ -59,7 +62,7 @@ import {
|
|
|
59
62
|
verifyAttestation,
|
|
60
63
|
verifyClearsigned,
|
|
61
64
|
verifyProof
|
|
62
|
-
} from "./chunk-
|
|
65
|
+
} from "./chunk-ROQWHCHP.js";
|
|
63
66
|
|
|
64
67
|
// src/provider.tsx
|
|
65
68
|
import { useMemo } from "react";
|
|
@@ -111,17 +114,21 @@ function IdentityKitProvider({
|
|
|
111
114
|
children,
|
|
112
115
|
rpcUrl,
|
|
113
116
|
neynarApiKey,
|
|
117
|
+
farcasterHub,
|
|
114
118
|
baseUrl = "https://thurin.id",
|
|
115
119
|
network = "mainnet",
|
|
116
120
|
registryAddress
|
|
117
121
|
}) {
|
|
118
122
|
const config = useMemo(
|
|
119
|
-
() => ({ rpcUrl, neynarApiKey, baseUrl, network, registryAddress }),
|
|
120
|
-
[rpcUrl, neynarApiKey, baseUrl, network, registryAddress]
|
|
123
|
+
() => ({ rpcUrl, neynarApiKey, farcasterHub, baseUrl, network, registryAddress }),
|
|
124
|
+
[rpcUrl, neynarApiKey, farcasterHub, baseUrl, network, registryAddress]
|
|
121
125
|
);
|
|
122
126
|
return /* @__PURE__ */ jsx(IdentityKitContext.Provider, { value: config, children: /* @__PURE__ */ jsx(WagmiDetector, { rpcUrl, network, children }) });
|
|
123
127
|
}
|
|
124
128
|
|
|
129
|
+
// src/components/ThurinCard/ThurinCard.tsx
|
|
130
|
+
import { useEffect, useState } from "react";
|
|
131
|
+
|
|
125
132
|
// src/hooks/useThurinIdentity.ts
|
|
126
133
|
import { useBlockNumber, useEnsAddress, useEnsName } from "wagmi";
|
|
127
134
|
import { normalize } from "viem/ens";
|
|
@@ -242,7 +249,7 @@ function usePGPProofs(fingerprint, armoredKey) {
|
|
|
242
249
|
const identified = keyInfo.notations.map((n) => identifyProof(n)).filter((p) => p !== null && p.provider !== "unknown");
|
|
243
250
|
const proofs = await Promise.all(
|
|
244
251
|
identified.map(async (proof) => {
|
|
245
|
-
const result = await verifyProof(proof, fingerprint, config.neynarApiKey);
|
|
252
|
+
const result = await verifyProof(proof, fingerprint, { neynarApiKey: config.neynarApiKey, farcasterHub: config.farcasterHub });
|
|
246
253
|
return {
|
|
247
254
|
provider: proof.provider,
|
|
248
255
|
label: proof.label,
|
|
@@ -394,6 +401,14 @@ function ThurinLogo() {
|
|
|
394
401
|
/* @__PURE__ */ jsx2("path", { d: "M50 65 L50 53", fill: "none", stroke: "#c9a227", strokeWidth: "4", strokeLinecap: "round" })
|
|
395
402
|
] });
|
|
396
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
|
+
}
|
|
397
412
|
function ThurinCard({ ens, address, theme = "thurin" }) {
|
|
398
413
|
const input = ens || address;
|
|
399
414
|
const identity = useThurinIdentity(input);
|
|
@@ -420,14 +435,7 @@ function ThurinCard({ ens, address, theme = "thurin" }) {
|
|
|
420
435
|
const hasVerifiedPgp = identity.claims.some((c) => c.verification?.verified && !c.revoked);
|
|
421
436
|
return /* @__PURE__ */ jsxs("div", { className: "thurin-card", "data-thurin-theme": theme, children: [
|
|
422
437
|
/* @__PURE__ */ jsxs("a", { className: "thurin-card-header", href: profileUrl || void 0, target: "_blank", rel: "noopener noreferrer", children: [
|
|
423
|
-
|
|
424
|
-
"img",
|
|
425
|
-
{
|
|
426
|
-
className: "thurin-card-avatar",
|
|
427
|
-
src: identity.ensAvatar,
|
|
428
|
-
alt: identity.ensName || ""
|
|
429
|
-
}
|
|
430
|
-
) : /* @__PURE__ */ jsx2(ThurinLogo, {}),
|
|
438
|
+
/* @__PURE__ */ jsx2(Avatar, { src: identity.ensAvatar, alt: identity.ensName || "" }),
|
|
431
439
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
432
440
|
identity.ensName && /* @__PURE__ */ jsx2("div", { className: "thurin-card-name", children: identity.ensName }),
|
|
433
441
|
displayAddress && /* @__PURE__ */ jsx2("div", { className: "thurin-card-address", children: displayAddress })
|
|
@@ -528,9 +536,11 @@ export {
|
|
|
528
536
|
EIP712_VERSION,
|
|
529
537
|
ENS_HINT_KEY,
|
|
530
538
|
ENS_TEXT_RESOLVER_ABI,
|
|
539
|
+
FARCASTER_HUB,
|
|
531
540
|
IDENTITY_ERROR_TEXT,
|
|
532
541
|
IDENTITY_KINDS,
|
|
533
542
|
IPFS_GATEWAY,
|
|
543
|
+
IPFS_GATEWAYS,
|
|
534
544
|
IdentityKitProvider,
|
|
535
545
|
KNOWN_KINDS,
|
|
536
546
|
MAX_RECORD_BYTES,
|
|
@@ -542,6 +552,7 @@ export {
|
|
|
542
552
|
addPointer,
|
|
543
553
|
attestTypedData,
|
|
544
554
|
authorizationDigest,
|
|
555
|
+
avatarFallbacks,
|
|
545
556
|
avatarUrl,
|
|
546
557
|
bytesToFingerprint,
|
|
547
558
|
chainFor,
|