124 lines
3.1 KiB
TypeScript
Raw Normal View History

2023-10-17 14:25:26 -04:00
"use client";
import {
createContext,
useContext,
useState,
useMemo,
type ReactNode,
} from "react";
import useCurrentUser from "@/lib/hooks/useCurrentUser";
import { findEphemeralSigner } from "@/lib/actions/ephemeral";
import {
NDKPrivateKeySigner,
NDKUser,
type NDKSigner,
type NDKList,
} from "@nostr-dev-kit/ndk";
import { useNDK } from "../ndk";
2023-10-18 21:55:45 -04:00
import { log } from "@/lib/utils";
2023-10-20 15:26:55 -04:00
import { getTagValues } from "@/lib/nostr/utils";
2023-10-17 14:25:26 -04:00
export type SignerStoreItem = {
signer: NDKPrivateKeySigner;
user: NDKUser;
saved: boolean;
title?: string;
id: string;
};
type SignerItems = Map<string, SignerStoreItem>;
type SignerContextProps = {
npubSigners: Map<string, NDKSigner>;
signers: SignerItems;
getSigner: (list: NDKList) => Promise<SignerStoreItem>;
};
const SignerContext = createContext<SignerContextProps | undefined>(undefined);
export default function SignerProvider({
children,
}: {
children?: ReactNode | undefined;
}) {
const { currentUser } = useCurrentUser();
const { ndk } = useNDK();
const [signers, setSigners] = useState(new Map());
const npubSigners = useMemo(() => {
const npubs = new Map<string, NDKSigner>();
for (const entry of signers) {
const { user, signer } = entry[1];
npubs.set(user.npub, signer);
}
return npubs;
}, [signers]);
async function getDelegatedSignerName(list: NDKList) {
let name = "";
2023-10-20 15:26:55 -04:00
console.log("getDelegatedSignerName", JSON.stringify(list));
if (list.kind === 30044) {
return list.title;
}
2023-10-17 14:25:26 -04:00
if (!currentUser?.profile) {
console.log("fetching user profile");
await currentUser?.fetchProfile();
}
name = `${
currentUser?.profile?.displayName ??
currentUser?.profile?.name ??
currentUser?.profile?.nip05 ??
`${currentUser?.npub.slice(0, 9)}...`
}'s `;
2023-10-20 15:26:55 -04:00
const suffix = list.kind === 30044 ? "Subscription" : "List";
return name + list.title ?? suffix;
2023-10-17 14:25:26 -04:00
}
async function getSigner(list: NDKList): Promise<SignerStoreItem> {
2023-10-18 21:55:45 -04:00
log("func", "getSigner");
2023-10-17 14:25:26 -04:00
const id = list.encode();
2023-10-18 21:55:45 -04:00
log("info", "list ID", id.toString());
2023-10-17 14:25:26 -04:00
let item = signers.get(id);
if (item) return item;
2023-10-18 21:55:45 -04:00
log("info", "NO local signer");
2023-10-17 14:25:26 -04:00
let signer = await findEphemeralSigner(ndk!, ndk!.signer!, {
associatedEventNip19: list.encode(),
});
if (signer) {
2023-10-20 15:26:55 -04:00
log("info", `found a signer for ${list.title}`, JSON.stringify(signer));
2023-10-17 14:25:26 -04:00
item = {
signer: signer!,
user: await signer.user(),
saved: true,
id,
};
} else {
2023-10-20 15:26:55 -04:00
log("info", `no signer found for ${list.title}`);
2023-10-17 14:25:26 -04:00
signer = NDKPrivateKeySigner.generate();
2023-10-20 15:26:55 -04:00
log("info", "generated signer", JSON.stringify(signer));
2023-10-17 14:25:26 -04:00
item = {
signer,
user: await signer.user(),
saved: false,
title: await getDelegatedSignerName(list),
id,
};
}
item.user.ndk = ndk;
setSigners((prev) => new Map(prev.set(id, item)));
return item;
}
return (
<SignerContext.Provider value={{ signers, npubSigners, getSigner }}>
{children}
</SignerContext.Provider>
);
}
export function useSigner() {
return useContext(SignerContext);
}