Let signer be undefined if there's no way to sign
This commit is contained in:
parent
8412a9869f
commit
7f74ec80af
4 changed files with 18 additions and 71 deletions
|
@ -134,7 +134,7 @@ const createAccount = (params: Record<string, any>) =>
|
|||
async (dispatch: AppDispatch, getState: () => RootState) => {
|
||||
const { instance } = getState();
|
||||
const { nostrSignup } = getFeatures(instance);
|
||||
const pubkey = nostrSignup ? await signer.getPublicKey() : undefined;
|
||||
const pubkey = (signer && nostrSignup) ? await signer.getPublicKey() : undefined;
|
||||
|
||||
dispatch({ type: ACCOUNT_CREATE_REQUEST, params });
|
||||
return api(getState, 'app').post('/api/v1/accounts', params, {
|
||||
|
|
|
@ -8,6 +8,10 @@ import { verifyCredentials } from './auth';
|
|||
/** Log in with a Nostr pubkey. */
|
||||
function nostrLogIn() {
|
||||
return async (dispatch: AppDispatch) => {
|
||||
if (!signer) {
|
||||
throw new Error('No Nostr signer available');
|
||||
}
|
||||
|
||||
const pubkey = await signer.getPublicKey();
|
||||
const npub = nip19.npubEncode(pubkey);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { NiceRelay } from 'nostr-machina';
|
||||
import { type Event } from 'nostr-tools';
|
||||
import { type NostrEvent } from 'nspec';
|
||||
import { useEffect, useMemo } from 'react';
|
||||
|
||||
import { signer } from 'soapbox/features/nostr/sign';
|
||||
|
@ -14,13 +14,13 @@ function useSignerStream() {
|
|||
const pubkey = instance.nostr?.pubkey;
|
||||
|
||||
const relay = useMemo(() => {
|
||||
if (relayUrl) {
|
||||
if (relayUrl && signer) {
|
||||
return new NiceRelay(relayUrl);
|
||||
}
|
||||
}, [relayUrl]);
|
||||
}, [relayUrl, !!signer]);
|
||||
|
||||
async function handleConnectEvent(event: Event) {
|
||||
if (!relay || !pubkey) return;
|
||||
async function handleConnectEvent(event: NostrEvent) {
|
||||
if (!relay || !pubkey || !signer) return;
|
||||
const decrypted = await signer.nip04!.decrypt(pubkey, event.content);
|
||||
|
||||
const reqMsg = jsonSchema.pipe(connectRequestSchema).safeParse(decrypted);
|
||||
|
@ -45,8 +45,8 @@ function useSignerStream() {
|
|||
relay.send(['EVENT', respEvent]);
|
||||
}
|
||||
|
||||
async function handleWalletEvent(event: Event) {
|
||||
if (!relay || !pubkey) return;
|
||||
async function handleWalletEvent(event: NostrEvent) {
|
||||
if (!relay || !pubkey || !signer) return;
|
||||
|
||||
const decrypted = await signer.nip04!.decrypt(pubkey, event.content);
|
||||
|
||||
|
|
|
@ -1,70 +1,13 @@
|
|||
import {
|
||||
type Event,
|
||||
type EventTemplate,
|
||||
generatePrivateKey,
|
||||
getPublicKey as _getPublicKey,
|
||||
finishEvent,
|
||||
nip04 as _nip04,
|
||||
} from 'nostr-tools';
|
||||
import { type NostrSigner } from 'nspec';
|
||||
|
||||
import { powWorker } from 'soapbox/workers';
|
||||
import { SoapboxSigner } from './SoapboxSigner';
|
||||
|
||||
/** localStorage key for the Nostr private key (if not using NIP-07). */
|
||||
const LOCAL_KEY = 'soapbox:nostr:privateKey';
|
||||
let signer: NostrSigner | undefined;
|
||||
|
||||
/** Get the private key from the browser, or generate one. */
|
||||
const getPrivateKey = (): string => {
|
||||
const local = localStorage.getItem(LOCAL_KEY);
|
||||
|
||||
if (!local) {
|
||||
const key = generatePrivateKey();
|
||||
localStorage.setItem(LOCAL_KEY, key);
|
||||
return key;
|
||||
}
|
||||
|
||||
return local;
|
||||
};
|
||||
|
||||
/** Get the user's public key from NIP-07, or generate one. */
|
||||
async function getPublicKey(): Promise<string> {
|
||||
return window.nostr ? window.nostr.getPublicKey() : _getPublicKey(getPrivateKey());
|
||||
try {
|
||||
signer = new SoapboxSigner();
|
||||
} catch (_) {
|
||||
// No signer available
|
||||
}
|
||||
|
||||
interface SignEventOpts {
|
||||
pow?: number;
|
||||
}
|
||||
|
||||
/** Sign an event with NIP-07, or the locally generated key. */
|
||||
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. */
|
||||
const nip04 = {
|
||||
/** Encrypt with NIP-07, or the local key. */
|
||||
encrypt: async (pubkey: string, content: string) => {
|
||||
return window.nostr?.nip04
|
||||
? window.nostr.nip04.encrypt(pubkey, content)
|
||||
: _nip04.encrypt(getPrivateKey(), pubkey, content);
|
||||
},
|
||||
/** Decrypt with NIP-07, or the local key. */
|
||||
decrypt: async (pubkey: string, content: string) => {
|
||||
return window.nostr?.nip04
|
||||
? window.nostr.nip04.decrypt(pubkey, content)
|
||||
: _nip04.decrypt(getPrivateKey(), pubkey, content);
|
||||
},
|
||||
};
|
||||
|
||||
const signer: NostrSigner = {
|
||||
getPublicKey,
|
||||
signEvent,
|
||||
nip04,
|
||||
};
|
||||
|
||||
export { signer };
|
Loading…
Reference in a new issue