UNPKG

@layr-labs/hourglass-performer

Version:

TypeScript SDK for building Hourglass AVS performers

260 lines 9.65 kB
"use strict"; // SolidityWorker base class for TypeChain integration and ABI handling 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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.SolidityWorkerUtils = exports.JsonSolidityWorker = exports.SolidityWorker = void 0; const iWorker_1 = require("./iWorker"); const abiUtils_1 = require("../utils/abiUtils"); /** * SolidityWorker base class with TypeChain integration * * Generic parameters: * - TContract: TypeChain-generated contract interface * - TFunction: Function name from the contract */ class SolidityWorker extends iWorker_1.BaseWorker { constructor(config) { super(); // Use default config if none provided (for simple usage) this.config = { autoDetectPayload: true, strictMode: false, abi: [], functionName: 'handleTask', ...config, }; if (this.config.abi.length > 0) { this.abiCodec = new abiUtils_1.AbiCodec(this.config.abi); } } /** * Validate task with ABI decoding */ async validateTask(task) { await super.validateTask(task); // Validate ABI decoding try { this.decodeTaskPayload(task.payload); } catch (error) { if (this.config.strictMode) { throw new Error(`ABI validation failed: ${error instanceof Error ? error.message : 'Unknown error'}`); } // In non-strict mode, just warn console.warn(`ABI validation warning: ${error instanceof Error ? error.message : 'Unknown error'}`); } } /** * Handle task with automatic ABI decoding/encoding */ async handleTask(task) { try { // Decode payload using ABI (if available) const decodedParams = this.abiCodec ? this.decodeTaskPayload(task.payload) : this.parsePayload(task.payload); // Call user-implemented handler with decoded parameters const result = await this.handleSolidityTask(decodedParams); // Encode result using ABI (if available) const encodedResult = this.abiCodec ? this.encodeTaskResult(result) : this.encodePayload(result); return this.createResponse(task.taskId, encodedResult); } catch (error) { throw new Error(`Solidity task handling failed: ${error instanceof Error ? error.message : 'Unknown error'}`); } } /** * Simple start method for one-line usage */ async start(port = 8080) { const { PerformerServer } = await Promise.resolve().then(() => __importStar(require('../server/performerServer'))); const server = new PerformerServer(this, { port, timeout: 10000, debug: true, }); // Set up graceful shutdown server.setupGracefulShutdown(); try { await server.start(); console.log(`🚀 Performer is running on port ${port}!`); } catch (error) { console.error('❌ Failed to start server:', error); process.exit(1); } } /** * Decode task payload using ABI */ decodeTaskPayload(payload) { if (this.config.autoDetectPayload) { const detection = abiUtils_1.PayloadAutoDecoder.decode(payload); if (detection.format === 'abi' && this.abiCodec) { return this.abiCodec.decodeFunctionCall(this.config.functionName, payload); } else if (detection.format === 'json') { // For JSON payloads, try to map to function parameters return this.mapJsonToAbiParams(detection.data); } else { // For other formats, pass through as raw data return { data: payload }; } } else { // Direct ABI decoding return this.abiCodec ? this.abiCodec.decodeFunctionCall(this.config.functionName, payload) : { data: payload }; } } /** * Encode task result using ABI */ encodeTaskResult(result) { return this.abiCodec ? this.abiCodec.encodeFunctionResult(this.config.functionName, result) : this.encodePayload(result); } /** * Map JSON data to ABI function parameters */ mapJsonToAbiParams(jsonData) { if (!this.abiCodec) { return jsonData; } const funcInfo = this.abiCodec.getFunctionInfo(this.config.functionName); if (!funcInfo) { throw new Error(`Function ${this.config.functionName} not found in ABI`); } const mapped = {}; for (const param of funcInfo.inputs) { const paramName = param.name || `param${funcInfo.inputs.indexOf(param)}`; if (jsonData.hasOwnProperty(paramName)) { mapped[paramName] = jsonData[paramName]; } } return mapped; } /** * Get function information from ABI */ getFunctionInfo() { return this.abiCodec ? this.abiCodec.getFunctionInfo(this.config.functionName) : undefined; } /** * Get all available functions from ABI */ getAllFunctions() { return this.abiCodec ? this.abiCodec.getAllFunctions() : []; } /** * Manually decode payload (for advanced use cases) */ manualDecode(payload) { return this.abiCodec ? this.abiCodec.decodeFunctionCall(this.config.functionName, payload) : { data: payload }; } /** * Manually encode result (for advanced use cases) */ manualEncode(result) { return this.abiCodec ? this.abiCodec.encodeFunctionResult(this.config.functionName, result) : this.encodePayload(result); } } exports.SolidityWorker = SolidityWorker; /** * Simplified SolidityWorker for JSON-based configuration */ class JsonSolidityWorker extends iWorker_1.BaseWorker { constructor(abi, functionName) { super(); this.abiCodec = new abiUtils_1.AbiCodec(abi); this.functionName = functionName; } async handleTask(task) { try { // Auto-detect and decode payload const detection = abiUtils_1.PayloadAutoDecoder.decode(task.payload); let decodedParams; if (detection.format === 'abi') { decodedParams = this.abiCodec.decodeFunctionCall(this.functionName, task.payload); } else if (detection.format === 'json') { decodedParams = detection.data; } else { decodedParams = { data: task.payload }; } // Call user handler const result = await this.handleDecodedTask(decodedParams); // Encode result let encodedResult; if (typeof result === 'object' && result !== null) { encodedResult = this.abiCodec.encodeFunctionResult(this.functionName, result); } else { encodedResult = this.abiCodec.encodeFunctionResult(this.functionName, { result }); } return this.createResponse(task.taskId, encodedResult); } catch (error) { throw new Error(`JSON Solidity task handling failed: ${error instanceof Error ? error.message : 'Unknown error'}`); } } } exports.JsonSolidityWorker = JsonSolidityWorker; /** * Utility functions for SolidityWorker */ class SolidityWorkerUtils { /** * Create a simple worker from ABI and handler function */ static createFromAbi(abi, functionName, handler) { return new (class extends JsonSolidityWorker { async handleDecodedTask(params) { return handler(params); } })(abi, functionName); } /** * Create a worker with automatic TypeChain integration */ static createTyped(config, handler) { return new (class extends SolidityWorker { async handleSolidityTask(params) { return handler(params); } })(config); } } exports.SolidityWorkerUtils = SolidityWorkerUtils; // Decorator removed - use SolidityWorker class directly for better type safety //# sourceMappingURL=solidityWorker.js.map