@node-dlc/messaging
Version:
DLC Messaging Protocol
224 lines (180 loc) • 6.21 kB
text/typescript
import { BufferReader, BufferWriter } from '@node-dlc/bufio';
import { MessageType } from '../MessageType';
import { IDlcMessage } from './DlcMessage';
export abstract class EventDescriptor {
public static deserialize(
buf: Buffer,
): EnumEventDescriptorV0 | DigitDecompositionEventDescriptorV0 {
const reader = new BufferReader(buf);
const type = Number(reader.readBigSize());
switch (type) {
case MessageType.EnumEventDescriptorV0:
return EnumEventDescriptorV0.deserialize(buf);
case MessageType.DigitDecompositionEventDescriptorV0:
return DigitDecompositionEventDescriptorV0.deserialize(buf);
default:
throw new Error(
`Payout function TLV type must be EnumEventDescriptorV0 or DigitDecompositionEventDescriptorV0`,
);
}
}
public abstract type: number;
public abstract length: bigint;
public abstract toJSON():
| IEnumEventDescriptorV0JSON
| IDigitDecompositionEventDescriptorV0JSON;
public abstract serialize(): Buffer;
}
/**
* EnumEventDescriptor V0 is a simple enumeration of outcomes
*/
export class EnumEventDescriptorV0
extends EventDescriptor
implements IDlcMessage {
public static type = MessageType.EnumEventDescriptorV0;
/**
* Deserializes an enum_event_descriptor_v0 message
* @param buf
*/
public static deserialize(buf: Buffer): EnumEventDescriptorV0 {
const instance = new EnumEventDescriptorV0();
const reader = new BufferReader(buf);
reader.readBigSize(); // read type
instance.length = reader.readBigSize(); // need to fix this
reader.readUInt16BE(); // num_outcomes
while (!reader.eof) {
const outcomeLen = reader.readBigSize();
const outcomeBuf = reader.readBytes(Number(outcomeLen));
instance.outcomes.push(outcomeBuf.toString());
}
return instance;
}
/**
* The type for enum_event_descriptor_v0 message. enum_event_descriptor_v0 = 55302
*/
public type = EnumEventDescriptorV0.type;
public length: bigint;
public outcomes: string[] = [];
/**
* Converts enum_event_descriptor_v0 to JSON
*/
public toJSON(): IEnumEventDescriptorV0JSON {
return {
type: this.type,
outcomes: this.outcomes,
};
}
/**
* Serializes the enum_event_descriptor_v0 message into a Buffer
*/
public serialize(): Buffer {
const writer = new BufferWriter();
writer.writeBigSize(this.type);
const dataWriter = new BufferWriter();
dataWriter.writeUInt16BE(this.outcomes.length);
for (const outcome of this.outcomes) {
dataWriter.writeBigSize(outcome.length);
dataWriter.writeBytes(Buffer.from(outcome));
}
writer.writeBigSize(dataWriter.size);
writer.writeBytes(dataWriter.toBuffer());
return writer.toBuffer();
}
}
/**
* DigitDecompositionEventDescriptorV0 V0 is a simple enumeration of outcomes
*/
export class DigitDecompositionEventDescriptorV0
extends EventDescriptor
implements IDlcMessage {
public static type = MessageType.DigitDecompositionEventDescriptorV0;
/**
* Deserializes an digit_decomposition_event_descriptor_v0 message
* @param buf
*/
public static deserialize(buf: Buffer): DigitDecompositionEventDescriptorV0 {
const instance = new DigitDecompositionEventDescriptorV0();
const reader = new BufferReader(buf);
reader.readBigSize(); // read type
instance.length = reader.readBigSize(); // need to fix this
/**
* NOTE: BASE IS INCORRECT FORMAT FOR DLC SPEC (SHOULD BE BIGSIZE)
* Will be fixed in oracle_announcement_v1
* https://github.com/discreetlogcontracts/dlcspecs/blob/master/Oracle.md#version-0-digit_decomposition_event_descriptor
*/
instance.base = reader.readUInt16BE();
instance.isSigned = reader.readUInt8() === 1;
const unitLen = reader.readBigSize();
const unitBuf = reader.readBytes(Number(unitLen));
instance.unit = unitBuf.toString();
instance.precision = reader.readUInt32BE();
instance.nbDigits = reader.readUInt16BE();
return instance;
}
/**
* The type for digit_decomposition_event_descriptor_v0 message. digit_decomposition_event_descriptor_v0 = 55302
*/
public type = DigitDecompositionEventDescriptorV0.type;
public length: bigint;
public base: number; // Switch to bigint in oracle_announcement_v1
public isSigned: boolean;
public unit: string;
public precision: number;
public nbDigits: number;
/**
* Validates correctness of all fields in the message
* https://github.com/discreetlogcontracts/dlcspecs/blob/master/Oracle.md
* @throws Will throw an error if validation fails
*/
public validate(): void {
if (this.base <= 0) {
throw new Error('base must be greater than 0');
}
// TODO: support isSigned according to specifications
if (this.isSigned) {
throw new Error('node-dlc does not support isSigned');
}
}
/**
* Converts digit_decomposition_event_descriptor_v0 to JSON
*/
public toJSON(): IDigitDecompositionEventDescriptorV0JSON {
return {
type: this.type,
base: this.base,
isSigned: this.isSigned,
unit: this.unit,
precision: this.precision,
nbDigits: this.nbDigits,
};
}
/**
* Serializes the digit_decomposition_event_descriptor_v0 message into a Buffer
*/
public serialize(): Buffer {
const writer = new BufferWriter();
writer.writeBigSize(this.type);
const dataWriter = new BufferWriter();
dataWriter.writeUInt16BE(this.base); // Switch to BigSize in oracle_announcement_v1
dataWriter.writeUInt8(this.isSigned ? 1 : 0);
dataWriter.writeBigSize(this.unit.length);
dataWriter.writeBytes(Buffer.from(this.unit));
dataWriter.writeUInt32BE(this.precision);
dataWriter.writeUInt16BE(this.nbDigits);
writer.writeBigSize(dataWriter.size);
writer.writeBytes(dataWriter.toBuffer());
return writer.toBuffer();
}
}
export interface IEnumEventDescriptorV0JSON {
type: number;
outcomes: string[];
}
export interface IDigitDecompositionEventDescriptorV0JSON {
type: number;
base: number;
isSigned: boolean;
unit: string;
precision: number;
nbDigits: number;
}