UNPKG

@node-dlc/messaging

Version:
221 lines (178 loc) 5.71 kB
import { BufferReader, BufferWriter } from '@node-dlc/bufio'; import { MessageType } from '../MessageType'; import { getTlv } from '../serialize/getTlv'; import { IDlcMessage } from './DlcMessage'; import { PayoutFunction, PayoutFunctionV0JSON } from './PayoutFunction'; import { IRoundingIntervalsV0JSON, RoundingIntervalsV0, } from './RoundingIntervalsV0'; export abstract class ContractDescriptor { public static deserialize( buf: Buffer, ): ContractDescriptorV0 | ContractDescriptorV1 { const reader = new BufferReader(buf); const type = Number(reader.readBigSize()); switch (type) { case MessageType.ContractDescriptorV0: return ContractDescriptorV0.deserialize(buf); case MessageType.ContractDescriptorV1: return ContractDescriptorV1.deserialize(buf); default: throw new Error( `Contract Descriptor TLV type must be ContractDescriptorV0 or ContractDescriptorV1`, ); } } public abstract type: number; public abstract length: bigint; public abstract toJSON(): ContractDescriptorV0JSON | ContractDescriptorV1JSON; public abstract serialize(): Buffer; } /** * ContractDescriptor V0 contains information about a contract's outcomes * and their corresponding payouts. */ export class ContractDescriptorV0 extends ContractDescriptor implements IDlcMessage { public static type = MessageType.ContractDescriptorV0; /** * Deserializes an contract_descriptor_v0 message * @param buf */ public static deserialize(buf: Buffer): ContractDescriptorV0 { const instance = new ContractDescriptorV0(); const reader = new BufferReader(buf); reader.readBigSize(); // read type instance.length = reader.readBigSize(); reader.readBigSize(); // num_outcomes while (!reader.eof) { instance.outcomes.push({ outcome: reader.readBytes(32), localPayout: reader.readUInt64BE(), }); } return instance; } /** * The type for contract_descriptor_v0 message. contract_descriptor_v0 = 42768 */ public type = ContractDescriptorV0.type; public length: bigint; public outcomes: IOutcome[] = []; /** * Converts contract_descriptor_v0 to JSON */ public toJSON(): ContractDescriptorV0JSON { return { type: this.type, outcomes: this.outcomes.map((outcome) => { return { outcome: outcome.outcome.toString('hex'), localPayout: Number(outcome.localPayout), }; }), }; } /** * Serializes the contract_descriptor_v0 message into a Buffer */ public serialize(): Buffer { const writer = new BufferWriter(); writer.writeBigSize(this.type); const dataWriter = new BufferWriter(); dataWriter.writeBigSize(this.outcomes.length); for (const outcome of this.outcomes) { dataWriter.writeBytes(outcome.outcome); dataWriter.writeUInt64BE(outcome.localPayout); } writer.writeBigSize(dataWriter.size); writer.writeBytes(dataWriter.toBuffer()); return writer.toBuffer(); } } /** * ContractDescriptor V1 contains information about a contract's outcomes * and their corresponding payouts. */ export class ContractDescriptorV1 extends ContractDescriptor implements IDlcMessage { public static type = MessageType.ContractDescriptorV1; /** * Deserializes an contract_descriptor_v1 message * @param buf */ public static deserialize(buf: Buffer): ContractDescriptorV1 { const instance = new ContractDescriptorV1(); const reader = new BufferReader(buf); reader.readBigSize(); // read type instance.length = reader.readBigSize(); instance.numDigits = reader.readUInt16BE(); // num_digits instance.payoutFunction = PayoutFunction.deserialize(getTlv(reader)); instance.roundingIntervals = RoundingIntervalsV0.deserialize( getTlv(reader), ); return instance; } /** * The type for contract_descriptor_v1 message. contract_descriptor_v1 = 42784 */ public type = ContractDescriptorV1.type; public length: bigint; public numDigits: number; public payoutFunction: PayoutFunction; public roundingIntervals: RoundingIntervalsV0; /** * Validates correctness of all fields in the message * https://github.com/discreetlogcontracts/dlcspecs/blob/master/Messaging.md#the-contract_descriptor-type * @throws Will throw an error if validation fails */ public validate(): void { this.roundingIntervals.validate(); } /** * Converts contract_descriptor_v1 to JSON */ public toJSON(): ContractDescriptorV1JSON { return { type: this.type, numDigits: this.numDigits, payoutFunction: this.payoutFunction.toJSON(), roundingIntervals: this.roundingIntervals.toJSON(), }; } /** * Serializes the contract_descriptor_v1 message into a Buffer */ public serialize(): Buffer { const writer = new BufferWriter(); writer.writeBigSize(this.type); const dataWriter = new BufferWriter(); dataWriter.writeUInt16BE(this.numDigits); dataWriter.writeBytes(this.payoutFunction.serialize()); dataWriter.writeBytes(this.roundingIntervals.serialize()); writer.writeBigSize(dataWriter.size); writer.writeBytes(dataWriter.toBuffer()); return writer.toBuffer(); } } interface IOutcome { outcome: Buffer; localPayout: bigint; } interface IOutcomeJSON { outcome: string; localPayout: number; } export interface ContractDescriptorV0JSON { type: number; outcomes: IOutcomeJSON[]; } export interface ContractDescriptorV1JSON { type: number; numDigits: number; payoutFunction: PayoutFunctionV0JSON; roundingIntervals: IRoundingIntervalsV0JSON; }