@thurinlabs/identity-kit 0.7.3 → 0.7.5
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 +9 -4
- package/dist/embed.global.js +24 -11
- package/dist/embed.global.js.map +1 -1
- package/dist/index.cjs +21 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +21 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -184,11 +184,14 @@ Hooks-only consumers don't need to import styles.
|
|
|
184
184
|
|
|
185
185
|
## Embed (No React Required)
|
|
186
186
|
|
|
187
|
-
For static sites, Jekyll blogs, WordPress, or any HTML page — use the standalone embed script.
|
|
187
|
+
For static sites, Jekyll blogs, WordPress, or any HTML page — use the standalone embed script. Everything runs client-side; there's no Thurin backend in the path.
|
|
188
188
|
|
|
189
189
|
```html
|
|
190
|
-
<div
|
|
191
|
-
|
|
190
|
+
<div
|
|
191
|
+
data-scry-card="bendoubleu.eth"
|
|
192
|
+
data-theme="thurin"
|
|
193
|
+
data-rpc-url="https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY"
|
|
194
|
+
></div>
|
|
192
195
|
|
|
193
196
|
<script src="https://cdn.jsdelivr.net/npm/@thurinlabs/identity-kit/dist/embed.global.js"></script>
|
|
194
197
|
```
|
|
@@ -197,8 +200,10 @@ For static sites, Jekyll blogs, WordPress, or any HTML page — use the standalo
|
|
|
197
200
|
|-----------|-------------|
|
|
198
201
|
| `data-scry-card` | ENS name or ETH address to look up (required) |
|
|
199
202
|
| `data-theme` | `thurin`, `dark`, or `light` (default: `thurin`) |
|
|
203
|
+
| `data-rpc-url` | An Ethereum RPC that supports `eth_getLogs` — required to verify on-chain claims. The card reads the chain directly, so use your own node or any provider. (Public fallback RPCs throttle `getLogs`.) |
|
|
204
|
+
| `data-neynar-key` | Optional. A Neynar API key, only to verify Farcaster proofs. Without it, Farcaster shows as unverified. |
|
|
200
205
|
|
|
201
|
-
The
|
|
206
|
+
The card talks directly to Ethereum, keys.openpgp.org, and each proof platform — no intermediary. Cards render automatically on page load and for dynamically added elements.
|
|
202
207
|
|
|
203
208
|
## Supported Proof Providers
|
|
204
209
|
|
package/dist/embed.global.js
CHANGED
|
@@ -39380,9 +39380,8 @@ ${prettyStateOverride(stateOverride)}`;
|
|
|
39380
39380
|
const name = typeof n2.name === "string" ? n2.name : new TextDecoder().decode(n2.name);
|
|
39381
39381
|
const value = n2.value instanceof Uint8Array ? new TextDecoder().decode(n2.value) : typeof n2.value === "string" ? n2.value : null;
|
|
39382
39382
|
if (value) {
|
|
39383
|
-
|
|
39384
|
-
|
|
39385
|
-
seen.add(dedupeKey);
|
|
39383
|
+
if (!seen.has(value)) {
|
|
39384
|
+
seen.add(value);
|
|
39386
39385
|
notations.push({ name, value });
|
|
39387
39386
|
}
|
|
39388
39387
|
}
|
|
@@ -39528,7 +39527,8 @@ ${prettyStateOverride(stateOverride)}`;
|
|
|
39528
39527
|
enabled: !!attestations && attestations.length > 0,
|
|
39529
39528
|
staleTime: 3e5
|
|
39530
39529
|
});
|
|
39531
|
-
const
|
|
39530
|
+
const eventLogsPending = !!address && attestationCount > 0 && eventData === void 0;
|
|
39531
|
+
const isLoading = countLoading || attestationsLoading || verifyLoading || eventLogsPending;
|
|
39532
39532
|
const activeClaims = (claims || []).filter((c2) => !c2.revoked);
|
|
39533
39533
|
const verifiedClaims = activeClaims.filter((c2) => c2.verification?.verified);
|
|
39534
39534
|
const currentFingerprint = verifiedClaims.length > 0 ? verifiedClaims[verifiedClaims.length - 1].fingerprint : null;
|
|
@@ -39620,9 +39620,8 @@ ${prettyStateOverride(stateOverride)}`;
|
|
|
39620
39620
|
parse: (m2) => ({ instance: m2[1], user: m2[2] })
|
|
39621
39621
|
}
|
|
39622
39622
|
];
|
|
39623
|
-
var PROOF_NAMESPACES = /* @__PURE__ */ new Set(["proof@thurin.id", "proof@ariadne.id"]);
|
|
39624
39623
|
function identifyProof(notation) {
|
|
39625
|
-
if (
|
|
39624
|
+
if (notation.name !== "proof@thurin.id") return null;
|
|
39626
39625
|
for (const { provider, label, pattern, parse } of PROVIDERS) {
|
|
39627
39626
|
const m2 = notation.value.match(pattern);
|
|
39628
39627
|
if (m2) {
|
|
@@ -39798,7 +39797,7 @@ ${prettyStateOverride(stateOverride)}`;
|
|
|
39798
39797
|
// src/hooks/usePGPProofs.ts
|
|
39799
39798
|
function usePGPProofs(fingerprint) {
|
|
39800
39799
|
const config = useIdentityKitConfig();
|
|
39801
|
-
const { data
|
|
39800
|
+
const { data } = useQuery({
|
|
39802
39801
|
queryKey: ["pgp-proofs", fingerprint],
|
|
39803
39802
|
queryFn: async () => {
|
|
39804
39803
|
if (!fingerprint) return { keyInfo: null, proofs: [] };
|
|
@@ -39806,7 +39805,7 @@ ${prettyStateOverride(stateOverride)}`;
|
|
|
39806
39805
|
if (!armoredKey) return { keyInfo: null, proofs: [] };
|
|
39807
39806
|
const keyInfo = await parsePgpKey(armoredKey);
|
|
39808
39807
|
if (!keyInfo) return { keyInfo: null, proofs: [] };
|
|
39809
|
-
const identified = keyInfo.notations.map((n2) => identifyProof(n2)).filter((p2) => p2 !== null);
|
|
39808
|
+
const identified = keyInfo.notations.map((n2) => identifyProof(n2)).filter((p2) => p2 !== null && p2.provider !== "unknown");
|
|
39810
39809
|
const proofs = await Promise.all(
|
|
39811
39810
|
identified.map(async (proof) => {
|
|
39812
39811
|
const result = await verifyProof(proof, fingerprint, config.neynarApiKey);
|
|
@@ -39822,7 +39821,15 @@ ${prettyStateOverride(stateOverride)}`;
|
|
|
39822
39821
|
};
|
|
39823
39822
|
})
|
|
39824
39823
|
);
|
|
39825
|
-
|
|
39824
|
+
const byAccount = /* @__PURE__ */ new Map();
|
|
39825
|
+
for (const p2 of proofs) {
|
|
39826
|
+
const key = `${p2.provider}:${p2.displayUrl}`;
|
|
39827
|
+
const prev = byAccount.get(key);
|
|
39828
|
+
if (!prev || p2.status === "verified" && prev.status !== "verified") {
|
|
39829
|
+
byAccount.set(key, p2);
|
|
39830
|
+
}
|
|
39831
|
+
}
|
|
39832
|
+
return { keyInfo, proofs: [...byAccount.values()] };
|
|
39826
39833
|
},
|
|
39827
39834
|
enabled: !!fingerprint,
|
|
39828
39835
|
staleTime: 3e5
|
|
@@ -39830,7 +39837,11 @@ ${prettyStateOverride(stateOverride)}`;
|
|
|
39830
39837
|
return {
|
|
39831
39838
|
keyInfo: data?.keyInfo ?? null,
|
|
39832
39839
|
proofs: data?.proofs ?? [],
|
|
39833
|
-
|
|
39840
|
+
// Report loading whenever a fingerprint is set but its proofs haven't
|
|
39841
|
+
// resolved yet. Using react-query's own isLoading leaves a gap while the
|
|
39842
|
+
// query is enabling (fingerprint just became known), during which the card
|
|
39843
|
+
// would briefly paint without proof badges and then pop them in.
|
|
39844
|
+
isLoading: !!fingerprint && data === void 0
|
|
39834
39845
|
};
|
|
39835
39846
|
}
|
|
39836
39847
|
|
|
@@ -39990,6 +40001,8 @@ ${prettyStateOverride(stateOverride)}`;
|
|
|
39990
40001
|
el2.dataset.scryRendered = "true";
|
|
39991
40002
|
const value = el2.dataset.scryCard;
|
|
39992
40003
|
const theme = el2.dataset.theme || "thurin";
|
|
40004
|
+
const rpcUrl = el2.dataset.rpcUrl;
|
|
40005
|
+
const neynarApiKey = el2.dataset.neynarKey;
|
|
39993
40006
|
const props = isAddress3(value) ? { address: value } : { ens: value };
|
|
39994
40007
|
const shadow = el2.attachShadow({ mode: "open" });
|
|
39995
40008
|
const style = document.createElement("style");
|
|
@@ -39999,7 +40012,7 @@ ${prettyStateOverride(stateOverride)}`;
|
|
|
39999
40012
|
shadow.appendChild(container);
|
|
40000
40013
|
const root = (0, import_client.createRoot)(container);
|
|
40001
40014
|
root.render(
|
|
40002
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(IdentityKitProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ScryCard, { ...props, theme }) })
|
|
40015
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(IdentityKitProvider, { rpcUrl, neynarApiKey, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ScryCard, { ...props, theme }) })
|
|
40003
40016
|
);
|
|
40004
40017
|
});
|
|
40005
40018
|
}
|