UNPKG

@colony/colony-js-contract-client

Version:

Method-like interface for Smart Contracts

74 lines (63 loc) 2.09 kB
/* @flow */ /* eslint-disable import/no-cycle */ import isPlainObject from 'lodash.isplainobject'; import ContractClient from './ContractClient'; import ContractMethod from './ContractMethod'; import type { ContractMethodArgs, ValidateEmpty } from '../flowtypes'; export default class ContractMethodCaller< InputValues: { [inputValueName: string]: any }, OutputValues: { [outputValueName: string]: any }, IContractClient: ContractClient, ContractData: { [dataValueName: string]: any }, > extends ContractMethod< InputValues, OutputValues, IContractClient, ContractData, > { _validateEmpty: ?ValidateEmpty; static containsNullValues(values: Object | null) { if (isPlainObject(values)) return Object.values(values || {}).some(value => value === null); return false; } constructor({ client, functionName, input, output, name, validateEmpty, }: ContractMethodArgs<IContractClient> & { validateEmpty?: ValidateEmpty, } = {}) { super({ client, name, functionName, input, output }); if (validateEmpty) this._validateEmpty = validateEmpty; } async validateEmpty(inputValues: *, outputValues: *) { if (this._validateEmpty) { let isValid: boolean = false; let reason; try { isValid = await this._validateEmpty(inputValues, outputValues); } catch (error) { reason = error.message || error.toString(); } if (!isValid) throw new Error(`Empty response${reason ? ` (${reason})` : ''}`); } return true; } /** * Given named input values, perform a call on the method's * contract function, and get named output values from the result. */ async call(inputValues?: InputValues) { const args = this.getValidatedArgs(inputValues); const callResult = await this.client.call(this.functionName, args); const outputValues = this.convertOutputValues(callResult, inputValues); if (this.constructor.containsNullValues(outputValues)) await this.validateEmpty(inputValues, outputValues); return outputValues; } }