Nostr: sign events with NIP-46

This commit is contained in:
Alex Gleason
2023-08-26 23:24:18 -05:00
parent c2a8044aa4
commit 1011be5333
13 changed files with 158 additions and 70 deletions

View File

@@ -53,4 +53,3 @@ export { useHashtagStream } from './streaming/useHashtagStream';
export { useListStream } from './streaming/useListStream';
export { useGroupStream } from './streaming/useGroupStream';
export { useRemoteStream } from './streaming/useRemoteStream';
export { useNostrStream } from './streaming/useNostrStream';

View File

@@ -0,0 +1,57 @@
import { relayInit, type Relay } from 'nostr-tools';
import { useEffect } from 'react';
import { useInstance } from 'soapbox/hooks';
import { connectRequestSchema } from 'soapbox/schemas/nostr';
import { jsonSchema } from 'soapbox/schemas/utils';
function useSignerStream() {
const { nostr } = useInstance();
const relayUrl = nostr.get('relay') as string | undefined;
const pubkey = nostr.get('pubkey') as string | undefined;
useEffect(() => {
let relay: Relay | undefined;
if (relayUrl && pubkey && window.nostr?.nip04) {
relay = relayInit(relayUrl);
relay.connect();
relay
.sub([{ kinds: [24133], authors: [pubkey], limit: 0 }])
.on('event', async (event) => {
if (!relay || !window.nostr?.nip04) return;
const decrypted = await window.nostr.nip04.decrypt(pubkey, event.content);
const reqMsg = jsonSchema.pipe(connectRequestSchema).safeParse(decrypted);
if (!reqMsg.success) {
console.warn(decrypted);
console.warn(reqMsg.error);
return;
}
const signed = await window.nostr.signEvent(reqMsg.data.params[0]);
const respMsg = {
id: reqMsg.data.id,
result: signed,
};
const respEvent = await window.nostr.signEvent({
kind: 24133,
content: await window.nostr.nip04.encrypt(pubkey, JSON.stringify(respMsg)),
tags: [['p', pubkey]],
created_at: Math.floor(Date.now() / 1000),
});
relay.publish(respEvent);
});
}
return () => {
relay?.close();
};
}, [relayUrl, pubkey]);
}
export { useSignerStream };

View File

@@ -1,20 +0,0 @@
import { useFeatures, useLoggedIn } from 'soapbox/hooks';
import { useTimelineStream } from './useTimelineStream';
function useNostrStream() {
const features = useFeatures();
const { isLoggedIn } = useLoggedIn();
return useTimelineStream(
'nostr',
'nostr',
null,
null,
{
enabled: isLoggedIn && features.nostrSign && Boolean(window.nostr),
},
);
}
export { useNostrStream };

View File

@@ -66,6 +66,7 @@ export const baseClient = (accessToken?: string | null, baseURL: string = ''): A
baseURL: isURL(BuildConfig.BACKEND_URL) ? BuildConfig.BACKEND_URL : baseURL,
headers: Object.assign(accessToken ? {
'Authorization': `Bearer ${accessToken}`,
'X-Nostr-Sign': 'true',
} : {}),
transformResponse: [maybeParseJSON],
});