import { EthApi } from "@joincivil/ethapi" ; import { DecodedLogEntry , DecodedLogEntryEvent , TxHash , EthAddress } from "@joincivil/typescript-types" ; import { isDefined , isDeployedBytecodeEqual } from "@joincivil/utils" ; import { Observable , Subscriber } from "rxjs" ; import { CivilTransactionReceipt , TwoStepEthTransaction } from "../../types" ; import { artifacts } from "../generated/artifacts" ; import { OwnableContract } from "../interfaces/ownable" ; import { Contract as IContract } from "../interfaces/contract" ; import { EventLog as EventData , TransactionReceipt , Log , TransactionConfig } from "web3-core" ; import { Contract } from "web3-eth-contract" ; export interface EventOptions { filter ? : { } ; fromBlock ? : number ; toBlock ? : number | "latest" | "pending" | "genesis" | undefined ; topics ? : any [ ] ; } export function findEvent < T extends DecodedLogEntry > ( tx , eventName ) { if ( tx . events && tx . events [ eventName ] ) { return tx . events [ eventName ] as T | undefined ; } } export function findEventOrThrow < T extends DecodedLogEntry > ( tx , eventName ) { const event = findEvent < T > ( tx , eventName ) ; if ( ! event ) { throw new Error ( `Log with event == "${ eventName }" not found` ) ; } return event ; } export function findEvents < T extends DecodedLogEntry > ( tx , eventName ) { return tx . logs ! . filter ( log => isDecodedLog ( log ) && log . event === eventName ) as T [ ] ; } export function isContract < T extends Contract > ( what ) { return ( what as T ) . abi !== undefined ; } export function isOwnableContract ( contract ) { return ( contract as OwnableContract ) . owner !== undefined ; } export function isDecodedLog ( what ) { return typeof ( what as any ) . event === "string" && isDefined ( what as any ) ; } export type TypedEventFilter < T > = { [ P in keyof T ] ? : T [ P ] | Array < T [ P ] > ; } ; export type DecodedFilterCallback < L extends DecodedLogEntryEvent > = ( err : Error , result : L ) => void ; export interface DecodedFilterResult < L extends DecodedLogEntryEvent > { get ( callback ) : void ; watch ( callback ) : void ; stopWatching ( callback ? ) : void ; } export type EventFunction < A , L extends DecodedLogEntryEvent < A > > = ( paramFilters ? : TypedEventFilter < A > , filterObject ? : EventOptions , callback ? : DecodedFilterCallback < L > ) => DecodedFilterResult < L > ; export function streamifyEvent < A , L extends DecodedLogEntryEvent < A > > ( instance , eventName ) { return ( paramFilters ? , filterObject ? ) => { return new Observable < L > ( ( subscriber ) => { if ( filterObject && filterObject . toBlock ) { instance . getPastEvents ( eventName , filterObject ) . then ( logs => { for ( const log of logs ) { subscriber . next ( log ) ; } subscriber . complete ( ) ; } ) . catch ( err => { subscriber . error ( err ) ; } ) ; } else { const eventStream = instance . events [ eventName ] ( filterObject ) ; eventStream . on ( "data" , ( event ) => { subscriber . next ( event ) ; } ) . on ( "error" , ( err ) => { subscriber . error ( err ) ; subscriber . complete ( ) ; } ) ; } } ) . distinctUntilChanged ( ( a , b ) => { return a . blockNumber === b . blockNumber && a . logIndex === b . logIndex ; } ) ; } ; } export function isTxData ( data ) { return ( data . gas !== undefined || data . gasPrice !== undefined || data . nonce !== undefined || data . from !== undefined || data . value !== undefined || data . to !== undefined ) ; } export function createTwoStepTransaction < T > ( ethApi , txHash , transform ) { return { txHash , awaitReceipt : async ( blockConfirmations ? ) => ethApi . awaitReceipt < CivilTransactionReceipt > ( txHash , blockConfirmations ) . then ( transform ) , } ; } export function createTwoStepSimple ( ethApi , txHash ) { return { txHash , awaitReceipt : ethApi . awaitReceipt . bind ( ethApi , txHash ) , } ; } export function isEthAddress ( what ) { return typeof what === "string" ; } export async function isAddressMultisigWallet ( ethApi , address ) { const code = await ethApi . getCode ( address ) ; return isDeployedBytecodeEqual ( artifacts . MultiSigWallet . deployedBytecode , code ) ; }