@thurinlabs/identity-kit 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1625,6 +1625,14 @@ var PROVIDERS = [
1625
1625
  pattern: /^https:\/\/gist\.github\.com\/([^/]+)\/([a-f0-9]+)$/i,
1626
1626
  parse: (m) => ({ user: m[1], gistId: m[2] })
1627
1627
  },
1628
+ {
1629
+ // A repository's description — the form an organisation can use, since
1630
+ // gists belong to user accounts only. Same shape as the Codeberg proof.
1631
+ provider: "github",
1632
+ label: "GitHub",
1633
+ pattern: /^https:\/\/github\.com\/([A-Za-z0-9-]+)\/([A-Za-z0-9._-]+)$/i,
1634
+ parse: (m) => ({ user: m[1], repo: m[2] })
1635
+ },
1628
1636
  {
1629
1637
  provider: "dns",
1630
1638
  label: "DNS",
@@ -1696,6 +1704,7 @@ function containsFingerprintUrl(text, fingerprint) {
1696
1704
  return text.toUpperCase().includes(fingerprint.toUpperCase());
1697
1705
  }
1698
1706
  async function verifyGitHub(proof, fingerprint) {
1707
+ if (proof.repo) return verifyGitHubRepo(proof, fingerprint);
1699
1708
  try {
1700
1709
  const resp = await fetch(`https://api.github.com/gists/${proof.gistId}`);
1701
1710
  if (!resp.ok) return { verified: false, reason: `GitHub API returned ${resp.status}` };
@@ -1713,6 +1722,24 @@ async function verifyGitHub(proof, fingerprint) {
1713
1722
  return { verified: false, reason: `GitHub fetch failed: ${err.message}` };
1714
1723
  }
1715
1724
  }
1725
+ async function verifyGitHubRepo(proof, fingerprint) {
1726
+ try {
1727
+ const resp = await fetch(
1728
+ `https://api.github.com/repos/${encodeURIComponent(proof.user)}/${encodeURIComponent(proof.repo)}`
1729
+ );
1730
+ if (!resp.ok) return { verified: false, reason: `GitHub API returned ${resp.status}` };
1731
+ const data = await resp.json();
1732
+ if (_optionalChain([data, 'access', _26 => _26.owner, 'optionalAccess', _27 => _27.login, 'optionalAccess', _28 => _28.toLowerCase, 'call', _29 => _29()]) !== proof.user.toLowerCase()) {
1733
+ return { verified: false, reason: "Repository owner does not match claimed account" };
1734
+ }
1735
+ if (data.description && containsFingerprint(data.description, fingerprint)) {
1736
+ return { verified: true };
1737
+ }
1738
+ return { verified: false, reason: "Fingerprint token not found in repository description" };
1739
+ } catch (err) {
1740
+ return { verified: false, reason: `GitHub fetch failed: ${err.message}` };
1741
+ }
1742
+ }
1716
1743
  async function verifyDNS(proof, fingerprint) {
1717
1744
  try {
1718
1745
  const resp = await fetch(
@@ -1758,7 +1785,7 @@ async function verifyFarcaster(proof, fingerprint, neynarApiKey) {
1758
1785
  const data = await resp.json();
1759
1786
  for (const msg of data.messages || []) {
1760
1787
  if (msg.hash && msg.hash.startsWith(proof.castHash)) {
1761
- const text = _optionalChain([msg, 'access', _26 => _26.data, 'optionalAccess', _27 => _27.castAddBody, 'optionalAccess', _28 => _28.text]) || "";
1788
+ const text = _optionalChain([msg, 'access', _30 => _30.data, 'optionalAccess', _31 => _31.castAddBody, 'optionalAccess', _32 => _32.text]) || "";
1762
1789
  if (containsFingerprint(text, fingerprint)) {
1763
1790
  return { verified: true };
1764
1791
  }
@@ -1834,7 +1861,7 @@ function usePGPProofs(fingerprint, armoredKey) {
1834
1861
  const { data } = _reactquery.useQuery.call(void 0, {
1835
1862
  // The key is large; key the query on its length + fingerprint, which
1836
1863
  // changes whenever a different attestation's key is supplied.
1837
- queryKey: ["pgp-proofs", fingerprint, _nullishCoalesce(_optionalChain([armoredKey, 'optionalAccess', _29 => _29.length]), () => ( 0))],
1864
+ queryKey: ["pgp-proofs", fingerprint, _nullishCoalesce(_optionalChain([armoredKey, 'optionalAccess', _33 => _33.length]), () => ( 0))],
1838
1865
  queryFn: async () => {
1839
1866
  if (!fingerprint || !armoredKey) return { keyInfo: null, proofs: [] };
1840
1867
  const keyInfo = await parsePgpKey(armoredKey);
@@ -1869,8 +1896,8 @@ function usePGPProofs(fingerprint, armoredKey) {
1869
1896
  staleTime: 3e5
1870
1897
  });
1871
1898
  return {
1872
- keyInfo: _nullishCoalesce(_optionalChain([data, 'optionalAccess', _30 => _30.keyInfo]), () => ( null)),
1873
- proofs: _nullishCoalesce(_optionalChain([data, 'optionalAccess', _31 => _31.proofs]), () => ( [])),
1899
+ keyInfo: _nullishCoalesce(_optionalChain([data, 'optionalAccess', _34 => _34.keyInfo]), () => ( null)),
1900
+ proofs: _nullishCoalesce(_optionalChain([data, 'optionalAccess', _35 => _35.proofs]), () => ( [])),
1874
1901
  // Report loading whenever a fingerprint is set but its proofs haven't
1875
1902
  // resolved yet. Using react-query's own isLoading leaves a gap while the
1876
1903
  // query is enabling (fingerprint just became known), during which the card
@@ -1919,13 +1946,13 @@ function useThurinIdentity(ensOrAddress) {
1919
1946
  isLoading: claimsLoading
1920
1947
  } = useAttestations(address);
1921
1948
  const currentClaim = [...claims].reverse().find(
1922
- (c) => !c.revoked && _optionalChain([c, 'access', _32 => _32.verification, 'optionalAccess', _33 => _33.verified]) && c.fingerprint === currentFingerprint
1949
+ (c) => !c.revoked && _optionalChain([c, 'access', _36 => _36.verification, 'optionalAccess', _37 => _37.verified]) && c.fingerprint === currentFingerprint
1923
1950
  );
1924
1951
  const {
1925
1952
  keyInfo: pgpKeyInfo,
1926
1953
  proofs,
1927
1954
  isLoading: proofsLoading
1928
- } = usePGPProofs(currentFingerprint, _nullishCoalesce(_optionalChain([currentClaim, 'optionalAccess', _34 => _34.pgpPublicKey]), () => ( null)));
1955
+ } = usePGPProofs(currentFingerprint, _nullishCoalesce(_optionalChain([currentClaim, 'optionalAccess', _38 => _38.pgpPublicKey]), () => ( null)));
1929
1956
  const { efp, isLoading: efpLoading } = useEFPGraph(address);
1930
1957
  return {
1931
1958
  address,
@@ -1964,7 +1991,7 @@ function ThurinCard({ ens, address, theme = "thurin" }) {
1964
1991
  }
1965
1992
  const displayAddress = identity.address || null;
1966
1993
  const verifiedProofs = identity.proofs.filter((p) => p.status === "verified").length;
1967
- const hasVerifiedPgp = identity.claims.some((c) => _optionalChain([c, 'access', _35 => _35.verification, 'optionalAccess', _36 => _36.verified]) && !c.revoked);
1994
+ const hasVerifiedPgp = identity.claims.some((c) => _optionalChain([c, 'access', _39 => _39.verification, 'optionalAccess', _40 => _40.verified]) && !c.revoked);
1968
1995
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "thurin-card", "data-thurin-theme": theme, children: [
1969
1996
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "a", { className: "thurin-card-header", href: profileUrl || void 0, target: "_blank", rel: "noopener noreferrer", children: [
1970
1997
  identity.ensAvatar ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -1990,13 +2017,13 @@ function ThurinCard({ ens, address, theme = "thurin" }) {
1990
2017
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "thurin-card-stat-label", children: "Proofs" })
1991
2018
  ] }),
1992
2019
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "thurin-card-stat", children: [
1993
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "thurin-card-stat-value", children: _nullishCoalesce(_optionalChain([identity, 'access', _37 => _37.efp, 'optionalAccess', _38 => _38.followers]), () => ( 0)) }),
2020
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "thurin-card-stat-value", children: _nullishCoalesce(_optionalChain([identity, 'access', _41 => _41.efp, 'optionalAccess', _42 => _42.followers]), () => ( 0)) }),
1994
2021
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "thurin-card-stat-label", children: "Followers" })
1995
2022
  ] })
1996
2023
  ] }),
1997
2024
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "thurin-card-badges", children: [
1998
2025
  hasVerifiedPgp && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "thurin-card-badge thurin-card-badge--verified", children: "PGP Verified" }),
1999
- _optionalChain([identity, 'access', _39 => _39.efp, 'optionalAccess', _40 => _40.hasEfp]) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "thurin-card-badge thurin-card-badge--verified", children: "EFP" }),
2026
+ _optionalChain([identity, 'access', _43 => _43.efp, 'optionalAccess', _44 => _44.hasEfp]) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "thurin-card-badge thurin-card-badge--verified", children: "EFP" }),
2000
2027
  identity.proofs.map((p, i) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2001
2028
  "span",
2002
2029
  {