blowater/app/UI/account-context.ts

101 lines
3.1 KiB
TypeScript
Raw Normal View History

import { sleep } from "@blowater/csp";
import { PublicKey } from "@blowater/nostr-sdk";
2023-06-30 14:05:57 +00:00
import {
InMemoryAccountContext,
NostrAccountContext,
NostrEvent,
NostrKind,
2023-06-30 14:05:57 +00:00
UnsignedNostrEvent,
} from "@blowater/nostr-sdk";
import { LocalPrivateKeyController } from "./sign-in.ts";
2023-06-30 14:05:57 +00:00
2023-07-09 07:06:13 +00:00
type NIP07 = {
2023-06-30 14:05:57 +00:00
getPublicKey(): Promise<string>;
signEvent<T extends NostrKind>(event: UnsignedNostrEvent<T>): Promise<NostrEvent<T>>;
getRelays(): { [url: string]: { read: boolean; write: boolean } };
2023-07-09 07:06:13 +00:00
nip04: {
encrypt: (pubkey: string, plaintext: string) => Promise<string | Error>;
decrypt: (pubkey: string, ciphertext: string) => Promise<string | Error>;
};
nip44: {
encrypt: (pubkey: string, plaintext: string) => Promise<string | Error>;
decrypt: (pubkey: string, ciphertext: string) => Promise<string | Error>;
};
2023-06-30 14:05:57 +00:00
};
2023-07-09 07:06:13 +00:00
export class Nip7ExtensionContext implements NostrAccountContext {
static async New(): Promise<Nip7ExtensionContext | Error | undefined> {
// wait for nip-07 extension init
await sleep(20);
let ext;
if ("nostr" in window) {
ext = window.nostr as NIP07;
} else {
2023-06-30 14:05:57 +00:00
return undefined;
}
2023-06-30 14:05:57 +00:00
let pubkey: string | undefined;
try {
pubkey = await ext.getPublicKey();
} catch (e) {
return e;
}
const pub = PublicKey.FromHex(pubkey);
if (pub instanceof Error) {
return pub;
}
2023-07-09 07:06:13 +00:00
return new Nip7ExtensionContext(ext, pub);
2023-06-30 14:05:57 +00:00
}
private constructor(
private nip07: NIP07,
2023-06-30 14:05:57 +00:00
public publicKey: PublicKey,
) {
console.log(nip07);
2023-06-30 14:05:57 +00:00
}
async signEvent<T extends NostrKind = NostrKind>(event: UnsignedNostrEvent<T>) {
return this.nip07.signEvent(event);
2023-06-30 14:05:57 +00:00
}
2023-07-09 07:06:13 +00:00
encrypt = async (pubkey: string, plaintext: string) => {
if (!("nip44" in this.nip07)) {
return new Error(
"This NIP-07 extension does not implement NIP-44, please use a NIP-44 compatible one",
);
}
try {
return this.nip07.nip44.encrypt(pubkey, plaintext);
} catch (e) {
return e as Error;
2023-07-09 07:06:13 +00:00
}
};
2023-07-09 07:06:13 +00:00
decrypt = async (pubkey: string, ciphertext: string) => {
2023-10-21 05:04:04 +00:00
try {
if (ciphertext.includes("?iv")) {
return await this.nip07.nip04.decrypt(pubkey, ciphertext);
} else {
if (!("nip44" in this.nip07)) {
return new Error(
"This NIP-07 extension does not implement NIP-44, please use a NIP-44 compatible one",
);
}
return await this.nip07.nip44.decrypt(pubkey, ciphertext);
}
2023-10-21 05:04:04 +00:00
} catch (e) {
return e as Error;
2023-06-30 14:05:57 +00:00
}
};
}
export async function GetLocalStorageAccountContext() {
const priKey = await LocalPrivateKeyController.getKey("blowater");
2024-01-19 07:21:43 +00:00
if (priKey instanceof Error) {
return priKey;
} else if (priKey == undefined) {
2023-06-30 14:05:57 +00:00
return undefined;
}
2024-01-19 07:21:43 +00:00
return InMemoryAccountContext.New(priKey);
2023-06-30 14:05:57 +00:00
}