zkverifyjs
Version:
Submit proofs to zkVerify and query proof state with ease using our npm package.
124 lines (123 loc) • 5.86 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.subscribeToNewAggregationReceipts = subscribeToNewAggregationReceipts;
exports.unsubscribe = unsubscribe;
const enums_1 = require("../../enums");
/**
* Subscribes to `aggregation.NewAggregationReceipt` events and triggers the provided callback.
*
* - If both `domainId` and `aggregationId` are provided, the listener stops after the matching receipt is found.
* - If only `domainId` is provided, listens indefinitely for all receipts within that domain.
* - If neither is provided, listens to all receipts across all domains.
* - Throws if `aggregationId` is provided without a `domainId`.
*
* @param {ApiPromise} api - The Polkadot.js API instance.
* @param callback
* @param options - NewAggregationEventSubscriptionOptions containing domainId, aggregationId and optional timeout.
* @param emitter - EventEmitter
* @returns {EventEmitter} EventEmitter for listening to emitted events and unsubscribing.
*/
async function subscribeToNewAggregationReceipts(api, callback, options = undefined, emitter) {
return new Promise((resolve, reject) => {
const DEFAULT_MATCH_TIMEOUT = 180000;
let domainId = undefined;
let aggregationId = undefined;
let timeoutId;
if (options) {
domainId = options.domainId?.toString().trim();
if ('aggregationId' in options) {
aggregationId = options.aggregationId?.toString().trim();
if (!domainId) {
reject(new Error('Cannot filter by aggregationId without also providing domainId.'));
return;
}
}
}
if (aggregationId && domainId) {
const timeoutValue = options && 'timeout' in options && typeof options.timeout === 'number'
? options.timeout
: DEFAULT_MATCH_TIMEOUT;
timeoutId = setTimeout(() => {
unsubscribe(emitter);
reject(new Error(`Timeout exceeded: No event received within ${timeoutValue} ms`));
}, timeoutValue);
}
try {
api.rpc.chain.subscribeFinalizedHeads(async (header) => {
const blockHash = header.hash.toHex();
const apiAt = await api.at(blockHash);
const events = (await apiAt.query.system.events());
events.forEach((record) => {
const { event, phase } = record;
if (event.section === 'aggregate' &&
event.method === 'NewAggregationReceipt') {
let currentDomainId;
let currentAggregationId;
const eventData = event.data.toHuman
? event.data.toHuman()
: Array.from(event.data, (item) => item.toString());
const eventObject = {
event: enums_1.ZkVerifyEvents.NewAggregationReceipt,
blockHash,
data: eventData,
phase: phase && typeof phase.toJSON === 'function'
? phase.toJSON()
: phase?.toString() || '',
};
try {
currentDomainId = event.data[0]?.toString();
currentAggregationId = event.data[1]?.toString();
if (!currentDomainId || !currentAggregationId) {
reject(new Error('Event data is missing required fields: domainId or aggregationId.'));
return;
}
}
catch (error) {
emitter.emit(enums_1.ZkVerifyEvents.ErrorEvent, error);
reject(error);
return;
}
if (!options || (!aggregationId && !domainId)) {
emitter.emit(enums_1.ZkVerifyEvents.NewAggregationReceipt, eventObject);
callback(eventObject);
}
else if (domainId &&
!aggregationId &&
domainId === currentDomainId) {
emitter.emit(enums_1.ZkVerifyEvents.NewAggregationReceipt, eventObject);
callback(eventObject);
}
else if (domainId === currentDomainId &&
currentAggregationId === aggregationId) {
if (timeoutId)
clearTimeout(timeoutId);
emitter.emit(enums_1.ZkVerifyEvents.NewAggregationReceipt, eventObject);
callback(eventObject);
resolve(emitter);
return;
}
}
});
});
}
catch (error) {
if (timeoutId)
clearTimeout(timeoutId);
emitter.emit(enums_1.ZkVerifyEvents.ErrorEvent, error);
reject(error);
}
return emitter;
});
}
/**
* Unsubscribes from all event tracking.
*
* - Emits a `ZkVerifyEvents.Unsubscribe` event before removing all listeners.
* - Use this to manually stop listening when not auto-unsubscribing on matched receipts.
*
* @param {EventEmitter} emitter - The EventEmitter instance returned by the subscription.
*/
function unsubscribe(emitter) {
emitter.emit(enums_1.ZkVerifyEvents.Unsubscribe);
emitter.removeAllListeners();
}