UNPKG

@node-dlc/messaging

Version:
162 lines (118 loc) 4.14 kB
import { BufferReader, BufferWriter } from '@node-dlc/bufio'; import { crc32c } from '@node-dlc/checksum'; import { MessageType } from '../MessageType'; const MAX_DATA_LEN = 190; export abstract class IrcMessage { public static deserialize(buf: Buffer): IrcMessageV0 { const reader = new BufferReader(buf); const type = Number(reader.readUInt16BE()); switch (type) { case MessageType.IrcMessageV0: return IrcMessageV0.deserialize(buf); default: throw new Error(`Irc message type must be IrcMessageV0`); } } public abstract type: number; public abstract serialize(): Buffer; } /** * IrcMessage contains information for Irc message packet. */ export class IrcMessageV0 extends IrcMessage { public static type = MessageType.IrcMessageV0; public static fromBuffer(buf: Buffer, pubkey: Buffer): IrcMessageV0[] { const instances: IrcMessageV0[] = []; const checksum = crc32c(buf); const sequenceLength = Math.ceil(buf.length / MAX_DATA_LEN); const reader = new BufferReader(buf); const bufLen = buf.length; const currentTime = Math.floor(new Date().getTime() / 1000); for (let i = 0; i < sequenceLength; i++) { const sequenceNumber = i; const instance = new IrcMessageV0(); instance.sequenceLength = BigInt(sequenceLength); instance.sequenceNumber = BigInt(sequenceNumber); instance.checksum = checksum; instance.pubkey = pubkey; instance.timestamp = currentTime; instance.data = reader.readBytes( Math.min(MAX_DATA_LEN, bufLen - reader.position), ); instances.push(instance); } return instances; } public static fromString(str: string, pubkey: Buffer): IrcMessageV0[] { const buf = Buffer.from(str); return IrcMessageV0.fromBuffer(buf, pubkey); } /** * Deserializes an irc message * @param buf */ public static deserialize(buf: Buffer): IrcMessageV0 { const instance = new IrcMessageV0(); const reader = new BufferReader(buf); reader.readBigSize(); // read type instance.length = reader.readBigSize(); instance.sequenceLength = reader.readBigSize(); instance.sequenceNumber = reader.readBigSize(); instance.checksum = reader.readUInt32BE(); instance.signature = reader.readBytes(64); instance.pubkey = reader.readBytes(33); instance.timestamp = reader.readUInt32BE(); const dataLen = reader.readUInt16BE(); instance.data = reader.readBytes(dataLen); return instance; } public type = IrcMessageV0.type; public length: bigint; public sequenceLength: bigint; public sequenceNumber: bigint; public checksum: number; public signature: Buffer; public pubkey: Buffer; public timestamp: number; public data: Buffer; public serializeWithoutSig(): Buffer { const writer = new BufferWriter(); writer.writeBigSize(this.sequenceLength); writer.writeBigSize(this.sequenceNumber); writer.writeUInt64BE(this.checksum); writer.writeBytes(this.pubkey); writer.writeUInt32BE(this.timestamp); writer.writeUInt16BE(this.data.length); writer.writeBytes(this.data); return writer.toBuffer(); } /** * Serializes the irc_message_v0 */ public serialize(): Buffer { const writer = new BufferWriter(); writer.writeBigSize(this.type); const dataWriter = new BufferWriter(); dataWriter.writeBigSize(this.sequenceLength); dataWriter.writeBigSize(this.sequenceNumber); dataWriter.writeUInt32BE(this.checksum); dataWriter.writeBytes(this.signature); dataWriter.writeBytes(this.pubkey); dataWriter.writeUInt32BE(this.timestamp); dataWriter.writeUInt16BE(this.data.length); dataWriter.writeBytes(this.data); writer.writeBigSize(dataWriter.size); writer.writeBytes(dataWriter.toBuffer()); return writer.toBuffer(); } } export class IrcMessageWithoutSig { constructor( readonly sequenceLength: bigint, readonly sequenceNumber: bigint, readonly checksum: number, readonly signature: Buffer, readonly pubkey: Buffer, readonly data: Buffer, ) {} }