Files
snort/packages/system/src/impl/nip55.ts
2024-12-06 11:59:15 +00:00

87 lines
2.6 KiB
TypeScript

import debug from "debug";
import { NostrEvent, NotSignedNostrEvent } from "../nostr";
import { EventSigner } from "../signer";
import { v4 as uuid } from "uuid";
import { bech32ToHex } from "@snort/shared";
export class Nip55Signer implements EventSigner {
#log = debug("NIP-55");
#queue: Array<{ id: string; resolve: (o: any) => void; reject: () => void }> = [];
init(): Promise<void> {
// nothing here
return Promise.resolve();
}
async getPubKey() {
let pk = await this.#call("get_public_key", "signature");
if (pk.startsWith("npub")) {
pk = bech32ToHex(pk);
}
return pk;
}
async nip4Encrypt(content: string, key: string) {
return await this.#call("nip04_encrypt", "signature", content, new Map([["pubkey", key]]));
}
async nip4Decrypt(content: string, otherKey: string) {
return await this.#call("nip04_decrypt", "signature", content, new Map([["pubkey", otherKey]]));
}
async nip44Encrypt(content: string, key: string) {
return await this.#call("nip44_encrypt", "signature", content, new Map([["pubkey", key]]));
}
async nip44Decrypt(content: string, otherKey: string) {
return await this.#call("nip44_decrypt", "signature", content, new Map([["pubkey", otherKey]]));
}
async sign(ev: NostrEvent | NotSignedNostrEvent) {
const evRet = await this.#call("sign_event", "event", ev);
return JSON.parse(evRet);
}
get supports(): string[] {
return ["nip04", "nip44"];
}
#call(
method: string,
returnType: string,
obj?: NostrEvent | NotSignedNostrEvent | string,
otherParams?: Map<string, string>,
) {
const id = uuid();
const objString = typeof obj === "string" ? obj : obj != undefined ? JSON.stringify(obj) : undefined;
const params = new URLSearchParams();
params.append("compressionType", "none");
params.append("returnType", returnType);
params.append("type", method);
if (otherParams) {
for (const [k, v] of otherParams) {
params.append(k, v);
}
}
return new Promise<string>((resolve, reject) => {
const t = setInterval(async () => {
if (document.hasFocus()) {
const text = await navigator.clipboard.readText();
if (text) {
this.#log("Response: %s", text);
await navigator.clipboard.writeText("");
resolve(text);
clearInterval(t);
}
}
}, 500);
const dst = `nostrsigner:${objString ?? ""}?${params.toString()}`;
this.#log("Sending command %s, %s", id, dst);
globalThis.location.href = dst;
});
}
}