wip: mandate signatures

This commit is contained in:
Danish Arora 2025-08-29 14:41:51 +05:30
parent d43d3bfec7
commit d8fe4a3dcc
No known key found for this signature in database
GPG Key ID: 1C6EF37CDAE1426E
8 changed files with 63 additions and 34 deletions

View File

@ -26,7 +26,8 @@ describe('RelevanceCalculator', () => {
content: 'Test content', content: 'Test content',
timestamp: Date.now(), timestamp: Date.now(),
upvotes: [], upvotes: [],
downvotes: [] downvotes: [],
signature: 'signature'
}; };
const result = calculator.calculatePostScore(post, [], [], mockUserVerificationStatus); const result = calculator.calculatePostScore(post, [], [], mockUserVerificationStatus);
@ -45,7 +46,8 @@ describe('RelevanceCalculator', () => {
content: 'Test content', content: 'Test content',
timestamp: Date.now(), timestamp: Date.now(),
upvotes: [], upvotes: [],
downvotes: [] downvotes: [],
signature: 'signature'
}; };
const result = calculator.calculatePostScore(post, [], [], mockUserVerificationStatus); const result = calculator.calculatePostScore(post, [], [], mockUserVerificationStatus);
@ -61,7 +63,8 @@ describe('RelevanceCalculator', () => {
verificationStatus: EVerificationStatus.VERIFIED_OWNER, verificationStatus: EVerificationStatus.VERIFIED_OWNER,
ensOwnership: true, ensOwnership: true,
ensName: 'test.eth', ensName: 'test.eth',
lastChecked: Date.now() lastChecked: Date.now(),
signature: 'signature'
}; };
const isVerified = calculator.isUserVerified(verifiedUser); const isVerified = calculator.isUserVerified(verifiedUser);
@ -74,7 +77,8 @@ describe('RelevanceCalculator', () => {
walletType: 'bitcoin', walletType: 'bitcoin',
verificationStatus: EVerificationStatus.VERIFIED_OWNER, verificationStatus: EVerificationStatus.VERIFIED_OWNER,
ordinalOwnership: true, ordinalOwnership: true,
lastChecked: Date.now() lastChecked: Date.now(),
signature: 'signature'
}; };
const isVerified = calculator.isUserVerified(verifiedUser); const isVerified = calculator.isUserVerified(verifiedUser);
@ -87,7 +91,8 @@ describe('RelevanceCalculator', () => {
walletType: 'ethereum', walletType: 'ethereum',
verificationStatus: EVerificationStatus.UNVERIFIED, verificationStatus: EVerificationStatus.UNVERIFIED,
ensOwnership: false, ensOwnership: false,
lastChecked: Date.now() lastChecked: Date.now(),
signature: 'signature'
}; };
const isVerified = calculator.isUserVerified(unverifiedUser); const isVerified = calculator.isUserVerified(unverifiedUser);
@ -104,7 +109,8 @@ describe('RelevanceCalculator', () => {
timestamp: Date.now(), timestamp: Date.now(),
upvotes: [], upvotes: [],
downvotes: [], downvotes: [],
moderated: true moderated: true,
signature: 'signature'
}; };
const result = calculator.calculatePostScore(post, [], [], mockUserVerificationStatus); const result = calculator.calculatePostScore(post, [], [], mockUserVerificationStatus);
@ -122,16 +128,17 @@ describe('RelevanceCalculator', () => {
content: 'Test content', content: 'Test content',
timestamp: Date.now(), timestamp: Date.now(),
upvotes: [], upvotes: [],
downvotes: [] downvotes: [],
signature: 'signature'
}; };
const votes: VoteMessage[] = [ const votes: VoteMessage[] = [
{ id: 'vote1', targetId: '1', value: 1, author: 'user1', timestamp: Date.now(), type: MessageType.VOTE }, { id: 'vote1', targetId: '1', value: 1, author: 'user1', timestamp: Date.now(), type: MessageType.VOTE, signature: 'signature' },
{ id: 'vote2', targetId: '1', value: 1, author: 'user3', timestamp: Date.now(), type: MessageType.VOTE } { id: 'vote2', targetId: '1', value: 1, author: 'user3', timestamp: Date.now(), type: MessageType.VOTE, signature: 'signature' }
]; ];
const comments: Comment[] = [ const comments: Comment[] = [
{ id: 'comment1', postId: '1', authorAddress: 'user1', content: 'Test comment', timestamp: Date.now(), upvotes: [], downvotes: [] } { id: 'comment1', postId: '1', authorAddress: 'user1', content: 'Test comment', timestamp: Date.now(), upvotes: [], downvotes: [], signature: 'signature' }
]; ];
const result = calculator.calculatePostScore(post, votes, comments, mockUserVerificationStatus); const result = calculator.calculatePostScore(post, votes, comments, mockUserVerificationStatus);
@ -156,7 +163,8 @@ describe('RelevanceCalculator', () => {
content: 'Recent content', content: 'Recent content',
timestamp: now, timestamp: now,
upvotes: [], upvotes: [],
downvotes: [] downvotes: [],
signature: 'signature'
}; };
const oldPost: Post = { const oldPost: Post = {
@ -167,7 +175,8 @@ describe('RelevanceCalculator', () => {
content: 'Old content', content: 'Old content',
timestamp: oneWeekAgo, timestamp: oneWeekAgo,
upvotes: [], upvotes: [],
downvotes: [] downvotes: [],
signature: 'signature'
}; };
const recentResult = calculator.calculatePostScore(recentPost, [], [], mockUserVerificationStatus); const recentResult = calculator.calculatePostScore(recentPost, [], [], mockUserVerificationStatus);
@ -186,14 +195,16 @@ describe('RelevanceCalculator', () => {
verificationStatus: EVerificationStatus.VERIFIED_OWNER, verificationStatus: EVerificationStatus.VERIFIED_OWNER,
ensOwnership: true, ensOwnership: true,
ensName: 'test.eth', ensName: 'test.eth',
lastChecked: Date.now() lastChecked: Date.now(),
signature: 'signature'
}, },
{ {
address: 'user2', address: 'user2',
walletType: 'bitcoin', walletType: 'bitcoin',
verificationStatus: EVerificationStatus.UNVERIFIED, verificationStatus: EVerificationStatus.UNVERIFIED,
ordinalOwnership: false, ordinalOwnership: false,
lastChecked: Date.now() lastChecked: Date.now(),
signature: 'signature'
} }
]; ];

View File

@ -67,6 +67,7 @@ export const createPost = async (
content, content,
timestamp: Date.now(), timestamp: Date.now(),
author: currentUser.address, author: currentUser.address,
signature: currentUser.signature
}; };
const cryptoService = new CryptoService(); const cryptoService = new CryptoService();
@ -134,11 +135,12 @@ export const createComment = async (
const commentId = uuidv4(); const commentId = uuidv4();
const commentMessage: CommentMessage = { const commentMessage: CommentMessage = {
type: MessageType.COMMENT, type: MessageType.COMMENT,
id: commentId, id: commentId,
postId, postId,
content, content,
timestamp: Date.now(), timestamp: Date.now(),
author: currentUser.address, author: currentUser.address,
signature: currentUser.signature
}; };
const cryptoService = new CryptoService(); const cryptoService = new CryptoService();
@ -198,6 +200,7 @@ export const createCell = async (
...(icon && { icon }), ...(icon && { icon }),
timestamp: Date.now(), timestamp: Date.now(),
author: currentUser.address, author: currentUser.address,
signature: currentUser.signature
}; };
const cryptoService = new CryptoService(); const cryptoService = new CryptoService();
@ -275,6 +278,7 @@ export const vote = async (
value: isUpvote ? 1 : -1, value: isUpvote ? 1 : -1,
timestamp: Date.now(), timestamp: Date.now(),
author: currentUser.address, author: currentUser.address,
signature: currentUser.signature
}; };
const cryptoService = new CryptoService(); const cryptoService = new CryptoService();
@ -342,6 +346,7 @@ export const moderatePost = async (
reason, reason,
timestamp: Date.now(), timestamp: Date.now(),
author: currentUser.address, author: currentUser.address,
signature: currentUser.signature
}; };
const cryptoService = new CryptoService(); const cryptoService = new CryptoService();
const messageService = new MessageService(authService!, cryptoService); const messageService = new MessageService(authService!, cryptoService);
@ -392,6 +397,7 @@ export const moderateComment = async (
reason, reason,
timestamp: Date.now(), timestamp: Date.now(),
author: currentUser.address, author: currentUser.address,
signature: currentUser.signature
}; };
const cryptoService = new CryptoService(); const cryptoService = new CryptoService();
const messageService = new MessageService(authService!, cryptoService); const messageService = new MessageService(authService!, cryptoService);
@ -439,7 +445,7 @@ export const moderateUser = async (
reason, reason,
author: currentUser.address, author: currentUser.address,
timestamp: Date.now(), timestamp: Date.now(),
signature: '', signature: currentUser.signature,
browserPubKey: currentUser.browserPubKey, browserPubKey: currentUser.browserPubKey,
}; };
const cryptoService = new CryptoService(); const cryptoService = new CryptoService();

View File

@ -2,7 +2,7 @@ import { createDecoder, createEncoder } from '@waku/sdk';
import { MessageType } from './types'; import { MessageType } from './types';
import { CellMessage, PostMessage, CommentMessage, VoteMessage } from './types'; import { CellMessage, PostMessage, CommentMessage, VoteMessage } from './types';
import { CONTENT_TOPICS, NETWORK_CONFIG } from './constants'; import { CONTENT_TOPICS, NETWORK_CONFIG } from './constants';
import { OpchanMessage } from '@/types'; import { OpchanMessage } from '@/types/forum';
export const encoders = { export const encoders = {
[MessageType.CELL]: createEncoder({ [MessageType.CELL]: createEncoder({
@ -21,6 +21,10 @@ export const encoders = {
contentTopic: CONTENT_TOPICS['vote'], contentTopic: CONTENT_TOPICS['vote'],
pubsubTopicShardInfo: {clusterId: NETWORK_CONFIG.clusterId, shard: 0} pubsubTopicShardInfo: {clusterId: NETWORK_CONFIG.clusterId, shard: 0}
}), }),
[MessageType.MODERATE]: createEncoder({
contentTopic: CONTENT_TOPICS['moderate'],
pubsubTopicShardInfo: {clusterId: NETWORK_CONFIG.clusterId, shard: 0}
})
} }
export const decoders = { export const decoders = {
@ -40,6 +44,10 @@ export const decoders = {
clusterId: NETWORK_CONFIG.clusterId, clusterId: NETWORK_CONFIG.clusterId,
shard: 0 shard: 0
}), }),
[MessageType.MODERATE]: createDecoder(CONTENT_TOPICS['moderate'], {
clusterId: NETWORK_CONFIG.clusterId,
shard: 0
})
} }
/** /**

View File

@ -1,4 +1,3 @@
import { NetworkConfig } from "@waku/sdk";
import { MessageType } from "./types"; import { MessageType } from "./types";
/** /**
@ -12,11 +11,11 @@ export const CONTENT_TOPICS: Record<MessageType, string> = {
[MessageType.MODERATE]: '/opchan/1/moderate/proto' [MessageType.MODERATE]: '/opchan/1/moderate/proto'
}; };
export const NETWORK_CONFIG: NetworkConfig = { export const NETWORK_CONFIG = {
// contentTopics: Object.values(CONTENT_TOPICS), // contentTopics: Object.values(CONTENT_TOPICS),
clusterId: 1, clusterId: 1,
shards: [0,1,2,3,4,5,6,7] shards: [0,1,2,3,4,5,6,7]
} } as const;
/** /**
* Bootstrap nodes for the Waku network * Bootstrap nodes for the Waku network

View File

@ -1,6 +1,6 @@
import { LightNode } from "@waku/sdk"; import { LightNode } from "@waku/sdk";
import { CellMessage, CommentMessage, MessageType, PostMessage, VoteMessage, ModerateMessage } from "./types"; import { CellMessage, CommentMessage, MessageType, PostMessage, VoteMessage, ModerateMessage } from "./types";
import { OpchanMessage } from "@/types"; import { OpchanMessage } from "@/types/forum";
import { encodeMessage, encoders, decoders, decodeMessage } from "./codec"; import { encodeMessage, encoders, decoders, decodeMessage } from "./codec";
export class EphemeralProtocolsManager { export class EphemeralProtocolsManager {

View File

@ -1,7 +1,6 @@
import { IDecodedMessage } from '@waku/sdk'; import { IDecodedMessage } from '@waku/sdk';
import { Cell, Post, Comment } from '@/types'; import { OpchanMessage, Cell, Post, Comment } from '@/types/forum';
import { CellMessage, CommentMessage, MessageType, PostMessage } from './types'; import { CellMessage, CommentMessage, MessageType, PostMessage } from './types';
import { OpchanMessage } from '@/types';
// Utility functions for converting between message types and application models // Utility functions for converting between message types and application models
export function cellToMessage(cell: Cell, sender: string): CellMessage { export function cellToMessage(cell: Cell, sender: string): CellMessage {
return { return {
@ -11,7 +10,8 @@ export function cellToMessage(cell: Cell, sender: string): CellMessage {
id: cell.id, id: cell.id,
name: cell.name, name: cell.name,
description: cell.description, description: cell.description,
...(cell.icon && { icon: cell.icon }) ...(cell.icon && { icon: cell.icon }),
signature: cell.signature,
}; };
} }
@ -20,7 +20,8 @@ export function messageToCell(message: CellMessage): Cell {
id: message.id, id: message.id,
name: message.name, name: message.name,
description: message.description, description: message.description,
icon: message.icon || '' icon: message.icon || '',
signature: message.signature,
}; };
} }
@ -32,7 +33,8 @@ export function postToMessage(post: Post, sender: string): PostMessage {
id: post.id, id: post.id,
title: post.title, title: post.title,
cellId: post.cellId, cellId: post.cellId,
content: post.content content: post.content,
signature: post.signature,
}; };
} }
@ -45,7 +47,8 @@ export function messageToPost(message: PostMessage): Post {
timestamp: message.timestamp, timestamp: message.timestamp,
title: message.title, title: message.title,
upvotes: [], upvotes: [],
downvotes: [] downvotes: [],
signature: message.signature,
}; };
} }
@ -56,7 +59,8 @@ export function commentToMessage(comment: Comment, sender: string): CommentMessa
author: sender, author: sender,
id: comment.id, id: comment.id,
postId: comment.postId, postId: comment.postId,
content: comment.content content: comment.content,
signature: comment.signature,
}; };
} }
@ -68,7 +72,8 @@ export function messageToComment(message: CommentMessage): Comment {
content: message.content, content: message.content,
timestamp: message.timestamp, timestamp: message.timestamp,
upvotes: [], upvotes: [],
downvotes: [] downvotes: [],
signature: message.signature,
}; };
} }

View File

@ -16,7 +16,7 @@ export interface BaseMessage {
type: MessageType; type: MessageType;
timestamp: number; timestamp: number;
author: string; author: string;
signature?: string; // Message signature for verification signature: string; // Message signature for verification
browserPubKey?: string; // Public key that signed the message browserPubKey?: string; // Public key that signed the message
} }

View File

@ -16,7 +16,7 @@ export interface User {
verificationStatus: EVerificationStatus; verificationStatus: EVerificationStatus;
signature?: string; signature: string;
lastChecked?: number; lastChecked?: number;
browserPubKey?: string; // Browser-generated public key for key delegation browserPubKey?: string; // Browser-generated public key for key delegation
delegationSignature?: string; // Signature from Bitcoin/Ethereum wallet for delegation delegationSignature?: string; // Signature from Bitcoin/Ethereum wallet for delegation
@ -52,7 +52,7 @@ export interface Post {
timestamp: number; timestamp: number;
upvotes: VoteMessage[]; upvotes: VoteMessage[];
downvotes: VoteMessage[]; downvotes: VoteMessage[];
signature?: string; // Message signature signature: string; // Message signature
browserPubKey?: string; // Public key that signed the message browserPubKey?: string; // Public key that signed the message
moderated?: boolean; moderated?: boolean;
moderatedBy?: string; moderatedBy?: string;
@ -72,7 +72,7 @@ export interface Comment {
timestamp: number; timestamp: number;
upvotes: VoteMessage[]; upvotes: VoteMessage[];
downvotes: VoteMessage[]; downvotes: VoteMessage[];
signature?: string; // Message signature signature: string; // Message signature
browserPubKey?: string; // Public key that signed the message browserPubKey?: string; // Public key that signed the message
moderated?: boolean; moderated?: boolean;
moderatedBy?: string; moderatedBy?: string;
@ -84,7 +84,7 @@ export interface Comment {
// Extended message types for verification // Extended message types for verification
export interface SignedMessage { export interface SignedMessage {
signature?: string; // Signature of the message signature: string; // Signature of the message
browserPubKey?: string; // Public key that signed the message browserPubKey?: string; // Public key that signed the message
} }