-
Notifications
You must be signed in to change notification settings - Fork 60
/
nip44.ts
62 lines (51 loc) · 1.76 KB
/
nip44.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import {join} from "ramda"
import {nip44} from "nostr-tools"
import {cached} from "@welshman/lib"
import {switcherFn, tryFunc} from "hurdak"
import {fromHex} from "src/util/nostr"
import type {Session} from "src/engine/model"
import type {Connect} from "./connect"
import {withExtension} from "./nip07"
// Deriving shared secret is an expensive computation, cache it
export const getSharedSecret = cached({
maxSize: 100,
getKey: join(":"),
getValue: ([sk, pk]: string[]) => nip44.v2.utils.getConversationKey(fromHex(sk), pk),
})
export class Nip44 {
constructor(
readonly session: Session,
readonly connect: Connect,
) {}
isEnabled() {
if (["privkey", "connect"].includes(this.session?.method)) {
return true
}
if (this.session?.method === "extension") {
return Boolean((window as any).nostr?.nip44)
}
return false
}
encrypt(message: string, pk: string, sk: string) {
return nip44.v2.encrypt(message, getSharedSecret(sk, pk))
}
decrypt(payload: string, pk: string, sk: string) {
return tryFunc(() => nip44.v2.decrypt(payload, getSharedSecret(sk, pk)))
}
encryptAsUser(message: string, pk: string) {
const {method, privkey} = this.session
return switcherFn(method, {
privkey: () => this.encrypt(message, pk, privkey),
extension: () => withExtension(ext => ext.nip44.encrypt(pk, message)),
connect: () => this.connect.broker.nip44Encrypt(pk, message),
})
}
decryptAsUser(message: string, pk: string) {
const {method, privkey} = this.session
return switcherFn(method, {
privkey: () => this.decrypt(message, pk, privkey),
extension: () => withExtension(ext => ext.nip44.decrypt(pk, message)),
connect: () => this.connect.broker.nip44Decrypt(pk, message),
})
}
}