1- import { providers , Signer } from 'ethers'
1+ import {
2+ Contract ,
3+ ContractFunction ,
4+ ContractReceipt ,
5+ ContractTransaction ,
6+ providers ,
7+ Signer ,
8+ } from 'ethers'
9+ import { Provider } from '@ethersproject/providers'
10+ import lodash from 'lodash'
11+ import fs from 'fs'
212
313import { AddressBook } from './address-book'
414import { logger } from './logging'
@@ -45,12 +55,17 @@ export interface NetworkContracts {
4555export const loadContracts = (
4656 addressBook : AddressBook ,
4757 signerOrProvider ?: Signer | providers . Provider ,
58+ enableTXLogging = false ,
4859) : NetworkContracts => {
4960 const contracts = { }
5061 for ( const contractName of addressBook . listEntries ( ) ) {
5162 const contractEntry = addressBook . getEntry ( contractName )
5263 try {
53- const contract = getContractAt ( contractName , contractEntry . address )
64+ let contract = getContractAt ( contractName , contractEntry . address )
65+ if ( enableTXLogging ) {
66+ contract . connect = getWrappedConnect ( contract , contractName )
67+ contract = wrapCalls ( contract , contractName )
68+ }
5469 contracts [ contractName ] = contract
5570 if ( signerOrProvider ) {
5671 contracts [ contractName ] = contracts [ contractName ] . connect ( signerOrProvider )
@@ -61,3 +76,77 @@ export const loadContracts = (
6176 }
6277 return contracts as NetworkContracts
6378}
79+
80+ // Returns a contract connect function that wrapps contract calls with wrapCalls
81+ function getWrappedConnect (
82+ contract : Contract ,
83+ contractName : string ,
84+ ) : ( signerOrProvider : string | Provider | Signer ) => Contract {
85+ const call = contract . connect . bind ( contract )
86+ const override = ( signerOrProvider : string | Provider | Signer ) : Contract => {
87+ const connectedContract = call ( signerOrProvider )
88+ connectedContract . connect = getWrappedConnect ( connectedContract , contractName )
89+ return wrapCalls ( connectedContract , contractName )
90+ }
91+ return override
92+ }
93+
94+ // Returns a contract with wrapped calls
95+ // The wrapper will run the tx, wait for confirmation and log the details
96+ function wrapCalls ( contract : Contract , contractName : string ) : Contract {
97+ const wrappedContract = lodash . cloneDeep ( contract )
98+
99+ for ( const fn of Object . keys ( contract . functions ) ) {
100+ const call : ContractFunction < ContractTransaction > = contract . functions [ fn ]
101+ const override = async ( ...args : Array < any > ) : Promise < ContractTransaction > => {
102+ // Make the call
103+ const tx = await call ( ...args )
104+ logContractCall ( tx , contractName , fn , args )
105+
106+ // Wait for confirmation
107+ const receipt = await contract . provider . waitForTransaction ( tx . hash )
108+ logContractReceipt ( tx , receipt )
109+ return tx
110+ }
111+
112+ wrappedContract . functions [ fn ] = override
113+ wrappedContract [ fn ] = override
114+ }
115+
116+ return wrappedContract
117+ }
118+
119+ function logContractCall (
120+ tx : ContractTransaction ,
121+ contractName : string ,
122+ fn : string ,
123+ args : Array < any > ,
124+ ) {
125+ const msg = [ ]
126+ msg . push ( `> Sent transaction ${ contractName } .${ fn } ` )
127+ msg . push ( ` sender: ${ tx . from } ` )
128+ msg . push ( ` contract: ${ tx . to } ` )
129+ msg . push ( ` params: [ ${ args } ]` )
130+ msg . push ( ` txHash: ${ tx . hash } ` )
131+
132+ logToConsoleAndFile ( msg )
133+ }
134+
135+ function logContractReceipt ( tx : ContractTransaction , receipt : ContractReceipt ) {
136+ const msg = [ ]
137+ msg . push (
138+ receipt . status ? `✔ Transaction succeeded: ${ tx . hash } ` : `✖ Transaction failed: ${ tx . hash } ` ,
139+ )
140+
141+ logToConsoleAndFile ( msg )
142+ }
143+
144+ function logToConsoleAndFile ( msg : string [ ] ) {
145+ const isoDate = new Date ( ) . toISOString ( )
146+ const fileName = `tx-${ isoDate . substring ( 0 , 10 ) } .log`
147+
148+ msg . map ( ( line ) => {
149+ console . log ( line )
150+ fs . appendFileSync ( fileName , `[${ isoDate } ] ${ line } \n` )
151+ } )
152+ }
0 commit comments