nip-07 support

This commit is contained in:
ennmichael 2023-04-09 00:09:05 +02:00
parent acfcd32dfa
commit 31b0538337
No known key found for this signature in database
GPG Key ID: 6E6E183431A26AF7
4 changed files with 50 additions and 7 deletions

View File

@ -1,7 +1,6 @@
import * as secp from "@noble/secp256k1" import * as secp from "@noble/secp256k1"
import base64 from "base64-js" import base64 from "base64-js"
import { bech32 } from "bech32" import { bech32 } from "bech32"
import { NostrError } from "./common"
// TODO Use toHex as well as toString? Might be more explicit // TODO Use toHex as well as toString? Might be more explicit
// Or maybe replace toString with toHex // Or maybe replace toString with toHex

View File

@ -50,8 +50,24 @@ export async function createDirectMessage(
): Promise<DirectMessage> { ): Promise<DirectMessage> {
recipient = parsePublicKey(recipient) recipient = parsePublicKey(recipient)
if (priv === undefined) { if (priv === undefined) {
// TODO Use NIP-07 if (
throw new NostrError("todo") typeof window === "undefined" ||
window.nostr?.nip04?.encrypt === undefined
) {
throw new NostrError("private key not specified")
}
const content = await window.nostr.nip04.encrypt(recipient, message)
return await signEvent(
{
kind: EventKind.DirectMessage,
tags: [["p", recipient]],
content,
getMessage,
getRecipient,
getPrevious,
},
priv
)
} else { } else {
priv = parsePrivateKey(priv) priv = parsePrivateKey(priv)
const { data, iv } = await aesEncryptBase64(priv, recipient, message) const { data, iv } = await aesEncryptBase64(priv, recipient, message)
@ -81,8 +97,13 @@ export async function getMessage(
throw new NostrError(`invalid direct message content ${this.content}`) throw new NostrError(`invalid direct message content ${this.content}`)
} }
if (priv === undefined) { if (priv === undefined) {
// TODO Try to use NIP-07 if (
throw new NostrError("todo") typeof window === "undefined" ||
window.nostr?.nip04?.decrypt === undefined
) {
throw new NostrError("private key not specified")
}
return await window.nostr.nip04.decrypt(this.pubkey, this.content)
} else if (getPublicKey(priv) === this.getRecipient()) { } else if (getPublicKey(priv) === this.getRecipient()) {
return await aesDecryptBase64(this.pubkey, priv, { data, iv }) return await aesDecryptBase64(this.pubkey, priv, { data, iv })
} }

View File

@ -22,6 +22,7 @@ import {
} from "./direct-message" } from "./direct-message"
import { ContactList, getContacts } from "./contact-list" import { ContactList, getContacts } from "./contact-list"
import { Deletion, getEvents } from "./deletion" import { Deletion, getEvents } from "./deletion"
import "../nostr-object"
// TODO Add remaining event types // TODO Add remaining event types
@ -135,8 +136,10 @@ export async function signEvent<T extends RawEvent>(
event.sig = await schnorrSign(id, priv) event.sig = await schnorrSign(id, priv)
return event as T return event as T
} else { } else {
// TODO Try to use NIP-07, otherwise throw if (typeof window === "undefined" || window.nostr === undefined) {
throw new NostrError("todo") throw new NostrError("no private key provided")
}
return await window.nostr.signEvent(event)
} }
} }

View File

@ -0,0 +1,20 @@
import { PublicKey } from "./crypto"
import { RawEvent, Unsigned } from "./event"
declare global {
interface Window {
nostr?: {
getPublicKey: () => Promise<PublicKey>
signEvent: <T extends RawEvent>(event: Unsigned<T>) => Promise<T>
getRelays?: () => Promise<{
[url: string]: { read: boolean; write: boolean }
}>
nip04?: {
encrypt?: (pubkey: PublicKey, plaintext: string) => Promise<string>
decrypt?: (pubkey: PublicKey, ciphertext: string) => Promise<string>
}
}
}
}