import { getEventHash } from 'nostr-tools/event'; import type { Event as NostrEvent } from 'nostr-tools/event'; import type { Pub } from 'nostr-tools/relay'; import '@/types/nostr.d'; import usePool from '@/clients/usePool'; const currentDate = (): number => Math.floor(Date.now() / 1000); // NIP-20: Command Result const waitCommandResult = (pub: Pub): Promise => { return new Promise((resolve, reject) => { pub.on('ok', () => { console.log(`${relayUrl} has accepted our event`); resolve(); }); pub.on('failed', (reason: string) => { console.log(`failed to publish to ${relayUrl}: ${reason}`); reject(reason); }); }); }; const useCommands = () => { const pool = usePool(); const publishEvent = async (relayUrls: string[], event: NostrEvent): Promise[]> => { const preSignedEvent: NostrEvent = { ...event }; preSignedEvent.id = getEventHash(preSignedEvent); if (window.nostr == null) { throw new Error('NIP-07 implementation not found'); } const signedEvent = await window.nostr.signEvent(preSignedEvent); return relayUrls.map(async (relayUrl) => { const relay = await pool().ensureRelay(relayUrl); const pub = relay.publish(signedEvent); return waitCommandResult(pub); }); }; return { // NIP-01 publishTextNote({ relayUrls, pubkey, content, notifyPubkeys, rootEventId, mentionEventIds, replyEventId, }: { relayUrls: string[]; pubkey: string; content: string; notifyPubkeys?: string[]; rootEventId?: string; mentionEventIds?: string[]; replyEventId?: string; }): Promise[]> { const pTags = notifyPubkeys?.map((p) => ['p', p]) ?? []; const eTags = []; if (rootEventId != null) eTags.push(['e', rootEventId, '', 'root']); if (mentionEventIds != null) mentionEventIds.forEach((id) => eTags.push(['e', id, '', 'mention'])); if (replyEventId != null) eTags.push(['e', replyEventId, '', 'reply']); const tags = [...pTags, ...eTags]; const preSignedEvent: NostrEvent = { kind: 1, pubkey, created_at: currentDate(), tags, content, }; return publishEvent(relayUrls, preSignedEvent); }, // NIP-25 publishReaction({ relayUrls, pubkey, eventId, content, notifyPubkey, }: { relayUrls: string[]; pubkey: string; eventId: string; content: string; notifyPubkey: string; }): Promise[]> { // TODO ensure that content is + or - or emoji. const preSignedEvent: NostrEvent = { kind: 7, pubkey, created_at: currentDate(), tags: [ ['e', eventId, ''], ['p', notifyPubkey], ], content, }; console.log(preSignedEvent); return publishEvent(relayUrls, preSignedEvent); }, // NIP-18 publishDeprecatedRepost({ relayUrls, pubkey, eventId, notifyPubkey, }: { relayUrls: string[]; pubkey: string; eventId: string; notifyPubkey: string; }): Promise[]> { const preSignedEvent: NostrEvent = { kind: 6, pubkey, created_at: currentDate(), tags: [ ['e', eventId, ''], ['p', notifyPubkey], ], content: '', }; return publishEvent(relayUrls, preSignedEvent); }, }; }; export default useCommands;