@node-dlc/messaging
Version:
DLC Messaging Protocol
131 lines • 5.44 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.OracleAnnouncement = void 0;
const bufio_1 = require("@node-dlc/bufio");
const bip_schnorr_1 = require("bip-schnorr");
const MessageType_1 = require("../MessageType");
const getTlv_1 = require("../serialize/getTlv");
const OracleEvent_1 = require("./OracleEvent");
/**
* Oracle announcement that describe an event and the way that an oracle will
* attest to it. Updated to be rust-dlc compliant.
*
* In order to make it possible to hold oracles accountable in cases where
* they do not release a signature for an event outcome, there needs to be
* a proof that an oracle has committed to a given outcome. This proof is
* given in a so-called oracle announcement, which contains an oracle event
* together with the oracle public key and a signature over its serialization,
* which must be valid with respect to the specified public key.
*
* This also makes it possible for users to obtain oracle event information
* from an un-trusted peer while being guaranteed that it originates from a
* given oracle.
*/
class OracleAnnouncement {
constructor() {
/**
* The type for oracle_announcement message. oracle_announcement = 55332
*/
this.type = OracleAnnouncement.type;
}
/**
* Creates an OracleAnnouncement from JSON data
* @param json JSON object representing oracle announcement
*/
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
static fromJSON(json) {
const instance = new OracleAnnouncement();
// Handle different field name variations
instance.announcementSig = Buffer.from(json.announcementSignature ||
json.announcementSig ||
json.announcement_signature, 'hex');
instance.oraclePublicKey = Buffer.from(json.oraclePublicKey || json.oraclePubkey || json.oracle_public_key, 'hex');
instance.oracleEvent = OracleEvent_1.OracleEvent.fromJSON(json.oracleEvent || json.oracle_event);
return instance;
}
/**
* Deserializes an oracle_announcement message
* @param buf
*/
static deserialize(buf) {
const instance = new OracleAnnouncement();
const reader = new bufio_1.BufferReader(buf);
reader.readBigSize(); // read type
instance.length = reader.readBigSize();
instance.announcementSig = reader.readBytes(64);
instance.oraclePublicKey = reader.readBytes(32);
instance.oracleEvent = OracleEvent_1.OracleEvent.deserialize((0, getTlv_1.getTlv)(reader));
return instance;
}
/**
* Validates the oracle announcement according to rust-dlc specification.
* This includes validating the oracle event and verifying the announcement signature.
* @throws Will throw an error if validation fails
*/
validate() {
// Validate oracle event first
this.oracleEvent.validate();
// Validate oracle public key format (32 bytes for x-only)
if (!this.oraclePublicKey || this.oraclePublicKey.length !== 32) {
throw new Error('Oracle public key must be 32 bytes (x-only format)');
}
// Validate announcement signature format (64 bytes for Schnorr)
if (!this.announcementSig || this.announcementSig.length !== 64) {
throw new Error('Announcement signature must be 64 bytes (Schnorr format)');
}
// Verify announcement signature over the oracle event
try {
const msg = bip_schnorr_1.math.taggedHash('DLC/oracle/announcement/v0', this.oracleEvent.serialize());
(0, bip_schnorr_1.verify)(this.oraclePublicKey, msg, this.announcementSig);
}
catch (error) {
throw new Error(`Invalid announcement signature: ${error.message}`);
}
}
/**
* Returns the nonces from the oracle event.
* This is useful for finding matching oracle announcements.
*/
getNonces() {
return this.oracleEvent.oracleNonces;
}
/**
* Returns the event maturity epoch from the oracle event.
*/
getEventMaturityEpoch() {
return this.oracleEvent.eventMaturityEpoch;
}
/**
* Returns the event ID from the oracle event.
*/
getEventId() {
return this.oracleEvent.eventId;
}
/**
* Converts oracle_announcement to JSON (canonical rust-dlc format)
*/
toJSON() {
return {
announcementSignature: this.announcementSig.toString('hex'),
oraclePublicKey: this.oraclePublicKey.toString('hex'),
oracleEvent: this.oracleEvent.toJSON(),
};
}
/**
* Serializes the oracle_announcement message into a Buffer
*/
serialize() {
const writer = new bufio_1.BufferWriter();
writer.writeBigSize(this.type);
const dataWriter = new bufio_1.BufferWriter();
dataWriter.writeBytes(this.announcementSig);
dataWriter.writeBytes(this.oraclePublicKey);
dataWriter.writeBytes(this.oracleEvent.serialize());
writer.writeBigSize(dataWriter.size);
writer.writeBytes(dataWriter.toBuffer());
return writer.toBuffer();
}
}
exports.OracleAnnouncement = OracleAnnouncement;
OracleAnnouncement.type = MessageType_1.MessageType.OracleAnnouncement;
//# sourceMappingURL=OracleAnnouncement.js.map