import { Account , AccountManager } from '../accounts' ; import { nextBlock } from '../utils' ; import { Api } from 'eosjs' ; import { Contract as EOSJSContract , Type } from 'eosjs/dist/eosjs-serialize' ; import { EOSManager } from '../eosManager' ; import { Abi } from 'eosjs/dist/eosjs-rpc-interfaces' ; import { camelCase } from './utils' ; export interface ContractActionParameters { [ key ] : any ; } export interface ContractActionOptions { from ? : Account ; debug ? : boolean ; } export interface ContractConstructorArgs { eos : Api ; identifier ? : string ; account : Account ; abi : Abi ; actions : Map < string , Type > ; types : Map < string , Type > ; } export interface GetTableRowsOptions { scope ? : string ; tableKey ? : string ; lowerBound ? : any ; upperBound ? : any ; indexPosition ? : any ; keyType ? : any ; limit ? : number ; reverse ? : boolean ; showPayer ? : boolean ; } export interface ActorPermission { actor : string ; permission : string ; } /**
 * Adds additional functionality to the EOSJS `Contract` class
 */ export class Contract implements EOSJSContract { hidden private _eos : Api ; hidden private _account : Account ; hidden private _identifier ? : string ; hidden private _abi : Abi ; /** Deployed contract actions */ public actions : Map < string , Type > = new Map ( ) ; /** Deployed contract types */ public types : Map < string , Type > = new Map ( ) ; author Kevin Brown <github.com/thekevinbrown>
     *  returns public get account ( ) { return this . _account ; } author Kevin Brown <github.com/thekevinbrown>
     *  returns public get identifier ( ) { return this . _identifier ; } constructor ( { eos , identifier , account , abi , actions , types } ) { this . _eos = eos ; this . _identifier = identifier ; this . _account = account ; this . _abi = abi ; this . actions = actions ; this . types = types ; for ( const action of actions . values ( ) ) { ( this as any ) [ action . name ] = function ( ) { const data = { } ; if ( arguments . length < action . fields . length ) { throw new Error ( `Insufficient arguments supplied to ${ action . name }. Expected ${ action . fields . length } got ${ arguments . length }.` ) ; } if ( arguments . length > action . fields . length + 1 ) { throw new Error ( `Too many arguments supplied to ${ action . name }. Expected ${ action . fields . length } got ${ arguments . length }.` ) ; } for ( let i = 0 ; i < action . fields . length ; i ++ ) { data [ action . fields [ i ] . name ] = arguments [ i ] ; } let authorization = account . active ; const options = arguments [ action . fields . length ] ; if ( options ) { if ( options . from && options . from instanceof Account ) { authorization = options . from . active ; EOSManager . addSigningAccountIfMissing ( options . from ) ; } else if ( options . auths && options . auths instanceof Array ) { authorization = options . auths ; } } return EOSManager . transact ( { actions : [ { account : account . name , name : action . name , authorization : authorization , data , } , ] , } , eos , { debug : options && options . debug } ) ; } ; } for ( const table of abi . tables ) { ( this as any ) [ camelCase ( table . name ) + 'Table' ] = function ( ) { return this . getTableRows ( table . name , arguments [ 0 ] ) ; } ; } } author Kevin Brown <github.com/thekevinbrown>
     *  note param table param scope note public getTableRows = async ( table , options ? ) => { await nextBlock ( ) ; const result = await this . _eos . rpc . get_table_rows ( { code : this . account . name , scope : ( options && options . scope ) || this . account . name , table_key : options && options . tableKey , lower_bound : options && options . lowerBound , upper_bound : options && options . upperBound , index_position : options && options . indexPosition , key_type : options && options . keyType , limit : options && options . limit , reverse : options && options . reverse , show_payer : options && options . showPayer , table , json : true , } ) ; const tableAbi = this . _abi . tables . find ( ( tableAbi ) => tableAbi . name === table ) ; if ( ! tableAbi ) throw new Error ( `Could not find ABI for table ${ table }` ) ; const tableRowType = this . types . get ( tableAbi . type ) ; if ( ! tableRowType ) throw new Error ( `Could not find table row type for table ${ table }` ) ; const booleanFields = tableRowType . fields . filter ( ( field ) => field . typeName === 'bool' ) ; if ( booleanFields . length > 0 ) { for ( const row of result . rows ) { for ( const field of booleanFields ) { const currentValue = row [ field . name ] ; if ( currentValue !== 0 && currentValue !== 1 ) { throw new Error ( `Invalid value while casting to boolean for ${ field . name } field on row. Got ${ currentValue }, expected 0 or 1.` ) ; } row [ field . name ] = currentValue ? true : false ; } } } const dateFields = tableRowType . fields . filter ( ( field ) => field . typeName === 'time_point_sec' ) ; if ( dateFields . length > 0 ) { for ( const row of result . rows ) { for ( const field of dateFields ) { const currentValue = row [ field . name ] ; let date = new Date ( currentValue + 'Z' ) ; if ( date === undefined ) { throw new Error ( `Invalid value while casting to Date for ${ field . name } field on row. Got ${ currentValue }, expected as ISO date string.` ) ; } row [ field . name ] = date ; } } } return result ; } ; note author Kevin Brown <github.com/thekevinbrown>
     *  author Mitch Pierias <github.com/MitchPierias>
      public addCodePermission = ( ) => AccountManager . addCodePermission ( this . _account ) ; }