UNPKG

openchain-sdk-yxl-ts

Version:

OpenChain SDK for browser

154 lines (131 loc) 4.56 kB
import JSONbig from 'json-bigint'; import { keypair } from 'openchain-encryption-nodejs-yxl-ts'; import errors from '../exception/index.js'; import CommonUtil from '../common/util.js'; import opOperations from './op.js'; import assetOperations from './asset.js'; import accountOperations from './account.js'; import logOperations from './log.js'; import contractOperations from './contract.js'; import ctp10TokenOperations from './ctp10Token.js'; class Operation extends CommonUtil { constructor(options = {}) { super(options); if (!(this instanceof Operation)) { return new Operation(options); } if (typeof options !== 'object' || options === null) { throw new Error('options is required'); } // 设置 options 到实例上,确保子模块可以访问 this.options = options; // 初始化所有操作模块 this.initializeOperations(); } // 初始化所有操作模块 initializeOperations() { const operations = [ { name: 'op', module: opOperations }, { name: 'asset', module: assetOperations }, { name: 'account', module: accountOperations }, { name: 'log', module: logOperations }, { name: 'contract', module: contractOperations }, { name: 'ctp10Token', module: ctp10TokenOperations } ]; operations.forEach(({ name, module }) => { this.initializeOperationModule(name, module); }); } // 初始化单个操作模块 /** * 初始化操作模块,将模块中的所有方法绑定到当前实例 * @param {string} name - 模块名称 * @param {Object} module - 要初始化的模块对象 * @description 遍历模块中的所有方法,将函数类型的方法绑定到当前实例上,并保持this上下文 */ initializeOperationModule(name, module) { // 将模块中的所有方法绑定到当前实例 Object.entries(module).forEach(([methodName, method]) => { if (typeof method === 'function') { // 绑定方法到当前实例,并保持 this 上下文 // 直接使用方法,不进行额外的绑定 this[methodName] = (...args) => { // 确保方法在正确的上下文中执行 try { return method.apply(this, args); } catch (err) { console.error(`Error in ${name} module, method ${methodName}:`, err); throw err; } }; } }); } // 验证操作参数 validateOperation(operation) { if (!operation || typeof operation !== 'object' || operation === null) { return { valid: false, error: this._responseError(errors.INVALID_ARGUMENTS) }; } if (!operation.type || !operation.data) { return { valid: false, error: this._responseError(errors.INVALID_ARGUMENTS) }; } return { valid: true }; } // 构建操作 async buildOperation(type, data) { try { const operation = { type, data }; const validation = this.validateOperation(operation); if (!validation.valid) { return validation.error; } return await this._buildOperation(type, data); } catch (err) { console.error('Error in buildOperation:', err); return this._responseError(errors.INVALID_OPERATIONS); } } // 评估操作费用 async evaluateOperationFee(operation) { try { const validation = this.validateOperation(operation); if (!validation.valid) { return validation.error; } const { type, data } = operation; const operationData = await this._buildOperation(type, data); if (!operationData || operationData.errorCode !== 0) { return this._responseError(errors.INVALID_OPERATIONS); } return this._responseData({ operation: operationData, estimated_fee: await this._estimateOperationFee(operationData) }); } catch (err) { console.error('Error in evaluateOperationFee:', err); return this._responseError(errors.INVALID_OPERATIONS); } } // 估算操作费用 async _estimateOperationFee(operation) { try { const response = await this._request('post', 'estimateOperationFee', { operation: JSONbig.stringify(operation) }); if (response.error_code === 0) { return response.result; } throw new Error('Failed to estimate operation fee'); } catch (err) { console.error('Error in _estimateOperationFee:', err); throw err; } } } export default Operation;