157 lines
4.0 KiB
TypeScript
157 lines
4.0 KiB
TypeScript
// import "websocket-polyfill";
|
|
import sha256 from "crypto-js/sha256";
|
|
import Hex from "crypto-js/enc-hex";
|
|
import { getTagValues } from "./utils";
|
|
import { sha256 as SHA256 } from "@noble/hashes/sha256";
|
|
import { bytesToHex } from "@noble/hashes/utils";
|
|
import crypto from "crypto";
|
|
import { Buffer } from "buffer";
|
|
import { log } from "../utils";
|
|
|
|
export enum Kind {
|
|
Metadata = 0,
|
|
Text = 1,
|
|
RecommendRelay = 2,
|
|
Contacts = 3,
|
|
EncryptedDirectMessage = 4,
|
|
EventDeletion = 5,
|
|
Reaction = 7,
|
|
ChannelCreation = 40,
|
|
ChannelMetadata = 41,
|
|
ChannelMessage = 42,
|
|
ChannelHideMessage = 43,
|
|
ChannelMuteUser = 44,
|
|
ProfileList = 30000,
|
|
GenericList = 30001,
|
|
}
|
|
|
|
export type Event = {
|
|
id?: string;
|
|
sig?: string;
|
|
kind: Kind;
|
|
tags: string[][];
|
|
pubkey: string;
|
|
content: string;
|
|
created_at: number;
|
|
};
|
|
|
|
export function getHashedKeyName(name: string) {
|
|
let eventHash = SHA256(name);
|
|
const version = bytesToHex(eventHash);
|
|
const alt = sha256(name).toString(Hex);
|
|
console.log("VERSION", version, "vs", alt);
|
|
console.log("EQUAL?", version === alt);
|
|
return version;
|
|
}
|
|
|
|
export namespace NostrService {
|
|
export function createEvent(
|
|
kind: number,
|
|
publicKey: string,
|
|
content: string,
|
|
tags: string[][],
|
|
) {
|
|
const event: Event = {
|
|
kind: kind,
|
|
pubkey: publicKey,
|
|
created_at: Math.floor(Date.now() / 1000),
|
|
content: content,
|
|
tags: tags,
|
|
};
|
|
event.id = getEventHash(event);
|
|
|
|
return event;
|
|
}
|
|
|
|
function serializeEvent(evt: Event) {
|
|
return JSON.stringify([
|
|
0,
|
|
evt.pubkey,
|
|
evt.created_at,
|
|
evt.kind,
|
|
evt.tags,
|
|
evt.content,
|
|
]);
|
|
}
|
|
|
|
function getEventHash(event: Event): string {
|
|
return sha256(serializeEvent(event)).toString(Hex);
|
|
}
|
|
|
|
export async function signEvent(event: Event) {
|
|
try {
|
|
return await window.nostr?.signEvent(event);
|
|
} catch (err: any) {
|
|
console.error("signing event failed");
|
|
}
|
|
return event;
|
|
}
|
|
|
|
export function filterBlogEvents(eventArray: Event[]) {
|
|
const filteredEvents = eventArray.filter((e1: Event, index: number) => {
|
|
if (e1.content === "") {
|
|
return false;
|
|
}
|
|
const title = getTagValues("title", e1.tags);
|
|
if (!title || title === "") {
|
|
return false;
|
|
}
|
|
// return eventArray.findIndex((e2: Event) => e2.id === e1.id) === index;
|
|
return true;
|
|
});
|
|
return filteredEvents;
|
|
}
|
|
}
|
|
|
|
export function encryptMessage(message: string, password: string) {
|
|
try {
|
|
const buffer = create32ByteBuffer(password);
|
|
const iv = crypto.randomBytes(16);
|
|
const cipher = crypto.createCipheriv("aes-256-cbc", buffer, iv);
|
|
|
|
const encrypted = Buffer.concat([
|
|
cipher.update(message, "utf-8"),
|
|
cipher.final(),
|
|
]);
|
|
|
|
return encrypted.toString("base64") + "?iv=" + iv.toString("base64");
|
|
} catch (e) {
|
|
console.error(e);
|
|
}
|
|
}
|
|
// Function to decrypt a hashed message using a passphrase
|
|
// Function to decrypt a hashed message using a passphrase
|
|
export function decryptMessage(encryptedMessage: string, password: string) {
|
|
log("func", "decryptMessage");
|
|
try {
|
|
const buffer = create32ByteBuffer(password);
|
|
// Extract IV from the received message
|
|
const [message, ivBase64] = encryptedMessage.split("?iv=");
|
|
if (!message || !ivBase64) {
|
|
return;
|
|
}
|
|
|
|
const iv = Buffer.from(ivBase64, "base64");
|
|
const encryptedText = Buffer.from(message, "base64");
|
|
const decipher = crypto.createDecipheriv("aes-256-cbc", buffer, iv);
|
|
const decrypted = decipher.update(encryptedText);
|
|
return Buffer.concat([decrypted, decipher.final()]).toString();
|
|
} catch (e) {
|
|
console.error("Error decrypting", e);
|
|
}
|
|
}
|
|
|
|
function create32ByteBuffer(inputString: string) {
|
|
const hash = crypto.createHash("sha256").update(inputString).digest("hex");
|
|
const buffer = Buffer.from(hash, "hex");
|
|
return buffer;
|
|
}
|
|
|
|
export function generateRandomString() {
|
|
return crypto.randomBytes(32).toString("hex");
|
|
}
|
|
|
|
export function randomId(): string {
|
|
return crypto.randomBytes(32).toString("hex").slice(0, 8);
|
|
}
|