@node-dlc/messaging
Version:
DLC Messaging Protocol
332 lines • 14 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.HyperbolaPayoutCurvePiece = exports.PolynomialPayoutCurvePiece = exports.PayoutCurvePiece = void 0;
const bufio_1 = require("@node-dlc/bufio");
const MessageType_1 = require("../MessageType");
const F64_1 = require("../serialize/F64");
const util_1 = require("../util");
class PayoutCurvePiece {
static deserialize(buf) {
const reader = new bufio_1.BufferReader(buf);
const typeId = Number(reader.readBigSize());
switch (typeId) {
case MessageType_1.PayoutCurvePieceType.Polynomial:
return PolynomialPayoutCurvePiece.deserialize(buf);
case MessageType_1.PayoutCurvePieceType.Hyperbola:
return HyperbolaPayoutCurvePiece.deserialize(buf);
default:
throw new Error(`Payout curve piece type must be Polynomial (0) or Hyperbola (1), got ${typeId}`);
}
}
/**
* Creates a PayoutCurvePiece from JSON data
* @param json JSON object representing a payout curve piece
*/
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
static fromJSON(json) {
if (!json) {
throw new Error('payoutCurvePiece is required');
}
// Handle test vector format with nested types
if (json.polynomialPayoutCurvePiece) {
return PolynomialPayoutCurvePiece.fromJSON(json.polynomialPayoutCurvePiece);
}
else if (json.hyperbolaPayoutCurvePiece) {
return HyperbolaPayoutCurvePiece.fromJSON(json.hyperbolaPayoutCurvePiece);
}
// Handle direct format
else if (json.points !== undefined || json.payoutPoints !== undefined) {
return PolynomialPayoutCurvePiece.fromJSON(json);
}
else if (json.usePositivePiece !== undefined) {
return HyperbolaPayoutCurvePiece.fromJSON(json);
}
else {
throw new Error('payoutCurvePiece must be either polynomial (with points) or hyperbola (with usePositivePiece)');
}
}
}
exports.PayoutCurvePiece = PayoutCurvePiece;
/**
* PolynomialPayoutCurvePiece defines a polynomial curve piece for payout functions.
* This corresponds to type 0 in the sibling sub-type format.
*/
class PolynomialPayoutCurvePiece extends PayoutCurvePiece {
constructor() {
super(...arguments);
/**
* The type for polynomial_payout_curve_piece message - Note: this is a sub-component, not a standalone wire message
*/
this.type = MessageType_1.MessageType.PolynomialPayoutCurvePiece;
/**
* The payout curve piece type for new format
*/
this.payoutCurvePieceType = MessageType_1.PayoutCurvePieceType.Polynomial;
this.points = [];
}
/**
* Creates a PolynomialPayoutCurvePiece from JSON data
* @param json JSON object representing a polynomial payout curve piece
*/
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
static fromJSON(json) {
const instance = new PolynomialPayoutCurvePiece();
const points = json.payoutPoints || json.points || [];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
instance.points = points.map((point) => ({
eventOutcome: (0, util_1.toBigInt)(point.eventOutcome || point.event_outcome),
outcomePayout: (0, util_1.toBigInt)(point.outcomePayout || point.outcome_payout),
extraPrecision: point.extraPrecision || point.extra_precision || 0,
}));
return instance;
}
/**
* Deserializes a polynomial_payout_curve_piece message
* @param buf
*/
static deserialize(buf) {
const instance = new PolynomialPayoutCurvePiece();
const reader = new bufio_1.BufferReader(buf);
reader.readBigSize(); // read type (0)
const numPts = Number(reader.readBigSize());
for (let i = 0; i < numPts; i++) {
const eventOutcome = reader.readUInt64BE();
const outcomePayout = reader.readUInt64BE();
const extraPrecision = reader.readUInt16BE();
instance.points.push({
eventOutcome,
outcomePayout,
extraPrecision,
});
}
return instance;
}
/**
* Converts polynomial_payout_curve_piece to JSON
*/
toJSON() {
return {
polynomialPayoutCurvePiece: {
payoutPoints: this.points.map((point) => {
return {
eventOutcome: (0, util_1.bigIntToNumber)(point.eventOutcome),
outcomePayout: (0, util_1.bigIntToNumber)(point.outcomePayout),
extraPrecision: Number(point.extraPrecision),
};
}),
},
};
}
/**
* Serializes the polynomial_payout_curve_piece message into a Buffer
*/
serialize() {
const writer = new bufio_1.BufferWriter();
writer.writeBigSize(this.payoutCurvePieceType);
writer.writeBigSize(this.points.length);
for (const point of this.points) {
writer.writeUInt64BE(point.eventOutcome);
writer.writeUInt64BE(point.outcomePayout);
writer.writeUInt16BE(point.extraPrecision);
}
return writer.toBuffer();
}
}
exports.PolynomialPayoutCurvePiece = PolynomialPayoutCurvePiece;
PolynomialPayoutCurvePiece.payoutCurvePieceType = MessageType_1.PayoutCurvePieceType.Polynomial;
/**
* HyperbolaPayoutCurvePiece defines a hyperbola curve piece for payout functions.
* This corresponds to type 1 in the sibling sub-type format.
* Updated to use F64 for precise f64 parameter handling.
*/
class HyperbolaPayoutCurvePiece extends PayoutCurvePiece {
/**
* Helper function to safely parse F64 values from JSON
* Handles both number and string inputs for maximum precision
*/
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
static parseF64Value(value) {
// Check for basic null/undefined
if (value === null || value === undefined) {
return null;
}
try {
if (typeof value === 'string') {
// Parse string directly to preserve precision
try {
return F64_1.F64.fromString(value);
}
catch (error) {
// If fromString fails, try parsing as number
const numValue = parseFloat(value);
if (!isNaN(numValue) && isFinite(numValue)) {
return F64_1.F64.fromNumber(numValue);
}
}
}
else if (typeof value === 'number') {
// Parse number - handle special cases
if (!isFinite(value)) {
return null; // Reject NaN, Infinity, -Infinity
}
return F64_1.F64.fromNumber(value);
}
// Try to convert other types to number as fallback
const numValue = Number(value);
if (!isNaN(numValue) && isFinite(numValue)) {
return F64_1.F64.fromNumber(numValue);
}
return null;
}
catch (error) {
return null;
}
}
/**
* Creates a HyperbolaPayoutCurvePiece from JSON data
* @param json JSON object representing a hyperbola payout curve piece
*/
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
static fromJSON(json) {
if (!json || typeof json !== 'object')
return null;
// Handle both wrapped format and direct format
let data = json.hyperbolaPayoutCurvePiece || json.hyperbola_payout_curve_piece;
// If no wrapper found, assume direct format if it has the expected properties
if (!data &&
(json.usePositivePiece !== undefined ||
json.use_positive_piece !== undefined)) {
data = json;
}
if (!data)
return null;
try {
const usePositivePiece = data.usePositivePiece || data.use_positive_piece || false;
// Parse each F64 value with null check
const translateOutcome = this.parseF64Value(data.translateOutcome !== undefined
? data.translateOutcome
: data.translate_outcome);
const translatePayout = this.parseF64Value(data.translatePayout !== undefined
? data.translatePayout
: data.translate_payout);
const a = this.parseF64Value(data.a);
const b = this.parseF64Value(data.b);
const c = this.parseF64Value(data.c);
const d = this.parseF64Value(data.d);
// Check that all required values were parsed successfully
if (!translateOutcome || !translatePayout || !a || !b || !c || !d) {
throw new Error('Failed to parse one or more F64 values');
}
return new HyperbolaPayoutCurvePiece(usePositivePiece, translateOutcome, translatePayout, a, b, c, d);
}
catch (error) {
return null;
}
}
/**
* Deserializes a hyperbola_payout_curve_piece message
* @param buf
*/
static deserialize(buf) {
const instance = new HyperbolaPayoutCurvePiece();
const reader = new bufio_1.BufferReader(buf);
reader.readBigSize(); // read type (1)
instance.usePositivePiece = reader.readUInt8() === 1;
// Read f64 values using F64 for precise handling - read raw 8-byte buffers
instance.translateOutcome = F64_1.F64.deserialize(reader.readBytes(8));
instance.translatePayout = F64_1.F64.deserialize(reader.readBytes(8));
instance.a = F64_1.F64.deserialize(reader.readBytes(8));
instance.b = F64_1.F64.deserialize(reader.readBytes(8));
instance.c = F64_1.F64.deserialize(reader.readBytes(8));
instance.d = F64_1.F64.deserialize(reader.readBytes(8));
// Note: leftEndPoint and rightEndPoint are not part of the serialization
// They will be set by PayoutFunction when creating from JSON
instance.leftEndPoint = {
eventOutcome: BigInt(0),
outcomePayout: BigInt(0),
extraPrecision: 0,
};
instance.rightEndPoint = {
eventOutcome: BigInt(0),
outcomePayout: BigInt(0),
extraPrecision: 0,
};
return instance;
}
constructor(usePositivePiece = false, translateOutcome, translatePayout, a, b, c, d) {
super();
/**
* The type for hyperbola_payout_curve_piece message - Note: this is a sub-component, not a standalone wire message
*/
this.type = MessageType_1.MessageType.HyperbolaPayoutCurvePiece;
this.payoutCurvePieceType = HyperbolaPayoutCurvePiece.payoutCurvePieceType;
this.usePositivePiece = usePositivePiece;
// Convert string inputs to F64 objects, or use existing F64 objects
this.translateOutcome = translateOutcome
? typeof translateOutcome === 'string'
? F64_1.F64.fromString(translateOutcome)
: translateOutcome
: F64_1.F64.fromNumber(0);
this.translatePayout = translatePayout
? typeof translatePayout === 'string'
? F64_1.F64.fromString(translatePayout)
: translatePayout
: F64_1.F64.fromNumber(0);
this.a = a
? typeof a === 'string'
? F64_1.F64.fromString(a)
: a
: F64_1.F64.fromNumber(0);
this.b = b
? typeof b === 'string'
? F64_1.F64.fromString(b)
: b
: F64_1.F64.fromNumber(0);
this.c = c
? typeof c === 'string'
? F64_1.F64.fromString(c)
: c
: F64_1.F64.fromNumber(0);
this.d = d
? typeof d === 'string'
? F64_1.F64.fromString(d)
: d
: F64_1.F64.fromNumber(0);
}
/**
* Converts hyperbola_payout_curve_piece to JSON
* Uses F64.toJSONValue() which preserves precision by using strings for very large numbers
*/
toJSON() {
return {
hyperbolaPayoutCurvePiece: {
usePositivePiece: this.usePositivePiece,
translateOutcome: this.translateOutcome.toJSONValue(),
translatePayout: this.translatePayout.toJSONValue(),
a: this.a.toJSONValue(),
b: this.b.toJSONValue(),
c: this.c.toJSONValue(),
d: this.d.toJSONValue(),
},
};
}
/**
* Serializes the hyperbola_payout_curve_piece message into a Buffer
*/
serialize() {
const writer = new bufio_1.BufferWriter();
writer.writeBigSize(this.payoutCurvePieceType);
writer.writeUInt8(this.usePositivePiece ? 1 : 0);
// Write f64 values using F64 for precise handling - write raw 8-byte buffers
writer.writeBytes(this.translateOutcome.serialize());
writer.writeBytes(this.translatePayout.serialize());
writer.writeBytes(this.a.serialize());
writer.writeBytes(this.b.serialize());
writer.writeBytes(this.c.serialize());
writer.writeBytes(this.d.serialize());
return writer.toBuffer();
}
}
exports.HyperbolaPayoutCurvePiece = HyperbolaPayoutCurvePiece;
HyperbolaPayoutCurvePiece.payoutCurvePieceType = MessageType_1.PayoutCurvePieceType.Hyperbola;
//# sourceMappingURL=PayoutCurvePiece.js.map