fully support nip05

This commit is contained in:
Ren Amamiya
2023-09-01 08:58:33 +07:00
parent 0d207d471c
commit cc315a190a
18 changed files with 158 additions and 44 deletions

73
src/shared/nip05.tsx Normal file
View File

@@ -0,0 +1,73 @@
import { useQuery } from '@tanstack/react-query';
import { twMerge } from 'tailwind-merge';
import { UnverifiedIcon, VerifiedIcon } from '@shared/icons';
interface NIP05 {
names: {
[key: string]: string;
};
}
export function NIP05({
pubkey,
nip05,
className,
}: {
pubkey: string;
nip05: string;
className?: string;
}) {
const { status, data } = useQuery(
[nip05],
async () => {
try {
const username = nip05.split('@')[0];
const service = nip05.split('@')[1];
// #TODO: use tauri native fetch to avoid CORS
const verifyURL = `https://${service}/.well-known/nostr.json?name=${username}`;
const res = await fetch(verifyURL, {
method: 'GET',
headers: {
'Content-Type': 'application/json; charset=utf-8',
},
});
if (!res.ok) throw new Error(`Failed to fetch NIP-05 service: ${nip05}`);
const data: NIP05 = await res.json();
if (data.names) {
if (data.names.username !== pubkey) return false;
return true;
}
} catch (e) {
throw new Error(`Failed to verify NIP-05, error: ${e}`);
}
},
{
refetchOnMount: false,
refetchOnReconnect: false,
refetchOnWindowFocus: false,
staleTime: Infinity,
}
);
if (status === 'loading') {
<div className="h-3 w-20 animate-pulse rounded bg-white/10" />;
}
return (
<div className={twMerge('leadning-none inline-flex items-center gap-1', className)}>
<p>{nip05}</p>
<div className="shrink-0">
{data === true ? (
<VerifiedIcon className="h-3 w-3 text-green-500" />
) : (
<UnverifiedIcon className="h-3 w-3 text-red-500" />
)}
</div>
</div>
);
}