UNPKG

zkverifyjs

Version:

Submit proofs to zkVerify and query proof state with ease using our npm package.

135 lines (134 loc) 6.07 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EventManager = void 0; const aggregation_1 = require("../../../api/aggregation"); const events_1 = require("events"); const enums_1 = require("../../../enums"); class EventManager { constructor(connectionManager) { this.connectionManager = connectionManager; this.emitter = new events_1.EventEmitter(); } /** * Subscribes to specified ZkVerifyEvents. * For `NewAggregationReceipt`, `options` can include `domainId` and `aggregationId`. * For runtime events (e.g., ProofVerified), options are ignored. * * @param subscriptions - List of events to subscribe to with optional callback and filtering options. * @returns EventEmitter to allow listening to additional internal events (e.g., `Unsubscribe`). */ subscribe(subscriptions) { const { api } = this.connectionManager; const eventsToSubscribe = subscriptions?.length ? subscriptions : enums_1.PUBLIC_ZK_VERIFY_EVENTS.map((event) => ({ event, callback: undefined, options: event === enums_1.ZkVerifyEvents.NewAggregationReceipt ? undefined : undefined, })); eventsToSubscribe.forEach(({ event, callback, options }) => { switch (event) { case enums_1.ZkVerifyEvents.NewAggregationReceipt: (0, aggregation_1.subscribeToNewAggregationReceipts)(api, (data) => { this.emitter.emit(event, data); if (callback) callback(data); }, options, this.emitter); break; case enums_1.ZkVerifyEvents.ProofVerified: case enums_1.ZkVerifyEvents.NewProof: case enums_1.ZkVerifyEvents.VkRegistered: case enums_1.ZkVerifyEvents.NewDomain: case enums_1.ZkVerifyEvents.DomainStateChanged: case enums_1.ZkVerifyEvents.AggregationComplete: this._subscribeToRuntimeEvent(api, event, callback); break; default: throw new Error(`Unsupported event type for subscription: ${event}`); } }); return this.emitter; } /** * Subscribes to on-chain runtime events using api.query.system.events */ _subscribeToRuntimeEvent(api, eventType, callback) { api.query.system .events((records) => { for (const { event, phase } of records) { const key = `${event.section}::${event.method}`; const matchMap = { [enums_1.ZkVerifyEvents.ProofVerified]: /::ProofVerified/, [enums_1.ZkVerifyEvents.CannotAggregate]: 'aggregate::CannotAggregate', [enums_1.ZkVerifyEvents.NewProof]: 'aggregate::NewProof', [enums_1.ZkVerifyEvents.VkRegistered]: /::VkRegistered/, [enums_1.ZkVerifyEvents.AggregationComplete]: 'aggregate::AggregationComplete', [enums_1.ZkVerifyEvents.NewDomain]: 'aggregate::NewDomain', [enums_1.ZkVerifyEvents.DomainStateChanged]: 'aggregate::DomainStateChanged', }; const expected = matchMap[eventType]; if (expected && ((typeof expected === 'string' && key === expected) || (expected instanceof RegExp && expected.test(key)))) { const parsedPhase = phase.toJSON ? phase.toJSON() : phase.toString(); const eventPayload = { event: eventType, data: event.data.toHuman?.() ?? event.data.toString(), phase: parsedPhase, }; this.emitter.emit(eventType, eventPayload); if (callback) { callback(eventPayload); } } } }) .catch((error) => { this.emitter.emit(enums_1.ZkVerifyEvents.ErrorEvent, error); }); } /** * Waits for a specific `NewAggregationReceipt` event and returns the result as a NewAggregationReceipt object. * * @param domainId - The domain ID to listen for. * @param aggregationId - The aggregation ID to listen for. * @param timeout - Optional timeout value in milliseconds. * @returns {Promise<NewAggregationReceipt>} Resolves with the event data when found, or rejects on timeout/error. */ async waitForAggregationReceipt(domainId, aggregationId, timeout) { const { api } = this.connectionManager; const options = { domainId, aggregationId, timeout }; return new Promise((resolve, reject) => { (0, aggregation_1.subscribeToNewAggregationReceipts)(api, (eventObject) => { const event = eventObject; if (event && event.data && event.data.domainId && event.data.aggregationId && event.data.receipt) { const result = { blockHash: event.blockHash ?? null, domainId: Number(event.data.domainId), aggregationId: Number(event.data.aggregationId), receipt: String(event.data.receipt), }; resolve(result); } else { reject(new Error('Invalid event data structure')); } }, options, this.emitter).catch(reject); }); } /** * Unsubscribes from all active subscriptions. */ unsubscribe() { (0, aggregation_1.unsubscribe)(this.emitter); } } exports.EventManager = EventManager;