Merge branch 'soapbox-pub:main' into fork

This commit is contained in:
Marcin Mikołajczak 2024-04-29 16:03:04 +02:00 committed by GitHub
commit 99b9d856a3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 81 additions and 16 deletions

View file

@ -5,9 +5,32 @@ import { useNostr } from 'soapbox/contexts/nostr-context';
import { connectRequestSchema, nwcRequestSchema } from 'soapbox/schemas/nostr';
import { jsonSchema } from 'soapbox/schemas/utils';
/** NIP-46 [response](https://github.com/nostr-protocol/nips/blob/master/46.md#response-events-kind24133) content. */
interface NostrConnectResponse {
/** Request ID that this response is for. */
id: string;
/** Result of the call (this can be either a string or a JSON stringified object) */
result: string;
/** Error in string form, if any. Its presence indicates an error with the request. */
error?: string;
}
function useSignerStream() {
const { relay, pubkey, signer } = useNostr();
async function sendConnect(response: NostrConnectResponse) {
if (!relay || !pubkey || !signer) return;
const event = await signer.signEvent({
kind: 24133,
content: await signer.nip04!.encrypt(pubkey, JSON.stringify(response)),
tags: [['p', pubkey]],
created_at: Math.floor(Date.now() / 1000),
});
relay.event(event);
}
async function handleConnectEvent(event: NostrEvent) {
if (!relay || !pubkey || !signer) return;
const decrypted = await signer.nip04!.decrypt(pubkey, event.content);
@ -19,19 +42,61 @@ function useSignerStream() {
return;
}
const respMsg = {
id: reqMsg.data.id,
result: JSON.stringify(await signer.signEvent(JSON.parse(reqMsg.data.params[0]))),
};
const request = reqMsg.data;
const respEvent = await signer.signEvent({
kind: 24133,
content: await signer.nip04!.encrypt(pubkey, JSON.stringify(respMsg)),
tags: [['p', pubkey]],
created_at: Math.floor(Date.now() / 1000),
});
relay.event(respEvent);
switch (request.method) {
case 'connect':
return sendConnect({
id: request.id,
result: 'ack',
});
case 'sign_event':
return sendConnect({
id: request.id,
result: JSON.stringify(await signer.signEvent(JSON.parse(request.params[0]))),
});
case 'ping':
return sendConnect({
id: request.id,
result: 'pong',
});
case 'get_relays':
return sendConnect({
id: request.id,
result: JSON.stringify(await signer.getRelays?.() ?? []),
});
case 'get_public_key':
return sendConnect({
id: request.id,
result: await signer.getPublicKey(),
});
case 'nip04_encrypt':
return sendConnect({
id: request.id,
result: await signer.nip04!.encrypt(request.params[0], request.params[1]),
});
case 'nip04_decrypt':
return sendConnect({
id: request.id,
result: await signer.nip04!.decrypt(request.params[0], request.params[1]),
});
case 'nip44_encrypt':
return sendConnect({
id: request.id,
result: await signer.nip44!.encrypt(request.params[0], request.params[1]),
});
case 'nip44_decrypt':
return sendConnect({
id: request.id,
result: await signer.nip44!.decrypt(request.params[0], request.params[1]),
});
default:
return sendConnect({
id: request.id,
result: '',
error: `Unrecognized method: ${request.method}`,
});
}
}
async function handleWalletEvent(event: NostrEvent) {

View file

@ -24,11 +24,11 @@ const eventSchema = eventTemplateSchema.extend({
/** Nostr event schema that also verifies the event's signature. */
const signedEventSchema = eventSchema.refine(verifyEvent);
/** NIP-46 signer request. */
/** NIP-46 request content schema. */
const connectRequestSchema = z.object({
id: z.string(),
method: z.literal('sign_event'),
params: z.tuple([z.string()]),
method: z.string(),
params: z.string().array(),
});
/** NIP-47 signer response. */

View file

@ -214,7 +214,7 @@ const getInstanceFeatures = (instance: Instance) => {
* @see DELETE /api/v1/announcements/:id/reactions/:name
* @see {@link https://docs.joinmastodon.org/methods/announcements/}
*/
announcementsReactions: true, // v.software === MASTODON && gte(v.compatVersion, '3.1.0'),
announcementsReactions: v.software === MASTODON && gte(v.compatVersion, '3.1.0'),
/**
* Pleroma backups.