file author Marek Kotewicz <marek@ethdev.com>
 *  date import * as utils from './utils/utils' ; import * as formatters from './utils/formatters' ; import { coder } from './solidity/coder' ; import { RequestManager } from './RequestManager' ; import { Contract } from './Contract' ; import { EthFilter } from './Filter' ; import { AbiEvent , AbiInput , FilterOptions , LogObject , TopicFilter } from './Schema' ; /**
 * This prototype should be used to create event filters
 */ export class SolidityEvent { _anonymous : boolean = false ; _name : string ; _params : AbiInput [ ] ; constructor ( public requestManager , json , public address ) { this . _params = json . inputs || [ ] ; this . _name = utils . transformToFullName ( json ) ; this . _anonymous = json . anonymous || false ; } param decide types ( indexed ) { return this . _params . filter ( function ( i ) { return i . indexed === indexed ; } ) ; } /**
     * Should be used to get event display name
     */ displayName ( ) { return utils . extractDisplayName ( this . _name ) ; } /**
     * Should be used to get event type name
     */ typeName ( ) { return utils . extractTypeName ( this . _name ) || 'void' ; } /**
     * Should be used to get event signature
     */ signature ( ) { return utils . sha3 ( this . _name ) ; } param { object } indexed param { object } options encode ( indexed = { } , options = { } ) { let result = { topics : [ ] , address : this . address } ; if ( options . fromBlock !== undefined ) result . fromBlock = formatters . inputBlockNumberFormatter ( options . fromBlock ) || undefined ; if ( options . toBlock !== undefined ) result . toBlock = formatters . inputBlockNumberFormatter ( options . toBlock ) || undefined ; result . topics = result . topics || [ ] ; if ( ! this . _anonymous ) { result . topics . push ( '0x' + this . signature ( ) ) ; } let indexedTopics = this . _params . filter ( function ( i ) { return i . indexed === true ; } ) . map ( function ( i ) { let value = indexed [ i . name ] ; if ( value === undefined || value === null ) { return null ; } if ( utils . isArray ( value ) ) { return value . map ( function ( v ) { return '0x' + coder . encodeParams ( [ i ] , [ v ] ) ; } ) ; } return '0x' + coder . encodeParams ( [ i ] , [ value ] ) ; } ) ; result . topics = result . topics . concat ( indexedTopics ) ; return result ; } param { object } data decode ( data ) { data . data = data . data || '' ; data . topics = data . topics || [ ] ; let argTopics = this . _anonymous ? data . topics : data . topics . slice ( 1 ) ; let indexedData = argTopics . map ( function ( topics ) { return topics . slice ( 2 ) ; } ) . join ( '' ) ; let indexedParams = coder . decodeParams ( this . types ( true ) , indexedData ) ; let notIndexedData = data . data . slice ( 2 ) ; let notIndexedParams = coder . decodeParams ( this . types ( false ) , notIndexedData ) ; const args = this . _params . reduce ( function ( acc , current ) { acc [ current . name ] = current . indexed ? indexedParams . shift ( ) : notIndexedParams . shift ( ) ; return acc ; } , { } as Record < string , any > ) ; return { ... formatters . outputLogFormatter ( data ) , event : this . displayName ( ) , address : data . address , args } ; } param { object } indexed param { object } options async execute ( indexed , options ? ) { let o = this . encode ( indexed , options ) ; let formatter = this . decode . bind ( this ) ; return new EthFilter < LogObject > ( this . requestManager , o , formatter ) ; } param { Contract } attachToContract ( contract ) { let execute = this . execute . bind ( this ) ; let displayName = this . displayName ( ) ; if ( ! contract . events [ displayName ] ) { contract . events [ displayName ] = execute ; } ; ( contract . events [ displayName ] as any ) [ this . typeName ( ) ] = this . execute . bind ( this , contract ) ; } }