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'
2
12
3
13
import { AddressBook } from './address-book'
4
14
import { logger } from './logging'
@@ -45,12 +55,17 @@ export interface NetworkContracts {
45
55
export const loadContracts = (
46
56
addressBook : AddressBook ,
47
57
signerOrProvider ?: Signer | providers . Provider ,
58
+ enableTXLogging = false ,
48
59
) : NetworkContracts => {
49
60
const contracts = { }
50
61
for ( const contractName of addressBook . listEntries ( ) ) {
51
62
const contractEntry = addressBook . getEntry ( contractName )
52
63
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
+ }
54
69
contracts [ contractName ] = contract
55
70
if ( signerOrProvider ) {
56
71
contracts [ contractName ] = contracts [ contractName ] . connect ( signerOrProvider )
@@ -61,3 +76,77 @@ export const loadContracts = (
61
76
}
62
77
return contracts as NetworkContracts
63
78
}
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