UNPKG

@hirosystems/chainhook-client

Version:
156 lines 7.84 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __exportStar = (this && this.__exportStar) || function(m, exports) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ChainhookEventObserver = exports.EventObserverPredicateSchema = void 0; const server_1 = require("./server"); const predicates_1 = require("./predicates"); const type_provider_typebox_1 = require("@fastify/type-provider-typebox"); const if_this_1 = require("./schemas/bitcoin/if_this"); const if_this_2 = require("./schemas/stacks/if_this"); const logger_1 = require("./util/logger"); const predicate_1 = require("./schemas/predicate"); const EventObserverOptionsSchema = type_provider_typebox_1.Type.Object({ /** Event observer host name (usually '0.0.0.0') */ hostname: type_provider_typebox_1.Type.String(), /** Event observer port */ port: type_provider_typebox_1.Type.Integer(), /** Authorization token for all Chainhook payloads */ auth_token: type_provider_typebox_1.Type.String(), /** Base URL that will be used by Chainhook to send all payloads to this event observer */ external_base_url: type_provider_typebox_1.Type.String(), /** Wait for the chainhook node to be available before submitting predicates */ wait_for_chainhook_node: type_provider_typebox_1.Type.Optional(type_provider_typebox_1.Type.Boolean({ default: true })), /** Validate the JSON schema of received chainhook payloads and report errors when invalid */ validate_chainhook_payloads: type_provider_typebox_1.Type.Optional(type_provider_typebox_1.Type.Boolean({ default: false })), /** Validate the authorization token sent by the server is correct. */ validate_token_authorization: type_provider_typebox_1.Type.Optional(type_provider_typebox_1.Type.Boolean({ default: true })), /** Size limit for received chainhook payloads (default 40MB) */ body_limit: type_provider_typebox_1.Type.Optional(type_provider_typebox_1.Type.Number({ default: 41943040 })), /** Node type: `chainhook` or `ordhook` */ node_type: type_provider_typebox_1.Type.Optional(type_provider_typebox_1.Type.Union([type_provider_typebox_1.Type.Literal('chainhook'), type_provider_typebox_1.Type.Literal('ordhook')], { default: 'chainhook', })), /** * Directory where registered predicates will be persisted to disk so they can be recalled on * restarts. */ predicate_disk_file_path: type_provider_typebox_1.Type.String(), /** * How often we should check with the Chainhook server to make sure our predicates are active and * up to date. If they become obsolete, we will attempt to re-register them. */ predicate_health_check_interval_ms: type_provider_typebox_1.Type.Optional(type_provider_typebox_1.Type.Integer({ default: 5000 })), predicate_re_register_callback: type_provider_typebox_1.Type.Optional(type_provider_typebox_1.Type.Function([predicate_1.PredicateSchema], type_provider_typebox_1.Type.Promise(predicate_1.PredicateSchema))), }); const ChainhookNodeOptionsSchema = type_provider_typebox_1.Type.Object({ /** Base URL where the Chainhook node is located */ base_url: type_provider_typebox_1.Type.String(), }); const IfThisThenNothingSchema = type_provider_typebox_1.Type.Union([ type_provider_typebox_1.Type.Composite([ if_this_1.BitcoinIfThisOptionsSchema, type_provider_typebox_1.Type.Object({ if_this: if_this_1.BitcoinIfThisSchema, }), ]), type_provider_typebox_1.Type.Composite([ if_this_2.StacksIfThisOptionsSchema, type_provider_typebox_1.Type.Object({ if_this: if_this_2.StacksIfThisSchema, }), ]), ]); exports.EventObserverPredicateSchema = type_provider_typebox_1.Type.Composite([ type_provider_typebox_1.Type.Object({ name: type_provider_typebox_1.Type.String(), version: type_provider_typebox_1.Type.Integer(), chain: type_provider_typebox_1.Type.String(), }), type_provider_typebox_1.Type.Object({ networks: type_provider_typebox_1.Type.Object({ mainnet: type_provider_typebox_1.Type.Optional(IfThisThenNothingSchema), testnet: type_provider_typebox_1.Type.Optional(IfThisThenNothingSchema), }), }), ]); /** * Local web server that registers predicates and receives events from a Chainhook node. It handles * retry logic and node availability transparently and provides a callback for individual event * processing. * * Predicates registered here do not accept a `then_that` entry as this will be configured * automatically to redirect events to this server. * * Events relayed by this component will include the original predicate's UUID so actions can be * taken for each relevant predicate. */ class ChainhookEventObserver { constructor(observer, chainhook) { this.observer = observer; this.chainhook = chainhook; } /** * Starts the Chainhook event observer. * @param predicates - Predicates to register. If `predicates_disk_file_path` is enabled in the * observer, predicates stored on disk will take precedent over those specified here. * @param callback - Function to handle every Chainhook event payload sent by the node */ async start(predicates, callback) { if (this.fastify) return; this.fastify = await (0, server_1.buildServer)(this.observer, this.chainhook, predicates, callback); await this.fastify.listen({ host: this.observer.hostname, port: this.observer.port }); if (this.observer.predicate_health_check_interval_ms && this.healthCheckTimer === undefined) { this.scheduleHealthCheck(); } } scheduleHealthCheck() { this.healthCheckTimer = setTimeout(() => { void (0, predicates_1.predicateHealthCheck)(this.observer, this.chainhook) .catch(err => { logger_1.logger.error(err, `ChainhookEventObserver predicate health check error`); }) .finally(() => { if (this.healthCheckTimer) { this.scheduleHealthCheck(); } }); }, this.observer.predicate_health_check_interval_ms); } /** * Stop the Chainhook event server gracefully. */ async close() { if (this.healthCheckTimer) clearInterval(this.healthCheckTimer); this.healthCheckTimer = undefined; await this.fastify?.close(); this.fastify = undefined; } } exports.ChainhookEventObserver = ChainhookEventObserver; __exportStar(require("./schemas/bitcoin/if_this"), exports); __exportStar(require("./schemas/bitcoin/payload"), exports); __exportStar(require("./schemas/common"), exports); __exportStar(require("./schemas/payload"), exports); __exportStar(require("./schemas/predicate"), exports); __exportStar(require("./schemas/stacks/if_this"), exports); __exportStar(require("./schemas/stacks/payload"), exports); __exportStar(require("./schemas/stacks/signers"), exports); __exportStar(require("./schemas/stacks/tx_events"), exports); __exportStar(require("./schemas/stacks/tx_kind"), exports); __exportStar(require("./server"), exports); //# sourceMappingURL=index.js.map