Git Nostr signer from currently-logged-in account
This commit is contained in:
parent
44411fdf29
commit
a83916537a
5 changed files with 17 additions and 70 deletions
|
@ -1,8 +1,5 @@
|
|||
import { nip19 } from 'nostr-tools';
|
||||
|
||||
import { importEntities } from 'soapbox/entity-store/actions';
|
||||
import { Entities } from 'soapbox/entity-store/entities';
|
||||
import { signer } from 'soapbox/features/nostr/sign';
|
||||
import { selectAccount } from 'soapbox/selectors';
|
||||
import { isLoggedIn } from 'soapbox/utils/auth';
|
||||
import { getFeatures, parseVersion, PLEROMA } from 'soapbox/utils/features';
|
||||
|
@ -132,14 +129,8 @@ const noOp = () => new Promise(f => f(undefined));
|
|||
|
||||
const createAccount = (params: Record<string, any>) =>
|
||||
async (dispatch: AppDispatch, getState: () => RootState) => {
|
||||
const { instance } = getState();
|
||||
const { nostrSignup } = getFeatures(instance);
|
||||
const pubkey = (signer && nostrSignup) ? await signer.getPublicKey() : undefined;
|
||||
|
||||
dispatch({ type: ACCOUNT_CREATE_REQUEST, params });
|
||||
return api(getState, 'app').post('/api/v1/accounts', params, {
|
||||
headers: pubkey ? { authorization: `Bearer ${nip19.npubEncode(pubkey)}` } : undefined,
|
||||
}).then(({ data: token }) => {
|
||||
return api(getState, 'app').post('/api/v1/accounts', params).then(({ data: token }) => {
|
||||
return dispatch({ type: ACCOUNT_CREATE_SUCCESS, params, token });
|
||||
}).catch(error => {
|
||||
dispatch({ type: ACCOUNT_CREATE_FAIL, error, params });
|
||||
|
|
|
@ -5,6 +5,14 @@ import { type AppDispatch } from 'soapbox/store';
|
|||
import { verifyCredentials } from './auth';
|
||||
import { closeModal } from './modals';
|
||||
|
||||
/** Log in with a Nostr pubkey. */
|
||||
function logInNostr(pubkey: string) {
|
||||
return (dispatch: AppDispatch) => {
|
||||
const npub = nip19.npubEncode(pubkey);
|
||||
return dispatch(verifyCredentials(npub));
|
||||
};
|
||||
}
|
||||
|
||||
/** Log in with a Nostr extension. */
|
||||
function nostrExtensionLogIn() {
|
||||
return async (dispatch: AppDispatch) => {
|
||||
|
@ -13,10 +21,9 @@ function nostrExtensionLogIn() {
|
|||
}
|
||||
|
||||
const pubkey = await window.nostr.getPublicKey();
|
||||
const npub = nip19.npubEncode(pubkey);
|
||||
|
||||
dispatch(closeModal('NOSTR_SIGNIN'));
|
||||
return dispatch(verifyCredentials(npub));
|
||||
return dispatch(logInNostr(pubkey));
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { NRelay, NRelay1, NostrSigner } from '@soapbox/nspec';
|
||||
import React, { createContext, useContext, useState, useEffect } from 'react';
|
||||
|
||||
import { signer } from 'soapbox/features/nostr/sign';
|
||||
import { NKeys } from 'soapbox/features/nostr/keys';
|
||||
import { useOwnAccount } from 'soapbox/hooks';
|
||||
import { useInstance } from 'soapbox/hooks/useInstance';
|
||||
|
||||
interface NostrContextType {
|
||||
|
@ -20,8 +21,13 @@ export const NostrProvider: React.FC<NostrProviderProps> = ({ children }) => {
|
|||
const instance = useInstance();
|
||||
const [relay, setRelay] = useState<NRelay1>();
|
||||
|
||||
const { account } = useOwnAccount();
|
||||
|
||||
const url = instance.nostr?.relay;
|
||||
const pubkey = instance.nostr?.pubkey;
|
||||
const accountPubkey = account?.nostr.pubkey;
|
||||
|
||||
const signer = (accountPubkey ? NKeys.get(accountPubkey) : undefined) ?? window.nostr;
|
||||
|
||||
useEffect(() => {
|
||||
if (url) {
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
import { hexToBytes } from '@noble/hashes/utils';
|
||||
import { type NostrSigner, type NostrEvent, NSecSigner } from '@soapbox/nspec';
|
||||
|
||||
/** Use key from `localStorage` if available, falling back to NIP-07. */
|
||||
export class SoapboxSigner implements NostrSigner {
|
||||
|
||||
#signer: NostrSigner;
|
||||
|
||||
constructor() {
|
||||
const privateKey = localStorage.getItem('soapbox:nostr:privateKey');
|
||||
const signer = privateKey ? new NSecSigner(hexToBytes(privateKey)) : window.nostr;
|
||||
|
||||
if (!signer) {
|
||||
throw new Error('No Nostr signer available');
|
||||
}
|
||||
|
||||
this.#signer = signer;
|
||||
}
|
||||
|
||||
async getPublicKey(): Promise<string> {
|
||||
return this.#signer.getPublicKey();
|
||||
}
|
||||
|
||||
async signEvent(event: Omit<NostrEvent, 'id' | 'pubkey' | 'sig'>): Promise<NostrEvent> {
|
||||
return this.#signer.signEvent(event);
|
||||
}
|
||||
|
||||
nip04 = {
|
||||
encrypt: (pubkey: string, plaintext: string): Promise<string> => {
|
||||
if (!this.#signer.nip04) {
|
||||
throw new Error('NIP-04 not supported by signer');
|
||||
}
|
||||
return this.#signer.nip04.encrypt(pubkey, plaintext);
|
||||
},
|
||||
|
||||
decrypt: (pubkey: string, ciphertext: string): Promise<string> => {
|
||||
if (!this.#signer.nip04) {
|
||||
throw new Error('NIP-04 not supported by signer');
|
||||
}
|
||||
return this.#signer.nip04.decrypt(pubkey, ciphertext);
|
||||
},
|
||||
};
|
||||
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
import { type NostrSigner } from '@soapbox/nspec';
|
||||
|
||||
import { SoapboxSigner } from './SoapboxSigner';
|
||||
|
||||
let signer: NostrSigner | undefined;
|
||||
|
||||
try {
|
||||
signer = new SoapboxSigner();
|
||||
} catch (_) {
|
||||
// No signer available
|
||||
}
|
||||
|
||||
export { signer };
|
Loading…
Reference in a new issue