"use strict" ; import { assert } from "chai" ; import { DecodedLogEntryEvent , } from "web3" ; import { Utils } from "../lib/utils" ; import { UtilsInternal } from "../lib/utilsInternal" ; import { Web3EventService } from "../lib/web3EventService" ; import { ApprovalEventResult , StandardTokenFactory , } from "../lib/wrappers/standardToken" ; import "./helpers" ; describe ( "Web3EventService" , ( ) => { interface EntityType { blockNumber : number ; } const makeTransactions = async ( count = 1 ) : Promise < void > => { while ( count -- ) { await web3 . eth . sendTransaction ( { from : accounts [ 0 ] , to : accounts [ 3 ] , value : web3 . toWei ( 0.00001 , "ether" ) , } ) ; } } ; it ( "can get entity with requiredDepth" , async ( ) => { const tokenAddress = await Utils . getGenTokenAddress ( ) ; assert . isOk ( tokenAddress ) ; const token = await StandardTokenFactory . at ( tokenAddress ) ; assert . isOk ( token ) ; const initialBlockNumber = await UtilsInternal . lastBlockNumber ( ) ; let currentBlockNumber = initialBlockNumber ; let eventBlockNumber = currentBlockNumber ; const web3EventService = new Web3EventService ( ) ; const fetcher = web3EventService . createEntityFetcherFactory < EntityType , ApprovalEventResult > ( token . Approval , async ( event ) : Promise < any > => { return Promise . resolve ( { blockNumber : event . blockNumber } ) ; } ) ( { spender : accounts [ 0 ] , owner : accounts [ 4 ] } , { fromBlock : initialBlockNumber } ) ; const amount = web3 . toWei ( 1 ) ; const result = await token . approve ( { amount , owner : accounts [ 4 ] , spender : accounts [ 0 ] , } ) ; await result . getTxConfirmed ( ) ; await makeTransactions ( 2 ) ; await new Promise ( async ( resolve , reject ) : Promise < void > => { fetcher . get ( async ( error , entitiesPromise ) => { const entities = await entitiesPromise ; for ( const entity of entities ) { currentBlockNumber = await UtilsInternal . lastBlockNumber ( ) ; eventBlockNumber = entity . blockNumber ; } resolve ( ) ; } , 2 ) ; } ) ; assert . equal ( eventBlockNumber , currentBlockNumber - 2 ) ; } ) ; it ( "can watch entity with requiredDepth" , async ( ) => { const tokenAddress = await Utils . getGenTokenAddress ( ) ; assert . isOk ( tokenAddress ) ; const token = await StandardTokenFactory . at ( tokenAddress ) ; assert . isOk ( token ) ; const initialBlockNumber = await UtilsInternal . lastBlockNumber ( ) ; let currentBlockNumber = initialBlockNumber ; let eventBlockNumber = currentBlockNumber ; const web3EventService = new Web3EventService ( ) ; const fetcher = web3EventService . createEntityFetcherFactory < EntityType , ApprovalEventResult > ( token . Approval , async ( event ) : Promise < EntityType > => { return { blockNumber : event . blockNumber } ; } ) ( { spender : accounts [ 0 ] , owner : accounts [ 4 ] } , { fromBlock : initialBlockNumber } ) ; let done = false ; const promise = new Promise ( async ( resolve , reject ) : Promise < void > => { fetcher . watch ( async ( error , entity ) => { currentBlockNumber = await UtilsInternal . lastBlockNumber ( ) ; eventBlockNumber = entity . blockNumber ; done = true ; resolve ( ) ; } , 2 ) ; } ) ; const amount = web3 . toWei ( 1 ) ; const result = await token . approve ( { amount , owner : accounts [ 4 ] , spender : accounts [ 0 ] , } ) ; await result . getTxConfirmed ( ) ; await makeTransactions ( 2 ) ; const timeoutPromise = new Promise ( async ( resolve , reject ) : Promise < void > => { setTimeout ( ( ) => { assert ( done , "didn't find tx of required depth" ) ; resolve ( ) ; } , 2000 ) ; } ) ; await Promise . all ( [ timeoutPromise , promise ] ) ; fetcher . stopWatching ( ) ; assert . equal ( eventBlockNumber , currentBlockNumber - 2 ) ; } ) ; it ( "can watch event with requiredDepth" , async ( ) => { const tokenAddress = await Utils . getGenTokenAddress ( ) ; assert . isOk ( tokenAddress ) ; const token = await StandardTokenFactory . at ( tokenAddress ) ; assert . isOk ( token ) ; const initialBlockNumber = await UtilsInternal . lastBlockNumber ( ) ; let currentBlockNumber = initialBlockNumber ; let eventBlockNumber = currentBlockNumber ; let done = false ; const fetcher = token . Approval ( { spender : accounts [ 0 ] , owner : accounts [ 4 ] } , { fromBlock : initialBlockNumber } ) ; const promise = new Promise ( async ( resolve , reject ) : Promise < void > => { fetcher . watch ( async ( error , event ) => { currentBlockNumber = await UtilsInternal . lastBlockNumber ( ) ; eventBlockNumber = event . blockNumber ; done = true ; resolve ( ) ; } , 2 ) ; } ) ; const amount = web3 . toWei ( 1 ) ; const result = await token . approve ( { amount , owner : accounts [ 4 ] , spender : accounts [ 0 ] , } ) ; await result . getTxConfirmed ( ) ; await makeTransactions ( 2 ) ; const timeoutPromise = new Promise ( async ( resolve , reject ) : Promise < void > => { setTimeout ( ( ) => { assert ( done , "didn't find tx of required depth" ) ; resolve ( ) ; } , 2000 ) ; } ) ; await Promise . all ( [ timeoutPromise , promise ] ) ; fetcher . stopWatching ( ) ; assert . equal ( eventBlockNumber , currentBlockNumber - 2 ) ; } ) ; it ( "will wait for event with requiredDepth" , async ( ) => { const tokenAddress = await Utils . getGenTokenAddress ( ) ; assert . isOk ( tokenAddress ) ; const token = await StandardTokenFactory . at ( tokenAddress ) ; assert . isOk ( token ) ; let found = false ; const fetcher = token . Approval ( { spender : accounts [ 0 ] , owner : accounts [ 4 ] } , { fromBlock : "latest" } ) ; fetcher . watch ( async ( error , event ) => { found = true ; } , 4 ) ; const result = await token . approve ( { amount : web3 . toWei ( 1 ) , owner : accounts [ 4 ] , spender : accounts [ 0 ] , } ) ; await result . getTxConfirmed ( ) ; await makeTransactions ( 2 ) ; await UtilsInternal . sleep ( 3000 ) ; /**
         * there is no way to shut down the fetcher if it is still watching for the transaction to
         * appear at the given depth -- there is an inner watch.  So jump
         * through some hoops here.
         */ const wasFound = found ; await makeTransactions ( 2 ) ; fetcher . stopWatching ( ) ; assert ( ! wasFound , "didn't wait for tx of required depth" ) ; } ) ; } ) ;