Refactor signers
This commit is contained in:
parent
7c2340d7fb
commit
9640a7fa57
@ -134,7 +134,7 @@ export default function SendSats(props: SendSatsProps) {
|
|||||||
const randomKey = generateRandomKey();
|
const randomKey = generateRandomKey();
|
||||||
console.debug("Generated new key for zap: ", randomKey);
|
console.debug("Generated new key for zap: ", randomKey);
|
||||||
|
|
||||||
const publisher = new EventPublisher(randomKey.publicKey, randomKey.privateKey);
|
const publisher = EventPublisher.privateKey(randomKey.privateKey);
|
||||||
zap = await publisher.zap(amount * 1000, author, relays, note, comment, eb => eb.tag(["anon", ""]));
|
zap = await publisher.zap(amount * 1000, author, relays, note, comment, eb => eb.tag(["anon", ""]));
|
||||||
} else {
|
} else {
|
||||||
zap = await publisher.zap(amount * 1000, author, relays, note, comment);
|
zap = await publisher.zap(amount * 1000, author, relays, note, comment);
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import useLogin from "Hooks/useLogin";
|
import useLogin from "Hooks/useLogin";
|
||||||
import { EventPublisher } from "@snort/system";
|
import { EventPublisher, Nip7Signer } from "@snort/system";
|
||||||
|
|
||||||
export default function useEventPublisher() {
|
export default function useEventPublisher() {
|
||||||
const { publicKey, privateKey } = useLogin();
|
const { publicKey, privateKey } = useLogin();
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
|
if (privateKey) {
|
||||||
|
return EventPublisher.privateKey(privateKey);
|
||||||
|
}
|
||||||
if (publicKey) {
|
if (publicKey) {
|
||||||
return new EventPublisher(publicKey, privateKey);
|
return new EventPublisher(new Nip7Signer(), publicKey);
|
||||||
}
|
}
|
||||||
}, [publicKey, privateKey]);
|
}, [publicKey, privateKey]);
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ export async function generateNewLogin() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const publicKey = utils.bytesToHex(secp.schnorr.getPublicKey(privateKey));
|
const publicKey = utils.bytesToHex(secp.schnorr.getPublicKey(privateKey));
|
||||||
const publisher = new EventPublisher(publicKey, privateKey);
|
const publisher = EventPublisher.privateKey(privateKey);
|
||||||
const ev = await publisher.contactList([bech32ToHex(SnortPubKey), publicKey], newRelays);
|
const ev = await publisher.contactList([bech32ToHex(SnortPubKey), publicKey], newRelays);
|
||||||
System.BroadcastEvent(ev);
|
System.BroadcastEvent(ev);
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ import { StrictMode } from "react";
|
|||||||
import * as ReactDOM from "react-dom/client";
|
import * as ReactDOM from "react-dom/client";
|
||||||
import { Provider } from "react-redux";
|
import { Provider } from "react-redux";
|
||||||
import { createBrowserRouter, RouterProvider } from "react-router-dom";
|
import { createBrowserRouter, RouterProvider } from "react-router-dom";
|
||||||
import { EventPublisher, NostrSystem, ProfileLoaderService } from "@snort/system";
|
import { EventPublisher, NostrSystem, ProfileLoaderService, Nip7Signer } from "@snort/system";
|
||||||
|
|
||||||
import * as serviceWorkerRegistration from "serviceWorkerRegistration";
|
import * as serviceWorkerRegistration from "serviceWorkerRegistration";
|
||||||
import { IntlProvider } from "IntlProvider";
|
import { IntlProvider } from "IntlProvider";
|
||||||
@ -46,8 +46,12 @@ export const System = new NostrSystem({
|
|||||||
relayMetrics: RelayMetrics,
|
relayMetrics: RelayMetrics,
|
||||||
authHandler: async (c, r) => {
|
authHandler: async (c, r) => {
|
||||||
const { publicKey, privateKey } = LoginStore.snapshot();
|
const { publicKey, privateKey } = LoginStore.snapshot();
|
||||||
|
if (privateKey) {
|
||||||
|
const pub = EventPublisher.privateKey(privateKey);
|
||||||
|
return await pub.nip42Auth(c, r);
|
||||||
|
}
|
||||||
if (publicKey) {
|
if (publicKey) {
|
||||||
const pub = new EventPublisher(publicKey, privateKey);
|
const pub = new EventPublisher(new Nip7Signer(), publicKey);
|
||||||
return await pub.nip42Auth(c, r);
|
return await pub.nip42Auth(c, r);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -39,85 +39,125 @@ declare global {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface EventSigner {
|
||||||
|
getPubKey(): Promise<string> | string;
|
||||||
|
nip4Encrypt(content: string, key: string): Promise<string>;
|
||||||
|
nip4Decrypt(content: string, otherKey: string): Promise<string>;
|
||||||
|
sign(ev: NostrEvent): Promise<NostrEvent>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Nip7Signer implements EventSigner {
|
||||||
|
async getPubKey(): Promise<string> {
|
||||||
|
if (!window.nostr) {
|
||||||
|
throw new Error("Cannot use NIP-07 signer, not found!");
|
||||||
|
}
|
||||||
|
return await window.nostr.getPublicKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
async nip4Encrypt(content: string, key: string): Promise<string> {
|
||||||
|
if (!window.nostr) {
|
||||||
|
throw new Error("Cannot use NIP-07 signer, not found!");
|
||||||
|
}
|
||||||
|
return await barrierQueue(Nip7Queue, () =>
|
||||||
|
unwrap(window.nostr?.nip04?.encrypt).call(window.nostr?.nip04, key, content)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async nip4Decrypt(content: string, otherKey: string): Promise<string> {
|
||||||
|
if (!window.nostr) {
|
||||||
|
throw new Error("Cannot use NIP-07 signer, not found!");
|
||||||
|
}
|
||||||
|
return await barrierQueue(Nip7Queue, () =>
|
||||||
|
unwrap(window.nostr?.nip04?.decrypt).call(window.nostr?.nip04, otherKey, content)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async sign(ev: NostrEvent): Promise<NostrEvent> {
|
||||||
|
if (!window.nostr) {
|
||||||
|
throw new Error("Cannot use NIP-07 signer, not found!");
|
||||||
|
}
|
||||||
|
return await barrierQueue(Nip7Queue, () => unwrap(window.nostr).signEvent(ev));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PrivateKeySigner implements EventSigner {
|
||||||
|
#publicKey: string;
|
||||||
|
#privateKey: string;
|
||||||
|
|
||||||
|
constructor(privateKey: string) {
|
||||||
|
this.#privateKey = privateKey;
|
||||||
|
this.#publicKey = getPublicKey(privateKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
getPubKey(): string {
|
||||||
|
return this.#publicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
async nip4Encrypt(content: string, key: string): Promise<string> {
|
||||||
|
return await EventExt.encryptDm(content, this.#privateKey, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
async nip4Decrypt(content: string, otherKey: string): Promise<string> {
|
||||||
|
return await EventExt.decryptDm(content, this.#privateKey, otherKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
sign(ev: NostrEvent): Promise<NostrEvent> {
|
||||||
|
EventExt.sign(ev, this.#privateKey);
|
||||||
|
return Promise.resolve(ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class EventPublisher {
|
export class EventPublisher {
|
||||||
#pubKey: string;
|
#pubKey: string;
|
||||||
#privateKey?: string;
|
#signer: EventSigner;
|
||||||
|
|
||||||
constructor(pubKey: string, privKey?: string) {
|
constructor(signer: EventSigner, pubKey: string) {
|
||||||
if (privKey) {
|
this.#signer = signer;
|
||||||
this.#privateKey = privKey;
|
|
||||||
this.#pubKey = utils.bytesToHex(secp.schnorr.getPublicKey(privKey));
|
|
||||||
} else {
|
|
||||||
this.#pubKey = pubKey;
|
this.#pubKey = pubKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a NIP-07 EventPublisher
|
||||||
|
*/
|
||||||
|
static async nip7() {
|
||||||
|
if ("nostr" in window) {
|
||||||
|
const signer = new Nip7Signer();
|
||||||
|
const pubkey = await signer.getPubKey();
|
||||||
|
if (pubkey) {
|
||||||
|
return new EventPublisher(signer, pubkey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an EventPublisher for a private key
|
||||||
|
*/
|
||||||
|
static privateKey(privateKey: string) {
|
||||||
|
const signer = new PrivateKeySigner(privateKey)
|
||||||
|
return new EventPublisher(signer, signer.getPubKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
get pubKey() {
|
get pubKey() {
|
||||||
return this.#pubKey;
|
return this.#pubKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
get #hasNip07() {
|
|
||||||
return "nostr" in window;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a NIP-07 EventPublisher
|
|
||||||
*/
|
|
||||||
static async nip7() {
|
|
||||||
if ("nostr" in window) {
|
|
||||||
const pubkey = await window.nostr?.getPublicKey();
|
|
||||||
if (pubkey) {
|
|
||||||
return new EventPublisher(pubkey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#eb(k: EventKind) {
|
#eb(k: EventKind) {
|
||||||
const eb = new EventBuilder();
|
const eb = new EventBuilder();
|
||||||
return eb.pubKey(this.#pubKey).kind(k);
|
return eb.pubKey(this.#pubKey).kind(k);
|
||||||
}
|
}
|
||||||
|
|
||||||
async #sign(eb: EventBuilder) {
|
async #sign(eb: EventBuilder) {
|
||||||
if (this.#hasNip07 && !this.#privateKey) {
|
|
||||||
const nip7PubKey = await barrierQueue(Nip7Queue, () => unwrap(window.nostr).getPublicKey());
|
|
||||||
if (nip7PubKey !== this.#pubKey) {
|
|
||||||
throw new Error("Can't sign event, NIP-07 pubkey does not match");
|
|
||||||
}
|
|
||||||
const ev = eb.build();
|
const ev = eb.build();
|
||||||
return await barrierQueue(Nip7Queue, () => unwrap(window.nostr).signEvent(ev));
|
return await this.#signer.sign(ev);
|
||||||
} else if (this.#privateKey) {
|
|
||||||
return await eb.buildAndSign(this.#privateKey);
|
|
||||||
} else {
|
|
||||||
throw new Error("Can't sign event, no private keys available");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async nip4Encrypt(content: string, key: HexKey) {
|
async nip4Encrypt(content: string, otherKey: string) {
|
||||||
if (this.#hasNip07 && !this.#privateKey) {
|
return await this.#signer.nip4Encrypt(content, otherKey);
|
||||||
const nip7PubKey = await barrierQueue(Nip7Queue, () => unwrap(window.nostr).getPublicKey());
|
|
||||||
if (nip7PubKey !== this.#pubKey) {
|
|
||||||
throw new Error("Can't encrypt content, NIP-07 pubkey does not match");
|
|
||||||
}
|
|
||||||
return await barrierQueue(Nip7Queue, () =>
|
|
||||||
unwrap(window.nostr?.nip04?.encrypt).call(window.nostr?.nip04, key, content)
|
|
||||||
);
|
|
||||||
} else if (this.#privateKey) {
|
|
||||||
return await EventExt.encryptDm(content, this.#privateKey, key);
|
|
||||||
} else {
|
|
||||||
throw new Error("Can't encrypt content, no private keys available");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async nip4Decrypt(content: string, otherKey: HexKey) {
|
async nip4Decrypt(content: string, otherKey: string) {
|
||||||
if (this.#hasNip07 && !this.#privateKey && window.nostr?.nip04?.decrypt) {
|
return await this.#signer.nip4Decrypt(content, otherKey);
|
||||||
return await barrierQueue(Nip7Queue, () =>
|
|
||||||
unwrap(window.nostr?.nip04?.decrypt).call(window.nostr?.nip04, otherKey, content)
|
|
||||||
);
|
|
||||||
} else if (this.#privateKey) {
|
|
||||||
return await EventExt.decryptDm(content, this.#privateKey, otherKey);
|
|
||||||
} else {
|
|
||||||
throw new Error("Can't decrypt content, no private keys available");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async nip42Auth(challenge: string, relay: string) {
|
async nip42Auth(challenge: string, relay: string) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user