@thurinlabs/identity-kit 1.1.0 → 1.1.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
@@ -34,7 +34,7 @@
34
34
 
35
35
 
36
36
 
37
- var _chunkNL4LHKJXcjs = require('./chunk-NL4LHKJX.cjs');
37
+ var _chunkRC4PCCYVcjs = require('./chunk-RC4PCCYV.cjs');
38
38
 
39
39
  // src/provider.tsx
40
40
  var _react = require('react');
@@ -64,7 +64,7 @@ var defaultQueryClient = new (0, _reactquery.QueryClient)({
64
64
  }
65
65
  });
66
66
  function createDefaultWagmiConfig(rpcUrl, network) {
67
- const url = rpcUrl || _chunkNL4LHKJXcjs.getRegistry.call(void 0, network).defaultRpcUrl;
67
+ const url = rpcUrl || _chunkRC4PCCYVcjs.getRegistry.call(void 0, network).defaultRpcUrl;
68
68
  if (network === "sepolia") return _wagmi.createConfig.call(void 0, { chains: [_chains.sepolia], transports: { [_chains.sepolia.id]: _wagmi.http.call(void 0, url) } });
69
69
  if (network === "local") return _wagmi.createConfig.call(void 0, { chains: [_chains.foundry], transports: { [_chains.foundry.id]: _wagmi.http.call(void 0, url) } });
70
70
  return _wagmi.createConfig.call(void 0, { chains: [_chains.mainnet], transports: { [_chains.mainnet.id]: _wagmi.http.call(void 0, url) } });
@@ -107,12 +107,12 @@ var _ens = require('viem/ens');
107
107
  var _viem = require('viem');
108
108
  function useAttestations(address) {
109
109
  const config = useIdentityKitConfig();
110
- const registry = _chunkNL4LHKJXcjs.getRegistry.call(void 0, config.network, config.registryAddress);
111
- const chain = _chunkNL4LHKJXcjs.chainFor.call(void 0, config.network);
110
+ const registry = _chunkRC4PCCYVcjs.getRegistry.call(void 0, config.network, config.registryAddress);
111
+ const chain = _chunkRC4PCCYVcjs.chainFor.call(void 0, config.network);
112
112
  const owner = address;
113
113
  const { data: rows, isLoading: rowsLoading } = _wagmi.useReadContract.call(void 0, {
114
114
  address: registry.address,
115
- abi: _chunkNL4LHKJXcjs.REGISTRY_ABI,
115
+ abi: _chunkRC4PCCYVcjs.REGISTRY_ABI,
116
116
  functionName: "attestationsOf",
117
117
  args: owner ? [owner] : void 0,
118
118
  chainId: chain.id,
@@ -121,7 +121,7 @@ function useAttestations(address) {
121
121
  const count = _nullishCoalesce(_optionalChain([rows, 'optionalAccess', _2 => _2.length]), () => ( 0));
122
122
  const contracts = owner && rows ? rows.map((_, i) => ({
123
123
  address: registry.address,
124
- abi: _chunkNL4LHKJXcjs.REGISTRY_ABI,
124
+ abi: _chunkRC4PCCYVcjs.REGISTRY_ABI,
125
125
  functionName: "getPayload",
126
126
  args: [owner, BigInt(i)],
127
127
  chainId: chain.id
@@ -146,8 +146,8 @@ function useAttestations(address) {
146
146
  pgpSignature = _viem.hexToString.call(void 0, sigHex);
147
147
  pgpPublicKey = _viem.hexToString.call(void 0, keyHex);
148
148
  }
149
- const fingerprint = _chunkNL4LHKJXcjs.bytesToFingerprint.call(void 0, row.fingerprint);
150
- const verification = pgpPublicKey && pgpSignature ? await _chunkNL4LHKJXcjs.verifyAttestation.call(void 0, { pgpPublicKey, pgpSignature, fingerprint, ethAddress: address }) : null;
149
+ const fingerprint = _chunkRC4PCCYVcjs.bytesToFingerprint.call(void 0, row.fingerprint);
150
+ const verification = pgpPublicKey && pgpSignature ? await _chunkRC4PCCYVcjs.verifyAttestation.call(void 0, { pgpPublicKey, pgpSignature, fingerprint, ethAddress: address }) : null;
151
151
  const revokedAt = Number(row.revokedAt);
152
152
  results.push({
153
153
  index: i,
@@ -184,7 +184,7 @@ function useAttestations(address) {
184
184
  function useEFPGraph(address) {
185
185
  const { data, isLoading } = _reactquery.useQuery.call(void 0, {
186
186
  queryKey: ["efp-graph", address],
187
- queryFn: () => _chunkNL4LHKJXcjs.fetchEFPGraph.call(void 0, address),
187
+ queryFn: () => _chunkRC4PCCYVcjs.fetchEFPGraph.call(void 0, address),
188
188
  enabled: !!address,
189
189
  staleTime: 3e5
190
190
  });
@@ -204,19 +204,19 @@ function usePGPProofs(fingerprint, armoredKey) {
204
204
  queryKey: ["pgp-proofs", fingerprint, _nullishCoalesce(_optionalChain([armoredKey, 'optionalAccess', _6 => _6.length]), () => ( 0))],
205
205
  queryFn: async () => {
206
206
  if (!fingerprint || !armoredKey) return { keyInfo: null, proofs: [] };
207
- const keyInfo = await _chunkNL4LHKJXcjs.parsePgpKey.call(void 0, armoredKey);
207
+ const keyInfo = await _chunkRC4PCCYVcjs.parsePgpKey.call(void 0, armoredKey);
208
208
  if (!keyInfo) return { keyInfo: null, proofs: [] };
209
- const identified = keyInfo.notations.map((n) => _chunkNL4LHKJXcjs.identifyProof.call(void 0, n)).filter((p) => p !== null && p.provider !== "unknown");
209
+ const identified = keyInfo.notations.map((n) => _chunkRC4PCCYVcjs.identifyProof.call(void 0, n)).filter((p) => p !== null && p.provider !== "unknown");
210
210
  const proofs = await Promise.all(
211
211
  identified.map(async (proof) => {
212
- const result = await _chunkNL4LHKJXcjs.verifyProof.call(void 0, proof, fingerprint, config.neynarApiKey);
212
+ const result = await _chunkRC4PCCYVcjs.verifyProof.call(void 0, proof, fingerprint, config.neynarApiKey);
213
213
  return {
214
214
  provider: proof.provider,
215
215
  label: proof.label,
216
216
  url: proof.url,
217
- displayUrl: _chunkNL4LHKJXcjs.displayUrl.call(void 0, proof),
218
- href: _chunkNL4LHKJXcjs.proofHref.call(void 0, proof),
219
- secondaryHref: _chunkNL4LHKJXcjs.proofSecondaryHref.call(void 0, proof),
217
+ displayUrl: _chunkRC4PCCYVcjs.displayUrl.call(void 0, proof),
218
+ href: _chunkRC4PCCYVcjs.proofHref.call(void 0, proof),
219
+ secondaryHref: _chunkRC4PCCYVcjs.proofSecondaryHref.call(void 0, proof),
220
220
  status: result.verified ? "verified" : "unverified",
221
221
  reason: result.reason
222
222
  };
@@ -258,7 +258,7 @@ function safeNormalize(name) {
258
258
  }
259
259
  }
260
260
  function useThurinIdentity(ensOrAddress) {
261
- const chain = _chunkNL4LHKJXcjs.chainFor.call(void 0, useIdentityKitConfig().network);
261
+ const chain = _chunkRC4PCCYVcjs.chainFor.call(void 0, useIdentityKitConfig().network);
262
262
  const isAddr = ensOrAddress ? isAddress(ensOrAddress) : false;
263
263
  const ensInput = ensOrAddress && !isAddr ? safeNormalize(ensOrAddress) : void 0;
264
264
  const { data: resolvedAddress } = _wagmi.useEnsAddress.call(void 0, {
@@ -427,5 +427,5 @@ function ThurinCard({ ens, address, theme = "thurin" }) {
427
427
 
428
428
 
429
429
 
430
- exports.AUTHORIZATION_TYPES = _chunkNL4LHKJXcjs.AUTHORIZATION_TYPES; exports.EIP712_NAME = _chunkNL4LHKJXcjs.EIP712_NAME; exports.EIP712_VERSION = _chunkNL4LHKJXcjs.EIP712_VERSION; exports.IdentityKitProvider = IdentityKitProvider; exports.NETWORKS = _chunkNL4LHKJXcjs.NETWORKS; exports.REGISTRY_ABI = _chunkNL4LHKJXcjs.REGISTRY_ABI; exports.REGISTRY_ADDRESS = _chunkNL4LHKJXcjs.REGISTRY_ADDRESS; exports.ThurinCard = ThurinCard; exports.attestTypedData = _chunkNL4LHKJXcjs.attestTypedData; exports.authorizationDigest = _chunkNL4LHKJXcjs.authorizationDigest; exports.bytesToFingerprint = _chunkNL4LHKJXcjs.bytesToFingerprint; exports.chainFor = _chunkNL4LHKJXcjs.chainFor; exports.displayUrl = _chunkNL4LHKJXcjs.displayUrl; exports.fetchEFPGraph = _chunkNL4LHKJXcjs.fetchEFPGraph; exports.fetchKeyByFingerprint = _chunkNL4LHKJXcjs.fetchKeyByFingerprint; exports.fetchKeyByKeyId = _chunkNL4LHKJXcjs.fetchKeyByKeyId; exports.fingerprintHash = _chunkNL4LHKJXcjs.fingerprintHash; exports.fingerprintToBytes = _chunkNL4LHKJXcjs.fingerprintToBytes; exports.getRegistry = _chunkNL4LHKJXcjs.getRegistry; exports.hasEmailUserID = _chunkNL4LHKJXcjs.hasEmailUserID; exports.identifyProof = _chunkNL4LHKJXcjs.identifyProof; exports.isNetworkName = _chunkNL4LHKJXcjs.isNetworkName; exports.keyIdOf = _chunkNL4LHKJXcjs.keyIdOf; exports.keyIdToBytes = _chunkNL4LHKJXcjs.keyIdToBytes; exports.normalizeFingerprint = _chunkNL4LHKJXcjs.normalizeFingerprint; exports.parsePgpKey = _chunkNL4LHKJXcjs.parsePgpKey; exports.proofHref = _chunkNL4LHKJXcjs.proofHref; exports.proofSecondaryHref = _chunkNL4LHKJXcjs.proofSecondaryHref; exports.reattestTypedData = _chunkNL4LHKJXcjs.reattestTypedData; exports.recordKind = _chunkNL4LHKJXcjs.recordKind; exports.registryDomain = _chunkNL4LHKJXcjs.registryDomain; exports.revokeTypedData = _chunkNL4LHKJXcjs.revokeTypedData; exports.setRecordTypedData = _chunkNL4LHKJXcjs.setRecordTypedData; exports.stripEmailUserIDs = _chunkNL4LHKJXcjs.stripEmailUserIDs; exports.updateKeyTypedData = _chunkNL4LHKJXcjs.updateKeyTypedData; exports.useAttestations = useAttestations; exports.useEFPGraph = useEFPGraph; exports.usePGPProofs = usePGPProofs; exports.useThurinIdentity = useThurinIdentity; exports.verifyAttestation = _chunkNL4LHKJXcjs.verifyAttestation; exports.verifyProof = _chunkNL4LHKJXcjs.verifyProof;
430
+ exports.AUTHORIZATION_TYPES = _chunkRC4PCCYVcjs.AUTHORIZATION_TYPES; exports.EIP712_NAME = _chunkRC4PCCYVcjs.EIP712_NAME; exports.EIP712_VERSION = _chunkRC4PCCYVcjs.EIP712_VERSION; exports.IdentityKitProvider = IdentityKitProvider; exports.NETWORKS = _chunkRC4PCCYVcjs.NETWORKS; exports.REGISTRY_ABI = _chunkRC4PCCYVcjs.REGISTRY_ABI; exports.REGISTRY_ADDRESS = _chunkRC4PCCYVcjs.REGISTRY_ADDRESS; exports.ThurinCard = ThurinCard; exports.attestTypedData = _chunkRC4PCCYVcjs.attestTypedData; exports.authorizationDigest = _chunkRC4PCCYVcjs.authorizationDigest; exports.bytesToFingerprint = _chunkRC4PCCYVcjs.bytesToFingerprint; exports.chainFor = _chunkRC4PCCYVcjs.chainFor; exports.displayUrl = _chunkRC4PCCYVcjs.displayUrl; exports.fetchEFPGraph = _chunkRC4PCCYVcjs.fetchEFPGraph; exports.fetchKeyByFingerprint = _chunkRC4PCCYVcjs.fetchKeyByFingerprint; exports.fetchKeyByKeyId = _chunkRC4PCCYVcjs.fetchKeyByKeyId; exports.fingerprintHash = _chunkRC4PCCYVcjs.fingerprintHash; exports.fingerprintToBytes = _chunkRC4PCCYVcjs.fingerprintToBytes; exports.getRegistry = _chunkRC4PCCYVcjs.getRegistry; exports.hasEmailUserID = _chunkRC4PCCYVcjs.hasEmailUserID; exports.identifyProof = _chunkRC4PCCYVcjs.identifyProof; exports.isNetworkName = _chunkRC4PCCYVcjs.isNetworkName; exports.keyIdOf = _chunkRC4PCCYVcjs.keyIdOf; exports.keyIdToBytes = _chunkRC4PCCYVcjs.keyIdToBytes; exports.normalizeFingerprint = _chunkRC4PCCYVcjs.normalizeFingerprint; exports.parsePgpKey = _chunkRC4PCCYVcjs.parsePgpKey; exports.proofHref = _chunkRC4PCCYVcjs.proofHref; exports.proofSecondaryHref = _chunkRC4PCCYVcjs.proofSecondaryHref; exports.reattestTypedData = _chunkRC4PCCYVcjs.reattestTypedData; exports.recordKind = _chunkRC4PCCYVcjs.recordKind; exports.registryDomain = _chunkRC4PCCYVcjs.registryDomain; exports.revokeTypedData = _chunkRC4PCCYVcjs.revokeTypedData; exports.setRecordTypedData = _chunkRC4PCCYVcjs.setRecordTypedData; exports.stripEmailUserIDs = _chunkRC4PCCYVcjs.stripEmailUserIDs; exports.updateKeyTypedData = _chunkRC4PCCYVcjs.updateKeyTypedData; exports.useAttestations = useAttestations; exports.useEFPGraph = useEFPGraph; exports.usePGPProofs = usePGPProofs; exports.useThurinIdentity = useThurinIdentity; exports.verifyAttestation = _chunkRC4PCCYVcjs.verifyAttestation; exports.verifyProof = _chunkRC4PCCYVcjs.verifyProof;
431
431
  //# sourceMappingURL=index.cjs.map
package/dist/index.js CHANGED
@@ -34,7 +34,7 @@ import {
34
34
  updateKeyTypedData,
35
35
  verifyAttestation,
36
36
  verifyProof
37
- } from "./chunk-TAJWEWED.js";
37
+ } from "./chunk-GKL42VHZ.js";
38
38
 
39
39
  // src/provider.tsx
40
40
  import { useMemo } from "react";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thurinlabs/identity-kit",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "React SDK for embedding Thurin identity data",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/ben/code/thurinlabs/identity-kit/dist/chunk-NL4LHKJX.cjs","../src/core/abi.ts","../src/core/contract.ts","../src/core/fingerprint.ts","../src/core/pgp.ts","../src/core/efp.ts","../src/core/proofs.ts","../src/core/authorization.ts"],"names":[],"mappings":"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,IAAA;AACA,IAAA;AACK,IAAA;AACL,IAAA;AACG,IAAA;AACtC,EAAA;AACQ,EAAA;AAC2B,IAAA;AACA,IAAA;AACA,IAAA;AACG,IAAA;AACtC,EAAA;AACW,EAAA;AACwB,IAAA;AACA,IAAA;AACD,IAAA;AACD,IAAA;AACE,IAAA;AACG,IAAA;AACtC,EAAA;AACF;AAgBwF;AAC/E,EAAA;AACmC,IAAA;AACI,IAAA;AAC/B,IAAA;AACJ,IAAA;AACE,MAAA;AACoC,MAAA;AACL,MAAA;AACA,MAAA;AAC/B,MAAA;AACG,MAAA;AACd,IAAA;AACF,EAAA;AACF;AAE4F;AACzC,EAAA;AAC1C,EAAA;AACQ,IAAA;AACmC,IAAA;AACnC,IAAA;AAC8B,IAAA;AAC7C,EAAA;AACF;AAE8F;AACrF,EAAA;AACmC,IAAA;AACU,IAAA;AACrC,IAAA;AAC8B,IAAA;AAC7C,EAAA;AACF;AAEwF;AAC/E,EAAA;AACmC,IAAA;AACI,IAAA;AAC/B,IAAA;AACqC,IAAA;AACpD,EAAA;AACF;AAE8F;AACrF,EAAA;AACmC,IAAA;AACU,IAAA;AACrC,IAAA;AACoC,IAAA;AACnD,EAAA;AACF;AAGoM;AAC7J,EAAA;AACvC;AAG8C;AACV,EAAA;AACpC;APmpDsD;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/chunk-NL4LHKJX.cjs","sourcesContent":[null,"// Generated from pgp-registry: `forge inspect PGPRegistry abi --json`. Do not edit by hand.\nexport const REGISTRY_ABI = [\n {\n \"type\": \"function\",\n \"name\": \"ATTEST_TYPEHASH\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"DOMAIN_SEPARATOR\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"EIP712_NAME\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"EIP712_VERSION\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"MAX_KEY_BYTES\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"MAX_RECORD_BYTES\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"MAX_SIG_BYTES\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"MESSAGE_VERSION\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint8\",\n \"internalType\": \"uint8\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"REATTEST_TYPEHASH\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"REVOKE_TYPEHASH\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"SET_RECORD_TYPEHASH\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"UPDATE_KEY_TYPEHASH\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"VERSION\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint8\",\n \"internalType\": \"uint8\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"addressesFor\",\n \"inputs\": [\n {\n \"name\": \"fingerprintHash\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"address[]\",\n \"internalType\": \"address[]\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"addressesForCount\",\n \"inputs\": [\n {\n \"name\": \"fingerprintHash\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"addressesForRange\",\n \"inputs\": [\n {\n \"name\": \"fingerprintHash\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"start\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"count\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"out\",\n \"type\": \"address[]\",\n \"internalType\": \"address[]\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"attest\",\n \"inputs\": [\n {\n \"name\": \"fingerprint\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"pgpSignature\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"pgpPublicKey\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"index\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"attestFor\",\n \"inputs\": [\n {\n \"name\": \"owner\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"fingerprint\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"pgpSignature\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"pgpPublicKey\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"deadline\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"signature\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"index\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"attestationCount\",\n \"inputs\": [\n {\n \"name\": \"owner\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"attestationsOf\",\n \"inputs\": [\n {\n \"name\": \"owner\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"tuple[]\",\n \"internalType\": \"struct PGPRegistry.Attestation[]\",\n \"components\": [\n {\n \"name\": \"fingerprint\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"createdAt\",\n \"type\": \"uint64\",\n \"internalType\": \"uint64\"\n },\n {\n \"name\": \"revokedAt\",\n \"type\": \"uint64\",\n \"internalType\": \"uint64\"\n },\n {\n \"name\": \"messageVersion\",\n \"type\": \"uint8\",\n \"internalType\": \"uint8\"\n },\n {\n \"name\": \"keyPtr\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"sigPtr\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ]\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"attestationsOfRange\",\n \"inputs\": [\n {\n \"name\": \"owner\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"start\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"count\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"out\",\n \"type\": \"tuple[]\",\n \"internalType\": \"struct PGPRegistry.Attestation[]\",\n \"components\": [\n {\n \"name\": \"fingerprint\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"createdAt\",\n \"type\": \"uint64\",\n \"internalType\": \"uint64\"\n },\n {\n \"name\": \"revokedAt\",\n \"type\": \"uint64\",\n \"internalType\": \"uint64\"\n },\n {\n \"name\": \"messageVersion\",\n \"type\": \"uint8\",\n \"internalType\": \"uint8\"\n },\n {\n \"name\": \"keyPtr\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"sigPtr\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ]\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"cancelAuthorization\",\n \"inputs\": [],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"current\",\n \"inputs\": [\n {\n \"name\": \"owner\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"found\",\n \"type\": \"bool\",\n \"internalType\": \"bool\"\n },\n {\n \"name\": \"index\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"attestation\",\n \"type\": \"tuple\",\n \"internalType\": \"struct PGPRegistry.Attestation\",\n \"components\": [\n {\n \"name\": \"fingerprint\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"createdAt\",\n \"type\": \"uint64\",\n \"internalType\": \"uint64\"\n },\n {\n \"name\": \"revokedAt\",\n \"type\": \"uint64\",\n \"internalType\": \"uint64\"\n },\n {\n \"name\": \"messageVersion\",\n \"type\": \"uint8\",\n \"internalType\": \"uint8\"\n },\n {\n \"name\": \"keyPtr\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"sigPtr\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ]\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"fingerprintsForKeyId\",\n \"inputs\": [\n {\n \"name\": \"keyId\",\n \"type\": \"bytes8\",\n \"internalType\": \"bytes8\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bytes[]\",\n \"internalType\": \"bytes[]\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"fingerprintsForKeyIdCount\",\n \"inputs\": [\n {\n \"name\": \"keyId\",\n \"type\": \"bytes8\",\n \"internalType\": \"bytes8\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"fingerprintsForKeyIdRange\",\n \"inputs\": [\n {\n \"name\": \"keyId\",\n \"type\": \"bytes8\",\n \"internalType\": \"bytes8\"\n },\n {\n \"name\": \"start\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"count\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"out\",\n \"type\": \"bytes[]\",\n \"internalType\": \"bytes[]\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getAttestation\",\n \"inputs\": [\n {\n \"name\": \"owner\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"index\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"tuple\",\n \"internalType\": \"struct PGPRegistry.Attestation\",\n \"components\": [\n {\n \"name\": \"fingerprint\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"createdAt\",\n \"type\": \"uint64\",\n \"internalType\": \"uint64\"\n },\n {\n \"name\": \"revokedAt\",\n \"type\": \"uint64\",\n \"internalType\": \"uint64\"\n },\n {\n \"name\": \"messageVersion\",\n \"type\": \"uint8\",\n \"internalType\": \"uint8\"\n },\n {\n \"name\": \"keyPtr\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"sigPtr\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ]\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getPayload\",\n \"inputs\": [\n {\n \"name\": \"owner\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"index\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"pgpSignature\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"pgpPublicKey\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"nonces\",\n \"inputs\": [\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"reattest\",\n \"inputs\": [\n {\n \"name\": \"revokeIndex\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"fingerprint\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"pgpSignature\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"pgpPublicKey\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"index\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"reattestFor\",\n \"inputs\": [\n {\n \"name\": \"owner\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"revokeIndex\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"fingerprint\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"pgpSignature\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"pgpPublicKey\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"deadline\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"signature\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"index\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"record\",\n \"inputs\": [\n {\n \"name\": \"owner\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"index\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"kind\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"revoke\",\n \"inputs\": [\n {\n \"name\": \"index\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"revokeFor\",\n \"inputs\": [\n {\n \"name\": \"owner\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"index\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"deadline\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"signature\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"setRecord\",\n \"inputs\": [\n {\n \"name\": \"index\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"kind\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"value\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"setRecordFor\",\n \"inputs\": [\n {\n \"name\": \"owner\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"index\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"kind\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"value\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"deadline\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"signature\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"updateKey\",\n \"inputs\": [\n {\n \"name\": \"index\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"pgpPublicKey\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"updateKeyFor\",\n \"inputs\": [\n {\n \"name\": \"owner\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"index\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"pgpPublicKey\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"deadline\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"signature\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"event\",\n \"name\": \"Attested\",\n \"inputs\": [\n {\n \"name\": \"owner\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"fingerprintHash\",\n \"type\": \"bytes32\",\n \"indexed\": true,\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"index\",\n \"type\": \"uint256\",\n \"indexed\": true,\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"fingerprint\",\n \"type\": \"bytes\",\n \"indexed\": false,\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"messageVersion\",\n \"type\": \"uint8\",\n \"indexed\": false,\n \"internalType\": \"uint8\"\n },\n {\n \"name\": \"keyPtr\",\n \"type\": \"address\",\n \"indexed\": false,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"sigPtr\",\n \"type\": \"address\",\n \"indexed\": false,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"submitter\",\n \"type\": \"address\",\n \"indexed\": false,\n \"internalType\": \"address\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"KeyUpdated\",\n \"inputs\": [\n {\n \"name\": \"owner\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"fingerprintHash\",\n \"type\": \"bytes32\",\n \"indexed\": true,\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"index\",\n \"type\": \"uint256\",\n \"indexed\": true,\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"oldKeyPtr\",\n \"type\": \"address\",\n \"indexed\": false,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"newKeyPtr\",\n \"type\": \"address\",\n \"indexed\": false,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"submitter\",\n \"type\": \"address\",\n \"indexed\": false,\n \"internalType\": \"address\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"NonceUsed\",\n \"inputs\": [\n {\n \"name\": \"owner\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"nonce\",\n \"type\": \"uint256\",\n \"indexed\": false,\n \"internalType\": \"uint256\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"RecordSet\",\n \"inputs\": [\n {\n \"name\": \"owner\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"index\",\n \"type\": \"uint256\",\n \"indexed\": true,\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"kind\",\n \"type\": \"bytes32\",\n \"indexed\": true,\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"submitter\",\n \"type\": \"address\",\n \"indexed\": false,\n \"internalType\": \"address\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"Revoked\",\n \"inputs\": [\n {\n \"name\": \"owner\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"fingerprintHash\",\n \"type\": \"bytes32\",\n \"indexed\": true,\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"index\",\n \"type\": \"uint256\",\n \"indexed\": true,\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"submitter\",\n \"type\": \"address\",\n \"indexed\": false,\n \"internalType\": \"address\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"error\",\n \"name\": \"AlreadyRevoked\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"AuthorizationExpired\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"DeploymentFailed\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"DuplicateActiveFingerprint\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"EmptyPublicKey\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"EmptySignature\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"IndexOutOfBounds\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"InvalidAuthorization\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"InvalidFingerprintLength\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"InvalidPointer\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"PublicKeyTooLarge\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"RecordTooLarge\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"SignatureTooLarge\",\n \"inputs\": []\n }\n] as const\n","import { mainnet, sepolia, foundry } from 'viem/chains'\nexport { REGISTRY_ABI } from './abi'\n\n/**\n * PGPRegistry v2 is deployed with CREATE2, so it has the same address on every\n * network. (v1 lived at 0xf7a45BC662A78a6fb417ED5f52b3766cbf13EbBb on mainnet and\n * is no longer read by Thurin.)\n */\nexport const REGISTRY_ADDRESS = '0x9302E02e2869e129aC8516fE5eFFd51EA3082c09' as const\n\n/** Networks the PGPRegistry is deployed on. `mainnet` is the default everywhere. */\nexport type NetworkName = 'mainnet' | 'sepolia' | 'local'\n\nexport interface RegistryDeployment {\n chainId: number\n address: `0x${string}`\n /** Block the registry was deployed in (informational; v2 needs no log scans). */\n deployBlock: bigint\n /** Block explorer base URL for address/tx links. Empty when there is none. */\n explorerUrl: string\n /** Keyless public RPC used when no rpcUrl is configured. */\n defaultRpcUrl: string\n}\n\nexport const NETWORKS: Record<NetworkName, RegistryDeployment> = {\n mainnet: {\n chainId: 1,\n address: REGISTRY_ADDRESS,\n deployBlock: 25962908n, // 2026-09-12, tx 0xda4c3a19cae4e71ffb02559a048403f664d5a7967c19d42158c39600ec63bad8\n explorerUrl: 'https://etherscan.io',\n defaultRpcUrl: 'https://ethereum-rpc.publicnode.com',\n },\n sepolia: {\n chainId: 11155111,\n address: REGISTRY_ADDRESS,\n deployBlock: 11683667n, // 2026-09-11, tx 0x3e40e8f5b9fbf82a4b8943561bcc9b964b2987de10640ac8ff3a1b4ef0725322\n explorerUrl: 'https://sepolia.etherscan.io',\n defaultRpcUrl: 'https://ethereum-sepolia-rpc.publicnode.com',\n },\n /** A local anvil instance (`anvil`, chain id 31337). Deploy with pgp-registry's Deploy script. */\n local: {\n chainId: 31337,\n address: REGISTRY_ADDRESS,\n deployBlock: 0n,\n explorerUrl: '',\n defaultRpcUrl: 'http://127.0.0.1:8545',\n },\n}\n\nexport function isNetworkName(value: unknown): value is NetworkName {\n return value === 'mainnet' || value === 'sepolia' || value === 'local'\n}\n\n/**\n * The registry deployment for a network. `addressOverride` swaps the contract\n * address (e.g. a local deploy that landed somewhere else).\n */\nexport function getRegistry(network: NetworkName = 'mainnet', addressOverride?: string): RegistryDeployment {\n const r = NETWORKS[network]\n if (!r) throw new Error(`Unknown network: ${network}`)\n if (addressOverride && /^0x[0-9a-fA-F]{40}$/.test(addressOverride)) {\n return { ...r, address: addressOverride as `0x${string}` }\n }\n return r\n}\n\n/** The viem chain object for a network name. */\nexport function chainFor(network: NetworkName = 'mainnet') {\n if (network === 'sepolia') return sepolia\n if (network === 'local') return foundry\n return mainnet\n}\n","import { keccak256, type Hex } from 'viem'\n\n/** 40 hex chars (OpenPGP v4) or 64 hex chars (v6), spaces/0x tolerated. */\nconst FINGERPRINT_HEX = /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/\n\n/** Normalize a fingerprint to lowercase hex with no prefix or spaces. Returns null if malformed. */\nexport function normalizeFingerprint(input: string): string | null {\n const hex = input.replace(/^0x/i, '').replace(/\\s+/g, '').toLowerCase()\n return FINGERPRINT_HEX.test(hex) ? hex : null\n}\n\n/** Fingerprint → the raw `bytes` argument the v2 registry takes (0x-prefixed, 20 or 32 bytes). */\nexport function fingerprintToBytes(fingerprint: string): Hex {\n const hex = normalizeFingerprint(fingerprint)\n if (!hex) throw new Error(`Invalid PGP fingerprint: ${fingerprint}`)\n return `0x${hex}`\n}\n\n/** Raw `bytes` from the registry → lowercase hex fingerprint without 0x. */\nexport function bytesToFingerprint(bytes: Hex | string): string {\n return bytes.replace(/^0x/i, '').toLowerCase()\n}\n\n/** keccak256 of the raw fingerprint bytes — the `fingerprintHash` the registry indexes by. */\nexport function fingerprintHash(fingerprint: string): Hex {\n return keccak256(fingerprintToBytes(fingerprint))\n}\n\n/**\n * The long key ID as the `bytes8` the registry indexes by. Per RFC 9580 §5.5.4 it is the\n * low-order 8 bytes of a v4 (20-byte) fingerprint and the high-order 8 bytes of a v6\n * (32-byte) fingerprint — the same value `gpg --keyid-format long` prints.\n */\nexport function keyIdOf(fingerprint: string): Hex {\n const hex = normalizeFingerprint(fingerprint)\n if (!hex) throw new Error(`Invalid PGP fingerprint: ${fingerprint}`)\n return `0x${keyIdHex(hex)}`\n}\n\n/** Long key ID (16 lowercase hex chars) of a normalized fingerprint. */\nexport function keyIdHex(normalizedFingerprint: string): string {\n return normalizedFingerprint.length === 64 ? normalizedFingerprint.slice(0, 16) : normalizedFingerprint.slice(-16)\n}\n\n/** A 16-hex long key ID (spaces/0x tolerated) → `bytes8`. */\nexport function keyIdToBytes(keyId: string): Hex | null {\n const hex = keyId.replace(/^0x/i, '').replace(/\\s+/g, '').toLowerCase()\n return /^[0-9a-f]{16}$/.test(hex) ? `0x${hex}` : null\n}\n","import type { PGPKeyInfo, PGPVerification } from './types'\n\n/**\n * openpgp.js refuses secp256k1 by default because RFC 9580 does not list the\n * curve — a compatibility choice, not a security one. A secp256k1 PGP key is a\n * valid key (and, incidentally, doubles as an Ethereum key: the address falls out\n * of the same public point). Thurin verifies signatures over any curve openpgp.js\n * can compute; whether a holder reuses such a key as a wallet is their business.\n * In Node, openpgp.js needs the optional `eckey-utils` package for this curve;\n * the browser build does not.\n *\n * The low-level packet/key methods take a *complete* config (they index into\n * it), so this builds one from the library's defaults rather than passing a\n * partial object.\n */\nfunction pgpConfig(openpgp: typeof import('openpgp')) {\n return { ...openpgp.config, rejectCurves: new Set() as Set<never> }\n}\n\n/** Human-readable algorithm for a key or subkey packet: \"Ed25519\", \"Cv25519\", \"RSA 4096\", \"NIST P-256\", … */\nfunction algorithmName(keyOrSubkey: any): string {\n try {\n const info = keyOrSubkey.getAlgorithmInfo() as { algorithm: string; bits?: number; curve?: string }\n const curve = (info.curve || '').toLowerCase()\n if (curve.startsWith('ed25519') || info.algorithm === 'ed25519' || info.algorithm === 'eddsaLegacy') return 'Ed25519'\n if (curve.startsWith('curve25519') || info.algorithm === 'x25519') return 'Cv25519'\n if (curve.startsWith('ed448')) return 'Ed448'\n if (curve.startsWith('curve448') || info.algorithm === 'x448') return 'X448'\n if (curve.startsWith('nistp') || curve.startsWith('p')) return `NIST P-${curve.replace(/\\D/g, '')}`\n if (curve.startsWith('secp')) return curve\n if (curve.startsWith('brainpool')) return curve\n if (info.algorithm.startsWith('rsa')) return info.bits ? `RSA ${info.bits}` : 'RSA'\n if (info.algorithm.startsWith('dsa')) return info.bits ? `DSA ${info.bits}` : 'DSA'\n if (info.algorithm.startsWith('elgamal')) return info.bits ? `ElGamal ${info.bits}` : 'ElGamal'\n return info.curve || info.algorithm\n } catch {\n return String(keyOrSubkey.keyPacket?.algorithm ?? 'unknown')\n }\n}\n\nexport async function parsePgpKey(armoredKey: string): Promise<PGPKeyInfo | null> {\n try {\n const openpgp = await import('openpgp')\n const { readKey } = openpgp\n const config = pgpConfig(openpgp)\n const key = await readKey({ armoredKey })\n const fingerprint = key.getFingerprint().toUpperCase()\n const algorithm = algorithmName(key)\n const created = key.keyPacket.created?.toISOString() ?? null\n const expiration = await key.getExpirationTime()\n const expires =\n expiration && expiration !== Infinity\n ? new Date(expiration as number).toISOString()\n : null\n\n // openpgp does not verify certification signatures when a key is parsed —\n // it groups them by issuer key ID only. A key's fingerprint also covers\n // only the primary key packet, not its user IDs or their certifications.\n // Each self-certification is therefore verified against the primary key\n // here before its user ID and notations are treated as authoritative.\n const userIDs: string[] = []\n const notations: { name: string; value: string }[] = []\n const seen = new Set<string>()\n for (const user of key.users) {\n const certs = (user as any).selfCertifications\n if (!certs || certs.length === 0) continue\n\n let userVerified = false\n for (const cert of certs) {\n try {\n await cert.verify(\n key.keyPacket,\n cert.signatureType,\n { userID: (user as any).userID, key: key.keyPacket },\n undefined, // date: now\n undefined, // detached\n config,\n )\n } catch {\n continue // signature not made by this key — ignore this certification\n }\n userVerified = true\n\n if (cert.rawNotations) {\n for (const n of cert.rawNotations) {\n const name =\n typeof n.name === 'string' ? n.name : new TextDecoder().decode(n.name)\n const value =\n n.value instanceof Uint8Array\n ? new TextDecoder().decode(n.value)\n : typeof n.value === 'string'\n ? n.value\n : null\n if (value) {\n // Dedupe by value alone: the same proof target is often present\n // under both proof@thurin.id and proof@ariadne.id, and should\n // surface once, not once per namespace.\n if (!seen.has(value)) {\n seen.add(value)\n notations.push({ name, value })\n }\n }\n }\n }\n }\n\n if (userVerified) {\n const uid = (user as any).userID?.userID\n if (uid) userIDs.push(uid)\n }\n }\n\n const subkeys = key.subkeys.map((sk: any) => ({\n algorithm: algorithmName(sk),\n created: sk.keyPacket.created?.toISOString() ?? null,\n fingerprint: sk.getFingerprint().toUpperCase(),\n }))\n\n return { fingerprint, userIDs, algorithm, created, expires, notations, subkeys }\n } catch {\n return null\n }\n}\n\nexport async function verifyAttestation({\n pgpPublicKey,\n pgpSignature,\n fingerprint,\n ethAddress,\n}: {\n pgpPublicKey: string | null\n pgpSignature: string | null\n fingerprint: string\n ethAddress: string\n}): Promise<PGPVerification> {\n try {\n if (!pgpPublicKey || !pgpSignature) {\n return { verified: false, reason: 'Missing PGP data' }\n }\n\n const openpgp = await import('openpgp')\n const { readKey, readCleartextMessage, LiteralDataPacket } = openpgp\n const config = pgpConfig(openpgp)\n\n const publicKey = await readKey({ armoredKey: pgpPublicKey })\n const keyFingerprint = publicKey.getFingerprint().toUpperCase()\n if (keyFingerprint !== fingerprint.toUpperCase()) {\n return { verified: false, reason: 'Key fingerprint mismatch' }\n }\n\n const message = await readCleartextMessage({ cleartextMessage: pgpSignature })\n\n // Verify the way gpg does: the key (or subkey) must be valid *now* — bound to\n // this primary, unrevoked, unexpired — and the signature must be sound. We\n // deliberately do not ask openpgp.verify(), which also demands the key was\n // valid at the instant the signature was made. Thurin's update flow tells\n // people to `export-minimal` after editing notations, which keeps only the\n // newest self-certification; when that postdates the attest signature\n // (Ben's own key, 2026-09-14: notations edited 16 minutes after signing),\n // openpgp.verify() reports \"Could not find valid self-signature\" for a\n // signature gpg verifies fine. A key that has since been revoked or expired\n // still fails here, as it should.\n // These are internals the .d.ts does not expose (the signature packet list,\n // the CRLF-normalised text, LiteralDataPacket.setText); they are stable across\n // openpgp.js 6 and exercised by the real-data tests in attestation.test.ts.\n const msg = message as any\n const now = new Date()\n let signed = false\n for (const sig of msg.signature.packets) {\n if (!publicKey.getKeys(sig.issuerKeyID).length) continue\n const signingKey = await publicKey.getSigningKey(sig.issuerKeyID, now, undefined, config)\n const literal: any = new LiteralDataPacket()\n literal.setText(msg.text ?? message.getText().replace(/\\r?\\n/g, '\\r\\n'))\n await sig.verify(signingKey.keyPacket, sig.signatureType, literal, now, true, config)\n signed = true\n break\n }\n if (!signed) return { verified: false, reason: 'Message is not signed by this key' }\n\n const signedText = message.getText()\n if (!signedText.toLowerCase().includes(ethAddress.toLowerCase())) {\n return { verified: false, reason: 'Signed message does not contain ETH address' }\n }\n\n return { verified: true }\n } catch {\n return { verified: false, reason: 'Signature verification failed' }\n }\n}\n\nexport interface StrippedKey {\n /** Armored public key containing only the non-email user IDs. */\n armored: string\n /** User IDs kept (no `@`). */\n kept: string[]\n /** User IDs removed (contained an `@`). */\n removed: string[]\n}\n\nconst EMAIL_UID = /@/\n\n/**\n * Remove every user ID that contains an email address, keeping the rest (and\n * their self-certifications, so proof notations on a non-email user ID survive).\n * Returns null when nothing would remain — openpgp needs at least one\n * self-certified user ID to verify signatures, so such a key must not be\n * published. The key material and subkeys are untouched; the fingerprint is\n * unchanged.\n */\nexport async function stripEmailUserIDs(armoredKey: string): Promise<StrippedKey | null> {\n try {\n const { readKey } = await import('openpgp')\n const key = await readKey({ armoredKey })\n const kept: string[] = []\n const removed: string[] = []\n const users = (key as any).users.filter((u: any) => {\n const uid: string | undefined = u.userID?.userID\n if (!uid) return false\n if (EMAIL_UID.test(uid)) { removed.push(uid); return false }\n kept.push(uid)\n return true\n })\n if (users.length === 0) return null\n ;(key as any).users = users\n return { armored: key.armor(), kept, removed }\n } catch {\n return null\n }\n}\n\n/** True when any user ID on the key contains an email address. */\nexport async function hasEmailUserID(armoredKey: string): Promise<boolean> {\n try {\n const { readKey } = await import('openpgp')\n const key = await readKey({ armoredKey })\n return (key as any).users.some((u: any) => EMAIL_UID.test(u.userID?.userID ?? ''))\n } catch {\n return false\n }\n}\n\nconst KEYSERVER_BASE = 'https://keys.openpgp.org/vks/v1'\n\nexport async function fetchKeyByFingerprint(fingerprint: string): Promise<string | null> {\n try {\n const resp = await fetch(`${KEYSERVER_BASE}/by-fingerprint/${fingerprint}`)\n if (!resp.ok) return null\n return await resp.text()\n } catch {\n return null\n }\n}\n\nexport async function fetchKeyByKeyId(keyId: string): Promise<string | null> {\n try {\n const resp = await fetch(`${KEYSERVER_BASE}/by-keyid/${keyId}`)\n if (!resp.ok) return null\n return await resp.text()\n } catch {\n return null\n }\n}\n","import type { EFPGraph } from './types'\n\nconst EFP_API = 'https://api.ethfollow.xyz/api/v1'\n\n/**\n * EFP social graph for an address. Followers are counted by EFP for any address,\n * whether or not it has published a list of its own; following and top-8 exist\n * only when it has (its \"primary list\"). An address with followers but no list\n * — a project account that has never followed anyone — is still on EFP.\n */\nexport async function fetchEFPGraph(address: string): Promise<EFPGraph | null> {\n try {\n const [statsResp, listsResp] = await Promise.all([\n fetch(`${EFP_API}/users/${address}/stats`),\n fetch(`${EFP_API}/users/${address}/lists`),\n ])\n if (!statsResp.ok && !listsResp.ok) return null\n\n const statsData = statsResp.ok ? await statsResp.json() : {}\n const listsData = listsResp.ok ? await listsResp.json() : {}\n const followers = parseInt(statsData.followers_count) || 0\n const listId = listsData.primary_list\n\n let following = 0\n let top8: string[] = []\n if (listId) {\n const [followingResp, top8Resp] = await Promise.all([\n fetch(`${EFP_API}/lists/${listId}/following?limit=100`),\n fetch(`${EFP_API}/lists/${listId}/following?limit=8&tags=top8`),\n ])\n const followingData = followingResp.ok ? await followingResp.json() : { following: [] }\n const top8Data = top8Resp.ok ? await top8Resp.json() : { following: [] }\n following = (followingData.following || []).length\n top8 = (top8Data.following || []).map((f: any) => f.data)\n }\n\n return { followers, following, top8, hasEfp: !!listId || followers > 0 }\n } catch {\n return null\n }\n}\n","import { keyIdHex } from './fingerprint'\nimport type { Notation, Proof, PGPVerification } from './types'\n\nconst PROVIDERS: {\n provider: string\n label: string\n pattern: RegExp\n parse: (m: RegExpMatchArray) => Record<string, string>\n}[] = [\n {\n provider: 'github',\n label: 'GitHub',\n pattern: /^https:\\/\\/gist\\.github\\.com\\/([^/]+)\\/([a-f0-9]+)$/i,\n parse: (m) => ({ user: m[1], gistId: m[2] }),\n },\n {\n // A repository's description — the form an organisation can use, since\n // gists belong to user accounts only. Same shape as the Codeberg proof.\n provider: 'github',\n label: 'GitHub',\n pattern: /^https:\\/\\/github\\.com\\/([A-Za-z0-9-]+)\\/([A-Za-z0-9._-]+)$/i,\n parse: (m) => ({ user: m[1], repo: m[2] }),\n },\n {\n provider: 'dns',\n label: 'DNS',\n // domain is restricted to a hostname (labels may include underscores for\n // records like _thurin.example.com); rejects slashes, userinfo, and spaces.\n pattern: /^dns:([a-z0-9._-]+)\\?type=TXT$/i,\n parse: (m) => ({ domain: m[1] }),\n },\n {\n provider: 'farcaster',\n label: 'Farcaster',\n pattern: /^https:\\/\\/farcaster\\.xyz\\/([^/]+)\\/(0x[a-f0-9]+)$/i,\n parse: (m) => ({ user: m[1], castHash: m[2] }),\n },\n {\n provider: 'codeberg',\n label: 'Codeberg',\n pattern: /^https:\\/\\/codeberg\\.org\\/([^/]+)\\/([^/]+)$/i,\n parse: (m) => ({ user: m[1], repo: m[2] }),\n },\n {\n provider: 'mastodon',\n label: 'Mastodon',\n // instance is restricted to a bare hostname (optional port) so a value\n // like \"mastodon.social@evil.com\" can't redirect the lookup elsewhere.\n pattern: /^https:\\/\\/([a-z0-9.-]+(?::\\d+)?)\\/@([^/@?#\\s]+)$/i,\n parse: (m) => ({ instance: m[1], user: m[2] }),\n },\n]\n\nexport function identifyProof(notation: Notation): Proof | null {\n if (notation.name !== 'proof@thurin.id') return null\n\n for (const { provider, label, pattern, parse } of PROVIDERS) {\n const m = notation.value.match(pattern)\n if (m) {\n return { provider, label, url: notation.value, ...parse(m) }\n }\n }\n\n return { provider: 'unknown', label: 'Unknown', url: notation.value }\n}\n\nexport function displayUrl(proof: Proof): string {\n if (proof.provider === 'dns') return proof.domain!\n if (proof.provider === 'github') return proof.user!\n if (proof.provider === 'farcaster') return `@${proof.user}`\n if (proof.provider === 'codeberg') return proof.user!\n if (proof.provider === 'mastodon') return `@${proof.user}@${proof.instance}`\n return proof.url\n}\n\nexport function proofHref(proof: Proof): string | null {\n if (proof.provider === 'dns') return `https://${proof.domain}`\n if (proof.provider === 'github') return `https://github.com/${proof.user}`\n if (proof.provider === 'farcaster') return `https://farcaster.xyz/${proof.user}`\n if (proof.provider === 'codeberg') return `https://codeberg.org/${proof.user}`\n if (proof.provider === 'mastodon') return `https://${proof.instance}/@${proof.user}`\n if (proof.url.startsWith('http')) return proof.url\n return null\n}\n\nexport function proofSecondaryHref(proof: Proof): string | null {\n if (proof.provider === 'github') return proof.url\n if (proof.provider === 'farcaster') return proof.url\n if (proof.provider === 'codeberg') return proof.url\n if (proof.provider === 'mastodon') return proof.url\n return null\n}\n\n// ─── Verification ──────────────────────────────────────────────────────────\n\nconst FPR_TOKEN = 'OPENPGP4FPR:'\n\nfunction containsFingerprint(text: string, fingerprint: string): boolean {\n return text.toUpperCase().includes(FPR_TOKEN + fingerprint.toUpperCase())\n}\n\nfunction containsFingerprintUrl(text: string, fingerprint: string): boolean {\n return text.toUpperCase().includes(fingerprint.toUpperCase())\n}\n\nasync function verifyGitHub(proof: Proof, fingerprint: string): Promise<PGPVerification> {\n if (proof.repo) return verifyGitHubRepo(proof, fingerprint)\n try {\n const resp = await fetch(`https://api.github.com/gists/${proof.gistId}`)\n if (!resp.ok) return { verified: false, reason: `GitHub API returned ${resp.status}` }\n const data = await resp.json()\n\n // A gist is identified solely by its globally-unique ID; the username in\n // the URL is not authoritative. Confirm the gist owner matches the claimed\n // account before trusting the token it contains.\n if (data.owner?.login?.toLowerCase() !== proof.user!.toLowerCase()) {\n return { verified: false, reason: 'Gist owner does not match claimed user' }\n }\n\n for (const file of Object.values(data.files || {}) as any[]) {\n if (file.content && containsFingerprint(file.content, fingerprint)) {\n return { verified: true }\n }\n }\n return { verified: false, reason: 'Fingerprint token not found in gist' }\n } catch (err: any) {\n return { verified: false, reason: `GitHub fetch failed: ${err.message}` }\n }\n}\n\nasync function verifyGitHubRepo(proof: Proof, fingerprint: string): Promise<PGPVerification> {\n try {\n const resp = await fetch(\n `https://api.github.com/repos/${encodeURIComponent(proof.user!)}/${encodeURIComponent(proof.repo!)}`,\n )\n if (!resp.ok) return { verified: false, reason: `GitHub API returned ${resp.status}` }\n const data = await resp.json()\n\n // GitHub follows renames and redirects, so the API may answer for a repo\n // under a different owner than the URL names. Only trust it if the owner\n // is the account being claimed.\n if (data.owner?.login?.toLowerCase() !== proof.user!.toLowerCase()) {\n return { verified: false, reason: 'Repository owner does not match claimed account' }\n }\n\n if (data.description && containsFingerprint(data.description, fingerprint)) {\n return { verified: true }\n }\n return { verified: false, reason: 'Fingerprint token not found in repository description' }\n } catch (err: any) {\n return { verified: false, reason: `GitHub fetch failed: ${err.message}` }\n }\n}\n\nasync function verifyDNS(proof: Proof, fingerprint: string): Promise<PGPVerification> {\n try {\n const resp = await fetch(\n `https://cloudflare-dns.com/dns-query?name=${encodeURIComponent(proof.domain!)}&type=TXT`,\n { headers: { Accept: 'application/dns-json' } },\n )\n if (!resp.ok) return { verified: false, reason: `DNS query returned ${resp.status}` }\n const data = await resp.json()\n\n for (const answer of data.Answer || []) {\n // TXT records only (type 16) — a CNAME or other record in the resolution\n // chain must not be eligible to match the token.\n if (answer.type !== 16) continue\n if (answer.data && containsFingerprint(answer.data, fingerprint)) {\n return { verified: true }\n }\n }\n return { verified: false, reason: 'Fingerprint token not found in TXT records' }\n } catch (err: any) {\n return { verified: false, reason: `DNS fetch failed: ${err.message}` }\n }\n}\n\nconst NEYNAR_HUB = 'https://hub-api.neynar.com'\n\nasync function resolveFid(\n username: string,\n apiKey: string,\n): Promise<number | null> {\n const resp = await fetch(\n `${NEYNAR_HUB}/v1/userNameProofByName?name=${encodeURIComponent(username)}`,\n { headers: { 'x-api-key': apiKey } },\n )\n if (!resp.ok) return null\n const data = await resp.json()\n return data.fid ?? null\n}\n\nasync function verifyFarcaster(\n proof: Proof,\n fingerprint: string,\n neynarApiKey?: string,\n): Promise<PGPVerification> {\n if (!neynarApiKey) {\n return { verified: false, reason: 'Farcaster verification requires a Neynar API key' }\n }\n\n try {\n const fid = await resolveFid(proof.user!, neynarApiKey)\n if (!fid) return { verified: false, reason: `Could not resolve Farcaster user \"${proof.user}\"` }\n\n const headers = { 'x-api-key': neynarApiKey }\n let pageToken = ''\n for (let page = 0; page < 5; page++) {\n const url = `${NEYNAR_HUB}/v1/castsByFid?fid=${fid}&pageSize=100&reverse=true${pageToken ? `&pageToken=${pageToken}` : ''}`\n const resp = await fetch(url, { headers })\n if (!resp.ok) return { verified: false, reason: `Farcaster Hub returned ${resp.status}` }\n const data = await resp.json()\n\n for (const msg of data.messages || []) {\n if (msg.hash && msg.hash.startsWith(proof.castHash!)) {\n const text = msg.data?.castAddBody?.text || ''\n if (containsFingerprint(text, fingerprint)) {\n return { verified: true }\n }\n // A short cast-hash prefix can match multiple casts; keep scanning\n // rather than stopping at the first prefix match without the token.\n }\n }\n\n if (!data.nextPageToken) break\n pageToken = data.nextPageToken\n }\n\n return { verified: false, reason: 'Cast not found' }\n } catch (err: any) {\n return { verified: false, reason: `Farcaster fetch failed: ${err.message}` }\n }\n}\n\nasync function verifyCodeberg(proof: Proof, fingerprint: string): Promise<PGPVerification> {\n try {\n const resp = await fetch(\n `https://codeberg.org/api/v1/repos/${encodeURIComponent(proof.user!)}/${encodeURIComponent(proof.repo!)}`,\n )\n if (!resp.ok) return { verified: false, reason: `Codeberg API returned ${resp.status}` }\n const data = await resp.json()\n\n if (data.description && containsFingerprint(data.description, fingerprint)) {\n return { verified: true }\n }\n\n return { verified: false, reason: 'Fingerprint token not found in repo description' }\n } catch (err: any) {\n return { verified: false, reason: `Codeberg fetch failed: ${err.message}` }\n }\n}\n\nasync function verifyMastodon(proof: Proof, fingerprint: string): Promise<PGPVerification> {\n try {\n // The instance host is user-supplied and interpolated into the request URL,\n // so restrict it to a bare hostname (optional port) before use — otherwise a\n // value such as \"mastodon.social@evil.com\" would send the lookup to another\n // server while still displaying as a legitimate handle.\n if (!proof.instance || !/^[a-z0-9.-]+(?::\\d+)?$/i.test(proof.instance)) {\n return { verified: false, reason: 'Invalid Mastodon instance host' }\n }\n const resp = await fetch(\n `https://${proof.instance}/api/v1/accounts/lookup?acct=${encodeURIComponent(proof.user!)}`,\n )\n if (!resp.ok) return { verified: false, reason: `Mastodon API returned ${resp.status}` }\n const data = await resp.json()\n\n const keyId = keyIdHex(fingerprint.replace(/^0x/i, '').replace(/\\s+/g, '').toLowerCase())\n\n for (const field of data.fields || []) {\n const text = field.value.replace(/<[^>]*>/g, '')\n if (containsFingerprintUrl(text, fingerprint) || containsFingerprintUrl(text, keyId)) {\n return { verified: true }\n }\n }\n\n if (data.note) {\n const text = data.note.replace(/<[^>]*>/g, '')\n if (containsFingerprintUrl(text, fingerprint) || containsFingerprintUrl(text, keyId)) {\n return { verified: true }\n }\n }\n\n return { verified: false, reason: 'Fingerprint not found in profile fields or bio' }\n } catch (err: any) {\n return { verified: false, reason: `Mastodon fetch failed: ${err.message}` }\n }\n}\n\ntype Verifier = (proof: Proof, fingerprint: string, neynarApiKey?: string) => Promise<PGPVerification>\n\nconst verifiers: Record<string, Verifier> = {\n github: verifyGitHub,\n dns: verifyDNS,\n farcaster: verifyFarcaster,\n codeberg: verifyCodeberg,\n mastodon: verifyMastodon,\n}\n\nexport async function verifyProof(\n proof: Proof,\n fingerprint: string,\n neynarApiKey?: string,\n): Promise<PGPVerification> {\n const fn = verifiers[proof.provider]\n if (!fn) return { verified: false, reason: 'Unknown provider' }\n return fn(proof, fingerprint, neynarApiKey)\n}\n","import { hashTypedData, keccak256, stringToHex, type Hex, type TypedDataDomain } from 'viem'\nimport { fingerprintToBytes } from './fingerprint'\n\n/**\n * EIP-712 authorizations for the registry's relayed writes (`attestFor`, `reattestFor`,\n * `updateKeyFor`, `revokeFor`, `setRecordFor`). The owner signs one of these typed\n * structs; anyone can then submit the matching call and pay the gas. Every field is\n * bound, plus the owner's current `nonce` (read with `nonces(owner)`) and a `deadline`.\n *\n * The domain includes the chain id, so an authorization for one network cannot be\n * replayed on another even though the registry has the same address everywhere.\n */\nexport const EIP712_NAME = 'Thurin PGPRegistry'\nexport const EIP712_VERSION = '2'\n\nexport function registryDomain(chainId: number, verifyingContract: Hex): TypedDataDomain {\n return { name: EIP712_NAME, version: EIP712_VERSION, chainId, verifyingContract }\n}\n\nexport const AUTHORIZATION_TYPES = {\n Attest: [\n { name: 'owner', type: 'address' },\n { name: 'fingerprint', type: 'bytes' },\n { name: 'pgpSignature', type: 'bytes' },\n { name: 'pgpPublicKey', type: 'bytes' },\n { name: 'nonce', type: 'uint256' },\n { name: 'deadline', type: 'uint256' },\n ],\n Reattest: [\n { name: 'owner', type: 'address' },\n { name: 'revokeIndex', type: 'uint256' },\n { name: 'fingerprint', type: 'bytes' },\n { name: 'pgpSignature', type: 'bytes' },\n { name: 'pgpPublicKey', type: 'bytes' },\n { name: 'nonce', type: 'uint256' },\n { name: 'deadline', type: 'uint256' },\n ],\n UpdateKey: [\n { name: 'owner', type: 'address' },\n { name: 'index', type: 'uint256' },\n { name: 'pgpPublicKey', type: 'bytes' },\n { name: 'nonce', type: 'uint256' },\n { name: 'deadline', type: 'uint256' },\n ],\n Revoke: [\n { name: 'owner', type: 'address' },\n { name: 'index', type: 'uint256' },\n { name: 'nonce', type: 'uint256' },\n { name: 'deadline', type: 'uint256' },\n ],\n SetRecord: [\n { name: 'owner', type: 'address' },\n { name: 'index', type: 'uint256' },\n { name: 'kind', type: 'bytes32' },\n { name: 'value', type: 'bytes' },\n { name: 'nonce', type: 'uint256' },\n { name: 'deadline', type: 'uint256' },\n ],\n} as const\n\nexport type AuthorizationAction = keyof typeof AUTHORIZATION_TYPES\n\ninterface Common { owner: Hex; nonce: bigint; deadline: bigint }\nexport type AttestAuthorization = Common & { fingerprint: string; pgpSignature: string; pgpPublicKey: string }\nexport type ReattestAuthorization = AttestAuthorization & { revokeIndex: bigint }\nexport type UpdateKeyAuthorization = Common & { index: bigint; pgpPublicKey: string }\nexport type RevokeAuthorization = Common & { index: bigint }\nexport type SetRecordAuthorization = Common & { index: bigint; kind: Hex; value: Hex }\n\n/**\n * Build the object to pass to viem/wagmi `signTypedData`. `fingerprint` is the hex\n * fingerprint; `pgpSignature` / `pgpPublicKey` are the armored text exactly as they\n * will be submitted (they are hashed as UTF-8 bytes).\n */\nexport function attestTypedData(chainId: number, registry: Hex, a: AttestAuthorization) {\n return {\n domain: registryDomain(chainId, registry),\n types: { Attest: AUTHORIZATION_TYPES.Attest },\n primaryType: 'Attest' as const,\n message: {\n owner: a.owner,\n fingerprint: fingerprintToBytes(a.fingerprint),\n pgpSignature: stringToHex(a.pgpSignature),\n pgpPublicKey: stringToHex(a.pgpPublicKey),\n nonce: a.nonce,\n deadline: a.deadline,\n },\n }\n}\n\nexport function reattestTypedData(chainId: number, registry: Hex, a: ReattestAuthorization) {\n const base = attestTypedData(chainId, registry, a)\n return {\n domain: base.domain,\n types: { Reattest: AUTHORIZATION_TYPES.Reattest },\n primaryType: 'Reattest' as const,\n message: { ...base.message, revokeIndex: a.revokeIndex },\n }\n}\n\nexport function updateKeyTypedData(chainId: number, registry: Hex, a: UpdateKeyAuthorization) {\n return {\n domain: registryDomain(chainId, registry),\n types: { UpdateKey: AUTHORIZATION_TYPES.UpdateKey },\n primaryType: 'UpdateKey' as const,\n message: { owner: a.owner, index: a.index, pgpPublicKey: stringToHex(a.pgpPublicKey), nonce: a.nonce, deadline: a.deadline },\n }\n}\n\nexport function revokeTypedData(chainId: number, registry: Hex, a: RevokeAuthorization) {\n return {\n domain: registryDomain(chainId, registry),\n types: { Revoke: AUTHORIZATION_TYPES.Revoke },\n primaryType: 'Revoke' as const,\n message: { owner: a.owner, index: a.index, nonce: a.nonce, deadline: a.deadline },\n }\n}\n\nexport function setRecordTypedData(chainId: number, registry: Hex, a: SetRecordAuthorization) {\n return {\n domain: registryDomain(chainId, registry),\n types: { SetRecord: AUTHORIZATION_TYPES.SetRecord },\n primaryType: 'SetRecord' as const,\n message: { owner: a.owner, index: a.index, kind: a.kind, value: a.value, nonce: a.nonce, deadline: a.deadline },\n }\n}\n\n/** The digest the registry recovers the signer from — handy for tests and CLIs. */\nexport function authorizationDigest(typedData: ReturnType<typeof attestTypedData | typeof reattestTypedData | typeof updateKeyTypedData | typeof revokeTypedData | typeof setRecordTypedData>): Hex {\n return hashTypedData(typedData as any)\n}\n\n/** `bytes32 kind` for a record from a human-readable name, e.g. recordKind('thurin.vouch'). */\nexport function recordKind(name: string): Hex {\n return keccak256(stringToHex(name))\n}\n"]}