NIP-04 encryption is deprecated due to security vulnerabilities. This migrates MuteList (kind 10000) and PinnedUsers (kind 10010) private entries to use NIP-44 encryption, with backward compatibility for reading existing NIP-04 encrypted content. When NIP-04 content is detected, it is automatically re-encrypted with NIP-44 and republished to gradually migrate users. Co-Authored-By: captain-stacks <201298974+captain-stacks@users.noreply.github.com> Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
70 lines
1.9 KiB
TypeScript
70 lines
1.9 KiB
TypeScript
import { ISigner, TDraftEvent } from '@/types'
|
|
import { finalizeEvent, getPublicKey as nGetPublicKey, nip04, nip19 } from 'nostr-tools'
|
|
import { v2 as nip44 } from 'nostr-tools/nip44'
|
|
|
|
export class NsecSigner implements ISigner {
|
|
private privkey: Uint8Array | null = null
|
|
private pubkey: string | null = null
|
|
|
|
login(nsecOrPrivkey: string | Uint8Array) {
|
|
let privkey
|
|
if (typeof nsecOrPrivkey === 'string') {
|
|
const { type, data } = nip19.decode(nsecOrPrivkey)
|
|
if (type !== 'nsec') {
|
|
throw new Error('invalid nsec')
|
|
}
|
|
privkey = data
|
|
} else {
|
|
privkey = nsecOrPrivkey
|
|
}
|
|
|
|
this.privkey = privkey
|
|
this.pubkey = nGetPublicKey(privkey)
|
|
return this.pubkey
|
|
}
|
|
|
|
async getPublicKey() {
|
|
if (!this.pubkey) {
|
|
throw new Error('Not logged in')
|
|
}
|
|
return this.pubkey
|
|
}
|
|
|
|
async signEvent(draftEvent: TDraftEvent) {
|
|
if (!this.privkey) {
|
|
throw new Error('Not logged in')
|
|
}
|
|
|
|
return finalizeEvent(draftEvent, this.privkey)
|
|
}
|
|
|
|
async nip04Encrypt(pubkey: string, plainText: string) {
|
|
if (!this.privkey) {
|
|
throw new Error('Not logged in')
|
|
}
|
|
return nip04.encrypt(this.privkey, pubkey, plainText)
|
|
}
|
|
|
|
async nip04Decrypt(pubkey: string, cipherText: string) {
|
|
if (!this.privkey) {
|
|
throw new Error('Not logged in')
|
|
}
|
|
return nip04.decrypt(this.privkey, pubkey, cipherText)
|
|
}
|
|
|
|
async nip44Encrypt(pubkey: string, plainText: string) {
|
|
if (!this.privkey) {
|
|
throw new Error('Not logged in')
|
|
}
|
|
const conversationKey = nip44.utils.getConversationKey(this.privkey, pubkey)
|
|
return nip44.encrypt(plainText, conversationKey)
|
|
}
|
|
|
|
async nip44Decrypt(pubkey: string, cipherText: string) {
|
|
if (!this.privkey) {
|
|
throw new Error('Not logged in')
|
|
}
|
|
const conversationKey = nip44.utils.getConversationKey(this.privkey, pubkey)
|
|
return nip44.decrypt(cipherText, conversationKey)
|
|
}
|
|
}
|