Merge branch 'sign-pow' into 'main'

Sign NIP-46 events with proof-of-work

See merge request soapbox-pub/soapbox!2864
This commit is contained in:
Alex Gleason 2023-11-21 03:22:40 +00:00
commit f216bde13e
3 changed files with 20 additions and 4 deletions

View File

@ -36,7 +36,7 @@ function useSignerStream() {
const respMsg = {
id: reqMsg.data.id,
result: await signEvent(reqMsg.data.params[0]),
result: await signEvent(reqMsg.data.params[0], reqMsg.data.params[1]),
};
const respEvent = await signEvent({

View File

@ -7,6 +7,8 @@ import {
nip04 as _nip04,
} from 'nostr-tools';
import { powWorker } from 'soapbox/workers';
/** localStorage key for the Nostr private key (if not using NIP-07). */
const LOCAL_KEY = 'soapbox:nostr:privateKey';
@ -28,9 +30,18 @@ async function getPublicKey(): Promise<string> {
return window.nostr ? window.nostr.getPublicKey() : _getPublicKey(getPrivateKey());
}
interface SignEventOpts {
pow?: number;
}
/** Sign an event with NIP-07, or the locally generated key. */
async function signEvent<K extends number>(event: EventTemplate<K>): Promise<Event<K>> {
return window.nostr ? window.nostr.signEvent(event) as Promise<Event<K>> : finishEvent(event, getPrivateKey()) ;
async function signEvent<K extends number>(template: EventTemplate<K>, opts: SignEventOpts = {}): Promise<Event<K>> {
if (opts.pow) {
const event = await powWorker.mine({ ...template, pubkey: await getPublicKey() }, opts.pow) as Omit<Event<K>, 'sig'>;
return window.nostr ? window.nostr.signEvent(event) as Promise<Event<K>> : finishEvent(event, getPrivateKey()) ;
} else {
return window.nostr ? window.nostr.signEvent(template) as Promise<Event<K>> : finishEvent(template, getPrivateKey()) ;
}
}
/** Crypto function with NIP-07, or the local key. */

View File

@ -24,11 +24,16 @@ const eventSchema = eventTemplateSchema.extend({
/** Nostr event schema that also verifies the event's signature. */
const signedEventSchema = eventSchema.refine(verifySignature);
/** NIP-46 signer options. */
const signEventOptsSchema = z.object({
pow: z.number().int().nonnegative(),
});
/** NIP-46 signer request. */
const connectRequestSchema = z.object({
id: z.string(),
method: z.literal('sign_event'),
params: z.tuple([eventTemplateSchema]),
params: z.tuple([eventTemplateSchema]).or(z.tuple([eventTemplateSchema, signEventOptsSchema])),
});
export { nostrIdSchema, kindSchema, eventSchema, signedEventSchema, connectRequestSchema };