@thurinlabs/identity-kit 1.3.1 → 1.3.3

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.
@@ -24932,239 +24932,6 @@ ${prettyStateOverride(stateOverride)}`;
24932
24932
  }
24933
24933
  }
24934
24934
 
24935
- // node_modules/viem/_esm/errors/ens.js
24936
- init_base();
24937
- var EnsAvatarInvalidMetadataError = class extends BaseError {
24938
- constructor({ data }) {
24939
- super("Unable to extract image from metadata. The metadata may be malformed or invalid.", {
24940
- metaMessages: [
24941
- "- Metadata must be a JSON object with at least an `image`, `image_url` or `image_data` property.",
24942
- "",
24943
- `Provided data: ${JSON.stringify(data)}`
24944
- ],
24945
- name: "EnsAvatarInvalidMetadataError"
24946
- });
24947
- }
24948
- };
24949
- var EnsAvatarInvalidNftUriError = class extends BaseError {
24950
- constructor({ reason }) {
24951
- super(`ENS NFT avatar URI is invalid. ${reason}`, {
24952
- name: "EnsAvatarInvalidNftUriError"
24953
- });
24954
- }
24955
- };
24956
- var EnsAvatarUriResolutionError = class extends BaseError {
24957
- constructor({ uri }) {
24958
- super(`Unable to resolve ENS avatar URI "${uri}". The URI may be malformed, invalid, or does not respond with a valid image.`, { name: "EnsAvatarUriResolutionError" });
24959
- }
24960
- };
24961
- var EnsAvatarUnsupportedNamespaceError = class extends BaseError {
24962
- constructor({ namespace }) {
24963
- super(`ENS NFT avatar namespace "${namespace}" is not supported. Must be "erc721" or "erc1155".`, { name: "EnsAvatarUnsupportedNamespaceError" });
24964
- }
24965
- };
24966
-
24967
- // node_modules/viem/_esm/utils/ens/avatar/utils.js
24968
- var networkRegex = /(?<protocol>https?:\/\/[^/]*|ipfs:\/|ipns:\/|ar:\/)?(?<root>\/)?(?<subpath>ipfs\/|ipns\/)?(?<target>[\w\-.]+)(?<subtarget>\/.*)?/;
24969
- var ipfsHashRegex = /^(Qm[1-9A-HJ-NP-Za-km-z]{44,}|b[A-Za-z2-7]{58,}|B[A-Z2-7]{58,}|z[1-9A-HJ-NP-Za-km-z]{48,}|F[0-9A-F]{50,})(\/(?<target>[\w\-.]+))?(?<subtarget>\/.*)?$/;
24970
- var base64Regex = /^data:([a-zA-Z\-/+]*);base64,([^"].*)/;
24971
- var dataURIRegex = /^data:([a-zA-Z\-/+]*)?(;[a-zA-Z0-9].*?)?(,)/;
24972
- async function isImageUri(uri) {
24973
- try {
24974
- const res = await fetch(uri, { method: "HEAD" });
24975
- if (res.status === 200) {
24976
- const contentType = res.headers.get("content-type");
24977
- return contentType?.startsWith("image/");
24978
- }
24979
- return false;
24980
- } catch (error) {
24981
- if (typeof error === "object" && typeof error.response !== "undefined") {
24982
- return false;
24983
- }
24984
- if (!Object.hasOwn(globalThis, "Image"))
24985
- return false;
24986
- return new Promise((resolve) => {
24987
- const img = new Image();
24988
- img.onload = () => {
24989
- resolve(true);
24990
- };
24991
- img.onerror = () => {
24992
- resolve(false);
24993
- };
24994
- img.src = uri;
24995
- });
24996
- }
24997
- }
24998
- function getGateway(custom2, defaultGateway) {
24999
- if (!custom2)
25000
- return defaultGateway;
25001
- if (custom2.endsWith("/"))
25002
- return custom2.slice(0, -1);
25003
- return custom2;
25004
- }
25005
- function resolveAvatarUri({ uri, gatewayUrls }) {
25006
- const isEncoded = base64Regex.test(uri);
25007
- if (isEncoded)
25008
- return { uri, isOnChain: true, isEncoded };
25009
- const ipfsGateway = getGateway(gatewayUrls?.ipfs, "https://ipfs.io");
25010
- const arweaveGateway = getGateway(gatewayUrls?.arweave, "https://arweave.net");
25011
- const networkRegexMatch = uri.match(networkRegex);
25012
- const { protocol, subpath, target, subtarget = "" } = networkRegexMatch?.groups || {};
25013
- const isIPNS = protocol === "ipns:/" || subpath === "ipns/";
25014
- const isIPFS = protocol === "ipfs:/" || subpath === "ipfs/" || ipfsHashRegex.test(uri);
25015
- if (uri.startsWith("http") && !isIPNS && !isIPFS) {
25016
- let replacedUri = uri;
25017
- if (gatewayUrls?.arweave)
25018
- replacedUri = uri.replace(/https:\/\/arweave.net/g, gatewayUrls?.arweave);
25019
- return { uri: replacedUri, isOnChain: false, isEncoded: false };
25020
- }
25021
- if ((isIPNS || isIPFS) && target) {
25022
- return {
25023
- uri: `${ipfsGateway}/${isIPNS ? "ipns" : "ipfs"}/${target}${subtarget}`,
25024
- isOnChain: false,
25025
- isEncoded: false
25026
- };
25027
- }
25028
- if (protocol === "ar:/" && target) {
25029
- return {
25030
- uri: `${arweaveGateway}/${target}${subtarget || ""}`,
25031
- isOnChain: false,
25032
- isEncoded: false
25033
- };
25034
- }
25035
- let parsedUri = uri.replace(dataURIRegex, "");
25036
- if (parsedUri.startsWith("<svg")) {
25037
- parsedUri = `data:image/svg+xml;base64,${btoa(parsedUri)}`;
25038
- }
25039
- if (parsedUri.startsWith("data:") || parsedUri.startsWith("{")) {
25040
- return {
25041
- uri: parsedUri,
25042
- isOnChain: true,
25043
- isEncoded: false
25044
- };
25045
- }
25046
- throw new EnsAvatarUriResolutionError({ uri });
25047
- }
25048
- function getJsonImage(data) {
25049
- if (typeof data !== "object" || !("image" in data) && !("image_url" in data) && !("image_data" in data)) {
25050
- throw new EnsAvatarInvalidMetadataError({ data });
25051
- }
25052
- return data.image || data.image_url || data.image_data;
25053
- }
25054
- async function getMetadataAvatarUri({ gatewayUrls, uri }) {
25055
- try {
25056
- const res = await fetch(uri).then((res2) => res2.json());
25057
- const image = await parseAvatarUri({
25058
- gatewayUrls,
25059
- uri: getJsonImage(res)
25060
- });
25061
- return image;
25062
- } catch {
25063
- throw new EnsAvatarUriResolutionError({ uri });
25064
- }
25065
- }
25066
- async function parseAvatarUri({ gatewayUrls, uri }) {
25067
- const { uri: resolvedURI, isOnChain } = resolveAvatarUri({ uri, gatewayUrls });
25068
- if (isOnChain)
25069
- return resolvedURI;
25070
- const isImage = await isImageUri(resolvedURI);
25071
- if (isImage)
25072
- return resolvedURI;
25073
- throw new EnsAvatarUriResolutionError({ uri });
25074
- }
25075
- function parseNftUri(uri_) {
25076
- let uri = uri_;
25077
- if (uri.startsWith("did:nft:")) {
25078
- uri = uri.replace("did:nft:", "").replace(/_/g, "/");
25079
- }
25080
- const [reference, asset_namespace, tokenID] = uri.split("/");
25081
- const [eip_namespace, chainID] = reference.split(":");
25082
- const [erc_namespace, contractAddress] = asset_namespace.split(":");
25083
- if (!eip_namespace || eip_namespace.toLowerCase() !== "eip155")
25084
- throw new EnsAvatarInvalidNftUriError({ reason: "Only EIP-155 supported" });
25085
- if (!chainID)
25086
- throw new EnsAvatarInvalidNftUriError({ reason: "Chain ID not found" });
25087
- if (!contractAddress)
25088
- throw new EnsAvatarInvalidNftUriError({
25089
- reason: "Contract address not found"
25090
- });
25091
- if (!tokenID)
25092
- throw new EnsAvatarInvalidNftUriError({ reason: "Token ID not found" });
25093
- if (!erc_namespace)
25094
- throw new EnsAvatarInvalidNftUriError({ reason: "ERC namespace not found" });
25095
- return {
25096
- chainID: Number.parseInt(chainID, 10),
25097
- namespace: erc_namespace.toLowerCase(),
25098
- contractAddress,
25099
- tokenID
25100
- };
25101
- }
25102
- async function getNftTokenUri(client, { nft }) {
25103
- if (nft.namespace === "erc721") {
25104
- return readContract(client, {
25105
- address: nft.contractAddress,
25106
- abi: [
25107
- {
25108
- name: "tokenURI",
25109
- type: "function",
25110
- stateMutability: "view",
25111
- inputs: [{ name: "tokenId", type: "uint256" }],
25112
- outputs: [{ name: "", type: "string" }]
25113
- }
25114
- ],
25115
- functionName: "tokenURI",
25116
- args: [BigInt(nft.tokenID)]
25117
- });
25118
- }
25119
- if (nft.namespace === "erc1155") {
25120
- return readContract(client, {
25121
- address: nft.contractAddress,
25122
- abi: [
25123
- {
25124
- name: "uri",
25125
- type: "function",
25126
- stateMutability: "view",
25127
- inputs: [{ name: "_id", type: "uint256" }],
25128
- outputs: [{ name: "", type: "string" }]
25129
- }
25130
- ],
25131
- functionName: "uri",
25132
- args: [BigInt(nft.tokenID)]
25133
- });
25134
- }
25135
- throw new EnsAvatarUnsupportedNamespaceError({ namespace: nft.namespace });
25136
- }
25137
-
25138
- // node_modules/viem/_esm/utils/ens/avatar/parseAvatarRecord.js
25139
- async function parseAvatarRecord(client, { gatewayUrls, record }) {
25140
- if (/eip155:/i.test(record))
25141
- return parseNftAvatarUri(client, { gatewayUrls, record });
25142
- return parseAvatarUri({ uri: record, gatewayUrls });
25143
- }
25144
- async function parseNftAvatarUri(client, { gatewayUrls, record }) {
25145
- const nft = parseNftUri(record);
25146
- const nftUri = await getNftTokenUri(client, { nft });
25147
- const { uri: resolvedNftUri, isOnChain, isEncoded } = resolveAvatarUri({ uri: nftUri, gatewayUrls });
25148
- if (isOnChain && (resolvedNftUri.includes("data:application/json;base64,") || resolvedNftUri.startsWith("{"))) {
25149
- const encodedJson = isEncoded ? (
25150
- // if it is encoded, decode it
25151
- atob(resolvedNftUri.replace("data:application/json;base64,", ""))
25152
- ) : (
25153
- // if it isn't encoded assume it is a JSON string, but it could be anything (it will error if it is)
25154
- resolvedNftUri
25155
- );
25156
- const decoded = JSON.parse(encodedJson);
25157
- return parseAvatarUri({ uri: getJsonImage(decoded), gatewayUrls });
25158
- }
25159
- let uriTokenId = nft.tokenID;
25160
- if (nft.namespace === "erc1155")
25161
- uriTokenId = uriTokenId.replace("0x", "").padStart(64, "0");
25162
- return getMetadataAvatarUri({
25163
- gatewayUrls,
25164
- uri: resolvedNftUri.replace(/(?:0x)?{id}/, uriTokenId)
25165
- });
25166
- }
25167
-
25168
24935
  // node_modules/viem/_esm/actions/ens/getEnsText.js
25169
24936
  init_abis();
25170
24937
  init_decodeFunctionResult();
@@ -25225,29 +24992,6 @@ ${prettyStateOverride(stateOverride)}`;
25225
24992
  }
25226
24993
  }
25227
24994
 
25228
- // node_modules/viem/_esm/actions/ens/getEnsAvatar.js
25229
- async function getEnsAvatar(client, { blockNumber, blockTag, assetGatewayUrls, name, gatewayUrls, strict, universalResolverAddress }) {
25230
- const record = await getAction(client, getEnsText, "getEnsText")({
25231
- blockNumber,
25232
- blockTag,
25233
- key: "avatar",
25234
- name,
25235
- universalResolverAddress,
25236
- gatewayUrls,
25237
- strict
25238
- });
25239
- if (!record)
25240
- return null;
25241
- try {
25242
- return await parseAvatarRecord(client, {
25243
- record,
25244
- gatewayUrls: assetGatewayUrls
25245
- });
25246
- } catch {
25247
- return null;
25248
- }
25249
- }
25250
-
25251
24995
  // node_modules/viem/_esm/actions/ens/getEnsName.js
25252
24996
  init_abis();
25253
24997
  init_getChainContractAddress();
@@ -25770,19 +25514,19 @@ ${prettyStateOverride(stateOverride)}`;
25770
25514
  return action(rest);
25771
25515
  }
25772
25516
 
25773
- // node_modules/@wagmi/core/dist/esm/actions/getEnsAvatar.js
25774
- function getEnsAvatar2(config, parameters) {
25517
+ // node_modules/@wagmi/core/dist/esm/actions/getEnsName.js
25518
+ function getEnsName2(config, parameters) {
25775
25519
  const { chainId, ...rest } = parameters;
25776
25520
  const client = config.getClient({ chainId });
25777
- const action = getAction2(client, getEnsAvatar, "getEnsAvatar");
25521
+ const action = getAction2(client, getEnsName, "getEnsName");
25778
25522
  return action(rest);
25779
25523
  }
25780
25524
 
25781
- // node_modules/@wagmi/core/dist/esm/actions/getEnsName.js
25782
- function getEnsName2(config, parameters) {
25525
+ // node_modules/@wagmi/core/dist/esm/actions/getEnsText.js
25526
+ function getEnsText2(config, parameters) {
25783
25527
  const { chainId, ...rest } = parameters;
25784
25528
  const client = config.getClient({ chainId });
25785
- const action = getAction2(client, getEnsName, "getEnsName");
25529
+ const action = getAction2(client, getEnsText, "getEnsText");
25786
25530
  return action(rest);
25787
25531
  }
25788
25532
 
@@ -29891,22 +29635,6 @@ ${prettyStateOverride(stateOverride)}`;
29891
29635
  return ["ensAddress", filterQueryOptions(options)];
29892
29636
  }
29893
29637
 
29894
- // node_modules/@wagmi/core/dist/esm/query/getEnsAvatar.js
29895
- function getEnsAvatarQueryOptions(config, options = {}) {
29896
- return {
29897
- async queryFn({ queryKey }) {
29898
- const { name, scopeKey: _2, ...parameters } = queryKey[1];
29899
- if (!name)
29900
- throw new Error("name is required");
29901
- return getEnsAvatar2(config, { ...parameters, name });
29902
- },
29903
- queryKey: getEnsAvatarQueryKey(options)
29904
- };
29905
- }
29906
- function getEnsAvatarQueryKey(options = {}) {
29907
- return ["ensAvatar", filterQueryOptions(options)];
29908
- }
29909
-
29910
29638
  // node_modules/@wagmi/core/dist/esm/query/getEnsName.js
29911
29639
  function getEnsNameQueryOptions(config, options = {}) {
29912
29640
  return {
@@ -29923,6 +29651,22 @@ ${prettyStateOverride(stateOverride)}`;
29923
29651
  return ["ensName", filterQueryOptions(options)];
29924
29652
  }
29925
29653
 
29654
+ // node_modules/@wagmi/core/dist/esm/query/getEnsText.js
29655
+ function getEnsTextQueryOptions(config, options = {}) {
29656
+ return {
29657
+ async queryFn({ queryKey }) {
29658
+ const { key, name, scopeKey: _2, ...parameters } = queryKey[1];
29659
+ if (!key || !name)
29660
+ throw new Error("key and name are required");
29661
+ return getEnsText2(config, { ...parameters, key, name });
29662
+ },
29663
+ queryKey: getEnsTextQueryKey(options)
29664
+ };
29665
+ }
29666
+ function getEnsTextQueryKey(options = {}) {
29667
+ return ["ensText", filterQueryOptions(options)];
29668
+ }
29669
+
29926
29670
  // node_modules/@wagmi/core/dist/esm/query/readContract.js
29927
29671
  function readContractQueryOptions(config, options = {}) {
29928
29672
  return {
@@ -30213,29 +29957,29 @@ ${prettyStateOverride(stateOverride)}`;
30213
29957
  return useQuery2({ ...query, ...options, enabled });
30214
29958
  }
30215
29959
 
30216
- // node_modules/wagmi/dist/esm/hooks/useEnsAvatar.js
30217
- function useEnsAvatar(parameters = {}) {
30218
- const { name, query = {} } = parameters;
29960
+ // node_modules/wagmi/dist/esm/hooks/useEnsName.js
29961
+ function useEnsName(parameters = {}) {
29962
+ const { address, query = {} } = parameters;
30219
29963
  const config = useConfig(parameters);
30220
29964
  const chainId = useChainId({ config });
30221
- const options = getEnsAvatarQueryOptions(config, {
29965
+ const options = getEnsNameQueryOptions(config, {
30222
29966
  ...parameters,
30223
29967
  chainId: parameters.chainId ?? chainId
30224
29968
  });
30225
- const enabled = Boolean(name && (query.enabled ?? true));
29969
+ const enabled = Boolean(address && (query.enabled ?? true));
30226
29970
  return useQuery2({ ...query, ...options, enabled });
30227
29971
  }
30228
29972
 
30229
- // node_modules/wagmi/dist/esm/hooks/useEnsName.js
30230
- function useEnsName(parameters = {}) {
30231
- const { address, query = {} } = parameters;
29973
+ // node_modules/wagmi/dist/esm/hooks/useEnsText.js
29974
+ function useEnsText(parameters = {}) {
29975
+ const { key, name, query = {} } = parameters;
30232
29976
  const config = useConfig(parameters);
30233
29977
  const chainId = useChainId({ config });
30234
- const options = getEnsNameQueryOptions(config, {
29978
+ const options = getEnsTextQueryOptions(config, {
30235
29979
  ...parameters,
30236
29980
  chainId: parameters.chainId ?? chainId
30237
29981
  });
30238
- const enabled = Boolean(address && (query.enabled ?? true));
29982
+ const enabled = Boolean(key && name && (query.enabled ?? true));
30239
29983
  return useQuery2({ ...query, ...options, enabled });
30240
29984
  }
30241
29985
 
@@ -31150,7 +30894,8 @@ ${prettyStateOverride(stateOverride)}`;
31150
30894
 
31151
30895
  // src/core/pgp.ts
31152
30896
  function pgpConfig(openpgp) {
31153
- return { ...openpgp.config, rejectCurves: /* @__PURE__ */ new Set() };
30897
+ const rejectCurves = new Set([...openpgp.config.rejectCurves ?? []].filter((c2) => c2 !== "secp256k1"));
30898
+ return { ...openpgp.config, rejectCurves };
31154
30899
  }
31155
30900
  function algorithmName(keyOrSubkey) {
31156
30901
  try {
@@ -31693,6 +31438,66 @@ ${prettyStateOverride(stateOverride)}`;
31693
31438
  };
31694
31439
  }
31695
31440
 
31441
+ // src/core/avatar.ts
31442
+ var IPFS_GATEWAY = "https://ipfs.io/ipfs/";
31443
+ var ARWEAVE_GATEWAY = "https://arweave.net/";
31444
+ function avatarUrl(uri) {
31445
+ if (typeof uri !== "string") return null;
31446
+ const u2 = uri.trim();
31447
+ if (/^data:image\/(png|jpe?g|gif|webp|avif|svg\+xml)[;,]/i.test(u2)) return u2;
31448
+ let m2 = u2.match(/^ipfs:\/\/(?:ipfs\/)?([a-zA-Z0-9]{46,}(?:\/[^?#\s]*)?)$/);
31449
+ if (m2) return IPFS_GATEWAY + m2[1];
31450
+ m2 = u2.match(/^ar:\/\/([a-zA-Z0-9_-]{43}(?:\/[^?#\s]*)?)$/);
31451
+ if (m2) return ARWEAVE_GATEWAY + m2[1];
31452
+ if (/^https:\/\/euc\.li\/[^?#\s]+$/.test(u2)) return u2;
31453
+ m2 = u2.match(/^https:\/\/[^/]+\/ipfs\/([a-zA-Z0-9]{46,}(?:\/[^?#\s]*)?)$/);
31454
+ if (m2) return IPFS_GATEWAY + m2[1];
31455
+ return null;
31456
+ }
31457
+ function parseNftAvatar(raw) {
31458
+ const m2 = typeof raw === "string" && raw.trim().match(/^eip155:(\d+)\/(erc721|erc1155):(0x[0-9a-fA-F]{40})\/(\d+)$/);
31459
+ return m2 ? { chainId: Number(m2[1]), standard: m2[2], contract: m2[3], tokenId: BigInt(m2[4]) } : null;
31460
+ }
31461
+ var NFT_AVATAR_ABI = [
31462
+ { type: "function", name: "tokenURI", stateMutability: "view", inputs: [{ type: "uint256" }], outputs: [{ type: "string" }] },
31463
+ { type: "function", name: "uri", stateMutability: "view", inputs: [{ type: "uint256" }], outputs: [{ type: "string" }] }
31464
+ ];
31465
+ async function nftAvatarImage(tokenUri, tokenId, fetchFn = fetch) {
31466
+ const uri = tokenUri.replace("{id}", tokenId.toString(16).padStart(64, "0"));
31467
+ let meta;
31468
+ const inline = uri.match(/^data:application\/json(;base64)?,([\s\S]*)$/);
31469
+ if (inline) meta = JSON.parse(inline[1] ? atob(inline[2]) : decodeURIComponent(inline[2]));
31470
+ else {
31471
+ const url = uri.startsWith("data:") ? null : avatarUrl(uri);
31472
+ if (!url) return null;
31473
+ const res = await fetchFn(url);
31474
+ if (!res.ok) return null;
31475
+ meta = await res.json();
31476
+ }
31477
+ return avatarUrl(meta?.image ?? meta?.image_url);
31478
+ }
31479
+
31480
+ // src/hooks/useSafeAvatar.ts
31481
+ function useSafeAvatar(name, chainId) {
31482
+ const { data: raw } = useEnsText({ name, key: "avatar", chainId, query: { enabled: !!name } });
31483
+ const direct = avatarUrl(raw);
31484
+ const nft = direct ? null : parseNftAvatar(raw);
31485
+ const { data: tokenUri } = useReadContract({
31486
+ address: nft?.contract,
31487
+ abi: NFT_AVATAR_ABI,
31488
+ functionName: nft?.standard === "erc1155" ? "uri" : "tokenURI",
31489
+ args: nft ? [nft.tokenId] : void 0,
31490
+ chainId,
31491
+ query: { enabled: !!nft && nft.chainId === chainId }
31492
+ });
31493
+ const { data: image } = useQuery({
31494
+ queryKey: ["thurin-nft-avatar", tokenUri, nft?.tokenId.toString()],
31495
+ queryFn: () => nftAvatarImage(tokenUri, nft.tokenId).catch(() => null),
31496
+ enabled: typeof tokenUri === "string" && !!nft
31497
+ });
31498
+ return direct ?? image ?? null;
31499
+ }
31500
+
31696
31501
  // src/hooks/useThurinIdentity.ts
31697
31502
  function isAddress2(value) {
31698
31503
  return /^0x[0-9a-fA-F]{40}$/.test(value);
@@ -31720,11 +31525,7 @@ ${prettyStateOverride(stateOverride)}`;
31720
31525
  query: { enabled: !!address }
31721
31526
  });
31722
31527
  const displayName = ensInput || ensName || null;
31723
- const { data: ensAvatar } = useEnsAvatar({
31724
- name: displayName ? safeNormalize(displayName) : void 0,
31725
- chainId: chain.id,
31726
- query: { enabled: !!displayName }
31727
- });
31528
+ const ensAvatar = useSafeAvatar(displayName ? safeNormalize(displayName) : void 0, chain.id);
31728
31529
  const {
31729
31530
  claims,
31730
31531
  totalClaims,
@@ -31744,7 +31545,7 @@ ${prettyStateOverride(stateOverride)}`;
31744
31545
  return {
31745
31546
  address,
31746
31547
  ensName: displayName,
31747
- ensAvatar: ensAvatar ?? null,
31548
+ ensAvatar,
31748
31549
  claims,
31749
31550
  totalClaims,
31750
31551
  activeClaims,