UNPKG

lotus-sdk

Version:

Central repository for several classes of tools for integrating with, and building for, the Lotusia ecosystem

101 lines (100 loc) 3.19 kB
import { Hash } from '../bitcore/crypto/hash.js'; import { Random } from '../bitcore/crypto/random.js'; import { BaseMessageType } from './types.js'; export class P2PProtocol { createMessage(type, payload, from, options) { const messageId = this._generateMessageId(); return { type, from, to: options?.to, payload, timestamp: Date.now(), messageId, signature: options?.signature, protocol: options?.protocol, }; } serialize(message) { try { const json = JSON.stringify(message); return Buffer.from(json, 'utf8'); } catch (error) { throw new Error(`Failed to serialize message: ${error}`); } } deserialize(data) { try { const json = data.toString('utf8'); const message = JSON.parse(json); return message; } catch (error) { throw new Error(`Failed to deserialize message: ${error}`); } } validateMessage(message) { if (!message.type || typeof message.type !== 'string') { return false; } if (!message.from || typeof message.from !== 'string') { return false; } if (!message.timestamp || typeof message.timestamp !== 'number') { return false; } if (!message.messageId || typeof message.messageId !== 'string') { return false; } const now = Date.now(); const maxAge = 300000; if (Math.abs(now - message.timestamp) > maxAge) { return false; } return true; } validateMessageSize(message, maxSize = 1024 * 1024) { const serialized = this.serialize(message); return serialized.length <= maxSize; } computeMessageHash(message) { const data = Buffer.concat([ Buffer.from(message.type), Buffer.from(message.from), Buffer.from(message.to || ''), Buffer.from(message.messageId), ]); return Hash.hmac(Hash.sha256, data, Buffer.from('lotus-lib-p2p-message-hash-key')).toString('hex'); } createHandshake(peerId, metadata) { return this.createMessage(BaseMessageType.PEER_HANDSHAKE, { peerId, timestamp: Date.now(), metadata, }, peerId); } createHeartbeat(peerId) { return this.createMessage(BaseMessageType.PEER_HEARTBEAT, { timestamp: Date.now(), }, peerId); } createDisconnect(peerId, reason) { return this.createMessage(BaseMessageType.PEER_DISCONNECT, { reason, timestamp: Date.now(), }, peerId); } createError(peerId, error, context) { return this.createMessage(BaseMessageType.ERROR, { error, context, timestamp: Date.now(), }, peerId); } _generateMessageId() { const timestamp = Date.now().toString(36); const random = Random.getRandomBuffer(8).toString('hex'); return `${timestamp}-${random}`; } }