'use strict'; import BN from 'bn.js'; import { Account } from './account'; import { getTransactionLastResult } from './providers'; import { PositionalArgsError, ArgumentTypeError } from './utils/errors'; export class Contract { readonly account: Account; readonly contractId: string; constructor(account: Account, contractId: string, options: { viewMethods: string[], changeMethods: string[] }) { this.account = account; this.contractId = contractId; const { viewMethods = [], changeMethods = [] } = options; viewMethods.forEach((methodName) => { Object.defineProperty(this, methodName, { writable: false, enumerable: true, value: async function(args: any) { if (arguments.length > 1) { throw new PositionalArgsError(); } return this.account.viewFunction(this.contractId, methodName, args || {}); } }); }); changeMethods.forEach((methodName) => { Object.defineProperty(this, methodName, { writable: false, enumerable: true, value: async function(args: any, gas?: BN, amount?: BN) { if (arguments.length > 3) { throw new PositionalArgsError(); } validateBNLike({ gas, amount }); const rawResult = await this.account.functionCall(this.contractId, methodName, args || {}, gas, amount); return getTransactionLastResult(rawResult); } }); }); } } function validateBNLike(argMap: { [name: string]: any }) { const bnLike = 'number, decimal string or BN'; for (const argName of Object.keys(argMap)) { const argValue = argMap[argName]; if (argValue && !BN.isBN(argValue) && isNaN(argValue)) { throw new ArgumentTypeError(argName, bnLike, argValue); } } }