import { CryptoUtil } from './crypto.js'; import { Post } from './post.js'; export class Message { constructor(content) { this.content = content; } async sign({ publicKey, privateKey }) { this.publicKey = await CryptoUtil.exportKey(publicKey); // Call toJSON before signing, to match what we'll later send this.signature = await CryptoUtil.sign(this.contentToJSON(this.content), privateKey); return this; } static async verify({ content, publicKey, signature }) { return CryptoUtil.verify(content, publicKey, signature); } static contentFromJSON(data) { return data; } static contentToJSON(content) { return content; } toJSON() { return { type: this.type, content: this.contentToJSON(this.content), publicKey: this.publicKey, signature: this.signature, }; } } export class PostMessage extends Message { type = 'post'; static contentFromJSON({ post, stake }) { return { post: Post.fromJSON(post), stake, }; } static contentToJSON({ post, stake }) { return { post: post.toJSON(), stake, }; } } export class PeerMessage extends Message { type = 'peer'; } const messageTypes = new Map([ ['post', PostMessage], ['peer', PeerMessage], ]); export const messageFromJSON = ({ type, content }) => { const MessageType = messageTypes.get(type) || Message; const messageContent = MessageType.contentFromJSON(content); return new MessageType(messageContent); };