@node-dlc/messaging
Version:
DLC Messaging Protocol
214 lines • 9.87 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ContractInfoV1 = exports.ContractInfoV0 = exports.ContractInfo = void 0;
const bufio_1 = require("@node-dlc/bufio");
const MessageType_1 = require("../MessageType");
const getTlv_1 = require("../serialize/getTlv");
const ContractDescriptor_1 = require("./ContractDescriptor");
const DlcMessage_1 = require("./DlcMessage");
const OracleInfoV0_1 = require("./OracleInfoV0");
class ContractInfo extends DlcMessage_1.DlcMessage {
static deserialize(buf) {
const reader = new bufio_1.BufferReader(buf);
const type = Number(reader.readBigSize());
switch (type) {
case MessageType_1.MessageType.ContractInfoV0:
return ContractInfoV0.deserialize(buf);
case MessageType_1.MessageType.ContractInfoV1:
return ContractInfoV1.deserialize(buf);
default:
throw new Error(`Contract info TLV type must be ContractInfoV0 or ContractInfoV1`);
}
}
}
exports.ContractInfo = ContractInfo;
/**
* ContractInfo V0 contains information about a contract's outcomes,
* their corresponding payouts, and the oracles to be used.
*/
class ContractInfoV0 {
constructor() {
/**
* The type for contract_info_v0 message. contract_info_v0 = 55342
*/
this.type = ContractInfoV0.type;
}
/**
* Deserializes an contract_info_v0 message
* @param buf
*/
static deserialize(buf) {
const instance = new ContractInfoV0();
const reader = new bufio_1.BufferReader(buf);
reader.readBigSize(); // read type
instance.length = reader.readBigSize();
instance.totalCollateral = reader.readUInt64BE();
instance.contractDescriptor = ContractDescriptor_1.ContractDescriptor.deserialize((0, getTlv_1.getTlv)(reader));
instance.oracleInfo = OracleInfoV0_1.OracleInfoV0.deserialize((0, getTlv_1.getTlv)(reader));
return instance;
}
/**
* Validates correctness of all fields in the message
* https://github.com/discreetlogcontracts/dlcspecs/blob/master/Messaging.md#the-contract_info-type
* @throws Will throw an error if validation fails
*/
validate() {
this.oracleInfo.validate();
switch (this.contractDescriptor.type) {
case MessageType_1.MessageType.ContractDescriptorV1:
// eslint-disable-next-line no-case-declarations
const contractDescriptor = this
.contractDescriptor;
contractDescriptor.validate();
// roundingmod should not be greater than totalCollateral
for (const interval of contractDescriptor.roundingIntervals.intervals) {
if (interval.roundingMod > this.totalCollateral) {
throw new Error(`Rounding modulus ${interval.roundingMod} is greater than total collateral ${this.totalCollateral}`);
}
}
switch (this.oracleInfo.announcement.oracleEvent.eventDescriptor.type) {
case MessageType_1.MessageType.DigitDecompositionEventDescriptorV0:
// eslint-disable-next-line no-case-declarations
const eventDescriptor = this.oracleInfo.announcement.oracleEvent
.eventDescriptor;
if (eventDescriptor.nbDigits !== contractDescriptor.numDigits)
throw new Error('DigitDecompositionEventDescriptorV0 and ContractDescriptorV1 must have the same numDigits');
// Sanity check. Shouldn't be hit since there are other validations which should catch this in OracleEventV0.
// eslint-disable-next-line no-case-declarations
const oracleEvent = this.oracleInfo.announcement
.oracleEvent;
if (oracleEvent.oracleNonces.length !== contractDescriptor.numDigits) {
throw new Error('oracleEvent.oracleNonces.length and contractDescriptor.numDigits must be the same');
}
break;
default:
throw new Error('Only ContractDescriptorV1 can be used with DigitDecompositionEventDescriptor');
}
}
}
/**
* Converts contract_info_v0 to JSON
*/
toJSON() {
return {
type: this.type,
totalCollateral: Number(this.totalCollateral),
contractDescriptor: this.contractDescriptor.toJSON(),
oracleInfo: this.oracleInfo.toJSON(),
};
}
/**
* Serializes the contract_info_v0 message into a Buffer
*/
serialize() {
const writer = new bufio_1.BufferWriter();
writer.writeBigSize(this.type);
const dataWriter = new bufio_1.BufferWriter();
dataWriter.writeUInt64BE(this.totalCollateral);
dataWriter.writeBytes(this.contractDescriptor.serialize());
dataWriter.writeBytes(this.oracleInfo.serialize());
writer.writeBigSize(dataWriter.size);
writer.writeBytes(dataWriter.toBuffer());
return writer.toBuffer();
}
}
exports.ContractInfoV0 = ContractInfoV0;
ContractInfoV0.type = MessageType_1.MessageType.ContractInfoV0;
/**
* ContractInfo V1 contains information about a contract's outcomes,
* their corresponding payouts, and the oracles to be used.
*/
class ContractInfoV1 {
constructor() {
/**
* The type for contract_info_v1 message. contract_info_v0 = 55342
*/
this.type = ContractInfoV1.type;
this.contractOraclePairs = [];
}
/**
* Deserializes an contract_info_v0 message
* @param buf
*/
static deserialize(buf) {
const instance = new ContractInfoV1();
const reader = new bufio_1.BufferReader(buf);
reader.readBigSize(); // read type
instance.length = reader.readBigSize();
instance.totalCollateral = reader.readUInt64BE();
reader.readBigSize(); // read num_disjoint_events
while (!reader.eof) {
const contractDescriptor = ContractDescriptor_1.ContractDescriptor.deserialize((0, getTlv_1.getTlv)(reader));
const oracleInfo = OracleInfoV0_1.OracleInfoV0.deserialize((0, getTlv_1.getTlv)(reader));
instance.contractOraclePairs.push({ contractDescriptor, oracleInfo });
}
return instance;
}
/**
* Validates correctness of all fields in the message
* https://github.com/discreetlogcontracts/dlcspecs/blob/master/Messaging.md#the-contract_info-type
* @throws Will throw an error if validation fails
*/
validate() {
this.contractOraclePairs.forEach((oraclePair) => {
oraclePair.oracleInfo.validate();
switch (oraclePair.contractDescriptor.type) {
case MessageType_1.MessageType.ContractDescriptorV1:
// eslint-disable-next-line no-case-declarations
const contractDescriptor = oraclePair.contractDescriptor;
contractDescriptor.validate();
switch (oraclePair.oracleInfo.announcement.oracleEvent.eventDescriptor.type) {
case MessageType_1.MessageType.DigitDecompositionEventDescriptorV0:
// eslint-disable-next-line no-case-declarations
const eventDescriptor = oraclePair.oracleInfo.announcement
.oracleEvent
.eventDescriptor;
if (eventDescriptor.nbDigits !== contractDescriptor.numDigits)
throw new Error('DigitDecompositionEventDescriptorV0 and ContractDescriptorV1 must have the same numDigits');
// eslint-disable-next-line no-case-declarations
const oracleEvent = oraclePair.oracleInfo.announcement
.oracleEvent;
if (oracleEvent.oracleNonces.length !== contractDescriptor.numDigits) {
throw new Error('oracleEvent.oracleNonces.length and contractDescriptor.numDigits must be the same');
}
}
}
});
}
/**
* Converts contract_info_v1 to JSON
*/
toJSON() {
return {
type: this.type,
totalCollateral: Number(this.totalCollateral),
contractOraclePairs: this.contractOraclePairs.map((oraclePairs) => {
return {
contractDescriptor: oraclePairs.contractDescriptor.toJSON(),
oracleInfo: oraclePairs.oracleInfo.toJSON(),
};
}),
};
}
/**
* Serializes the contract_info_v1 message into a Buffer
*/
serialize() {
const writer = new bufio_1.BufferWriter();
writer.writeBigSize(this.type);
const dataWriter = new bufio_1.BufferWriter();
dataWriter.writeUInt64BE(this.totalCollateral);
dataWriter.writeBigSize(this.contractOraclePairs.length);
for (const contractOraclePair of this.contractOraclePairs) {
const { contractDescriptor, oracleInfo } = contractOraclePair;
dataWriter.writeBytes(contractDescriptor.serialize());
dataWriter.writeBytes(oracleInfo.serialize());
}
writer.writeBigSize(dataWriter.size);
writer.writeBytes(dataWriter.toBuffer());
return writer.toBuffer();
}
}
exports.ContractInfoV1 = ContractInfoV1;
ContractInfoV1.type = MessageType_1.MessageType.ContractInfoV1;
//# sourceMappingURL=ContractInfo.js.map