@node-dlc/core
Version:
101 lines • 5.73 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getOptionInfoFromOffer = exports.getOptionInfoFromContractInfo = void 0;
const messaging_1 = require("@node-dlc/messaging");
const bignumber_js_1 = __importDefault(require("bignumber.js"));
const HyperbolaPayoutCurve_1 = require("../HyperbolaPayoutCurve");
const CoveredCall_1 = require("./CoveredCall");
const ShortPut_1 = require("./ShortPut");
function getOptionInfoFromContractInfo(_contractInfo) {
if (_contractInfo.type !== messaging_1.MessageType.SingleContractInfo)
throw Error('Only SingleContractInfo currently supported');
const contractInfo = _contractInfo;
if (contractInfo.contractDescriptor.contractDescriptorType !==
messaging_1.ContractDescriptorType.NumericOutcome)
throw Error('Numeric Descriptor currently supported');
const oracleInfo = contractInfo.oracleInfo;
// Handle both SingleOracleInfo and MultiOracleInfo using proper type discrimination
let eventMaturityEpoch;
let eventDescriptor;
switch (oracleInfo.type) {
case messaging_1.MessageType.SingleOracleInfo: {
const singleOracleInfo = oracleInfo;
eventMaturityEpoch =
singleOracleInfo.announcement.oracleEvent.eventMaturityEpoch;
eventDescriptor = singleOracleInfo.announcement.oracleEvent
.eventDescriptor;
if (singleOracleInfo.announcement.oracleEvent.eventDescriptor.type !==
messaging_1.MessageType.DigitDecompositionEventDescriptorV0) {
throw Error('Only DigitDecompositionEventDescriptorV0 currently supported');
}
break;
}
case messaging_1.MessageType.MultiOracleInfo: {
const multiOracleInfo = oracleInfo;
eventMaturityEpoch =
multiOracleInfo.announcements[0].oracleEvent.eventMaturityEpoch;
eventDescriptor = multiOracleInfo.announcements[0].oracleEvent
.eventDescriptor;
if (multiOracleInfo.announcements[0].oracleEvent.eventDescriptor.type !==
messaging_1.MessageType.DigitDecompositionEventDescriptorV0) {
throw Error('Only DigitDecompositionEventDescriptorV0 currently supported');
}
break;
}
default:
throw Error(`Unknown oracle info type: ${oracleInfo.type}`);
}
const { base: oracleBase, nbDigits: oracleDigits } = eventDescriptor;
const contractDescriptor = contractInfo.contractDescriptor;
if (contractDescriptor.payoutFunction.type !== messaging_1.MessageType.PayoutFunction)
throw Error('Only PayoutFunction currently supported');
const payoutFunction = contractDescriptor.payoutFunction;
if (payoutFunction.payoutFunctionPieces.length === 0)
throw Error('PayoutFunction must have at least once PayoutFunctionPiece');
if (payoutFunction.payoutFunctionPieces.length > 1)
throw Error('More than one PayoutFunctionPiece not supported');
const payoutCurvePiece = payoutFunction.payoutFunctionPieces[0]
.payoutCurvePiece;
if (payoutCurvePiece.payoutCurvePieceType !== messaging_1.PayoutCurvePieceType.Hyperbola)
throw Error('Must be HyperbolaPayoutCurvePiece');
if (!payoutCurvePiece.b.isZero() || !payoutCurvePiece.c.isZero())
throw Error('b and c HyperbolaPayoutCurvePiece values must be 0');
const curve = HyperbolaPayoutCurve_1.HyperbolaPayoutCurve.fromPayoutCurvePiece(payoutCurvePiece);
const maxOutcome = BigInt(new bignumber_js_1.default(oracleBase).pow(oracleDigits).minus(1).toString(10));
// For the new PayoutFunction structure, we need to get the initial payout from the first piece
const initialPayout = payoutFunction.payoutFunctionPieces[0].endPoint.outcomePayout;
const isAscending = curve.getPayout(maxOutcome).gt(Number(initialPayout));
const expiry = new Date(eventMaturityEpoch * 1000);
const totalCollateral = contractInfo.totalCollateral;
// if curve is ascending, assume it is a put.
const contractSize = isAscending
? BigInt(payoutCurvePiece.translatePayout.toDecimal().toString()) -
totalCollateral
: totalCollateral -
BigInt(payoutCurvePiece.translatePayout.toDecimal().toString());
const strikePrice = BigInt(payoutCurvePiece.d.toDecimal().toString()) / contractSize;
// rebuild payout curve from option info and perform a sanity check
const { payoutCurve: sanityCurve } = isAscending
? ShortPut_1.ShortPut.buildCurve(strikePrice, contractSize, totalCollateral, oracleBase, oracleDigits)
: CoveredCall_1.CoveredCall.buildCurve(strikePrice, contractSize, oracleBase, oracleDigits);
const type = isAscending ? 'put' : 'call';
if (!curve.equals(sanityCurve))
throw new Error('Payout curve built from extracted OptionInfo does not match original payout curve');
return { contractSize, strikePrice, expiry, type };
}
exports.getOptionInfoFromContractInfo = getOptionInfoFromContractInfo;
function getOptionInfoFromOffer(offer) {
if (offer.type !== messaging_1.MessageType.DlcOffer &&
offer.type !== messaging_1.MessageType.OrderOffer)
throw Error('Only DlcOffer and OrderOffer currently supported');
const premium = offer.contractInfo.totalCollateral - offer.offerCollateral;
return {
...getOptionInfoFromContractInfo(offer.contractInfo),
premium,
};
}
exports.getOptionInfoFromOffer = getOptionInfoFromOffer;
//# sourceMappingURL=OptionInfo.js.map